use-everywhere 1.0.0 → 1.0.2

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/index.cjs CHANGED
@@ -1,644 +1,688 @@
1
1
  'use client';
2
- "use strict";
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, { get: all[name], enumerable: true });
10
- };
11
- var __copyProps = (to, from, except, desc) => {
12
- if (from && typeof from === "object" || typeof from === "function") {
13
- for (let key of __getOwnPropNames(from))
14
- if (!__hasOwnProp.call(to, key) && key !== except)
15
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
- }
17
- return to;
18
- };
19
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
-
21
- // src/index.ts
22
- var src_exports = {};
23
- __export(src_exports, {
24
- BroadcastChannelTransport: () => import_core4.BroadcastChannelTransport,
25
- CID_PARAM: () => import_core4.CID_PARAM,
26
- DEFAULT_NAME: () => import_core.DEFAULT_NAME,
27
- HandshakeTimeoutError: () => import_core4.HandshakeTimeoutError,
28
- NoopTransport: () => import_core4.NoopTransport,
29
- SharedWorkerTransport: () => import_core4.SharedWorkerTransport,
30
- StorageTransport: () => import_core4.StorageTransport,
31
- WIRE_VERSION: () => import_core4.WIRE_VERSION,
32
- WindowClosedError: () => import_core4.WindowClosedError,
33
- connectToOpener: () => import_core4.connectToOpener,
34
- createChannel: () => import_core4.createChannel,
35
- createLeader: () => import_core4.createLeader,
36
- createNamespace: () => createNamespace,
37
- createPresence: () => import_core4.createPresence,
38
- createSharedReducer: () => import_core4.createSharedReducer,
39
- createSharedStore: () => import_core4.createSharedStore,
40
- createStoreHooks: () => createStoreHooks,
41
- defaultTransport: () => import_core4.defaultTransport,
42
- defineChannel: () => defineChannel,
43
- enableDebug: () => import_core4.enableDebug,
44
- getBusNames: () => import_core4.getBusNames,
45
- getLeader: () => getLeader,
46
- getSharedStore: () => getSharedStore,
47
- getTransportKind: () => import_core4.getTransportKind,
48
- getWireSkew: () => import_core4.getWireSkew,
49
- indexedDbAdapter: () => import_core4.indexedDbAdapter,
50
- isBroadcastChannelAvailable: () => import_core4.isBroadcastChannelAvailable,
51
- isSharedWorkerAvailable: () => import_core4.isSharedWorkerAvailable,
52
- isStorageEventAvailable: () => import_core4.isStorageEventAvailable,
53
- jsonSerializer: () => import_core4.jsonSerializer,
54
- localStorageAdapter: () => import_core4.localStorageAdapter,
55
- newer: () => import_core4.newer,
56
- observeBus: () => import_core4.observeBus,
57
- openWindow: () => import_core4.openWindow,
58
- sessionStorageAdapter: () => import_core4.sessionStorageAdapter,
59
- shallowEqual: () => shallowEqual,
60
- useAnswer: () => useAnswer,
61
- useAsk: () => useAsk,
62
- useChannel: () => useChannel,
63
- useClientId: () => useClientId,
64
- useHydrated: () => useHydrated,
65
- useIsLeader: () => useIsLeader,
66
- useLeader: () => useLeader,
67
- useLeaderEffect: () => useLeaderEffect,
68
- useOnMessage: () => useOnMessage,
69
- usePeers: () => usePeers,
70
- usePresenceMetadata: () => usePresenceMetadata,
71
- useSend: () => useSend,
72
- useSharedReducer: () => useSharedReducer,
73
- useSharedSelector: () => useSharedSelector,
74
- useSharedState: () => useSharedState,
75
- useWindowResult: () => useWindowResult,
76
- webStorageAdapter: () => import_core4.webStorageAdapter
77
- });
78
- module.exports = __toCommonJS(src_exports);
79
-
80
- // src/use-shared-state.ts
81
- var import_react = require("react");
82
-
83
- // src/dev.ts
84
- var inDev = false;
85
- try {
86
- inDev = process.env.NODE_ENV !== "production";
87
- } catch {
88
- }
89
- var warned = /* @__PURE__ */ new Set();
90
- var DOCS = "https://rxova.org/packages/use-everywhere/errors";
91
- function diagnostic(code, message) {
92
- return `[use-everywhere] ${code}: ${message}
93
- \u2192 ${DOCS}/#${code.toLowerCase()}`;
94
- }
95
- function devWarn(code, message) {
96
- if (!inDev) return;
97
- const line = diagnostic(code, message);
98
- if (warned.has(line)) return;
99
- warned.add(line);
100
- console.warn(line);
101
- }
102
- var seenInitials = /* @__PURE__ */ new Map();
103
- function warnOnInitialMismatch(storeName, key, initial) {
104
- if (!inDev) return;
105
- const id = `${storeName} ${key}`;
106
- if (!seenInitials.has(id)) {
107
- seenInitials.set(id, initial);
108
- return;
109
- }
110
- const first = seenInitials.get(id);
111
- const comparable = (v) => v === null || typeof v !== "object";
112
- if (comparable(first) && comparable(initial) && !Object.is(first, initial)) {
113
- devWarn(
114
- "UE2001",
115
- `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 createStoreHooks, or a shared constant.`
116
- );
117
- }
118
- }
119
-
120
- // src/registry.ts
121
- var import_core = require("@use-everywhere/core");
122
-
123
- // src/server-stubs.ts
124
- var SERVER_CLIENT_ID = "";
125
- var EMPTY = Object.freeze({});
126
- var NO_PEERS = Object.freeze([]);
127
- var noop = () => {
128
- };
129
- var unsubscribe = () => noop;
130
- var INERT = Object.freeze({
131
- clientId: SERVER_CLIENT_ID,
132
- // store
133
- //
134
- // Resolved, unlike the leader's `waitForLeadership` below. A server render
135
- // has nothing to restore and is documented to render defaults, so `await
136
- // store.hydrated` must proceed — a never-settling promise would hang the
137
- // render rather than describe it honestly.
138
- hydrated: Promise.resolve(),
139
- state: EMPTY,
140
- getVersions: () => EMPTY,
141
- set: noop,
142
- subscribeKey: unsubscribe,
143
- registerKey: noop,
144
- // store + leader share getSnapshot; presence has getPeers
145
- getSnapshot: () => EMPTY,
146
- getPeers: () => NO_PEERS,
147
- // presence
148
- setMetadata: noop,
149
- // leader
150
- resign: noop,
151
- setEligible: noop,
152
- // common
153
- subscribe: unsubscribe,
154
- close: noop
155
- });
156
- var createServerStore = () => INERT;
157
- var createServerPresence = () => INERT;
158
- var NO_LEADER = Object.freeze({ leaderId: null, isLeader: false });
159
- var NEVER = () => new Promise(() => {
160
- });
161
- var createServerLeader = () => ({
162
- ...INERT,
163
- strategy: "heartbeat",
164
- getSnapshot: () => NO_LEADER,
165
- waitForLeadership: NEVER
166
- });
167
- var createServerReducer = (initial) => ({
168
- ...INERT,
169
- getSnapshot: () => initial,
170
- dispatch: noop,
171
- pendingCount: () => 0
172
- });
173
- var createServerChannel = (name) => ({ ...INERT, name, post: noop, on: unsubscribe });
174
-
175
- // src/registry.ts
176
- var stores = /* @__PURE__ */ new Map();
177
- var presences = /* @__PURE__ */ new Map();
178
- var channels = /* @__PURE__ */ new Map();
179
- var leaders = /* @__PURE__ */ new Map();
180
- var storeConfig = /* @__PURE__ */ new Map();
181
- var isServer = () => typeof window === "undefined";
182
- var scopeOptions = {
183
- everywhere: {},
184
- tabs: { accept: (meta) => meta.kind !== "worker" },
185
- tab: { transport: () => new import_core.NoopTransport() }
186
- };
187
- function getSharedStore(name = import_core.DEFAULT_NAME, scope = "everywhere") {
188
- return getStore(name, scope);
189
- }
190
- function configSignature(options) {
191
- const persist = options?.persist;
192
- if (!persist) return "none";
193
- return `persist:${persist.keys?.join(",") ?? "*"}:${persist.debounceMs ?? "default"}:v${persist.version ?? 0}`;
194
- }
195
- function configureStore(name, scope, options) {
196
- const key = `${scope} ${name}`;
197
- if (stores.has(key)) {
198
- if (configSignature(storeConfig.get(key)) === configSignature(options)) return;
199
- if (process.env.NODE_ENV !== "production") {
200
- devWarn(
201
- "UE2002",
202
- `createStoreHooks('${name}') ran after that store was already created, with different options. The live store keeps the configuration it was built with. Move createStoreHooks to module scope, before any component reads the store.`
203
- );
204
- }
205
- return;
206
- }
207
- storeConfig.set(key, options);
208
- }
209
- function getStore(name, scope = "everywhere") {
210
- const key = `${scope} ${name}`;
211
- let store = stores.get(key);
212
- if (!store) {
213
- store = isServer() ? createServerStore() : (0, import_core.createSharedStore)(name, {}, { ...scopeOptions[scope], ...storeConfig.get(key) });
214
- stores.set(key, store);
215
- }
216
- return store;
217
- }
218
- function getPresence(name, includeSelf = false) {
219
- const key = includeSelf ? `self ${name}` : name;
220
- let presence = presences.get(key);
221
- if (!presence) {
222
- presence = isServer() ? createServerPresence() : (0, import_core.createPresence)(name, { includeSelf });
223
- presences.set(key, presence);
224
- }
225
- return presence;
226
- }
227
- function getLeader(name, options) {
228
- let leader = leaders.get(name);
229
- if (!leader) {
230
- leader = isServer() ? createServerLeader() : (0, import_core.createLeader)(name, options);
231
- leaders.set(name, leader);
232
- if (options) leaderOptions.set(name, options);
233
- } else if (options) {
234
- warnOnLeaderOptionConflict(name, options);
235
- }
236
- return leader;
237
- }
238
- var leaderOptions = /* @__PURE__ */ new Map();
239
- function warnOnLeaderOptionConflict(name, options) {
240
- const first = leaderOptions.get(name);
241
- for (const key of ["heartbeatMs", "leaseMs"]) {
242
- const requested = options[key];
243
- if (requested !== void 0 && requested !== first?.[key]) {
244
- if (process.env.NODE_ENV !== "production") {
245
- devWarn(
246
- "UE2003",
247
- `leader "${name}": ${key} ignored \u2014 the first useLeader/getLeader call fixes the election timings for this tab.`
248
- );
249
- }
250
- }
251
- }
252
- }
253
- var channelConfig = /* @__PURE__ */ new Map();
254
- function configureChannel(name, options) {
255
- if (channels.has(name)) {
256
- const before = Object.keys(channelConfig.get(name)?.schema ?? {}).sort();
257
- const after = Object.keys(options.schema ?? {}).sort();
258
- if (before.join() === after.join()) return;
259
- if (process.env.NODE_ENV !== "production") {
260
- devWarn(
261
- "UE2004",
262
- `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.`
263
- );
264
- }
265
- return;
266
- }
267
- channelConfig.set(name, options);
268
- }
269
- var reducers = /* @__PURE__ */ new Map();
270
- function getReducer(name, key, reducer, initial) {
271
- const id = `${name} ${key}`;
272
- let existing = reducers.get(id);
273
- if (!existing) {
274
- existing = isServer() ? createServerReducer(initial) : (0, import_core.createSharedReducer)(name, reducer, initial, { key, leader: getLeader(name) });
275
- reducers.set(id, existing);
276
- }
277
- return existing;
278
- }
279
- function getChannel(name) {
280
- let channel = channels.get(name);
281
- if (!channel) {
282
- channel = isServer() ? createServerChannel(name) : (0, import_core.createChannel)(name, channelConfig.get(name));
283
- channels.set(name, channel);
284
- }
285
- return channel;
286
- }
287
-
288
- // src/use-shared-state.ts
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const require_use_peers = require("./use-peers-RhIB77TV.cjs");
4
+ let react = require("react");
5
+ let _use_everywhere_core = require("@use-everywhere/core");
6
+ //#region src/use-shared-state.ts
7
+ /**
8
+ * Like useState, but the value exists in every tab, window, and worker on
9
+ * this origin. Late-joining tabs hydrate to the current value; concurrent
10
+ * writes converge last-writer-wins. Pass options.scope to delimit how much
11
+ * is shared ('everywhere' | 'tabs' | 'tab').
12
+ *
13
+ * Note the convergence rule is last-writer-wins per key, not per operation:
14
+ * two tabs running `set(n => n + 1)` at the same moment agree on one value,
15
+ * and one of the increments is lost. For counters and other accumulating
16
+ * writes, drive them from a single tab (useLeaderEffect) until an op-based
17
+ * primitive lands.
18
+ */
289
19
  function useSharedState(key, initial, options) {
290
- const storeName = options?.store ?? import_core.DEFAULT_NAME;
291
- const store = getStore(storeName, options?.scope ?? "everywhere");
292
- store.registerKey(key, initial);
293
- if (process.env.NODE_ENV !== "production") {
294
- warnOnInitialMismatch(storeName, key, initial);
295
- }
296
- const value = (0, import_react.useSyncExternalStore)(
297
- (0, import_react.useCallback)((onChange) => store.subscribeKey(key, onChange), [store, key]),
298
- () => store.getSnapshot()[key],
299
- () => initial
300
- );
301
- const setValue = (0, import_react.useCallback)(
302
- (next) => store.set(key, next),
303
- [store, key]
304
- );
305
- return [value, setValue];
306
- }
307
-
308
- // src/use-shared-reducer.ts
309
- var import_react2 = require("react");
20
+ const storeName = options?.store ?? _use_everywhere_core.DEFAULT_NAME;
21
+ const store = require_use_peers.getStore(storeName, options?.scope ?? "everywhere");
22
+ store.registerKey(key, initial);
23
+ if (process.env.NODE_ENV !== "production") require_use_peers.warnOnInitialMismatch(storeName, key, initial);
24
+ return [(0, react.useSyncExternalStore)((0, react.useCallback)((onChange) => store.subscribeKey(key, onChange), [store, key]), () => store.getSnapshot()[key], () => initial), (0, react.useCallback)((next) => store.set(key, next), [store, key])];
25
+ }
26
+ //#endregion
27
+ //#region src/use-shared-reducer.ts
28
+ /**
29
+ * Like `useReducer`, but every tab, window, and worker on this origin applies
30
+ * the same actions in the same order.
31
+ *
32
+ * ```tsx
33
+ * const [count, dispatch] = useSharedReducer((n, action) => n + action.by, 0);
34
+ * <button onClick={() => dispatch({ by: 1 })}>{count}</button>;
35
+ * ```
36
+ *
37
+ * Reach for this instead of `useSharedState` whenever a write is *relative to
38
+ * what is already there* — a counter, a total, a list you append to. Shared
39
+ * state converges last-writer-wins on the value, so two tabs incrementing at
40
+ * once both write the same result and one increment vanishes. A reducer sends
41
+ * the action rather than the result, and two increments are two actions.
42
+ *
43
+ * For a plain register — a theme, a selection, a draft — `useSharedState` is
44
+ * still the right tool and the cheaper one.
45
+ *
46
+ * ## The rules
47
+ *
48
+ * **Actions must survive the wire.** They are structured-cloned to every peer,
49
+ * so no functions, no class instances, no DOM nodes.
50
+ *
51
+ * **The reducer must be pure**, and it must be the *same* reducer everywhere.
52
+ * Every client folds the same actions itself; a client whose fold differs gets
53
+ * a different answer, and nothing can detect that. The first caller's function
54
+ * is the one used for the life of the page — a re-render passes a new identity
55
+ * every time, and swapping the fold under a history already applied is exactly
56
+ * the divergence this exists to prevent.
57
+ *
58
+ * **Ordering needs a leader**, which this shares with `useLeader` on the same
59
+ * bus rather than electing a second one. Before a seat is filled — the first
60
+ * moments of the first tab — dispatches are held locally and ordered once it
61
+ * is. They are never lost, only pending.
62
+ */
310
63
  function useSharedReducer(reducer, initial, options) {
311
- const engine = getReducer(
312
- options?.name ?? import_core.DEFAULT_NAME,
313
- options?.key ?? "default",
314
- reducer,
315
- initial
316
- );
317
- const value = (0, import_react2.useSyncExternalStore)(
318
- (0, import_react2.useCallback)((onChange) => engine.subscribe(onChange), [engine]),
319
- () => engine.getSnapshot(),
320
- () => initial
321
- );
322
- const dispatch = (0, import_react2.useCallback)((action) => engine.dispatch(action), [engine]);
323
- return [value, dispatch];
324
- }
325
-
326
- // src/use-shared-selector.ts
327
- var import_react3 = require("react");
64
+ const engine = require_use_peers.getReducer(options?.name ?? _use_everywhere_core.DEFAULT_NAME, options?.key ?? "default", reducer, initial);
65
+ return [(0, react.useSyncExternalStore)((0, react.useCallback)((onChange) => engine.subscribe(onChange), [engine]), () => engine.getSnapshot(), () => initial), (0, react.useCallback)((action) => engine.dispatch(action), [engine])];
66
+ }
67
+ //#endregion
68
+ //#region src/use-shared-selector.ts
69
+ /**
70
+ * Read a derived value from a shared store, re-rendering only when it changes.
71
+ *
72
+ * `useSharedState` subscribes to one key, which is the right shape for reading
73
+ * one thing. Reading *across* keys meant either one hook per key or a
74
+ * subscription to the whole store, and the latter re-renders on every write to
75
+ * anything in it.
76
+ *
77
+ * ```tsx
78
+ * const total = useSharedSelector<Cart, number>(
79
+ * (cart) => cart.items.length + cart.saved.length,
80
+ * );
81
+ * ```
82
+ *
83
+ * The selector runs on every store change; the component only re-renders when
84
+ * its result changes by `equal`.
85
+ *
86
+ * ## It reads, it does not declare
87
+ *
88
+ * `useSharedState(key, initial)` registers `key` with a default. A selector
89
+ * does not — it sees whatever is in the store, so a key nothing has registered
90
+ * or written yet is `undefined`. Write selectors that tolerate that, or declare
91
+ * the defaults with `useSharedState` (or a store initial) somewhere that
92
+ * mounts first.
93
+ *
94
+ * The same applies on a server, where the store is inert and empty: the
95
+ * selector runs against `{}`, and its result is what the server-rendered markup
96
+ * shows.
97
+ */
328
98
  function useSharedSelector(selector, options) {
329
- const store = getStore(options?.store ?? import_core.DEFAULT_NAME, options?.scope ?? "everywhere");
330
- const equal = options?.equal ?? Object.is;
331
- const selectorRef = (0, import_react3.useRef)(selector);
332
- selectorRef.current = selector;
333
- const equalRef = (0, import_react3.useRef)(equal);
334
- equalRef.current = equal;
335
- const cache = (0, import_react3.useRef)(null);
336
- const getSelection = (0, import_react3.useCallback)(() => {
337
- const source = store.getSnapshot();
338
- const select = selectorRef.current;
339
- const previous = cache.current;
340
- if (previous && previous.source === source && previous.select === select) return previous.value;
341
- const next = select(source);
342
- const value = previous && equalRef.current(previous.value, next) ? previous.value : next;
343
- cache.current = { source, select, value };
344
- return value;
345
- }, [store]);
346
- return (0, import_react3.useSyncExternalStore)(
347
- (0, import_react3.useCallback)((onChange) => store.subscribe(onChange), [store]),
348
- getSelection,
349
- getSelection
350
- );
351
- }
99
+ const store = require_use_peers.getStore(options?.store ?? _use_everywhere_core.DEFAULT_NAME, options?.scope ?? "everywhere");
100
+ const equal = options?.equal ?? Object.is;
101
+ const selectorRef = (0, react.useRef)(selector);
102
+ selectorRef.current = selector;
103
+ const equalRef = (0, react.useRef)(equal);
104
+ equalRef.current = equal;
105
+ /**
106
+ * The last selection, and what produced it.
107
+ *
108
+ * `useSyncExternalStore` re-renders whenever the snapshot getter returns a
109
+ * value it has not seen, so a selector building a fresh object each call
110
+ * would loop forever. Caching against the *store* snapshot answers the common
111
+ * case in one identity check; caching against the selector as well is what
112
+ * keeps a changed selector from returning last render's answer.
113
+ */
114
+ const cache = (0, react.useRef)(null);
115
+ const getSelection = (0, react.useCallback)(() => {
116
+ const source = store.getSnapshot();
117
+ const select = selectorRef.current;
118
+ const previous = cache.current;
119
+ if (previous && previous.source === source && previous.select === select) return previous.value;
120
+ const next = select(source);
121
+ const value = previous && equalRef.current(previous.value, next) ? previous.value : next;
122
+ cache.current = {
123
+ source,
124
+ select,
125
+ value
126
+ };
127
+ return value;
128
+ }, [store]);
129
+ return (0, react.useSyncExternalStore)((0, react.useCallback)((onChange) => store.subscribe(onChange), [store]), getSelection, getSelection);
130
+ }
131
+ /** Shallow equality over an object or array, for selectors that build one. */
352
132
  function shallowEqual(a, b) {
353
- if (Object.is(a, b)) return true;
354
- if (typeof a !== "object" || a === null || typeof b !== "object" || b === null) return false;
355
- const left = a;
356
- const right = b;
357
- const keys = Object.keys(left);
358
- if (keys.length !== Object.keys(right).length) return false;
359
- return keys.every((key) => Object.is(left[key], right[key]));
360
- }
361
-
362
- // src/use-on-message.ts
363
- var import_react4 = require("react");
133
+ if (Object.is(a, b)) return true;
134
+ if (typeof a !== "object" || a === null || typeof b !== "object" || b === null) return false;
135
+ const left = a;
136
+ const right = b;
137
+ const keys = Object.keys(left);
138
+ if (keys.length !== Object.keys(right).length) return false;
139
+ return keys.every((key) => Object.is(left[key], right[key]));
140
+ }
141
+ //#endregion
142
+ //#region src/use-on-message.ts
143
+ /** Get the page-wide typed channel for `name` (one instance per name). */
364
144
  function useChannel(name) {
365
- return getChannel(name);
145
+ return require_use_peers.getChannel(name);
366
146
  }
