shelving 1.181.2 → 1.182.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 (67) hide show
  1. package/api/cache/APICache.d.ts +1 -0
  2. package/api/cache/APICache.js +8 -6
  3. package/api/cache/EndpointCache.d.ts +5 -6
  4. package/api/cache/EndpointCache.js +7 -13
  5. package/api/endpoint/Endpoint.d.ts +1 -1
  6. package/api/index.d.ts +0 -1
  7. package/api/index.js +0 -1
  8. package/api/provider/APIProvider.d.ts +39 -4
  9. package/api/provider/APIProvider.js +76 -0
  10. package/api/provider/MockAPIProvider.d.ts +5 -5
  11. package/api/provider/MockAPIProvider.js +2 -2
  12. package/api/provider/ThroughAPIProvider.d.ts +6 -0
  13. package/api/provider/ThroughAPIProvider.js +15 -0
  14. package/bun/BunPostgreSQLProvider.d.ts +3 -2
  15. package/cloudflare/CloudflareD1Provider.d.ts +3 -2
  16. package/cloudflare/CloudflareKVProvider.d.ts +16 -18
  17. package/cloudflare/CloudflareKVProvider.js +11 -13
  18. package/db/cache/CollectionCache.d.ts +37 -0
  19. package/db/cache/CollectionCache.js +62 -0
  20. package/db/cache/DBCache.d.ts +38 -0
  21. package/db/cache/DBCache.js +59 -0
  22. package/db/collection/Collection.d.ts +12 -10
  23. package/db/index.d.ts +2 -0
  24. package/db/index.js +2 -0
  25. package/db/provider/CacheDBProvider.d.ts +18 -18
  26. package/db/provider/ChangesDBProvider.d.ts +11 -11
  27. package/db/provider/DBProvider.d.ts +17 -17
  28. package/db/provider/DBProvider.js +2 -2
  29. package/db/provider/DebugDBProvider.d.ts +15 -15
  30. package/db/provider/MemoryDBProvider.d.ts +28 -26
  31. package/db/provider/MemoryDBProvider.js +10 -5
  32. package/db/provider/MockDBProvider.d.ts +17 -17
  33. package/db/provider/PostgreSQLProvider.d.ts +4 -2
  34. package/db/provider/PostgreSQLProvider.js +1 -1
  35. package/db/provider/SQLProvider.d.ts +23 -23
  36. package/db/provider/SQLProvider.js +24 -23
  37. package/db/provider/SQLiteProvider.d.ts +6 -2
  38. package/db/provider/SQLiteProvider.js +14 -1
  39. package/db/provider/ThroughDBProvider.d.ts +19 -19
  40. package/db/provider/ValidationDBProvider.d.ts +14 -14
  41. package/db/provider/ValidationDBProvider.js +4 -8
  42. package/db/store/QueryStore.d.ts +3 -3
  43. package/firestore/client/FirestoreClientProvider.d.ts +21 -15
  44. package/firestore/client/FirestoreClientProvider.js +40 -37
  45. package/firestore/lite/FirestoreLiteProvider.d.ts +21 -15
  46. package/firestore/lite/FirestoreLiteProvider.js +38 -29
  47. package/firestore/server/FirestoreServerProvider.d.ts +21 -15
  48. package/firestore/server/FirestoreServerProvider.js +67 -71
  49. package/package.json +1 -1
  50. package/react/createAPIContext.d.ts +4 -2
  51. package/react/createAPIContext.js +22 -15
  52. package/react/createDBContext.d.ts +31 -0
  53. package/react/createDBContext.js +35 -0
  54. package/react/index.d.ts +1 -2
  55. package/react/index.js +1 -2
  56. package/util/http.d.ts +3 -2
  57. package/util/http.js +6 -6
  58. package/util/item.d.ts +4 -4
  59. package/util/query.d.ts +1 -4
  60. package/util/uri.d.ts +9 -4
  61. package/util/uri.js +4 -0
  62. package/api/provider/ClientAPIProvider.d.ts +0 -37
  63. package/api/provider/ClientAPIProvider.js +0 -51
  64. package/react/createCacheContext.d.ts +0 -13
  65. package/react/createCacheContext.js +0 -22
  66. package/react/createDataContext.d.ts +0 -26
  67. package/react/createDataContext.js +0 -31
