use-everywhere 0.6.0 → 0.8.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/dist/{chunk-YOXUZYKA.js → chunk-75TICQ7E.js} +75 -14
- package/dist/devtools/index.cjs +14 -5
- package/dist/devtools/index.js +1 -1
- package/dist/index.cjs +270 -66
- package/dist/index.d.cts +242 -10
- package/dist/index.d.ts +242 -10
- package/dist/index.js +171 -27
- package/package.json +23 -11
package/dist/index.cjs
CHANGED
|
@@ -21,41 +21,57 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
// src/index.ts
|
|
22
22
|
var src_exports = {};
|
|
23
23
|
__export(src_exports, {
|
|
24
|
-
BroadcastChannelTransport: () =>
|
|
25
|
-
CID_PARAM: () =>
|
|
24
|
+
BroadcastChannelTransport: () => import_core4.BroadcastChannelTransport,
|
|
25
|
+
CID_PARAM: () => import_core4.CID_PARAM,
|
|
26
26
|
DEFAULT_NAME: () => import_core.DEFAULT_NAME,
|
|
27
|
-
HandshakeTimeoutError: () =>
|
|
28
|
-
NoopTransport: () =>
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
27
|
+
HandshakeTimeoutError: () => import_core4.HandshakeTimeoutError,
|
|
28
|
+
NoopTransport: () => import_core4.NoopTransport,
|
|
29
|
+
StorageTransport: () => import_core4.StorageTransport,
|
|
30
|
+
WIRE_VERSION: () => import_core4.WIRE_VERSION,
|
|
31
|
+
WindowClosedError: () => import_core4.WindowClosedError,
|
|
32
|
+
connectToOpener: () => import_core4.connectToOpener,
|
|
33
|
+
createChannel: () => import_core4.createChannel,
|
|
34
|
+
createLeader: () => import_core4.createLeader,
|
|
35
|
+
createNamespace: () => createNamespace,
|
|
36
|
+
createPresence: () => import_core4.createPresence,
|
|
37
|
+
createSharedReducer: () => import_core4.createSharedReducer,
|
|
38
|
+
createSharedStore: () => import_core4.createSharedStore,
|
|
39
|
+
defaultTransport: () => import_core4.defaultTransport,
|
|
36
40
|
defineChannel: () => defineChannel,
|
|
37
41
|
defineStore: () => defineStore,
|
|
38
|
-
enableDebug: () =>
|
|
39
|
-
getBusNames: () =>
|
|
42
|
+
enableDebug: () => import_core4.enableDebug,
|
|
43
|
+
getBusNames: () => import_core4.getBusNames,
|
|
40
44
|
getLeader: () => getLeader,
|
|
41
45
|
getSharedStore: () => getSharedStore,
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
getTransportKind: () => import_core4.getTransportKind,
|
|
47
|
+
getWireSkew: () => import_core4.getWireSkew,
|
|
48
|
+
indexedDbAdapter: () => import_core4.indexedDbAdapter,
|
|
49
|
+
isBroadcastChannelAvailable: () => import_core4.isBroadcastChannelAvailable,
|
|
50
|
+
isStorageEventAvailable: () => import_core4.isStorageEventAvailable,
|
|
51
|
+
jsonSerializer: () => import_core4.jsonSerializer,
|
|
52
|
+
localStorageAdapter: () => import_core4.localStorageAdapter,
|
|
53
|
+
newer: () => import_core4.newer,
|
|
54
|
+
observeBus: () => import_core4.observeBus,
|
|
55
|
+
openWindow: () => import_core4.openWindow,
|
|
56
|
+
sessionStorageAdapter: () => import_core4.sessionStorageAdapter,
|
|
57
|
+
shallowEqual: () => shallowEqual,
|
|
58
|
+
useAnswer: () => useAnswer,
|
|
59
|
+
useAsk: () => useAsk,
|
|
48
60
|
useChannel: () => useChannel,
|
|
49
61
|
useClientId: () => useClientId,
|
|
62
|
+
useHydrated: () => useHydrated,
|
|
50
63
|
useIsLeader: () => useIsLeader,
|
|
51
64
|
useLeader: () => useLeader,
|
|
52
65
|
useLeaderEffect: () => useLeaderEffect,
|
|
53
66
|
useMessage: () => useMessage,
|
|
54
67
|
useOpenedWindow: () => useOpenedWindow,
|
|
55
68
|
usePeers: () => usePeers,
|
|
69
|
+
usePresenceMetadata: () => usePresenceMetadata,
|
|
56
70
|
useSend: () => useSend,
|
|
71
|
+
useSharedReducer: () => useSharedReducer,
|
|
57
72
|
useSharedState: () => useSharedState,
|
|
58
|
-
|
|
73
|
+
useSharedStore: () => useSharedStore,
|
|
74
|
+
webStorageAdapter: () => import_core4.webStorageAdapter
|
|
59
75
|
});
|
|
60
76
|
module.exports = __toCommonJS(src_exports);
|
|
61
77
|
|
|
@@ -104,6 +120,12 @@ var unsubscribe = () => noop;
|
|
|
104
120
|
var INERT = Object.freeze({
|
|
105
121
|
clientId: SERVER_CLIENT_ID,
|
|
106
122
|
// store
|
|
123
|
+
//
|
|
124
|
+
// Resolved, unlike the leader's `waitForLeadership` below. A server render
|
|
125
|
+
// has nothing to restore and is documented to render defaults, so `await
|
|
126
|
+
// store.hydrated` must proceed — a never-settling promise would hang the
|
|
127
|
+
// render rather than describe it honestly.
|
|
128
|
+
hydrated: Promise.resolve(),
|
|
107
129
|
state: EMPTY,
|
|
108
130
|
getVersions: () => EMPTY,
|
|
109
131
|
set: noop,
|
|
@@ -112,6 +134,8 @@ var INERT = Object.freeze({
|
|
|
112
134
|
// store + leader share getSnapshot; presence has getPeers
|
|
113
135
|
getSnapshot: () => EMPTY,
|
|
114
136
|
getPeers: () => NO_PEERS,
|
|
137
|
+
// presence
|
|
138
|
+
setMetadata: noop,
|
|
115
139
|
// leader
|
|
116
140
|
resign: noop,
|
|
117
141
|
setEligible: noop,
|
|
@@ -122,7 +146,20 @@ var INERT = Object.freeze({
|
|
|
122
146
|
var createServerStore = () => INERT;
|
|
123
147
|
var createServerPresence = () => INERT;
|
|
124
148
|
var NO_LEADER = Object.freeze({ leaderId: null, isLeader: false });
|
|
125
|
-
var
|
|
149
|
+
var NEVER = () => new Promise(() => {
|
|
150
|
+
});
|
|
151
|
+
var createServerLeader = () => ({
|
|
152
|
+
...INERT,
|
|
153
|
+
strategy: "heartbeat",
|
|
154
|
+
getSnapshot: () => NO_LEADER,
|
|
155
|
+
waitForLeadership: NEVER
|
|
156
|
+
});
|
|
157
|
+
var createServerReducer = (initial) => ({
|
|
158
|
+
...INERT,
|
|
159
|
+
getSnapshot: () => initial,
|
|
160
|
+
dispatch: noop,
|
|
161
|
+
pendingCount: () => 0
|
|
162
|
+
});
|
|
126
163
|
var createServerChannel = (name) => ({ ...INERT, name, post: noop, on: unsubscribe });
|
|
127
164
|
|
|
128
165
|
// src/registry.ts
|
|
@@ -143,15 +180,17 @@ function getSharedStore(name = import_core.DEFAULT_NAME, scope = "everywhere") {
|
|
|
143
180
|
function configSignature(options) {
|
|
144
181
|
const persist = options?.persist;
|
|
145
182
|
if (!persist) return "none";
|
|
146
|
-
return `persist:${persist.keys?.join(",") ?? "*"}:${persist.debounceMs ?? "default"}`;
|
|
183
|
+
return `persist:${persist.keys?.join(",") ?? "*"}:${persist.debounceMs ?? "default"}:v${persist.version ?? 0}`;
|
|
147
184
|
}
|
|
148
185
|
function configureStore(name, scope, options) {
|
|
149
186
|
const key = `${scope} ${name}`;
|
|
150
187
|
if (stores.has(key)) {
|
|
151
188
|
if (configSignature(storeConfig.get(key)) === configSignature(options)) return;
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
189
|
+
if (process.env.NODE_ENV !== "production") {
|
|
190
|
+
devWarn(
|
|
191
|
+
`[use-everywhere] defineStore('${name}') ran after that store was already created, with different options. The live store keeps the configuration it was built with. Move defineStore to module scope, before any component reads the store.`
|
|
192
|
+
);
|
|
193
|
+
}
|
|
155
194
|
return;
|
|
156
195
|
}
|
|
157
196
|
storeConfig.set(key, options);
|
|
@@ -165,11 +204,12 @@ function getStore(name, scope = "everywhere") {
|
|
|
165
204
|
}
|
|
166
205
|
return store;
|
|
167
206
|
}
|
|
168
|
-
function getPresence(name) {
|
|
169
|
-
|
|
207
|
+
function getPresence(name, includeSelf = false) {
|
|
208
|
+
const key = includeSelf ? `self ${name}` : name;
|
|
209
|
+
let presence = presences.get(key);
|
|
170
210
|
if (!presence) {
|
|
171
|
-
presence = isServer() ? createServerPresence() : (0, import_core.createPresence)(name);
|
|
172
|
-
presences.set(
|
|
211
|
+
presence = isServer() ? createServerPresence() : (0, import_core.createPresence)(name, { includeSelf });
|
|
212
|
+
presences.set(key, presence);
|
|
173
213
|
}
|
|
174
214
|
return presence;
|
|
175
215
|
}
|
|
@@ -190,16 +230,43 @@ function warnOnLeaderOptionConflict(name, options) {
|
|
|
190
230
|
for (const key of ["heartbeatMs", "leaseMs"]) {
|
|
191
231
|
const requested = options[key];
|
|
192
232
|
if (requested !== void 0 && requested !== first?.[key]) {
|
|
233
|
+
if (process.env.NODE_ENV !== "production") {
|
|
234
|
+
devWarn(
|
|
235
|
+
`[use-everywhere] leader "${name}": ${key} ignored \u2014 the first useLeader/getLeader call fixes the election timings for this tab.`
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
var channelConfig = /* @__PURE__ */ new Map();
|
|
242
|
+
function configureChannel(name, options) {
|
|
243
|
+
if (channels.has(name)) {
|
|
244
|
+
const before = Object.keys(channelConfig.get(name)?.schema ?? {}).sort();
|
|
245
|
+
const after = Object.keys(options.schema ?? {}).sort();
|
|
246
|
+
if (before.join() === after.join()) return;
|
|
247
|
+
if (process.env.NODE_ENV !== "production") {
|
|
193
248
|
devWarn(
|
|
194
|
-
`[use-everywhere]
|
|
249
|
+
`[use-everywhere] defineChannel('${name}') ran after that channel was already created, with different options. The live channel keeps the configuration it was built with. Move defineChannel to module scope, before any component sends or receives on it.`
|
|
195
250
|
);
|
|
196
251
|
}
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
channelConfig.set(name, options);
|
|
255
|
+
}
|
|
256
|
+
var reducers = /* @__PURE__ */ new Map();
|
|
257
|
+
function getReducer(name, key, reducer, initial) {
|
|
258
|
+
const id = `${name} ${key}`;
|
|
259
|
+
let existing = reducers.get(id);
|
|
260
|
+
if (!existing) {
|
|
261
|
+
existing = isServer() ? createServerReducer(initial) : (0, import_core.createSharedReducer)(name, reducer, initial, { key, leader: getLeader(name) });
|
|
262
|
+
reducers.set(id, existing);
|
|
197
263
|
}
|
|
264
|
+
return existing;
|
|
198
265
|
}
|
|
199
266
|
function getChannel(name) {
|
|
200
267
|
let channel = channels.get(name);
|
|
201
268
|
if (!channel) {
|
|
202
|
-
channel = isServer() ? createServerChannel(name) : (0, import_core.createChannel)(name);
|
|
269
|
+
channel = isServer() ? createServerChannel(name) : (0, import_core.createChannel)(name, channelConfig.get(name));
|
|
203
270
|
channels.set(name, channel);
|
|
204
271
|
}
|
|
205
272
|
return channel;
|
|
@@ -210,7 +277,9 @@ function useSharedState(key, initial, options) {
|
|
|
210
277
|
const storeName = options?.store ?? import_core.DEFAULT_NAME;
|
|
211
278
|
const store = getStore(storeName, options?.scope ?? "everywhere");
|
|
212
279
|
store.registerKey(key, initial);
|
|
213
|
-
|
|
280
|
+
if (process.env.NODE_ENV !== "production") {
|
|
281
|
+
warnOnInitialMismatch(storeName, key, initial);
|
|
282
|
+
}
|
|
214
283
|
const value = (0, import_react.useSyncExternalStore)(
|
|
215
284
|
(0, import_react.useCallback)((onChange) => store.subscribeKey(key, onChange), [store, key]),
|
|
216
285
|
() => store.getSnapshot()[key],
|
|
@@ -223,27 +292,98 @@ function useSharedState(key, initial, options) {
|
|
|
223
292
|
return [value, setValue];
|
|
224
293
|
}
|
|
225
294
|
|
|
226
|
-
// src/use-
|
|
295
|
+
// src/use-shared-reducer.ts
|
|
227
296
|
var import_react2 = require("react");
|
|
297
|
+
function useSharedReducer(reducer, initial, options) {
|
|
298
|
+
const engine = getReducer(
|
|
299
|
+
options?.name ?? import_core.DEFAULT_NAME,
|
|
300
|
+
options?.key ?? "default",
|
|
301
|
+
reducer,
|
|
302
|
+
initial
|
|
303
|
+
);
|
|
304
|
+
const value = (0, import_react2.useSyncExternalStore)(
|
|
305
|
+
(0, import_react2.useCallback)((onChange) => engine.subscribe(onChange), [engine]),
|
|
306
|
+
() => engine.getSnapshot(),
|
|
307
|
+
() => initial
|
|
308
|
+
);
|
|
309
|
+
const dispatch = (0, import_react2.useCallback)((action) => engine.dispatch(action), [engine]);
|
|
310
|
+
return [value, dispatch];
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// src/use-shared-selector.ts
|
|
314
|
+
var import_react3 = require("react");
|
|
315
|
+
function useSharedStore(selector, options) {
|
|
316
|
+
const store = getStore(options?.store ?? import_core.DEFAULT_NAME, options?.scope ?? "everywhere");
|
|
317
|
+
const equal = options?.equal ?? Object.is;
|
|
318
|
+
const selectorRef = (0, import_react3.useRef)(selector);
|
|
319
|
+
selectorRef.current = selector;
|
|
320
|
+
const equalRef = (0, import_react3.useRef)(equal);
|
|
321
|
+
equalRef.current = equal;
|
|
322
|
+
const cache = (0, import_react3.useRef)(null);
|
|
323
|
+
const getSelection = (0, import_react3.useCallback)(() => {
|
|
324
|
+
const source = store.getSnapshot();
|
|
325
|
+
const select = selectorRef.current;
|
|
326
|
+
const previous = cache.current;
|
|
327
|
+
if (previous && previous.source === source && previous.select === select) return previous.value;
|
|
328
|
+
const next = select(source);
|
|
329
|
+
const value = previous && equalRef.current(previous.value, next) ? previous.value : next;
|
|
330
|
+
cache.current = { source, select, value };
|
|
331
|
+
return value;
|
|
332
|
+
}, [store]);
|
|
333
|
+
return (0, import_react3.useSyncExternalStore)(
|
|
334
|
+
(0, import_react3.useCallback)((onChange) => store.subscribe(onChange), [store]),
|
|
335
|
+
getSelection,
|
|
336
|
+
getSelection
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
function shallowEqual(a, b) {
|
|
340
|
+
if (Object.is(a, b)) return true;
|
|
341
|
+
if (typeof a !== "object" || a === null || typeof b !== "object" || b === null) return false;
|
|
342
|
+
const left = a;
|
|
343
|
+
const right = b;
|
|
344
|
+
const keys = Object.keys(left);
|
|
345
|
+
if (keys.length !== Object.keys(right).length) return false;
|
|
346
|
+
return keys.every((key) => Object.is(left[key], right[key]));
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// src/use-message.ts
|
|
350
|
+
var import_react4 = require("react");
|
|
228
351
|
function useChannel(name) {
|
|
229
352
|
return getChannel(name);
|
|
230
353
|
}
|
|
231
|
-
function useMessage(channel, type, handler) {
|
|
232
|
-
const handlerRef = (0,
|
|
233
|
-
(0,
|
|
354
|
+
function useMessage(channel, type, handler, options) {
|
|
355
|
+
const handlerRef = (0, import_react4.useRef)(handler);
|
|
356
|
+
(0, import_react4.useEffect)(() => {
|
|
234
357
|
handlerRef.current = handler;
|
|
235
358
|
});
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
359
|
+
const enabled = options?.enabled ?? true;
|
|
360
|
+
const once = options?.once ?? false;
|
|
361
|
+
(0, import_react4.useEffect)(() => {
|
|
362
|
+
if (!enabled) return;
|
|
363
|
+
return channel.on(type, (payload, meta) => handlerRef.current(payload, meta), { once });
|
|
364
|
+
}, [channel, type, enabled, once]);
|
|
365
|
+
}
|
|
366
|
+
function useAnswer(channel, type, responder, options) {
|
|
367
|
+
const responderRef = (0, import_react4.useRef)(responder);
|
|
368
|
+
(0, import_react4.useEffect)(() => {
|
|
369
|
+
responderRef.current = responder;
|
|
370
|
+
});
|
|
371
|
+
const enabled = options?.enabled ?? true;
|
|
372
|
+
(0, import_react4.useEffect)(() => {
|
|
373
|
+
if (!enabled) return;
|
|
374
|
+
return channel.answer(type, (payload, meta) => responderRef.current(payload, meta));
|
|
375
|
+
}, [channel, type, enabled]);
|
|
240
376
|
}
|
|
241
377
|
function useSend(channel) {
|
|
242
378
|
return channel.post;
|
|
243
379
|
}
|
|
380
|
+
function useAsk(channel) {
|
|
381
|
+
return channel.ask;
|
|
382
|
+
}
|
|
244
383
|
|
|
245
384
|
// src/define-channel.ts
|
|
246
|
-
function defineChannel(name) {
|
|
385
|
+
function defineChannel(name, options) {
|
|
386
|
+
if (options) configureChannel(name, options);
|
|
247
387
|
const useBoundSend = () => useSend(useChannel(name));
|
|
248
388
|
const useBoundMessage = (type, handler) => useMessage(useChannel(name), type, handler);
|
|
249
389
|
return {
|
|
@@ -261,7 +401,10 @@ function defineStore(name, options = {}) {
|
|
|
261
401
|
persist: {
|
|
262
402
|
adapter: options.persist,
|
|
263
403
|
...options.persistKeys ? { keys: options.persistKeys } : {},
|
|
264
|
-
...options.persistDebounceMs === void 0 ? {} : { debounceMs: options.persistDebounceMs }
|
|
404
|
+
...options.persistDebounceMs === void 0 ? {} : { debounceMs: options.persistDebounceMs },
|
|
405
|
+
...options.persistVersion === void 0 ? {} : { version: options.persistVersion },
|
|
406
|
+
...options.migrate ? { migrate: options.migrate } : {},
|
|
407
|
+
...options.onRestoreError ? { onRestoreError: options.onRestoreError } : {}
|
|
265
408
|
}
|
|
266
409
|
});
|
|
267
410
|
}
|
|
@@ -272,41 +415,64 @@ function defineStore(name, options = {}) {
|
|
|
272
415
|
}
|
|
273
416
|
|
|
274
417
|
// src/use-peers.ts
|
|
275
|
-
var
|
|
418
|
+
var import_react5 = require("react");
|
|
276
419
|
var NO_PEERS2 = Object.freeze([]);
|
|
277
420
|
function usePeers(options) {
|
|
278
|
-
const presence = getPresence(options?.name ?? import_core.DEFAULT_NAME);
|
|
279
|
-
return (0,
|
|
280
|
-
(0,
|
|
421
|
+
const presence = getPresence(options?.name ?? import_core.DEFAULT_NAME, options?.includeSelf ?? false);
|
|
422
|
+
return (0, import_react5.useSyncExternalStore)(
|
|
423
|
+
(0, import_react5.useCallback)((onChange) => presence.subscribe(onChange), [presence]),
|
|
281
424
|
() => presence.getPeers(),
|
|
282
425
|
() => NO_PEERS2
|
|
283
426
|
);
|
|
284
427
|
}
|
|
285
428
|
function useClientId(options) {
|
|
286
429
|
const presence = getPresence(options?.name ?? import_core.DEFAULT_NAME);
|
|
287
|
-
return (0,
|
|
430
|
+
return (0, import_react5.useSyncExternalStore)(
|
|
288
431
|
// The id never changes for the life of a presence engine, so there is
|
|
289
432
|
// nothing to subscribe to — but uSES still needs the post-hydration read,
|
|
290
433
|
// which it performs when it attaches this subscription.
|
|
291
|
-
(0,
|
|
434
|
+
(0, import_react5.useCallback)(() => () => {
|
|
292
435
|
}, [presence]),
|
|
293
436
|
() => presence.clientId,
|
|
294
437
|
() => SERVER_CLIENT_ID
|
|
295
438
|
);
|
|
296
439
|
}
|
|
440
|
+
function usePresenceMetadata(metadata, options) {
|
|
441
|
+
const presence = getPresence(options?.name ?? import_core.DEFAULT_NAME, options?.includeSelf ?? false);
|
|
442
|
+
(0, import_react5.useEffect)(() => {
|
|
443
|
+
presence.setMetadata(metadata);
|
|
444
|
+
}, [presence, metadata]);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// src/use-hydrated.ts
|
|
448
|
+
var import_react6 = require("react");
|
|
449
|
+
function useHydrated(options) {
|
|
450
|
+
const store = getStore(options?.store ?? import_core.DEFAULT_NAME, options?.scope ?? "everywhere");
|
|
451
|
+
const [ready, setReady] = (0, import_react6.useState)(false);
|
|
452
|
+
(0, import_react6.useEffect)(() => {
|
|
453
|
+
let cancelled = false;
|
|
454
|
+
void store.hydrated.then(() => {
|
|
455
|
+
if (!cancelled) setReady(true);
|
|
456
|
+
});
|
|
457
|
+
return () => {
|
|
458
|
+
cancelled = true;
|
|
459
|
+
};
|
|
460
|
+
}, [store]);
|
|
461
|
+
return ready;
|
|
462
|
+
}
|
|
297
463
|
|
|
298
464
|
// src/use-leader.ts
|
|
299
|
-
var
|
|
465
|
+
var import_react7 = require("react");
|
|
300
466
|
var NO_LEADER2 = Object.freeze({ leaderId: null, isLeader: false });
|
|
301
467
|
function useLeader(options) {
|
|
302
468
|
const leader = getLeader(options?.name ?? import_core.DEFAULT_NAME, options);
|
|
303
469
|
const eligible = options?.eligible;
|
|
304
|
-
(0,
|
|
470
|
+
(0, import_react7.useEffect)(() => {
|
|
305
471
|
if (eligible === void 0) return;
|
|
306
472
|
leader.setEligible(eligible);
|
|
307
473
|
}, [leader, eligible]);
|
|
308
|
-
return (0,
|
|
309
|
-
(0,
|
|
474
|
+
return (0, import_react7.useSyncExternalStore)(
|
|
475
|
+
(0, import_react7.useCallback)((onChange) => leader.subscribe(onChange), [leader]),
|
|
310
476
|
() => leader.getSnapshot(),
|
|
311
477
|
() => NO_LEADER2
|
|
312
478
|
);
|
|
@@ -316,32 +482,54 @@ function useIsLeader(options) {
|
|
|
316
482
|
}
|
|
317
483
|
function useLeaderEffect(effect, options) {
|
|
318
484
|
const { isLeader } = useLeader(options);
|
|
319
|
-
const effectRef = (0,
|
|
320
|
-
(0,
|
|
485
|
+
const effectRef = (0, import_react7.useRef)(effect);
|
|
486
|
+
(0, import_react7.useEffect)(() => {
|
|
321
487
|
effectRef.current = effect;
|
|
322
488
|
});
|
|
323
|
-
(0,
|
|
489
|
+
(0, import_react7.useEffect)(() => {
|
|
324
490
|
if (!isLeader) return;
|
|
325
491
|
return effectRef.current();
|
|
326
492
|
}, [isLeader]);
|
|
327
493
|
}
|
|
328
494
|
|
|
329
|
-
// src/
|
|
330
|
-
var import_react5 = require("react");
|
|
495
|
+
// src/namespace.ts
|
|
331
496
|
var import_core2 = require("@use-everywhere/core");
|
|
497
|
+
function createNamespace(namespace) {
|
|
498
|
+
const core = (0, import_core2.createNamespace)(namespace);
|
|
499
|
+
const { busName } = core;
|
|
500
|
+
return {
|
|
501
|
+
...core,
|
|
502
|
+
defineStore: (name, options) => defineStore(busName(name), options),
|
|
503
|
+
defineChannel: (name, options) => defineChannel(busName(name), options),
|
|
504
|
+
getSharedStore: (name, scope) => getSharedStore(busName(name), scope),
|
|
505
|
+
useSharedState: (key, initial, options) => useSharedState(key, initial, { ...options, store: busName(options?.store) }),
|
|
506
|
+
useSharedStore: (selector, options) => useSharedStore(selector, { ...options, store: busName(options?.store) }),
|
|
507
|
+
usePeers: (options) => usePeers({ ...options, name: busName(options?.name) }),
|
|
508
|
+
usePresenceMetadata: (metadata, options) => usePresenceMetadata(metadata, { ...options, name: busName(options?.name) }),
|
|
509
|
+
useHydrated: (options) => useHydrated({ ...options, store: busName(options?.store) }),
|
|
510
|
+
useClientId: (options) => useClientId({ name: busName(options?.name) }),
|
|
511
|
+
useLeader: (options) => useLeader({ ...options, name: busName(options?.name) }),
|
|
512
|
+
useIsLeader: (options) => useIsLeader({ ...options, name: busName(options?.name) }),
|
|
513
|
+
useLeaderEffect: (effect, options) => useLeaderEffect(effect, { ...options, name: busName(options?.name) })
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
// src/use-opened-window.ts
|
|
518
|
+
var import_react8 = require("react");
|
|
519
|
+
var import_core3 = require("@use-everywhere/core");
|
|
332
520
|
var IDLE = Object.freeze({
|
|
333
521
|
status: "idle",
|
|
334
522
|
result: void 0,
|
|
335
523
|
error: void 0
|
|
336
524
|
});
|
|
337
525
|
function useOpenedWindow(factory) {
|
|
338
|
-
const [state, setState] = (0,
|
|
339
|
-
const current = (0,
|
|
340
|
-
const factoryRef = (0,
|
|
341
|
-
(0,
|
|
526
|
+
const [state, setState] = (0, import_react8.useState)(IDLE);
|
|
527
|
+
const current = (0, import_react8.useRef)(null);
|
|
528
|
+
const factoryRef = (0, import_react8.useRef)(factory);
|
|
529
|
+
(0, import_react8.useEffect)(() => {
|
|
342
530
|
factoryRef.current = factory;
|
|
343
531
|
});
|
|
344
|
-
const open = (0,
|
|
532
|
+
const open = (0, import_react8.useCallback)(() => {
|
|
345
533
|
current.current?.close();
|
|
346
534
|
let opened;
|
|
347
535
|
try {
|
|
@@ -371,20 +559,20 @@ function useOpenedWindow(factory) {
|
|
|
371
559
|
(err) => {
|
|
372
560
|
if (!fresh()) return;
|
|
373
561
|
setState(
|
|
374
|
-
err instanceof
|
|
562
|
+
err instanceof import_core3.WindowClosedError ? { status: "closed-early", result: void 0, error: err } : { status: "error", result: void 0, error: err }
|
|
375
563
|
);
|
|
376
564
|
}
|
|
377
565
|
);
|
|
378
566
|
}, []);
|
|
379
|
-
const post = (0,
|
|
567
|
+
const post = (0, import_react8.useCallback)((type, payload) => {
|
|
380
568
|
current.current?.post(type, payload);
|
|
381
569
|
}, []);
|
|
382
|
-
const close = (0,
|
|
570
|
+
const close = (0, import_react8.useCallback)(() => current.current?.close(), []);
|
|
383
571
|
return { ...state, open, post, close };
|
|
384
572
|
}
|
|
385
573
|
|
|
386
574
|
// src/index.ts
|
|
387
|
-
var
|
|
575
|
+
var import_core4 = require("@use-everywhere/core");
|
|
388
576
|
// Annotate the CommonJS export names for ESM import in node:
|
|
389
577
|
0 && (module.exports = {
|
|
390
578
|
BroadcastChannelTransport,
|
|
@@ -392,11 +580,15 @@ var import_core3 = require("@use-everywhere/core");
|
|
|
392
580
|
DEFAULT_NAME,
|
|
393
581
|
HandshakeTimeoutError,
|
|
394
582
|
NoopTransport,
|
|
583
|
+
StorageTransport,
|
|
584
|
+
WIRE_VERSION,
|
|
395
585
|
WindowClosedError,
|
|
396
586
|
connectToOpener,
|
|
397
587
|
createChannel,
|
|
398
588
|
createLeader,
|
|
589
|
+
createNamespace,
|
|
399
590
|
createPresence,
|
|
591
|
+
createSharedReducer,
|
|
400
592
|
createSharedStore,
|
|
401
593
|
defaultTransport,
|
|
402
594
|
defineChannel,
|
|
@@ -405,21 +597,33 @@ var import_core3 = require("@use-everywhere/core");
|
|
|
405
597
|
getBusNames,
|
|
406
598
|
getLeader,
|
|
407
599
|
getSharedStore,
|
|
600
|
+
getTransportKind,
|
|
601
|
+
getWireSkew,
|
|
602
|
+
indexedDbAdapter,
|
|
408
603
|
isBroadcastChannelAvailable,
|
|
604
|
+
isStorageEventAvailable,
|
|
605
|
+
jsonSerializer,
|
|
409
606
|
localStorageAdapter,
|
|
410
607
|
newer,
|
|
411
608
|
observeBus,
|
|
412
609
|
openWindow,
|
|
413
610
|
sessionStorageAdapter,
|
|
611
|
+
shallowEqual,
|
|
612
|
+
useAnswer,
|
|
613
|
+
useAsk,
|
|
414
614
|
useChannel,
|
|
415
615
|
useClientId,
|
|
616
|
+
useHydrated,
|
|
416
617
|
useIsLeader,
|
|
417
618
|
useLeader,
|
|
418
619
|
useLeaderEffect,
|
|
419
620
|
useMessage,
|
|
420
621
|
useOpenedWindow,
|
|
421
622
|
usePeers,
|
|
623
|
+
usePresenceMetadata,
|
|
422
624
|
useSend,
|
|
625
|
+
useSharedReducer,
|
|
423
626
|
useSharedState,
|
|
627
|
+
useSharedStore,
|
|
424
628
|
webStorageAdapter
|
|
425
629
|
});
|