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