@@ -0,0 +1,38 @@
1
+ import type { Data } from "../../util/data.js";
2
+ import type { Identifier, Item } from "../../util/item.js";
3
+ import type { Query } from "../../util/query.js";
4
+ import type { Collection } from "../collection/Collection.js";
5
+ import type { DBProvider } from "../provider/DBProvider.js";
6
+ import type { MemoryDBProvider } from "../provider/MemoryDBProvider.js";
7
+ import type { ItemStore } from "../store/ItemStore.js";
8
+ import type { QueryStore } from "../store/QueryStore.js";
9
+ import { CollectionCache } from "./CollectionCache.js";
10
+ /**
11
+ * Cache of `CollectionCache` objects for multiple collections.
12
+ * - Use `get(collection)` to retrieve or create the `CollectionCache` for a given collection,
13
+ * then `getItem(id)` / `getQuery(query)` on that to get a specific store.
14
+ */
15
+ export declare class DBCache<I extends Identifier = Identifier, T extends Data = Data> implements Disposable {
16
+ private readonly _caches;
17
+ readonly provider: DBProvider<I, T>;
18
+ readonly memory: MemoryDBProvider<I, T> | undefined;
19
+ constructor(provider: DBProvider<I, T>);
20
+ private _get;
21
+ /** Get (or create) the `CollectionCache` for the given collection. */
22
+ get<II extends I, TT extends T>(collection: Collection<string, II, TT>): CollectionCache<II, TT>;
23
+ /** Get (or create) an `ItemStore` for a collection/id in one hop. */
24
+ getItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): ItemStore<II, TT>;
25
+ /** Get (or create) a `QueryStore` for a collection/query in one hop. */
26
+ getQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>): QueryStore<II, TT>;
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;
29
+ /** Refresh every cached item store for a collection. */
30
+ refreshItems<II extends I, TT extends T>(collection: Collection<string, II, TT>): void;
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;
33
+ /** Refresh every cached query store for a collection. */
34
+ refreshQueries<II extends I, TT extends T>(collection: Collection<string, II, TT>): void;
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;
38
+ }
@@ -0,0 +1,59 @@
1
+ import { setMapItem } from "../../util/map.js";
2
+ import { getSource } from "../../util/source.js";
3
+ import { CacheDBProvider } from "../provider/CacheDBProvider.js";
4
+ import { CollectionCache } from "./CollectionCache.js";
5
+ /**
6
+ * Cache of `CollectionCache` objects for multiple collections.
7
+ * - Use `get(collection)` to retrieve or create the `CollectionCache` for a given collection,
8
+ * then `getItem(id)` / `getQuery(query)` on that to get a specific store.
9
+ */
10
+ export class DBCache {
11
+ _caches = new Map();
12
+ provider;
13
+ memory;
14
+ constructor(provider) {
15
+ this.provider = provider;
16
+ // If the provider chain contains a `CacheDBProvider`, reuse its memory so we can seed stores synchronously.
17
+ this.memory = getSource(CacheDBProvider, provider)?.memory;
18
+ }
19
+ _get(collection) {
20
+ return this._caches.get(collection);
21
+ }
22
+ get(collection) {
23
+ return this._get(collection) || setMapItem(this._caches, collection, new CollectionCache(collection, this.provider, this.memory));
24
+ }
25
+ /** Get (or create) an `ItemStore` for a collection/id in one hop. */
26
+ getItem(collection, id) {
27
+ return this.get(collection).getItem(id);
28
+ }
29
+ /** Get (or create) a `QueryStore` for a collection/query in one hop. */
30
+ getQuery(collection, query) {
31
+ return this.get(collection).getQuery(query);
32
+ }
33
+ /** Refresh a specific item store for a collection. */
34
+ refreshItem(collection, id) {
35
+ this._get(collection)?.refreshItem(id);
36
+ }
37
+ /** Refresh every cached item store for a collection. */
38
+ refreshItems(collection) {
39
+ this._get(collection)?.refreshItems();
40
+ }
41
+ /** Refresh a specific query store for a collection. */
42
+ refreshQuery(collection, query) {
43
+ this._get(collection)?.refreshQuery(query);
44
+ }
45
+ /** Refresh every cached query store for a collection. */
46
+ refreshQueries(collection) {
47
+ this._get(collection)?.refreshQueries();
48
+ }
49
+ /** 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();
58
+ }
59
+ }
@@ -3,11 +3,11 @@ import { NumberSchema } from "../../schema/NumberSchema.js";
3
3
  import type { Schema, Schemas } from "../../schema/Schema.js";
4
4
  import type { ImmutableArray } from "../../util/array.js";
5
5
  import type { Data } from "../../util/data.js";
6
- import type { Identifier, Item } from "../../util/item.js";
6
+ import type { Identifier, Item, Items, OptionalItem } from "../../util/item.js";
7
7
  /** Default identifier schema (integer). */
8
8
  export declare const ID: NumberSchema;
9
9
  /** Declarative definition of a database collection/table. */
10
- export declare class Collection<N extends string, I extends Identifier, T extends Data> extends DataSchema<T> {
10
+ export declare class Collection<N extends string = string, I extends Identifier = Identifier, T extends Data = Data> extends DataSchema<T> {
11
11
  /** Collection name (used as the table/collection key). */
12
12
  readonly name: N;
13
13
  /** Schema for the identifier type. */
@@ -18,18 +18,20 @@ export declare class Collection<N extends string, I extends Identifier, T extend
18
18
  }
19
19
  /** Shortcut factory for creating a Collection. */
20
20
  export declare function COLLECTION<K extends string, I extends Identifier, T extends Data>(name: K, id: Schema<I>, data: Schemas<T> | DataSchema<T>): Collection<K, I, T>;
21
- /** Any collection object, possibly with a standardised `Identifier` type. */
22
- export type AnyCollection<I extends Identifier = Identifier> = Collection<string, I, Data>;
23
21
  /** Extract the string name from a `Collection` instance. */
24
- export type CollectionName<C extends AnyCollection> = C extends Collection<infer N, infer _I, infer _T> ? N : never;
22
+ export type CollectionName<C extends Collection> = C extends Collection<infer N, infer _I, infer _T> ? N : never;
25
23
  /** Extract the `Identifier` type from a `Collection` instance. */
26
- export type CollectionIdentifier<C extends AnyCollection> = C extends Collection<infer _N, infer I, infer _T> ? I : never;
24
+ export type CollectionIdentifier<C extends Collection> = C extends Collection<infer _N, infer I, infer _T> ? I : never;
27
25
  /** Extract the `Data` type from a `Collection` instance. */
28
- export type CollectionData<C extends AnyCollection> = C extends Collection<infer _N, infer _I, infer T> ? T : never;
26
+ export type CollectionData<C extends Collection> = C extends Collection<infer _N, infer _I, infer T> ? T : never;
29
27
  /** Extract the `Item` type from a `Collection` instance. */
30
- export type CollectionItem<C extends AnyCollection> = C extends Collection<infer _N, infer I, infer T> ? Item<I, T> : never;
31
- /** A readonly array of Collection instances, possibly with a standardised `Identifier` type. */
32
- export type Collections<I extends Identifier = Identifier> = ImmutableArray<AnyCollection<I>>;
28
+ export type CollectionItem<C extends Collection> = Item<CollectionIdentifier<C>, CollectionData<C>>;
29
+ /** Extract the optional (possibly undefined) `Item` type from a `Collection` instance. */
30
+ export type OptionalCollectionItem<C extends Collection> = OptionalItem<CollectionIdentifier<C>, CollectionData<C>>;
31
+ /** Extract the array of `Item` types from a `Collection` instance. */
32
+ export type CollectionItems<C extends Collection> = Items<CollectionIdentifier<C>, CollectionData<C>>;
33
+ /** A readonly array of Collection instances, possibly with a standardised `Identifier` and `Data` types. */
34
+ export type Collections<I extends Identifier = Identifier, D extends Data = Data> = ImmutableArray<Collection<string, I, D>>;
33
35
  /** Extract the union of string collection names from a `Collections` type. */
34
36
  export type CollectionNames<C extends Collections> = C[number]["name"];
35
37
  /** Convert a `Collections` array type to a Database-style object mapping in `{ name: data }` format. */
package/db/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ export * from "./cache/CollectionCache.js";
2
+ export * from "./cache/DBCache.js";
1
3
  export * from "./collection/Collection.js";
2
4
  export * from "./migrate/DBMigrator.js";
3
5
  export * from "./migrate/PostgreSQLMigrator.js";
package/db/index.js CHANGED
@@ -1,3 +1,5 @@
1
+ export * from "./cache/CollectionCache.js";
2
+ export * from "./cache/DBCache.js";
1
3
  export * from "./collection/Collection.js";
2
4
  export * from "./migrate/DBMigrator.js";
3
5
  export * from "./migrate/PostgreSQLMigrator.js";
@@ -1,26 +1,26 @@
1
1
  import type { Data } from "../../util/data.js";
2
- import type { Identifier, Items, OptionalItem } from "../../util/item.js";
3
- import type { ItemQuery } from "../../util/query.js";
2
+ import type { Identifier, Item, Items, OptionalItem } from "../../util/item.js";
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";
6
6
  import type { Collection } from "../collection/Collection.js";
7
7
  import { DBProvider } from "./DBProvider.js";
8
8
  import { MemoryDBProvider } from "./MemoryDBProvider.js";
9
9
  /** Keep a copy of asynchronous remote data in a local synchronous cache. */
10
- export declare class CacheDBProvider<I extends Identifier = Identifier> extends DBProvider<I> implements Sourceable<DBProvider<I>> {
11
- readonly source: DBProvider<I>;
12
- readonly memory: MemoryDBProvider<I>;
13
- constructor(source: DBProvider<I>, cache?: MemoryDBProvider<I>);
14
- getItem<T extends Data>(collection: Collection<string, I, T>, id: I): Promise<OptionalItem<I, T>>;
15
- getItemSequence<T extends Data>(collection: Collection<string, I, T>, id: I): AsyncIterable<OptionalItem<I, T>>;
16
- addItem<T extends Data>(collection: Collection<string, I, T>, data: T): Promise<I>;
17
- setItem<T extends Data>(collection: Collection<string, I, T>, id: I, data: T): Promise<void>;
18
- updateItem<T extends Data>(collection: Collection<string, I, T>, id: I, updates: Updates<T>): Promise<void>;
19
- deleteItem<T extends Data>(collection: Collection<string, I, T>, id: I): Promise<void>;
20
- countQuery<T extends Data>(collection: Collection<string, I, T>, query?: ItemQuery<I, T>): Promise<number>;
21
- getQuery<T extends Data>(collection: Collection<string, I, T>, query?: ItemQuery<I, T>): Promise<Items<I, T>>;
22
- getQuerySequence<T extends Data>(collection: Collection<string, I, T>, query?: ItemQuery<I, T>): AsyncIterable<Items<I, T>>;
23
- setQuery<T extends Data>(collection: Collection<string, I, T>, query: ItemQuery<I, T>, data: T): Promise<void>;
24
- updateQuery<T extends Data>(collection: Collection<string, I, T>, query: ItemQuery<I, T>, updates: Updates<T>): Promise<void>;
25
- deleteQuery<T extends Data>(collection: Collection<string, I, T>, query: ItemQuery<I, T>): Promise<void>;
10
+ export declare class CacheDBProvider<I extends Identifier, T extends Data> extends DBProvider<I, T> implements Sourceable<DBProvider<I, T>> {
11
+ readonly source: DBProvider<I, T>;
12
+ readonly memory: MemoryDBProvider<I, T>;
13
+ constructor(source: DBProvider<I, T>, cache?: MemoryDBProvider<I, T>);
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>>;
16
+ addItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, data: TT): Promise<II>;
17
+ setItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II, data: TT): Promise<void>;
18
+ updateItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II, updates: Updates<Item<II, TT>>): Promise<void>;
19
+ deleteItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): Promise<void>;
20
+ countQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query?: Query<Item<II, TT>>): Promise<number>;
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>>;
23
+ setQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>, data: TT): Promise<void>;
24
+ updateQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>, updates: Updates<TT>): Promise<void>;
25
+ deleteQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>): Promise<void>;
26
26
  }
