feat(events): isOnline presence check for a user and app

This commit is contained in:
Daniel Salazar committed 2026-10-28 00:53:28 -07:00
1 parent fe58213bb5
commit 3b4945f018
2 files changed
+26

No files matched your search

@@ -403,6 +403,17 @@ export class EventForwardService extends PuterService {
}
}
/**
* Whether the pair holds a socket anywhere: this node, this region or a
* peer region. Only this node's sockets count where presence is not kept.
*/
async isOnline(userId: number, appUid: string | null): Promise<boolean> {
if (this.services.socket.has(forwardTarget(userId, appUid))) return true;
if (!this.active) return false;
if (await this.heldInRegion(userId, appUid)) return true;
return (await this.regionsFor(userId, appUid)).length > 0;
}
/** Send one `single` to a named region, carrying what settles it. */
handOff(region: string, delivery: ForwardableDelivery): void {
this.#send(region, delivery);
@@ -1647,6 +1647,21 @@ describe('presence moving in another region', () => {
});
});
describe('isOnline', () => {
it('is true for a socket on this node, in this region or in a peer region', async () => {
const west = makeRegion('west', ['east']);
const east = makeRegion('east', ['west']);
await register(west);
expect(await west.forward.isOnline(userId, null)).toBe(false);
east.rooms.add(String(userId));
await east.forward.noteConnect(actorFor(), 'tab-1');
expect(await east.forward.isOnline(userId, null)).toBe(true);
expect(await west.forward.isOnline(userId, null)).toBe(true);
expect(await west.forward.isOnline(userId, 'app-other')).toBe(false);
});
});
// -- Decommissioned regions --------------------------------------------
describe('a row naming a region that is not a peer', () => {