shelving 1.187.3 → 1.188.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.
Files changed (107) hide show
  1. package/api/cache/APICache.d.ts +5 -5
  2. package/api/cache/APICache.js +13 -13
  3. package/api/cache/EndpointCache.d.ts +5 -5
  4. package/api/cache/EndpointCache.js +13 -13
  5. package/api/store/EndpointStore.d.ts +4 -36
  6. package/api/store/EndpointStore.js +7 -108
  7. package/cloudflare/CloudflareKVProvider.d.ts +3 -3
  8. package/db/cache/CollectionCache.d.ts +7 -7
  9. package/db/cache/CollectionCache.js +19 -20
  10. package/db/cache/DBCache.d.ts +8 -8
  11. package/db/cache/DBCache.js +19 -19
  12. package/db/provider/CacheDBProvider.d.ts +3 -3
  13. package/db/provider/DBProvider.d.ts +3 -3
  14. package/db/provider/DebugDBProvider.d.ts +3 -3
  15. package/db/provider/MemoryDBProvider.d.ts +4 -4
  16. package/db/provider/MemoryDBProvider.js +1 -1
  17. package/db/provider/SQLProvider.d.ts +3 -3
  18. package/db/provider/ThroughDBProvider.d.ts +3 -3
  19. package/db/provider/ValidationDBProvider.d.ts +3 -3
  20. package/db/store/ItemStore.d.ts +11 -18
  21. package/db/store/ItemStore.js +13 -38
  22. package/db/store/QueryStore.d.ts +11 -17
  23. package/db/store/QueryStore.js +39 -60
  24. package/error/BaseError.d.ts +4 -4
  25. package/error/BaseError.js +6 -10
  26. package/error/Errors.d.ts +10 -0
  27. package/error/Errors.js +12 -0
  28. package/error/NetworkError.d.ts +4 -2
  29. package/error/NetworkError.js +5 -4
  30. package/error/RequestError.d.ts +6 -4
  31. package/error/RequestError.js +7 -6
  32. package/error/RequiredError.d.ts +4 -2
  33. package/error/RequiredError.js +5 -4
  34. package/error/ResponseError.d.ts +4 -4
  35. package/error/ResponseError.js +5 -7
  36. package/error/UnexpectedError.d.ts +4 -2
  37. package/error/UnexpectedError.js +5 -4
  38. package/error/UnimplementedError.d.ts +4 -2
  39. package/error/UnimplementedError.js +5 -4
  40. package/error/ValueError.d.ts +4 -2
  41. package/error/ValueError.js +5 -4
  42. package/error/index.d.ts +1 -0
  43. package/error/index.js +1 -0
  44. package/firestore/client/FirestoreClientProvider.d.ts +3 -3
  45. package/firestore/client/FirestoreClientProvider.js +6 -3
  46. package/firestore/lite/FirestoreLiteProvider.d.ts +3 -3
  47. package/firestore/server/FirestoreServerProvider.d.ts +3 -3
  48. package/firestore/server/FirestoreServerProvider.js +6 -3
  49. package/package.json +1 -1
  50. package/react/createAPIContext.d.ts +2 -2
  51. package/react/createAPIContext.js +2 -7
  52. package/react/createDBContext.js +2 -4
  53. package/sequence/DeferredSequence.d.ts +38 -19
  54. package/sequence/DeferredSequence.js +67 -48
  55. package/sequence/InspectSequence.d.ts +9 -7
  56. package/sequence/InspectSequence.js +16 -10
  57. package/sequence/LazySequence.d.ts +34 -0
  58. package/sequence/LazySequence.js +77 -0
  59. package/sequence/Sequence.d.ts +45 -0
  60. package/sequence/Sequence.js +46 -0
  61. package/sequence/ThroughSequence.d.ts +13 -8
  62. package/sequence/ThroughSequence.js +20 -12
  63. package/sequence/index.d.ts +2 -3
  64. package/sequence/index.js +2 -3
  65. package/store/ArrayStore.d.ts +1 -1
  66. package/store/ArrayStore.js +2 -2
  67. package/store/BooleanStore.d.ts +2 -1
  68. package/store/BooleanStore.js +6 -2
  69. package/store/DictionaryStore.d.ts +1 -1
  70. package/store/DictionaryStore.js +2 -2
  71. package/store/FetchStore.d.ts +53 -0
  72. package/store/FetchStore.js +130 -0
  73. package/store/PathStore.d.ts +1 -1
  74. package/store/PathStore.js +2 -2
  75. package/store/PayloadFetchStore.d.ts +20 -0
  76. package/store/PayloadFetchStore.js +40 -0
  77. package/store/Store.d.ts +38 -10
  78. package/store/Store.js +65 -15
  79. package/store/URLStore.d.ts +1 -1
  80. package/store/URLStore.js +1 -1
  81. package/store/index.d.ts +2 -0
  82. package/store/index.js +2 -0
  83. package/test/util.js +0 -1
  84. package/util/async.d.ts +16 -8
  85. package/util/async.js +27 -8
  86. package/util/constants.d.ts +2 -2
  87. package/util/constants.js +2 -2
  88. package/util/dispose.d.ts +40 -10
  89. package/util/dispose.js +92 -33
  90. package/util/function.d.ts +8 -2
  91. package/util/function.js +0 -1
  92. package/util/index.d.ts +0 -1
  93. package/util/index.js +0 -1
  94. package/util/item.d.ts +6 -0
  95. package/util/sequence.d.ts +22 -8
  96. package/util/sequence.js +71 -36
  97. package/util/start.d.ts +2 -1
  98. package/util/start.js +23 -7
  99. package/util/timeout.d.ts +1 -1
  100. package/sequence/AbstractSequence.d.ts +0 -8
  101. package/sequence/AbstractSequence.js +0 -16
  102. package/sequence/IteratorSequence.d.ts +0 -9
  103. package/sequence/IteratorSequence.js +0 -13
  104. package/sequence/LazyDeferredSequence.d.ts +0 -10
  105. package/sequence/LazyDeferredSequence.js +0 -30
  106. package/util/callback.d.ts +0 -23
  107. package/util/callback.js +0 -28