@@ -1,12 +1,12 @@
1
1
  import type { MutableArray } from "../../util/array.js";
2
2
  import type { Data } from "../../util/data.js";
3
- import type { Identifier } from "../../util/item.js";
4
- import type { ItemQuery } from "../../util/query.js";
3
+ import type { Identifier, Item } from "../../util/item.js";
4
+ import type { Query } from "../../util/query.js";
5
5
  import type { Updates } from "../../util/update.js";
6
6
  import type { Collection } from "../collection/Collection.js";
7
7
  import { ThroughDBProvider } from "./ThroughDBProvider.js";
8
8
  /** A structured log entry for a database change. */
9
- export type DBChange<I extends Identifier = Identifier> = {
9
+ export type DBChange<I extends Identifier> = {
10
10
  readonly action: "add" | "set" | "update" | "delete";
11
11
  readonly collection: string;
12
12
  readonly id?: I | undefined;
@@ -15,14 +15,14 @@ export type DBChange<I extends Identifier = Identifier> = {
15
15
  readonly updates?: unknown;
16
16
  };
17
17
  /** Asynchronous provider that keeps a log of any written changes to its `.changes` property. */
18
- export declare class ChangesDBProvider<I extends Identifier = Identifier> extends ThroughDBProvider<I> {
18
+ export declare class ChangesDBProvider<I extends Identifier, T extends Data> extends ThroughDBProvider<I, T> {
19
19
  get changes(): ReadonlyArray<DBChange<I>>;
20
20
  readonly _changes: MutableArray<DBChange<I>>;
21
- addItem<T extends Data>(collection: Collection<string, I, T>, data: T): Promise<I>;
22
- setItem<T extends Data>(collection: Collection<string, I, T>, id: I, data: T): Promise<void>;
23
- updateItem<T extends Data>(collection: Collection<string, I, T>, id: I, updates: Updates<T>): Promise<void>;
24
- deleteItem<T extends Data>(collection: Collection<string, I, T>, id: I): Promise<void>;
25
- setQuery<T extends Data>(collection: Collection<string, I, T>, query: ItemQuery<I, T>, data: T): Promise<void>;
26
- updateQuery<T extends Data>(collection: Collection<string, I, T>, query: ItemQuery<I, T>, updates: Updates<T>): Promise<void>;
27
- deleteQuery<T extends Data>(collection: Collection<string, I, T>, query: ItemQuery<I, T>): Promise<void>;
21
+ addItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, data: TT): Promise<II>;
22
+ setItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II, data: TT): Promise<void>;
23
+ updateItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II, updates: Updates<Item<II, TT>>): Promise<void>;
24
+ deleteItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): Promise<void>;
25
+ setQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>, data: TT): Promise<void>;
26
+ updateQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>, updates: Updates<TT>): Promise<void>;
27
+ deleteQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>): Promise<void>;
28
28
  }
