tab-bridge 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.
- package/LICENSE +21 -0
- package/README.md +834 -0
- package/dist/chunk-42VOZR6E.js +1309 -0
- package/dist/chunk-BQCNBNBT.cjs +1332 -0
- package/dist/index.cjs +149 -0
- package/dist/index.d.cts +304 -0
- package/dist/index.d.ts +304 -0
- package/dist/index.js +59 -0
- package/dist/react/index.cjs +174 -0
- package/dist/react/index.d.cts +61 -0
- package/dist/react/index.d.ts +61 -0
- package/dist/react/index.js +167 -0
- package/dist/types-BtK4ixKz.d.cts +306 -0
- package/dist/types-BtK4ixKz.d.ts +306 -0
- package/package.json +90 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkBQCNBNBT_cjs = require('./chunk-BQCNBNBT.cjs');
|
|
4
|
+
|
|
5
|
+
// src/utils/message.ts
|
|
6
|
+
function createMessage(type, senderId, payload, targetId) {
|
|
7
|
+
return {
|
|
8
|
+
type,
|
|
9
|
+
senderId,
|
|
10
|
+
targetId,
|
|
11
|
+
timestamp: chunkBQCNBNBT_cjs.monotonic(),
|
|
12
|
+
version: chunkBQCNBNBT_cjs.PROTOCOL_VERSION,
|
|
13
|
+
payload
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// src/utils/emitter.ts
|
|
18
|
+
var Emitter = class {
|
|
19
|
+
constructor() {
|
|
20
|
+
this._handlers = /* @__PURE__ */ new Map();
|
|
21
|
+
}
|
|
22
|
+
on(event, handler) {
|
|
23
|
+
let set = this._handlers.get(event);
|
|
24
|
+
if (!set) {
|
|
25
|
+
set = /* @__PURE__ */ new Set();
|
|
26
|
+
this._handlers.set(event, set);
|
|
27
|
+
}
|
|
28
|
+
set.add(handler);
|
|
29
|
+
return () => {
|
|
30
|
+
set.delete(handler);
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
once(event, handler) {
|
|
34
|
+
const off = this.on(event, ((...args) => {
|
|
35
|
+
off();
|
|
36
|
+
handler(...args);
|
|
37
|
+
}));
|
|
38
|
+
return off;
|
|
39
|
+
}
|
|
40
|
+
emit(...args) {
|
|
41
|
+
const [event, data] = args;
|
|
42
|
+
const set = this._handlers.get(event);
|
|
43
|
+
if (!set) return;
|
|
44
|
+
for (const handler of set) {
|
|
45
|
+
handler(data);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
listenerCount(event) {
|
|
49
|
+
return this._handlers.get(event)?.size ?? 0;
|
|
50
|
+
}
|
|
51
|
+
removeAll(event) {
|
|
52
|
+
if (event) {
|
|
53
|
+
this._handlers.delete(event);
|
|
54
|
+
} else {
|
|
55
|
+
this._handlers.clear();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
Object.defineProperty(exports, "BroadcastChannelTransport", {
|
|
61
|
+
enumerable: true,
|
|
62
|
+
get: function () { return chunkBQCNBNBT_cjs.BroadcastChannelTransport; }
|
|
63
|
+
});
|
|
64
|
+
Object.defineProperty(exports, "ErrorCode", {
|
|
65
|
+
enumerable: true,
|
|
66
|
+
get: function () { return chunkBQCNBNBT_cjs.ErrorCode; }
|
|
67
|
+
});
|
|
68
|
+
Object.defineProperty(exports, "LeaderElection", {
|
|
69
|
+
enumerable: true,
|
|
70
|
+
get: function () { return chunkBQCNBNBT_cjs.LeaderElection; }
|
|
71
|
+
});
|
|
72
|
+
Object.defineProperty(exports, "PROTOCOL_VERSION", {
|
|
73
|
+
enumerable: true,
|
|
74
|
+
get: function () { return chunkBQCNBNBT_cjs.PROTOCOL_VERSION; }
|
|
75
|
+
});
|
|
76
|
+
Object.defineProperty(exports, "RPCHandler", {
|
|
77
|
+
enumerable: true,
|
|
78
|
+
get: function () { return chunkBQCNBNBT_cjs.RPCHandler; }
|
|
79
|
+
});
|
|
80
|
+
Object.defineProperty(exports, "StateManager", {
|
|
81
|
+
enumerable: true,
|
|
82
|
+
get: function () { return chunkBQCNBNBT_cjs.StateManager; }
|
|
83
|
+
});
|
|
84
|
+
Object.defineProperty(exports, "StorageChannel", {
|
|
85
|
+
enumerable: true,
|
|
86
|
+
get: function () { return chunkBQCNBNBT_cjs.StorageChannel; }
|
|
87
|
+
});
|
|
88
|
+
Object.defineProperty(exports, "TabRegistry", {
|
|
89
|
+
enumerable: true,
|
|
90
|
+
get: function () { return chunkBQCNBNBT_cjs.TabRegistry; }
|
|
91
|
+
});
|
|
92
|
+
Object.defineProperty(exports, "TabSyncError", {
|
|
93
|
+
enumerable: true,
|
|
94
|
+
get: function () { return chunkBQCNBNBT_cjs.TabSyncError; }
|
|
95
|
+
});
|
|
96
|
+
Object.defineProperty(exports, "createBatcher", {
|
|
97
|
+
enumerable: true,
|
|
98
|
+
get: function () { return chunkBQCNBNBT_cjs.createBatcher; }
|
|
99
|
+
});
|
|
100
|
+
Object.defineProperty(exports, "createChannel", {
|
|
101
|
+
enumerable: true,
|
|
102
|
+
get: function () { return chunkBQCNBNBT_cjs.createChannel; }
|
|
103
|
+
});
|
|
104
|
+
Object.defineProperty(exports, "createTabSync", {
|
|
105
|
+
enumerable: true,
|
|
106
|
+
get: function () { return chunkBQCNBNBT_cjs.createTabSync; }
|
|
107
|
+
});
|
|
108
|
+
Object.defineProperty(exports, "destroyMiddleware", {
|
|
109
|
+
enumerable: true,
|
|
110
|
+
get: function () { return chunkBQCNBNBT_cjs.destroyMiddleware; }
|
|
111
|
+
});
|
|
112
|
+
Object.defineProperty(exports, "generateTabId", {
|
|
113
|
+
enumerable: true,
|
|
114
|
+
get: function () { return chunkBQCNBNBT_cjs.generateTabId; }
|
|
115
|
+
});
|
|
116
|
+
Object.defineProperty(exports, "hasBroadcastChannel", {
|
|
117
|
+
enumerable: true,
|
|
118
|
+
get: function () { return chunkBQCNBNBT_cjs.hasBroadcastChannel; }
|
|
119
|
+
});
|
|
120
|
+
Object.defineProperty(exports, "hasCrypto", {
|
|
121
|
+
enumerable: true,
|
|
122
|
+
get: function () { return chunkBQCNBNBT_cjs.hasCrypto; }
|
|
123
|
+
});
|
|
124
|
+
Object.defineProperty(exports, "hasDocument", {
|
|
125
|
+
enumerable: true,
|
|
126
|
+
get: function () { return chunkBQCNBNBT_cjs.hasDocument; }
|
|
127
|
+
});
|
|
128
|
+
Object.defineProperty(exports, "hasLocalStorage", {
|
|
129
|
+
enumerable: true,
|
|
130
|
+
get: function () { return chunkBQCNBNBT_cjs.hasLocalStorage; }
|
|
131
|
+
});
|
|
132
|
+
Object.defineProperty(exports, "isBrowser", {
|
|
133
|
+
enumerable: true,
|
|
134
|
+
get: function () { return chunkBQCNBNBT_cjs.isBrowser; }
|
|
135
|
+
});
|
|
136
|
+
Object.defineProperty(exports, "monotonic", {
|
|
137
|
+
enumerable: true,
|
|
138
|
+
get: function () { return chunkBQCNBNBT_cjs.monotonic; }
|
|
139
|
+
});
|
|
140
|
+
Object.defineProperty(exports, "notifyMiddleware", {
|
|
141
|
+
enumerable: true,
|
|
142
|
+
get: function () { return chunkBQCNBNBT_cjs.notifyMiddleware; }
|
|
143
|
+
});
|
|
144
|
+
Object.defineProperty(exports, "runMiddleware", {
|
|
145
|
+
enumerable: true,
|
|
146
|
+
get: function () { return chunkBQCNBNBT_cjs.runMiddleware; }
|
|
147
|
+
});
|
|
148
|
+
exports.Emitter = Emitter;
|
|
149
|
+
exports.createMessage = createMessage;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import { R as RPCMap, T as TabSyncOptions, a as TabSyncInstance, b as TabMessage, S as SendFn, C as ChangeMeta, c as TabInfo, M as Middleware, d as MiddlewareContext, e as MessageType, f as MessagePayloadMap, g as MessageOf } from './types-BtK4ixKz.cjs';
|
|
2
|
+
export { L as LeaderClaimPayload, h as LeaderOptions, i as MiddlewareResult, P as PROTOCOL_VERSION, j as PersistOptions, k as RPCArgs, l as RPCResult, m as RpcRequestPayload, n as RpcResponsePayload, o as StateSyncResponsePayload, p as StateUpdatePayload, q as TabAnnouncePayload } from './types-BtK4ixKz.cjs';
|
|
3
|
+
|
|
4
|
+
declare function createTabSync<TState extends Record<string, unknown> = Record<string, unknown>, TRPCMap extends RPCMap = RPCMap>(options?: TabSyncOptions<TState>): TabSyncInstance<TState, TRPCMap>;
|
|
5
|
+
|
|
6
|
+
interface Channel {
|
|
7
|
+
postMessage(message: TabMessage): void;
|
|
8
|
+
onMessage(callback: (message: TabMessage) => void): () => void;
|
|
9
|
+
close(): void;
|
|
10
|
+
}
|
|
11
|
+
declare function createChannel(channelName: string, transport?: 'broadcast-channel' | 'local-storage'): Channel;
|
|
12
|
+
|
|
13
|
+
declare class BroadcastChannelTransport implements Channel {
|
|
14
|
+
private bc;
|
|
15
|
+
private closed;
|
|
16
|
+
constructor(channelName: string);
|
|
17
|
+
postMessage(message: TabMessage): void;
|
|
18
|
+
onMessage(callback: (message: TabMessage) => void): () => void;
|
|
19
|
+
close(): void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Fallback transport using `localStorage` `storage` events.
|
|
24
|
+
*
|
|
25
|
+
* Limitations vs BroadcastChannel:
|
|
26
|
+
* - Values must be JSON-serializable
|
|
27
|
+
* - `storage` event only fires on OTHER tabs (same-tab is not needed since
|
|
28
|
+
* the originating tab already handles the change locally)
|
|
29
|
+
* - Slightly slower due to serialization overhead
|
|
30
|
+
*/
|
|
31
|
+
declare class StorageChannel implements Channel {
|
|
32
|
+
private readonly key;
|
|
33
|
+
private readonly listeners;
|
|
34
|
+
private closed;
|
|
35
|
+
private seq;
|
|
36
|
+
constructor(channelName: string);
|
|
37
|
+
postMessage(message: TabMessage): void;
|
|
38
|
+
onMessage(callback: (message: TabMessage) => void): () => void;
|
|
39
|
+
close(): void;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface StateManagerOptions<TState extends Record<string, unknown>> {
|
|
43
|
+
send: SendFn;
|
|
44
|
+
tabId: string;
|
|
45
|
+
initial?: TState;
|
|
46
|
+
merge?: (localValue: unknown, remoteValue: unknown, key: keyof TState) => unknown;
|
|
47
|
+
/**
|
|
48
|
+
* Hook called before a remote value is applied.
|
|
49
|
+
* Return `false` to reject, `{ value }` to transform, or `void` to accept.
|
|
50
|
+
*/
|
|
51
|
+
interceptRemote?: (key: keyof TState, value: unknown, previousValue: unknown, meta: ChangeMeta) => {
|
|
52
|
+
value: unknown;
|
|
53
|
+
} | false | void;
|
|
54
|
+
/** Hook called after any remote change is committed. */
|
|
55
|
+
afterRemoteChange?: (key: keyof TState, value: unknown, meta: ChangeMeta) => void;
|
|
56
|
+
}
|
|
57
|
+
declare class StateManager<TState extends Record<string, unknown>> {
|
|
58
|
+
private readonly state;
|
|
59
|
+
private readonly keyListeners;
|
|
60
|
+
private readonly changeListeners;
|
|
61
|
+
private readonly send;
|
|
62
|
+
private readonly tabId;
|
|
63
|
+
private readonly mergeFn?;
|
|
64
|
+
private readonly interceptRemote?;
|
|
65
|
+
private readonly afterRemoteChange?;
|
|
66
|
+
private readonly batcher;
|
|
67
|
+
private snapshotCache;
|
|
68
|
+
constructor(options: StateManagerOptions<TState>);
|
|
69
|
+
get<K extends keyof TState>(key: K): TState[K];
|
|
70
|
+
/**
|
|
71
|
+
* Returns a cached snapshot. The same reference is returned until state
|
|
72
|
+
* changes, making this safe for React's `useSyncExternalStore`.
|
|
73
|
+
*/
|
|
74
|
+
getAll(): Readonly<TState>;
|
|
75
|
+
set<K extends keyof TState>(key: K, value: TState[K]): void;
|
|
76
|
+
patch(partial: Partial<TState>): void;
|
|
77
|
+
on<K extends keyof TState>(key: K, callback: (value: TState[K], meta: ChangeMeta) => void): () => void;
|
|
78
|
+
onChange(callback: (state: Readonly<TState>, changedKeys: (keyof TState)[], meta: ChangeMeta) => void): () => void;
|
|
79
|
+
handleMessage(message: TabMessage): void;
|
|
80
|
+
requestSync(): void;
|
|
81
|
+
respondToSync(targetId: string): void;
|
|
82
|
+
flush(): void;
|
|
83
|
+
destroy(): void;
|
|
84
|
+
private applyRemoteUpdate;
|
|
85
|
+
/** LWW: accept remote if newer timestamp, or same timestamp with higher senderId. */
|
|
86
|
+
private shouldAcceptRemote;
|
|
87
|
+
private applySyncResponse;
|
|
88
|
+
private notifyKey;
|
|
89
|
+
private notifyChange;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
interface TabRegistryOptions {
|
|
93
|
+
send: SendFn;
|
|
94
|
+
tabId: string;
|
|
95
|
+
tabCreatedAt: number;
|
|
96
|
+
/** Interval (ms) to check for dead tabs. Default: `2000` */
|
|
97
|
+
heartbeatInterval?: number;
|
|
98
|
+
/** How long (ms) before a tab is considered dead. Default: `6000` */
|
|
99
|
+
tabTimeout?: number;
|
|
100
|
+
}
|
|
101
|
+
declare class TabRegistry {
|
|
102
|
+
private readonly tabs;
|
|
103
|
+
private readonly tabChangeListeners;
|
|
104
|
+
private readonly send;
|
|
105
|
+
private readonly tabId;
|
|
106
|
+
private readonly tabCreatedAt;
|
|
107
|
+
private readonly heartbeatInterval;
|
|
108
|
+
private readonly tabTimeout;
|
|
109
|
+
private heartbeatTimer;
|
|
110
|
+
private pruneTimer;
|
|
111
|
+
private visibilityHandler;
|
|
112
|
+
private unloadHandler;
|
|
113
|
+
constructor(options: TabRegistryOptions);
|
|
114
|
+
getTabs(): TabInfo[];
|
|
115
|
+
getTabCount(): number;
|
|
116
|
+
getTab(id: string): TabInfo | undefined;
|
|
117
|
+
onTabChange(callback: (tabs: TabInfo[]) => void): () => void;
|
|
118
|
+
announce(): void;
|
|
119
|
+
handleMessage(message: TabMessage): void;
|
|
120
|
+
setLeader(tabId: string | null): void;
|
|
121
|
+
destroy(): void;
|
|
122
|
+
private registerSelf;
|
|
123
|
+
private buildAnnouncePayload;
|
|
124
|
+
private startHeartbeat;
|
|
125
|
+
private startPruning;
|
|
126
|
+
private listenVisibility;
|
|
127
|
+
private listenUnload;
|
|
128
|
+
private sendGoodbye;
|
|
129
|
+
private handleAnnounce;
|
|
130
|
+
private handleGoodbye;
|
|
131
|
+
private touchTab;
|
|
132
|
+
private touchSelf;
|
|
133
|
+
private pruneDeadTabs;
|
|
134
|
+
private notifyChange;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
interface LeaderElectionOptions {
|
|
138
|
+
send: SendFn;
|
|
139
|
+
tabId: string;
|
|
140
|
+
tabCreatedAt: number;
|
|
141
|
+
/** Time (ms) to wait for a higher-priority claim before becoming leader. Default: `300` */
|
|
142
|
+
electionTimeout?: number;
|
|
143
|
+
/** Heartbeat interval (ms). Default: `2000` */
|
|
144
|
+
heartbeatInterval?: number;
|
|
145
|
+
/** How many missed heartbeats before declaring leader dead. Default: `3` */
|
|
146
|
+
missedHeartbeatsLimit?: number;
|
|
147
|
+
}
|
|
148
|
+
declare class LeaderElection {
|
|
149
|
+
private readonly send;
|
|
150
|
+
private readonly tabId;
|
|
151
|
+
private readonly tabCreatedAt;
|
|
152
|
+
private readonly electionTimeout;
|
|
153
|
+
private readonly heartbeatInterval;
|
|
154
|
+
private readonly leaderTimeout;
|
|
155
|
+
private leaderId;
|
|
156
|
+
private electionTimer;
|
|
157
|
+
private heartbeatTimer;
|
|
158
|
+
private leaderWatchTimer;
|
|
159
|
+
private lastLeaderHeartbeat;
|
|
160
|
+
private electing;
|
|
161
|
+
private readonly leaderCallbacks;
|
|
162
|
+
private readonly leaderCleanups;
|
|
163
|
+
constructor(options: LeaderElectionOptions);
|
|
164
|
+
isLeader(): boolean;
|
|
165
|
+
getLeaderId(): string | null;
|
|
166
|
+
onLeader(callback: () => void | (() => void)): () => void;
|
|
167
|
+
start(): void;
|
|
168
|
+
handleMessage(message: TabMessage): void;
|
|
169
|
+
destroy(): void;
|
|
170
|
+
private startElection;
|
|
171
|
+
private handleClaim;
|
|
172
|
+
private handleAck;
|
|
173
|
+
private handleHeartbeat;
|
|
174
|
+
private handleResign;
|
|
175
|
+
private becomeLeader;
|
|
176
|
+
private setLeader;
|
|
177
|
+
/**
|
|
178
|
+
* Priority: oldest tab (smaller `createdAt`) wins.
|
|
179
|
+
* Tiebreak: lower `tabId` wins (deterministic).
|
|
180
|
+
*/
|
|
181
|
+
private hasPriority;
|
|
182
|
+
private startHeartbeat;
|
|
183
|
+
private clearHeartbeat;
|
|
184
|
+
private startLeaderWatch;
|
|
185
|
+
private clearLeaderWatch;
|
|
186
|
+
private clearElectionTimer;
|
|
187
|
+
private runCleanups;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
interface RPCHandlerOptions {
|
|
191
|
+
send: SendFn;
|
|
192
|
+
tabId: string;
|
|
193
|
+
resolveLeaderId?: () => string | null;
|
|
194
|
+
onError?: (error: Error) => void;
|
|
195
|
+
}
|
|
196
|
+
declare class RPCHandler {
|
|
197
|
+
private readonly send;
|
|
198
|
+
private readonly tabId;
|
|
199
|
+
private readonly resolveLeaderId;
|
|
200
|
+
private readonly onError;
|
|
201
|
+
private readonly handlers;
|
|
202
|
+
private readonly pending;
|
|
203
|
+
constructor(options: RPCHandlerOptions);
|
|
204
|
+
call<TResult>(targetTabId: string | 'leader', method: string, args?: unknown, timeout?: number): Promise<TResult>;
|
|
205
|
+
handle<TArgs = unknown, TResult = unknown>(method: string, handler: (args: TArgs, callerTabId: string) => TResult | Promise<TResult>): () => void;
|
|
206
|
+
handleMessage(message: TabMessage): void;
|
|
207
|
+
destroy(): void;
|
|
208
|
+
private handleRequest;
|
|
209
|
+
private handleResponse;
|
|
210
|
+
private sendResponse;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Runs the middleware pipeline for a given hook (`onSet`).
|
|
215
|
+
* Returns the (possibly transformed) value and whether the change was rejected.
|
|
216
|
+
*/
|
|
217
|
+
declare function runMiddleware<TState extends Record<string, unknown>>(middlewares: readonly Middleware<TState>[], ctx: MiddlewareContext<TState>): {
|
|
218
|
+
value: unknown;
|
|
219
|
+
rejected: boolean;
|
|
220
|
+
};
|
|
221
|
+
/** Notify all middlewares that a state change has been committed. */
|
|
222
|
+
declare function notifyMiddleware<TState extends Record<string, unknown>>(middlewares: readonly Middleware<TState>[], key: keyof TState, value: unknown, meta: ChangeMeta): void;
|
|
223
|
+
/** Destroy all middlewares. */
|
|
224
|
+
declare function destroyMiddleware<TState extends Record<string, unknown>>(middlewares: readonly Middleware<TState>[]): void;
|
|
225
|
+
|
|
226
|
+
declare function generateTabId(): string;
|
|
227
|
+
|
|
228
|
+
declare function monotonic(): number;
|
|
229
|
+
|
|
230
|
+
interface Batcher<T> {
|
|
231
|
+
/** Queue a key-value pair. Resets the flush timer if not already running. */
|
|
232
|
+
add(key: string, value: T): void;
|
|
233
|
+
/** Immediately flush all pending entries. */
|
|
234
|
+
flush(): void;
|
|
235
|
+
/** Cancel pending flush and discard all entries. */
|
|
236
|
+
destroy(): void;
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Batches rapid writes into a single flush callback.
|
|
240
|
+
* Within the `delay` window, only the last value per key is kept.
|
|
241
|
+
*/
|
|
242
|
+
declare function createBatcher<T>(onFlush: (entries: Map<string, T>) => void, delay?: number): Batcher<T>;
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Type-safe message factory. Guarantees every message has a correct
|
|
246
|
+
* structure, protocol version, and monotonically increasing timestamp.
|
|
247
|
+
*
|
|
248
|
+
* ```ts
|
|
249
|
+
* const msg = createMessage('STATE_UPDATE', tabId, { entries: { ... } });
|
|
250
|
+
* // ^? MessageOf<'STATE_UPDATE'> — payload is StateUpdatePayload
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
253
|
+
declare function createMessage<T extends MessageType>(type: T, senderId: string, payload: MessagePayloadMap[T], targetId?: string): MessageOf<T>;
|
|
254
|
+
|
|
255
|
+
type Handler<T = void> = T extends void ? () => void : (data: T) => void;
|
|
256
|
+
/**
|
|
257
|
+
* Minimal, fully typed event emitter.
|
|
258
|
+
*
|
|
259
|
+
* ```ts
|
|
260
|
+
* const bus = new Emitter<{ click: { x: number }; close: void }>();
|
|
261
|
+
* bus.on('click', ({ x }) => console.log(x));
|
|
262
|
+
* bus.emit('click', { x: 42 });
|
|
263
|
+
* ```
|
|
264
|
+
*/
|
|
265
|
+
declare class Emitter<TEvents extends Record<string, unknown>> {
|
|
266
|
+
private readonly _handlers;
|
|
267
|
+
on<K extends keyof TEvents>(event: K, handler: Handler<TEvents[K]>): () => void;
|
|
268
|
+
once<K extends keyof TEvents>(event: K, handler: Handler<TEvents[K]>): () => void;
|
|
269
|
+
emit<K extends keyof TEvents>(...args: TEvents[K] extends void ? [event: K] : [event: K, data: TEvents[K]]): void;
|
|
270
|
+
listenerCount<K extends keyof TEvents>(event: K): number;
|
|
271
|
+
removeAll(event?: keyof TEvents): void;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
declare const ErrorCode: {
|
|
275
|
+
readonly CHANNEL_CLOSED: "CHANNEL_CLOSED";
|
|
276
|
+
readonly CHANNEL_SEND_FAILED: "CHANNEL_SEND_FAILED";
|
|
277
|
+
readonly RPC_TIMEOUT: "RPC_TIMEOUT";
|
|
278
|
+
readonly RPC_NO_HANDLER: "RPC_NO_HANDLER";
|
|
279
|
+
readonly RPC_NO_LEADER: "RPC_NO_LEADER";
|
|
280
|
+
readonly RPC_HANDLER_ERROR: "RPC_HANDLER_ERROR";
|
|
281
|
+
readonly RPC_DESTROYED: "RPC_DESTROYED";
|
|
282
|
+
readonly STORAGE_QUOTA_EXCEEDED: "STORAGE_QUOTA_EXCEEDED";
|
|
283
|
+
readonly MIDDLEWARE_REJECTED: "MIDDLEWARE_REJECTED";
|
|
284
|
+
readonly ALREADY_DESTROYED: "ALREADY_DESTROYED";
|
|
285
|
+
};
|
|
286
|
+
type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode];
|
|
287
|
+
declare class TabSyncError extends Error {
|
|
288
|
+
readonly code: ErrorCode;
|
|
289
|
+
readonly name = "TabSyncError";
|
|
290
|
+
readonly cause?: unknown;
|
|
291
|
+
constructor(message: string, code: ErrorCode, cause?: unknown);
|
|
292
|
+
static timeout(method: string, ms: number): TabSyncError;
|
|
293
|
+
static noLeader(): TabSyncError;
|
|
294
|
+
static noHandler(method: string): TabSyncError;
|
|
295
|
+
static destroyed(): TabSyncError;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
declare const isBrowser: boolean;
|
|
299
|
+
declare const hasDocument: boolean;
|
|
300
|
+
declare const hasLocalStorage: boolean;
|
|
301
|
+
declare const hasBroadcastChannel: boolean;
|
|
302
|
+
declare const hasCrypto: boolean;
|
|
303
|
+
|
|
304
|
+
export { type Batcher, BroadcastChannelTransport, ChangeMeta, type Channel, Emitter, ErrorCode, LeaderElection, type LeaderElectionOptions, MessageOf, MessagePayloadMap, MessageType, Middleware, MiddlewareContext, RPCHandler, type RPCHandlerOptions, RPCMap, SendFn, StateManager, type StateManagerOptions, StorageChannel, TabInfo, TabMessage, TabRegistry, type TabRegistryOptions, TabSyncError, TabSyncInstance, TabSyncOptions, createBatcher, createChannel, createMessage, createTabSync, destroyMiddleware, generateTabId, hasBroadcastChannel, hasCrypto, hasDocument, hasLocalStorage, isBrowser, monotonic, notifyMiddleware, runMiddleware };
|