@@ -5,8 +5,8 @@ import { EndpointCache } from "./EndpointCache.js";
5
5
  * Cache of `EndpointCache` objects for multiple endpoints.
6
6
  * - Use `get(endpoint)` to retrieve or create the `EndpointCache` for a given endpoint, then `get(payload)` on that to get a specific `EndpointStore`.
7
7
  */
8
- export declare class APICache<P, R> implements Disposable {
9
- private readonly _caches;
8
+ export declare class APICache<P, R> implements AsyncDisposable {
9
+ private readonly _endpoints;
10
10
  readonly provider: APIProvider<P, R>;
11
11
  constructor(provider: APIProvider<P, R>);
12
12
  private _get;
@@ -17,8 +17,8 @@ export declare class APICache<P, R> implements Disposable {
17
17
  /** Invalidate all stores for an endpoint. */
18
18
  invalidateAll<PP extends P, RR extends R>(endpoint: Endpoint<PP, RR>): void;
19
19
  /** Trigger a refetch on a specific store for an endpoint. */
20
- refetch<PP extends P, RR extends R>(endpoint: Endpoint<PP, RR>, payload: PP): void;
20
+ refresh<PP extends P, RR extends R>(endpoint: Endpoint<PP, RR>, payload: PP): void;
21
21
  /** Trigger a refetch on all stores for an endpoint. */
22
- refetchAll<PP extends P, RR extends R>(endpoint: Endpoint<PP, RR>): void;
23
- [Symbol.dispose](): void;
22
+ refreshAll<PP extends P, RR extends R>(endpoint: Endpoint<PP, RR>): void;
23
+ [Symbol.asyncDispose](): Promise<void>;
24
24
  }
@@ -1,3 +1,4 @@
1
+ import { awaitDispose } from "../../util/dispose.js";
1
2
  import { setMapItem } from "../../util/map.js";
2
3
  import { EndpointCache } from "./EndpointCache.js";
3
4
  /**
@@ -5,16 +6,16 @@ import { EndpointCache } from "./EndpointCache.js";
5
6
  * - Use `get(endpoint)` to retrieve or create the `EndpointCache` for a given endpoint, then `get(payload)` on that to get a specific `EndpointStore`.
6
7
  */
7
8
  export class APICache {
8
- _caches = new Map();
9
+ _endpoints = new Map();
9
10
  provider;
10
11
  constructor(provider) {
11
12
  this.provider = provider;
12
13
  }
13
14
  _get(endpoint) {
14
- return this._caches.get(endpoint);
15
+ return this._endpoints.get(endpoint);
15
16
  }
16
17
  get(endpoint) {
17
- return this._get(endpoint) || setMapItem(this._caches, endpoint, new EndpointCache(endpoint, this.provider));
18
+ return this._get(endpoint) || setMapItem(this._endpoints, endpoint, new EndpointCache(endpoint, this.provider));
18
19
  }
19
20
  /** Invalidate a specific store for an endpoint. */
20
21
  invalidate(endpoint, payload) {
@@ -25,17 +26,16 @@ export class APICache {
25
26
  this._get(endpoint)?.invalidateAll();
26
27
  }
27
28
  /** Trigger a refetch on a specific store for an endpoint. */
28
- refetch(endpoint, payload) {
29
- this._get(endpoint)?.refetch(payload);
29
+ refresh(endpoint, payload) {
30
+ this._get(endpoint)?.refresh(payload);
30
31
  }
31
32
  /** Trigger a refetch on all stores for an endpoint. */
32
- refetchAll(endpoint) {
33
- this._get(endpoint)?.refetchAll();
34
- }
35
- // Implement Disposable.
36
- [Symbol.dispose]() {
37
- for (const cache of this._caches.values())
38
- cache[Symbol.dispose]();
39
- this._caches.clear();
33
+ refreshAll(endpoint) {
34
+ this._get(endpoint)?.refreshAll();
35
+ }
36
+ // Implement `AsyncDisposable`
37
+ [Symbol.asyncDispose]() {
38
+ return awaitDispose(...this._endpoints.values(), // Dispose all endpoints.
39
+ () => this._endpoints.clear());
40
40
  }
41
41
  }
@@ -6,8 +6,8 @@ import { EndpointStore } from "../store/EndpointStore.js";
6
6
  * Cache of `EndpointStore` objects for a single endpoint, keyed by serialized payload.
7
7
  * - Use `get(payload)` to retrieve or create the `EndpointStore` for a given payload.
8
8
  */
9
- export declare class EndpointCache<P = unknown, R = unknown> implements Disposable {
10
- private readonly _stores;
9
+ export declare class EndpointCache<P = unknown, R = unknown> implements AsyncDisposable {
10
+ private readonly _endpoints;
11
11
  readonly endpoint: Endpoint<P, R>;
12
12
  readonly provider: APIProvider<P, R>;
13
13
  constructor(endpoint: Endpoint<P, R>, provider: APIProvider<P, R>);
@@ -18,8 +18,8 @@ export declare class EndpointCache<P = unknown, R = unknown> implements Disposab
18
18
  /** Invalidate all stores. */
19
19
  invalidateAll(): void;
20
20
  /** Trigger a refetch on a specific store. */
21
- refetch(payload: P, caller?: AnyCaller): void;
21
+ refresh(payload: P, caller?: AnyCaller): Promise<void>;
22
22
  /** Trigger a refetch on all stores. */
23
- refetchAll(): void;
24
- [Symbol.dispose](): void;
23
+ refreshAll(): Promise<void>;
24
+ [Symbol.asyncDispose](): Promise<void>;
25
25
  }
@@ -1,3 +1,5 @@
1
+ import { awaitValues } from "../../util/async.js";
2
+ import { awaitDispose } from "../../util/dispose.js";
1
3
  import { setMapItem } from "../../util/map.js";
2
4
  import { EndpointStore } from "../store/EndpointStore.js";
3
5
  /**
@@ -5,7 +7,7 @@ import { EndpointStore } from "../store/EndpointStore.js";
5
7
  * - Use `get(payload)` to retrieve or create the `EndpointStore` for a given payload.
6
8
  */
7
9
  export class EndpointCache {
8
- _stores = new Map();
10
+ _endpoints = new Map();
9
11
  endpoint;
10
12
  provider;
11
13
  constructor(endpoint, provider) {
@@ -15,7 +17,7 @@ export class EndpointCache {
15
17
  /** Get (or create) the `EndpointStore` for the given payload. */
16
18
  get(payload, caller = this.get) {
17
19
  const url = this.provider.renderURL(this.endpoint, payload, caller).href;
18
- return this._stores.get(url) || setMapItem(this._stores, url, new EndpointStore(this.endpoint, payload, this.provider));
20
+ return this._endpoints.get(url) || setMapItem(this._endpoints, url, new EndpointStore(this.endpoint, payload, this.provider));
19
21
  }
20
22
  /** Invalidate a specific store. */
21
23
  invalidate(payload, caller = this.invalidate) {
@@ -23,22 +25,20 @@ export class EndpointCache {
23
25
  }
24
26
  /** Invalidate all stores. */
25
27
  invalidateAll() {
26
- for (const store of this._stores.values())
28
+ for (const store of this._endpoints.values())
27
29
  store.invalidate();
28
30
  }
29
31
  /** Trigger a refetch on a specific store. */
30
- refetch(payload, caller = this.invalidate) {
31
- this.get(payload, caller)?.fetch();
32
+ async refresh(payload, caller = this.invalidate) {
33
+ await this.get(payload, caller)?.refresh();
32
34
  }
33
35
  /** Trigger a refetch on all stores. */
34
- refetchAll() {
35
- for (const store of this._stores.values())
36
- store.fetch();
36
+ async refreshAll() {
37
+ await awaitValues(...this._endpoints.values().map(store => store.refresh()));
37
38
  }
38
- // Implement Disposable.
39
- [Symbol.dispose]() {
40
- for (const store of this._stores.values())
41
- store[Symbol.dispose]();
42
- this._stores.clear();
39
+ // Implement `AsyncDisposable`
40
+ [Symbol.asyncDispose]() {
41
+ return awaitDispose(...this._endpoints.values(), // Dispose all endpoints.
42
+ () => this._endpoints.clear());
43
43
  }
44
44
  }
@@ -1,42 +1,10 @@
1
- import { Store } from "../../store/Store.js";
2
- import { NONE } from "../../util/constants.js";
1
+ import { PayloadFetchStore } from "../../store/PayloadFetchStore.js";
3
2
  import type { Endpoint } from "../endpoint/Endpoint.js";
4
3
  import type { APIProvider } from "../provider/APIProvider.js";
5
- /**
6
- * Store object that loads a result from an API endpoint and manages its state.
7
- */
8
- export declare class EndpointStore<P, R> extends Store<R> implements Disposable {
4
+ /** Store object that loads a result from an API endpoint and provider. */
5
+ export declare class EndpointStore<P, R> extends PayloadFetchStore<P, R> {
9
6
  readonly provider: APIProvider<P, R>;
10
7
  readonly endpoint: Endpoint<P, R>;
11
- private _payload;
12
- /**
13
- * The current payload set for this endpoint.
14
- * - Value will only change if the new payload is not deeply equal to the current one.
15
- * - If a new payload is set, it will abort any current in-flight request
16
- */
17
- get payload(): P;
18
- set payload(next: P);
19
- get loading(): boolean;
20
- get value(): R;
21
- set value(value: R | typeof NONE);
22
8
  constructor(endpoint: Endpoint<P, R>, payload: P, provider: APIProvider<P, R>);
23
- /** Store the inflight fetch request. */
24
- private _inflight;
25
- /**
26
- * Invalidate this endpoint, so that calls to `this.value` trigger a new fetch immediately.
27
- */
28
- invalidate(): void;
29
- /**
30
- * Fetch the result for this endpoint now.
31
- * - Triggered automatically when someone reads `value` or `loading`
32
- */
33
- fetch(): Promise<void>;
34
- /** Fetch the result if the current value is older than `maxAge` milliseconds. */
35
- refreshStale(maxAge: number): void;
36
- /** Abort any in-flight request now. */
37
- private abort;
38
- private _fetch;
39
- [Symbol.dispose](): void;
9
+ protected _fetch(): Promise<R>;
40
10
  }
41
- /** Any endpoint store. */
42
- export type AnyEndpointStore = EndpointStore<any, any>;
@@ -1,117 +1,16 @@
1
- import { Store } from "../../store/Store.js";
1
+ import { PayloadFetchStore } from "../../store/PayloadFetchStore.js";
2
2
  import { NONE } from "../../util/constants.js";
3
- import { isDeepEqual } from "../../util/equal.js";
4
- const _CANCELLED = Symbol("EndpointStore/CANCELLED");
5
- const _TIMEOUT = Symbol("EndpointStore/TIMEOUT");
6
- /**
7
- * Store object that loads a result from an API endpoint and manages its state.
8
- */
9
- export class EndpointStore extends Store {
3
+ /** Store object that loads a result from an API endpoint and provider. */
4
+ export class EndpointStore extends PayloadFetchStore {
10
5
  provider;
11
6
  endpoint;
12
- _payload;
13
- /**
14
- * The current payload set for this endpoint.
15
- * - Value will only change if the new payload is not deeply equal to the current one.
16
- * - If a new payload is set, it will abort any current in-flight request
17
- */
18
- get payload() {
19
- return this._payload;
20
- }
21
- set payload(next) {
22
- const current = this._payload;
23
- // Did the payload actually change?
24
- if (!isDeepEqual(current, next)) {
25
- this._payload = next;
26
- this.abort(); // Abort any in-flight requst now (as it would've been sent with the previous payload).
27
- this.fetch();
28
- }
29
- }
30
- // Override to possibly trigger a fetch when `this.loading` is read.
31
- // This is because when we check `store.loading` in a component we are signalling intent that we wish to use that value.
32
- get loading() {
33
- const loading = super.loading;
34
- if (loading)
35
- this.fetch();
36
- return loading;
37
- }
38
- // Override to possibly trigger a fetch when `this.value` is first read.
39
- // This is because when we check `store.loading` in a component we are signalling intent that we wish to use that value.
40
- get value() {
41
- if (super.loading)
42
- this.fetch();
43
- return super.value;
44
- }
45
- set value(value) {
46
- super.value = value;
47
- }
48
7
  constructor(endpoint, payload, provider) {
49
- super(NONE);
8
+ super(payload, NONE);
50
9
  this.endpoint = endpoint;
51
10
  this.provider = provider;
52
- this.payload = payload;
53
- }
54
- /** Store the inflight fetch request. */
55
- _inflight = undefined;
56
- /**
57
- * Invalidate this endpoint, so that calls to `this.value` trigger a new fetch immediately.
58
- */
59
- invalidate() {
60
- this.abort();
61
- // @todo Implement this by setting the _age_ to `undefined` instead, so that the current value continues to exist but is so old that it triggers a refetch.
62
- // That means we need to have an age system built into this somehow, we can't just implement it in `useAPI()`
63
- // Don't know if I like that.....
64
- this.value = NONE;
65
- }
66
- /**
67
- * Fetch the result for this endpoint now.
68
- * - Triggered automatically when someone reads `value` or `loading`
69
- */
70
- fetch() {
71
- // Re-use existing fetch if it exists.
72
- if (this._inflight)
73
- return this._inflight.promise;
74
- // Create a new fetch.
75
- const abort = new AbortController();
76
- const promise = this._fetch(abort);
77
- this._inflight = { abort, promise };
78
- return promise;
79
- }
80
- /** Fetch the result if the current value is older than `maxAge` milliseconds. */
81
- refreshStale(maxAge) {
82
- if (this.age > maxAge)
83
- void this.fetch();
84
- }
85
- /** Abort any in-flight request now. */
86
- abort() {
87
- if (this._inflight) {
88
- const { abort } = this._inflight;
89
- this._inflight = undefined;
90
- abort.abort(_CANCELLED);
91
- }
92
- }
93
- /** Fetch the result from the API endpoint now. */
94
- async _fetch(abort) {
95
- try {
96
- const value = await this.provider.call(this.endpoint, this._payload, { signal: abort.signal });
97
- this.reason = undefined;
98
- this.value = value;
99
- }
100
- catch (thrown) {
101
- console.error(thrown);
102
- if (thrown === _CANCELLED)
103
- return; // Cancelled on purpose.
104
- else if (thrown === _TIMEOUT)
105
- this.reason = "Timed out"; // Request timed out.
106
- else
107
- this.reason = thrown;
108
- }
109
- finally {
110
- this._inflight = undefined;
111
- }
112
11
  }
113
- // Implement Disposable.
114
- [Symbol.dispose]() {
115
- this.abort();
12
+ // Override to fetch the value using the provider and endpoint.
13
+ _fetch() {
14
+ return this.provider.call(this.endpoint, this.payload.value, { signal: this.signal });
116
15
  }
117
16
  }
@@ -1,7 +1,7 @@
1
1
  import type { Collection } from "../db/collection/Collection.js";
2
2
  import { DBProvider } from "../db/provider/DBProvider.js";
3
3
  import type { Data } from "../util/data.js";
4
- import { type Item, type Items, type OptionalItem } from "../util/item.js";
4
+ import { type Item, type Items, type ItemsSequence, type OptionalItem, type OptionalItemSequence } from "../util/item.js";
5
5
  import type { Query } from "../util/query.js";
6
6
  import type { Updates } from "../util/update.js";
7
7
  import type { KVNamespace } from "./types.js";
@@ -31,13 +31,13 @@ export declare class CloudflareKVProvider<I extends string = string, T extends D
31
31
  private readonly _kv;
32
32
  constructor(kv: KVNamespace);
33
33
  getItem<II extends I, TT extends T>({ name }: Collection<string, II, TT>, id: II): Promise<OptionalItem<II, TT>>;
34
- getItemSequence<II extends I, TT extends T>(_collection: Collection<string, II, TT>, _id: II): AsyncIterable<OptionalItem<II, TT>>;
34
+ getItemSequence<II extends I, TT extends T>(_collection: Collection<string, II, TT>, _id: II): OptionalItemSequence<II, TT>;
35
35
  addItem<II extends I, TT extends T>({ name }: Collection<string, II, TT>, data: TT): Promise<II>;
36
36
  setItem<II extends I, TT extends T>({ name }: Collection<string, II, TT>, id: II, data: TT): Promise<void>;
37
37
  updateItem<II extends I, TT extends T>(_collection: Collection<string, II, TT>, _id: II, _updates: Updates<Item<II, TT>>): Promise<void>;
38
38
  deleteItem<II extends I, TT extends T>({ name }: Collection<string, II, TT>, id: II): Promise<void>;
39
39
  getQuery<II extends I, TT extends T>(_collection: Collection<string, II, TT>, _query?: Query<Item<II, TT>>): Promise<Items<II, TT>>;
40
- getQuerySequence<II extends I, TT extends T>(_collection: Collection<string, II, TT>, _query?: Query<Item<II, TT>>): AsyncIterable<Items<II, TT>>;
40
+ getQuerySequence<II extends I, TT extends T>(_collection: Collection<string, II, TT>, _query?: Query<Item<II, TT>>): ItemsSequence<II, TT>;
41
41
  setQuery<II extends I, TT extends T>(_collection: Collection<string, II, TT>, _query: Query<Item<II, TT>>, _data: TT): Promise<void>;
42
42
  updateQuery<II extends I, TT extends T>(_collection: Collection<string, II, TT>, _query: Query<Item<II, TT>>, _updates: Updates<TT>): Promise<void>;
43
43
  deleteQuery<II extends I, TT extends T>(_collection: Collection<string, II, TT>, _query: Query<Item<II, TT>>): Promise<void>;
@@ -11,7 +11,7 @@ import { QueryStore } from "../store/QueryStore.js";
11
11
  * - Use `getItem(id)` to retrieve or create the `ItemStore` for a given id.
12
12
  * - Use `getQuery(query)` to retrieve or create the `QueryStore` for a given query.
13
13
  */
14
- export declare class CollectionCache<I extends Identifier, T extends Data> implements Disposable {
14
+ export declare class CollectionCache<I extends Identifier, T extends Data> implements AsyncDisposable {
15
15
  private readonly _items;
16
16
  private readonly _queries;
17
17
  readonly collection: Collection<string, I, T>;
@@ -23,15 +23,15 @@ export declare class CollectionCache<I extends Identifier, T extends Data> imple
23
23
  /** Get (or create) the `QueryStore` for the given query. */
24
24
  getQuery(query: Query<Item<I, T>>): QueryStore<I, T>;
25
25
  /** Refresh a specific item store. */
26
- refreshItem(id: I): void;
26
+ refreshItem(id: I): Promise<void>;
27
27
  /** Refresh every cached item store. */
28
- refreshItems(): void;
28
+ refreshItems(): Promise<void>;
29
29
  /** Refresh a specific query store. */
30
- refreshQuery(query: Query<Item<I, T>>): void;
30
+ refreshQuery(query: Query<Item<I, T>>): Promise<void>;
31
31
  /** Refresh every cached query store. */
32
- refreshQueries(): void;
32
+ refreshQueries(): Promise<void>;
33
33
  /** Refresh every cached store (items and queries). */
34
- refreshAll(): void;
34
+ refreshAll(): Promise<void>;
35
35
  private _queryKey;
36
- [Symbol.dispose](): void;
36
+ [Symbol.asyncDispose](): Promise<void>;
37
37
  }
@@ -1,3 +1,5 @@
1
+ import { awaitValues } from "../../util/async.js";
2
+ import { awaitDispose } from "../../util/dispose.js";
1
3
  import { setMapItem } from "../../util/map.js";
2
4
  import { ItemStore } from "../store/ItemStore.js";
3
5
  import { QueryStore } from "../store/QueryStore.js";
@@ -19,8 +21,7 @@ export class CollectionCache {
19
21
  }
20
22
  /** Get (or create) the `ItemStore` for the given id. */
21
23
  getItem(id) {
22
- const key = String(id);
23
- return this._items.get(key) || setMapItem(this._items, key, new ItemStore(this.collection, id, this.provider, this.memory));
24
+ return this._items.get(id) || setMapItem(this._items, id, new ItemStore(this.collection, id, this.provider, this.memory));
24
25
  }
25
26
  /** Get (or create) the `QueryStore` for the given query. */
26
27
  getQuery(query) {
@@ -28,35 +29,33 @@ export class CollectionCache {
28
29
  return this._queries.get(key) || setMapItem(this._queries, key, new QueryStore(this.collection, query, this.provider, this.memory));
29
30
  }
30
31
  /** Refresh a specific item store. */
31
- refreshItem(id) {
32
- this._items.get(String(id))?.refresh();
32
+ async refreshItem(id) {
33
+ await this._items.get(id)?.refresh();
33
34
  }
34
35
  /** Refresh every cached item store. */
35
- refreshItems() {
36
- for (const store of this._items.values())
37
- store.refresh();
36
+ async refreshItems() {
37
+ await awaitValues(...this._items.values().map(store => store.refresh()));
38
38
  }
39
39
  /** Refresh a specific query store. */
40
- refreshQuery(query) {
41
- this._queries.get(this._queryKey(query))?.refresh();
40
+ async refreshQuery(query) {
41
+ await this._queries.get(this._queryKey(query))?.refresh();
42
42
  }
43
43
  /** Refresh every cached query store. */
44
- refreshQueries() {
45
- for (const store of this._queries.values())
46
- store.refresh();
44
+ async refreshQueries() {
45
+ await awaitValues(...this._queries.values().map(store => store.refresh()));
47
46
  }
48
47
  /** Refresh every cached store (items and queries). */
49
- refreshAll() {
50
- this.refreshItems();
51
- this.refreshQueries();
48
+ async refreshAll() {
49
+ await awaitValues(this.refreshItems(), this.refreshQueries());
52
50
  }
53
51
  _queryKey(query) {
54
52
  return JSON.stringify(query);
55
53
  }
56
- // Implement Disposable.
57
- [Symbol.dispose]() {
58
- // Note: `ItemStore`/`QueryStore` are not themselves `Disposable`, so we only drop references.
59
- this._items.clear();
60
- this._queries.clear();
54
+ // Implement `AsyncDisposable`
55
+ [Symbol.asyncDispose]() {
56
+ return awaitDispose(...this._items.values(), // Dispose all items.
57
+ ...this._queries.values(), // Dispose all queries.
58
+ () => this._items.clear(), // Clear the items.
59
+ () => this._queries.clear());
61
60
  }
62
61
  }
@@ -12,8 +12,8 @@ import { CollectionCache } from "./CollectionCache.js";
12
12
  * - Use `get(collection)` to retrieve or create the `CollectionCache` for a given collection,
13
13
  * then `getItem(id)` / `getQuery(query)` on that to get a specific store.
14
14
  */
15
- export declare class DBCache<I extends Identifier = Identifier, T extends Data = Data> implements Disposable {
16
- private readonly _caches;
15
+ export declare class DBCache<I extends Identifier = Identifier, T extends Data = Data> implements AsyncDisposable {
16
+ private readonly _collections;
17
17
  readonly provider: DBProvider<I, T>;
18
18
  readonly memory: MemoryDBProvider<I, T> | undefined;
19
19
  constructor(provider: DBProvider<I, T>);
@@ -25,14 +25,14 @@ export declare class DBCache<I extends Identifier = Identifier, T extends Data =
25
25
  /** Get (or create) a `QueryStore` for a collection/query in one hop. */
26
26
  getQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>): QueryStore<II, TT>;
27
27
  /** Refresh a specific item store for a collection. */
28
- refreshItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): void;
28
+ refreshItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): Promise<void>;
29
29
  /** Refresh every cached item store for a collection. */
30
- refreshItems<II extends I, TT extends T>(collection: Collection<string, II, TT>): void;
30
+ refreshItems<II extends I, TT extends T>(collection: Collection<string, II, TT>): Promise<void>;
31
31
  /** Refresh a specific query store for a collection. */
32
- refreshQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>): void;
32
+ refreshQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>): Promise<void>;
33
33
  /** Refresh every cached query store for a collection. */
34
- refreshQueries<II extends I, TT extends T>(collection: Collection<string, II, TT>): void;
34
+ refreshQueries<II extends I, TT extends T>(collection: Collection<string, II, TT>): Promise<void>;
35
35
  /** Refresh every cached store (items and queries) for a collection. */
36
- refreshAll<II extends I, TT extends T>(collection: Collection<string, II, TT>): void;
37
- [Symbol.dispose](): void;
36
+ refreshAll<II extends I, TT extends T>(collection: Collection<string, II, TT>): Promise<void>;
37
+ [Symbol.asyncDispose](): Promise<void>;
38
38
  }
@@ -1,3 +1,4 @@
1
+ import { awaitDispose } from "../../util/dispose.js";
1
2
  import { setMapItem } from "../../util/map.js";
2
3
  import { getSource } from "../../util/source.js";
3
4
  import { CacheDBProvider } from "../provider/CacheDBProvider.js";
@@ -8,7 +9,7 @@ import { CollectionCache } from "./CollectionCache.js";
8
9
  * then `getItem(id)` / `getQuery(query)` on that to get a specific store.
9
10
  */
10
11
  export class DBCache {
11
- _caches = new Map();
12
+ _collections = new Map();
12
13
  provider;
13
14
  memory;
14
15
  constructor(provider) {
@@ -17,10 +18,10 @@ export class DBCache {
17
18
  this.memory = getSource(CacheDBProvider, provider)?.memory;
18
19
  }
19
20
  _get(collection) {
20
- return this._caches.get(collection);
21
+ return this._collections.get(collection);
21
22
  }
22
23
  get(collection) {
23
- return this._get(collection) || setMapItem(this._caches, collection, new CollectionCache(collection, this.provider, this.memory));
24
+ return this._get(collection) || setMapItem(this._collections, collection, new CollectionCache(collection, this.provider, this.memory));
24
25
  }
25
26
  /** Get (or create) an `ItemStore` for a collection/id in one hop. */
26
27
  getItem(collection, id) {
@@ -31,29 +32,28 @@ export class DBCache {
31
32
  return this.get(collection).getQuery(query);
32
33
  }
33
34
  /** Refresh a specific item store for a collection. */
34
- refreshItem(collection, id) {
35
- this._get(collection)?.refreshItem(id);
35
+ async refreshItem(collection, id) {
36
+ await this._get(collection)?.refreshItem(id);
36
37
  }
37
38
  /** Refresh every cached item store for a collection. */
38
- refreshItems(collection) {
39
- this._get(collection)?.refreshItems();
39
+ async refreshItems(collection) {
40
+ await this._get(collection)?.refreshItems();
40
41
  }
41
42
  /** Refresh a specific query store for a collection. */
42
- refreshQuery(collection, query) {
43
- this._get(collection)?.refreshQuery(query);
43
+ async refreshQuery(collection, query) {
44
+ await this._get(collection)?.refreshQuery(query);
44
45
  }
45
46
  /** Refresh every cached query store for a collection. */
46
- refreshQueries(collection) {
47
- this._get(collection)?.refreshQueries();
47
+ async refreshQueries(collection) {
48
+ await this._get(collection)?.refreshQueries();
48
49
  }
49
50
  /** Refresh every cached store (items and queries) for a collection. */
50
- refreshAll(collection) {
51
- this._get(collection)?.refreshAll();
52
- }
53
- // Implement Disposable.
54
- [Symbol.dispose]() {
55
- for (const cache of this._caches.values())
56
- cache[Symbol.dispose]();
57
- this._caches.clear();
51
+ async refreshAll(collection) {
52
+ await this._get(collection)?.refreshAll();
53
+ }
54
+ // Implement `AsyncDisposable`
55
+ async [Symbol.asyncDispose]() {
56
+ return awaitDispose(...this._collections.values(), // Dispose all collections.
57
+ () => this._collections.clear());
58
58
  }
59
59
  }
@@ -1,5 +1,5 @@
1
1
  import type { Data } from "../../util/data.js";
2
- import type { Identifier, Item, Items, OptionalItem } from "../../util/item.js";
2
+ import type { Identifier, Item, Items, ItemsSequence, OptionalItem, OptionalItemSequence } from "../../util/item.js";
3
3
  import type { Query } from "../../util/query.js";
4
4
  import type { Sourceable } from "../../util/source.js";
5
5
  import type { Updates } from "../../util/update.js";
@@ -12,14 +12,14 @@ export declare class CacheDBProvider<I extends Identifier, T extends Data> exten
12
12
  readonly memory: MemoryDBProvider<I, T>;
13
13
  constructor(source: DBProvider<I, T>, cache?: MemoryDBProvider<I, T>);
14
14
  getItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): Promise<OptionalItem<II, TT>>;
15
- getItemSequence<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): AsyncIterable<OptionalItem<II, TT>>;
15
+ getItemSequence<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): OptionalItemSequence<II, TT>;
16
16
  addItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, data: TT): Promise<II>;
17
17
  setItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II, data: TT): Promise<void>;
18
18
  updateItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II, updates: Updates<Item<II, TT>>): Promise<void>;
19
19
  deleteItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): Promise<void>;
20
20
  countQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query?: Query<Item<II, TT>>): Promise<number>;
21
21
  getQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query?: Query<Item<II, TT>>): Promise<Items<II, TT>>;
22
- getQuerySequence<II extends I, TT extends T>(collection: Collection<string, II, TT>, query?: Query<Item<II, TT>>): AsyncIterable<Items<II, TT>>;
22
+ getQuerySequence<II extends I, TT extends T>(collection: Collection<string, II, TT>, query?: Query<Item<II, TT>>): ItemsSequence<II, TT>;
23
23
  setQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>, data: TT): Promise<void>;
24
24
  updateQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>, updates: Updates<TT>): Promise<void>;
25
25
  deleteQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>): Promise<void>;
@@ -1,5 +1,5 @@
1
1
  import type { Data } from "../../util/data.js";
2
- import type { Identifier, Item, Items, OptionalItem } from "../../util/item.js";
2
+ import type { Identifier, Item, Items, ItemsSequence, OptionalItem, OptionalItemSequence } from "../../util/item.js";
3
3
  import type { Query } from "../../util/query.js";
4
4
  import type { Updates } from "../../util/update.js";
5
5
  import type { Collection } from "../collection/Collection.js";
@@ -7,14 +7,14 @@ import type { Collection } from "../collection/Collection.js";
7
7
  export declare abstract class DBProvider<I extends Identifier = Identifier, T extends Data = Data> {
8
8
  abstract getItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): Promise<OptionalItem<II, TT>>;
9
9
  requireItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): Promise<Item<II, TT>>;
10
- abstract getItemSequence<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): AsyncIterable<OptionalItem<II, TT>>;
10
+ abstract getItemSequence<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): OptionalItemSequence<II, TT>;
11
11
  abstract addItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, data: TT): Promise<II>;
12
12
  abstract setItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II, data: TT): Promise<void>;
13
13
  abstract updateItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II, updates: Updates<Item<II, TT>>): Promise<void>;
14
14
  abstract deleteItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): Promise<void>;
15
15
  countQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query?: Query<Item<II, TT>>): Promise<number>;
16
16
  abstract getQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query?: Query<Item<II, TT>>): Promise<Items<II, TT>>;
17
- abstract getQuerySequence<II extends I, TT extends T>(collection: Collection<string, II, TT>, query?: Query<Item<II, TT>>): AsyncIterable<Items<II, TT>>;
17
+ abstract getQuerySequence<II extends I, TT extends T>(collection: Collection<string, II, TT>, query?: Query<Item<II, TT>>): ItemsSequence<II, TT>;
18
18
  abstract setQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>, data: TT): Promise<void>;
19
19
  abstract updateQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>, updates: Updates<TT>): Promise<void>;
20
20
  abstract deleteQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>): Promise<void>;
@@ -1,5 +1,5 @@
1
1
  import type { Data } from "../../util/data.js";
2
- import type { Identifier, Item, Items, OptionalItem } from "../../util/item.js";
2
+ import type { Identifier, Item, Items, ItemsSequence, OptionalItem, OptionalItemSequence } from "../../util/item.js";
3
3
  import type { Query } from "../../util/query.js";
4
4
  import type { Updates } from "../../util/update.js";
5
5
  import type { Collection } from "../collection/Collection.js";
@@ -7,14 +7,14 @@ import { ThroughDBProvider } from "./ThroughDBProvider.js";
7
7
  /** Provider that logs operations to the console. */
8
8
  export declare class DebugDBProvider<I extends Identifier, T extends Data> extends ThroughDBProvider<I, T> {
9
9
  getItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): Promise<OptionalItem<II, TT>>;
10
- getItemSequence<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): AsyncIterableIterator<OptionalItem<II, TT>>;
10
+ getItemSequence<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): OptionalItemSequence<II, TT>;
11
11
  addItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, data: TT): Promise<II>;
12
12
  setItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II, data: TT): Promise<void>;
13
13
  updateItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II, updates: Updates<Item<II, TT>>): Promise<void>;
14
14
  deleteItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): Promise<void>;
15
15
  countQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query?: Query<Item<II, TT>>): Promise<number>;
16
16
  getQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query?: Query<Item<II, TT>>): Promise<Items<II, TT>>;
17
- getQuerySequence<II extends I, TT extends T>(collection: Collection<string, II, TT>, query?: Query<Item<II, TT>>): AsyncIterableIterator<Items<II, TT>>;
17
+ getQuerySequence<II extends I, TT extends T>(collection: Collection<string, II, TT>, query?: Query<Item<II, TT>>): ItemsSequence<II, TT>;
18
18
  setQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>, data: TT): Promise<void>;
19
19
  updateQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>, updates: Updates<TT>): Promise<void>;
20
20
  deleteQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>): Promise<void>;