ai-database 2.1.3 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -1
- package/README.md +880 -669
- package/dist/actions.d.ts +2 -2
- package/dist/actions.d.ts.map +1 -1
- package/dist/actions.js +1 -1
- package/dist/actions.js.map +1 -1
- package/dist/ai-promise-db.d.ts +49 -23
- package/dist/ai-promise-db.d.ts.map +1 -1
- package/dist/ai-promise-db.js +91 -63
- package/dist/ai-promise-db.js.map +1 -1
- package/dist/authorization.d.ts.map +1 -1
- package/dist/authorization.js +38 -30
- package/dist/authorization.js.map +1 -1
- package/dist/cascade-orchestrator.d.ts +404 -0
- package/dist/cascade-orchestrator.d.ts.map +1 -0
- package/dist/cascade-orchestrator.js +828 -0
- package/dist/cascade-orchestrator.js.map +1 -0
- package/dist/cascade-write-strategy.d.ts +584 -0
- package/dist/cascade-write-strategy.d.ts.map +1 -0
- package/dist/cascade-write-strategy.js +590 -0
- package/dist/cascade-write-strategy.js.map +1 -0
- package/dist/ch-adapter.d.ts +358 -0
- package/dist/ch-adapter.d.ts.map +1 -0
- package/dist/ch-adapter.js +929 -0
- package/dist/ch-adapter.js.map +1 -0
- package/dist/client/index.d.ts +42 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +43 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client.d.ts +266 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +81 -0
- package/dist/client.js.map +1 -0
- package/dist/constants.d.ts +64 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +52 -2
- package/dist/constants.js.map +1 -1
- package/dist/dataloader.d.ts +99 -0
- package/dist/dataloader.d.ts.map +1 -0
- package/dist/dataloader.js +225 -0
- package/dist/dataloader.js.map +1 -0
- package/dist/db-provider-port.d.ts +501 -0
- package/dist/db-provider-port.d.ts.map +1 -0
- package/dist/db-provider-port.js +113 -0
- package/dist/db-provider-port.js.map +1 -0
- package/dist/digital-objects-provider.d.ts +49 -0
- package/dist/digital-objects-provider.d.ts.map +1 -0
- package/dist/digital-objects-provider.js +55 -0
- package/dist/digital-objects-provider.js.map +1 -0
- package/dist/do-sqlite-adapter.d.ts +402 -0
- package/dist/do-sqlite-adapter.d.ts.map +1 -0
- package/dist/do-sqlite-adapter.js +745 -0
- package/dist/do-sqlite-adapter.js.map +1 -0
- package/dist/docs-rels/custom-types.d.ts +134 -0
- package/dist/docs-rels/custom-types.d.ts.map +1 -0
- package/dist/docs-rels/custom-types.js +70 -0
- package/dist/docs-rels/custom-types.js.map +1 -0
- package/dist/docs-rels/index.d.ts +16 -0
- package/dist/docs-rels/index.d.ts.map +1 -0
- package/dist/docs-rels/index.js +16 -0
- package/dist/docs-rels/index.js.map +1 -0
- package/dist/docs-rels/migrations/index.d.ts +30 -0
- package/dist/docs-rels/migrations/index.d.ts.map +1 -0
- package/dist/docs-rels/migrations/index.js +128 -0
- package/dist/docs-rels/migrations/index.js.map +1 -0
- package/dist/docs-rels/schema.d.ts +2961 -0
- package/dist/docs-rels/schema.d.ts.map +1 -0
- package/dist/docs-rels/schema.js +244 -0
- package/dist/docs-rels/schema.js.map +1 -0
- package/dist/durable-clickhouse.d.ts.map +1 -1
- package/dist/durable-clickhouse.js +16 -13
- package/dist/durable-clickhouse.js.map +1 -1
- package/dist/durable-promise.d.ts.map +1 -1
- package/dist/durable-promise.js +34 -15
- package/dist/durable-promise.js.map +1 -1
- package/dist/errors.d.ts +127 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +210 -0
- package/dist/errors.js.map +1 -0
- package/dist/eventbridge.d.ts +117 -0
- package/dist/eventbridge.d.ts.map +1 -0
- package/dist/eventbridge.js +238 -0
- package/dist/eventbridge.js.map +1 -0
- package/dist/events.d.ts +2 -2
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +1 -1
- package/dist/events.js.map +1 -1
- package/dist/execution-queue.d.ts.map +1 -1
- package/dist/execution-queue.js +4 -5
- package/dist/execution-queue.js.map +1 -1
- package/dist/index.d.ts +35 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +106 -6
- package/dist/index.js.map +1 -1
- package/dist/linguistic.d.ts +3 -108
- package/dist/linguistic.d.ts.map +1 -1
- package/dist/linguistic.js +3 -372
- package/dist/linguistic.js.map +1 -1
- package/dist/logger.d.ts +132 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +137 -0
- package/dist/logger.js.map +1 -0
- package/dist/memory-provider.d.ts +128 -0
- package/dist/memory-provider.d.ts.map +1 -1
- package/dist/memory-provider.js +592 -257
- package/dist/memory-provider.js.map +1 -1
- package/dist/pg-adapter.d.ts +424 -0
- package/dist/pg-adapter.d.ts.map +1 -0
- package/dist/pg-adapter.js +921 -0
- package/dist/pg-adapter.js.map +1 -0
- package/dist/pipelines-iceberg-emitter.d.ts +327 -0
- package/dist/pipelines-iceberg-emitter.d.ts.map +1 -0
- package/dist/pipelines-iceberg-emitter.js +351 -0
- package/dist/pipelines-iceberg-emitter.js.map +1 -0
- package/dist/provider-capabilities.d.ts +146 -0
- package/dist/provider-capabilities.d.ts.map +1 -0
- package/dist/provider-capabilities.js +214 -0
- package/dist/provider-capabilities.js.map +1 -0
- package/dist/rdb-provider-adapter.d.ts +195 -0
- package/dist/rdb-provider-adapter.d.ts.map +1 -0
- package/dist/rdb-provider-adapter.js +291 -0
- package/dist/rdb-provider-adapter.js.map +1 -0
- package/dist/schema/cascade.d.ts +48 -17
- package/dist/schema/cascade.d.ts.map +1 -1
- package/dist/schema/cascade.js +477 -278
- package/dist/schema/cascade.js.map +1 -1
- package/dist/schema/definition-caches.d.ts +24 -0
- package/dist/schema/definition-caches.d.ts.map +1 -0
- package/dist/schema/definition-caches.js +26 -0
- package/dist/schema/definition-caches.js.map +1 -0
- package/dist/schema/dependency-graph.d.ts +21 -109
- package/dist/schema/dependency-graph.d.ts.map +1 -1
- package/dist/schema/dependency-graph.js +25 -333
- package/dist/schema/dependency-graph.js.map +1 -1
- package/dist/schema/diff.d.ts +103 -0
- package/dist/schema/diff.d.ts.map +1 -0
- package/dist/schema/diff.js +329 -0
- package/dist/schema/diff.js.map +1 -0
- package/dist/schema/entity-operations.d.ts +99 -0
- package/dist/schema/entity-operations.d.ts.map +1 -0
- package/dist/schema/entity-operations.js +818 -0
- package/dist/schema/entity-operations.js.map +1 -0
- package/dist/schema/index.d.ts +28 -34
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +454 -521
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/migration.d.ts +205 -0
- package/dist/schema/migration.d.ts.map +1 -0
- package/dist/schema/migration.js +327 -0
- package/dist/schema/migration.js.map +1 -0
- package/dist/schema/nl-query-generator.d.ts +68 -0
- package/dist/schema/nl-query-generator.d.ts.map +1 -0
- package/dist/schema/nl-query-generator.js +362 -0
- package/dist/schema/nl-query-generator.js.map +1 -0
- package/dist/schema/nl-query.d.ts +65 -0
- package/dist/schema/nl-query.d.ts.map +1 -0
- package/dist/schema/nl-query.js +178 -0
- package/dist/schema/nl-query.js.map +1 -0
- package/dist/schema/parse.d.ts.map +1 -1
- package/dist/schema/parse.js +144 -89
- package/dist/schema/parse.js.map +1 -1
- package/dist/schema/provider.d.ts +37 -0
- package/dist/schema/provider.d.ts.map +1 -1
- package/dist/schema/provider.js +15 -7
- package/dist/schema/provider.js.map +1 -1
- package/dist/schema/resolve.d.ts +46 -5
- package/dist/schema/resolve.d.ts.map +1 -1
- package/dist/schema/resolve.js +237 -95
- package/dist/schema/resolve.js.map +1 -1
- package/dist/schema/search-utils.d.ts +76 -0
- package/dist/schema/search-utils.d.ts.map +1 -0
- package/dist/schema/search-utils.js +86 -0
- package/dist/schema/search-utils.js.map +1 -0
- package/dist/schema/seed.d.ts +53 -0
- package/dist/schema/seed.d.ts.map +1 -0
- package/dist/schema/seed.js +94 -0
- package/dist/schema/seed.js.map +1 -0
- package/dist/schema/semantic.d.ts +10 -0
- package/dist/schema/semantic.d.ts.map +1 -1
- package/dist/schema/semantic.js +192 -86
- package/dist/schema/semantic.js.map +1 -1
- package/dist/schema/sub-apis.d.ts +52 -0
- package/dist/schema/sub-apis.d.ts.map +1 -0
- package/dist/schema/sub-apis.js +216 -0
- package/dist/schema/sub-apis.js.map +1 -0
- package/dist/schema/system-entities.d.ts +42 -0
- package/dist/schema/system-entities.d.ts.map +1 -0
- package/dist/schema/system-entities.js +101 -0
- package/dist/schema/system-entities.js.map +1 -0
- package/dist/schema/types.d.ts +91 -9
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/union-fallback.d.ts.map +1 -1
- package/dist/schema/union-fallback.js +21 -15
- package/dist/schema/union-fallback.js.map +1 -1
- package/dist/schema/value-generators/ai.d.ts +54 -0
- package/dist/schema/value-generators/ai.d.ts.map +1 -0
- package/dist/schema/value-generators/ai.js +136 -0
- package/dist/schema/value-generators/ai.js.map +1 -0
- package/dist/schema/value-generators/index.d.ts +126 -0
- package/dist/schema/value-generators/index.d.ts.map +1 -0
- package/dist/schema/value-generators/index.js +219 -0
- package/dist/schema/value-generators/index.js.map +1 -0
- package/dist/schema/value-generators/placeholder.d.ts +52 -0
- package/dist/schema/value-generators/placeholder.d.ts.map +1 -0
- package/dist/schema/value-generators/placeholder.js +328 -0
- package/dist/schema/value-generators/placeholder.js.map +1 -0
- package/dist/schema/value-generators/types.d.ts +116 -0
- package/dist/schema/value-generators/types.d.ts.map +1 -0
- package/dist/schema/value-generators/types.js +11 -0
- package/dist/schema/value-generators/types.js.map +1 -0
- package/dist/schema/version.d.ts +111 -0
- package/dist/schema/version.d.ts.map +1 -0
- package/dist/schema/version.js +190 -0
- package/dist/schema/version.js.map +1 -0
- package/dist/schema.d.ts +1095 -24
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +2852 -40
- package/dist/schema.js.map +1 -1
- package/dist/semantic-vectors.d.ts +39 -0
- package/dist/semantic-vectors.d.ts.map +1 -0
- package/dist/semantic-vectors.js +334 -0
- package/dist/semantic-vectors.js.map +1 -0
- package/dist/semantic.d.ts +29 -1
- package/dist/semantic.d.ts.map +1 -1
- package/dist/semantic.js +26 -16
- package/dist/semantic.js.map +1 -1
- package/dist/telemetry.d.ts +128 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +305 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/tests.d.ts.map +1 -1
- package/dist/tests.js +30 -22
- package/dist/tests.js.map +1 -1
- package/dist/type-guards.d.ts +50 -5
- package/dist/type-guards.d.ts.map +1 -1
- package/dist/type-guards.js +87 -16
- package/dist/type-guards.js.map +1 -1
- package/dist/types.d.ts +33 -245
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +62 -72
- package/dist/types.js.map +1 -1
- package/dist/validation.d.ts +2 -5
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +65 -93
- package/dist/validation.js.map +1 -1
- package/dist/worker/db-provider.d.ts +168 -0
- package/dist/worker/db-provider.d.ts.map +1 -0
- package/dist/worker/db-provider.js +277 -0
- package/dist/worker/db-provider.js.map +1 -0
- package/dist/worker/index.d.ts +35 -0
- package/dist/worker/index.d.ts.map +1 -0
- package/dist/worker/index.js +37 -0
- package/dist/worker/index.js.map +1 -0
- package/dist/worker.d.ts +779 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +2786 -0
- package/dist/worker.js.map +1 -0
- package/package.json +46 -16
- package/src/docs-rels/migrations/0001-init.sql +125 -0
- package/LICENSE +0 -21
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,GAAG,CAAA;AAE/C;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,4BAA4B,CAAA;AAEhE;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,kEAAkE;IAClE,aAAa,EAAE,IAAI;IACnB,mEAAmE;IACnE,aAAa,EAAE,IAAI;IACnB,gEAAgE;IAChE,cAAc,EAAE,IAAI;IACpB,oEAAoE;IACpE,cAAc,EAAE,IAAI;CACZ,CAAA"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DataLoader - Microtask-batching for N+1 query prevention
|
|
3
|
+
*
|
|
4
|
+
* Batches individual entity lookups that occur within the same microtask tick
|
|
5
|
+
* into a single bulk fetch, deduplicating by (entityType, id) pairs.
|
|
6
|
+
*
|
|
7
|
+
* Inspired by the Facebook DataLoader pattern but tailored for ai-database's
|
|
8
|
+
* provider.get() interface.
|
|
9
|
+
*
|
|
10
|
+
* @packageDocumentation
|
|
11
|
+
*/
|
|
12
|
+
import type { DBProvider } from './schema.js';
|
|
13
|
+
/**
|
|
14
|
+
* Generic DataLoader that batches provider.get() calls within a microtask tick.
|
|
15
|
+
*
|
|
16
|
+
* Usage:
|
|
17
|
+
* ```ts
|
|
18
|
+
* const loader = new DataLoader(provider)
|
|
19
|
+
* // These all batch into a single tick:
|
|
20
|
+
* const [a, b, c] = await Promise.all([
|
|
21
|
+
* loader.load('User', 'id1'),
|
|
22
|
+
* loader.load('User', 'id2'),
|
|
23
|
+
* loader.load('User', 'id1'), // deduped, returns cached
|
|
24
|
+
* ])
|
|
25
|
+
* loader.clear() // reset for next request
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export declare class DataLoader {
|
|
29
|
+
private _provider;
|
|
30
|
+
private _cache;
|
|
31
|
+
private _queue;
|
|
32
|
+
private _scheduled;
|
|
33
|
+
private _cacheEnabled;
|
|
34
|
+
constructor(provider: DBProvider, options?: {
|
|
35
|
+
cache?: boolean;
|
|
36
|
+
});
|
|
37
|
+
/**
|
|
38
|
+
* Load a single entity by type and id.
|
|
39
|
+
* Batches with other load() calls in the same microtask tick.
|
|
40
|
+
* Results are cached for the lifetime of this DataLoader instance.
|
|
41
|
+
*/
|
|
42
|
+
load(type: string, id: string): Promise<Record<string, unknown> | null>;
|
|
43
|
+
/**
|
|
44
|
+
* Load multiple entities at once. Returns results in same order as input keys.
|
|
45
|
+
*/
|
|
46
|
+
loadMany(keys: Array<{
|
|
47
|
+
type: string;
|
|
48
|
+
id: string;
|
|
49
|
+
}>): Promise<Array<Record<string, unknown> | null>>;
|
|
50
|
+
/**
|
|
51
|
+
* Prime the cache with a known value (e.g., from a create or list result).
|
|
52
|
+
*/
|
|
53
|
+
prime(type: string, id: string, value: Record<string, unknown> | null): void;
|
|
54
|
+
/**
|
|
55
|
+
* Clear the entire cache, or a single entry.
|
|
56
|
+
*/
|
|
57
|
+
clear(type?: string, id?: string): void;
|
|
58
|
+
/**
|
|
59
|
+
* Get cache statistics for debugging.
|
|
60
|
+
*/
|
|
61
|
+
get stats(): {
|
|
62
|
+
cacheSize: number;
|
|
63
|
+
pendingQueue: number;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Dispatch all queued requests in a single batch.
|
|
67
|
+
* Groups by entity type, deduplicates IDs, then resolves all waiting promises.
|
|
68
|
+
*/
|
|
69
|
+
private _dispatch;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Create a new request-scoped DataLoader.
|
|
73
|
+
* Call this at the start of each request to enable batching.
|
|
74
|
+
*/
|
|
75
|
+
export declare function createRequestLoader(provider: DBProvider): DataLoader;
|
|
76
|
+
/**
|
|
77
|
+
* Get the active request-scoped DataLoader, if any.
|
|
78
|
+
*/
|
|
79
|
+
export declare function getRequestLoader(): DataLoader | null;
|
|
80
|
+
/**
|
|
81
|
+
* Clear the active request-scoped DataLoader.
|
|
82
|
+
* Call this at the end of each request.
|
|
83
|
+
*/
|
|
84
|
+
export declare function clearRequestLoader(): void;
|
|
85
|
+
/**
|
|
86
|
+
* Run a function within a DataLoader context.
|
|
87
|
+
* All provider.get() calls via loadEntity() within the callback
|
|
88
|
+
* will be batched within each microtask tick.
|
|
89
|
+
*/
|
|
90
|
+
export declare function withDataLoader<T>(provider: DBProvider, fn: () => Promise<T>): Promise<T>;
|
|
91
|
+
/**
|
|
92
|
+
* Load an entity using the active DataLoader if available,
|
|
93
|
+
* otherwise fall back to direct provider.get().
|
|
94
|
+
*
|
|
95
|
+
* This is the function that should replace direct provider.get() calls
|
|
96
|
+
* in entity resolution (hydrateEntity).
|
|
97
|
+
*/
|
|
98
|
+
export declare function loadEntity(provider: DBProvider, type: string, id: string): Promise<Record<string, unknown> | null>;
|
|
99
|
+
//# sourceMappingURL=dataloader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataloader.d.ts","sourceRoot":"","sources":["../src/dataloader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAiB7C;;;;;;;;;;;;;;GAcG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,MAAM,CAAwD;IACtE,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,aAAa,CAAS;gBAElB,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;IAQ/D;;;;OAIG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IA6BvE;;OAEG;IACG,QAAQ,CACZ,IAAI,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,GACxC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;IAIjD;;OAEG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,IAAI;IAQ5E;;OAEG;IACH,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAQvC;;OAEG;IACH,IAAI,KAAK,IAAI;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAKvD;IAED;;;OAGG;YACW,SAAS;CA+DxB;AASD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,UAAU,GAAG,UAAU,CAIpE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,UAAU,GAAG,IAAI,CAEpD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAKzC;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAO9F;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,UAAU,EACpB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,GACT,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAOzC"}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DataLoader - Microtask-batching for N+1 query prevention
|
|
3
|
+
*
|
|
4
|
+
* Batches individual entity lookups that occur within the same microtask tick
|
|
5
|
+
* into a single bulk fetch, deduplicating by (entityType, id) pairs.
|
|
6
|
+
*
|
|
7
|
+
* Inspired by the Facebook DataLoader pattern but tailored for ai-database's
|
|
8
|
+
* provider.get() interface.
|
|
9
|
+
*
|
|
10
|
+
* @packageDocumentation
|
|
11
|
+
*/
|
|
12
|
+
function makeCacheKey(type, id) {
|
|
13
|
+
return `${type}:${id}`;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Generic DataLoader that batches provider.get() calls within a microtask tick.
|
|
17
|
+
*
|
|
18
|
+
* Usage:
|
|
19
|
+
* ```ts
|
|
20
|
+
* const loader = new DataLoader(provider)
|
|
21
|
+
* // These all batch into a single tick:
|
|
22
|
+
* const [a, b, c] = await Promise.all([
|
|
23
|
+
* loader.load('User', 'id1'),
|
|
24
|
+
* loader.load('User', 'id2'),
|
|
25
|
+
* loader.load('User', 'id1'), // deduped, returns cached
|
|
26
|
+
* ])
|
|
27
|
+
* loader.clear() // reset for next request
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export class DataLoader {
|
|
31
|
+
_provider;
|
|
32
|
+
_cache;
|
|
33
|
+
_queue;
|
|
34
|
+
_scheduled;
|
|
35
|
+
_cacheEnabled;
|
|
36
|
+
constructor(provider, options) {
|
|
37
|
+
this._provider = provider;
|
|
38
|
+
this._cache = new Map();
|
|
39
|
+
this._queue = [];
|
|
40
|
+
this._scheduled = false;
|
|
41
|
+
this._cacheEnabled = options?.cache !== false;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Load a single entity by type and id.
|
|
45
|
+
* Batches with other load() calls in the same microtask tick.
|
|
46
|
+
* Results are cached for the lifetime of this DataLoader instance.
|
|
47
|
+
*/
|
|
48
|
+
load(type, id) {
|
|
49
|
+
const key = makeCacheKey(type, id);
|
|
50
|
+
// Return cached result if available
|
|
51
|
+
if (this._cacheEnabled) {
|
|
52
|
+
const cached = this._cache.get(key);
|
|
53
|
+
if (cached !== undefined) {
|
|
54
|
+
return cached;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Create a new promise and queue the request
|
|
58
|
+
const promise = new Promise((resolve, reject) => {
|
|
59
|
+
this._queue.push({ type, id, resolve, reject });
|
|
60
|
+
});
|
|
61
|
+
if (this._cacheEnabled) {
|
|
62
|
+
this._cache.set(key, promise);
|
|
63
|
+
}
|
|
64
|
+
// Schedule batch dispatch on next microtask if not already scheduled
|
|
65
|
+
if (!this._scheduled) {
|
|
66
|
+
this._scheduled = true;
|
|
67
|
+
Promise.resolve().then(() => this._dispatch());
|
|
68
|
+
}
|
|
69
|
+
return promise;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Load multiple entities at once. Returns results in same order as input keys.
|
|
73
|
+
*/
|
|
74
|
+
async loadMany(keys) {
|
|
75
|
+
return Promise.all(keys.map(({ type, id }) => this.load(type, id)));
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Prime the cache with a known value (e.g., from a create or list result).
|
|
79
|
+
*/
|
|
80
|
+
prime(type, id, value) {
|
|
81
|
+
if (!this._cacheEnabled)
|
|
82
|
+
return;
|
|
83
|
+
const key = makeCacheKey(type, id);
|
|
84
|
+
if (!this._cache.has(key)) {
|
|
85
|
+
this._cache.set(key, Promise.resolve(value));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Clear the entire cache, or a single entry.
|
|
90
|
+
*/
|
|
91
|
+
clear(type, id) {
|
|
92
|
+
if (type && id) {
|
|
93
|
+
this._cache.delete(makeCacheKey(type, id));
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
this._cache.clear();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Get cache statistics for debugging.
|
|
101
|
+
*/
|
|
102
|
+
get stats() {
|
|
103
|
+
return {
|
|
104
|
+
cacheSize: this._cache.size,
|
|
105
|
+
pendingQueue: this._queue.length,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Dispatch all queued requests in a single batch.
|
|
110
|
+
* Groups by entity type, deduplicates IDs, then resolves all waiting promises.
|
|
111
|
+
*/
|
|
112
|
+
async _dispatch() {
|
|
113
|
+
// Grab current queue and reset
|
|
114
|
+
const queue = this._queue;
|
|
115
|
+
this._queue = [];
|
|
116
|
+
this._scheduled = false;
|
|
117
|
+
if (queue.length === 0)
|
|
118
|
+
return;
|
|
119
|
+
// Group requests by type
|
|
120
|
+
const byType = new Map();
|
|
121
|
+
for (const req of queue) {
|
|
122
|
+
let typeMap = byType.get(req.type);
|
|
123
|
+
if (!typeMap) {
|
|
124
|
+
typeMap = new Map();
|
|
125
|
+
byType.set(req.type, typeMap);
|
|
126
|
+
}
|
|
127
|
+
let idRequests = typeMap.get(req.id);
|
|
128
|
+
if (!idRequests) {
|
|
129
|
+
idRequests = [];
|
|
130
|
+
typeMap.set(req.id, idRequests);
|
|
131
|
+
}
|
|
132
|
+
idRequests.push(req);
|
|
133
|
+
}
|
|
134
|
+
// Fetch all unique (type, id) pairs in parallel
|
|
135
|
+
const fetches = [];
|
|
136
|
+
for (const [type, idMap] of byType) {
|
|
137
|
+
for (const [id, requests] of idMap) {
|
|
138
|
+
fetches.push({
|
|
139
|
+
type,
|
|
140
|
+
id,
|
|
141
|
+
requests,
|
|
142
|
+
promise: this._provider
|
|
143
|
+
.get(type, id)
|
|
144
|
+
.then((result) => result ?? null),
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// Resolve all fetches and distribute results
|
|
149
|
+
const results = await Promise.allSettled(fetches.map((f) => f.promise));
|
|
150
|
+
for (let i = 0; i < fetches.length; i++) {
|
|
151
|
+
const fetch = fetches[i];
|
|
152
|
+
const result = results[i];
|
|
153
|
+
if (result.status === 'fulfilled') {
|
|
154
|
+
for (const req of fetch.requests) {
|
|
155
|
+
req.resolve(result.value);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
else {
|
|
159
|
+
for (const req of fetch.requests) {
|
|
160
|
+
req.reject(result.reason);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// =============================================================================
|
|
167
|
+
// Request-scoped DataLoader context
|
|
168
|
+
// =============================================================================
|
|
169
|
+
/** Active DataLoader for the current request context */
|
|
170
|
+
let activeLoader = null;
|
|
171
|
+
/**
|
|
172
|
+
* Create a new request-scoped DataLoader.
|
|
173
|
+
* Call this at the start of each request to enable batching.
|
|
174
|
+
*/
|
|
175
|
+
export function createRequestLoader(provider) {
|
|
176
|
+
const loader = new DataLoader(provider);
|
|
177
|
+
activeLoader = loader;
|
|
178
|
+
return loader;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Get the active request-scoped DataLoader, if any.
|
|
182
|
+
*/
|
|
183
|
+
export function getRequestLoader() {
|
|
184
|
+
return activeLoader;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Clear the active request-scoped DataLoader.
|
|
188
|
+
* Call this at the end of each request.
|
|
189
|
+
*/
|
|
190
|
+
export function clearRequestLoader() {
|
|
191
|
+
if (activeLoader) {
|
|
192
|
+
activeLoader.clear();
|
|
193
|
+
activeLoader = null;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Run a function within a DataLoader context.
|
|
198
|
+
* All provider.get() calls via loadEntity() within the callback
|
|
199
|
+
* will be batched within each microtask tick.
|
|
200
|
+
*/
|
|
201
|
+
export async function withDataLoader(provider, fn) {
|
|
202
|
+
const loader = createRequestLoader(provider);
|
|
203
|
+
try {
|
|
204
|
+
return await fn();
|
|
205
|
+
}
|
|
206
|
+
finally {
|
|
207
|
+
clearRequestLoader();
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Load an entity using the active DataLoader if available,
|
|
212
|
+
* otherwise fall back to direct provider.get().
|
|
213
|
+
*
|
|
214
|
+
* This is the function that should replace direct provider.get() calls
|
|
215
|
+
* in entity resolution (hydrateEntity).
|
|
216
|
+
*/
|
|
217
|
+
export async function loadEntity(provider, type, id) {
|
|
218
|
+
if (activeLoader) {
|
|
219
|
+
return activeLoader.load(type, id);
|
|
220
|
+
}
|
|
221
|
+
// Fallback: direct provider call (no batching)
|
|
222
|
+
const result = await provider.get(type, id);
|
|
223
|
+
return result ?? null;
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=dataloader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataloader.js","sourceRoot":"","sources":["../src/dataloader.ts"],"names":[],"mappings":"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"}
|