cross-tab-worker-databus 0.20.71 → 0.20.85

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 (95) hide show
  1. package/CHANGELOG.md +204 -2
  2. package/README.md +8 -0
  3. package/README.zh.md +4 -0
  4. package/dist/centrifuge-protocol.d.ts +59 -26
  5. package/dist/centrifuge-protocol.d.ts.map +1 -1
  6. package/dist/centrifuge-session.d.ts +9 -0
  7. package/dist/centrifuge-session.d.ts.map +1 -1
  8. package/dist/centrifuge.d.ts +12 -2
  9. package/dist/centrifuge.d.ts.map +1 -1
  10. package/dist/centrifuge.js +168 -88
  11. package/dist/centrifuge.js.map +3 -3
  12. package/dist/centrifuge.shared.worker.js +146 -38
  13. package/dist/centrifuge.shared.worker.js.map +3 -3
  14. package/dist/centrifuge.worker.js +140 -33
  15. package/dist/centrifuge.worker.js.map +3 -3
  16. package/dist/{chunk-D2SIT473.js → chunk-PW63EWIK.js} +1090 -494
  17. package/dist/chunk-PW63EWIK.js.map +7 -0
  18. package/dist/chunk-TZ7ZP7YD.js +175 -0
  19. package/dist/chunk-TZ7ZP7YD.js.map +7 -0
  20. package/dist/cjs/centrifuge.cjs +1403 -637
  21. package/dist/cjs/centrifuge.cjs.map +4 -4
  22. package/dist/cjs/hooks.cjs +37 -2
  23. package/dist/cjs/hooks.cjs.map +3 -3
  24. package/dist/cjs/index.cjs +1453 -730
  25. package/dist/cjs/index.cjs.map +4 -4
  26. package/dist/cjs/vue.cjs +45 -2
  27. package/dist/cjs/vue.cjs.map +3 -3
  28. package/dist/core/cluster.d.ts +40 -4
  29. package/dist/core/cluster.d.ts.map +1 -1
  30. package/dist/core/data-bus.d.ts +93 -69
  31. package/dist/core/data-bus.d.ts.map +1 -1
  32. package/dist/core/dedup-manager.d.ts +98 -0
  33. package/dist/core/dedup-manager.d.ts.map +1 -0
  34. package/dist/core/environment.d.ts +43 -3
  35. package/dist/core/environment.d.ts.map +1 -1
  36. package/dist/core/replay-manager.d.ts +128 -0
  37. package/dist/core/replay-manager.d.ts.map +1 -0
  38. package/dist/core/replay-persistence.d.ts +2 -1
  39. package/dist/core/replay-persistence.d.ts.map +1 -1
  40. package/dist/core/routing.d.ts +22 -3
  41. package/dist/core/routing.d.ts.map +1 -1
  42. package/dist/core/storage-batch.d.ts +0 -4
  43. package/dist/core/storage-batch.d.ts.map +1 -1
  44. package/dist/core/trace.d.ts +55 -15
  45. package/dist/core/trace.d.ts.map +1 -1
  46. package/dist/core/types.d.ts +58 -9
  47. package/dist/core/types.d.ts.map +1 -1
  48. package/dist/core/version.d.ts +2 -0
  49. package/dist/core/version.d.ts.map +1 -0
  50. package/dist/hooks.d.ts +12 -1
  51. package/dist/hooks.d.ts.map +1 -1
  52. package/dist/hooks.js +28 -2
  53. package/dist/hooks.js.map +2 -2
  54. package/dist/index.d.ts +6 -6
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js +228 -162
  57. package/dist/index.js.map +3 -3
  58. package/dist/utils/constants.d.ts +170 -0
  59. package/dist/utils/constants.d.ts.map +1 -0
  60. package/dist/utils/error-utils.d.ts +28 -0
  61. package/dist/utils/error-utils.d.ts.map +1 -0
  62. package/dist/utils/metadata.d.ts +16 -0
  63. package/dist/utils/metadata.d.ts.map +1 -0
  64. package/dist/utils/storage-utils.d.ts +24 -0
  65. package/dist/utils/storage-utils.d.ts.map +1 -0
  66. package/dist/utils/validation.d.ts +76 -0
  67. package/dist/utils/validation.d.ts.map +1 -0
  68. package/dist/vue.d.ts +13 -1
  69. package/dist/vue.d.ts.map +1 -1
  70. package/dist/vue.js +36 -2
  71. package/dist/vue.js.map +2 -2
  72. package/dist/websocket.d.ts +6 -1
  73. package/dist/websocket.d.ts.map +1 -1
  74. package/dist/worker-mode.d.ts +6 -2
  75. package/dist/worker-mode.d.ts.map +1 -1
  76. package/docs/README.md +1 -0
  77. package/docs/api.md +122 -2
  78. package/docs/architecture.md +80 -0
  79. package/docs/benchmarks.md +24 -0
  80. package/docs/capabilities.md +24 -3
  81. package/docs/configuration.md +58 -0
  82. package/docs/getting-started.md +35 -0
  83. package/docs/release-checklist.md +28 -5
  84. package/docs/roadmap.md +74 -5
  85. package/docs/zh/README.md +2 -1
  86. package/docs/zh/api.md +121 -2
  87. package/docs/zh/architecture.md +49 -0
  88. package/docs/zh/benchmarks.md +24 -0
  89. package/docs/zh/capabilities.md +21 -3
  90. package/docs/zh/configuration.md +53 -0
  91. package/docs/zh/getting-started.md +35 -0
  92. package/docs/zh/release-checklist.md +29 -6
  93. package/docs/zh/roadmap.md +86 -5
  94. package/package.json +39 -16
  95. package/dist/chunk-D2SIT473.js.map +0 -7
