cross-tab-worker-databus 0.1.0

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 (59) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/LICENSE +21 -0
  3. package/README.md +185 -0
  4. package/README.zh.md +98 -0
  5. package/dist/centrifuge-protocol.d.ts +77 -0
  6. package/dist/centrifuge-protocol.d.ts.map +1 -0
  7. package/dist/centrifuge-session.d.ts +39 -0
  8. package/dist/centrifuge-session.d.ts.map +1 -0
  9. package/dist/centrifuge.d.ts +135 -0
  10. package/dist/centrifuge.d.ts.map +1 -0
  11. package/dist/centrifuge.js +407 -0
  12. package/dist/centrifuge.js.map +7 -0
  13. package/dist/centrifuge.shared.worker.js +5220 -0
  14. package/dist/centrifuge.shared.worker.js.map +7 -0
  15. package/dist/centrifuge.worker.js +5109 -0
  16. package/dist/centrifuge.worker.js.map +7 -0
  17. package/dist/chunk-GABYBK7I.js +1527 -0
  18. package/dist/chunk-GABYBK7I.js.map +7 -0
  19. package/dist/core/cluster.d.ts +219 -0
  20. package/dist/core/cluster.d.ts.map +1 -0
  21. package/dist/core/data-bus.d.ts +133 -0
  22. package/dist/core/data-bus.d.ts.map +1 -0
  23. package/dist/core/environment.d.ts +67 -0
  24. package/dist/core/environment.d.ts.map +1 -0
  25. package/dist/core/hash.d.ts +11 -0
  26. package/dist/core/hash.d.ts.map +1 -0
  27. package/dist/core/routing.d.ts +42 -0
  28. package/dist/core/routing.d.ts.map +1 -0
  29. package/dist/core/storage-batch.d.ts +35 -0
  30. package/dist/core/storage-batch.d.ts.map +1 -0
  31. package/dist/core/trace.d.ts +126 -0
  32. package/dist/core/trace.d.ts.map +1 -0
  33. package/dist/core/types.d.ts +112 -0
  34. package/dist/core/types.d.ts.map +1 -0
  35. package/dist/index.d.ts +23 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +27 -0
  38. package/dist/index.js.map +7 -0
  39. package/dist/worker-mode.d.ts +25 -0
  40. package/dist/worker-mode.d.ts.map +1 -0
  41. package/dist/workers/centrifuge.shared.worker.d.ts +2 -0
  42. package/dist/workers/centrifuge.shared.worker.d.ts.map +1 -0
  43. package/dist/workers/centrifuge.worker.d.ts +2 -0
  44. package/dist/workers/centrifuge.worker.d.ts.map +1 -0
  45. package/dist/workers/port-reaper.d.ts +52 -0
  46. package/dist/workers/port-reaper.d.ts.map +1 -0
  47. package/docs/README.md +21 -0
  48. package/docs/api.md +261 -0
  49. package/docs/architecture.md +514 -0
  50. package/docs/capabilities.md +41 -0
  51. package/docs/configuration.md +211 -0
  52. package/docs/getting-started.md +161 -0
  53. package/docs/zh/README.md +23 -0
  54. package/docs/zh/api.md +261 -0
  55. package/docs/zh/architecture.md +515 -0
  56. package/docs/zh/capabilities.md +41 -0
  57. package/docs/zh/configuration.md +211 -0
  58. package/docs/zh/getting-started.md +161 -0
  59. package/package.json +71 -0
