@xemahq/realtime-stream 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +67 -0
  3. package/dist/index.d.ts +15 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +31 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/lib/cached-membership-resolver.d.ts +25 -0
  8. package/dist/lib/cached-membership-resolver.d.ts.map +1 -0
  9. package/dist/lib/cached-membership-resolver.js +69 -0
  10. package/dist/lib/cached-membership-resolver.js.map +1 -0
  11. package/dist/lib/connection-lifecycle.d.ts +14 -0
  12. package/dist/lib/connection-lifecycle.d.ts.map +1 -0
  13. package/dist/lib/connection-lifecycle.js +3 -0
  14. package/dist/lib/connection-lifecycle.js.map +1 -0
  15. package/dist/lib/control-frame.d.ts +54 -0
  16. package/dist/lib/control-frame.d.ts.map +1 -0
  17. package/dist/lib/control-frame.js +14 -0
  18. package/dist/lib/control-frame.js.map +1 -0
  19. package/dist/lib/cursor.d.ts +11 -0
  20. package/dist/lib/cursor.d.ts.map +1 -0
  21. package/dist/lib/cursor.js +101 -0
  22. package/dist/lib/cursor.js.map +1 -0
  23. package/dist/lib/default-hub-stream-source.d.ts +9 -0
  24. package/dist/lib/default-hub-stream-source.d.ts.map +1 -0
  25. package/dist/lib/default-hub-stream-source.js +43 -0
  26. package/dist/lib/default-hub-stream-source.js.map +1 -0
  27. package/dist/lib/frame-authz.d.ts +17 -0
  28. package/dist/lib/frame-authz.d.ts.map +1 -0
  29. package/dist/lib/frame-authz.js +49 -0
  30. package/dist/lib/frame-authz.js.map +1 -0
  31. package/dist/lib/hub-stream-source.d.ts +4 -0
  32. package/dist/lib/hub-stream-source.d.ts.map +1 -0
  33. package/dist/lib/hub-stream-source.js +3 -0
  34. package/dist/lib/hub-stream-source.js.map +1 -0
  35. package/dist/lib/membership-resolver.d.ts +15 -0
  36. package/dist/lib/membership-resolver.d.ts.map +1 -0
  37. package/dist/lib/membership-resolver.js +13 -0
  38. package/dist/lib/membership-resolver.js.map +1 -0
  39. package/dist/lib/module-options.d.ts +17 -0
  40. package/dist/lib/module-options.d.ts.map +1 -0
  41. package/dist/lib/module-options.js +3 -0
  42. package/dist/lib/module-options.js.map +1 -0
  43. package/dist/lib/realtime-fanout.service.d.ts +57 -0
  44. package/dist/lib/realtime-fanout.service.d.ts.map +1 -0
  45. package/dist/lib/realtime-fanout.service.js +384 -0
  46. package/dist/lib/realtime-fanout.service.js.map +1 -0
  47. package/dist/lib/realtime-stream.controller.d.ts +19 -0
  48. package/dist/lib/realtime-stream.controller.d.ts.map +1 -0
  49. package/dist/lib/realtime-stream.controller.js +185 -0
  50. package/dist/lib/realtime-stream.controller.js.map +1 -0
  51. package/dist/lib/realtime-stream.module.d.ts +14 -0
  52. package/dist/lib/realtime-stream.module.d.ts.map +1 -0
  53. package/dist/lib/realtime-stream.module.js +80 -0
  54. package/dist/lib/realtime-stream.module.js.map +1 -0
  55. package/dist/lib/role-based-fetcher.d.ts +14 -0
  56. package/dist/lib/role-based-fetcher.d.ts.map +1 -0
  57. package/dist/lib/role-based-fetcher.js +23 -0
  58. package/dist/lib/role-based-fetcher.js.map +1 -0
  59. package/dist/lib/tokens.d.ts +5 -0
  60. package/dist/lib/tokens.d.ts.map +1 -0
  61. package/dist/lib/tokens.js +8 -0
  62. package/dist/lib/tokens.js.map +1 -0
  63. package/package.json +59 -0
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.encodeCursorMap = encodeCursorMap;
4
+ exports.parseCursorMap = parseCursorMap;
5
+ exports.cursorFromEvent = cursorFromEvent;
6
+ function encodeCursorMap(cursors) {
7
+ const out = { global: cursors.global };
8
+ if (cursors.org !== undefined)
9
+ out['org'] = cursors.org;
10
+ if (cursors.project && Object.keys(cursors.project).length > 0) {
11
+ out['project'] = { ...cursors.project };
12
+ }
13
+ if (cursors.session && Object.keys(cursors.session).length > 0) {
14
+ out['session'] = { ...cursors.session };
15
+ }
16
+ return JSON.stringify(out);
17
+ }
18
+ function parseCursorMap(input) {
19
+ if (!input || input.length === 0)
20
+ return { global: '0' };
21
+ if (!input.startsWith('{')) {
22
+ return { global: assertNonNegativeInt(input, 'global') };
23
+ }
24
+ let parsed;
25
+ try {
26
+ parsed = JSON.parse(input);
27
+ }
28
+ catch (err) {
29
+ throw new TypeError(`Last-Event-ID JSON could not be parsed: ${err instanceof Error ? err.message : String(err)}`);
30
+ }
31
+ if (!parsed || typeof parsed !== 'object') {
32
+ throw new TypeError('Last-Event-ID JSON must be an object.');
33
+ }
34
+ const obj = parsed;
35
+ const globalRaw = obj['global'];
36
+ const global = typeof globalRaw === 'number'
37
+ ? assertNonNegativeInt(String(globalRaw), 'global')
38
+ : typeof globalRaw === 'string'
39
+ ? assertNonNegativeInt(globalRaw, 'global')
40
+ : null;
41
+ if (global === null) {
42
+ throw new TypeError('Last-Event-ID JSON requires a `global` field.');
43
+ }
44
+ const out = { global };
45
+ const org = obj['org'];
46
+ if (typeof org === 'string' || typeof org === 'number') {
47
+ out.org = assertNonNegativeInt(String(org), 'org');
48
+ }
49
+ const project = obj['project'];
50
+ if (project && typeof project === 'object' && !Array.isArray(project)) {
51
+ out.project = freezeRecord(coerceCursorRecord(project, 'project'));
52
+ }
53
+ const session = obj['session'];
54
+ if (session && typeof session === 'object' && !Array.isArray(session)) {
55
+ out.session = freezeRecord(coerceCursorRecord(session, 'session'));
56
+ }
57
+ return out;
58
+ }
59
+ function coerceCursorRecord(src, scope) {
60
+ const out = {};
61
+ for (const [k, v] of Object.entries(src)) {
62
+ if (typeof v === 'string' || typeof v === 'number') {
63
+ out[k] = assertNonNegativeInt(String(v), `${scope}/${k}`);
64
+ }
65
+ else {
66
+ throw new TypeError(`Last-Event-ID ${scope} cursor for key "${k}" must be a string or number.`);
67
+ }
68
+ }
69
+ return out;
70
+ }
71
+ function freezeRecord(rec) {
72
+ return Object.freeze({ ...rec });
73
+ }
74
+ function assertNonNegativeInt(raw, label) {
75
+ if (!/^\d+$/.test(raw)) {
76
+ throw new TypeError(`Last-Event-ID ${label} cursor must be a non-negative integer string; got "${raw}".`);
77
+ }
78
+ return raw;
79
+ }
80
+ function cursorFromEvent(event, scope) {
81
+ if (scope === 'global') {
82
+ const v = event['ehglobalseq'];
83
+ return typeof v === 'string' ? v : undefined;
84
+ }
85
+ if (scope === 'org') {
86
+ const v = event['ehorgseq'];
87
+ return typeof v === 'string' ? v : undefined;
88
+ }
89
+ if (scope.kind === 'project') {
90
+ if (event['ehprojectid'] !== scope.id)
91
+ return undefined;
92
+ const v = event['ehprojectseq'];
93
+ return typeof v === 'string' ? v : undefined;
94
+ }
95
+ const subj = event['subject'];
96
+ if (subj !== `session/${scope.id}`)
97
+ return undefined;
98
+ const v = event['ehsessionseq'];
99
+ return typeof v === 'string' ? v : undefined;
100
+ }
101
+ //# sourceMappingURL=cursor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor.js","sourceRoot":"","sources":["../../src/lib/cursor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { EventHubReplayClient } from '@xemahq/event-hub-client';
2
+ import type { HubStreamSource } from './hub-stream-source';
3
+ export declare class DefaultHubStreamSource implements HubStreamSource {
4
+ private readonly client;
5
+ private readonly logger;
6
+ constructor(client: EventHubReplayClient);
7
+ open(fromGlobalSeq: string, onEnvelope: (envelope: Record<string, unknown>) => void, onResync: () => void, onError: (err: Error) => void): Promise<() => void>;
8
+ }
9
+ //# sourceMappingURL=default-hub-stream-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-hub-stream-source.d.ts","sourceRoot":"","sources":["../../src/lib/default-hub-stream-source.ts"],"names":[],"mappings":"AACA,OAAO,EACL,oBAAoB,EAErB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAU3D,qBACa,sBAAuB,YAAW,eAAe;IAGhD,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA2C;gBAErC,MAAM,EAAE,oBAAoB;IAEnD,IAAI,CACR,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,EACvD,QAAQ,EAAE,MAAM,IAAI,EACpB,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,GAC5B,OAAO,CAAC,MAAM,IAAI,CAAC;CAoBvB"}
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var DefaultHubStreamSource_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.DefaultHubStreamSource = void 0;
14
+ const common_1 = require("@nestjs/common");
15
+ const event_hub_client_1 = require("@xemahq/event-hub-client");
16
+ let DefaultHubStreamSource = DefaultHubStreamSource_1 = class DefaultHubStreamSource {
17
+ client;
18
+ logger = new common_1.Logger(DefaultHubStreamSource_1.name);
19
+ constructor(client) {
20
+ this.client = client;
21
+ }
22
+ async open(fromGlobalSeq, onEnvelope, onResync, onError) {
23
+ const cursors = { global: fromGlobalSeq };
24
+ const stop = await this.client.streamFrom(cursors, {}, (env) => {
25
+ try {
26
+ onEnvelope(env);
27
+ }
28
+ catch (err) {
29
+ this.logger.error({
30
+ message: 'envelope handler threw',
31
+ error: err instanceof Error ? err.message : String(err),
32
+ });
33
+ }
34
+ }, onResync, onError);
35
+ return stop;
36
+ }
37
+ };
38
+ exports.DefaultHubStreamSource = DefaultHubStreamSource;
39
+ exports.DefaultHubStreamSource = DefaultHubStreamSource = DefaultHubStreamSource_1 = __decorate([
40
+ (0, common_1.Injectable)(),
41
+ __metadata("design:paramtypes", [event_hub_client_1.EventHubReplayClient])
42
+ ], DefaultHubStreamSource);
43
+ //# sourceMappingURL=default-hub-stream-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"default-hub-stream-source.js","sourceRoot":"","sources":["../../src/lib/default-hub-stream-source.ts"],"names":[],"mappings":";;;;;;;;;;;;;AAAA,2CAAoD;AACpD,+DAGkC;AAY3B,IAAM,sBAAsB,8BAA5B,MAAM,sBAAsB;IAGJ;IAFZ,MAAM,GAAG,IAAI,eAAM,CAAC,wBAAsB,CAAC,IAAI,CAAC,CAAC;IAElE,YAA6B,MAA4B;QAA5B,WAAM,GAAN,MAAM,CAAsB;IAAG,CAAC;IAE7D,KAAK,CAAC,IAAI,CACR,aAAqB,EACrB,UAAuD,EACvD,QAAoB,EACpB,OAA6B;QAE7B,MAAM,OAAO,GAAkB,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;QACzD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CACvC,OAAO,EACP,EAAE,EACF,CAAC,GAAG,EAAE,EAAE;YACN,IAAI,CAAC;gBACH,UAAU,CAAC,GAA8B,CAAC,CAAC;YAC7C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;oBAChB,OAAO,EAAE,wBAAwB;oBACjC,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;iBACxD,CAAC,CAAC;YACL,CAAC;QACH,CAAC,EACD,QAAQ,EACR,OAAO,CACR,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;CACF,CAAA;AA9BY,wDAAsB;iCAAtB,sBAAsB;IADlC,IAAA,mBAAU,GAAE;qCAI0B,uCAAoB;GAH9C,sBAAsB,CA8BlC"}
@@ -0,0 +1,17 @@
1
+ import type { ScopeRef } from './control-frame';
2
+ import type { CallerIdentity } from './membership-resolver';
3
+ export interface DeliverableEnvelope {
4
+ readonly ehorgid: string;
5
+ readonly ehprojectid?: string;
6
+ readonly ehuserid?: string;
7
+ readonly ehvisibility: string;
8
+ readonly subject?: string;
9
+ readonly type: string;
10
+ }
11
+ export declare function envelopeAuthorizedForCaller(envelope: DeliverableEnvelope, caller: CallerIdentity, membership: {
12
+ hasProject: boolean;
13
+ hasSession: boolean;
14
+ }, activeSessionScopes: ReadonlyArray<string>): boolean;
15
+ export declare function sessionIdFromSubject(subject: string | undefined): string | null;
16
+ export declare function isValidScopeRef(scope: ScopeRef): boolean;
17
+ //# sourceMappingURL=frame-authz.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame-authz.d.ts","sourceRoot":"","sources":["../../src/lib/frame-authz.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAQ5D,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAWD,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,mBAAmB,EAC7B,MAAM,EAAE,cAAc,EACtB,UAAU,EAAE;IAAE,UAAU,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,EACxD,mBAAmB,EAAE,aAAa,CAAC,MAAM,CAAC,GACzC,OAAO,CAqCT;AAED,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,GAAG,SAAS,GAC1B,MAAM,GAAG,IAAI,CAMf;AAMD,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAIxD"}
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.envelopeAuthorizedForCaller = envelopeAuthorizedForCaller;
4
+ exports.sessionIdFromSubject = sessionIdFromSubject;
5
+ exports.isValidScopeRef = isValidScopeRef;
6
+ function envelopeAuthorizedForCaller(envelope, caller, membership, activeSessionScopes) {
7
+ if (envelope.ehorgid !== caller.orgId)
8
+ return false;
9
+ if (envelope.ehvisibility === 'user') {
10
+ if (!envelope.ehuserid)
11
+ return false;
12
+ return envelope.ehuserid === caller.userId;
13
+ }
14
+ if (envelope.ehvisibility === 'internal')
15
+ return false;
16
+ if (envelope.ehvisibility === 'public')
17
+ return true;
18
+ if (envelope.ehvisibility === 'project') {
19
+ if (!envelope.ehprojectid)
20
+ return false;
21
+ if (!membership.hasProject)
22
+ return false;
23
+ const sessionId = sessionIdFromSubject(envelope.subject);
24
+ if (sessionId !== null) {
25
+ if (!membership.hasSession)
26
+ return false;
27
+ return activeSessionScopes.includes(sessionId);
28
+ }
29
+ return true;
30
+ }
31
+ return false;
32
+ }
33
+ function sessionIdFromSubject(subject) {
34
+ if (!subject)
35
+ return null;
36
+ const prefix = 'session/';
37
+ if (!subject.startsWith(prefix))
38
+ return null;
39
+ const id = subject.slice(prefix.length);
40
+ return id.length > 0 ? id : null;
41
+ }
42
+ function isValidScopeRef(scope) {
43
+ if (!scope.id || scope.id.length === 0)
44
+ return false;
45
+ if (scope.id.length > 256)
46
+ return false;
47
+ return scope.kind === 'project' || scope.kind === 'session';
48
+ }
49
+ //# sourceMappingURL=frame-authz.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frame-authz.js","sourceRoot":"","sources":["../../src/lib/frame-authz.ts"],"names":[],"mappings":";;AA2BA,kEA0CC;AAED,oDAQC;AAMD,0CAIC;AA9DD,SAAgB,2BAA2B,CACzC,QAA6B,EAC7B,MAAsB,EACtB,UAAwD,EACxD,mBAA0C;IAI1C,IAAI,QAAQ,CAAC,OAAO,KAAK,MAAM,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IAGpD,IAAI,QAAQ,CAAC,YAAY,KAAK,MAAM,EAAE,CAAC;QACrC,IAAI,CAAC,QAAQ,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QACrC,OAAO,QAAQ,CAAC,QAAQ,KAAK,MAAM,CAAC,MAAM,CAAC;IAC7C,CAAC;IAGD,IAAI,QAAQ,CAAC,YAAY,KAAK,UAAU;QAAE,OAAO,KAAK,CAAC;IAGvD,IAAI,QAAQ,CAAC,YAAY,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAKpD,IAAI,QAAQ,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACxC,IAAI,CAAC,QAAQ,CAAC,WAAW;YAAE,OAAO,KAAK,CAAC;QACxC,IAAI,CAAC,UAAU,CAAC,UAAU;YAAE,OAAO,KAAK,CAAC;QAEzC,MAAM,SAAS,GAAG,oBAAoB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACzD,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YAIvB,IAAI,CAAC,UAAU,CAAC,UAAU;gBAAE,OAAO,KAAK,CAAC;YACzC,OAAO,mBAAmB,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAGD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAgB,oBAAoB,CAClC,OAA2B;IAE3B,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,MAAM,MAAM,GAAG,UAAU,CAAC;IAC1B,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7C,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACxC,OAAO,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACnC,CAAC;AAMD,SAAgB,eAAe,CAAC,KAAe;IAC7C,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,KAAK,CAAC,EAAE,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACrD,IAAI,KAAK,CAAC,EAAE,CAAC,MAAM,GAAG,GAAG;QAAE,OAAO,KAAK,CAAC;IACxC,OAAO,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC;AAC9D,CAAC"}
@@ -0,0 +1,4 @@
1
+ export interface HubStreamSource {
2
+ open(fromGlobalSeq: string, onEnvelope: (envelope: Record<string, unknown>) => void, onResync: () => void, onError: (err: Error) => void): Promise<() => void>;
3
+ }
4
+ //# sourceMappingURL=hub-stream-source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hub-stream-source.d.ts","sourceRoot":"","sources":["../../src/lib/hub-stream-source.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,eAAe;IAc9B,IAAI,CACF,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,EACvD,QAAQ,EAAE,MAAM,IAAI,EACpB,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,GAC5B,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;CACxB"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=hub-stream-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hub-stream-source.js","sourceRoot":"","sources":["../../src/lib/hub-stream-source.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ export interface CallerIdentity {
2
+ readonly orgId: string;
3
+ readonly userId: string;
4
+ readonly realmId?: string;
5
+ readonly roles?: ReadonlyArray<string>;
6
+ }
7
+ export interface MembershipResolver {
8
+ hasProjectAccess(caller: CallerIdentity, projectId: string): Promise<boolean>;
9
+ hasSessionAccess(caller: CallerIdentity, sessionId: string): Promise<boolean>;
10
+ }
11
+ export declare class DenyAllMembershipResolver implements MembershipResolver {
12
+ hasProjectAccess(): Promise<boolean>;
13
+ hasSessionAccess(): Promise<boolean>;
14
+ }
15
+ //# sourceMappingURL=membership-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"membership-resolver.d.ts","sourceRoot":"","sources":["../../src/lib/membership-resolver.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAM1B,QAAQ,CAAC,KAAK,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACxC;AAWD,MAAM,WAAW,kBAAkB;IAOjC,gBAAgB,CACd,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC,CAAC;IAOpB,gBAAgB,CACd,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC,CAAC;CACrB;AAQD,qBAAa,yBAA0B,YAAW,kBAAkB;IAC5D,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC;IAGpC,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC;CAG3C"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DenyAllMembershipResolver = void 0;
4
+ class DenyAllMembershipResolver {
5
+ async hasProjectAccess() {
6
+ return false;
7
+ }
8
+ async hasSessionAccess() {
9
+ return false;
10
+ }
11
+ }
12
+ exports.DenyAllMembershipResolver = DenyAllMembershipResolver;
13
+ //# sourceMappingURL=membership-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"membership-resolver.js","sourceRoot":"","sources":["../../src/lib/membership-resolver.ts"],"names":[],"mappings":";;;AAyDA,MAAa,yBAAyB;IACpC,KAAK,CAAC,gBAAgB;QACpB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,KAAK,CAAC,gBAAgB;QACpB,OAAO,KAAK,CAAC;IACf,CAAC;CACF;AAPD,8DAOC"}
@@ -0,0 +1,17 @@
1
+ import type { ConnectionLifecycleListener } from './connection-lifecycle';
2
+ import type { CallerIdentity, MembershipResolver } from './membership-resolver';
3
+ import type { HubStreamSource } from './hub-stream-source';
4
+ export interface CallerIdentityExtractor {
5
+ fromRequest(req: unknown): CallerIdentity;
6
+ }
7
+ export interface RealtimeStreamModuleOptions {
8
+ membershipResolver: MembershipResolver;
9
+ hubStreamSource: HubStreamSource;
10
+ callerIdentityExtractor: CallerIdentityExtractor;
11
+ heartbeatIntervalMs?: number;
12
+ maxConnectionsPerPod?: number;
13
+ podId?: string;
14
+ initialFromGlobalSeq?: string;
15
+ connectionLifecycleListener?: ConnectionLifecycleListener;
16
+ }
17
+ //# sourceMappingURL=module-options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-options.d.ts","sourceRoot":"","sources":["../../src/lib/module-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,wBAAwB,CAAC;AAC1E,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAQ3D,MAAM,WAAW,uBAAuB;IACtC,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,CAAC;CAC3C;AAED,MAAM,WAAW,2BAA2B;IAE1C,kBAAkB,EAAE,kBAAkB,CAAC;IAEvC,eAAe,EAAE,eAAe,CAAC;IAEjC,uBAAuB,EAAE,uBAAuB,CAAC;IAKjD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAK7B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAK9B,KAAK,CAAC,EAAE,MAAM,CAAC;IAOf,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAQ9B,2BAA2B,CAAC,EAAE,2BAA2B,CAAC;CAC3D"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=module-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-options.js","sourceRoot":"","sources":["../../src/lib/module-options.ts"],"names":[],"mappings":""}
@@ -0,0 +1,57 @@
1
+ import { OnModuleInit, OnModuleDestroy } from '@nestjs/common';
2
+ import { Observable } from 'rxjs';
3
+ import { type CursorMap, type ScopeRef } from './control-frame';
4
+ import type { HubStreamSource } from './hub-stream-source';
5
+ import type { CallerIdentity, MembershipResolver } from './membership-resolver';
6
+ import type { RealtimeStreamModuleOptions } from './module-options';
7
+ export type ConnectionMode = 'unified' | 'session';
8
+ export interface SseFrame {
9
+ readonly type: string;
10
+ readonly id?: string;
11
+ readonly data: unknown;
12
+ }
13
+ interface OpenConnectionInput {
14
+ caller: CallerIdentity;
15
+ initialCursors: CursorMap;
16
+ mode: ConnectionMode;
17
+ dedicatedSessionId?: string;
18
+ }
19
+ export declare class RealtimeFanoutService implements OnModuleInit, OnModuleDestroy {
20
+ private readonly options;
21
+ private readonly membership;
22
+ private readonly hubSource;
23
+ private readonly logger;
24
+ private readonly connections;
25
+ private readonly heartbeatIntervalMs;
26
+ private readonly maxConnections;
27
+ private readonly podId;
28
+ private readonly lifecycleListener;
29
+ private heartbeatTimer;
30
+ private stopHubSource;
31
+ constructor(options: RealtimeStreamModuleOptions, membership: MembershipResolver, hubSource: HubStreamSource);
32
+ onModuleInit(): Promise<void>;
33
+ onModuleDestroy(): void;
34
+ openConnection(input: OpenConnectionInput): {
35
+ connectionId: string;
36
+ stream: Observable<SseFrame>;
37
+ };
38
+ closeConnection(connectionId: string): void;
39
+ addSubscription(connectionId: string, scope: ScopeRef): Promise<void>;
40
+ removeSubscription(connectionId: string, scope: ScopeRef): void;
41
+ onUpstreamEnvelope(envelope: Record<string, unknown>): void;
42
+ onUpstreamResync(): void;
43
+ onUpstreamError(err: Error): void;
44
+ private deliverEnvelope;
45
+ private emitConnected;
46
+ private emitControl;
47
+ private broadcastHeartbeat;
48
+ private fireLifecycle;
49
+ private cursorForScope;
50
+ stats(): {
51
+ podId: string;
52
+ totalConnections: number;
53
+ maxConnections: number;
54
+ };
55
+ }
56
+ export {};
57
+ //# sourceMappingURL=realtime-fanout.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"realtime-fanout.service.d.ts","sourceRoot":"","sources":["../../src/lib/realtime-fanout.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAA8B,YAAY,EAAE,eAAe,EAA+B,MAAM,gBAAgB,CAAC;AACxH,OAAO,EAAW,UAAU,EAAmB,MAAM,MAAM,CAAC;AAK5D,OAAO,EAAkC,KAAK,SAAS,EAAE,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAMhG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,kBAAkB,CAAC;AA6BpE,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,SAAS,CAAC;AAEnD,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACxB;AAED,UAAU,mBAAmB;IAC3B,MAAM,EAAE,cAAc,CAAC;IACvB,cAAc,EAAE,SAAS,CAAC;IAC1B,IAAI,EAAE,cAAc,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,qBACa,qBAAsB,YAAW,YAAY,EAAE,eAAe;IAWtC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAC5B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC7B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAZvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA0C;IACjE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuC;IACnE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA0C;IAC5E,OAAO,CAAC,cAAc,CAA+C;IACrE,OAAO,CAAC,aAAa,CAA6B;gBAGE,OAAO,EAAE,2BAA2B,EACxC,UAAU,EAAE,kBAAkB,EAChC,SAAS,EAAE,eAAe;IAQlE,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAqBnC,eAAe,IAAI,IAAI;IA4BvB,cAAc,CACZ,KAAK,EAAE,mBAAmB,GACzB;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAA;KAAE;IAiDzD,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;IAUrC,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAyC3E,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,IAAI;IAuB/D,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IA8C3D,gBAAgB,IAAI,IAAI;IA0BxB,eAAe,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI;IAyBjC,OAAO,CAAC,eAAe;IAcvB,OAAO,CAAC,aAAa;IAerB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,kBAAkB;IAiB1B,OAAO,CAAC,aAAa;IAqCrB,OAAO,CAAC,cAAc;IAYtB,KAAK,IAAI;QACP,KAAK,EAAE,MAAM,CAAC;QACd,gBAAgB,EAAE,MAAM,CAAC;QACzB,cAAc,EAAE,MAAM,CAAC;KACxB;CAOF"}