@@ -1,23 +1,23 @@
1
1
  import type { Data } from "../../util/data.js";
2
2
  import type { Identifier, Item, Items, OptionalItem } from "../../util/item.js";
3
- import type { ItemQuery } from "../../util/query.js";
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";
6
6
  /** Provider with a fully asynchronous interface for database access. */
7
- export declare abstract class DBProvider<I extends Identifier = Identifier> {
8
- abstract getItem<T extends Data>(collection: Collection<string, I, T>, id: I): Promise<OptionalItem<I, T>>;
9
- requireItem<T extends Data>(collection: Collection<string, I, T>, id: I): Promise<Item<I, T>>;
10
- abstract getItemSequence<T extends Data>(collection: Collection<string, I, T>, id: I): AsyncIterable<OptionalItem<I, T>>;
11
- abstract addItem<T extends Data>(collection: Collection<string, I, T>, data: T): Promise<I>;
12
- abstract setItem<T extends Data>(collection: Collection<string, I, T>, id: I, data: T): Promise<void>;
13
- abstract updateItem<T extends Data>(collection: Collection<string, I, T>, id: I, updates: Updates<T>): Promise<void>;
14
- abstract deleteItem<T extends Data>(collection: Collection<string, I, T>, id: I): Promise<void>;
15
- countQuery<T extends Data>(collection: Collection<string, I, T>, query?: ItemQuery<I, T>): Promise<number>;
16
- abstract getQuery<T extends Data>(collection: Collection<string, I, T>, query?: ItemQuery<I, T>): Promise<Items<I, T>>;
17
- abstract getQuerySequence<T extends Data>(collection: Collection<string, I, T>, query?: ItemQuery<I, T>): AsyncIterable<Items<I, T>>;
18
- abstract setQuery<T extends Data>(collection: Collection<string, I, T>, query: ItemQuery<I, T>, data: T): Promise<void>;
19
- abstract updateQuery<T extends Data>(collection: Collection<string, I, T>, query: ItemQuery<I, T>, updates: Updates<T>): Promise<void>;
20
- abstract deleteQuery<T extends Data>(collection: Collection<string, I, T>, query: ItemQuery<I, T>): Promise<void>;
21
- getFirst<T extends Data>(collection: Collection<string, I, T>, query: ItemQuery<I, T>): Promise<OptionalItem<I, T>>;
22
- requireFirst<T extends Data>(collection: Collection<string, I, T>, query: ItemQuery<I, T>): Promise<Item<I, T>>;
7
+ export declare abstract class DBProvider<I extends Identifier = Identifier, T extends Data = Data> {
8
+ abstract getItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): Promise<OptionalItem<II, TT>>;
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>>;
11
+ abstract addItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, data: TT): Promise<II>;
12
+ abstract setItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II, data: TT): Promise<void>;
13
+ abstract updateItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II, updates: Updates<Item<II, TT>>): Promise<void>;
14
+ abstract deleteItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): Promise<void>;
15
+ countQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query?: Query<Item<II, TT>>): Promise<number>;
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>>;
18
+ abstract setQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>, data: TT): Promise<void>;
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
+ abstract deleteQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>): Promise<void>;
21
+ getFirst<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>): Promise<OptionalItem<II, TT>>;
22
+ requireFirst<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>): Promise<Item<II, TT>>;
23
23
  }
