@happyvertical/smrt-core 0.40.70 → 0.41.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/AGENTS.md +2 -2
- package/agents/change-feed.md +1 -1
- package/agents/schema-paths.md +487 -29
- package/dist/browser.js +5 -4
- package/dist/cascade.d.ts +120 -0
- package/dist/cascade.d.ts.map +1 -0
- package/dist/cascade.js +430 -0
- package/dist/cascade.js.map +1 -0
- package/dist/change-feed.d.ts +34 -2
- package/dist/change-feed.d.ts.map +1 -1
- package/dist/change-feed.js +52 -11
- package/dist/change-feed.js.map +1 -1
- package/dist/class.d.ts +36 -3
- package/dist/class.d.ts.map +1 -1
- package/dist/class.js +59 -5
- package/dist/class.js.map +1 -1
- package/dist/collection-cache.js +0 -0
- package/dist/collection-cache.js.map +1 -1
- package/dist/collection.d.ts +29 -0
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +66 -14
- package/dist/collection.js.map +1 -1
- package/dist/config.d.ts +10 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/decorators/index.d.ts +63 -5
- package/dist/decorators/index.d.ts.map +1 -1
- package/dist/decorators/index.js +37 -5
- package/dist/decorators/index.js.map +1 -1
- package/dist/dispatch/collections/Dispatches.d.ts.map +1 -1
- package/dist/dispatch/collections/Dispatches.js +19 -4
- package/dist/dispatch/collections/Dispatches.js.map +1 -1
- package/dist/dispatch/types.d.ts +5 -0
- package/dist/dispatch/types.d.ts.map +1 -1
- package/dist/embedded-write-queue.d.ts +46 -0
- package/dist/embedded-write-queue.d.ts.map +1 -0
- package/dist/embedded-write-queue.js +66 -0
- package/dist/embedded-write-queue.js.map +1 -0
- package/dist/embeddings/storage.d.ts +7 -0
- package/dist/embeddings/storage.d.ts.map +1 -1
- package/dist/embeddings/storage.js +29 -12
- package/dist/embeddings/storage.js.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/hierarchical.js +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -6
- package/dist/interceptors.d.ts +21 -0
- package/dist/interceptors.d.ts.map +1 -1
- package/dist/interceptors.js +27 -1
- package/dist/interceptors.js.map +1 -1
- package/dist/manifest/generator.d.ts.map +1 -1
- package/dist/manifest/generator.js +4 -7
- package/dist/manifest/generator.js.map +1 -1
- package/dist/manifest/static-manifest.js +10 -10
- package/dist/manifest/static-manifest.js.map +1 -1
- package/dist/manifest/store.js +1 -1
- package/dist/manifest/store.js.map +1 -1
- package/dist/manifest.json +19 -19
- package/dist/migrations/differ.d.ts +9 -1
- package/dist/migrations/differ.d.ts.map +1 -1
- package/dist/migrations/differ.js +10 -5
- package/dist/migrations/differ.js.map +1 -1
- package/dist/migrations/index.d.ts +1 -0
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/index.js +2 -1
- package/dist/migrations/minor-units.d.ts +162 -0
- package/dist/migrations/minor-units.d.ts.map +1 -0
- package/dist/migrations/minor-units.js +381 -0
- package/dist/migrations/minor-units.js.map +1 -0
- package/dist/migrations.js +2 -1
- package/dist/object.d.ts +98 -5
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +138 -30
- package/dist/object.js.map +1 -1
- package/dist/query-bounds.d.ts +5 -1
- package/dist/query-bounds.d.ts.map +1 -1
- package/dist/query-bounds.js +5 -1
- package/dist/query-bounds.js.map +1 -1
- package/dist/registry/class-registration.d.ts.map +1 -1
- package/dist/registry/class-registration.js +3 -1
- package/dist/registry/class-registration.js.map +1 -1
- package/dist/registry/manifest-field-merge.d.ts +12 -0
- package/dist/registry/manifest-field-merge.d.ts.map +1 -1
- package/dist/registry/manifest-field-merge.js +14 -2
- package/dist/registry/manifest-field-merge.js.map +1 -1
- package/dist/registry/schema-builder.d.ts +22 -1
- package/dist/registry/schema-builder.d.ts.map +1 -1
- package/dist/registry/schema-builder.js +205 -165
- package/dist/registry/schema-builder.js.map +1 -1
- package/dist/registry/types.d.ts +3 -2
- package/dist/registry/types.d.ts.map +1 -1
- package/dist/registry.d.ts +41 -46
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +61 -83
- package/dist/registry.js.map +1 -1
- package/dist/scanner/manifest-generator.d.ts +45 -0
- package/dist/scanner/manifest-generator.d.ts.map +1 -1
- package/dist/scanner/manifest-generator.js +92 -28
- package/dist/scanner/manifest-generator.js.map +1 -1
- package/dist/schema/conflict-target.d.ts +104 -0
- package/dist/schema/conflict-target.d.ts.map +1 -0
- package/dist/schema/conflict-target.js +129 -0
- package/dist/schema/conflict-target.js.map +1 -0
- package/dist/schema/ddl/duckdb-strategy.d.ts.map +1 -1
- package/dist/schema/ddl/duckdb-strategy.js +2 -1
- package/dist/schema/ddl/duckdb-strategy.js.map +1 -1
- package/dist/schema/ddl/postgres-strategy.d.ts.map +1 -1
- package/dist/schema/ddl/postgres-strategy.js +12 -1
- package/dist/schema/ddl/postgres-strategy.js.map +1 -1
- package/dist/schema/generator.d.ts +252 -16
- package/dist/schema/generator.d.ts.map +1 -1
- package/dist/schema/generator.js +411 -106
- package/dist/schema/generator.js.map +1 -1
- package/dist/schema/index-utils.d.ts +120 -0
- package/dist/schema/index-utils.d.ts.map +1 -1
- package/dist/schema/index-utils.js +242 -1
- package/dist/schema/index-utils.js.map +1 -1
- package/dist/schema/index.d.ts +1 -1
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +2 -2
- package/dist/schema/live-parity.d.ts.map +1 -1
- package/dist/schema/live-parity.js +4 -2
- package/dist/schema/live-parity.js.map +1 -1
- package/dist/schema/system-table-shapes.d.ts +13 -0
- package/dist/schema/system-table-shapes.d.ts.map +1 -1
- package/dist/schema/system-table-shapes.js +14 -1
- package/dist/schema/system-table-shapes.js.map +1 -1
- package/dist/schema/utils.d.ts +1 -1
- package/dist/schema/utils.d.ts.map +1 -1
- package/dist/schema/utils.js +3 -3
- package/dist/schema/utils.js.map +1 -1
- package/dist/schema.js +2 -2
- package/dist/smrt-knowledge.json +9 -9
- package/dist/system/compatibility.d.ts +42 -0
- package/dist/system/compatibility.d.ts.map +1 -1
- package/dist/system/compatibility.js +182 -9
- package/dist/system/compatibility.js.map +1 -1
- package/dist/system/index.d.ts +1 -0
- package/dist/system/index.d.ts.map +1 -1
- package/dist/system/index.js +3 -2
- package/dist/system/retention.d.ts +237 -0
- package/dist/system/retention.d.ts.map +1 -0
- package/dist/system/retention.js +497 -0
- package/dist/system/retention.js.map +1 -0
- package/dist/system/schema.d.ts +100 -15
- package/dist/system/schema.d.ts.map +1 -1
- package/dist/system/schema.js +81 -45
- package/dist/system/schema.js.map +1 -1
- package/dist/system/types.d.ts +0 -2
- package/dist/system/types.d.ts.map +1 -1
- package/dist/testing/database.d.ts.map +1 -1
- package/dist/testing/database.js.map +1 -1
- package/dist/vite-plugin/index.d.ts.map +1 -1
- package/dist/vite-plugin/index.js +4 -9
- package/dist/vite-plugin/index.js.map +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-process write serialization for embedded database engines (#2360).
|
|
3
|
+
*
|
|
4
|
+
* File-backed SQLite (libsql) allows one writer at a time and the SDK opens a
|
|
5
|
+
* NEW connection for every null-aware upsert attempt (`transaction("write")`),
|
|
6
|
+
* with no busy timeout on either connection. Any other write on the root
|
|
7
|
+
* connection while such a transaction is open — most commonly the change-feed
|
|
8
|
+
* append that follows every model save — collides as `SQLITE_BUSY`, and under
|
|
9
|
+
* sustained concurrency (a `Promise.all` of creates) the two sides livelock
|
|
10
|
+
* through every retry tier. Before the tenant-led conflict target (#2360) the
|
|
11
|
+
* null-aware path was rare (custom conflict keys with NULL values, #1246);
|
|
12
|
+
* with `tenant_id` leading every tenant-scoped default key, EVERY NULL-tenant
|
|
13
|
+
* (global) create takes it, so the collision became the steady state.
|
|
14
|
+
*
|
|
15
|
+
* The queue makes the process a single writer per database for exactly the
|
|
16
|
+
* two participants of that collision:
|
|
17
|
+
*
|
|
18
|
+
* - a `save()` whose upsert conflict values contain NULL (the only shape the
|
|
19
|
+
* SDK routes through a second-connection transaction), and
|
|
20
|
+
* - the change-feed append (a root-connection write that follows every save).
|
|
21
|
+
*
|
|
22
|
+
* Each hold is a LEAF database call — never an interceptor or hook — so the
|
|
23
|
+
* queue cannot deadlock on nested saves. PostgreSQL is never serialized here:
|
|
24
|
+
* its null-aware upsert already arbitrates through advisory locks
|
|
25
|
+
* server-side, and cross-process writers exist that an in-process queue could
|
|
26
|
+
* not order anyway (which is also why this queue is a mitigation for embedded
|
|
27
|
+
* engines' in-process writers, not a cross-process guarantee — embedded
|
|
28
|
+
* engines have no cross-process writers in supported deployments).
|
|
29
|
+
*/
|
|
30
|
+
interface QueueableDatabase {
|
|
31
|
+
url?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Whether `db` is an embedded engine (SQLite/DuckDB/JSON — anything that is
|
|
35
|
+
* not PostgreSQL). Handles without a URL are treated as embedded: serializing
|
|
36
|
+
* them is at worst a throughput cost, while not serializing an embedded
|
|
37
|
+
* handle reintroduces the livelock.
|
|
38
|
+
*/
|
|
39
|
+
export declare function isEmbeddedDatabase(db: QueueableDatabase): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Run `operation` after every previously queued write on the same database
|
|
42
|
+
* has settled. When `serialize` is false the operation runs immediately.
|
|
43
|
+
*/
|
|
44
|
+
export declare function withEmbeddedWriteQueue<T>(db: QueueableDatabase, serialize: boolean, operation: () => Promise<T>): Promise<T>;
|
|
45
|
+
export {};
|
|
46
|
+
//# sourceMappingURL=embedded-write-queue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedded-write-queue.d.ts","sourceRoot":"","sources":["../src/embedded-write-queue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAMH,UAAU,iBAAiB;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,iBAAiB,GAAG,OAAO,CAEjE;AAMD;;;GAGG;AACH,wBAAsB,sBAAsB,CAAC,CAAC,EAC5C,EAAE,EAAE,iBAAiB,EACrB,SAAS,EAAE,OAAO,EAClB,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAC1B,OAAO,CAAC,CAAC,CAAC,CAoBZ"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
//#region src/embedded-write-queue.ts
|
|
2
|
+
/**
|
|
3
|
+
* In-process write serialization for embedded database engines (#2360).
|
|
4
|
+
*
|
|
5
|
+
* File-backed SQLite (libsql) allows one writer at a time and the SDK opens a
|
|
6
|
+
* NEW connection for every null-aware upsert attempt (`transaction("write")`),
|
|
7
|
+
* with no busy timeout on either connection. Any other write on the root
|
|
8
|
+
* connection while such a transaction is open — most commonly the change-feed
|
|
9
|
+
* append that follows every model save — collides as `SQLITE_BUSY`, and under
|
|
10
|
+
* sustained concurrency (a `Promise.all` of creates) the two sides livelock
|
|
11
|
+
* through every retry tier. Before the tenant-led conflict target (#2360) the
|
|
12
|
+
* null-aware path was rare (custom conflict keys with NULL values, #1246);
|
|
13
|
+
* with `tenant_id` leading every tenant-scoped default key, EVERY NULL-tenant
|
|
14
|
+
* (global) create takes it, so the collision became the steady state.
|
|
15
|
+
*
|
|
16
|
+
* The queue makes the process a single writer per database for exactly the
|
|
17
|
+
* two participants of that collision:
|
|
18
|
+
*
|
|
19
|
+
* - a `save()` whose upsert conflict values contain NULL (the only shape the
|
|
20
|
+
* SDK routes through a second-connection transaction), and
|
|
21
|
+
* - the change-feed append (a root-connection write that follows every save).
|
|
22
|
+
*
|
|
23
|
+
* Each hold is a LEAF database call — never an interceptor or hook — so the
|
|
24
|
+
* queue cannot deadlock on nested saves. PostgreSQL is never serialized here:
|
|
25
|
+
* its null-aware upsert already arbitrates through advisory locks
|
|
26
|
+
* server-side, and cross-process writers exist that an in-process queue could
|
|
27
|
+
* not order anyway (which is also why this queue is a mitigation for embedded
|
|
28
|
+
* engines' in-process writers, not a cross-process guarantee — embedded
|
|
29
|
+
* engines have no cross-process writers in supported deployments).
|
|
30
|
+
*/
|
|
31
|
+
/** Queue tail per database identity (URL string, or the handle itself). */
|
|
32
|
+
var urlQueues = /* @__PURE__ */ new Map();
|
|
33
|
+
var handleQueues = /* @__PURE__ */ new WeakMap();
|
|
34
|
+
/**
|
|
35
|
+
* Whether `db` is an embedded engine (SQLite/DuckDB/JSON — anything that is
|
|
36
|
+
* not PostgreSQL). Handles without a URL are treated as embedded: serializing
|
|
37
|
+
* them is at worst a throughput cost, while not serializing an embedded
|
|
38
|
+
* handle reintroduces the livelock.
|
|
39
|
+
*/
|
|
40
|
+
function isEmbeddedDatabase(db) {
|
|
41
|
+
return !/^postgres(?:ql)?:/iu.test(db?.url ?? "");
|
|
42
|
+
}
|
|
43
|
+
function queueKey(db) {
|
|
44
|
+
return typeof db?.url === "string" && db.url.length > 0 ? db.url : db;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Run `operation` after every previously queued write on the same database
|
|
48
|
+
* has settled. When `serialize` is false the operation runs immediately.
|
|
49
|
+
*/
|
|
50
|
+
async function withEmbeddedWriteQueue(db, serialize, operation) {
|
|
51
|
+
if (!serialize) return operation();
|
|
52
|
+
const key = queueKey(db);
|
|
53
|
+
const next = ((typeof key === "string" ? urlQueues.get(key) : handleQueues.get(key)) ?? Promise.resolve()).then(operation, operation);
|
|
54
|
+
const tail = next.catch(() => void 0);
|
|
55
|
+
if (typeof key === "string") {
|
|
56
|
+
urlQueues.set(key, tail);
|
|
57
|
+
tail.finally(() => {
|
|
58
|
+
if (urlQueues.get(key) === tail) urlQueues.delete(key);
|
|
59
|
+
});
|
|
60
|
+
} else handleQueues.set(key, tail);
|
|
61
|
+
return next;
|
|
62
|
+
}
|
|
63
|
+
//#endregion
|
|
64
|
+
export { isEmbeddedDatabase, withEmbeddedWriteQueue };
|
|
65
|
+
|
|
66
|
+
//# sourceMappingURL=embedded-write-queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedded-write-queue.js","names":[],"sources":["../src/embedded-write-queue.ts"],"sourcesContent":["/**\n * In-process write serialization for embedded database engines (#2360).\n *\n * File-backed SQLite (libsql) allows one writer at a time and the SDK opens a\n * NEW connection for every null-aware upsert attempt (`transaction(\"write\")`),\n * with no busy timeout on either connection. Any other write on the root\n * connection while such a transaction is open — most commonly the change-feed\n * append that follows every model save — collides as `SQLITE_BUSY`, and under\n * sustained concurrency (a `Promise.all` of creates) the two sides livelock\n * through every retry tier. Before the tenant-led conflict target (#2360) the\n * null-aware path was rare (custom conflict keys with NULL values, #1246);\n * with `tenant_id` leading every tenant-scoped default key, EVERY NULL-tenant\n * (global) create takes it, so the collision became the steady state.\n *\n * The queue makes the process a single writer per database for exactly the\n * two participants of that collision:\n *\n * - a `save()` whose upsert conflict values contain NULL (the only shape the\n * SDK routes through a second-connection transaction), and\n * - the change-feed append (a root-connection write that follows every save).\n *\n * Each hold is a LEAF database call — never an interceptor or hook — so the\n * queue cannot deadlock on nested saves. PostgreSQL is never serialized here:\n * its null-aware upsert already arbitrates through advisory locks\n * server-side, and cross-process writers exist that an in-process queue could\n * not order anyway (which is also why this queue is a mitigation for embedded\n * engines' in-process writers, not a cross-process guarantee — embedded\n * engines have no cross-process writers in supported deployments).\n */\n\n/** Queue tail per database identity (URL string, or the handle itself). */\nconst urlQueues = new Map<string, Promise<unknown>>();\nconst handleQueues = new WeakMap<object, Promise<unknown>>();\n\ninterface QueueableDatabase {\n url?: string;\n}\n\n/**\n * Whether `db` is an embedded engine (SQLite/DuckDB/JSON — anything that is\n * not PostgreSQL). Handles without a URL are treated as embedded: serializing\n * them is at worst a throughput cost, while not serializing an embedded\n * handle reintroduces the livelock.\n */\nexport function isEmbeddedDatabase(db: QueueableDatabase): boolean {\n return !/^postgres(?:ql)?:/iu.test(db?.url ?? '');\n}\n\nfunction queueKey(db: QueueableDatabase): string | object {\n return typeof db?.url === 'string' && db.url.length > 0 ? db.url : db;\n}\n\n/**\n * Run `operation` after every previously queued write on the same database\n * has settled. When `serialize` is false the operation runs immediately.\n */\nexport async function withEmbeddedWriteQueue<T>(\n db: QueueableDatabase,\n serialize: boolean,\n operation: () => Promise<T>,\n): Promise<T> {\n if (!serialize) return operation();\n\n const key = queueKey(db);\n const previous =\n (typeof key === 'string' ? urlQueues.get(key) : handleQueues.get(key)) ??\n Promise.resolve();\n const next = previous.then(operation, operation);\n // The stored tail must never reject, or one failed write would poison the\n // queue for every later writer.\n const tail = next.catch(() => undefined);\n if (typeof key === 'string') {\n urlQueues.set(key, tail);\n void tail.finally(() => {\n if (urlQueues.get(key) === tail) urlQueues.delete(key);\n });\n } else {\n handleQueues.set(key, tail);\n }\n return next;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BA,IAAM,4BAAY,IAAI,IAA8B;AACpD,IAAM,+BAAe,IAAI,QAAkC;;;;;;;AAY3D,SAAgB,mBAAmB,IAAgC;CACjE,OAAO,CAAC,sBAAsB,KAAK,IAAI,OAAO,EAAE;AAClD;AAEA,SAAS,SAAS,IAAwC;CACxD,OAAO,OAAO,IAAI,QAAQ,YAAY,GAAG,IAAI,SAAS,IAAI,GAAG,MAAM;AACrE;;;;;AAMA,eAAsB,uBACpB,IACA,WACA,WACY;CACZ,IAAI,CAAC,WAAW,OAAO,UAAU;CAEjC,MAAM,MAAM,SAAS,EAAE;CAIvB,MAAM,SAFH,OAAO,QAAQ,WAAW,UAAU,IAAI,GAAG,IAAI,aAAa,IAAI,GAAG,MACpE,QAAQ,QAAQ,EAAA,CACI,KAAK,WAAW,SAAS;CAG/C,MAAM,OAAO,KAAK,YAAY,KAAA,CAAS;CACvC,IAAI,OAAO,QAAQ,UAAU;EAC3B,UAAU,IAAI,KAAK,IAAI;EACvB,KAAU,cAAc;GACtB,IAAI,UAAU,IAAI,GAAG,MAAM,MAAM,UAAU,OAAO,GAAG;EACvD,CAAC;CACH,OACE,aAAa,IAAI,KAAK,IAAI;CAE5B,OAAO;AACT"}
|
|
@@ -40,6 +40,13 @@ export declare class EmbeddingStorage {
|
|
|
40
40
|
model?: string;
|
|
41
41
|
limit?: number;
|
|
42
42
|
minSimilarity?: number;
|
|
43
|
+
/**
|
|
44
|
+
* Restrict candidates to these object ids BEFORE ranking (#2365).
|
|
45
|
+
* `undefined` means no restriction; an empty array means no candidates
|
|
46
|
+
* (the search returns no results). Used by tenant-scoped collections so
|
|
47
|
+
* top-K never ranks rows the caller is not allowed to see.
|
|
48
|
+
*/
|
|
49
|
+
objectIds?: string[];
|
|
43
50
|
}, vector?: VectorCapabilities): Promise<Array<{
|
|
44
51
|
objectId: string;
|
|
45
52
|
similarity: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/embeddings/storage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/embeddings/storage.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAGhF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAO/C;;GAEG;AACH,qBAAa,gBAAgB;IAC3B;;;;;;OAMG;WACU,MAAM,CACjB,EAAE,EAAE,iBAAiB,EACrB,IAAI,EAAE;QACJ,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,EAAE,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,EACD,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC;IA6ChB;;;;;;;;;;;;;OAaG;WACU,aAAa,CACxB,EAAE,EAAE,iBAAiB,EACrB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EAAE,EACnB,OAAO,GAAE;QACP,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB;;;;;WAKG;QACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;KACjB,EACN,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IA+G3D;;;;;;;OAOG;WACU,mBAAmB,CAC9B,GAAG,EAAE,iBAAiB,EACtB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,IAAI,CAAC;IAShB;;;;;;;;;OASG;WACU,GAAG,CACd,EAAE,EAAE,iBAAiB,EACrB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAclC;;;;;;;OAOG;WACU,YAAY,CACvB,EAAE,EAAE,iBAAiB,EACrB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,eAAe,EAAE,CAAC;IAY7B;;;;;;;;OAQG;WACU,YAAY,CACvB,EAAE,EAAE,iBAAiB,EACrB,WAAW,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,EAClB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,eAAe,EAAE,CAAC;IAqB7B;;;;;;;OAOG;WACU,0BAA0B,CACrC,EAAE,EAAE,iBAAiB,EACrB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,EAAE,CAAC;IAWpB;;;;;;OAMG;WACU,eAAe,CAC1B,EAAE,EAAE,iBAAiB,EACrB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAQhB;;;;;;;;OAQG;WACU,MAAM,CACjB,EAAE,EAAE,iBAAiB,EACrB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC;IAWhB;;;;;OAKG;WACU,WAAW,CAAC,EAAE,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IASjE;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ;CAexB"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { chunkArray } from "../utils/chunk.js";
|
|
1
2
|
import { CosineSimilarity } from "./similarity.js";
|
|
2
3
|
import { createLogger } from "@happyvertical/logger";
|
|
3
4
|
import { randomUUID } from "node:crypto";
|
|
@@ -69,7 +70,8 @@ var EmbeddingStorage = class EmbeddingStorage {
|
|
|
69
70
|
* @returns Array of { objectId, similarity } ranked by similarity (highest first)
|
|
70
71
|
*/
|
|
71
72
|
static async searchSimilar(db, objectClass, embedding, options = {}, vector) {
|
|
72
|
-
const { field, model, limit = 10, minSimilarity = 0 } = options;
|
|
73
|
+
const { field, model, limit = 10, minSimilarity = 0, objectIds } = options;
|
|
74
|
+
if (objectIds !== void 0 && objectIds.length === 0) return [];
|
|
73
75
|
if (vector) try {
|
|
74
76
|
const conditions = ["object_class = $2"];
|
|
75
77
|
const params = [objectClass];
|
|
@@ -81,21 +83,36 @@ var EmbeddingStorage = class EmbeddingStorage {
|
|
|
81
83
|
conditions.push(`model = $${params.length + 2}`);
|
|
82
84
|
params.push(model);
|
|
83
85
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
params
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
86
|
+
const idChunks = objectIds ? chunkArray(objectIds, 900) : [void 0];
|
|
87
|
+
const merged = [];
|
|
88
|
+
for (const chunk of idChunks) {
|
|
89
|
+
const chunkConditions = [...conditions];
|
|
90
|
+
const chunkParams = [...params];
|
|
91
|
+
if (chunk) {
|
|
92
|
+
const placeholders = chunk.map((_, index) => `$${chunkParams.length + 2 + index}`);
|
|
93
|
+
chunkConditions.push(`object_id IN (${placeholders.join(", ")})`);
|
|
94
|
+
chunkParams.push(...chunk);
|
|
95
|
+
}
|
|
96
|
+
const results = await vector.search("_smrt_embeddings", VECTOR_COLUMN, embedding, {
|
|
97
|
+
limit,
|
|
98
|
+
metric: "cosine",
|
|
99
|
+
where: chunkConditions.join(" AND "),
|
|
100
|
+
params: chunkParams
|
|
101
|
+
});
|
|
102
|
+
merged.push(...results.map((r) => ({
|
|
103
|
+
objectId: r.object_id,
|
|
104
|
+
similarity: 1 - r.distance
|
|
105
|
+
})));
|
|
106
|
+
}
|
|
107
|
+
return merged.filter((r) => r.similarity >= minSimilarity).sort((a, b) => b.similarity - a.similarity).slice(0, limit);
|
|
93
108
|
} catch (error) {
|
|
94
109
|
logger.warn(`[embeddings] Native vector search failed, falling back to in-memory: ${error instanceof Error ? error.message : String(error)}`);
|
|
95
110
|
}
|
|
96
111
|
const storedEmbeddings = await EmbeddingStorage.listForClass(db, objectClass, field, model);
|
|
97
|
-
|
|
98
|
-
|
|
112
|
+
const allowedIds = objectIds ? new Set(objectIds) : void 0;
|
|
113
|
+
const candidates = allowedIds ? storedEmbeddings.filter((stored) => allowedIds.has(stored.object_id)) : storedEmbeddings;
|
|
114
|
+
if (candidates.length === 0) return [];
|
|
115
|
+
return candidates.map((stored) => ({
|
|
99
116
|
objectId: stored.object_id,
|
|
100
117
|
similarity: CosineSimilarity.calculate(embedding, stored.embedding)
|
|
101
118
|
})).filter((item) => item.similarity >= minSimilarity).sort((a, b) => b.similarity - a.similarity).slice(0, limit);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.js","names":[],"sources":["../../src/embeddings/storage.ts"],"sourcesContent":["/**\n * Embedding Storage Operations\n *\n * CRUD operations for the _smrt_embeddings system table.\n * Supports both JSON-based and native vector storage strategies.\n */\n\nimport { randomUUID } from 'node:crypto';\nimport { createLogger } from '@happyvertical/logger';\nimport type { DatabaseInterface, VectorCapabilities } from '@happyvertical/sql';\nimport { CosineSimilarity } from './similarity';\nimport type { StoredEmbedding } from './types';\n\nconst logger = createLogger({ level: 'info' });\n\n/** Column name for native vector storage */\nconst VECTOR_COLUMN = 'embedding_vector';\n\n/**\n * Storage operations for embeddings in _smrt_embeddings table\n */\nexport class EmbeddingStorage {\n /**\n * Insert or update an embedding\n *\n * @param db - Database interface\n * @param data - Embedding data to store\n * @param vector - Optional vector capabilities for native storage\n */\n static async upsert(\n db: DatabaseInterface,\n data: {\n objectClass: string;\n objectId: string;\n fieldName: string;\n contentHash: string;\n embedding: number[];\n model: string;\n dimensions: number;\n provider?: string;\n },\n vector?: VectorCapabilities,\n ): Promise<void> {\n const now = new Date().toISOString();\n const id = randomUUID();\n\n await db.upsert(\n '_smrt_embeddings',\n ['object_class', 'object_id', 'field_name', 'model'],\n {\n id,\n object_class: data.objectClass,\n object_id: data.objectId,\n field_name: data.fieldName,\n content_hash: data.contentHash,\n embedding: JSON.stringify(data.embedding),\n model: data.model,\n dimensions: data.dimensions,\n provider: data.provider || null,\n created_at: now,\n updated_at: now,\n },\n );\n\n // Also store native vector if capability is available\n if (vector) {\n try {\n await vector.upsertVector(\n '_smrt_embeddings',\n {\n object_class: data.objectClass,\n object_id: data.objectId,\n field_name: data.fieldName,\n model: data.model,\n },\n VECTOR_COLUMN,\n data.embedding,\n );\n } catch (error) {\n // Log but don't fail — JSON fallback is always available\n logger.warn(\n `[embeddings] Failed to store native vector: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n }\n\n /**\n * Search for similar embeddings using the best available strategy.\n *\n * When vector capabilities are provided, delegates to database-level\n * vector search. Otherwise falls back to loading all embeddings and\n * computing cosine similarity in memory.\n *\n * @param db - Database interface\n * @param objectClass - Class name to search within\n * @param embedding - Query embedding vector\n * @param options - Search options\n * @param vector - Optional vector capabilities for native search\n * @returns Array of { objectId, similarity } ranked by similarity (highest first)\n */\n static async searchSimilar(\n db: DatabaseInterface,\n objectClass: string,\n embedding: number[],\n options: {\n field?: string;\n model?: string;\n limit?: number;\n minSimilarity?: number;\n } = {},\n vector?: VectorCapabilities,\n ): Promise<Array<{ objectId: string; similarity: number }>> {\n const { field, model, limit = 10, minSimilarity = 0 } = options;\n\n // Native vector search path\n if (vector) {\n try {\n // Build WHERE clause for class/field/model filtering.\n // Parameter numbering starts at $2 because vector.search() reserves\n // $1 for the query vector embedding in its internal SQL query.\n const conditions: string[] = ['object_class = $2'];\n const params: unknown[] = [objectClass];\n\n if (field) {\n conditions.push(`field_name = $${params.length + 2}`);\n params.push(field);\n }\n\n if (model) {\n conditions.push(`model = $${params.length + 2}`);\n params.push(model);\n }\n\n const results = await vector.search(\n '_smrt_embeddings',\n VECTOR_COLUMN,\n embedding,\n {\n limit,\n metric: 'cosine',\n where: conditions.join(' AND '),\n params,\n },\n );\n\n // Convert cosine distance (0=identical, 2=opposite) to similarity (1=identical, -1=opposite)\n return results\n .map((r) => ({\n objectId: r.object_id as string,\n similarity: 1 - r.distance,\n }))\n .filter((r) => r.similarity >= minSimilarity);\n } catch (error) {\n // Fall back to in-memory search on vector search failure\n logger.warn(\n `[embeddings] Native vector search failed, falling back to in-memory: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n // In-memory fallback: load all embeddings and compute cosine similarity\n const storedEmbeddings = await EmbeddingStorage.listForClass(\n db,\n objectClass,\n field,\n model,\n );\n\n if (storedEmbeddings.length === 0) {\n return [];\n }\n\n return storedEmbeddings\n .map((stored) => ({\n objectId: stored.object_id,\n similarity: CosineSimilarity.calculate(embedding, stored.embedding),\n }))\n .filter((item) => item.similarity >= minSimilarity)\n .sort((a, b) => b.similarity - a.similarity)\n .slice(0, limit);\n }\n\n /**\n * Ensure the native vector column and index exist on _smrt_embeddings.\n * Called once during initialization when storage: 'native' is configured.\n *\n * @param db - Database interface\n * @param dimensions - Vector dimensions\n * @param vector - Vector capabilities\n */\n static async ensureVectorStorage(\n _db: DatabaseInterface,\n dimensions: number,\n vector: VectorCapabilities,\n ): Promise<void> {\n await vector.ensureColumn('_smrt_embeddings', VECTOR_COLUMN, dimensions);\n await vector.ensureIndex('_smrt_embeddings', VECTOR_COLUMN, {\n dimensions,\n metric: 'cosine',\n type: 'hnsw',\n });\n }\n\n /**\n * Get a specific embedding\n *\n * @param db - Database interface\n * @param objectClass - Class name\n * @param objectId - Object ID\n * @param fieldName - Field name\n * @param model - Model used\n * @returns Stored embedding or null\n */\n static async get(\n db: DatabaseInterface,\n objectClass: string,\n objectId: string,\n fieldName: string,\n model: string,\n ): Promise<StoredEmbedding | null> {\n const result = await db.single`\n SELECT * FROM _smrt_embeddings\n WHERE object_class = ${objectClass}\n AND object_id = ${objectId}\n AND field_name = ${fieldName}\n AND model = ${model}\n `;\n\n if (!result) return null;\n\n return EmbeddingStorage.parseRow(result);\n }\n\n /**\n * Get all embeddings for an object\n *\n * @param db - Database interface\n * @param objectClass - Class name\n * @param objectId - Object ID\n * @returns Array of stored embeddings\n */\n static async getForObject(\n db: DatabaseInterface,\n objectClass: string,\n objectId: string,\n ): Promise<StoredEmbedding[]> {\n const { rows } = await db.query(\n `SELECT * FROM _smrt_embeddings WHERE object_class = ? AND object_id = ?`,\n objectClass,\n objectId,\n );\n\n return rows.map((row: Record<string, unknown>) =>\n EmbeddingStorage.parseRow(row),\n );\n }\n\n /**\n * List embeddings for a class (optionally filtered by field and model)\n *\n * @param db - Database interface\n * @param objectClass - Class name\n * @param fieldName - Optional field filter\n * @param model - Optional model filter\n * @returns Array of stored embeddings\n */\n static async listForClass(\n db: DatabaseInterface,\n objectClass: string,\n fieldName?: string,\n model?: string,\n ): Promise<StoredEmbedding[]> {\n let sql = `SELECT * FROM _smrt_embeddings WHERE object_class = ?`;\n const params: unknown[] = [objectClass];\n\n if (fieldName) {\n sql += ` AND field_name = ?`;\n params.push(fieldName);\n }\n\n if (model) {\n sql += ` AND model = ?`;\n params.push(model);\n }\n\n const { rows } = await db.query(sql, ...params);\n\n return rows.map((row: Record<string, unknown>) =>\n EmbeddingStorage.parseRow(row),\n );\n }\n\n /**\n * Get object IDs that have embeddings for a specific field\n *\n * @param db - Database interface\n * @param objectClass - Class name\n * @param fieldName - Field name\n * @returns Array of object IDs\n */\n static async getObjectIdsWithEmbeddings(\n db: DatabaseInterface,\n objectClass: string,\n fieldName: string,\n ): Promise<string[]> {\n const { rows } = await db.query(\n `SELECT DISTINCT object_id FROM _smrt_embeddings\n WHERE object_class = ? AND field_name = ?`,\n objectClass,\n fieldName,\n );\n\n return rows.map((row: Record<string, unknown>) => row.object_id as string);\n }\n\n /**\n * Delete all embeddings for an object\n *\n * @param db - Database interface\n * @param objectClass - Class name\n * @param objectId - Object ID\n */\n static async deleteForObject(\n db: DatabaseInterface,\n objectClass: string,\n objectId: string,\n ): Promise<void> {\n await db.query(\n `DELETE FROM _smrt_embeddings WHERE object_class = ? AND object_id = ?`,\n objectClass,\n objectId,\n );\n }\n\n /**\n * Delete a specific embedding\n *\n * @param db - Database interface\n * @param objectClass - Class name\n * @param objectId - Object ID\n * @param fieldName - Field name\n * @param model - Model used\n */\n static async delete(\n db: DatabaseInterface,\n objectClass: string,\n objectId: string,\n fieldName: string,\n model: string,\n ): Promise<void> {\n await db.query(\n `DELETE FROM _smrt_embeddings\n WHERE object_class = ? AND object_id = ? AND field_name = ? AND model = ?`,\n objectClass,\n objectId,\n fieldName,\n model,\n );\n }\n\n /**\n * Check if embedding table exists\n *\n * @param db - Database interface\n * @returns True if table exists\n */\n static async tableExists(db: DatabaseInterface): Promise<boolean> {\n try {\n await db.query(`SELECT 1 FROM _smrt_embeddings LIMIT 1`);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Parse a database row into StoredEmbedding\n */\n private static parseRow(row: Record<string, unknown>): StoredEmbedding {\n return {\n id: row.id as string,\n object_class: row.object_class as string,\n object_id: row.object_id as string,\n field_name: row.field_name as string,\n content_hash: row.content_hash as string,\n embedding: JSON.parse(row.embedding as string) as number[],\n model: row.model as string,\n dimensions: row.dimensions as number,\n provider: row.provider as string | undefined,\n created_at: new Date(row.created_at as string),\n updated_at: new Date(row.updated_at as string),\n };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"storage.js","names":[],"sources":["../../src/embeddings/storage.ts"],"sourcesContent":["/**\n * Embedding Storage Operations\n *\n * CRUD operations for the _smrt_embeddings system table.\n * Supports both JSON-based and native vector storage strategies.\n */\n\nimport { randomUUID } from 'node:crypto';\nimport { createLogger } from '@happyvertical/logger';\nimport type { DatabaseInterface, VectorCapabilities } from '@happyvertical/sql';\nimport { chunkArray, IN_LIST_CHUNK_SIZE } from '../utils/chunk';\nimport { CosineSimilarity } from './similarity';\nimport type { StoredEmbedding } from './types';\n\nconst logger = createLogger({ level: 'info' });\n\n/** Column name for native vector storage */\nconst VECTOR_COLUMN = 'embedding_vector';\n\n/**\n * Storage operations for embeddings in _smrt_embeddings table\n */\nexport class EmbeddingStorage {\n /**\n * Insert or update an embedding\n *\n * @param db - Database interface\n * @param data - Embedding data to store\n * @param vector - Optional vector capabilities for native storage\n */\n static async upsert(\n db: DatabaseInterface,\n data: {\n objectClass: string;\n objectId: string;\n fieldName: string;\n contentHash: string;\n embedding: number[];\n model: string;\n dimensions: number;\n provider?: string;\n },\n vector?: VectorCapabilities,\n ): Promise<void> {\n const now = new Date().toISOString();\n const id = randomUUID();\n\n await db.upsert(\n '_smrt_embeddings',\n ['object_class', 'object_id', 'field_name', 'model'],\n {\n id,\n object_class: data.objectClass,\n object_id: data.objectId,\n field_name: data.fieldName,\n content_hash: data.contentHash,\n embedding: JSON.stringify(data.embedding),\n model: data.model,\n dimensions: data.dimensions,\n provider: data.provider || null,\n created_at: now,\n updated_at: now,\n },\n );\n\n // Also store native vector if capability is available\n if (vector) {\n try {\n await vector.upsertVector(\n '_smrt_embeddings',\n {\n object_class: data.objectClass,\n object_id: data.objectId,\n field_name: data.fieldName,\n model: data.model,\n },\n VECTOR_COLUMN,\n data.embedding,\n );\n } catch (error) {\n // Log but don't fail — JSON fallback is always available\n logger.warn(\n `[embeddings] Failed to store native vector: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n }\n\n /**\n * Search for similar embeddings using the best available strategy.\n *\n * When vector capabilities are provided, delegates to database-level\n * vector search. Otherwise falls back to loading all embeddings and\n * computing cosine similarity in memory.\n *\n * @param db - Database interface\n * @param objectClass - Class name to search within\n * @param embedding - Query embedding vector\n * @param options - Search options\n * @param vector - Optional vector capabilities for native search\n * @returns Array of { objectId, similarity } ranked by similarity (highest first)\n */\n static async searchSimilar(\n db: DatabaseInterface,\n objectClass: string,\n embedding: number[],\n options: {\n field?: string;\n model?: string;\n limit?: number;\n minSimilarity?: number;\n /**\n * Restrict candidates to these object ids BEFORE ranking (#2365).\n * `undefined` means no restriction; an empty array means no candidates\n * (the search returns no results). Used by tenant-scoped collections so\n * top-K never ranks rows the caller is not allowed to see.\n */\n objectIds?: string[];\n } = {},\n vector?: VectorCapabilities,\n ): Promise<Array<{ objectId: string; similarity: number }>> {\n const { field, model, limit = 10, minSimilarity = 0, objectIds } = options;\n\n // An explicit empty candidate set means \"nothing is visible\" — never fall\n // through to the unrestricted search.\n if (objectIds !== undefined && objectIds.length === 0) {\n return [];\n }\n\n // Native vector search path\n if (vector) {\n try {\n // Build WHERE clause for class/field/model filtering.\n // Parameter numbering starts at $2 because vector.search() reserves\n // $1 for the query vector embedding in its internal SQL query.\n const conditions: string[] = ['object_class = $2'];\n const params: unknown[] = [objectClass];\n\n if (field) {\n conditions.push(`field_name = $${params.length + 2}`);\n params.push(field);\n }\n\n if (model) {\n conditions.push(`model = $${params.length + 2}`);\n params.push(model);\n }\n\n // Candidate restriction (#2365). The id list is chunked so one query\n // never exceeds the backend's bind-variable limit; per-chunk top-K\n // results merge into an exact global top-K because every chunk\n // returns its own best `limit` candidates.\n const idChunks = objectIds\n ? chunkArray(objectIds, IN_LIST_CHUNK_SIZE)\n : [undefined];\n\n const merged: Array<{ objectId: string; similarity: number }> = [];\n for (const chunk of idChunks) {\n const chunkConditions = [...conditions];\n const chunkParams = [...params];\n if (chunk) {\n const placeholders = chunk.map(\n (_, index) => `$${chunkParams.length + 2 + index}`,\n );\n chunkConditions.push(`object_id IN (${placeholders.join(', ')})`);\n chunkParams.push(...chunk);\n }\n\n const results = await vector.search(\n '_smrt_embeddings',\n VECTOR_COLUMN,\n embedding,\n {\n limit,\n metric: 'cosine',\n where: chunkConditions.join(' AND '),\n params: chunkParams,\n },\n );\n\n // Convert cosine distance (0=identical, 2=opposite) to similarity\n // (1=identical, -1=opposite)\n merged.push(\n ...results.map((r) => ({\n objectId: r.object_id as string,\n similarity: 1 - r.distance,\n })),\n );\n }\n\n return merged\n .filter((r) => r.similarity >= minSimilarity)\n .sort((a, b) => b.similarity - a.similarity)\n .slice(0, limit);\n } catch (error) {\n // Fall back to in-memory search on vector search failure\n logger.warn(\n `[embeddings] Native vector search failed, falling back to in-memory: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n // In-memory fallback: load all embeddings and compute cosine similarity\n const storedEmbeddings = await EmbeddingStorage.listForClass(\n db,\n objectClass,\n field,\n model,\n );\n\n // Candidate restriction (#2365): drop invisible rows BEFORE ranking so\n // top-K is computed only over what the caller may see.\n const allowedIds = objectIds ? new Set(objectIds) : undefined;\n const candidates = allowedIds\n ? storedEmbeddings.filter((stored) => allowedIds.has(stored.object_id))\n : storedEmbeddings;\n\n if (candidates.length === 0) {\n return [];\n }\n\n return candidates\n .map((stored) => ({\n objectId: stored.object_id,\n similarity: CosineSimilarity.calculate(embedding, stored.embedding),\n }))\n .filter((item) => item.similarity >= minSimilarity)\n .sort((a, b) => b.similarity - a.similarity)\n .slice(0, limit);\n }\n\n /**\n * Ensure the native vector column and index exist on _smrt_embeddings.\n * Called once during initialization when storage: 'native' is configured.\n *\n * @param db - Database interface\n * @param dimensions - Vector dimensions\n * @param vector - Vector capabilities\n */\n static async ensureVectorStorage(\n _db: DatabaseInterface,\n dimensions: number,\n vector: VectorCapabilities,\n ): Promise<void> {\n await vector.ensureColumn('_smrt_embeddings', VECTOR_COLUMN, dimensions);\n await vector.ensureIndex('_smrt_embeddings', VECTOR_COLUMN, {\n dimensions,\n metric: 'cosine',\n type: 'hnsw',\n });\n }\n\n /**\n * Get a specific embedding\n *\n * @param db - Database interface\n * @param objectClass - Class name\n * @param objectId - Object ID\n * @param fieldName - Field name\n * @param model - Model used\n * @returns Stored embedding or null\n */\n static async get(\n db: DatabaseInterface,\n objectClass: string,\n objectId: string,\n fieldName: string,\n model: string,\n ): Promise<StoredEmbedding | null> {\n const result = await db.single`\n SELECT * FROM _smrt_embeddings\n WHERE object_class = ${objectClass}\n AND object_id = ${objectId}\n AND field_name = ${fieldName}\n AND model = ${model}\n `;\n\n if (!result) return null;\n\n return EmbeddingStorage.parseRow(result);\n }\n\n /**\n * Get all embeddings for an object\n *\n * @param db - Database interface\n * @param objectClass - Class name\n * @param objectId - Object ID\n * @returns Array of stored embeddings\n */\n static async getForObject(\n db: DatabaseInterface,\n objectClass: string,\n objectId: string,\n ): Promise<StoredEmbedding[]> {\n const { rows } = await db.query(\n `SELECT * FROM _smrt_embeddings WHERE object_class = ? AND object_id = ?`,\n objectClass,\n objectId,\n );\n\n return rows.map((row: Record<string, unknown>) =>\n EmbeddingStorage.parseRow(row),\n );\n }\n\n /**\n * List embeddings for a class (optionally filtered by field and model)\n *\n * @param db - Database interface\n * @param objectClass - Class name\n * @param fieldName - Optional field filter\n * @param model - Optional model filter\n * @returns Array of stored embeddings\n */\n static async listForClass(\n db: DatabaseInterface,\n objectClass: string,\n fieldName?: string,\n model?: string,\n ): Promise<StoredEmbedding[]> {\n let sql = `SELECT * FROM _smrt_embeddings WHERE object_class = ?`;\n const params: unknown[] = [objectClass];\n\n if (fieldName) {\n sql += ` AND field_name = ?`;\n params.push(fieldName);\n }\n\n if (model) {\n sql += ` AND model = ?`;\n params.push(model);\n }\n\n const { rows } = await db.query(sql, ...params);\n\n return rows.map((row: Record<string, unknown>) =>\n EmbeddingStorage.parseRow(row),\n );\n }\n\n /**\n * Get object IDs that have embeddings for a specific field\n *\n * @param db - Database interface\n * @param objectClass - Class name\n * @param fieldName - Field name\n * @returns Array of object IDs\n */\n static async getObjectIdsWithEmbeddings(\n db: DatabaseInterface,\n objectClass: string,\n fieldName: string,\n ): Promise<string[]> {\n const { rows } = await db.query(\n `SELECT DISTINCT object_id FROM _smrt_embeddings\n WHERE object_class = ? AND field_name = ?`,\n objectClass,\n fieldName,\n );\n\n return rows.map((row: Record<string, unknown>) => row.object_id as string);\n }\n\n /**\n * Delete all embeddings for an object\n *\n * @param db - Database interface\n * @param objectClass - Class name\n * @param objectId - Object ID\n */\n static async deleteForObject(\n db: DatabaseInterface,\n objectClass: string,\n objectId: string,\n ): Promise<void> {\n await db.query(\n `DELETE FROM _smrt_embeddings WHERE object_class = ? AND object_id = ?`,\n objectClass,\n objectId,\n );\n }\n\n /**\n * Delete a specific embedding\n *\n * @param db - Database interface\n * @param objectClass - Class name\n * @param objectId - Object ID\n * @param fieldName - Field name\n * @param model - Model used\n */\n static async delete(\n db: DatabaseInterface,\n objectClass: string,\n objectId: string,\n fieldName: string,\n model: string,\n ): Promise<void> {\n await db.query(\n `DELETE FROM _smrt_embeddings\n WHERE object_class = ? AND object_id = ? AND field_name = ? AND model = ?`,\n objectClass,\n objectId,\n fieldName,\n model,\n );\n }\n\n /**\n * Check if embedding table exists\n *\n * @param db - Database interface\n * @returns True if table exists\n */\n static async tableExists(db: DatabaseInterface): Promise<boolean> {\n try {\n await db.query(`SELECT 1 FROM _smrt_embeddings LIMIT 1`);\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * Parse a database row into StoredEmbedding\n */\n private static parseRow(row: Record<string, unknown>): StoredEmbedding {\n return {\n id: row.id as string,\n object_class: row.object_class as string,\n object_id: row.object_id as string,\n field_name: row.field_name as string,\n content_hash: row.content_hash as string,\n embedding: JSON.parse(row.embedding as string) as number[],\n model: row.model as string,\n dimensions: row.dimensions as number,\n provider: row.provider as string | undefined,\n created_at: new Date(row.created_at as string),\n updated_at: new Date(row.updated_at as string),\n };\n }\n}\n"],"mappings":"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"}
|
package/dist/errors.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export declare abstract class SmrtError extends Error {
|
|
|
17
17
|
name: string;
|
|
18
18
|
message: string;
|
|
19
19
|
code: string;
|
|
20
|
-
category: "
|
|
20
|
+
category: "database" | "ai" | "filesystem" | "validation" | "network" | "configuration" | "runtime";
|
|
21
21
|
details: Record<string, unknown> | undefined;
|
|
22
22
|
stack: string | undefined;
|
|
23
23
|
cause: {
|
package/dist/hierarchical.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { chunkArray } from "./utils/chunk.js";
|
|
1
2
|
import { SmrtObject } from "./object.js";
|
|
2
3
|
import { ObjectRegistry } from "./registry.js";
|
|
3
|
-
import { chunkArray } from "./utils/chunk.js";
|
|
4
4
|
//#region src/hierarchical.ts
|
|
5
5
|
var SmrtHierarchical = class SmrtHierarchical extends SmrtObject {
|
|
6
6
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* - MCPGenerator: Create MCP servers for AI model integration
|
|
17
17
|
*/
|
|
18
18
|
export * from './adapters/index';
|
|
19
|
+
export { buildCascadePlan, type CascadePlan, type CascadePolymorphicReference, type CascadeReference, type CascadeRegistryView, type CascadeResult, cascadeReferencesTo, normalizeOnDelete, type OnDeleteAction, runCascadeDelete, } from './cascade';
|
|
19
20
|
export { type AppendChangeInput, appendChange, bumpChangeFeed, CHANGE_FEED_INTERCEPTOR_NAME, CHANGE_FEED_TABLE, type ChangeFeedEntry, type ChangeFeedPage, type ChangeFeedRetention, type ChangeOperation, DEFAULT_CHANGES_LIMIT, ensureChangeFeedTable, type GetChangesOptions, getChangesSince, getTableVersion, getTenantScopedChangesSince, MAX_CHANGES_LIMIT, pruneChangeFeed, registerChangeFeedWriter, resetChangeFeedWarnings, unregisterChangeFeedWriter, } from './change-feed';
|
|
20
21
|
export { CHANGE_SIGNAL_CHANNEL, type ChangeSignal, type ChangeSignalListener, resetChangeSignals, stopChangeSignalListeners, subscribeToChangeSignals, } from './change-signals';
|
|
21
22
|
export { applyOneToManyChildAccessors, childAccessorName, } from './child-accessors';
|
|
@@ -54,7 +55,7 @@ export { smrt as smrtRegistry } from './registry';
|
|
|
54
55
|
export * from './runtime/index';
|
|
55
56
|
export { detectEngine, generateDDLForEngine } from './schema/ddl';
|
|
56
57
|
export { type ConflictTargetInput, checkLiveSchemaParity, type ExpectedTableOrigin, type LiveParityFinding, type LiveParityFindingKind, type LiveParitySeverity, LiveSchemaParityError, type LiveSchemaParityOptions, type LiveSchemaParityReport, } from './schema/live-parity';
|
|
57
|
-
export { getSystemTableShapes, type SystemTableShape, } from './schema/system-table-shapes';
|
|
58
|
+
export { getSystemTableShapes, SYSTEM_TABLE_NAMES, type SystemTableShape, } from './schema/system-table-shapes';
|
|
58
59
|
export type { SchemaDefinition } from './schema/types';
|
|
59
60
|
export * from './signals/index';
|
|
60
61
|
export * from './sync/apply';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,cAAc,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,cAAc,kBAAkB,CAAC;AAEjC,OAAO,EACL,gBAAgB,EAChB,KAAK,WAAW,EAChB,KAAK,2BAA2B,EAChC,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,KAAK,cAAc,EACnB,gBAAgB,GACjB,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,KAAK,iBAAiB,EACtB,YAAY,EACZ,cAAc,EACd,4BAA4B,EAC5B,iBAAiB,EACjB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,KAAK,iBAAiB,EACtB,eAAe,EACf,eAAe,EACf,2BAA2B,EAC3B,iBAAiB,EACjB,eAAe,EACf,wBAAwB,EACxB,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,eAAe,CAAC;AAKvB,OAAO,EACL,qBAAqB,EACrB,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,kBAAkB,EAClB,yBAAyB,EACzB,wBAAwB,GACzB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,4BAA4B,EAC5B,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAE3B,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAE7B,OAAO,EACL,0BAA0B,EAC1B,0BAA0B,EAC1B,KAAK,qBAAqB,EAC1B,+BAA+B,EAC/B,kBAAkB,EAClB,yBAAyB,EACzB,oBAAoB,EACpB,iBAAiB,EACjB,8BAA8B,GAC/B,MAAM,oBAAoB,CAAC;AAC5B,cAAc,wBAAwB,CAAC;AACvC,YAAY,EACV,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,YAAY,GACb,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,OAAO,EACL,KAAK,cAAc,EACnB,mBAAmB,EACnB,KAAK,sBAAsB,EAC3B,eAAe,GAChB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,KAAK,2BAA2B,EAChC,KAAK,iBAAiB,EACtB,yBAAyB,EACzB,4BAA4B,EAC5B,uBAAuB,EACvB,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,kCAAkC,EAClC,KAAK,2BAA2B,EAChC,KAAK,kCAAkC,EACvC,KAAK,6BAA6B,EAClC,gCAAgC,GACjC,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EACL,KAAK,sBAAsB,EAC3B,eAAe,EACf,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,EACL,UAAU,EACV,KAAK,IAAI,EACT,UAAU,EACV,IAAI,EACJ,KAAK,mBAAmB,EACxB,SAAS,EACT,KAAK,wBAAwB,EAC7B,KAAK,gBAAgB,GACtB,MAAM,oBAAoB,CAAC;AAE5B,cAAc,kBAAkB,CAAC;AAEjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,UAAU,CAAC;AAEzB,OAAO,EACL,uBAAuB,EACvB,KAAK,wBAAwB,EAC7B,gCAAgC,GACjC,MAAM,qBAAqB,CAAC;AAE7B,cAAc,oBAAoB,CAAC;AACnC,OAAO,EAAE,KAAK,aAAa,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEtE,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,YAAY,GACb,MAAM,YAAY,CAAC;AACpB,cAAc,aAAa,CAAC;AAG5B,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACnB,sBAAsB,EACtB,oBAAoB,EACpB,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,wBAAwB,EACxB,0BAA0B,GAC3B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,uBAAuB,EACvB,KAAK,eAAe,EACpB,cAAc,EACd,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,GAC5B,MAAM,kBAAkB,CAAC;AAE1B,cAAc,kBAAkB,CAAC;AACjC,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,cAAc,GACf,MAAM,qBAAqB,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,OAAO,EACL,0BAA0B,EAC1B,KAAK,iCAAiC,GACvC,MAAM,2BAA2B,CAAC;AAMnC,OAAO,EACL,4BAA4B,EAC5B,yBAAyB,EACzB,yBAAyB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,uBAAuB,GACxB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,KAAK,gBAAgB,EACrB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,IAAI,IAAI,YAAY,EAAE,MAAM,YAAY,CAAC;AAElD,cAAc,iBAAiB,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAGlE,OAAO,EACL,KAAK,mBAAmB,EACxB,qBAAqB,EACrB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,qBAAqB,EACrB,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,GAC5B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,KAAK,gBAAgB,GACtB,MAAM,8BAA8B,CAAC;AAEtC,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,cAAc,iBAAiB,CAAC;AAGhC,cAAc,cAAc,CAAC;AAE7B,cAAc,gBAAgB,CAAC;AAC/B,YAAY,EACV,iBAAiB,EACjB,aAAa,EACb,kBAAkB,EAClB,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,aAAa,EACb,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,EACL,eAAe,EACf,KAAK,mBAAmB,GACzB,MAAM,oBAAoB,CAAC;AAE5B,cAAc,eAAe,CAAC;AAE9B,OAAO,EACL,KAAK,EACL,cAAc,EACd,OAAO,EACP,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,EACL,KAAK,MAAM,EACX,KAAK,cAAc,EACnB,SAAS,EACT,aAAa,EACb,SAAS,GACV,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,mBAAmB,EACnB,YAAY,EACZ,2BAA2B,EAC3B,aAAa,EACb,eAAe,EACf,MAAM,EACN,KAAK,mBAAmB,EACxB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -3,11 +3,15 @@ import { DEFAULT_AI_COST_RATES, estimateAiUsageCost } from "./adapters/cost-rate
|
|
|
3
3
|
import { MetricsAdapter } from "./adapters/metrics.js";
|
|
4
4
|
import { PubSubAdapter } from "./adapters/pubsub.js";
|
|
5
5
|
import "./adapters/index.js";
|
|
6
|
+
import { classifyDatabaseError, classifyDialectMessage, isAbortedTransactionError, isDeterministicDatabaseError, isNotNullViolationError, isTransientDatabaseError, isUniqueViolationError } from "./db-errors.js";
|
|
7
|
+
import { AIError, ConfigurationError, DatabaseError, ErrorUtils, FilesystemError, NetworkError, RuntimeError, SmrtError, TenantIsolationError, ValidationError, ValidationReport, ValidationUtils } from "./errors.js";
|
|
8
|
+
import { buildCascadePlan, cascadeReferencesTo, normalizeOnDelete, runCascadeDelete } from "./cascade.js";
|
|
6
9
|
import { CACHE_INVALIDATION_CHANNEL, broadcastCacheInvalidation, ensureCacheInvalidationListener, getCacheGeneration, invalidateCollectionCache, resetCollectionCache, resolveDbCacheKey, stopCacheInvalidationListeners } from "./collection-cache.js";
|
|
7
10
|
import { CHANGE_SIGNAL_CHANNEL, resetChangeSignals, stopChangeSignalListeners, subscribeToChangeSignals } from "./change-signals.js";
|
|
8
11
|
import { isTenantScopedClassResolved, resolveDispatchTenantId, resolveDispatchTenantScope, setDispatchTenantResolver, setTenantScopedClassResolver } from "./dispatch/tenant-resolver.js";
|
|
9
|
-
import { GlobalInterceptors, createInterceptorContext } from "./interceptors.js";
|
|
12
|
+
import { GlobalInterceptors, createInterceptorContext, resolveGetStringFilter } from "./interceptors.js";
|
|
10
13
|
import { detectEngine, generateDDLForEngine } from "./schema/ddl/index.js";
|
|
14
|
+
import { SYSTEM_TABLE_NAMES, getSystemTableShapes } from "./schema/system-table-shapes.js";
|
|
11
15
|
import { CHANGE_FEED_INTERCEPTOR_NAME, CHANGE_FEED_TABLE, DEFAULT_CHANGES_LIMIT, MAX_CHANGES_LIMIT, appendChange, bumpChangeFeed, ensureChangeFeedTable, getChangesSince, getTableVersion, getTenantScopedChangesSince, pruneChangeFeed, registerChangeFeedWriter, resetChangeFeedWarnings, unregisterChangeFeedWriter } from "./change-feed.js";
|
|
12
16
|
import { applyOneToManyChildAccessors, childAccessorName } from "./child-accessors.js";
|
|
13
17
|
import { config } from "./config.js";
|
|
@@ -16,13 +20,11 @@ import { createFilesystemAdapter, registerFilesystemAdapterFactory } from "./fil
|
|
|
16
20
|
import { DEFAULT_POSTGRES_TIMEOUTS, POSTGRES_TIMEOUT_ENV_VARS, applyPostgresRuntimeTimeouts, resolvePostgresTimeouts } from "./postgres-timeouts.js";
|
|
17
21
|
import { SignalSanitizer } from "./signals/sanitizer.js";
|
|
18
22
|
import { SignalBus } from "./signals/bus.js";
|
|
19
|
-
import { assertPostgresSystemTimestampsCurrent, ensureDispatchSubscriptionsSystemTableCompatibility, ensureDispatchSystemTableCompatibility, ensureJobEventsSystemTableCompatibility, ensureJobsSystemTableCompatibility, ensureLegacySystemTableCompatibility, getDatabaseEngine, migratePostgresSystemTimestamps, planPostgresSystemTimestampMigrations, tableExists } from "./system/compatibility.js";
|
|
23
|
+
import { assertPostgresSystemTimestampsCurrent, ensureBootstrapSystemTableCompatibility, ensureDeferredSystemTableCompatibility, ensureDispatchSubscriptionsSystemTableCompatibility, ensureDispatchSystemTableCompatibility, ensureJobEventsSystemTableCompatibility, ensureJobsSystemTableCompatibility, ensureLegacySystemTableCompatibility, getDatabaseEngine, migratePostgresSystemTimestamps, planPostgresSystemTimestampMigrations, tableExists } from "./system/compatibility.js";
|
|
20
24
|
import { SmrtClass } from "./class.js";
|
|
21
25
|
import { DEFAULT_EMBEDDING_CONFIG, EmbeddingProvider } from "./embeddings/provider.js";
|
|
22
26
|
import { CosineSimilarity } from "./embeddings/similarity.js";
|
|
23
27
|
import { EmbeddingStorage } from "./embeddings/storage.js";
|
|
24
|
-
import { classifyDatabaseError, classifyDialectMessage, isAbortedTransactionError, isDeterministicDatabaseError, isNotNullViolationError, isTransientDatabaseError, isUniqueViolationError } from "./db-errors.js";
|
|
25
|
-
import { AIError, ConfigurationError, DatabaseError, ErrorUtils, FilesystemError, NetworkError, RuntimeError, SmrtError, TenantIsolationError, ValidationError, ValidationReport, ValidationUtils } from "./errors.js";
|
|
26
28
|
import { DEFAULT_LIST_LIMIT, DEFAULT_LIST_ORDER_BY, MAX_LIST_LIMIT, QueryBoundsError, QueryOrderByError, buildDefaultListOrderBy, resolveListLimit, resolveListOffset } from "./query-bounds.js";
|
|
27
29
|
import { applyPendingDecoratorRegistrations, registerCompatibleFieldDecorator } from "./decorators/compatibility.js";
|
|
28
30
|
import { createQualifiedName, getClassName, getPackageFromQualifiedName, isFromPackage, isQualifiedName, isType, parseQualifiedName, qualifiedNamesEqual } from "./utils/qualified-names.js";
|
|
@@ -72,11 +74,11 @@ import { createSmrtClient } from "./runtime/client.js";
|
|
|
72
74
|
import { SmrtMCPServer, createMCPServer } from "./runtime/mcp.js";
|
|
73
75
|
import { createSmrtServer } from "./runtime/server.js";
|
|
74
76
|
import "./runtime/index.js";
|
|
75
|
-
import { getSystemTableShapes } from "./schema/system-table-shapes.js";
|
|
76
77
|
import { LiveSchemaParityError, checkLiveSchemaParity } from "./schema/live-parity.js";
|
|
77
78
|
import "./signals/index.js";
|
|
79
|
+
import { DEFAULT_RETENTION_POLICY, clearRetentionTasks, getRetentionTasks, pruneAiUsage, pruneExpiredContexts, registerRetentionTask, runRetentionSweep, unregisterRetentionTask } from "./system/retention.js";
|
|
78
80
|
import "./system/index.js";
|
|
79
81
|
import { getTestDatabase } from "./testing/database.js";
|
|
80
82
|
import "./tools/index.js";
|
|
81
83
|
import { smrtPlugin } from "./vite-plugin/index.js";
|
|
82
|
-
export { AIError, APIGenerator, AiUsageCollector, AiUsagePersistenceHandler, CACHE_INVALIDATION_CHANNEL, CHANGE_FEED_INTERCEPTOR_NAME, CHANGE_FEED_TABLE, CHANGE_SIGNAL_CHANNEL, CLIGenerator, ConfigurationError, ContentHasher, CosineSimilarity, DEFAULT_AI_COST_RATES, DEFAULT_CHANGES_LIMIT, DEFAULT_EMBEDDING_CONFIG, DEFAULT_EVENTS_HEARTBEAT_MS, DEFAULT_EVENTS_MAX_SUBSCRIBERS, DEFAULT_EVENTS_RETRY_AFTER_SECONDS, DEFAULT_LEARNING_CONFIG, DEFAULT_LIST_LIMIT, DEFAULT_LIST_ORDER_BY, DEFAULT_POSTGRES_TIMEOUTS, DatabaseError, Dispatch, DispatchBus, DispatchCollection, DispatchSubscription, DispatchSubscriptionCollection, EmbeddingProvider, EmbeddingStorage, ErrorUtils, FilesystemError, GlobalInterceptors, LearningMemory, LiveSchemaParityError, MAX_CHANGES_LIMIT, MAX_LIST_LIMIT, MAX_SYNC_APPLY_BATCH_SIZE, MCPGenerator, MCP_STABLE_CATALOG_TTL_MS, MODULE_DOC_HASH_PREFIX, ManifestBuilder, ManifestGenerator, ManifestManager, MetricsAdapter, NetworkError, ObjectRegistry, POSTGRES_TIMEOUT_ENV_VARS, PRIVATE_READ_CACHE_CONTROL, PubSubAdapter, QueryBoundsError, QueryOrderByError, RuntimeError, SMRT_COLLECTION_BASE_NAMES, SMRT_CUSTOM_ACTION_ERROR_METADATA_KEY, SYNC_APPLY_ROUTE_SEGMENTS, SYNC_APPLY_UUID_PATTERN, SchemaComparer, SignalBus, SignalSanitizer, SmrtClass, SmrtCollection, SmrtError, SmrtHierarchical, SmrtJunction, SmrtMCPServer, SmrtObject, SmrtPolymorphicAssociation, TenantIsolationError, ValidationError, ValidationReport, ValidationUtils, appendChange, applyOneToManyChildAccessors, applyPendingDecoratorRegistrations, applyPostgresRuntimeTimeouts, applySyncWritablePolicy, assertPostgresSystemTimestampsCurrent, broadcastCacheInvalidation, buildChangeEventStream, buildCustomActionInputSchema, buildCustomActionInvocationArgs, buildDefaultListOrderBy, buildDomainKnowledgeManifest, bumpChangeFeed, canonicalReadRepresentation, changeEventSubscribersAtCapacity, checkLiveSchemaParity, childAccessorName, classifyDatabaseError, classifyDialectMessage, clone, computeBodyEtag, computeRuntimeWebManifestHash, computeTableVersionEtag, conditionalJsonResponse, config, convertTypeToJsonSchema, createDispatchBus, createFilesystemAdapter, createInterceptorContext, createMCPServer, createQualifiedName, createRestServer, createSmrtClient, createSmrtServer, crossPackageRef, customActionParameterInputName, detectEngine, discoverManifestEntry, ensureCacheInvalidationListener, ensureChangeFeedTable, ensureDispatchSubscriptionsSystemTableCompatibility, ensureDispatchSystemTableCompatibility, ensureJobEventsSystemTableCompatibility, ensureJobsSystemTableCompatibility, ensureLegacySystemTableCompatibility, estimateAiUsageCost, eventStreamCapacityExceededResponse, executeCollectionReadPlan, executeToolCall, executeToolCalls, field, findManifestEntryByQualifiedName, foreignKey, formatToolResults, generateDDLForEngine, generateOpenAPISpec, generateSchemaDiff, generateToolFromMethod, generateToolManifest, getAdapterInfo, getCLIHandler, getCacheGeneration, getChangesSince, getClassConfigResolvers, getClassName, getConfigResolver, getDatabaseEngine, getManifest, getPackageFromQualifiedName, getSQLFromDiff, getSystemTableShapes, getTableVersion, getTenantScopedChangesSince, getTestDatabase, hasActionableChanges, ifNoneMatchHasConcreteMatch, ifNoneMatchSatisfied, importOptionalDependency, invalidateCollectionCache, isAbortedTransactionError, isAdvisoryOnlyChange, isDatabaseInterface, isDeterministicDatabaseError, isFromPackage, isLazyConfigSentinel, isManualOrAdvisoryChange, isNotNullViolationError, isQualifiedName, isSmrtCollectionExtendsName, isStaleWrite, isTenantScopedClassResolved, isTransientDatabaseError, isType, isUniqueViolationError, isValid, listConfigResolvers, loadExternalManifest, loadExternalManifestSync, loadLocalTestManifestSync, loadManifestFromPathSync, manifest, manyToMany, meta, migratePostgresSystemTimestamps, normalizeCustomActionFailure, normalizeEventsMaxSubscribers, normalizeTypedHttpError, oneToMany, parse, parseQualifiedName, parseSyncApplyBatch, payloadMatchesRow, planPostgresSystemTimestampMigrations, processSyncApplyBatch, pruneChangeFeed, qualifiedNamesEqual, readAgentModuleDocs, registerChangeFeedWriter, registerCompatibleFieldDecorator, registerConfigResolver, registerFilesystemAdapterFactory, registerOptionalDependency, resetChangeFeedWarnings, resetChangeSignals, resetCollectionCache, resetConfigResolvers, resetVerifiedTables, resolveAgentModuleDocPaths, resolveCustomActionMetadata, resolveDatabase, resolveDbCacheKey, resolveDispatchTenantId, resolveDispatchTenantScope, resolveLazyConfig, resolveListLimit, resolveListOffset, resolveMCPToolListCacheHint, resolvePostgresTimeouts, resolveReadCacheControl, resolveTenantEtagDiscriminator, runWithTenantGate, safeParse, safeStringify, setDispatchTenantResolver, setTenantEntryPointRunner, setTenantScopedClassResolver, setupCLI, setupSwaggerUI, shouldIncludeMethod, signalVisibleToTenant, smrt, smrtPlugin, smrt as smrtRegistry, sortMCPTools, startRestServer, staticManifest, stopCacheInvalidationListeners, stopChangeSignalListeners, stringify, subscribeToChangeSignals, tableExists, tryReserveChangeEventSubscriberSlot, unregisterChangeFeedWriter, unregisterConfigResolver, validateSyncApplyItem, validateToolCall, versionConditionalResponse, warnIfSharedCacheNeutralized };
|
|
84
|
+
export { AIError, APIGenerator, AiUsageCollector, AiUsagePersistenceHandler, CACHE_INVALIDATION_CHANNEL, CHANGE_FEED_INTERCEPTOR_NAME, CHANGE_FEED_TABLE, CHANGE_SIGNAL_CHANNEL, CLIGenerator, ConfigurationError, ContentHasher, CosineSimilarity, DEFAULT_AI_COST_RATES, DEFAULT_CHANGES_LIMIT, DEFAULT_EMBEDDING_CONFIG, DEFAULT_EVENTS_HEARTBEAT_MS, DEFAULT_EVENTS_MAX_SUBSCRIBERS, DEFAULT_EVENTS_RETRY_AFTER_SECONDS, DEFAULT_LEARNING_CONFIG, DEFAULT_LIST_LIMIT, DEFAULT_LIST_ORDER_BY, DEFAULT_POSTGRES_TIMEOUTS, DEFAULT_RETENTION_POLICY, DatabaseError, Dispatch, DispatchBus, DispatchCollection, DispatchSubscription, DispatchSubscriptionCollection, EmbeddingProvider, EmbeddingStorage, ErrorUtils, FilesystemError, GlobalInterceptors, LearningMemory, LiveSchemaParityError, MAX_CHANGES_LIMIT, MAX_LIST_LIMIT, MAX_SYNC_APPLY_BATCH_SIZE, MCPGenerator, MCP_STABLE_CATALOG_TTL_MS, MODULE_DOC_HASH_PREFIX, ManifestBuilder, ManifestGenerator, ManifestManager, MetricsAdapter, NetworkError, ObjectRegistry, POSTGRES_TIMEOUT_ENV_VARS, PRIVATE_READ_CACHE_CONTROL, PubSubAdapter, QueryBoundsError, QueryOrderByError, RuntimeError, SMRT_COLLECTION_BASE_NAMES, SMRT_CUSTOM_ACTION_ERROR_METADATA_KEY, SYNC_APPLY_ROUTE_SEGMENTS, SYNC_APPLY_UUID_PATTERN, SYSTEM_TABLE_NAMES, SchemaComparer, SignalBus, SignalSanitizer, SmrtClass, SmrtCollection, SmrtError, SmrtHierarchical, SmrtJunction, SmrtMCPServer, SmrtObject, SmrtPolymorphicAssociation, TenantIsolationError, ValidationError, ValidationReport, ValidationUtils, appendChange, applyOneToManyChildAccessors, applyPendingDecoratorRegistrations, applyPostgresRuntimeTimeouts, applySyncWritablePolicy, assertPostgresSystemTimestampsCurrent, broadcastCacheInvalidation, buildCascadePlan, buildChangeEventStream, buildCustomActionInputSchema, buildCustomActionInvocationArgs, buildDefaultListOrderBy, buildDomainKnowledgeManifest, bumpChangeFeed, canonicalReadRepresentation, cascadeReferencesTo, changeEventSubscribersAtCapacity, checkLiveSchemaParity, childAccessorName, classifyDatabaseError, classifyDialectMessage, clearRetentionTasks, clone, computeBodyEtag, computeRuntimeWebManifestHash, computeTableVersionEtag, conditionalJsonResponse, config, convertTypeToJsonSchema, createDispatchBus, createFilesystemAdapter, createInterceptorContext, createMCPServer, createQualifiedName, createRestServer, createSmrtClient, createSmrtServer, crossPackageRef, customActionParameterInputName, detectEngine, discoverManifestEntry, ensureBootstrapSystemTableCompatibility, ensureCacheInvalidationListener, ensureChangeFeedTable, ensureDeferredSystemTableCompatibility, ensureDispatchSubscriptionsSystemTableCompatibility, ensureDispatchSystemTableCompatibility, ensureJobEventsSystemTableCompatibility, ensureJobsSystemTableCompatibility, ensureLegacySystemTableCompatibility, estimateAiUsageCost, eventStreamCapacityExceededResponse, executeCollectionReadPlan, executeToolCall, executeToolCalls, field, findManifestEntryByQualifiedName, foreignKey, formatToolResults, generateDDLForEngine, generateOpenAPISpec, generateSchemaDiff, generateToolFromMethod, generateToolManifest, getAdapterInfo, getCLIHandler, getCacheGeneration, getChangesSince, getClassConfigResolvers, getClassName, getConfigResolver, getDatabaseEngine, getManifest, getPackageFromQualifiedName, getRetentionTasks, getSQLFromDiff, getSystemTableShapes, getTableVersion, getTenantScopedChangesSince, getTestDatabase, hasActionableChanges, ifNoneMatchHasConcreteMatch, ifNoneMatchSatisfied, importOptionalDependency, invalidateCollectionCache, isAbortedTransactionError, isAdvisoryOnlyChange, isDatabaseInterface, isDeterministicDatabaseError, isFromPackage, isLazyConfigSentinel, isManualOrAdvisoryChange, isNotNullViolationError, isQualifiedName, isSmrtCollectionExtendsName, isStaleWrite, isTenantScopedClassResolved, isTransientDatabaseError, isType, isUniqueViolationError, isValid, listConfigResolvers, loadExternalManifest, loadExternalManifestSync, loadLocalTestManifestSync, loadManifestFromPathSync, manifest, manyToMany, meta, migratePostgresSystemTimestamps, normalizeCustomActionFailure, normalizeEventsMaxSubscribers, normalizeOnDelete, normalizeTypedHttpError, oneToMany, parse, parseQualifiedName, parseSyncApplyBatch, payloadMatchesRow, planPostgresSystemTimestampMigrations, processSyncApplyBatch, pruneAiUsage, pruneChangeFeed, pruneExpiredContexts, qualifiedNamesEqual, readAgentModuleDocs, registerChangeFeedWriter, registerCompatibleFieldDecorator, registerConfigResolver, registerFilesystemAdapterFactory, registerOptionalDependency, registerRetentionTask, resetChangeFeedWarnings, resetChangeSignals, resetCollectionCache, resetConfigResolvers, resetVerifiedTables, resolveAgentModuleDocPaths, resolveCustomActionMetadata, resolveDatabase, resolveDbCacheKey, resolveDispatchTenantId, resolveDispatchTenantScope, resolveGetStringFilter, resolveLazyConfig, resolveListLimit, resolveListOffset, resolveMCPToolListCacheHint, resolvePostgresTimeouts, resolveReadCacheControl, resolveTenantEtagDiscriminator, runCascadeDelete, runRetentionSweep, runWithTenantGate, safeParse, safeStringify, setDispatchTenantResolver, setTenantEntryPointRunner, setTenantScopedClassResolver, setupCLI, setupSwaggerUI, shouldIncludeMethod, signalVisibleToTenant, smrt, smrtPlugin, smrt as smrtRegistry, sortMCPTools, startRestServer, staticManifest, stopCacheInvalidationListeners, stopChangeSignalListeners, stringify, subscribeToChangeSignals, tableExists, tryReserveChangeEventSubscriberSlot, unregisterChangeFeedWriter, unregisterConfigResolver, unregisterRetentionTask, validateSyncApplyItem, validateToolCall, versionConditionalResponse, warnIfSharedCacheNeutralized };
|
package/dist/interceptors.d.ts
CHANGED
|
@@ -244,6 +244,27 @@ export declare class GlobalInterceptors {
|
|
|
244
244
|
*/
|
|
245
245
|
static executeAfterDelete(instance: SmrtObject, context: InterceptorContext): Promise<void>;
|
|
246
246
|
}
|
|
247
|
+
/**
|
|
248
|
+
* Resolve a string filter to the WHERE shape `SmrtCollection.get()` gives it:
|
|
249
|
+
* a UUID string becomes `{ id }`, anything else becomes the natural-key lookup
|
|
250
|
+
* `{ slug, context: '' }`.
|
|
251
|
+
*
|
|
252
|
+
* This is the single source of truth for that string-filter contract. Any
|
|
253
|
+
* `beforeGet` interceptor that rewrites a string filter into an object filter
|
|
254
|
+
* MUST resolve it through this helper first — the tenancy interceptor used to
|
|
255
|
+
* rewrite every string to `{ id: filter, tenantId }`, which broke get-by-slug
|
|
256
|
+
* under an active tenant context (null on SQLite, a uuid cast error on
|
|
257
|
+
* PostgreSQL native-uuid id columns). See #2365.
|
|
258
|
+
*
|
|
259
|
+
* @param filter - The string filter passed to `get()`
|
|
260
|
+
* @returns The object filter `get()` would build for that string
|
|
261
|
+
*/
|
|
262
|
+
export declare function resolveGetStringFilter(filter: string): {
|
|
263
|
+
id: string;
|
|
264
|
+
} | {
|
|
265
|
+
slug: string;
|
|
266
|
+
context: string;
|
|
267
|
+
};
|
|
247
268
|
/**
|
|
248
269
|
* Helper function to create an interceptor context
|
|
249
270
|
* @internal
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interceptors.d.ts","sourceRoot":"","sources":["../src/interceptors.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"interceptors.d.ts","sourceRoot":"","sources":["../src/interceptors.ts"],"names":[],"mappings":"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"}
|
package/dist/interceptors.js
CHANGED
|
@@ -188,6 +188,32 @@ var GlobalInterceptors = class {
|
|
|
188
188
|
}
|
|
189
189
|
};
|
|
190
190
|
/**
|
|
191
|
+
* Canonical UUID shape used by `SmrtCollection.get()` to decide whether a
|
|
192
|
+
* string filter is an id or a slug.
|
|
193
|
+
*/
|
|
194
|
+
var GET_STRING_FILTER_UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
195
|
+
/**
|
|
196
|
+
* Resolve a string filter to the WHERE shape `SmrtCollection.get()` gives it:
|
|
197
|
+
* a UUID string becomes `{ id }`, anything else becomes the natural-key lookup
|
|
198
|
+
* `{ slug, context: '' }`.
|
|
199
|
+
*
|
|
200
|
+
* This is the single source of truth for that string-filter contract. Any
|
|
201
|
+
* `beforeGet` interceptor that rewrites a string filter into an object filter
|
|
202
|
+
* MUST resolve it through this helper first — the tenancy interceptor used to
|
|
203
|
+
* rewrite every string to `{ id: filter, tenantId }`, which broke get-by-slug
|
|
204
|
+
* under an active tenant context (null on SQLite, a uuid cast error on
|
|
205
|
+
* PostgreSQL native-uuid id columns). See #2365.
|
|
206
|
+
*
|
|
207
|
+
* @param filter - The string filter passed to `get()`
|
|
208
|
+
* @returns The object filter `get()` would build for that string
|
|
209
|
+
*/
|
|
210
|
+
function resolveGetStringFilter(filter) {
|
|
211
|
+
return GET_STRING_FILTER_UUID_PATTERN.test(filter) ? { id: filter } : {
|
|
212
|
+
slug: filter,
|
|
213
|
+
context: ""
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
191
217
|
* Helper function to create an interceptor context
|
|
192
218
|
* @internal
|
|
193
219
|
*/
|
|
@@ -201,6 +227,6 @@ function createInterceptorContext(className, operation, collectionName, metadata
|
|
|
201
227
|
};
|
|
202
228
|
}
|
|
203
229
|
//#endregion
|
|
204
|
-
export { GlobalInterceptors, createInterceptorContext };
|
|
230
|
+
export { GlobalInterceptors, createInterceptorContext, resolveGetStringFilter };
|
|
205
231
|
|
|
206
232
|
//# sourceMappingURL=interceptors.js.map
|