147
+ /**
148
+ * Subscribe to one message type. The handler is kept fresh without
149
+ * resubscribing, so it may close over render state.
150
+ */
367
151
  function useOnMessage(channel, type, handler, options) {
368
- const handlerRef = (0, import_react4.useRef)(handler);
369
- (0, import_react4.useEffect)(() => {
370
- handlerRef.current = handler;
371
- });
372
- const enabled = options?.enabled ?? true;
373
- const once = options?.once ?? false;
374
- (0, import_react4.useEffect)(() => {
375
- if (!enabled) return;
376
- return channel.on(type, (payload, meta) => handlerRef.current(payload, meta), { once });
377
- }, [channel, type, enabled, once]);
378
- }
152
+ const handlerRef = (0, react.useRef)(handler);
153
+ (0, react.useEffect)(() => {
154
+ handlerRef.current = handler;
155
+ });
156
+ const enabled = options?.enabled ?? true;
157
+ const once = options?.once ?? false;
158
+ (0, react.useEffect)(() => {
159
+ if (!enabled) return;
160
+ return channel.on(type, (payload, meta) => handlerRef.current(payload, meta), { once });
161
+ }, [
162
+ channel,
163
+ type,
164
+ enabled,
165
+ once
166
+ ]);
167
+ }
168
+ /**
169
+ * Answer `ask`s of one type for as long as this component is mounted.
170
+ *
171
+ * A hook rather than a bare `channel.answer` call because a responder is a
172
+ * subscription: registering one in a render would leave the last unmounted
173
+ * component answering for the page.
174
+ *
175
+ * One responder per type per channel — registering a second replaces the first,
176
+ * which is the same first-wins-then-replace rule `answer` has in core.
177
+ */
379
178
  function useAnswer(channel, type, responder, options) {
380
- const responderRef = (0, import_react4.useRef)(responder);
381
- (0, import_react4.useEffect)(() => {
382
- responderRef.current = responder;
383
- });
384
- const enabled = options?.enabled ?? true;
385
- (0, import_react4.useEffect)(() => {
386
- if (!enabled) return;
387
- return channel.answer(type, (payload, meta) => responderRef.current(payload, meta));
388
- }, [channel, type, enabled]);
389
- }
179
+ const responderRef = (0, react.useRef)(responder);
180
+ (0, react.useEffect)(() => {
181
+ responderRef.current = responder;
182
+ });
183
+ const enabled = options?.enabled ?? true;
184
+ (0, react.useEffect)(() => {
185
+ if (!enabled) return;
186
+ return channel.answer(type, (payload, meta) => responderRef.current(payload, meta));
187
+ }, [
188
+ channel,
189
+ type,
190
+ enabled
191
+ ]);
192
+ }
193
+ /** The channel's post function (stable identity per channel). */
390
194
  function useSend(channel) {
391
- return channel.post;
195
+ return channel.post;
392
196
  }