@@ -7,7 +7,7 @@ export class DBProvider {
7
7
  if (!item)
8
8
  throw new RequiredError(`Item does not exist in collection "${collection.name}"`, {
9
9
  provider: this,
10
- collection: collection.name,
10
+ collection,
11
11
  id,
12
12
  caller: this.requireItem,
13
13
  });
@@ -24,7 +24,7 @@ export class DBProvider {
24
24
  if (!first)
25
25
  throw new RequiredError(`First item does not exist in collection "${collection.name}"`, {
26
26
  provider: this,
27
- collection: collection.name,
27
+ collection,
28
28
  query,
29
29
  caller: this.requireFirst,
30
30
  });
@@ -1,21 +1,21 @@
1
1
  import type { Data } from "../../util/data.js";
2
- import type { Identifier, Items, OptionalItem } from "../../util/item.js";
3
- import type { ItemQuery } from "../../util/query.js";
2
+ import type { Identifier, Item, Items, OptionalItem } from "../../util/item.js";
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";
6
6
  import { ThroughDBProvider } from "./ThroughDBProvider.js";
7
7
  /** Provider that logs operations to the console. */
8
- export declare class DebugDBProvider<I extends Identifier = Identifier> extends ThroughDBProvider<I> {
9
- getItem<T extends Data>(collection: Collection<string, I, T>, id: I): Promise<OptionalItem<I, T>>;
10
- getItemSequence<T extends Data>(collection: Collection<string, I, T>, id: I): AsyncIterableIterator<OptionalItem<I, T>>;
11
- addItem<T extends Data>(collection: Collection<string, I, T>, data: T): Promise<I>;
12
- setItem<T extends Data>(collection: Collection<string, I, T>, id: I, data: T): Promise<void>;
13
- updateItem<T extends Data>(collection: Collection<string, I, T>, id: I, updates: Updates<T>): Promise<void>;
14
- deleteItem<T extends Data>(collection: Collection<string, I, T>, id: I): Promise<void>;
15
- countQuery<T extends Data>(collection: Collection<string, I, T>, query?: ItemQuery<I, T>): Promise<number>;
16
- getQuery<T extends Data>(collection: Collection<string, I, T>, query?: ItemQuery<I, T>): Promise<Items<I, T>>;
17
- getQuerySequence<T extends Data>(collection: Collection<string, I, T>, query?: ItemQuery<I, T>): AsyncIterableIterator<Items<I, T>>;
18
- setQuery<T extends Data>(collection: Collection<string, I, T>, query: ItemQuery<I, T>, data: T): Promise<void>;
19
- updateQuery<T extends Data>(collection: Collection<string, I, T>, query: ItemQuery<I, T>, updates: Updates<T>): Promise<void>;
20
- deleteQuery<T extends Data>(collection: Collection<string, I, T>, query: ItemQuery<I, T>): Promise<void>;
8
+ export declare class DebugDBProvider<I extends Identifier, T extends Data> extends ThroughDBProvider<I, T> {
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>>;
11
+ addItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, data: TT): Promise<II>;
12
+ setItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II, data: TT): Promise<void>;
13
+ updateItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II, updates: Updates<Item<II, TT>>): Promise<void>;
14
+ deleteItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): Promise<void>;
15
+ countQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query?: Query<Item<II, TT>>): Promise<number>;
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>>;
18
+ setQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>, data: TT): Promise<void>;
19
+ updateQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>, updates: Updates<TT>): Promise<void>;
20
+ deleteQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>): Promise<void>;
21
21
  }