@@ -1,54 +1,119 @@
1
1
  import {
2
2
  CrossTabDataBus,
3
+ assertHeartbeatInterval,
4
+ assertStructuredCloneable,
3
5
  parseDataBusPublication,
6
+ publicationMetadata,
4
7
  selectWorkerBackend
5
- } from "./chunk-D2SIT473.js";
8
+ } from "./chunk-PW63EWIK.js";
9
+ import {
10
+ CENTRIFUGE_INPUT_TYPE,
11
+ CENTRIFUGE_OUTPUT_TYPE,
12
+ DEFAULT_STORAGE_PREFIX,
13
+ WORKER_BACKEND,
14
+ WORKER_MODE,
15
+ WORKER_STATUS
16
+ } from "./chunk-TZ7ZP7YD.js";
6
17
 
7
18
  // src/centrifuge-session.ts
8
19
  import { Centrifuge } from "centrifuge";
20
+
21
+ // src/utils/error-utils.ts
22
+ function serializeError(error) {
23
+ if (error instanceof Error) {
24
+ return {
25
+ name: error.name,
26
+ message: error.message,
27
+ ...error.stack ? { stack: error.stack } : {}
28
+ };
29
+ }
30
+ const context = error === void 0 ? void 0 : error;
31
+ return {
32
+ name: "CentrifugeError",
33
+ message: typeof error === "string" ? error : "Centrifuge worker operation failed.",
34
+ ...context === void 0 || !isStructuredCloneable(context) ? {} : { context }
35
+ };
36
+ }
37
+ function isStructuredCloneable(value) {
38
+ if (typeof structuredClone !== "function") return true;
39
+ try {
40
+ structuredClone(value);
41
+ return true;
42
+ } catch {
43
+ return false;
44
+ }
45
+ }
46
+ function deserializeWorkerError(error) {
47
+ const result = new Error(error.message);
48
+ result.name = error.name;
49
+ if (error.stack) result.stack = error.stack;
50
+ if (error.context !== void 0) Object.assign(result, { context: error.context });
51
+ return result;
52
+ }
53
+
54
+ // src/centrifuge-session.ts
9
55
  var CentrifugeSession = class {
10
56
  constructor(sink) {
11
57
  this.sink = sink;
12
58
  }
59
+ sink;
13
60
  client = null;
14
61
  subscriptions = /* @__PURE__ */ new Map();
15
62
  transferable = false;
63
+ tokenBridge = false;
64
+ nextRequestId = 1;
65
+ pendingTokenRequests = /* @__PURE__ */ new Map();
16
66
  /** Dispatch an incoming Worker message to the matching operation.
17
67
  * Unknown message types are ignored rather than thrown, so a future protocol
18
68
  * extension adding a new variant cannot crash an older session. */
19
69
  handle(message) {
20
70
  switch (message.type) {
21
- case "INIT":
22
- this.initialize(message.url, message.config, message.transferable === true);
71
+ case CENTRIFUGE_INPUT_TYPE.INIT:
72
+ this.initialize(message.url, message.config, message.transferable === true, message.tokenBridge === true);
23
73
  return;
24
- case "SUBSCRIBE":
74
+ case CENTRIFUGE_INPUT_TYPE.SUBSCRIBE:
25
75
  this.subscribe(message.topic);
26
76
  return;
27
- case "UNSUBSCRIBE":
77
+ case CENTRIFUGE_INPUT_TYPE.UNSUBSCRIBE:
28
78
  this.unsubscribe(message.topic);
29
79
  return;
30
- case "PUBLISH":
31
- case "PUBLISH_BIN":
80
+ case CENTRIFUGE_INPUT_TYPE.PUBLISH:
81
+ case CENTRIFUGE_INPUT_TYPE.PUBLISH_BIN:
32
82
  this.publish(message.topic, message.data, message.messageId, message.timestamp);
33
83
  return;
34
- case "STOP":
84
+ case CENTRIFUGE_INPUT_TYPE.STOP:
35
85
  this.stop();
36
86
  return;
87
+ case CENTRIFUGE_INPUT_TYPE.TOKEN_RESPONSE:
88
+ this.resolveToken(message.requestId, message.token);
89
+ return;
90
+ case CENTRIFUGE_INPUT_TYPE.TOKEN_ERROR:
91
+ this.rejectToken(message.requestId, deserializeWorkerError(message.error));
92
+ return;
37
93
  default:
38
94
  return;
39
95
  }
40
96
  }
41
97
  /** Create the Centrifuge client, wire up lifecycle listeners, and connect. */
42
- initialize(url, config, transferable) {
98
+ initialize(url, config, transferable, tokenBridge) {
43
99
  if (this.client) return;
44
100
  this.transferable = transferable;
45
- const client = new Centrifuge(url, config);
101
+ this.tokenBridge = tokenBridge;
102
+ const clientOptions = tokenBridge ? {
103
+ ...config,
104
+ // Route credential fetches back to the main thread, where the
105
+ // application's credentialProvider lives (config must stay
106
+ // structured-cloneable, so functions cannot cross the boundary).
107
+ getToken: () => this.requestToken("token"),
108
+ getChannelToken: (channel) => this.requestToken("channelToken", channel)
109
+ } : config;
110
+ const client = new Centrifuge(url, clientOptions);
46
111
  this.client = client;
47
112
  client.on("state", (context) => {
48
- this.post({ type: "STATUS", status: normalizeStatus(context.newState) });
113
+ this.post({ type: CENTRIFUGE_OUTPUT_TYPE.STATUS, status: normalizeStatus(context.newState) });
49
114
  });
50
- client.on("connected", () => this.post({ type: "STATUS", status: "connected" }));
51
- client.on("disconnected", () => this.post({ type: "STATUS", status: "disconnected" }));
115
+ client.on("connected", () => this.post({ type: CENTRIFUGE_OUTPUT_TYPE.STATUS, status: WORKER_STATUS.CONNECTED }));
116
+ client.on("disconnected", () => this.post({ type: CENTRIFUGE_OUTPUT_TYPE.STATUS, status: WORKER_STATUS.DISCONNECTED }));
52
117
  client.on("error", (context) => this.postError(context));
53
118
  client.on("publication", (context) => {
54
119
  const topic = context.channel || getPayloadTopic(context.data);
@@ -111,25 +176,56 @@ var CentrifugeSession = class {
111
176
  postPublication(topic, data) {
112
177
  if (!topic) return;
113
178
  if (this.transferable && data instanceof ArrayBuffer) {
114
- this.post({ type: "MESSAGE_BIN", topic, data }, [data]);
179
+ this.post({ type: CENTRIFUGE_OUTPUT_TYPE.MESSAGE_BIN, topic, data }, [data]);
115
180
  return;
116
181
  }
117
182
  const publication = parseDataBusPublication(data, topic);
118
183
  if (!publication) return;
119
184
  this.post({
120
- type: "MESSAGE",
185
+ type: CENTRIFUGE_OUTPUT_TYPE.MESSAGE,
121
186
  topic: publication.topic,
122
187
  data: publication.data,
123
- ...publication.messageId === void 0 ? {} : { messageId: publication.messageId },
124
- ...publication.timestamp === void 0 ? {} : { timestamp: publication.timestamp }
188
+ ...publicationMetadata(publication.messageId, publication.timestamp)
125
189
  });
126
190
  }
127
191
  /** Disconnect the client and clear all subscriptions. */
128
192
  stop() {
193
+ for (const [, pending] of this.pendingTokenRequests) {
194
+ pending.reject(new Error("Centrifuge session stopped before the credential was resolved."));
195
+ }
196
+ this.pendingTokenRequests.clear();
129
197
  this.client?.disconnect();
130
198
  this.subscriptions.clear();
131
199
  this.client = null;
132
- this.post({ type: "STATUS", status: "disconnected" });
200
+ this.post({ type: CENTRIFUGE_OUTPUT_TYPE.STATUS, status: WORKER_STATUS.DISCONNECTED });
201
+ }
202
+ /** Issue a credential request to the main thread and await the response.
203
+ * Used as Centrifuge's `getToken` / `getChannelToken` when token bridging is
204
+ * enabled; resolved or rejected by a matching TOKEN_RESPONSE / TOKEN_ERROR. */
205
+ requestToken(kind, channel) {
206
+ const requestId = this.nextRequestId;
207
+ this.nextRequestId += 1;
208
+ return new Promise((resolve, reject) => {
209
+ this.pendingTokenRequests.set(requestId, { resolve, reject });
210
+ this.post({
211
+ type: CENTRIFUGE_OUTPUT_TYPE.TOKEN_REQUEST,
212
+ requestId,
213
+ kind,
214
+ ...channel === void 0 ? {} : { channel }
215
+ });
216
+ });
217
+ }
218
+ resolveToken(requestId, token) {
219
+ const pending = this.pendingTokenRequests.get(requestId);
220
+ if (!pending) return;
221
+ this.pendingTokenRequests.delete(requestId);
222
+ pending.resolve(token);
223
+ }
224
+ rejectToken(requestId, error) {
225
+ const pending = this.pendingTokenRequests.get(requestId);
226
+ if (!pending) return;
227
+ this.pendingTokenRequests.delete(requestId);
228
+ pending.reject(error);
133
229
  }
134
230
  /** Forward a message to the sink (the transport layer). */
135
231
  post(message, transfer) {
@@ -141,7 +237,7 @@ var CentrifugeSession = class {
141
237
  * Fatal errors are distinguished by the client eventually emitting
142
238
  * `disconnected` without a subsequent `connected`. */
143
239
  postError(error) {
144
- this.post({ type: "ERROR", error: serializeError(error) });
240
+ this.post({ type: CENTRIFUGE_OUTPUT_TYPE.ERROR, error: serializeError(error) });
145
241
  }
146
242
  };
147
243
  function getPayloadTopic(data) {
@@ -152,24 +248,10 @@ function getPayloadTopic(data) {
152
248
  const topic = nested ?? payload.channel;
153
249
  return typeof topic === "string" ? topic : "";
154
250
  }
155
- var LIVE_STATES = /* @__PURE__ */ new Set(["connecting", "connected"]);
251
+ var LIVE_STATES = /* @__PURE__ */ new Set([WORKER_STATUS.CONNECTING, WORKER_STATUS.CONNECTED]);
156
252
  function normalizeStatus(status) {
157
253
  return LIVE_STATES.has(status) ? status : "disconnected";
158
254
  }
159
- function serializeError(error) {
160
- if (error instanceof Error) {
161
- return {
162
- name: error.name,
163
- message: error.message,
164
- ...error.stack ? { stack: error.stack } : {}
165
- };
166
- }
167
- return {
168
- name: "CentrifugeError",
169
- message: typeof error === "string" ? error : "Centrifuge worker operation failed.",
170
- ...error === void 0 ? {} : { context: error }
171
- };
172
- }
173
255
 
174
256
  // src/centrifuge-protocol.ts
175
257
  var DEFAULT_HEARTBEAT_INTERVAL_MS = 1e4;
@@ -184,6 +266,7 @@ var CentrifugeWorkerTransport = class {
184
266
  heartbeatIntervalMs;
185
267
  workerFactory;
186
268
  sharedWorkerFactory;
269
+ credentialProvider;
187
270
  backend = null;
188
271
  worker = null;
189
272
  sharedWorker = null;
@@ -201,12 +284,13 @@ var CentrifugeWorkerTransport = class {
201
284
  return this.backend ?? "uninitialized";
202
285
  }
203
286
  constructor(options = {}) {
204
- this.workerMode = options.workerMode ?? "dedicated";
287
+ this.workerMode = options.workerMode ?? WORKER_MODE.DEDICATED;
205
288
  this.transferable = options.transferable ?? false;
206
289
  this.heartbeatIntervalMs = options.heartbeatIntervalMs ?? DEFAULT_HEARTBEAT_INTERVAL_MS;
207
290
  assertHeartbeatInterval(this.heartbeatIntervalMs);
208
291
  this.workerFactory = options.workerFactory;
209
292
  this.sharedWorkerFactory = options.sharedWorkerFactory;
293
+ this.credentialProvider = options.credentialProvider;
210
294
  }
211
295
  /**
212
296
  * Start the transport: select a backend, initialise the Worker (or local
@@ -217,29 +301,29 @@ var CentrifugeWorkerTransport = class {
217
301
  assertStructuredCloneable(config.options ?? {});
218
302
  this.handlers = handlers;
219
303
  const backend = selectWorkerBackend(this.workerMode, {
220
- worker: this.workerFactory !== void 0,
221
- sharedWorker: this.sharedWorkerFactory !== void 0
304
+ worker: this.workerFactory !== void 0 || typeof Worker !== "undefined",
305
+ sharedWorker: this.sharedWorkerFactory !== void 0 || typeof SharedWorker !== "undefined"
222
306
  });
223
307
  const input = this.buildInitInput(config);
224
- if (backend === "shared") {
308
+ if (backend === WORKER_BACKEND.SHARED) {
225
309
  this.startSharedWorker(input);
226
- this.backend = "shared";
310
+ this.backend = WORKER_BACKEND.SHARED;
227
311
  return;
228
312
  }
229
- if (backend === "dedicated") {
313
+ if (backend === WORKER_BACKEND.DEDICATED) {
230
314
  this.startDedicatedWorker(input);
231
- this.backend = "dedicated";
315
+ this.backend = WORKER_BACKEND.DEDICATED;
232
316
  return;
233
317
  }
234
318
  this.localSession = new CentrifugeSession({ post: this.handleSessionOutput });
235
319
  this.localSession.handle(input);
236
- this.backend = "local";
320
+ this.backend = WORKER_BACKEND.LOCAL;
237
321
  }
238
322
  subscribe(topic) {
239
- this.post({ type: "SUBSCRIBE", topic });
323
+ this.post({ type: CENTRIFUGE_INPUT_TYPE.SUBSCRIBE, topic });
240
324
  }
241
325
  unsubscribe(topic) {
242
- this.post({ type: "UNSUBSCRIBE", topic });
326
+ this.post({ type: CENTRIFUGE_INPUT_TYPE.UNSUBSCRIBE, topic });
243
327
  }
244
328
  /**
245
329
  * Publish data to `topic`. Binary data (ArrayBuffer) is sent via Transferable
@@ -247,10 +331,10 @@ var CentrifugeWorkerTransport = class {
247
331
  */
248
332
  publish(topic, data, options) {
249
333
  if (this.transferable && data instanceof ArrayBuffer) {
250
- this.post({ type: "PUBLISH_BIN", topic, data, ...publicationMetadata(options) }, [data]);
334
+ this.post({ type: CENTRIFUGE_INPUT_TYPE.PUBLISH_BIN, topic, data, ...publicationMetadata(options?.messageId, options?.timestamp) }, [data]);
251
335
  return;
252
336
  }
253
- this.post({ type: "PUBLISH", topic, data, ...publicationMetadata(options) });
337
+ this.post({ type: CENTRIFUGE_INPUT_TYPE.PUBLISH, topic, data, ...publicationMetadata(options?.messageId, options?.timestamp) });
254
338
  }
255
339
  /**
256
340
  * Gracefully stop the transport: send STOP, clean up event listeners, and
@@ -259,7 +343,7 @@ var CentrifugeWorkerTransport = class {
259
343
  stop() {
260
344
  if (!this.backend) return;
261
345
  this.generation++;
262
- this.post({ type: "STOP" });
346
+ this.post({ type: CENTRIFUGE_INPUT_TYPE.STOP });
263
347
  this.clearHeartbeat();
264
348
  if (this.worker) {
265
349
  this.worker.removeEventListener("message", this.handleMessage);
@@ -278,10 +362,11 @@ var CentrifugeWorkerTransport = class {
278
362
  * default-resolution logic kicks in for the common case. */
279
363
  buildInitInput(config) {
280
364
  return {
281
- type: "INIT",
365
+ type: CENTRIFUGE_INPUT_TYPE.INIT,
282
366
  url: config.url,
283
367
  config: config.options ?? {},
284
368
  ...this.transferable ? { transferable: true } : {},
369
+ ...this.credentialProvider ? { tokenBridge: true } : {},
285
370
  ...this.heartbeatIntervalMs !== DEFAULT_HEARTBEAT_INTERVAL_MS ? { heartbeatIntervalMs: this.heartbeatIntervalMs } : {}
286
371
  };
287
372
  }
@@ -320,10 +405,34 @@ var CentrifugeWorkerTransport = class {
320
405
  * Shared by the Worker message listener, the SharedWorker port listener,
321
406
  * and the local-session sink — all three feed into this single dispatcher. */
322
407
  handleOutput(message) {
323
- if (message.type === "STATUS") this.handlers?.onStatus(message.status);
324
- if (message.type === "MESSAGE") this.handlers?.onMessage({ topic: message.topic, data: message.data, ...publicationMetadata(message) });
325
- if (message.type === "MESSAGE_BIN") this.handlers?.onMessage({ topic: message.topic, data: message.data, ...publicationMetadata(message) });
326
- if (message.type === "ERROR") this.handlers?.onError(deserializeWorkerError(message.error));
408
+ if (message.type === CENTRIFUGE_OUTPUT_TYPE.STATUS) this.handlers?.onStatus(message.status);
409
+ if (message.type === CENTRIFUGE_OUTPUT_TYPE.MESSAGE) this.handlers?.onMessage({ topic: message.topic, data: message.data, ...publicationMetadata(message.messageId, message.timestamp) });
410
+ if (message.type === CENTRIFUGE_OUTPUT_TYPE.MESSAGE_BIN) this.handlers?.onMessage({ topic: message.topic, data: message.data, ...publicationMetadata(message.messageId, message.timestamp) });
411
+ if (message.type === CENTRIFUGE_OUTPUT_TYPE.ERROR) this.handlers?.onError(deserializeWorkerError(message.error));
412
+ if (message.type === CENTRIFUGE_OUTPUT_TYPE.TOKEN_REQUEST) this.resolveTokenRequest(message.requestId, message.kind, message.channel);
413
+ }
414
+ /** Resolve a Worker credential request from the main thread: call the
415
+ * credentialProvider, then post the fresh token (or a serialized failure)
416
+ * back to the session that issued the request. */
417
+ resolveTokenRequest(requestId, kind, channel) {
418
+ const provider = this.credentialProvider;
419
+ const value = kind === "channelToken" && provider?.getChannelToken ? provider.getChannelToken(channel ?? "") : provider?.getToken?.();
420
+ Promise.resolve(value).then(
421
+ (token) => {
422
+ if (typeof token !== "string" || token.length === 0) {
423
+ this.post({
424
+ type: CENTRIFUGE_INPUT_TYPE.TOKEN_ERROR,
425
+ requestId,
426
+ error: serializeError(new Error(`The credential provider returned no ${kind}.`))
427
+ });
428
+ return;
429
+ }
430
+ this.post({ type: CENTRIFUGE_INPUT_TYPE.TOKEN_RESPONSE, requestId, token });
431
+ },
432
+ (error) => {
433
+ this.post({ type: CENTRIFUGE_INPUT_TYPE.TOKEN_ERROR, requestId, error: serializeError(error) });
434
+ }
435
+ );
327
436
  }
328
437
  /** Handle a Worker-level failure (crash, message decode error). Discards the
329
438
  * dead backend so a later start()/reopen can rebuild from scratch, and
@@ -339,7 +448,7 @@ var CentrifugeWorkerTransport = class {
339
448
  this.clearHeartbeat();
340
449
  this.resetBackend();
341
450
  this.handlers?.onError(new Error(message));
342
- this.handlers?.onStatus("error");
451
+ this.handlers?.onStatus(WORKER_STATUS.ERROR);
343
452
  }
344
453
  /** Remove every listener attached to the current SharedWorker and its port. */
345
454
  detachSharedWorkerListeners() {
@@ -352,7 +461,7 @@ var CentrifugeWorkerTransport = class {
352
461
  if (this.heartbeatHandle !== null) return;
353
462
  if (this.heartbeatIntervalMs === Infinity) return;
354
463
  this.heartbeatHandle = setInterval(() => {
355
- this.post({ type: "PING" });
464
+ this.post({ type: CENTRIFUGE_INPUT_TYPE.PING });
356
465
  }, this.heartbeatIntervalMs);
357
466
  }
358
467
  clearHeartbeat() {
@@ -403,6 +512,7 @@ function createCentrifugeDataBus(options) {
403
512
  const {
404
513
  clusterKey,
405
514
  connection,
515
+ credentialProvider,
406
516
  heartbeatIntervalMs,
407
517
  sharedWorkerFactory,
408
518
  transferable,
@@ -420,7 +530,8 @@ function createCentrifugeDataBus(options) {
420
530
  ...sharedWorkerFactory ? { sharedWorkerFactory } : {},
421
531
  ...transferable === void 0 ? {} : { transferable },
422
532
  ...workerMode ? { workerMode } : {},
423
- ...heartbeatIntervalMs === void 0 ? {} : { heartbeatIntervalMs }
533
+ ...heartbeatIntervalMs === void 0 ? {} : { heartbeatIntervalMs },
534
+ ...credentialProvider ? { credentialProvider } : {}
424
535
  })
425
536
  });
426
537
  }
@@ -437,7 +548,7 @@ function createDefaultWorker() {
437
548
  );
438
549
  }
439
550
  return new Worker(workerUrl, {
440
- name: "cross-tab-worker-databus",
551
+ name: DEFAULT_STORAGE_PREFIX,
441
552
  type: "module"
442
553
  });
443
554
  }
@@ -454,45 +565,14 @@ function createDefaultSharedWorker() {
454
565
  );
455
566
  }
456
567
  return new SharedWorker(workerUrl, {
457
- name: "cross-tab-worker-databus-shared",
568
+ name: `${DEFAULT_STORAGE_PREFIX}-shared`,
458
569
  type: "module"
459
570
  });
460
571
  }
461
- function assertHeartbeatInterval(value) {
462
- if (value === Infinity) return;
463
- if (typeof value === "number" && Number.isFinite(value) && value > 0) return;
464
- throw new TypeError(
465
- `Centrifuge heartbeatIntervalMs must be a positive number or Infinity, got ${String(value)}.`
466
- );
467
- }
468
- function assertStructuredCloneable(value) {
469
- if (typeof structuredClone !== "function") return;
470
- try {
471
- structuredClone(value);
472
- } catch (error) {
473
- throw new TypeError(
474
- "Centrifuge Worker configuration and published data must be structured-cloneable.",
475
- { cause: error }
476
- );
477
- }
478
- }
479
572
  function postToPortLike(target, message, transfer) {
480
573
  if (transfer) target.postMessage(message, transfer);
481
574
  else target.postMessage(message);
482
575
  }
483
- function deserializeWorkerError(error) {
484
- const result = new Error(error.message);
485
- result.name = error.name;
486
- if (error.stack) result.stack = error.stack;
487
- if (error.context !== void 0) Object.assign(result, { context: error.context });
488
- return result;
489
- }
490
- function publicationMetadata(metadata) {
491
- return {
492
- ...metadata?.messageId === void 0 ? {} : { messageId: metadata.messageId },
493
- ...metadata?.timestamp === void 0 ? {} : { timestamp: metadata.timestamp }
494
- };
495
- }
496
576
  export {
497
577
  CentrifugeWorkerTransport,
498
578
  createCentrifugeDataBus