197
+ /** The channel's ask function (stable identity per channel). */
393
198
  function useAsk(channel) {
394
- return channel.ask;
395
- }
396
-
397
- // src/define-channel.ts
199
+ return channel.ask;
200
+ }
201
+ //#endregion
202
+ //#region src/define-channel.ts
203
+ /**
204
+ * Bind a channel name and message map once, at module level, and get fully
205
+ * typed hooks back. Sugar over useChannel/useOnMessage/useSend — the same
206
+ * page-wide channel singleton is shared, so mixing bound and standalone
207
+ * hooks for one name is safe.
208
+ *
209
+ * Options are registered here and applied when the channel is first needed, so
210
+ * declaring a `schema` at module scope still constructs nothing on import.
211
+ */
398
212
  function defineChannel(name, options) {
399
- if (options) configureChannel(name, options);
400
- const useBoundSend = () => useSend(useChannel(name));
401
- const useBoundMessage = (type, handler) => useOnMessage(useChannel(name), type, handler);
402
- return {
403
- get: () => getChannel(name),
404
- useSend: useBoundSend,
405
- useOnMessage: useBoundMessage
406
- };
407
- }
408
-
409
- // src/create-store-hooks.ts
213
+ if (options) require_use_peers.configureChannel(name, options);
214
+ const useBoundSend = () => useSend(useChannel(name));
215
+ const useBoundMessage = (type, handler) => useOnMessage(useChannel(name), type, handler);
216
+ return {
217
+ get: () => require_use_peers.getChannel(name),
218
+ useSend: useBoundSend,
219
+ useOnMessage: useBoundMessage
220
+ };
221
+ }
222
+ //#endregion
223
+ //#region src/create-store-hooks.ts
224
+ /**
225
+ * Bind a store name — and optionally persistence — once, at module level.
226
+ *
227
+ * Like defineChannel, this does not construct anything: it registers the
228
+ * options the registry will use when the store is first needed, so importing
229
+ * the module has no side effect. The store stays a singleton per name, so
230
+ * `createStoreHooks('settings', { persist })` and a bare
231
+ * `useSharedState('theme', 'dark', { store: 'settings' })` elsewhere resolve to
232
+ * the same store, and both get persistence.
233
+ *
234
+ * Must run before that store exists. Module evaluation always precedes render,
235
+ * so intended usage is automatic; if it does run late it throws rather than
236
+ * quietly handing back a store with no persistence.
237
+ */
410
238
  function createStoreHooks(name, options = {}) {
411
- const scope = options.scope ?? "everywhere";
412
- if (options.persist) {
413
- configureStore(name, scope, {
414
- persist: {
415
- adapter: options.persist,
416
- ...options.persistKeys ? { keys: options.persistKeys } : {},
417
- ...options.persistDebounceMs === void 0 ? {} : { debounceMs: options.persistDebounceMs },
418
- ...options.persistVersion === void 0 ? {} : { version: options.persistVersion },
419
- ...options.migrate ? { migrate: options.migrate } : {},
420
- ...options.onRestoreError ? { onRestoreError: options.onRestoreError } : {}
421
- }
422
- });
423
- }
424
- return {
425
- store: () => getStore(name, scope),
426
- useSharedState: (key, initial) => useSharedState(key, initial, { store: name, scope })
427
- };
428
- }
429
-
430
- // src/use-peers.ts
431
- var import_react5 = require("react");
432
- var NO_PEERS2 = Object.freeze([]);
433
- function usePeers(options) {
434
- const presence = getPresence(options?.name ?? import_core.DEFAULT_NAME, options?.includeSelf ?? false);
435
- return (0, import_react5.useSyncExternalStore)(
436
- (0, import_react5.useCallback)((onChange) => presence.subscribe(onChange), [presence]),
437
- () => presence.getPeers(),
438
- () => NO_PEERS2
439
- );
440
- }
441
- function useClientId(options) {
442
- const presence = getPresence(options?.name ?? import_core.DEFAULT_NAME);
443
- return (0, import_react5.useSyncExternalStore)(
444
- // The id never changes for the life of a presence engine, so there is
445
- // nothing to subscribe to — but uSES still needs the post-hydration read,
446
- // which it performs when it attaches this subscription.
447
- (0, import_react5.useCallback)(() => () => {
448
- }, [presence]),
449
- () => presence.clientId,
450
- () => SERVER_CLIENT_ID
451
- );
452
- }
453
- function usePresenceMetadata(metadata, options) {
454
- const presence = getPresence(options?.name ?? import_core.DEFAULT_NAME, options?.includeSelf ?? false);
455
- (0, import_react5.useEffect)(() => {
456
- presence.setMetadata(metadata);
457
- }, [presence, metadata]);
458
- }
459
-
460
- // src/use-hydrated.ts
461
- var import_react6 = require("react");
239
+ const scope = options.scope ?? "everywhere";
240
+ if (options.persist) require_use_peers.configureStore(name, scope, { persist: {
241
+ adapter: options.persist,
242
+ ...options.persistKeys ? { keys: options.persistKeys } : {},
243
+ ...options.persistDebounceMs === void 0 ? {} : { debounceMs: options.persistDebounceMs },
244
+ ...options.persistVersion === void 0 ? {} : { version: options.persistVersion },
245
+ ...options.migrate ? { migrate: options.migrate } : {},
246
+ ...options.onRestoreError ? { onRestoreError: options.onRestoreError } : {}
247
+ } });
248
+ return {
249
+ store: () => require_use_peers.getStore(name, scope),
250
+ useSharedState: (key, initial) => useSharedState(key, initial, {
251
+ store: name,
252
+ scope
253
+ })
254
+ };
255
+ }
256
+ //#endregion
257
+ //#region src/use-hydrated.ts
258
+ /**
259
+ * Whether a persisted store has finished restoring.
260
+ *
261
+ * `false` on the first render, then `true` once the restore lands — including
262
+ * the cases where there is nothing to restore, which settle immediately.
263
+ *
264
+ * Deliberately `false` first even for a synchronous adapter that has already
265
+ * finished. The alternative is a value that differs between the server render
266
+ * and the browser's hydrating render, which is a hydration mismatch on every
267
+ * app that uses it — the same reason `useClientId` reports `''` until the
268
+ * commit after hydration.
269
+ *
270
+ * The gap this closes only exists for **async** adapters, and it is one
271
+ * last-writer-wins makes invisible: a keystroke landing before the restore
272
+ * writes at counter 1, the restore arrives holding counter 5, and the newer
273
+ * keystroke is correctly discarded. The behaviour is right; the surprise is
274
+ * total. Gate the input and there is no gap:
275
+ *
276
+ * ```tsx
277
+ * const ready = useHydrated({ store: 'settings' });
278
+ * return <input disabled={!ready} value={draft} onChange={…} />;
279
+ * ```
280
+ *
281
+ * A synchronous adapter — `localStorageAdapter` and friends — has already
282
+ * restored by the time the store is handed back, so there is no gap to guard
283
+ * and this simply flips to `true` in the commit after mount.
284
+ */
462
285
  function useHydrated(options) {
463
- const store = getStore(options?.store ?? import_core.DEFAULT_NAME, options?.scope ?? "everywhere");
464
- const [ready, setReady] = (0, import_react6.useState)(false);
465
- (0, import_react6.useEffect)(() => {
466
- let cancelled = false;
467
- void store.hydrated.then(() => {
468
- if (!cancelled) setReady(true);
469
- });
470
- return () => {
471
- cancelled = true;
472
- };
473
- }, [store]);
474
- return ready;
475
- }
476
-
477
- // src/use-leader.ts
478
- var import_react7 = require("react");
479
- var NO_LEADER2 = Object.freeze({ leaderId: null, isLeader: false });
286
+ const store = require_use_peers.getStore(options?.store ?? _use_everywhere_core.DEFAULT_NAME, options?.scope ?? "everywhere");
287
+ const [ready, setReady] = (0, react.useState)(false);
288
+ (0, react.useEffect)(() => {
289
+ let cancelled = false;
290
+ store.hydrated.then(() => {
291
+ if (!cancelled) setReady(true);
292
+ });
293
+ return () => {
294
+ cancelled = true;
295
+ };
296
+ }, [store]);
297
+ return ready;
298
+ }
299
+ //#endregion
300
+ //#region src/use-leader.ts
301
+ const NO_LEADER = Object.freeze({
302
+ leaderId: null,
303
+ isLeader: false
304
+ });
305
+ /**
306
+ * Who currently holds the seat on this bus, and whether it is us. Exactly one
307
+ * tab leads; opening another does not steal it, and closing the leader hands it
308
+ * over at once.
309
+ */
480
310
  function useLeader(options) {
481
- const leader = getLeader(options?.name ?? import_core.DEFAULT_NAME, options);
482
- const eligible = options?.eligible;
483
- (0, import_react7.useEffect)(() => {
484
- if (eligible === void 0) return;
485
- leader.setEligible(eligible);
486
- }, [leader, eligible]);
487
- return (0, import_react7.useSyncExternalStore)(
488
- (0, import_react7.useCallback)((onChange) => leader.subscribe(onChange), [leader]),
489
- () => leader.getSnapshot(),
490
- () => NO_LEADER2
491
- );
492
- }
311
+ const leader = require_use_peers.getLeader(options?.name ?? _use_everywhere_core.DEFAULT_NAME, options);
312
+ const eligible = options?.eligible;
313
+ (0, react.useEffect)(() => {
314
+ if (eligible === void 0) return;
315
+ leader.setEligible(eligible);
316
+ }, [leader, eligible]);
317
+ return (0, react.useSyncExternalStore)((0, react.useCallback)((onChange) => leader.subscribe(onChange), [leader]), () => leader.getSnapshot(), () => NO_LEADER);
318
+ }
319
+ /** Is this tab the leader? */
493
320
  function useIsLeader(options) {
494
- return useLeader(options).isLeader;
321
+ return useLeader(options).isLeader;
495
322
  }