@@ -1,7 +1,7 @@
1
1
  import { DeferredSequence } from "../../sequence/DeferredSequence.js";
2
2
  import type { Data } from "../../util/data.js";
3
3
  import type { Identifier, Item, Items, OptionalItem } from "../../util/item.js";
4
- import type { ItemQuery } from "../../util/query.js";
4
+ import type { Query } from "../../util/query.js";
5
5
  import type { Updates } from "../../util/update.js";
6
6
  import type { Collection } from "../collection/Collection.js";
7
7
  import { DBProvider } from "./DBProvider.js";
@@ -10,31 +10,33 @@ import { DBProvider } from "./DBProvider.js";
10
10
  * - Extremely fast (ideal for caching!), but does not persist data after the browser window is closed.
11
11
  * - `get()` etc return the exact same instance of an object that's passed into `set()`
12
12
  */
13
- export declare class MemoryDBProvider<I extends Identifier = Identifier> extends DBProvider<I> {
14
- /** List of tables in `{ collection: Table }` format. */
13
+ export declare class MemoryDBProvider<I extends Identifier = Identifier, T extends Data = Data> extends DBProvider<I, T> {
14
+ /** List of tables in `{ name: MemoryTable }` format. */
15
15
  private _tables;
16
16
  /** Get a table for a collection. */
17
- getTable<T extends Data>({ name }: Collection<string, I, T>): MemoryTable<I, T>;
18
- getItem<T extends Data>(collection: Collection<string, I, T>, id: I): Promise<OptionalItem<I, T>>;
19
- getItemSequence<T extends Data>(collection: Collection<string, I, T>, id: I): AsyncIterable<OptionalItem<I, T>>;
20
- addItem<T extends Data>(collection: Collection<string, I, T>, data: T): Promise<I>;
21
- setItem<T extends Data>(collection: Collection<string, I, T>, id: I, data: T): Promise<void>;
22
- updateItem<T extends Data>(collection: Collection<string, I, T>, id: I, updates: Updates<T>): Promise<void>;
23
- deleteItem<T extends Data>(collection: Collection<string, I, T>, id: I): Promise<void>;
24
- countQuery<T extends Data>(collection: Collection<string, I, T>, query?: ItemQuery<I, T>): Promise<number>;
25
- getQuery<T extends Data>(collection: Collection<string, I, T>, query?: ItemQuery<I, T>): Promise<Items<I, T>>;
26
- getQuerySequence<T extends Data>(collection: Collection<string, I, T>, query?: ItemQuery<I, T>): AsyncIterable<Items<I, T>>;
27
- setQuery<T extends Data>(collection: Collection<string, I, T>, query: ItemQuery<I, T>, data: T): Promise<void>;
28
- updateQuery<T extends Data>(collection: Collection<string, I, T>, query: ItemQuery<I, T>, updates: Updates<T>): Promise<void>;
29
- deleteQuery<T extends Data>(collection: Collection<string, I, T>, query: ItemQuery<I, T>): Promise<void>;
30
- setItems<T extends Data>(collection: Collection<string, I, T>, items: Items<I, T>): void;
17
+ getTable<II extends I, TT extends T>(collection: Collection<string, II, TT>): MemoryTable<II, TT>;
18
+ getItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): Promise<OptionalItem<II, TT>>;
19
+ getItemSequence<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): AsyncIterable<OptionalItem<II, TT>>;
20
+ addItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, data: TT): Promise<II>;
21
+ setItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II, data: TT): Promise<void>;
22
+ updateItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II, updates: Updates<Item<II, TT>>): Promise<void>;
23
+ deleteItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): Promise<void>;
24
+ countQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query?: Query<Item<II, TT>>): Promise<number>;
25
+ getQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query?: Query<Item<II, TT>>): Promise<Items<II, TT>>;
26
+ getQuerySequence<II extends I, TT extends T>(collection: Collection<string, II, TT>, query?: Query<Item<II, TT>>): AsyncIterable<Items<II, TT>>;
27
+ setQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>, data: TT): Promise<void>;
28
+ updateQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>, updates: Updates<TT>): Promise<void>;
29
+ deleteQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>): Promise<void>;
30
+ setItems<II extends I, TT extends T>(collection: Collection<string, II, TT>, items: Items<II, TT>): void;
31
31
  }
32
32
  /** An individual table of data. */
