cross-state 0.32.0 → 0.33.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/es/scope.mjs CHANGED
@@ -1,376 +1,19 @@
1
- import { a as autobind, S as Store, c as createStore, b as calcDuration, m as makeSelector } from "./store.mjs";
2
- import { h as hash } from "./hash.mjs";
3
- class ResourceGroup {
4
- constructor(name) {
5
- this.name = name;
6
- this.refMap = /* @__PURE__ */ new WeakMap();
7
- this.refSet = /* @__PURE__ */ new Set();
8
- autobind(ResourceGroup);
1
+ import { a as autobind } from "./store.mjs";
2
+ function hash(value) {
3
+ if (value instanceof Set) {
4
+ return `s[${[...value].map(hash).sort().join(",")}]`;
9
5
  }
10
- add(resource) {
11
- const ref = new WeakRef(resource);
12
- this.refMap.set(resource, ref);
13
- this.refSet.add(ref);
6
+ if (value instanceof Map) {
7
+ return `m[${[...value.entries()].map(hash).sort().join(",")}]`;
14
8
  }
15
- delete(resource) {
16
- const ref = this.refMap.get(resource);
17
- if (ref) {
18
- this.refMap.delete(resource);
19
- this.refSet.delete(ref);
20
- }
9
+ if (Array.isArray(value)) {
10
+ return `[${value.map(hash).join(",")}]`;
21
11
  }
22
- invalidateAll() {
23
- for (const ref of this.refSet) {
24
- const resource = ref.deref();
25
- if (resource) {
26
- resource.invalidateAll();
27
- } else {
28
- this.refSet.delete(ref);
29
- }
30
- }
31
- }
32
- clearAll() {
33
- for (const ref of this.refSet) {
34
- const resource = ref.deref();
35
- if (resource) {
36
- resource.clearAll();
37
- } else {
38
- this.refSet.delete(ref);
39
- }
40
- }
41
- }
42
- }
43
- const allResources = /* @__PURE__ */ new ResourceGroup();
44
- function createResourceGroup(name) {
45
- return new ResourceGroup(name);
46
- }
47
- class InstanceCache {
48
- constructor(factory, cacheTime) {
49
- this.factory = factory;
50
- this.cacheTime = cacheTime;
51
- this.cache = /* @__PURE__ */ new Map();
52
- this.interval = this.cacheTime ? setInterval(() => this.cleanup(), Math.max(this.cacheTime / 10, 1)) : void 0;
53
- }
54
- cleanup() {
55
- var _a;
56
- const cutoff = this.now() - (this.cacheTime ?? 0);
57
- for (const [key, entry] of this.cache.entries()) {
58
- if (entry.ref && entry.t <= cutoff) {
59
- delete entry.ref;
60
- }
61
- if (!entry.ref && !((_a = entry.weakRef) == null ? void 0 : _a.deref())) {
62
- this.cache.delete(key);
63
- }
64
- }
65
- }
66
- get(...args) {
67
- var _a;
68
- const key = hash(args);
69
- let entry = this.cache.get(key);
70
- let value = (entry == null ? void 0 : entry.ref) ?? ((_a = entry == null ? void 0 : entry.weakRef) == null ? void 0 : _a.deref());
71
- if (!entry || !value) {
72
- value = this.factory(...args);
73
- entry = {
74
- t: this.now(),
75
- ref: value,
76
- weakRef: new WeakRef(value)
77
- };
78
- this.cache.set(key, entry);
79
- } else {
80
- entry.t = this.now();
81
- entry.ref ?? (entry.ref = value);
82
- }
83
- return value;
84
- }
85
- values() {
86
- return [...this.cache.values()].map((entry) => {
87
- var _a;
88
- return entry.ref ?? ((_a = entry.weakRef) == null ? void 0 : _a.deref());
89
- }).filter((value) => !!value);
90
- }
91
- stop() {
92
- if (this.interval) {
93
- clearInterval(this.interval);
94
- }
95
- }
96
- stats() {
97
- return {
98
- count: this.cache.size,
99
- withRef: [...this.cache.values()].filter((x) => !!x.ref).length,
100
- withWeakRef: [...this.cache.values()].filter((x) => {
101
- var _a;
102
- return !!((_a = x.weakRef) == null ? void 0 : _a.deref());
103
- }).length
104
- };
105
- }
106
- now() {
107
- return performance.now();
108
- }
109
- }
110
- class PromiseWithState extends Promise {
111
- constructor(value, state = { status: "pending" }) {
112
- super((resolve) => resolve(value));
113
- this.state = state;
114
- value.then((value2) => {
115
- this.state = { status: "value", value: value2 };
116
- }).catch((error) => {
117
- this.state = { status: "error", error };
118
- });
119
- }
120
- static resolve(value) {
121
- return new PromiseWithState(Promise.resolve(value), {
122
- status: "value",
123
- value
124
- });
125
- }
126
- static reject(error) {
127
- return new PromiseWithState(Promise.reject(error), { status: "error", error });
12
+ if (value instanceof Object) {
13
+ return `o[${Object.entries(value).map(hash).sort().join(",")}]`;
128
14
  }
15
+ return JSON.stringify(value);
129
16
  }
130
- class Cache extends Store {
131
- constructor(getter, options = {}, derivedFromCache, _call) {
132
- super(
133
- function() {
134
- let result = getter.apply(this);
135
- if (result instanceof Function) {
136
- result = result(this);
137
- }
138
- return result;
139
- },
140
- options,
141
- void 0,
142
- _call
143
- );
144
- this.options = options;
145
- this.derivedFromCache = derivedFromCache;
146
- this.state = createStore({
147
- status: "pending",
148
- isStale: true,
149
- isUpdating: false
150
- });
151
- autobind(Cache);
152
- this.calculationHelper.options.onInvalidate = () => this.invalidate({ invalidateDependencies: false });
153
- this.watchPromise();
154
- this.watchFocus();
155
- }
156
- get({ update = "whenStale", backgroundUpdate = false } = {}) {
157
- var _a;
158
- const promise = (_a = this._value) == null ? void 0 : _a.v;
159
- const stalePromise = this.stalePromise;
160
- if (update === "whenMissing" && !promise && !stalePromise || update === "whenStale" && !promise || update === "force") {
161
- this.calculationHelper.execute();
162
- if (!promise && !stalePromise || !backgroundUpdate) {
163
- return super.get();
164
- }
165
- }
166
- if (!promise || stalePromise && backgroundUpdate) {
167
- return stalePromise;
168
- }
169
- return promise;
170
- }
171
- updateValue(value) {
172
- this.set(PromiseWithState.resolve(value));
173
- }
174
- updateError(error) {
175
- this.set(PromiseWithState.reject(error));
176
- }
177
- invalidate({ invalidateDependencies = true } = {}) {
178
- var _a;
179
- const { clearOnInvalidate = createCache.defaultOptions.clearOnInvalidate } = this.options;
180
- if (clearOnInvalidate) {
181
- return this.clear({ invalidateDependencies });
182
- }
183
- if (invalidateDependencies) {
184
- this.calculationHelper.invalidateDependencies();
185
- }
186
- const { status, isStale, isUpdating } = this.state.get();
187
- if (status !== "pending" && !isStale && !isUpdating) {
188
- this.stalePromise = (_a = this._value) == null ? void 0 : _a.v;
189
- }
190
- this.state.set((state) => ({
191
- ...state,
192
- isStale: true,
193
- isUpdating: false
194
- }));
195
- this.calculationHelper.stop();
196
- super.reset();
197
- }
198
- clear({ invalidateDependencies = true } = {}) {
199
- if (invalidateDependencies) {
200
- this.calculationHelper.invalidateDependencies();
201
- }
202
- this.state.set({
203
- status: "pending",
204
- isStale: true,
205
- isUpdating: false
206
- });
207
- delete this.stalePromise;
208
- this.calculationHelper.stop();
209
- super.reset();
210
- }
211
- mapValue(_selector) {
212
- const selector = makeSelector(_selector);
213
- const derivedFromCache = {
214
- cache: this.derivedFromCache ? this.derivedFromCache.cache : this,
215
- selectors: this.derivedFromCache ? [...this.derivedFromCache.selectors, _selector] : [_selector]
216
- };
217
- const that = this;
218
- return new Cache(
219
- async function() {
220
- const value = await this.use(that);
221
- return selector(value);
222
- },
223
- {},
224
- derivedFromCache
225
- );
226
- }
227
- watchPromise() {
228
- this.subscribe(
229
- async (promise) => {
230
- var _a, _b;
231
- if (promise instanceof PromiseWithState) {
232
- this.state.set({
233
- ...promise.state,
234
- isStale: false,
235
- isUpdating: false
236
- });
237
- delete this.stalePromise;
238
- this.setTimers();
239
- return;
240
- }
241
- this.state.set((state) => ({
242
- ...state,
243
- isUpdating: true
244
- }));
245
- this.setTimers();
246
- try {
247
- const value = await promise;
248
- if (promise !== ((_a = this._value) == null ? void 0 : _a.v)) {
249
- return;
250
- }
251
- this.state.set({
252
- status: "value",
253
- value,
254
- isStale: false,
255
- isUpdating: false
256
- });
257
- delete this.stalePromise;
258
- this.setTimers();
259
- } catch (error) {
260
- if (promise !== ((_b = this._value) == null ? void 0 : _b.v)) {
261
- return;
262
- }
263
- this.state.set({
264
- status: "error",
265
- error,
266
- isStale: false,
267
- isUpdating: false
268
- });
269
- delete this.stalePromise;
270
- this.setTimers();
271
- }
272
- },
273
- { passive: true }
274
- );
275
- }
276
- setTimers() {
277
- if (this.invalidationTimer) {
278
- clearTimeout(this.invalidationTimer);
279
- }
280
- this.invalidationTimer = void 0;
281
- const state = this.state.get();
282
- let { invalidateAfter = createCache.defaultOptions.invalidateAfter } = this.options;
283
- const ref = new WeakRef(this);
284
- if (state.status === "pending") {
285
- return;
286
- }
287
- if (invalidateAfter instanceof Function) {
288
- invalidateAfter = invalidateAfter(state);
289
- }
290
- if (invalidateAfter !== null && invalidateAfter !== void 0) {
291
- this.invalidationTimer = setTimeout(
292
- () => {
293
- var _a;
294
- return (_a = ref == null ? void 0 : ref.deref()) == null ? void 0 : _a.invalidate();
295
- },
296
- calcDuration(invalidateAfter)
297
- );
298
- }
299
- }
300
- watchFocus() {
301
- const { invalidateOnWindowFocus = createCache.defaultOptions.invalidateOnWindowFocus } = this.options;
302
- if (!invalidateOnWindowFocus || typeof document === "undefined" || typeof document.addEventListener === "undefined") {
303
- return;
304
- }
305
- const ref = new WeakRef(this);
306
- const onFocus = () => {
307
- const that = ref == null ? void 0 : ref.deref();
308
- if (!that) {
309
- document.removeEventListener("visibilitychange", onFocus);
310
- return;
311
- }
312
- if (!document.hidden) {
313
- that.invalidate();
314
- }
315
- };
316
- document.addEventListener("visibilitychange", onFocus);
317
- }
318
- }
319
- function create(cacheFunction, options) {
320
- const { clearUnusedAfter = createCache.defaultOptions.clearUnusedAfter, resourceGroup } = options ?? {};
321
- let baseInstance;
322
- const instanceCache = new InstanceCache(
323
- (...args) => {
324
- if (args.length === 0 && baseInstance) {
325
- return baseInstance;
326
- }
327
- return new Cache(function() {
328
- return cacheFunction.apply(this, args);
329
- }, options);
330
- },
331
- clearUnusedAfter ? calcDuration(clearUnusedAfter) : void 0
332
- );
333
- const get = (...args) => {
334
- return instanceCache.get(...args);
335
- };
336
- const invalidateAll = () => {
337
- for (const instance of instanceCache.values()) {
338
- instance.invalidate();
339
- }
340
- };
341
- const clearAll = () => {
342
- for (const instance of instanceCache.values()) {
343
- instance.clear();
344
- }
345
- };
346
- baseInstance = Object.assign(
347
- new Cache(
348
- function() {
349
- return cacheFunction.apply(this);
350
- },
351
- options,
352
- void 0,
353
- get
354
- ),
355
- {
356
- invalidateAll,
357
- clearAll
358
- }
359
- );
360
- const groups = Array.isArray(resourceGroup) ? resourceGroup : resourceGroup ? [resourceGroup] : [];
361
- for (const group of groups.concat(allResources)) {
362
- group.add(baseInstance);
363
- }
364
- get(...[]);
365
- return baseInstance;
366
- }
367
- const createCache = /* @__PURE__ */ Object.assign(create, {
368
- defaultOptions: {
369
- invalidateOnWindowFocus: true,
370
- invalidateOnActivation: true,
371
- clearUnusedAfter: { days: 1 }
372
- }
373
- });
374
17
  class Scope {
375
18
  constructor(defaultValue) {
376
19
  this.defaultValue = defaultValue;
@@ -381,13 +24,8 @@ function createScope(defaultValue) {
381
24
  return new Scope(defaultValue);
382
25
  }
383
26
  export {
384
- Cache as C,
385
- InstanceCache as I,
386
- ResourceGroup as R,
387
27
  Scope as S,
388
- allResources as a,
389
- createResourceGroup as b,
390
- createCache as c,
391
- createScope as d
28
+ createScope as c,
29
+ hash as h
392
30
  };
393
31
  //# sourceMappingURL=scope.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"scope.mjs","sources":["../../src/core/resourceGroup.ts","../../src/lib/instanceCache.ts","../../src/lib/promiseWithState.ts","../../src/core/cache.ts","../../src/core/scope.ts"],"sourcesContent":["import { autobind } from '@lib/autobind';\n\nexport interface Resource {\n invalidateAll(): void;\n clearAll(): void;\n}\n\nexport class ResourceGroup {\n private refMap = new WeakMap<Resource, WeakRef<Resource>>();\n\n private refSet = new Set<WeakRef<Resource>>();\n\n constructor(public readonly name?: string) {\n autobind(ResourceGroup);\n }\n\n add(resource: Resource) {\n const ref = new WeakRef(resource);\n this.refMap.set(resource, ref);\n this.refSet.add(ref);\n }\n\n delete(resource: Resource) {\n const ref = this.refMap.get(resource);\n if (ref) {\n this.refMap.delete(resource);\n this.refSet.delete(ref);\n }\n }\n\n invalidateAll() {\n for (const ref of this.refSet) {\n const resource = ref.deref();\n if (resource) {\n resource.invalidateAll();\n } else {\n this.refSet.delete(ref);\n }\n }\n }\n\n clearAll() {\n for (const ref of this.refSet) {\n const resource = ref.deref();\n if (resource) {\n resource.clearAll();\n } else {\n this.refSet.delete(ref);\n }\n }\n }\n}\n\nexport const allResources = /* @__PURE__ */ new ResourceGroup();\n\nexport function createResourceGroup(name?: string) {\n return new ResourceGroup(name);\n}\n","import { hash } from './hash';\n\nexport class InstanceCache<Args extends any[], T extends object> {\n private cache = new Map<string, { t: number; ref?: T; weakRef: WeakRef<T> }>();\n\n private interval = this.cacheTime\n ? setInterval(() => this.cleanup(), Math.max(this.cacheTime / 10, 1))\n : undefined;\n\n constructor(public readonly factory: (...args: Args) => T, public readonly cacheTime?: number) {}\n\n cleanup() {\n const cutoff = this.now() - (this.cacheTime ?? 0);\n\n for (const [key, entry] of this.cache.entries()) {\n if (entry.ref && entry.t <= cutoff) {\n delete entry.ref;\n }\n\n if (!entry.ref && !entry.weakRef?.deref()) {\n this.cache.delete(key);\n }\n }\n }\n\n get(...args: Args) {\n const key = hash(args);\n let entry = this.cache.get(key);\n let value = entry?.ref ?? entry?.weakRef?.deref();\n\n if (!entry || !value) {\n value = this.factory(...args);\n entry = {\n t: this.now(),\n ref: value,\n weakRef: new WeakRef(value),\n };\n\n this.cache.set(key, entry);\n } else {\n entry.t = this.now();\n entry.ref ??= value;\n }\n\n return value;\n }\n\n values() {\n return [...this.cache.values()]\n .map((entry) => entry.ref ?? entry.weakRef?.deref())\n .filter((value): value is T => !!value);\n }\n\n stop() {\n if (this.interval) {\n clearInterval(this.interval);\n }\n }\n\n stats() {\n return {\n count: this.cache.size,\n withRef: [...this.cache.values()].filter((x) => !!x.ref).length,\n withWeakRef: [...this.cache.values()].filter((x) => !!x.weakRef?.deref()).length,\n };\n }\n\n private now() {\n return performance.now();\n }\n}\n","import { type ErrorState, type PendingState, type ValueState } from './cacheState';\nimport { type MaybePromise } from './maybePromise';\n\nexport class PromiseWithState<T> extends Promise<T> {\n static override resolve(): PromiseWithState<void>;\n\n static override resolve<T>(value: MaybePromise<T>): PromiseWithState<T>;\n\n static override resolve<T>(value?: MaybePromise<T>) {\n return new PromiseWithState<T>(Promise.resolve(value as MaybePromise<T>), {\n status: 'value',\n value: value as T,\n });\n }\n\n static override reject<T = never>(error: unknown) {\n return new PromiseWithState<T>(Promise.reject(error), { status: 'error', error });\n }\n\n constructor(\n value: Promise<T>,\n public state: ValueState<T> | ErrorState | PendingState = { status: 'pending' },\n ) {\n super((resolve) => resolve(value));\n\n value\n .then((value) => {\n this.state = { status: 'value', value };\n })\n .catch((error) => {\n this.state = { status: 'error', error };\n });\n }\n}\n","import type { Duration, Selector, Use } from './commonTypes';\nimport { allResources, type ResourceGroup } from './resourceGroup';\nimport { Store, createStore } from './store';\nimport { autobind } from '@lib/autobind';\nimport type { CacheState, ErrorState, ValueState } from '@lib/cacheState';\nimport { calcDuration } from '@lib/calcDuration';\nimport { InstanceCache } from '@lib/instanceCache';\nimport { makeSelector } from '@lib/makeSelector';\nimport { type MaybePromise } from '@lib/maybePromise';\nimport type { Path, Value } from '@lib/path';\nimport { PromiseWithState } from '@lib/promiseWithState';\n\nexport interface CacheGetOptions {\n update?: 'whenMissing' | 'whenStale' | 'force';\n backgroundUpdate?: boolean;\n}\n\nexport interface CacheFunction<T, Args extends any[] = []> {\n (this: { use: Use }, ...args: Args): Promise<T> | ((cache: { use: Use }) => Promise<T>);\n}\n\nexport interface CacheOptions<T> {\n invalidateAfter?: Duration | ((state: ValueState<T> | ErrorState) => Duration | null) | null;\n invalidateOnWindowFocus?: boolean;\n invalidateOnActivation?: boolean;\n clearOnInvalidate?: boolean;\n clearUnusedAfter?: Duration | null;\n resourceGroup?: ResourceGroup | ResourceGroup[];\n retain?: number;\n}\n\nexport class Cache<T> extends Store<Promise<T>> {\n readonly state = createStore<CacheState<T>>({\n status: 'pending',\n isStale: true,\n isUpdating: false,\n });\n\n protected stalePromise?: Promise<T>;\n\n protected invalidationTimer?: ReturnType<typeof setTimeout>;\n\n constructor(\n getter: CacheFunction<T>,\n public readonly options: CacheOptions<T> = {},\n public readonly derivedFromCache?: {\n cache: Cache<any>;\n selectors: (Selector<any, any> | Path<any>)[];\n },\n _call?: (...args: any[]) => any,\n ) {\n super(\n function () {\n let result = getter.apply(this);\n\n if (result instanceof Function) {\n result = result(this);\n }\n\n return result;\n },\n options,\n undefined,\n _call,\n );\n autobind(Cache);\n\n this.calculationHelper.options.onInvalidate = () =>\n this.invalidate({ invalidateDependencies: false });\n this.watchPromise();\n this.watchFocus();\n }\n\n get({ update = 'whenStale', backgroundUpdate = false }: CacheGetOptions = {}) {\n const promise = this._value?.v;\n const stalePromise = this.stalePromise;\n\n if (\n (update === 'whenMissing' && !promise && !stalePromise) ||\n (update === 'whenStale' && !promise) ||\n update === 'force'\n ) {\n this.calculationHelper.execute();\n\n if ((!promise && !stalePromise) || !backgroundUpdate) {\n return super.get();\n }\n }\n\n if (!promise || (stalePromise && backgroundUpdate)) {\n return stalePromise!;\n }\n\n return promise;\n }\n\n updateValue(value: MaybePromise<T>) {\n this.set(PromiseWithState.resolve(value));\n }\n\n updateError(error: unknown) {\n this.set(PromiseWithState.reject(error));\n }\n\n invalidate({ invalidateDependencies = true }: { invalidateDependencies?: boolean } = {}) {\n const { clearOnInvalidate = createCache.defaultOptions.clearOnInvalidate } = this.options;\n\n if (clearOnInvalidate) {\n return this.clear({ invalidateDependencies });\n }\n\n if (invalidateDependencies) {\n this.calculationHelper.invalidateDependencies();\n }\n\n const { status, isStale, isUpdating } = this.state.get();\n if (status !== 'pending' && !isStale && !isUpdating) {\n this.stalePromise = this._value?.v;\n }\n\n this.state.set((state) => ({\n ...state,\n isStale: true,\n isUpdating: false,\n }));\n\n this.calculationHelper.stop();\n super.reset();\n }\n\n clear({ invalidateDependencies = true }: { invalidateDependencies?: boolean } = {}): void {\n if (invalidateDependencies) {\n this.calculationHelper.invalidateDependencies();\n }\n\n this.state.set({\n status: 'pending',\n isStale: true,\n isUpdating: false,\n });\n delete this.stalePromise;\n\n this.calculationHelper.stop();\n super.reset();\n }\n\n mapValue<S>(selector: Selector<T, S>): Cache<S>;\n\n mapValue<P extends Path<T>>(selector: P): Cache<Value<T, P>>;\n\n mapValue<S>(_selector: Selector<T, S> | Path<any>): Cache<S> {\n const selector = makeSelector(_selector);\n const derivedFromCache = {\n cache: this.derivedFromCache ? this.derivedFromCache.cache : this,\n selectors: this.derivedFromCache\n ? [...this.derivedFromCache.selectors, _selector]\n : [_selector],\n };\n const that = this;\n\n return new Cache(\n async function () {\n const value = await this.use(that);\n return selector(value);\n },\n {},\n derivedFromCache,\n );\n }\n\n protected watchPromise() {\n this.subscribe(\n async (promise) => {\n if (promise instanceof PromiseWithState) {\n this.state.set({\n ...promise.state,\n isStale: false,\n isUpdating: false,\n });\n\n delete this.stalePromise;\n this.setTimers();\n return;\n }\n\n this.state.set((state) => ({\n ...state,\n isUpdating: true,\n }));\n\n this.setTimers();\n\n try {\n const value = await promise;\n\n if (promise !== this._value?.v) {\n return;\n }\n\n this.state.set({\n status: 'value',\n value,\n isStale: false,\n isUpdating: false,\n });\n delete this.stalePromise;\n this.setTimers();\n } catch (error) {\n if (promise !== this._value?.v) {\n return;\n }\n\n this.state.set({\n status: 'error',\n error,\n isStale: false,\n isUpdating: false,\n });\n delete this.stalePromise;\n this.setTimers();\n }\n },\n { passive: true },\n );\n }\n\n protected setTimers() {\n if (this.invalidationTimer) {\n clearTimeout(this.invalidationTimer);\n }\n this.invalidationTimer = undefined;\n\n const state = this.state.get();\n let { invalidateAfter = createCache.defaultOptions.invalidateAfter } = this.options;\n const ref = new WeakRef(this);\n\n if (state.status === 'pending') {\n return;\n }\n\n if (invalidateAfter instanceof Function) {\n invalidateAfter = invalidateAfter(state);\n }\n\n if (invalidateAfter !== null && invalidateAfter !== undefined) {\n this.invalidationTimer = setTimeout(\n () => ref?.deref()?.invalidate(),\n calcDuration(invalidateAfter),\n );\n }\n }\n\n protected watchFocus() {\n const { invalidateOnWindowFocus = createCache.defaultOptions.invalidateOnWindowFocus } =\n this.options;\n\n if (\n !invalidateOnWindowFocus ||\n typeof document === 'undefined' ||\n typeof document.addEventListener === 'undefined'\n ) {\n return;\n }\n\n const ref = new WeakRef(this);\n\n const onFocus = () => {\n const that = ref?.deref();\n if (!that) {\n document.removeEventListener('visibilitychange', onFocus);\n return;\n }\n\n if (!document.hidden) {\n that.invalidate();\n }\n };\n\n document.addEventListener('visibilitychange', onFocus);\n }\n}\n\ntype CreateReturnType<T, Args extends any[]> = {\n (...args: Args): Cache<T>;\n invalidateAll: () => void;\n clearAll: () => void;\n} & ([] extends Args ? Cache<T> : {});\n\nfunction create<T, Args extends any[]>(\n cacheFunction: CacheFunction<T, Args>,\n options?: CacheOptions<T>,\n): CreateReturnType<T, Args> {\n const { clearUnusedAfter = createCache.defaultOptions.clearUnusedAfter, resourceGroup } =\n options ?? {};\n\n let baseInstance: CreateReturnType<T, Args> & Cache<T>;\n\n const instanceCache = new InstanceCache<Args, Cache<T>>(\n (...args: Args): Cache<T> => {\n if (args.length === 0 && baseInstance) {\n return baseInstance;\n }\n\n return new Cache(function () {\n return cacheFunction.apply(this, args);\n }, options);\n },\n clearUnusedAfter ? calcDuration(clearUnusedAfter) : undefined,\n );\n\n const get = (...args: Args) => {\n return instanceCache.get(...args);\n };\n\n const invalidateAll = () => {\n for (const instance of instanceCache.values()) {\n instance.invalidate();\n }\n };\n\n const clearAll = () => {\n for (const instance of instanceCache.values()) {\n instance.clear();\n }\n };\n\n baseInstance = Object.assign(\n new Cache(\n function () {\n return cacheFunction.apply(this);\n },\n options,\n undefined,\n get,\n ),\n {\n invalidateAll,\n clearAll,\n },\n ) as CreateReturnType<T, Args> & Cache<T>;\n\n const groups = Array.isArray(resourceGroup)\n ? resourceGroup\n : resourceGroup\n ? [resourceGroup]\n : [];\n for (const group of groups.concat(allResources)) {\n group.add(baseInstance);\n }\n\n get(...([] as any));\n\n return baseInstance;\n}\n\nexport const createCache = /* @__PURE__ */ Object.assign(create, {\n defaultOptions: {\n invalidateOnWindowFocus: true,\n invalidateOnActivation: true,\n clearUnusedAfter: { days: 1 },\n } as CacheOptions<unknown>,\n});\n","import { autobind } from '@lib/autobind';\n\nexport class Scope<T> {\n constructor(public readonly defaultValue: T) {\n autobind(Scope);\n }\n}\n\nexport function createScope<T>(defaultValue: T): Scope<T> {\n return new Scope(defaultValue);\n}\n"],"names":["value"],"mappings":";;AAOO,MAAM,cAAc;AAAA,EAKzB,YAA4B,MAAe;AAAf,SAAA,OAAA;AAJpB,SAAA,6BAAa;AAEb,SAAA,6BAAa;AAGnB,aAAS,aAAa;AAAA,EACxB;AAAA,EAEA,IAAI,UAAoB;AAChB,UAAA,MAAM,IAAI,QAAQ,QAAQ;AAC3B,SAAA,OAAO,IAAI,UAAU,GAAG;AACxB,SAAA,OAAO,IAAI,GAAG;AAAA,EACrB;AAAA,EAEA,OAAO,UAAoB;AACzB,UAAM,MAAM,KAAK,OAAO,IAAI,QAAQ;AACpC,QAAI,KAAK;AACF,WAAA,OAAO,OAAO,QAAQ;AACtB,WAAA,OAAO,OAAO,GAAG;AAAA,IACxB;AAAA,EACF;AAAA,EAEA,gBAAgB;AACH,eAAA,OAAO,KAAK,QAAQ;AACvB,YAAA,WAAW,IAAI;AACrB,UAAI,UAAU;AACZ,iBAAS,cAAc;AAAA,MAAA,OAClB;AACA,aAAA,OAAO,OAAO,GAAG;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,WAAW;AACE,eAAA,OAAO,KAAK,QAAQ;AACvB,YAAA,WAAW,IAAI;AACrB,UAAI,UAAU;AACZ,iBAAS,SAAS;AAAA,MAAA,OACb;AACA,aAAA,OAAO,OAAO,GAAG;AAAA,MACxB;AAAA,IACF;AAAA,EACF;AACF;AAEa,MAAA,mCAAmC,cAAc;AAEvD,SAAS,oBAAoB,MAAe;AAC1C,SAAA,IAAI,cAAc,IAAI;AAC/B;ACvDO,MAAM,cAAoD;AAAA,EAO/D,YAA4B,SAA+C,WAAoB;AAAnE,SAAA,UAAA;AAA+C,SAAA,YAAA;AANnE,SAAA,4BAAY;AAEpB,SAAQ,WAAW,KAAK,YACpB,YAAY,MAAM,KAAK,QAAW,GAAA,KAAK,IAAI,KAAK,YAAY,IAAI,CAAC,CAAC,IAClE;AAAA,EAE4F;AAAA,EAEhG,UAAU;;AACR,UAAM,SAAS,KAAK,IAAI,KAAK,KAAK,aAAa;AAE/C,eAAW,CAAC,KAAK,KAAK,KAAK,KAAK,MAAM,WAAW;AAC/C,UAAI,MAAM,OAAO,MAAM,KAAK,QAAQ;AAClC,eAAO,MAAM;AAAA,MACf;AAEA,UAAI,CAAC,MAAM,OAAO,GAAC,WAAM,YAAN,mBAAe,UAAS;AACpC,aAAA,MAAM,OAAO,GAAG;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO,MAAY;;AACX,UAAA,MAAM,KAAK,IAAI;AACrB,QAAI,QAAQ,KAAK,MAAM,IAAI,GAAG;AAC9B,QAAI,SAAQ,+BAAO,UAAO,oCAAO,YAAP,mBAAgB;AAEtC,QAAA,CAAC,SAAS,CAAC,OAAO;AACZ,cAAA,KAAK,QAAQ,GAAG,IAAI;AACpB,cAAA;AAAA,QACN,GAAG,KAAK,IAAI;AAAA,QACZ,KAAK;AAAA,QACL,SAAS,IAAI,QAAQ,KAAK;AAAA,MAAA;AAGvB,WAAA,MAAM,IAAI,KAAK,KAAK;AAAA,IAAA,OACpB;AACC,YAAA,IAAI,KAAK;AACf,YAAM,QAAN,MAAM,MAAQ;AAAA,IAChB;AAEO,WAAA;AAAA,EACT;AAAA,EAEA,SAAS;AACA,WAAA,CAAC,GAAG,KAAK,MAAM,OAAQ,CAAA,EAC3B,IAAI,CAAC;;AAAU,mBAAM,SAAO,WAAM,YAAN,mBAAe;AAAA,KAAO,EAClD,OAAO,CAAC,UAAsB,CAAC,CAAC,KAAK;AAAA,EAC1C;AAAA,EAEA,OAAO;AACL,QAAI,KAAK,UAAU;AACjB,oBAAc,KAAK,QAAQ;AAAA,IAC7B;AAAA,EACF;AAAA,EAEA,QAAQ;AACC,WAAA;AAAA,MACL,OAAO,KAAK,MAAM;AAAA,MAClB,SAAS,CAAC,GAAG,KAAK,MAAM,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE;AAAA,MACzD,aAAa,CAAC,GAAG,KAAK,MAAM,OAAQ,CAAA,EAAE,OAAO,CAAC;;AAAM,gBAAC,GAAC,OAAE,YAAF,mBAAW;AAAA,OAAO,EAAE;AAAA,IAAA;AAAA,EAE9E;AAAA,EAEQ,MAAM;AACZ,WAAO,YAAY;EACrB;AACF;ACnEO,MAAM,yBAA4B,QAAW;AAAA,EAgBlD,YACE,OACO,QAAmD,EAAE,QAAQ,aACpE;AACA,UAAM,CAAC,YAAY,QAAQ,KAAK,CAAC;AAF1B,SAAA,QAAA;AAKJ,UAAA,KAAK,CAACA,WAAU;AACf,WAAK,QAAQ,EAAE,QAAQ,SAAS,OAAAA;IAAM,CACvC,EACA,MAAM,CAAC,UAAU;AAChB,WAAK,QAAQ,EAAE,QAAQ,SAAS,MAAM;AAAA,IAAA,CACvC;AAAA,EACL;AAAA,EAxBA,OAAgB,QAAW,OAAyB;AAClD,WAAO,IAAI,iBAAoB,QAAQ,QAAQ,KAAwB,GAAG;AAAA,MACxE,QAAQ;AAAA,MACR;AAAA,IAAA,CACD;AAAA,EACH;AAAA,EAEA,OAAgB,OAAkB,OAAgB;AACzC,WAAA,IAAI,iBAAoB,QAAQ,OAAO,KAAK,GAAG,EAAE,QAAQ,SAAS,MAAA,CAAO;AAAA,EAClF;AAgBF;ACFO,MAAM,cAAiB,MAAkB;AAAA,EAW9C,YACE,QACgB,UAA2B,CAAA,GAC3B,kBAIhB,OACA;AACA;AAAA,MACE,WAAY;AACN,YAAA,SAAS,OAAO,MAAM,IAAI;AAE9B,YAAI,kBAAkB,UAAU;AAC9B,mBAAS,OAAO,IAAI;AAAA,QACtB;AAEO,eAAA;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAnBc,SAAA,UAAA;AACA,SAAA,mBAAA;AAblB,SAAS,QAAQ,YAA2B;AAAA,MAC1C,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,YAAY;AAAA,IAAA,CACb;AA6BC,aAAS,KAAK;AAET,SAAA,kBAAkB,QAAQ,eAAe,MAC5C,KAAK,WAAW,EAAE,wBAAwB,MAAA,CAAO;AACnD,SAAK,aAAa;AAClB,SAAK,WAAW;AAAA,EAClB;AAAA,EAEA,IAAI,EAAE,SAAS,aAAa,mBAAmB,MAAM,IAAqB,IAAI;;AACtE,UAAA,WAAU,UAAK,WAAL,mBAAa;AAC7B,UAAM,eAAe,KAAK;AAGvB,QAAA,WAAW,iBAAiB,CAAC,WAAW,CAAC,gBACzC,WAAW,eAAe,CAAC,WAC5B,WAAW,SACX;AACA,WAAK,kBAAkB;AAEvB,UAAK,CAAC,WAAW,CAAC,gBAAiB,CAAC,kBAAkB;AACpD,eAAO,MAAM;MACf;AAAA,IACF;AAEI,QAAA,CAAC,WAAY,gBAAgB,kBAAmB;AAC3C,aAAA;AAAA,IACT;AAEO,WAAA;AAAA,EACT;AAAA,EAEA,YAAY,OAAwB;AAClC,SAAK,IAAI,iBAAiB,QAAQ,KAAK,CAAC;AAAA,EAC1C;AAAA,EAEA,YAAY,OAAgB;AAC1B,SAAK,IAAI,iBAAiB,OAAO,KAAK,CAAC;AAAA,EACzC;AAAA,EAEA,WAAW,EAAE,yBAAyB,KAAK,IAA0C,CAAA,GAAI;;AACvF,UAAM,EAAE,oBAAoB,YAAY,eAAe,sBAAsB,KAAK;AAElF,QAAI,mBAAmB;AACrB,aAAO,KAAK,MAAM,EAAE,uBAAwB,CAAA;AAAA,IAC9C;AAEA,QAAI,wBAAwB;AAC1B,WAAK,kBAAkB;IACzB;AAEA,UAAM,EAAE,QAAQ,SAAS,WAAe,IAAA,KAAK,MAAM;AACnD,QAAI,WAAW,aAAa,CAAC,WAAW,CAAC,YAAY;AAC9C,WAAA,gBAAe,UAAK,WAAL,mBAAa;AAAA,IACnC;AAEK,SAAA,MAAM,IAAI,CAAC,WAAW;AAAA,MACzB,GAAG;AAAA,MACH,SAAS;AAAA,MACT,YAAY;AAAA,IACZ,EAAA;AAEF,SAAK,kBAAkB;AACvB,UAAM,MAAM;AAAA,EACd;AAAA,EAEA,MAAM,EAAE,yBAAyB,KAAK,IAA0C,CAAA,GAAU;AACxF,QAAI,wBAAwB;AAC1B,WAAK,kBAAkB;IACzB;AAEA,SAAK,MAAM,IAAI;AAAA,MACb,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,YAAY;AAAA,IAAA,CACb;AACD,WAAO,KAAK;AAEZ,SAAK,kBAAkB;AACvB,UAAM,MAAM;AAAA,EACd;AAAA,EAMA,SAAY,WAAiD;AACrD,UAAA,WAAW,aAAa,SAAS;AACvC,UAAM,mBAAmB;AAAA,MACvB,OAAO,KAAK,mBAAmB,KAAK,iBAAiB,QAAQ;AAAA,MAC7D,WAAW,KAAK,mBACZ,CAAC,GAAG,KAAK,iBAAiB,WAAW,SAAS,IAC9C,CAAC,SAAS;AAAA,IAAA;AAEhB,UAAM,OAAO;AAEb,WAAO,IAAI;AAAA,MACT,iBAAkB;AAChB,cAAM,QAAQ,MAAM,KAAK,IAAI,IAAI;AACjC,eAAO,SAAS,KAAK;AAAA,MACvB;AAAA,MACA,CAAC;AAAA,MACD;AAAA,IAAA;AAAA,EAEJ;AAAA,EAEU,eAAe;AAClB,SAAA;AAAA,MACH,OAAO,YAAY;;AACjB,YAAI,mBAAmB,kBAAkB;AACvC,eAAK,MAAM,IAAI;AAAA,YACb,GAAG,QAAQ;AAAA,YACX,SAAS;AAAA,YACT,YAAY;AAAA,UAAA,CACb;AAED,iBAAO,KAAK;AACZ,eAAK,UAAU;AACf;AAAA,QACF;AAEK,aAAA,MAAM,IAAI,CAAC,WAAW;AAAA,UACzB,GAAG;AAAA,UACH,YAAY;AAAA,QACZ,EAAA;AAEF,aAAK,UAAU;AAEX,YAAA;AACF,gBAAM,QAAQ,MAAM;AAEhB,cAAA,cAAY,UAAK,WAAL,mBAAa,IAAG;AAC9B;AAAA,UACF;AAEA,eAAK,MAAM,IAAI;AAAA,YACb,QAAQ;AAAA,YACR;AAAA,YACA,SAAS;AAAA,YACT,YAAY;AAAA,UAAA,CACb;AACD,iBAAO,KAAK;AACZ,eAAK,UAAU;AAAA,iBACR,OAAO;AACV,cAAA,cAAY,UAAK,WAAL,mBAAa,IAAG;AAC9B;AAAA,UACF;AAEA,eAAK,MAAM,IAAI;AAAA,YACb,QAAQ;AAAA,YACR;AAAA,YACA,SAAS;AAAA,YACT,YAAY;AAAA,UAAA,CACb;AACD,iBAAO,KAAK;AACZ,eAAK,UAAU;AAAA,QACjB;AAAA,MACF;AAAA,MACA,EAAE,SAAS,KAAK;AAAA,IAAA;AAAA,EAEpB;AAAA,EAEU,YAAY;AACpB,QAAI,KAAK,mBAAmB;AAC1B,mBAAa,KAAK,iBAAiB;AAAA,IACrC;AACA,SAAK,oBAAoB;AAEnB,UAAA,QAAQ,KAAK,MAAM,IAAI;AAC7B,QAAI,EAAE,kBAAkB,YAAY,eAAe,oBAAoB,KAAK;AACtE,UAAA,MAAM,IAAI,QAAQ,IAAI;AAExB,QAAA,MAAM,WAAW,WAAW;AAC9B;AAAA,IACF;AAEA,QAAI,2BAA2B,UAAU;AACvC,wBAAkB,gBAAgB,KAAK;AAAA,IACzC;AAEI,QAAA,oBAAoB,QAAQ,oBAAoB,QAAW;AAC7D,WAAK,oBAAoB;AAAA,QACvB;;AAAM,kDAAK,YAAL,mBAAc;AAAA;AAAA,QACpB,aAAa,eAAe;AAAA,MAAA;AAAA,IAEhC;AAAA,EACF;AAAA,EAEU,aAAa;AACrB,UAAM,EAAE,0BAA0B,YAAY,eAAe,4BAC3D,KAAK;AAGL,QAAA,CAAC,2BACD,OAAO,aAAa,eACpB,OAAO,SAAS,qBAAqB,aACrC;AACA;AAAA,IACF;AAEM,UAAA,MAAM,IAAI,QAAQ,IAAI;AAE5B,UAAM,UAAU,MAAM;AACd,YAAA,OAAO,2BAAK;AAClB,UAAI,CAAC,MAAM;AACA,iBAAA,oBAAoB,oBAAoB,OAAO;AACxD;AAAA,MACF;AAEI,UAAA,CAAC,SAAS,QAAQ;AACpB,aAAK,WAAW;AAAA,MAClB;AAAA,IAAA;AAGO,aAAA,iBAAiB,oBAAoB,OAAO;AAAA,EACvD;AACF;AAQA,SAAS,OACP,eACA,SAC2B;AACrB,QAAA,EAAE,mBAAmB,YAAY,eAAe,kBAAkB,cAAc,IACpF,WAAW;AAET,MAAA;AAEJ,QAAM,gBAAgB,IAAI;AAAA,IACxB,IAAI,SAAyB;AACvB,UAAA,KAAK,WAAW,KAAK,cAAc;AAC9B,eAAA;AAAA,MACT;AAEO,aAAA,IAAI,MAAM,WAAY;AACpB,eAAA,cAAc,MAAM,MAAM,IAAI;AAAA,SACpC,OAAO;AAAA,IACZ;AAAA,IACA,mBAAmB,aAAa,gBAAgB,IAAI;AAAA,EAAA;AAGhD,QAAA,MAAM,IAAI,SAAe;AACtB,WAAA,cAAc,IAAI,GAAG,IAAI;AAAA,EAAA;AAGlC,QAAM,gBAAgB,MAAM;AACf,eAAA,YAAY,cAAc,UAAU;AAC7C,eAAS,WAAW;AAAA,IACtB;AAAA,EAAA;AAGF,QAAM,WAAW,MAAM;AACV,eAAA,YAAY,cAAc,UAAU;AAC7C,eAAS,MAAM;AAAA,IACjB;AAAA,EAAA;AAGF,iBAAe,OAAO;AAAA,IACpB,IAAI;AAAA,MACF,WAAY;AACH,eAAA,cAAc,MAAM,IAAI;AAAA,MACjC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,IACF;AAAA,EAAA;AAGI,QAAA,SAAS,MAAM,QAAQ,aAAa,IACtC,gBACA,gBACA,CAAC,aAAa,IACd;AACJ,aAAW,SAAS,OAAO,OAAO,YAAY,GAAG;AAC/C,UAAM,IAAI,YAAY;AAAA,EACxB;AAEI,MAAA,GAAI,CAAA,CAAU;AAEX,SAAA;AACT;AAEa,MAAA,cAAqC,uBAAA,OAAO,QAAQ;AAAA,EAC/D,gBAAgB;AAAA,IACd,yBAAyB;AAAA,IACzB,wBAAwB;AAAA,IACxB,kBAAkB,EAAE,MAAM,EAAE;AAAA,EAC9B;AACF,CAAC;ACvWM,MAAM,MAAS;AAAA,EACpB,YAA4B,cAAiB;AAAjB,SAAA,eAAA;AAC1B,aAAS,KAAK;AAAA,EAChB;AACF;AAEO,SAAS,YAAe,cAA2B;AACjD,SAAA,IAAI,MAAM,YAAY;AAC/B;"}
1
+ {"version":3,"file":"scope.mjs","sources":["../../src/lib/hash.ts","../../src/core/scope.ts"],"sourcesContent":["export function hash(value: unknown): string {\n if (value instanceof Set) {\n return `s[${[...value].map(hash).sort().join(',')}]`;\n }\n\n if (value instanceof Map) {\n return `m[${[...value.entries()].map(hash).sort().join(',')}]`;\n }\n\n if (Array.isArray(value)) {\n return `[${value.map(hash).join(',')}]`;\n }\n\n if (value instanceof Object) {\n return `o[${Object.entries(value).map(hash).sort().join(',')}]`;\n }\n\n return JSON.stringify(value);\n}\n","import { autobind } from '@lib/autobind';\n\nexport class Scope<T> {\n constructor(public readonly defaultValue: T) {\n autobind(Scope);\n }\n}\n\nexport function createScope<T>(defaultValue: T): Scope<T> {\n return new Scope(defaultValue);\n}\n"],"names":[],"mappings":";AAAO,SAAS,KAAK,OAAwB;AAC3C,MAAI,iBAAiB,KAAK;AACxB,WAAO,KAAK,CAAC,GAAG,KAAK,EAAE,IAAI,IAAI,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC;AAAA,EACnD;AAEA,MAAI,iBAAiB,KAAK;AACxB,WAAO,KAAK,CAAC,GAAG,MAAM,QAAS,CAAA,EAAE,IAAI,IAAI,EAAE,KAAA,EAAO,KAAK,GAAG,CAAC;AAAA,EAC7D;AAEI,MAAA,MAAM,QAAQ,KAAK,GAAG;AACxB,WAAO,IAAI,MAAM,IAAI,IAAI,EAAE,KAAK,GAAG,CAAC;AAAA,EACtC;AAEA,MAAI,iBAAiB,QAAQ;AAC3B,WAAO,KAAK,OAAO,QAAQ,KAAK,EAAE,IAAI,IAAI,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC;AAAA,EAC9D;AAEO,SAAA,KAAK,UAAU,KAAK;AAC7B;AChBO,MAAM,MAAS;AAAA,EACpB,YAA4B,cAAiB;AAAjB,SAAA,eAAA;AAC1B,aAAS,KAAK;AAAA,EAChB;AACF;AAEO,SAAS,YAAe,cAA2B;AACjD,SAAA,IAAI,MAAM,YAAY;AAC/B;"}
@@ -1,7 +1,7 @@
1
1
  import { d as deepEqual, m as makeSelector, c as createStore } from "./store.mjs";
2
- import require$$0, { useRef, useMemo, useCallback, useLayoutEffect, useDebugValue, useEffect, useContext, createContext } from "react";
3
- import { jsx } from "react/jsx-runtime";
4
- import { h as hash } from "./hash.mjs";
2
+ import require$$0, { useRef, useMemo, useCallback, useLayoutEffect, useDebugValue, useContext, createContext, useEffect } from "react";
3
+ import { h as hash, c as createScope } from "./scope.mjs";
4
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
5
5
  const unwrapProxySymbol = /* @__PURE__ */ Symbol("unwrapProxy");
6
6
  function isPlainObject(value) {
7
7
  return typeof value === "object" && value !== null && Object.getPrototypeOf(value) === Object.prototype;
@@ -535,6 +535,62 @@ function useProp(store, argument1, argument2, argument3) {
535
535
  const value = useStore(store, options);
536
536
  return [value, store.set];
537
537
  }
538
+ function getScopeContext(scope) {
539
+ scope.context ?? (scope.context = createContext(createStore(scope.defaultValue)));
540
+ return scope.context;
541
+ }
542
+ function ScopeProvider({ scope, store: inputStore, children }) {
543
+ const context = getScopeContext(scope);
544
+ const currentStore = useMemo(
545
+ () => inputStore ?? createStore(scope.defaultValue),
546
+ [scope, inputStore]
547
+ );
548
+ return /* @__PURE__ */ jsx(context.Provider, { value: currentStore, children });
549
+ }
550
+ function useScope(scope) {
551
+ const context = getScopeContext(scope);
552
+ return useContext(context);
553
+ }
554
+ function useScopeStore(scope, options) {
555
+ const store = useScope(scope);
556
+ return useStore(store, options);
557
+ }
558
+ function useScopeProp(scope, options) {
559
+ const store = useScope(scope);
560
+ return useProp(store, options);
561
+ }
562
+ const LoadingBoundaryContext = createScope(/* @__PURE__ */ new Set());
563
+ function LoadingBoundary({
564
+ fallback,
565
+ children,
566
+ isLoading: isLoadingExternal
567
+ }) {
568
+ const store = useMemo(() => createStore(/* @__PURE__ */ new Set()), []);
569
+ const entries = useStore(store);
570
+ const isLoading = entries.size > 0 || isLoadingExternal;
571
+ const fallbackNode = isLoading ? typeof fallback === "function" ? fallback([...entries]) : fallback : void 0;
572
+ return /* @__PURE__ */ jsx(ScopeProvider, { scope: LoadingBoundaryContext, store, children: fallbackNode !== void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
573
+ fallbackNode,
574
+ /* @__PURE__ */ jsx("div", { style: { display: "none" }, children })
575
+ ] }) : children });
576
+ }
577
+ function useLoadingBoundary(isLoading, label) {
578
+ const store = useScope(LoadingBoundaryContext);
579
+ useLayoutEffect(() => {
580
+ if (!isLoading) {
581
+ return;
582
+ }
583
+ const entry = { label };
584
+ store.set((entries) => new Set(entries).add(entry));
585
+ return () => {
586
+ store.set((entries) => {
587
+ const newEntries = new Set(entries);
588
+ newEntries.delete(entry);
589
+ return newEntries;
590
+ });
591
+ };
592
+ }, [isLoading]);
593
+ }
538
594
  function boundUseStore(...args) {
539
595
  return useStore(this, ...args);
540
596
  }
@@ -551,6 +607,7 @@ function useCache(cache, {
551
607
  updateOnMount,
552
608
  withViewTransition,
553
609
  suspense,
610
+ loadingBoundary = true,
554
611
  ...options
555
612
  } = {}) {
556
613
  if (withViewTransition === true) {
@@ -601,43 +658,22 @@ function useCache(cache, {
601
658
  return cache.subscribe(() => void 0);
602
659
  }, [cache, passive, disabled]);
603
660
  const result = useStore(mappedState, { ...options, withViewTransition });
661
+ useLoadingBoundary(loadingBoundary && !disabled && result.status === "pending");
604
662
  if (suspense && result.status === "pending") {
605
663
  throw cache.get();
606
664
  }
607
665
  return result;
608
666
  }
609
- function getScopeContext(scope) {
610
- scope.context ?? (scope.context = createContext(createStore(scope.defaultValue)));
611
- return scope.context;
612
- }
613
- function ScopeProvider({ scope, store: inputStore, children }) {
614
- const context = getScopeContext(scope);
615
- const currentStore = useMemo(
616
- () => inputStore ?? createStore(scope.defaultValue),
617
- [scope, inputStore]
618
- );
619
- return /* @__PURE__ */ jsx(context.Provider, { value: currentStore, children });
620
- }
621
- function useScope(scope) {
622
- const context = getScopeContext(scope);
623
- return useContext(context);
624
- }
625
- function useScopeStore(scope, options) {
626
- const store = useScope(scope);
627
- return useStore(store, options);
628
- }
629
- function useScopeProp(scope, options) {
630
- const store = useScope(scope);
631
- return useProp(store, options);
632
- }
633
667
  export {
668
+ LoadingBoundary as L,
634
669
  ScopeProvider as S,
635
670
  useScope as a,
636
671
  useScopeStore as b,
637
672
  useScopeProp as c,
638
673
  useStore as d,
639
- useProp as e,
674
+ useLoadingBoundary as e,
675
+ useProp as f,
640
676
  reactMethods as r,
641
677
  useCache as u
642
678
  };
643
- //# sourceMappingURL=scope2.mjs.map
679
+ //# sourceMappingURL=useCache.mjs.map