@@ -0,0 +1,133 @@
1
+ import type { WorkerClusterOptions } from './cluster';
2
+ import type { DataBusErrorHandler, DataBusMessageHandler, DataBusStatusHandler, DataBusTransport, WorkerStatus } from './types';
3
+ import type { DataBusTraceOptions } from './trace';
4
+ export interface CrossTabDataBusOptions<TConfig, TData> extends Omit<WorkerClusterOptions, 'handlers'> {
5
+ transport: DataBusTransport<TConfig, TData>;
6
+ initialConfig?: TConfig;
7
+ autoStart?: boolean;
8
+ trace?: DataBusTraceOptions;
9
+ }
10
+ /**
11
+ * High-level cross-tab pub/sub client.
12
+ *
13
+ * Orchestrates a transport (e.g. Centrifuge WebSocket inside a Worker) and a
14
+ * WorkerClusterRuntime for cross-tab coordination. Messages arriving from the
15
+ * transport are fanned out to all tabs in the cluster and dispatched locally
16
+ * to registered handlers.
17
+ */
18
+ export declare class CrossTabDataBus<TConfig = unknown, TData = unknown> {
19
+ private readonly transport;
20
+ private readonly cluster;
21
+ private readonly topicHandlers;
22
+ private readonly transportSubscribedTopics;
23
+ private readonly statusHandlers;
24
+ private readonly errorHandlers;
25
+ private readonly initialConfig;
26
+ private readonly hasInitialConfig;
27
+ private readonly trace;
28
+ private activeConfig;
29
+ private status;
30
+ private started;
31
+ private stopping;
32
+ private transportReady;
33
+ private lastError;
34
+ private startPromise;
35
+ private lastRecoveryAt;
36
+ private suspended;
37
+ private pendingStop;
38
+ private static readonly RECOVERY_COOLDOWN_MS;
39
+ constructor(options: CrossTabDataBusOptions<TConfig, TData>);
40
+ /**
41
+ * Start the DataBus with the given transport config.
42
+ *
43
+ * The first call starts the cluster and opens the transport. Concurrent calls
44
+ * during an in-flight start return the same promise. Once the operation
45
+ * settles (success or failure) the promise gate is cleared so a subsequent
46
+ * start() or resumeTransport() can open a fresh lifecycle.
47
+ */
48
+ start(config: TConfig): Promise<void>;
49
+ /**
50
+ * Open the transport, chained after `before` to ensure lifecycle ordering.
51
+ * When `stopClusterOnFailure` is true (initial start), a transport failure
52
+ * tears down the cluster as well.
53
+ */
54
+ private openTransport;
55
+ /**
56
+ * Await the DataBus to be fully started (lazy init when using initialConfig).
57
+ * Returns a rejected promise when the transport has failed and no start is in
58
+ * flight — the caller can retry by calling start() or ready() again.
59
+ */
60
+ ready(): Promise<void>;
61
+ /**
62
+ * Register a handler for `topic`. The handler fires on every publication
63
+ * delivered to this tab, regardless of which tab published it. Returns an
64
+ * unsubscribe function for convenience.
65
+ */
66
+ subscribe(topic: string, handler: DataBusMessageHandler<TData>): () => void;
67
+ /** Remove a specific handler, or all handlers for `topic`. */
68
+ unsubscribe(topic: string, handler?: DataBusMessageHandler<TData>): void;
69
+ /** Publish a message to `topic`. The owning Worker delivers it to the transport. */
70
+ publish(topic: string, data: unknown): void;
71
+ /** Register a handler that fires on every transport status change. Immediately invoked with the current status. */
72
+ onStatus(handler: DataBusStatusHandler): () => void;
73
+ /** Register a handler for transport errors. */
74
+ onError(handler: DataBusErrorHandler): () => void;
75
+ /** Current transport connection status. */
76
+ getStatus(): WorkerStatus;
77
+ /** Snapshot of the cluster state (workers, routes, assignments). */
78
+ getClusterSnapshot(): import("./cluster").WorkerClusterSnapshot;
79
+ /**
80
+ * Gracefully stop the DataBus: unsubscribe all topics, stop the cluster,
81
+ * and close the transport. Idempotent.
82
+ */
83
+ stop(): Promise<void>;
84
+ /**
85
+ * Incoming message from the transport.
86
+ * Records metrics, checks ownership via the cluster, broadcasts to other tabs,
87
+ * and dispatches locally.
88
+ */
89
+ private handleTransportMessage;
90
+ /** Deliver a message to every local handler registered for its topic. */
91
+ private dispatch;
92
+ /**
93
+ * Propagate a status change to the cluster, trace, and all registered
94
+ * status handlers. On reconnect, re-subscribe any topics assigned to us.
95
+ */
96
+ private updateStatus;
97
+ private reportError;
98
+ private traceSubscription;
99
+ /** Ask the transport to subscribe to a topic (idempotent). */
100
+ private subscribeTransport;
101
+ private unsubscribeTransport;
102
+ /**
103
+ * Suspend the transport when the tab goes hidden. Stops the transport and
104
+ * clears subscription state so it will be re-established on resume.
105
+ */
106
+ private suspendTransport;
107
+ /**
108
+ * Resume the transport when the tab becomes visible again, or recover from a
109
+ * runtime transport failure. Re-opens the transport with the stored active
110
+ * config, chained after any pending operation so an async transport stop
111
+ * completes before the new start. Returns the opening promise.
112
+ */
113
+ private resumeTransport;
114
+ /**
115
+ * Re-open the transport with the previously stored active config. Chains
116
+ * after any in-flight lifecycle operation (e.g. a suspend stop), swallowing
117
+ * its rejection so the reopen is not blocked. Returns the opening promise so
118
+ * callers can queue operations behind it.
119
+ */
120
+ private reopenTransport;
121
+ /**
122
+ * Run a transport operation now if the transport is ready, otherwise queue
123
+ * it behind the start promise. This ensures subscribe/unsubscribe calls made
124
+ * during startup are not lost.
125
+ */
126
+ private runTransport;
127
+ /**
128
+ * Ensure the DataBus is started, throwing if no initialConfig was provided.
129
+ * Called automatically by subscribe/publish/ready when autoStart is true.
130
+ */
131
+ private ensureStarted;
132
+ }
133
+ //# sourceMappingURL=data-bus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-bus.d.ts","sourceRoot":"","sources":["../../src/core/data-bus.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Browser environment adapters — storage, BroadcastChannel, timers, lifecycle.
3
+ *
4
+ * Separates platform-specific APIs from the core coordination logic so the
5
+ * same Runtime can run in a browser, in a test, or in an embedded context
6
+ * with custom adapters injected via `ClusterEnvironment`.
7
+ */
8
+ import type { TabVisibilityState, WorkerClusterMessage } from './types';
9
+ /** Minimal storage interface compatible with both localStorage and MemoryStorage. */
10
+ export interface StorageLike {
11
+ readonly length: number;
12
+ clear(): void;
13
+ getItem(key: string): string | null;
14
+ key(index: number): string | null;
15
+ removeItem(key: string): void;
16
+ setItem(key: string, value: string): void;
17
+ }
18
+ /** Minimal BroadcastChannel interface. The cluster uses it for control messages and event fan-out. */
19
+ export interface ClusterChannel {
20
+ addEventListener(type: 'message', listener: (event: MessageEvent<WorkerClusterMessage>) => void): void;
21
+ removeEventListener(type: 'message', listener: (event: MessageEvent<WorkerClusterMessage>) => void): void;
22
+ postMessage(message: WorkerClusterMessage): void;
23
+ close(): void;
24
+ }
25
+ /**
26
+ * Environment abstraction that lets the cluster operate in Node, SSR, or
27
+ * test environments without touching browser globals directly.
28
+ * Tests inject a fake environment to control timing, storage, and lifecycle.
29
+ */
30
+ export interface ClusterEnvironment {
31
+ /** localStorage (or null if unavailable). */
32
+ storage: StorageLike | null;
33
+ /** sessionStorage (or null if unavailable). Used for stable tab IDs. */
34
+ sessionStorage: StorageLike | null;
35
+ now: () => number;
36
+ randomId: () => string;
37
+ createChannel: (name: string) => ClusterChannel | null;
38
+ setInterval: (callback: () => void, intervalMs: number) => unknown;
39
+ clearInterval: (handle: unknown) => void;
40
+ getVisibilityState: () => TabVisibilityState;
41
+ addVisibilityChangeListener: (listener: () => void) => void;
42
+ removeVisibilityChangeListener: (listener: () => void) => void;
43
+ addPageHideListener: (listener: () => void) => void;
44
+ removePageHideListener: (listener: () => void) => void;
45
+ addPageShowListener: (listener: () => void) => void;
46
+ removePageShowListener: (listener: () => void) => void;
47
+ }
48
+ /**
49
+ * Default environment adapter for browser runtimes.
50
+ * Probes for localStorage, BroadcastChannel, document, and window APIs
51
+ * and gracefully returns null / no-ops when they are absent (SSR, Node).
52
+ */
53
+ export declare function createBrowserEnvironment(): ClusterEnvironment;
54
+ /**
55
+ * Probe a storage instance with a write-read-delete round-trip.
56
+ * Returns a type guard so the caller can narrow the type after a successful check.
57
+ * Catches quota errors, disabled-storage, or opaque exceptions.
58
+ */
59
+ export declare function canUseStorage(storage: StorageLike | null, probeKey: string): storage is StorageLike;
60
+ /**
61
+ * Get-or-create a stable tab ID stored in sessionStorage.
62
+ * sessionStorage is scoped to the tab and survives refresh, so the same tab
63
+ * retains its identity across the page lifecycle without coordination overhead.
64
+ * Falls back to a random ID when sessionStorage is unavailable.
65
+ */
66
+ export declare function getOrCreateTabId(environment: ClusterEnvironment, key?: string): string;
67
+ //# sourceMappingURL=environment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/core/environment.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAExE,qFAAqF;AACrF,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,KAAK,IAAI,IAAI,CAAC;IACd,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACpC,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAClC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3C;AAED,sGAAsG;AACtG,MAAM,WAAW,cAAc;IAC7B,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,oBAAoB,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACvG,mBAAmB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,oBAAoB,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IAC1G,WAAW,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACjD,KAAK,IAAI,IAAI,CAAC;CACf;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,6CAA6C;IAC7C,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IAC5B,wEAAwE;IACxE,cAAc,EAAE,WAAW,GAAG,IAAI,CAAC;IACnC,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,MAAM,CAAC;IACvB,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,cAAc,GAAG,IAAI,CAAC;IACvD,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;IACnE,aAAa,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;IAC7C,2BAA2B,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAC5D,8BAA8B,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IAC/D,mBAAmB,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACpD,sBAAsB,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACvD,mBAAmB,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACpD,sBAAsB,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;CACxD;AAuBD;;;;GAIG;AACH,wBAAgB,wBAAwB,IAAI,kBAAkB,CAoC7D;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,IAAI,WAAW,CASnG;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,kBAAkB,EAC/B,GAAG,SAAoC,GACtC,MAAM,CAqBR"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Derives a stable 128-bit hex key from a string.
3
+ *
4
+ * This is a non-cryptographic four-way hash (inspired by MurmurHash-style
5
+ * mixing). It exists so connection URLs and topic plaintext never touch
6
+ * localStorage or BroadcastChannel namespaces — consumers only ever see the
7
+ * opaque key. It trades collision resistance for speed and zero dependencies:
8
+ * use `crypto.subtle.digest` if you need a cryptographic hash.
9
+ */
10
+ export declare function createOpaqueKey(value: string): string;
11
+ //# sourceMappingURL=hash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/core/hash.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAyBrD"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Routing primitives for topic-owner selection and rebalancing.
3
+ *
4
+ * Pure functions that select candidate Workers, compute the least-loaded
5
+ * owner, and decide when to migrate a topic. All side-effect-free, making
6
+ * them straightforward to test and reason about.
7
+ */
8
+ import type { WorkerRecord, WorkerRoute } from './types';
9
+ /** Default cap on the number of Workers that can own topics concurrently. */
10
+ export declare const DEFAULT_MAX_ACTIVE_WORKERS = 3;
11
+ /**
12
+ * Pick the Worker with the fewest owned topics, optionally preferring a
13
+ * specific sticky owner when it is still in the candidate set.
14
+ * Uses a single reduce pass instead of a full sort — O(n) — and breaks
15
+ * load ties by workerId for deterministic routing across tabs.
16
+ */
17
+ export declare function selectLeastLoadedWorker(workers: readonly WorkerRecord[], preferredWorkerId?: string): WorkerRecord | undefined;
18
+ /**
19
+ * Select the (up to `maxActiveWorkers`) Workers eligible to own topics.
20
+ *
21
+ * Eligibility cascade:
22
+ * 1. Only `connecting` / `connected` workers are candidates.
23
+ * 2. If any candidate is visible, prefer visible tabs (hidden tabs yield as owner).
24
+ * 3. Fall back to all available workers when none is visible, so the cluster
25
+ * does not stall when every tab is in the background.
26
+ * 4. Tie-break by registration time, then workerId, for determinism.
27
+ */
28
+ export declare function selectActiveWorkers(workers: readonly WorkerRecord[], maxActiveWorkers?: number): WorkerRecord[];
29
+ /**
30
+ * Decide whether `currentWorkerId` should hand one topic to a less-loaded peer.
31
+ * Returns the target Worker only when its load gap is significant (more than
32
+ * one topic lighter), so the cluster does not churn over a single-topic
33
+ * imbalance. One topic is migrated per reconciliation round to avoid thrashing.
34
+ *
35
+ * This remains exported as a standalone routing utility for API compatibility.
36
+ * WorkerClusterRuntime intentionally does not use it: established routes are
37
+ * sticky and load balancing applies only when selecting a new owner.
38
+ */
39
+ export declare function selectRebalanceTarget(workers: readonly WorkerRecord[], currentWorkerId: string): WorkerRecord | null;
40
+ /** True when a route's owner is still a live, active Worker in the given set. */
41
+ export declare function hasActiveOwner(route: WorkerRoute | null, workers: readonly WorkerRecord[]): boolean;
42
+ //# sourceMappingURL=routing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../../src/core/routing.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEzD,6EAA6E;AAC7E,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAE5C;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,iBAAiB,CAAC,EAAE,MAAM,GACzB,YAAY,GAAG,SAAS,CAS1B;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,gBAAgB,SAA6B,GAC5C,YAAY,EAAE,CAWhB;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,SAAS,YAAY,EAAE,EAChC,eAAe,EAAE,MAAM,GACtB,YAAY,GAAG,IAAI,CAYrB;AAED,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,EAAE,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,OAAO,CAEnG"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * BatchingStorageWriter — coalesced, resilient localStorage writes.
3
+ *
4
+ * Decorates a StorageLike with write coalescing: mutations within the same task
5
+ * are merged by key and flushed once via a microtask, with exponential backoff
6
+ * on quota/failure. Keeps the coordination metadata writes off the hot path.
7
+ */
8
+ import type { StorageLike } from './environment';
9
+ /**
10
+ * Coalesces synchronous storage writes and applies them in one pass, with
11
+ * exponential backoff when the underlying storage rejects a write.
12
+ */
13
+ export declare class BatchingStorageWriter implements StorageLike {
14
+ private readonly storage;
15
+ /** Coalesced write set. A `null` value represents a pending delete. */
16
+ private readonly pending;
17
+ private flushScheduled;
18
+ private retryHandle;
19
+ private retryDelayMs;
20
+ constructor(storage: StorageLike);
21
+ get pendingSize(): number;
22
+ get length(): number;
23
+ clear(): void;
24
+ getItem(key: string): string | null;
25
+ key(index: number): string | null;
26
+ removeItem(key: string): void;
27
+ setItem(key: string, value: string): void;
28
+ flush(): void;
29
+ /** Union of persisted keys and pending writes, minus pending deletes. */
30
+ private keys;
31
+ private scheduleFlush;
32
+ private scheduleRetry;
33
+ private cancelRetry;
34
+ }
35
+ //# sourceMappingURL=storage-batch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-batch.d.ts","sourceRoot":"","sources":["../../src/core/storage-batch.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAKjD;;;GAGG;AACH,qBAAa,qBAAsB,YAAW,WAAW;IAO3C,OAAO,CAAC,QAAQ,CAAC,OAAO;IANpC,uEAAuE;IACvE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoC;IAC5D,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,WAAW,CAA8C;IACjE,OAAO,CAAC,YAAY,CAA0B;gBAEjB,OAAO,EAAE,WAAW;IAEjD,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,KAAK,IAAI,IAAI;IAYb,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAKnC,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAIjC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAK7B,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAKzC,KAAK,IAAI,IAAI;IAoBb,yEAAyE;IACzE,OAAO,CAAC,IAAI;IAeZ,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,WAAW;CAMpB"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * DataBusTraceReporter — optional diagnostics, metrics, and delivery latency.
3
+ *
4
+ * Aggregates message throughput and dispatch latency over configurable windows,
5
+ * emitting structured events (lifecycle, status, subscription, coordination,
6
+ * error) and periodic metrics summaries. The sink is decoupled from the hot
7
+ * message path — errors in the sink are isolated to console.warn.
8
+ */
9
+ import type { WorkerStatus } from './types';
10
+ /** Trace reporting mode: record only events, only metrics, or both. */
11
+ export type DataBusTraceMode = 'events' | 'metrics' | 'all';
12
+ /** Emitted when the DataBus starts, stops, suspends, or resumes. */
13
+ export interface DataBusLifecycleTraceEvent {
14
+ type: 'lifecycle';
15
+ action: 'start' | 'stop' | 'suspend' | 'resume';
16
+ timestamp: number;
17
+ }
18
+ /** Emitted when the transport connection status changes. */
19
+ export interface DataBusStatusTraceEvent {
20
+ type: 'status';
21
+ status: WorkerStatus;
22
+ timestamp: number;
23
+ }
24
+ /** Emitted when a topic subscription is added or removed. */
25
+ export interface DataBusSubscriptionTraceEvent {
26
+ type: 'subscription';
27
+ action: 'subscribe' | 'unsubscribe';
28
+ topic: string;
29
+ activeTopics: number;
30
+ timestamp: number;
31
+ }
32
+ /** Emitted on each reconciliation round to record whether the cluster coordinated. */
33
+ export interface DataBusCoordinationTraceEvent {
34
+ type: 'coordination';
35
+ coordinated: boolean;
36
+ activeWorkers: number;
37
+ workers: string[];
38
+ routes: string[];
39
+ timestamp: number;
40
+ }
41
+ /** Emitted when a transport or operation error occurs. */
42
+ export interface DataBusErrorTraceEvent {
43
+ type: 'error';
44
+ source: 'transport' | 'operation';
45
+ timestamp: number;
46
+ }
47
+ /**
48
+ * Periodic metrics snapshot: message throughput, dispatch latency percentiles,
49
+ * and active topic count. Aggregated over the interval and emitted every
50
+ * `metricsIntervalMs`.
51
+ */
52
+ export interface DataBusMetricsTraceEvent {
53
+ type: 'message_metrics';
54
+ durationMs: number;
55
+ received: number;
56
+ dispatched: number;
57
+ topics: number;
58
+ dispatchSamples: number;
59
+ dispatchAvgMs: number;
60
+ dispatchP50Ms: number;
61
+ dispatchP95Ms: number;
62
+ dispatchMaxMs: number;
63
+ timestamp: number;
64
+ }
65
+ export type DataBusTraceEvent = DataBusLifecycleTraceEvent | DataBusStatusTraceEvent | DataBusSubscriptionTraceEvent | DataBusCoordinationTraceEvent | DataBusErrorTraceEvent | DataBusMetricsTraceEvent;
66
+ /** Distributive-conditional type: given a trace event union, derive the same shape minus `timestamp`. */
67
+ type DataBusTraceEventInput = DataBusTraceEvent extends infer TEvent ? TEvent extends DataBusTraceEvent ? Omit<TEvent, 'timestamp'> : never : never;
68
+ export interface DataBusTraceOptions {
69
+ enabled?: boolean;
70
+ mode?: DataBusTraceMode;
71
+ metricsIntervalMs?: number;
72
+ sink: (event: DataBusTraceEvent) => void;
73
+ }
74
+ /**
75
+ * Aggregates DataBus diagnostics — lifecycle events, status changes, and
76
+ * periodic latency histograms — and forwards them to a user-supplied sink.
77
+ *
78
+ * Latency is measured in a bucketed histogram (20 buckets × 50ms) rather than
79
+ * storing every sample, keeping memory bounded even under high throughput.
80
+ */
81
+ export declare class DataBusTraceReporter {
82
+ private readonly enabled;
83
+ private readonly mode;
84
+ private readonly metricsIntervalMs;
85
+ private readonly sink;
86
+ private readonly now;
87
+ private intervalHandle;
88
+ private intervalStartedAt;
89
+ private received;
90
+ private dispatched;
91
+ private latencySamples;
92
+ private readonly topics;
93
+ private readonly receivedAt;
94
+ private readonly latencyBuckets;
95
+ private latencySumMs;
96
+ constructor(options?: DataBusTraceOptions, now?: () => number);
97
+ /** Start the periodic metrics flush interval. No-op when mode is 'events'. */
98
+ start(): void;
99
+ /** Pause the metrics interval and reset accumulated counters. */
100
+ pause(): void;
101
+ stop(): void;
102
+ /** Record an instantaneous trace event (lifecycle, status, error, etc.). */
103
+ event(event: DataBusTraceEventInput): void;
104
+ /** Record that a message was received on `topic`; stores its timestamp for latency tracking. */
105
+ recordReceived(topic: string): void;
106
+ /**
107
+ * Record that a received message will never be dispatched locally. Pops the
108
+ * matching FIFO slot so a later dispatch on the same topic does not pair
109
+ * with a stale receive timestamp.
110
+ */
111
+ recordDiscarded(topic: string): void;
112
+ /**
113
+ * Record that a message was dispatched on `topic`. Pops the oldest receive
114
+ * timestamp (FIFO) and increments the latency histogram. Dispatches without
115
+ * a matching receive (e.g. broadcast fan-out from another tab) still count
116
+ * as dispatched but do not produce a latency sample.
117
+ */
118
+ recordDispatched(topic: string): void;
119
+ /** Emit the accumulated metrics snapshot if the interval is active. */
120
+ flush(): void;
121
+ private flushNow;
122
+ private resetMetrics;
123
+ private emit;
124
+ }
125
+ export {};
126
+ //# sourceMappingURL=trace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace.d.ts","sourceRoot":"","sources":["../../src/core/trace.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Core type definitions for the cross-tab DataBus.
3
+ *
4
+ * Defines the shapes of Worker records, topic routes, control messages,
5
+ * transport interfaces, trace events, and all supporting types used across
6
+ * the cluster coordination, DataBus public API, and diagnostics layers.
7
+ */
8
+ /** Convenience alias for values that may be synchronously returned or Promise. */
9
+ export type MaybePromise<T> = T | Promise<T>;
10
+ /** Whether this Worker can act as a Topic owner. */
11
+ export type WorkerRole = 'active' | 'standby';
12
+ /** Connection-level status of the transport. */
13
+ export type WorkerStatus = 'connecting' | 'connected' | 'disconnected' | 'error';
14
+ /** Control-plane actions routed between Workers via BroadcastChannel. */
15
+ export type WorkerControlAction = 'SUBSCRIBE' | 'UNSUBSCRIBE' | 'PUBLISH';
16
+ /** Whether the tab is currently visible to the user. */
17
+ export type TabVisibilityState = 'visible' | 'hidden';
18
+ /**
19
+ * A Worker's self-published registration record, written to localStorage
20
+ * so sibling tabs can discover and route to it.
21
+ */
22
+ export interface WorkerRecord {
23
+ workerId: string;
24
+ tabId: string;
25
+ /** Number of topics this Worker owns. Not a CPU load. */
26
+ load: number;
27
+ role: WorkerRole;
28
+ status: WorkerStatus;
29
+ visibilityState: TabVisibilityState;
30
+ /** Last heartbeat write timestamp (ms). */
31
+ heartbeatAt: number;
32
+ /** First registration timestamp (ms). Used for deterministic ordering. */
33
+ registeredAt: number;
34
+ }
35
+ /**
36
+ * A topic-to-Worker mapping stored in localStorage. The route is written
37
+ * by the subscriber's Runtime and confirmed by the owner once it processes
38
+ * the SUBSCRIBE control message.
39
+ */
40
+ export interface WorkerRoute {
41
+ topicKey: string;
42
+ workerId: string;
43
+ tabId: string;
44
+ updatedAt: number;
45
+ /** Monotonic route generation; handoff acknowledgements must match it. */
46
+ generation: number;
47
+ /** Previous owner must release its transport subscription before takeover. */
48
+ handoffFromWorkerId?: string;
49
+ /** Set by the owner when it has processed the SUBSCRIBE. Absent → subscriber will retry. */
50
+ confirmedAt?: number;
51
+ }
52
+ /** Per-tab-per-topic marker stored in localStorage so the cluster knows which tabs still need a topic. */
53
+ export interface TopicSubscriberRecord {
54
+ tabId: string;
55
+ updatedAt: number;
56
+ }
57
+ /**
58
+ * Messages exchanged over the BroadcastChannel. Three types:
59
+ * - CONTROL: direct peer-to-peer actions (SUBSCRIBE / UNSUBSCRIBE / PUBLISH)
60
+ * - EVENT: fan-out publications from the owning Worker to all tabs
61
+ * - REGISTRY: heartbeat signal that triggers reconciliation on other tabs
62
+ */
63
+ export type WorkerClusterMessage<TEvent = unknown> = {
64
+ type: 'CONTROL';
65
+ sourceWorkerId: string;
66
+ targetWorkerId: string;
67
+ action: WorkerControlAction;
68
+ topic: string;
69
+ topicKey: string;
70
+ data?: unknown;
71
+ } | {
72
+ type: 'EVENT';
73
+ sourceWorkerId: string;
74
+ eventType: string;
75
+ payload: TEvent;
76
+ } | {
77
+ type: 'REGISTRY';
78
+ sourceWorkerId: string;
79
+ } | {
80
+ type: 'ROUTE_RELEASED';
81
+ sourceWorkerId: string;
82
+ targetWorkerId: string;
83
+ topic: string;
84
+ topicKey: string;
85
+ generation: number;
86
+ };
87
+ export interface DataBusMessage<TData = unknown> {
88
+ topic: string;
89
+ data: TData;
90
+ }
91
+ /** Callbacks the transport calls to notify the DataBus of events. */
92
+ export interface DataBusTransportHandlers<TData = unknown> {
93
+ onMessage: (message: DataBusMessage<TData>) => void;
94
+ onStatus: (status: WorkerStatus) => void;
95
+ onError: (error: unknown) => void;
96
+ }
97
+ /**
98
+ * Transport abstraction that the DataBus delegates to for real I/O.
99
+ * Implementations may wrap a WebSocket library, a Worker, or a mock.
100
+ * subscribe / unsubscribe MUST be idempotent.
101
+ */
102
+ export interface DataBusTransport<TConfig = unknown, TData = unknown> {
103
+ start(config: TConfig, handlers: DataBusTransportHandlers<TData>): MaybePromise<void>;
104
+ subscribe(topic: string): MaybePromise<void>;
105
+ unsubscribe(topic: string): MaybePromise<void>;
106
+ publish(topic: string, data: unknown): MaybePromise<void>;
107
+ stop(): MaybePromise<void>;
108
+ }
109
+ export type DataBusMessageHandler<TData = unknown> = (message: DataBusMessage<TData>) => void;
110
+ export type DataBusStatusHandler = (status: WorkerStatus) => void;
111
+ export type DataBusErrorHandler = (error: unknown) => void;
112
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * cross-tab-worker-databus — public API barrel export.
3
+ *
4
+ * Re-exports every type and class consumers need from the library's
5
+ * internal modules. Consumers import from the package root:
6
+ *
7
+ * ```ts
8
+ * import { CrossTabDataBus, createOpaqueKey } from 'cross-tab-worker-databus';
9
+ * ```
10
+ */
11
+ export { CrossTabDataBus } from './core/data-bus';
12
+ export type { CrossTabDataBusOptions } from './core/data-bus';
13
+ export type { DataBusCoordinationTraceEvent, DataBusErrorTraceEvent, DataBusLifecycleTraceEvent, DataBusMetricsTraceEvent, DataBusStatusTraceEvent, DataBusSubscriptionTraceEvent, DataBusTraceEvent, DataBusTraceMode, DataBusTraceOptions } from './core/trace';
14
+ export { WorkerClusterRuntime } from './core/cluster';
15
+ export type { WorkerClusterHandlers, WorkerClusterOptions, WorkerClusterSnapshot } from './core/cluster';
16
+ export { createBrowserEnvironment, getOrCreateTabId } from './core/environment';
17
+ export type { ClusterChannel, ClusterEnvironment, StorageLike } from './core/environment';
18
+ export { createOpaqueKey } from './core/hash';
19
+ export { selectWorkerBackend } from './worker-mode';
20
+ export type { WorkerBackend, WorkerMode } from './worker-mode';
21
+ export { DEFAULT_MAX_ACTIVE_WORKERS, hasActiveOwner, selectActiveWorkers, selectLeastLoadedWorker, selectRebalanceTarget } from './core/routing';
22
+ export type { DataBusErrorHandler, DataBusMessage, DataBusMessageHandler, DataBusStatusHandler, DataBusTransport, DataBusTransportHandlers, MaybePromise, TabVisibilityState, TopicSubscriberRecord, WorkerClusterMessage, WorkerControlAction, WorkerRecord, WorkerRole, WorkerRoute, WorkerStatus } from './core/types';
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,YAAY,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAC9D,YAAY,EACV,6BAA6B,EAC7B,sBAAsB,EACtB,0BAA0B,EAC1B,wBAAwB,EACxB,uBAAuB,EACvB,6BAA6B,EAC7B,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,EACpB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,YAAY,EACV,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAChF,YAAY,EAAE,cAAc,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EACL,0BAA0B,EAC1B,cAAc,EACd,mBAAmB,EACnB,uBAAuB,EACvB,qBAAqB,EACtB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,mBAAmB,EACnB,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACpB,gBAAgB,EAChB,wBAAwB,EACxB,YAAY,EACZ,kBAAkB,EAClB,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,YAAY,EACZ,UAAU,EACV,WAAW,EACX,YAAY,EACb,MAAM,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,27 @@
1
+ import {
2
+ CrossTabDataBus,
3
+ DEFAULT_MAX_ACTIVE_WORKERS,
4
+ WorkerClusterRuntime,
5
+ createBrowserEnvironment,
6
+ createOpaqueKey,
7
+ getOrCreateTabId,
8
+ hasActiveOwner,
9
+ selectActiveWorkers,
10
+ selectLeastLoadedWorker,
11
+ selectRebalanceTarget,
12
+ selectWorkerBackend
13
+ } from "./chunk-GABYBK7I.js";
14
+ export {
15
+ CrossTabDataBus,
16
+ DEFAULT_MAX_ACTIVE_WORKERS,
17
+ WorkerClusterRuntime,
18
+ createBrowserEnvironment,
19
+ createOpaqueKey,
20
+ getOrCreateTabId,
21
+ hasActiveOwner,
22
+ selectActiveWorkers,
23
+ selectLeastLoadedWorker,
24
+ selectRebalanceTarget,
25
+ selectWorkerBackend
26
+ };
27
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": [],
4
+ "sourcesContent": [],
5
+ "mappings": "",
6
+ "names": []
7
+ }