33
33
  export declare class MemoryTable<I extends Identifier, T extends Data> {
34
34
  /** Actual data in this table. */
35
- protected readonly _data: Map<Identifier, Item<I, T>>;
35
+ protected readonly _data: Map<I, Item<I, T>>;
36
36
  /** Deferred sequence of next values. */
37
37
  readonly next: DeferredSequence<void>;
38
+ readonly collection: Collection<string, I, T>;
39
+ constructor(collection: Collection<string, I, T>);
38
40
  getItem(id: I): OptionalItem<I, T>;
39
41
  /**
40
42
  * Subscribe to all changes for this item key.
@@ -42,24 +44,24 @@ export declare class MemoryTable<I extends Identifier, T extends Data> {
42
44
  * - Wakes on every table change, but only yields when this item's value actually changed.
43
45
  */
44
46
  getItemSequence(id: I): AsyncIterable<OptionalItem<I, T>>;
45
- /** Function to generate a random ID for this table. */
47
+ /** Generate a unique ID for a new item in this table. */
46
48
  generateUniqueID(): I;
47
49
  addItem(data: T): I;
48
50
  setItem(id: I, data: Item<I, T> | T): void;
49
51
  setItemSequence(id: I, sequence: AsyncIterable<OptionalItem<I, T>>): AsyncIterable<OptionalItem<I, T>>;
50
- updateItem(id: I, updates: Updates<T>): void;
52
+ updateItem(id: I, updates: Updates<Item<I, T>>): void;
51
53
  deleteItem(id: I): void;
52
- countQuery(query?: ItemQuery<I, T>): number;
53
- getQuery(query?: ItemQuery<I, T>): Items<I, T>;
54
+ countQuery(query?: Query<Item<I, T>>): number;
55
+ getQuery(query?: Query<Item<I, T>>): Items<I, T>;
54
56
  /**
55
57
  * Subscribe to the live result of a query.
56
58
  * - Emits the current query result immediately, even if empty.
57
59
  * - Wakes on every table change, but only yields when the computed query result changed.
58
60
  */
59
- getQuerySequence(query?: ItemQuery<I, T>): AsyncIterable<Items<I, T>>;
60
- setQuery(query: ItemQuery<I, T>, data: T): void;
61
- updateQuery(query: ItemQuery<I, T>, updates: Updates<T>): void;
62
- deleteQuery(query: ItemQuery<I, T>): void;
61
+ getQuerySequence(query?: Query<Item<I, T>>): AsyncIterable<Items<I, T>>;
62
+ setQuery(query: Query<Item<I, T>>, data: T): void;
63
+ updateQuery(query: Query<Item<I, T>>, updates: Updates<T>): void;
64
+ deleteQuery(query: Query<Item<I, T>>): void;
63
65
  setItems(items: Items<I, T>): void;
64
66
  setItemsSequence(sequence: AsyncIterable<Items<I, T>>): AsyncIterable<Items<I, T>>;
65
67
  }
@@ -1,3 +1,4 @@
1
+ import { StringSchema } from "../../schema/StringSchema.js";
1
2
  import { DeferredSequence } from "../../sequence/DeferredSequence.js";
2
3
  import { requireArray } from "../../util/array.js";
3
4
  import { isArrayEqual } from "../../util/equal.js";
@@ -13,12 +14,11 @@ import { DBProvider } from "./DBProvider.js";
13
14
  * - `get()` etc return the exact same instance of an object that's passed into `set()`
14
15
  */