323
+ /**
324
+ * Run an effect only in the tab that holds the seat, and tear it down when the
325
+ * seat moves. The one place to put "exactly one tab owns the socket".
326
+ */
496
327
  function useLeaderEffect(effect, options) {
497
- const { isLeader } = useLeader(options);
498
- const effectRef = (0, import_react7.useRef)(effect);
499
- (0, import_react7.useEffect)(() => {
500
- effectRef.current = effect;
501
- });
502
- (0, import_react7.useEffect)(() => {
503
- if (!isLeader) return;
504
- return effectRef.current();
505
- }, [isLeader]);
506
- }
507
-
508
- // src/namespace.ts
509
- var import_core2 = require("@use-everywhere/core");
328
+ const { isLeader } = useLeader(options);
329
+ const effectRef = (0, react.useRef)(effect);
330
+ (0, react.useEffect)(() => {
331
+ effectRef.current = effect;
332
+ });
333
+ (0, react.useEffect)(() => {
334
+ if (!isLeader) return;
335
+ return effectRef.current();
336
+ }, [isLeader]);
337
+ }
338
+ //#endregion
339
+ //#region src/namespace.ts
340
+ /**
341
+ * Namespaced hooks and factories, so two independently deployed apps on one
342
+ * origin cannot collide by both taking the defaults.
343
+ *
344
+ * ```ts
345
+ * // checkout/bus.ts
346
+ * export const checkout = createNamespace('checkout');
347
+ *
348
+ * // anywhere in the checkout app
349
+ * const [items, setItems] = checkout.useSharedState('items', []);
350
+ * ```
351
+ *
352
+ * Call it **at module scope**, like `createStoreHooks` and `defineChannel`. It
353
+ * builds a small object of bound functions, and rebuilding that on every render
354
+ * would hand React a new `useSharedState` identity each time — harmless for the
355
+ * hooks themselves, which key off the bus name, but pointless work and a
356
+ * confusing thing to see in a profile.
357
+ *
358
+ * See the core `createNamespace` for what a namespace does and does not
359
+ * guarantee. In short: it prevents collision, not access.
360
+ */
510
361
  function createNamespace(namespace) {
511
- const core = (0, import_core2.createNamespace)(namespace);
512
- const { busName } = core;
513
- return {
514
- ...core,
515
- createStoreHooks: (name, options) => createStoreHooks(busName(name), options),
516
- defineChannel: (name, options) => defineChannel(busName(name), options),
517
- getSharedStore: (name, scope) => getSharedStore(busName(name), scope),
518
- useSharedState: (key, initial, options) => useSharedState(key, initial, { ...options, store: busName(options?.store) }),
519
- useSharedSelector: (selector, options) => useSharedSelector(selector, { ...options, store: busName(options?.store) }),
520
- usePeers: (options) => usePeers({ ...options, name: busName(options?.name) }),
521
- usePresenceMetadata: (metadata, options) => usePresenceMetadata(metadata, { ...options, name: busName(options?.name) }),
522
- useHydrated: (options) => useHydrated({ ...options, store: busName(options?.store) }),
523
- useClientId: (options) => useClientId({ name: busName(options?.name) }),
524
- useLeader: (options) => useLeader({ ...options, name: busName(options?.name) }),
525
- useIsLeader: (options) => useIsLeader({ ...options, name: busName(options?.name) }),
526
- useLeaderEffect: (effect, options) => useLeaderEffect(effect, { ...options, name: busName(options?.name) })
527
- };
528
- }
529
-
530
- // src/use-window-result.ts
531
- var import_react8 = require("react");
532
- var import_core3 = require("@use-everywhere/core");
533
- var IDLE = Object.freeze({
534
- status: "idle",
535
- result: void 0,
536
- error: void 0
362
+ const core = (0, _use_everywhere_core.createNamespace)(namespace);
363
+ const { busName } = core;
364
+ return {
365
+ ...core,
366
+ createStoreHooks: (name, options) => createStoreHooks(busName(name), options),
367
+ defineChannel: (name, options) => defineChannel(busName(name), options),
368
+ getSharedStore: (name, scope) => require_use_peers.getSharedStore(busName(name), scope),
369
+ useSharedState: (key, initial, options) => useSharedState(key, initial, {
370
+ ...options,
371
+ store: busName(options?.store)
372
+ }),
373
+ useSharedSelector: (selector, options) => useSharedSelector(selector, {
374
+ ...options,
375
+ store: busName(options?.store)
376
+ }),
377
+ usePeers: (options) => require_use_peers.usePeers({
378
+ ...options,
379
+ name: busName(options?.name)
380
+ }),
381
+ usePresenceMetadata: (metadata, options) => require_use_peers.usePresenceMetadata(metadata, {
382
+ ...options,
383
+ name: busName(options?.name)
384
+ }),
385
+ useHydrated: (options) => useHydrated({
386
+ ...options,
387
+ store: busName(options?.store)
388
+ }),
389
+ useClientId: (options) => require_use_peers.useClientId({ name: busName(options?.name) }),
390
+ useLeader: (options) => useLeader({
391
+ ...options,
392
+ name: busName(options?.name)
393
+ }),
394
+ useIsLeader: (options) => useIsLeader({
395
+ ...options,
396
+ name: busName(options?.name)
397
+ }),
398
+ useLeaderEffect: (effect, options) => useLeaderEffect(effect, {
399
+ ...options,
400
+ name: busName(options?.name)
401
+ })
402
+ };
403
+ }
404
+ //#endregion
405
+ //#region src/use-window-result.ts
406
+ const IDLE = Object.freeze({
407
+ status: "idle",
408
+ result: void 0,
409
+ error: void 0
537
410
  });
411
+ /**
412
+ * Drive an openWindow() flow from a component: the factory is called on
413
+ * open(), and the child window's lifecycle is folded into render state.
414
+ * Reopening replaces the previous window; a stale window's outcome is ignored.
415
+ *
416
+ * The child window deliberately outlives an unmount: closing a payment page
417
+ * because a route changed would lose the user's in-flight transaction. Call
418
+ * close() if the component owns the window's lifetime.
419
+ */
538
420
  function useWindowResult(factory) {
539
- const [state, setState] = (0, import_react8.useState)(IDLE);
540
- const current = (0, import_react8.useRef)(null);
541
- const factoryRef = (0, import_react8.useRef)(factory);
542
- (0, import_react8.useEffect)(() => {
543
- factoryRef.current = factory;
544
- });
545
- const open = (0, import_react8.useCallback)(() => {
546
- current.current?.close();
547
- let opened;
548
- try {
549
- opened = factoryRef.current();
550
- } catch (err) {
551
- setState({ status: "error", result: void 0, error: err });
552
- return;
553
- }
554
- current.current = opened;
555
- setState({ status: "opening", result: void 0, error: void 0 });
556
- const fresh = () => current.current === opened;
557
- opened.ready.then(
558
- () => {
559
- if (!fresh()) return;
560
- setState(
561
- (s) => s.status === "opening" ? { status: "connected", result: void 0, error: void 0 } : s
562
- );
563
- },
564
- () => {
565
- }
566
- // surfaced through result below
567
- );
568
- opened.result.then(
569
- (value) => {
570
- if (fresh()) setState({ status: "done", result: value, error: void 0 });
571
- },
572
- (err) => {
573
- if (!fresh()) return;
574
- setState(
575
- err instanceof import_core3.WindowClosedError ? { status: "closed-early", result: void 0, error: err } : { status: "error", result: void 0, error: err }
576
- );
577
- }
578
- );
579
- }, []);
580
- const post = (0, import_react8.useCallback)((type, payload) => {
581
- current.current?.post(type, payload);
582
- }, []);
583
- const close = (0, import_react8.useCallback)(() => current.current?.close(), []);
584
- return { ...state, open, post, close };
585
- }
586
-
587
- // src/index.ts
588
- var import_core4 = require("@use-everywhere/core");
589
- // Annotate the CommonJS export names for ESM import in node:
590
- 0 && (module.exports = {
591
- BroadcastChannelTransport,
592
- CID_PARAM,
593
- DEFAULT_NAME,
594
- HandshakeTimeoutError,
595
- NoopTransport,
596
- SharedWorkerTransport,
597
- StorageTransport,
598
- WIRE_VERSION,
599
- WindowClosedError,
600
- connectToOpener,
601
- createChannel,
602
- createLeader,
603
- createNamespace,
604
- createPresence,
605
- createSharedReducer,
606
- createSharedStore,
607
- createStoreHooks,
608
- defaultTransport,
609
- defineChannel,
610
- enableDebug,
611
- getBusNames,
612
- getLeader,
613
- getSharedStore,
614
- getTransportKind,
615
- getWireSkew,
616
- indexedDbAdapter,
617
- isBroadcastChannelAvailable,
618
- isSharedWorkerAvailable,
619
- isStorageEventAvailable,
620
- jsonSerializer,
621
- localStorageAdapter,
622
- newer,
623
- observeBus,
624
- openWindow,
625
- sessionStorageAdapter,
626
- shallowEqual,
627
- useAnswer,
628
- useAsk,
629
- useChannel,
630
- useClientId,
631
- useHydrated,
632
- useIsLeader,
633
- useLeader,
634
- useLeaderEffect,
635
- useOnMessage,
636
- usePeers,
637
- usePresenceMetadata,
638
- useSend,
639
- useSharedReducer,
640
- useSharedSelector,
641
- useSharedState,
642
- useWindowResult,
643
- webStorageAdapter
421
+ const [state, setState] = (0, react.useState)(IDLE);
422
+ const current = (0, react.useRef)(null);
423
+ const factoryRef = (0, react.useRef)(factory);
424
+ (0, react.useEffect)(() => {
425
+ factoryRef.current = factory;
426
+ });
427
+ const open = (0, react.useCallback)(() => {
428
+ current.current?.close();
429
+ let opened;
430
+ try {
431
+ opened = factoryRef.current();
432
+ } catch (err) {
433
+ setState({
434
+ status: "error",
435
+ result: void 0,
436
+ error: err
437
+ });
438
+ return;
439
+ }
440
+ current.current = opened;
441
+ setState({
442
+ status: "opening",
443
+ result: void 0,
444
+ error: void 0
445
+ });
446
+ const fresh = () => current.current === opened;
447
+ opened.ready.then(() => {
448
+ if (!fresh()) return;
449
+ setState((s) => s.status === "opening" ? {
450
+ status: "connected",
451
+ result: void 0,
452
+ error: void 0
453
+ } : s);
454
+ }, () => {});
455
+ opened.result.then((value) => {
456
+ if (fresh()) setState({
457
+ status: "done",
458
+ result: value,
459
+ error: void 0
460
+ });
461
+ }, (err) => {
462
+ if (!fresh()) return;
463
+ setState(err instanceof _use_everywhere_core.WindowClosedError ? {
464
+ status: "closed-early",
465
+ result: void 0,
466
+ error: err
467
+ } : {
468
+ status: "error",
469
+ result: void 0,
470
+ error: err
471
+ });
472
+ });
473
+ }, []);
474
+ const post = (0, react.useCallback)((type, payload) => {
475
+ current.current?.post(type, payload);
476
+ }, []);
477
+ const close = (0, react.useCallback)(() => current.current?.close(), []);
478
+ return {
479
+ ...state,
480
+ open,
481
+ post,
482
+ close
483
+ };
484
+ }
485
+ //#endregion
486
+ Object.defineProperty(exports, "BroadcastChannelTransport", {
487
+ enumerable: true,
488
+ get: function() {
489
+ return _use_everywhere_core.BroadcastChannelTransport;
490
+ }
491
+ });
492
+ Object.defineProperty(exports, "CID_PARAM", {
493
+ enumerable: true,
494
+ get: function() {
495
+ return _use_everywhere_core.CID_PARAM;
496
+ }
497
+ });
498
+ exports.DEFAULT_NAME = _use_everywhere_core.DEFAULT_NAME;
499
+ Object.defineProperty(exports, "HandshakeTimeoutError", {
500
+ enumerable: true,
501
+ get: function() {
502
+ return _use_everywhere_core.HandshakeTimeoutError;
503
+ }
504
+ });
505
+ Object.defineProperty(exports, "NoopTransport", {
506
+ enumerable: true,
507
+ get: function() {
508
+ return _use_everywhere_core.NoopTransport;
509
+ }
510
+ });
511
+ Object.defineProperty(exports, "SharedWorkerTransport", {
512
+ enumerable: true,
513
+ get: function() {
514
+ return _use_everywhere_core.SharedWorkerTransport;
515
+ }
516
+ });
517
+ Object.defineProperty(exports, "StorageTransport", {
518
+ enumerable: true,
519
+ get: function() {
520
+ return _use_everywhere_core.StorageTransport;
521
+ }
522
+ });
523
+ Object.defineProperty(exports, "WIRE_VERSION", {
524
+ enumerable: true,
525
+ get: function() {
526
+ return _use_everywhere_core.WIRE_VERSION;
527
+ }
528
+ });
529
+ Object.defineProperty(exports, "WindowClosedError", {
530
+ enumerable: true,
531
+ get: function() {
532
+ return _use_everywhere_core.WindowClosedError;
533
+ }
534
+ });
535
+ Object.defineProperty(exports, "connectToOpener", {
536
+ enumerable: true,
537
+ get: function() {
538
+ return _use_everywhere_core.connectToOpener;
539
+ }
540
+ });
541
+ Object.defineProperty(exports, "createChannel", {
542
+ enumerable: true,
543
+ get: function() {
544
+ return _use_everywhere_core.createChannel;
545
+ }
546
+ });
547
+ Object.defineProperty(exports, "createLeader", {
548
+ enumerable: true,
549
+ get: function() {
550
+ return _use_everywhere_core.createLeader;
551
+ }
552
+ });
553
+ exports.createNamespace = createNamespace;
554
+ Object.defineProperty(exports, "createPresence", {
555
+ enumerable: true,
556
+ get: function() {
557
+ return _use_everywhere_core.createPresence;
558
+ }
559
+ });
560
+ Object.defineProperty(exports, "createSharedReducer", {
561
+ enumerable: true,
562
+ get: function() {
563
+ return _use_everywhere_core.createSharedReducer;
564
+ }
565
+ });
566
+ Object.defineProperty(exports, "createSharedStore", {
567
+ enumerable: true,
568
+ get: function() {
569
+ return _use_everywhere_core.createSharedStore;
570
+ }
571
+ });
572
+ exports.createStoreHooks = createStoreHooks;
573
+ Object.defineProperty(exports, "defaultTransport", {
574
+ enumerable: true,
575
+ get: function() {
576
+ return _use_everywhere_core.defaultTransport;
577
+ }
578
+ });
579
+ exports.defineChannel = defineChannel;
580
+ Object.defineProperty(exports, "enableDebug", {
581
+ enumerable: true,
582
+ get: function() {
583
+ return _use_everywhere_core.enableDebug;
584
+ }
585
+ });
586
+ Object.defineProperty(exports, "getBusNames", {
587
+ enumerable: true,
588
+ get: function() {
589
+ return _use_everywhere_core.getBusNames;
590
+ }
591
+ });
592
+ exports.getLeader = require_use_peers.getLeader;
593
+ exports.getSharedStore = require_use_peers.getSharedStore;
594
+ Object.defineProperty(exports, "getTransportKind", {
595
+ enumerable: true,
596
+ get: function() {
597
+ return _use_everywhere_core.getTransportKind;
598
+ }
599
+ });
600
+ Object.defineProperty(exports, "getWireSkew", {
601
+ enumerable: true,
602
+ get: function() {
603
+ return _use_everywhere_core.getWireSkew;
604
+ }
605
+ });
606
+ Object.defineProperty(exports, "indexedDbAdapter", {
607
+ enumerable: true,
608
+ get: function() {
609
+ return _use_everywhere_core.indexedDbAdapter;
610
+ }
611
+ });
612
+ Object.defineProperty(exports, "isBroadcastChannelAvailable", {
613
+ enumerable: true,
614
+ get: function() {
615
+ return _use_everywhere_core.isBroadcastChannelAvailable;
616
+ }
617
+ });
618
+ Object.defineProperty(exports, "isSharedWorkerAvailable", {
619
+ enumerable: true,
620
+ get: function() {
621
+ return _use_everywhere_core.isSharedWorkerAvailable;
622
+ }
623
+ });
624
+ Object.defineProperty(exports, "isStorageEventAvailable", {
625
+ enumerable: true,
626
+ get: function() {
627
+ return _use_everywhere_core.isStorageEventAvailable;
628
+ }
629
+ });
630
+ Object.defineProperty(exports, "jsonSerializer", {
631
+ enumerable: true,
632
+ get: function() {
633
+ return _use_everywhere_core.jsonSerializer;
634
+ }
635
+ });
636
+ Object.defineProperty(exports, "localStorageAdapter", {
637
+ enumerable: true,
638
+ get: function() {
639
+ return _use_everywhere_core.localStorageAdapter;
640
+ }
641
+ });
642
+ Object.defineProperty(exports, "newer", {
643
+ enumerable: true,
644
+ get: function() {
645
+ return _use_everywhere_core.newer;
646
+ }
647
+ });
648
+ Object.defineProperty(exports, "observeBus", {
649
+ enumerable: true,
650
+ get: function() {
651
+ return _use_everywhere_core.observeBus;
652
+ }
653
+ });
654
+ Object.defineProperty(exports, "openWindow", {
655
+ enumerable: true,
656
+ get: function() {
657
+ return _use_everywhere_core.openWindow;
658
+ }
659
+ });
660
+ Object.defineProperty(exports, "sessionStorageAdapter", {
661
+ enumerable: true,
662
+ get: function() {
663
+ return _use_everywhere_core.sessionStorageAdapter;
664
+ }
665
+ });
666
+ exports.shallowEqual = shallowEqual;
667
+ exports.useAnswer = useAnswer;
668
+ exports.useAsk = useAsk;
669
+ exports.useChannel = useChannel;
670
+ exports.useClientId = require_use_peers.useClientId;
671
+ exports.useHydrated = useHydrated;
672
+ exports.useIsLeader = useIsLeader;
673
+ exports.useLeader = useLeader;
674
+ exports.useLeaderEffect = useLeaderEffect;
675
+ exports.useOnMessage = useOnMessage;
676
+ exports.usePeers = require_use_peers.usePeers;
677
+ exports.usePresenceMetadata = require_use_peers.usePresenceMetadata;
678
+ exports.useSend = useSend;
679
+ exports.useSharedReducer = useSharedReducer;
680
+ exports.useSharedSelector = useSharedSelector;
681
+ exports.useSharedState = useSharedState;
682
+ exports.useWindowResult = useWindowResult;
683
+ Object.defineProperty(exports, "webStorageAdapter", {
684
+ enumerable: true,
685
+ get: function() {
686
+ return _use_everywhere_core.webStorageAdapter;
687
+ }
644
688
  });