tab-bridge 0.1.1 → 0.3.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.
- package/README.md +263 -10
- package/dist/{chunk-42VOZR6E.js → chunk-4JDWAUYM.js} +216 -93
- package/dist/{chunk-BQCNBNBT.cjs → chunk-TGEXRVAL.cjs} +219 -92
- package/dist/index.cjs +41 -25
- package/dist/index.d.cts +112 -5
- package/dist/index.d.ts +112 -5
- package/dist/index.js +2 -2
- package/dist/instance-hvEUHx6i.d.cts +194 -0
- package/dist/instance-hvEUHx6i.d.ts +194 -0
- package/dist/options-DmHyGTL0.d.cts +93 -0
- package/dist/options-iN7Rnvwj.d.ts +93 -0
- package/dist/react/index.cjs +82 -9
- package/dist/react/index.d.cts +48 -2
- package/dist/react/index.d.ts +48 -2
- package/dist/react/index.js +79 -9
- package/dist/zustand/index.cjs +80 -0
- package/dist/zustand/index.d.cts +87 -0
- package/dist/zustand/index.d.ts +87 -0
- package/dist/zustand/index.js +78 -0
- package/package.json +22 -6
- package/dist/types-BtK4ixKz.d.cts +0 -306
- package/dist/types-BtK4ixKz.d.ts +0 -306
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkTGEXRVAL_cjs = require('./chunk-TGEXRVAL.cjs');
|
|
4
4
|
|
|
5
5
|
// src/utils/message.ts
|
|
6
6
|
function createMessage(type, senderId, payload, targetId) {
|
|
@@ -8,8 +8,8 @@ function createMessage(type, senderId, payload, targetId) {
|
|
|
8
8
|
type,
|
|
9
9
|
senderId,
|
|
10
10
|
targetId,
|
|
11
|
-
timestamp:
|
|
12
|
-
version:
|
|
11
|
+
timestamp: chunkTGEXRVAL_cjs.monotonic(),
|
|
12
|
+
version: chunkTGEXRVAL_cjs.PROTOCOL_VERSION,
|
|
13
13
|
payload
|
|
14
14
|
};
|
|
15
15
|
}
|
|
@@ -59,91 +59,107 @@ var Emitter = class {
|
|
|
59
59
|
|
|
60
60
|
Object.defineProperty(exports, "BroadcastChannelTransport", {
|
|
61
61
|
enumerable: true,
|
|
62
|
-
get: function () { return
|
|
62
|
+
get: function () { return chunkTGEXRVAL_cjs.BroadcastChannelTransport; }
|
|
63
63
|
});
|
|
64
64
|
Object.defineProperty(exports, "ErrorCode", {
|
|
65
65
|
enumerable: true,
|
|
66
|
-
get: function () { return
|
|
66
|
+
get: function () { return chunkTGEXRVAL_cjs.ErrorCode; }
|
|
67
67
|
});
|
|
68
68
|
Object.defineProperty(exports, "LeaderElection", {
|
|
69
69
|
enumerable: true,
|
|
70
|
-
get: function () { return
|
|
70
|
+
get: function () { return chunkTGEXRVAL_cjs.LeaderElection; }
|
|
71
71
|
});
|
|
72
72
|
Object.defineProperty(exports, "PROTOCOL_VERSION", {
|
|
73
73
|
enumerable: true,
|
|
74
|
-
get: function () { return
|
|
74
|
+
get: function () { return chunkTGEXRVAL_cjs.PROTOCOL_VERSION; }
|
|
75
75
|
});
|
|
76
76
|
Object.defineProperty(exports, "RPCHandler", {
|
|
77
77
|
enumerable: true,
|
|
78
|
-
get: function () { return
|
|
78
|
+
get: function () { return chunkTGEXRVAL_cjs.RPCHandler; }
|
|
79
79
|
});
|
|
80
80
|
Object.defineProperty(exports, "StateManager", {
|
|
81
81
|
enumerable: true,
|
|
82
|
-
get: function () { return
|
|
82
|
+
get: function () { return chunkTGEXRVAL_cjs.StateManager; }
|
|
83
83
|
});
|
|
84
84
|
Object.defineProperty(exports, "StorageChannel", {
|
|
85
85
|
enumerable: true,
|
|
86
|
-
get: function () { return
|
|
86
|
+
get: function () { return chunkTGEXRVAL_cjs.StorageChannel; }
|
|
87
87
|
});
|
|
88
88
|
Object.defineProperty(exports, "TabRegistry", {
|
|
89
89
|
enumerable: true,
|
|
90
|
-
get: function () { return
|
|
90
|
+
get: function () { return chunkTGEXRVAL_cjs.TabRegistry; }
|
|
91
91
|
});
|
|
92
92
|
Object.defineProperty(exports, "TabSyncError", {
|
|
93
93
|
enumerable: true,
|
|
94
|
-
get: function () { return
|
|
94
|
+
get: function () { return chunkTGEXRVAL_cjs.TabSyncError; }
|
|
95
95
|
});
|
|
96
96
|
Object.defineProperty(exports, "createBatcher", {
|
|
97
97
|
enumerable: true,
|
|
98
|
-
get: function () { return
|
|
98
|
+
get: function () { return chunkTGEXRVAL_cjs.createBatcher; }
|
|
99
99
|
});
|
|
100
100
|
Object.defineProperty(exports, "createChannel", {
|
|
101
101
|
enumerable: true,
|
|
102
|
-
get: function () { return
|
|
102
|
+
get: function () { return chunkTGEXRVAL_cjs.createChannel; }
|
|
103
|
+
});
|
|
104
|
+
Object.defineProperty(exports, "createLogger", {
|
|
105
|
+
enumerable: true,
|
|
106
|
+
get: function () { return chunkTGEXRVAL_cjs.createLogger; }
|
|
107
|
+
});
|
|
108
|
+
Object.defineProperty(exports, "createPersistSaver", {
|
|
109
|
+
enumerable: true,
|
|
110
|
+
get: function () { return chunkTGEXRVAL_cjs.createPersistSaver; }
|
|
103
111
|
});
|
|
104
112
|
Object.defineProperty(exports, "createTabSync", {
|
|
105
113
|
enumerable: true,
|
|
106
|
-
get: function () { return
|
|
114
|
+
get: function () { return chunkTGEXRVAL_cjs.createTabSync; }
|
|
107
115
|
});
|
|
108
116
|
Object.defineProperty(exports, "destroyMiddleware", {
|
|
109
117
|
enumerable: true,
|
|
110
|
-
get: function () { return
|
|
118
|
+
get: function () { return chunkTGEXRVAL_cjs.destroyMiddleware; }
|
|
111
119
|
});
|
|
112
120
|
Object.defineProperty(exports, "generateTabId", {
|
|
113
121
|
enumerable: true,
|
|
114
|
-
get: function () { return
|
|
122
|
+
get: function () { return chunkTGEXRVAL_cjs.generateTabId; }
|
|
115
123
|
});
|
|
116
124
|
Object.defineProperty(exports, "hasBroadcastChannel", {
|
|
117
125
|
enumerable: true,
|
|
118
|
-
get: function () { return
|
|
126
|
+
get: function () { return chunkTGEXRVAL_cjs.hasBroadcastChannel; }
|
|
119
127
|
});
|
|
120
128
|
Object.defineProperty(exports, "hasCrypto", {
|
|
121
129
|
enumerable: true,
|
|
122
|
-
get: function () { return
|
|
130
|
+
get: function () { return chunkTGEXRVAL_cjs.hasCrypto; }
|
|
123
131
|
});
|
|
124
132
|
Object.defineProperty(exports, "hasDocument", {
|
|
125
133
|
enumerable: true,
|
|
126
|
-
get: function () { return
|
|
134
|
+
get: function () { return chunkTGEXRVAL_cjs.hasDocument; }
|
|
127
135
|
});
|
|
128
136
|
Object.defineProperty(exports, "hasLocalStorage", {
|
|
129
137
|
enumerable: true,
|
|
130
|
-
get: function () { return
|
|
138
|
+
get: function () { return chunkTGEXRVAL_cjs.hasLocalStorage; }
|
|
131
139
|
});
|
|
132
140
|
Object.defineProperty(exports, "isBrowser", {
|
|
133
141
|
enumerable: true,
|
|
134
|
-
get: function () { return
|
|
142
|
+
get: function () { return chunkTGEXRVAL_cjs.isBrowser; }
|
|
143
|
+
});
|
|
144
|
+
Object.defineProperty(exports, "loadPersistedState", {
|
|
145
|
+
enumerable: true,
|
|
146
|
+
get: function () { return chunkTGEXRVAL_cjs.loadPersistedState; }
|
|
135
147
|
});
|
|
136
148
|
Object.defineProperty(exports, "monotonic", {
|
|
137
149
|
enumerable: true,
|
|
138
|
-
get: function () { return
|
|
150
|
+
get: function () { return chunkTGEXRVAL_cjs.monotonic; }
|
|
139
151
|
});
|
|
140
152
|
Object.defineProperty(exports, "notifyMiddleware", {
|
|
141
153
|
enumerable: true,
|
|
142
|
-
get: function () { return
|
|
154
|
+
get: function () { return chunkTGEXRVAL_cjs.notifyMiddleware; }
|
|
155
|
+
});
|
|
156
|
+
Object.defineProperty(exports, "resolvePersistOptions", {
|
|
157
|
+
enumerable: true,
|
|
158
|
+
get: function () { return chunkTGEXRVAL_cjs.resolvePersistOptions; }
|
|
143
159
|
});
|
|
144
160
|
Object.defineProperty(exports, "runMiddleware", {
|
|
145
161
|
enumerable: true,
|
|
146
|
-
get: function () { return
|
|
162
|
+
get: function () { return chunkTGEXRVAL_cjs.runMiddleware; }
|
|
147
163
|
});
|
|
148
164
|
exports.Emitter = Emitter;
|
|
149
165
|
exports.createMessage = createMessage;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,92 @@
|
|
|
1
|
-
import { R as RPCMap, T as
|
|
2
|
-
export {
|
|
1
|
+
import { R as RPCMap, T as TabSyncInstance, C as ChangeMeta, a as TabInfo, b as RPCCallAllResult } from './instance-hvEUHx6i.cjs';
|
|
2
|
+
export { c as RPCArgs, d as RPCResult } from './instance-hvEUHx6i.cjs';
|
|
3
|
+
import { T as TabSyncOptions, M as Middleware, a as MiddlewareContext, P as PersistOptions } from './options-DmHyGTL0.cjs';
|
|
4
|
+
export { L as LeaderOptions, b as MiddlewareResult } from './options-DmHyGTL0.cjs';
|
|
5
|
+
|
|
6
|
+
declare const PROTOCOL_VERSION = 1;
|
|
7
|
+
interface StateUpdatePayload {
|
|
8
|
+
entries: Record<string, {
|
|
9
|
+
value: unknown;
|
|
10
|
+
timestamp: number;
|
|
11
|
+
}>;
|
|
12
|
+
}
|
|
13
|
+
interface StateSyncResponsePayload {
|
|
14
|
+
state: Record<string, {
|
|
15
|
+
value: unknown;
|
|
16
|
+
timestamp: number;
|
|
17
|
+
}>;
|
|
18
|
+
}
|
|
19
|
+
interface LeaderClaimPayload {
|
|
20
|
+
createdAt: number;
|
|
21
|
+
claimId: string;
|
|
22
|
+
generation: number;
|
|
23
|
+
}
|
|
24
|
+
interface LeaderAckPayload {
|
|
25
|
+
claimId: string;
|
|
26
|
+
generation: number;
|
|
27
|
+
}
|
|
28
|
+
interface TabAnnouncePayload {
|
|
29
|
+
createdAt: number;
|
|
30
|
+
isActive: boolean;
|
|
31
|
+
url: string;
|
|
32
|
+
title?: string;
|
|
33
|
+
}
|
|
34
|
+
interface RpcRequestPayload {
|
|
35
|
+
callId: string;
|
|
36
|
+
method: string;
|
|
37
|
+
args: unknown;
|
|
38
|
+
}
|
|
39
|
+
interface RpcResponsePayload {
|
|
40
|
+
callId: string;
|
|
41
|
+
result?: unknown;
|
|
42
|
+
error?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Maps every message type to its exact payload shape.
|
|
46
|
+
* Adding a new message only requires extending this interface.
|
|
47
|
+
*/
|
|
48
|
+
interface MessagePayloadMap {
|
|
49
|
+
STATE_UPDATE: StateUpdatePayload;
|
|
50
|
+
STATE_SYNC_REQUEST: null;
|
|
51
|
+
STATE_SYNC_RESPONSE: StateSyncResponsePayload;
|
|
52
|
+
LEADER_CLAIM: LeaderClaimPayload;
|
|
53
|
+
LEADER_ACK: LeaderAckPayload;
|
|
54
|
+
LEADER_HEARTBEAT: null;
|
|
55
|
+
LEADER_RESIGN: null;
|
|
56
|
+
TAB_ANNOUNCE: TabAnnouncePayload;
|
|
57
|
+
TAB_GOODBYE: null;
|
|
58
|
+
RPC_REQUEST: RpcRequestPayload;
|
|
59
|
+
RPC_RESPONSE: RpcResponsePayload;
|
|
60
|
+
}
|
|
61
|
+
type MessageType = keyof MessagePayloadMap;
|
|
62
|
+
/**
|
|
63
|
+
* Discriminated union of all inter-tab messages.
|
|
64
|
+
*
|
|
65
|
+
* Checking `msg.type` narrows `msg.payload` to the exact payload type,
|
|
66
|
+
* eliminating the need for runtime casts:
|
|
67
|
+
*
|
|
68
|
+
* ```ts
|
|
69
|
+
* if (msg.type === 'STATE_UPDATE') {
|
|
70
|
+
* msg.payload.entries; // ← StateUpdatePayload, fully typed
|
|
71
|
+
* }
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
type TabMessage = {
|
|
75
|
+
[K in MessageType]: {
|
|
76
|
+
readonly type: K;
|
|
77
|
+
readonly senderId: string;
|
|
78
|
+
readonly targetId?: string;
|
|
79
|
+
readonly timestamp: number;
|
|
80
|
+
readonly version?: number;
|
|
81
|
+
readonly payload: MessagePayloadMap[K];
|
|
82
|
+
};
|
|
83
|
+
}[MessageType];
|
|
84
|
+
/** Extract a single message variant by its type discriminant. */
|
|
85
|
+
type MessageOf<T extends MessageType> = Extract<TabMessage, {
|
|
86
|
+
type: T;
|
|
87
|
+
}>;
|
|
88
|
+
/** Function that sends a message through the transport channel. */
|
|
89
|
+
type SendFn = (message: TabMessage) => void;
|
|
3
90
|
|
|
4
91
|
declare function createTabSync<TState extends Record<string, unknown> = Record<string, unknown>, TRPCMap extends RPCMap = RPCMap>(options?: TabSyncOptions<TState>): TabSyncInstance<TState, TRPCMap>;
|
|
5
92
|
|
|
@@ -8,7 +95,7 @@ interface Channel {
|
|
|
8
95
|
onMessage(callback: (message: TabMessage) => void): () => void;
|
|
9
96
|
close(): void;
|
|
10
97
|
}
|
|
11
|
-
declare function createChannel(channelName: string, transport?: 'broadcast-channel' | 'local-storage'): Channel;
|
|
98
|
+
declare function createChannel(channelName: string, transport?: 'broadcast-channel' | 'local-storage', onError?: (error: Error) => void): Channel;
|
|
12
99
|
|
|
13
100
|
declare class BroadcastChannelTransport implements Channel {
|
|
14
101
|
private bc;
|
|
@@ -31,9 +118,10 @@ declare class BroadcastChannelTransport implements Channel {
|
|
|
31
118
|
declare class StorageChannel implements Channel {
|
|
32
119
|
private readonly key;
|
|
33
120
|
private readonly listeners;
|
|
121
|
+
private readonly onError?;
|
|
34
122
|
private closed;
|
|
35
123
|
private seq;
|
|
36
|
-
constructor(channelName: string);
|
|
124
|
+
constructor(channelName: string, onError?: (error: Error) => void);
|
|
37
125
|
postMessage(message: TabMessage): void;
|
|
38
126
|
onMessage(callback: (message: TabMessage) => void): () => void;
|
|
39
127
|
close(): void;
|
|
@@ -158,6 +246,8 @@ declare class LeaderElection {
|
|
|
158
246
|
private leaderWatchTimer;
|
|
159
247
|
private lastLeaderHeartbeat;
|
|
160
248
|
private electing;
|
|
249
|
+
private generation;
|
|
250
|
+
private currentClaimId;
|
|
161
251
|
private readonly leaderCallbacks;
|
|
162
252
|
private readonly leaderCleanups;
|
|
163
253
|
constructor(options: LeaderElectionOptions);
|
|
@@ -191,17 +281,20 @@ interface RPCHandlerOptions {
|
|
|
191
281
|
send: SendFn;
|
|
192
282
|
tabId: string;
|
|
193
283
|
resolveLeaderId?: () => string | null;
|
|
284
|
+
resolveTabIds?: () => string[];
|
|
194
285
|
onError?: (error: Error) => void;
|
|
195
286
|
}
|
|
196
287
|
declare class RPCHandler {
|
|
197
288
|
private readonly send;
|
|
198
289
|
private readonly tabId;
|
|
199
290
|
private readonly resolveLeaderId;
|
|
291
|
+
private readonly resolveTabIds;
|
|
200
292
|
private readonly onError;
|
|
201
293
|
private readonly handlers;
|
|
202
294
|
private readonly pending;
|
|
203
295
|
constructor(options: RPCHandlerOptions);
|
|
204
296
|
call<TResult>(targetTabId: string | 'leader', method: string, args?: unknown, timeout?: number): Promise<TResult>;
|
|
297
|
+
callAll<TResult>(method: string, args?: unknown, timeout?: number): Promise<RPCCallAllResult<TResult>[]>;
|
|
205
298
|
handle<TArgs = unknown, TResult = unknown>(method: string, handler: (args: TArgs, callerTabId: string) => TResult | Promise<TResult>): () => void;
|
|
206
299
|
handleMessage(message: TabMessage): void;
|
|
207
300
|
destroy(): void;
|
|
@@ -223,6 +316,15 @@ declare function notifyMiddleware<TState extends Record<string, unknown>>(middle
|
|
|
223
316
|
/** Destroy all middlewares. */
|
|
224
317
|
declare function destroyMiddleware<TState extends Record<string, unknown>>(middlewares: readonly Middleware<TState>[]): void;
|
|
225
318
|
|
|
319
|
+
declare function resolvePersistOptions<TState extends Record<string, unknown>>(opt: PersistOptions<TState> | boolean | undefined): PersistOptions<TState> | null;
|
|
320
|
+
declare function loadPersistedState<TState extends Record<string, unknown>>(opts: PersistOptions<TState>): Partial<TState>;
|
|
321
|
+
interface PersistSaver<TState extends Record<string, unknown>> {
|
|
322
|
+
save: (state: Readonly<TState>) => void;
|
|
323
|
+
flush: () => void;
|
|
324
|
+
destroy: () => void;
|
|
325
|
+
}
|
|
326
|
+
declare function createPersistSaver<TState extends Record<string, unknown>>(opts: PersistOptions<TState>, onError: (e: Error) => void): PersistSaver<TState>;
|
|
327
|
+
|
|
226
328
|
declare function generateTabId(): string;
|
|
227
329
|
|
|
228
330
|
declare function monotonic(): number;
|
|
@@ -301,4 +403,9 @@ declare const hasLocalStorage: boolean;
|
|
|
301
403
|
declare const hasBroadcastChannel: boolean;
|
|
302
404
|
declare const hasCrypto: boolean;
|
|
303
405
|
|
|
304
|
-
|
|
406
|
+
interface Logger {
|
|
407
|
+
log: (label: string, ...args: unknown[]) => void;
|
|
408
|
+
}
|
|
409
|
+
declare function createLogger(enabled: boolean, tabId: string): Logger;
|
|
410
|
+
|
|
411
|
+
export { type Batcher, BroadcastChannelTransport, ChangeMeta, type Channel, Emitter, ErrorCode, type LeaderAckPayload, type LeaderClaimPayload, LeaderElection, type LeaderElectionOptions, type Logger, type MessageOf, type MessagePayloadMap, type MessageType, Middleware, MiddlewareContext, PROTOCOL_VERSION, PersistOptions, type PersistSaver, RPCCallAllResult, RPCHandler, type RPCHandlerOptions, RPCMap, type RpcRequestPayload, type RpcResponsePayload, type SendFn, StateManager, type StateManagerOptions, type StateSyncResponsePayload, type StateUpdatePayload, StorageChannel, type TabAnnouncePayload, TabInfo, type TabMessage, TabRegistry, type TabRegistryOptions, TabSyncError, TabSyncInstance, TabSyncOptions, createBatcher, createChannel, createLogger, createMessage, createPersistSaver, createTabSync, destroyMiddleware, generateTabId, hasBroadcastChannel, hasCrypto, hasDocument, hasLocalStorage, isBrowser, loadPersistedState, monotonic, notifyMiddleware, resolvePersistOptions, runMiddleware };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,92 @@
|
|
|
1
|
-
import { R as RPCMap, T as
|
|
2
|
-
export {
|
|
1
|
+
import { R as RPCMap, T as TabSyncInstance, C as ChangeMeta, a as TabInfo, b as RPCCallAllResult } from './instance-hvEUHx6i.js';
|
|
2
|
+
export { c as RPCArgs, d as RPCResult } from './instance-hvEUHx6i.js';
|
|
3
|
+
import { T as TabSyncOptions, M as Middleware, a as MiddlewareContext, P as PersistOptions } from './options-iN7Rnvwj.js';
|
|
4
|
+
export { L as LeaderOptions, b as MiddlewareResult } from './options-iN7Rnvwj.js';
|
|
5
|
+
|
|
6
|
+
declare const PROTOCOL_VERSION = 1;
|
|
7
|
+
interface StateUpdatePayload {
|
|
8
|
+
entries: Record<string, {
|
|
9
|
+
value: unknown;
|
|
10
|
+
timestamp: number;
|
|
11
|
+
}>;
|
|
12
|
+
}
|
|
13
|
+
interface StateSyncResponsePayload {
|
|
14
|
+
state: Record<string, {
|
|
15
|
+
value: unknown;
|
|
16
|
+
timestamp: number;
|
|
17
|
+
}>;
|
|
18
|
+
}
|
|
19
|
+
interface LeaderClaimPayload {
|
|
20
|
+
createdAt: number;
|
|
21
|
+
claimId: string;
|
|
22
|
+
generation: number;
|
|
23
|
+
}
|
|
24
|
+
interface LeaderAckPayload {
|
|
25
|
+
claimId: string;
|
|
26
|
+
generation: number;
|
|
27
|
+
}
|
|
28
|
+
interface TabAnnouncePayload {
|
|
29
|
+
createdAt: number;
|
|
30
|
+
isActive: boolean;
|
|
31
|
+
url: string;
|
|
32
|
+
title?: string;
|
|
33
|
+
}
|
|
34
|
+
interface RpcRequestPayload {
|
|
35
|
+
callId: string;
|
|
36
|
+
method: string;
|
|
37
|
+
args: unknown;
|
|
38
|
+
}
|
|
39
|
+
interface RpcResponsePayload {
|
|
40
|
+
callId: string;
|
|
41
|
+
result?: unknown;
|
|
42
|
+
error?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Maps every message type to its exact payload shape.
|
|
46
|
+
* Adding a new message only requires extending this interface.
|
|
47
|
+
*/
|
|
48
|
+
interface MessagePayloadMap {
|
|
49
|
+
STATE_UPDATE: StateUpdatePayload;
|
|
50
|
+
STATE_SYNC_REQUEST: null;
|
|
51
|
+
STATE_SYNC_RESPONSE: StateSyncResponsePayload;
|
|
52
|
+
LEADER_CLAIM: LeaderClaimPayload;
|
|
53
|
+
LEADER_ACK: LeaderAckPayload;
|
|
54
|
+
LEADER_HEARTBEAT: null;
|
|
55
|
+
LEADER_RESIGN: null;
|
|
56
|
+
TAB_ANNOUNCE: TabAnnouncePayload;
|
|
57
|
+
TAB_GOODBYE: null;
|
|
58
|
+
RPC_REQUEST: RpcRequestPayload;
|
|
59
|
+
RPC_RESPONSE: RpcResponsePayload;
|
|
60
|
+
}
|
|
61
|
+
type MessageType = keyof MessagePayloadMap;
|
|
62
|
+
/**
|
|
63
|
+
* Discriminated union of all inter-tab messages.
|
|
64
|
+
*
|
|
65
|
+
* Checking `msg.type` narrows `msg.payload` to the exact payload type,
|
|
66
|
+
* eliminating the need for runtime casts:
|
|
67
|
+
*
|
|
68
|
+
* ```ts
|
|
69
|
+
* if (msg.type === 'STATE_UPDATE') {
|
|
70
|
+
* msg.payload.entries; // ← StateUpdatePayload, fully typed
|
|
71
|
+
* }
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
type TabMessage = {
|
|
75
|
+
[K in MessageType]: {
|
|
76
|
+
readonly type: K;
|
|
77
|
+
readonly senderId: string;
|
|
78
|
+
readonly targetId?: string;
|
|
79
|
+
readonly timestamp: number;
|
|
80
|
+
readonly version?: number;
|
|
81
|
+
readonly payload: MessagePayloadMap[K];
|
|
82
|
+
};
|
|
83
|
+
}[MessageType];
|
|
84
|
+
/** Extract a single message variant by its type discriminant. */
|
|
85
|
+
type MessageOf<T extends MessageType> = Extract<TabMessage, {
|
|
86
|
+
type: T;
|
|
87
|
+
}>;
|
|
88
|
+
/** Function that sends a message through the transport channel. */
|
|
89
|
+
type SendFn = (message: TabMessage) => void;
|
|
3
90
|
|
|
4
91
|
declare function createTabSync<TState extends Record<string, unknown> = Record<string, unknown>, TRPCMap extends RPCMap = RPCMap>(options?: TabSyncOptions<TState>): TabSyncInstance<TState, TRPCMap>;
|
|
5
92
|
|
|
@@ -8,7 +95,7 @@ interface Channel {
|
|
|
8
95
|
onMessage(callback: (message: TabMessage) => void): () => void;
|
|
9
96
|
close(): void;
|
|
10
97
|
}
|
|
11
|
-
declare function createChannel(channelName: string, transport?: 'broadcast-channel' | 'local-storage'): Channel;
|
|
98
|
+
declare function createChannel(channelName: string, transport?: 'broadcast-channel' | 'local-storage', onError?: (error: Error) => void): Channel;
|
|
12
99
|
|
|
13
100
|
declare class BroadcastChannelTransport implements Channel {
|
|
14
101
|
private bc;
|
|
@@ -31,9 +118,10 @@ declare class BroadcastChannelTransport implements Channel {
|
|
|
31
118
|
declare class StorageChannel implements Channel {
|
|
32
119
|
private readonly key;
|
|
33
120
|
private readonly listeners;
|
|
121
|
+
private readonly onError?;
|
|
34
122
|
private closed;
|
|
35
123
|
private seq;
|
|
36
|
-
constructor(channelName: string);
|
|
124
|
+
constructor(channelName: string, onError?: (error: Error) => void);
|
|
37
125
|
postMessage(message: TabMessage): void;
|
|
38
126
|
onMessage(callback: (message: TabMessage) => void): () => void;
|
|
39
127
|
close(): void;
|
|
@@ -158,6 +246,8 @@ declare class LeaderElection {
|
|
|
158
246
|
private leaderWatchTimer;
|
|
159
247
|
private lastLeaderHeartbeat;
|
|
160
248
|
private electing;
|
|
249
|
+
private generation;
|
|
250
|
+
private currentClaimId;
|
|
161
251
|
private readonly leaderCallbacks;
|
|
162
252
|
private readonly leaderCleanups;
|
|
163
253
|
constructor(options: LeaderElectionOptions);
|
|
@@ -191,17 +281,20 @@ interface RPCHandlerOptions {
|
|
|
191
281
|
send: SendFn;
|
|
192
282
|
tabId: string;
|
|
193
283
|
resolveLeaderId?: () => string | null;
|
|
284
|
+
resolveTabIds?: () => string[];
|
|
194
285
|
onError?: (error: Error) => void;
|
|
195
286
|
}
|
|
196
287
|
declare class RPCHandler {
|
|
197
288
|
private readonly send;
|
|
198
289
|
private readonly tabId;
|
|
199
290
|
private readonly resolveLeaderId;
|
|
291
|
+
private readonly resolveTabIds;
|
|
200
292
|
private readonly onError;
|
|
201
293
|
private readonly handlers;
|
|
202
294
|
private readonly pending;
|
|
203
295
|
constructor(options: RPCHandlerOptions);
|
|
204
296
|
call<TResult>(targetTabId: string | 'leader', method: string, args?: unknown, timeout?: number): Promise<TResult>;
|
|
297
|
+
callAll<TResult>(method: string, args?: unknown, timeout?: number): Promise<RPCCallAllResult<TResult>[]>;
|
|
205
298
|
handle<TArgs = unknown, TResult = unknown>(method: string, handler: (args: TArgs, callerTabId: string) => TResult | Promise<TResult>): () => void;
|
|
206
299
|
handleMessage(message: TabMessage): void;
|
|
207
300
|
destroy(): void;
|
|
@@ -223,6 +316,15 @@ declare function notifyMiddleware<TState extends Record<string, unknown>>(middle
|
|
|
223
316
|
/** Destroy all middlewares. */
|
|
224
317
|
declare function destroyMiddleware<TState extends Record<string, unknown>>(middlewares: readonly Middleware<TState>[]): void;
|
|
225
318
|
|
|
319
|
+
declare function resolvePersistOptions<TState extends Record<string, unknown>>(opt: PersistOptions<TState> | boolean | undefined): PersistOptions<TState> | null;
|
|
320
|
+
declare function loadPersistedState<TState extends Record<string, unknown>>(opts: PersistOptions<TState>): Partial<TState>;
|
|
321
|
+
interface PersistSaver<TState extends Record<string, unknown>> {
|
|
322
|
+
save: (state: Readonly<TState>) => void;
|
|
323
|
+
flush: () => void;
|
|
324
|
+
destroy: () => void;
|
|
325
|
+
}
|
|
326
|
+
declare function createPersistSaver<TState extends Record<string, unknown>>(opts: PersistOptions<TState>, onError: (e: Error) => void): PersistSaver<TState>;
|
|
327
|
+
|
|
226
328
|
declare function generateTabId(): string;
|
|
227
329
|
|
|
228
330
|
declare function monotonic(): number;
|
|
@@ -301,4 +403,9 @@ declare const hasLocalStorage: boolean;
|
|
|
301
403
|
declare const hasBroadcastChannel: boolean;
|
|
302
404
|
declare const hasCrypto: boolean;
|
|
303
405
|
|
|
304
|
-
|
|
406
|
+
interface Logger {
|
|
407
|
+
log: (label: string, ...args: unknown[]) => void;
|
|
408
|
+
}
|
|
409
|
+
declare function createLogger(enabled: boolean, tabId: string): Logger;
|
|
410
|
+
|
|
411
|
+
export { type Batcher, BroadcastChannelTransport, ChangeMeta, type Channel, Emitter, ErrorCode, type LeaderAckPayload, type LeaderClaimPayload, LeaderElection, type LeaderElectionOptions, type Logger, type MessageOf, type MessagePayloadMap, type MessageType, Middleware, MiddlewareContext, PROTOCOL_VERSION, PersistOptions, type PersistSaver, RPCCallAllResult, RPCHandler, type RPCHandlerOptions, RPCMap, type RpcRequestPayload, type RpcResponsePayload, type SendFn, StateManager, type StateManagerOptions, type StateSyncResponsePayload, type StateUpdatePayload, StorageChannel, type TabAnnouncePayload, TabInfo, type TabMessage, TabRegistry, type TabRegistryOptions, TabSyncError, TabSyncInstance, TabSyncOptions, createBatcher, createChannel, createLogger, createMessage, createPersistSaver, createTabSync, destroyMiddleware, generateTabId, hasBroadcastChannel, hasCrypto, hasDocument, hasLocalStorage, isBrowser, loadPersistedState, monotonic, notifyMiddleware, resolvePersistOptions, runMiddleware };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { PROTOCOL_VERSION, monotonic } from './chunk-
|
|
2
|
-
export { BroadcastChannelTransport, ErrorCode, LeaderElection, PROTOCOL_VERSION, RPCHandler, StateManager, StorageChannel, TabRegistry, TabSyncError, createBatcher, createChannel, createTabSync, destroyMiddleware, generateTabId, hasBroadcastChannel, hasCrypto, hasDocument, hasLocalStorage, isBrowser, monotonic, notifyMiddleware, runMiddleware } from './chunk-
|
|
1
|
+
import { PROTOCOL_VERSION, monotonic } from './chunk-4JDWAUYM.js';
|
|
2
|
+
export { BroadcastChannelTransport, ErrorCode, LeaderElection, PROTOCOL_VERSION, RPCHandler, StateManager, StorageChannel, TabRegistry, TabSyncError, createBatcher, createChannel, createLogger, createPersistSaver, createTabSync, destroyMiddleware, generateTabId, hasBroadcastChannel, hasCrypto, hasDocument, hasLocalStorage, isBrowser, loadPersistedState, monotonic, notifyMiddleware, resolvePersistOptions, runMiddleware } from './chunk-4JDWAUYM.js';
|
|
3
3
|
|
|
4
4
|
// src/utils/message.ts
|
|
5
5
|
function createMessage(type, senderId, payload, targetId) {
|