15
16
  export class MemoryDBProvider extends DBProvider {
16
- /** List of tables in `{ collection: Table }` format. */
17
- // biome-ignore lint/suspicious/noExplicitAny: Internal storage erases T; getTable<T> restores it per-call.
17
+ /** List of tables in `{ name: MemoryTable }` format. */
18
18
  _tables = {};
19
19
  /** Get a table for a collection. */
20
- getTable({ name }) {
21
- return (this._tables[name] ||= new MemoryTable());
20
+ getTable(collection) {
21
+ return (this._tables[collection.name] ||= new MemoryTable(collection));
22
22
  }
23
23
  async getItem(collection, id) {
24
24
  return this.getTable(collection).getItem(id);
@@ -66,6 +66,10 @@ export class MemoryTable {
66
66
  _data = new Map();
67
67
  /** Deferred sequence of next values. */
68
68
  next = new DeferredSequence();
69
+ collection;
70
+ constructor(collection) {
71
+ this.collection = collection;
72
+ }
69
73
  getItem(id) {
70
74
  return this._data.get(id);
71
75
  }
@@ -86,8 +90,9 @@ export class MemoryTable {
86
90
  }
87
91
  }
88
92
  }
93
+ /** Generate a unique ID for a new item in this table. */
89
94
  generateUniqueID() {
90
- const gen = typeof this._data.keys().next().value === "number" ? getRandom : getRandomKey;
95
+ const gen = (this.collection.id instanceof StringSchema ? getRandomKey : getRandom);
91
96
  let id = gen();
92
97
  while (this._data.has(id))
93
98
  id = gen(); // Regenerate ID until unique.
@@ -1,30 +1,30 @@
1
1
  import type { Data } from "../../util/data.js";
2
- import type { Identifier, Items, OptionalItem } from "../../util/item.js";
3
- import type { ItemQuery } from "../../util/query.js";
2
+ import type { Identifier, Item, Items, OptionalItem } from "../../util/item.js";
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";
6
6
  import { MemoryDBProvider } from "./MemoryDBProvider.js";
7
7
  /** A structured log entry emitted by `MockDBProvider` for one of its provider operations. */
8
- export type MockDBCall<I extends Identifier = Identifier> = {
8
+ export type MockDBCall = {
9
9
  readonly type: "getItem" | "addItem" | "setItem" | "updateItem" | "deleteItem" | "countQuery" | "getQuery" | "setQuery" | "updateQuery" | "deleteQuery";
10
10
  readonly collection: string;
11
- readonly id?: I | undefined;
11
+ readonly id?: Identifier | undefined;
12
12
  readonly query?: unknown;
13
- readonly data?: unknown;
13
+ readonly data?: Data;
14
14
  readonly updates?: unknown;
15
15
  readonly result?: unknown;
16
16
  };
17
17
  /** Provider that logs database operations for testing purposes. */
18
- export declare class MockDBProvider<I extends Identifier = Identifier> extends MemoryDBProvider<I> {
19
- readonly calls: MockDBCall<I>[];
20
- getItem<T extends Data>(collection: Collection<string, I, T>, id: I): Promise<OptionalItem<I, T>>;
21
- addItem<T extends Data>(collection: Collection<string, I, T>, data: T): Promise<I>;
22
- setItem<T extends Data>(collection: Collection<string, I, T>, id: I, data: T): Promise<void>;
23
- updateItem<T extends Data>(collection: Collection<string, I, T>, id: I, updates: Updates<T>): Promise<void>;
24
- deleteItem<T extends Data>(collection: Collection<string, I, T>, id: I): Promise<void>;
25
- countQuery<T extends Data>(collection: Collection<string, I, T>, query?: ItemQuery<I, T>): Promise<number>;
26
- getQuery<T extends Data>(collection: Collection<string, I, T>, query?: ItemQuery<I, T>): Promise<Items<I, T>>;
27
- setQuery<T extends Data>(collection: Collection<string, I, T>, query: ItemQuery<I, T>, data: T): Promise<void>;
28
- updateQuery<T extends Data>(collection: Collection<string, I, T>, query: ItemQuery<I, T>, updates: Updates<T>): Promise<void>;
29
- deleteQuery<T extends Data>(collection: Collection<string, I, T>, query: ItemQuery<I, T>): Promise<void>;
18
+ export declare class MockDBProvider<I extends Identifier = Identifier, T extends Data = Data> extends MemoryDBProvider<I, T> {
19
+ readonly calls: MockDBCall[];
20
+ getItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): Promise<OptionalItem<II, TT>>;
21
+ addItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, data: TT): Promise<II>;
22
+ setItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II, data: TT): Promise<void>;
23
+ updateItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II, updates: Updates<Item<II, TT>>): Promise<void>;
24
+ deleteItem<II extends I, TT extends T>(collection: Collection<string, II, TT>, id: II): Promise<void>;
25
+ countQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query?: Query<Item<II, TT>>): Promise<number>;
26
+ getQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query?: Query<Item<II, TT>>): Promise<Items<II, TT>>;
27
+ setQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>, data: TT): Promise<void>;
28
+ updateQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>, updates: Updates<TT>): Promise<void>;
29
+ deleteQuery<II extends I, TT extends T>(collection: Collection<string, II, TT>, query: Query<Item<II, TT>>): Promise<void>;
30
30
  }
@@ -1,11 +1,13 @@
1
- import type { DataPath } from "../../util/data.js";
1
+ import type { Data, DataPath } from "../../util/data.js";
2
+ import type { Identifier } from "../../util/item.js";
2
3
  import type { QueryFilter } from "../../util/query.js";
3
4
  import type { Update } from "../../util/update.js";
4
5
  import { type SQLFragment, SQLProvider } from "./SQLProvider.js";
5
6
  /** Abstract PostgreSQL provider with JSONB function support for nested keys, array containment, and array mutations. */
6
- export declare abstract class PostgreSQLProvider extends SQLProvider {
7
+ export declare abstract class PostgreSQLProvider<I extends Identifier = Identifier, T extends Data = Data> extends SQLProvider<I, T> {
7
8
  /** Get the Postgres JSONB path for the nested segments of a key, e.g. `{"b","c"}`. */
8
9
  private sqlPath;
10
+ /** Get the Postgres JSONB extract syntax, e.g. `"a" #>> {"b","c"}` */
9
11
  sqlExtract(key: DataPath): SQLFragment;
10
12
  sqlUpdate(update: Update): SQLFragment;
11
13
  sqlFilter(filter: QueryFilter): SQLFragment;
@@ -5,7 +5,7 @@ export class PostgreSQLProvider extends SQLProvider {
5
5
  sqlPath(key) {
6
6
  return this.sqlConcat(key.slice(1).map(k => this.sqlIdentifier(k)), ",", "{", "}");
7
7
  }
8
- // Override to support nested JSONB extract syntax, e.g. `"a" #>> {"b","c"}`
8
+ /** Get the Postgres JSONB extract syntax, e.g. `"a" #>> {"b","c"}` */
9
9
  sqlExtract(key) {
10
10
  const column = this.sqlIdentifier(key[0]);
11
11
  if (key.length > 1) {