@nicia-ai/typegraph 0.28.1 → 0.30.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/dist/backend/postgres/index.cjs +24 -762
- package/dist/backend/postgres/index.cjs.map +1 -1
- package/dist/backend/postgres/index.d.cts +24 -5
- package/dist/backend/postgres/index.d.ts +24 -5
- package/dist/backend/postgres/index.js +11 -753
- package/dist/backend/postgres/index.js.map +1 -1
- package/dist/backend/postgres/pglite.cjs +52 -0
- package/dist/backend/postgres/pglite.cjs.map +1 -0
- package/dist/backend/postgres/pglite.d.cts +116 -0
- package/dist/backend/postgres/pglite.d.ts +116 -0
- package/dist/backend/postgres/pglite.js +50 -0
- package/dist/backend/postgres/pglite.js.map +1 -0
- package/dist/backend/sqlite/index.cjs +23 -27
- package/dist/backend/sqlite/index.d.cts +22 -15
- package/dist/backend/sqlite/index.d.ts +22 -15
- package/dist/backend/sqlite/index.js +10 -10
- package/dist/backend/sqlite/libsql.cjs +18 -14
- package/dist/backend/sqlite/libsql.cjs.map +1 -1
- package/dist/backend/sqlite/libsql.d.cts +3 -3
- package/dist/backend/sqlite/libsql.d.ts +3 -3
- package/dist/backend/sqlite/libsql.js +17 -13
- package/dist/backend/sqlite/libsql.js.map +1 -1
- package/dist/backend/sqlite/local.cjs +19 -17
- package/dist/backend/sqlite/local.cjs.map +1 -1
- package/dist/backend/sqlite/local.d.cts +9 -3
- package/dist/backend/sqlite/local.d.ts +9 -3
- package/dist/backend/sqlite/local.js +17 -15
- package/dist/backend/sqlite/local.js.map +1 -1
- package/dist/chunk-26HWIIVS.cjs +740 -0
- package/dist/chunk-26HWIIVS.cjs.map +1 -0
- package/dist/chunk-2QA5EHEN.js +181 -0
- package/dist/chunk-2QA5EHEN.js.map +1 -0
- package/dist/chunk-3IRMLJEK.js +206 -0
- package/dist/chunk-3IRMLJEK.js.map +1 -0
- package/dist/{chunk-5MTOKWDA.js → chunk-3JLRHQ67.js} +9 -9
- package/dist/{chunk-5MTOKWDA.js.map → chunk-3JLRHQ67.js.map} +1 -1
- package/dist/{chunk-WVQXAFP3.js → chunk-454I6GDF.js} +46 -5
- package/dist/chunk-454I6GDF.js.map +1 -0
- package/dist/{chunk-CTHNVU6K.cjs → chunk-4BXHVEFB.cjs} +16 -16
- package/dist/{chunk-CTHNVU6K.cjs.map → chunk-4BXHVEFB.cjs.map} +1 -1
- package/dist/{chunk-NMOE2ZEU.cjs → chunk-4LBO6KIF.cjs} +139 -128
- package/dist/chunk-4LBO6KIF.cjs.map +1 -0
- package/dist/chunk-633N7DSE.js +258 -0
- package/dist/chunk-633N7DSE.js.map +1 -0
- package/dist/{chunk-WFUN6DCM.cjs → chunk-7JGLPAFV.cjs} +11 -11
- package/dist/chunk-7JGLPAFV.cjs.map +1 -0
- package/dist/{chunk-ZTREJOGB.js → chunk-AI3RNREM.js} +140 -69
- package/dist/chunk-AI3RNREM.js.map +1 -0
- package/dist/{chunk-TSGBRPNE.js → chunk-ENDUY2CD.js} +46 -46
- package/dist/chunk-ENDUY2CD.js.map +1 -0
- package/dist/{chunk-7V335GHG.cjs → chunk-FLRCVI2G.cjs} +12 -2
- package/dist/chunk-FLRCVI2G.cjs.map +1 -0
- package/dist/chunk-FVIGJTS7.js +305 -0
- package/dist/chunk-FVIGJTS7.js.map +1 -0
- package/dist/chunk-FWBVPATK.cjs +208 -0
- package/dist/chunk-FWBVPATK.cjs.map +1 -0
- package/dist/chunk-IE6GN7L3.cjs +319 -0
- package/dist/chunk-IE6GN7L3.cjs.map +1 -0
- package/dist/{chunk-PGU2XKMA.js → chunk-IUIJJYPI.js} +117 -106
- package/dist/chunk-IUIJJYPI.js.map +1 -0
- package/dist/{chunk-E5ROA3MN.js → chunk-IX7RE7CG.js} +3 -3
- package/dist/{chunk-E5ROA3MN.js.map → chunk-IX7RE7CG.js.map} +1 -1
- package/dist/{chunk-YEDQLNVE.cjs → chunk-JIEJCTDS.cjs} +30 -2
- package/dist/chunk-JIEJCTDS.cjs.map +1 -0
- package/dist/{chunk-WZH2MKHW.cjs → chunk-K4N35E7B.cjs} +101 -101
- package/dist/{chunk-WZH2MKHW.cjs.map → chunk-K4N35E7B.cjs.map} +1 -1
- package/dist/{chunk-NZ5PMBTG.js → chunk-K5P5OZXS.js} +12 -3
- package/dist/chunk-K5P5OZXS.js.map +1 -0
- package/dist/chunk-K5VREXMZ.js +738 -0
- package/dist/chunk-K5VREXMZ.js.map +1 -0
- package/dist/chunk-LUHU4T2F.cjs +12 -0
- package/dist/{chunk-4FJVSF3K.cjs.map → chunk-LUHU4T2F.cjs.map} +1 -1
- package/dist/{chunk-O57GYGYK.js → chunk-M6OC455F.js} +32 -18
- package/dist/chunk-M6OC455F.js.map +1 -0
- package/dist/{chunk-OYLF3IC7.js → chunk-MAQJYNJR.js} +4 -4
- package/dist/chunk-MAQJYNJR.js.map +1 -0
- package/dist/{chunk-OOS2RKRH.js → chunk-MXE2U3EX.js} +4 -4
- package/dist/{chunk-OOS2RKRH.js.map → chunk-MXE2U3EX.js.map} +1 -1
- package/dist/{chunk-TKM2WDT4.js → chunk-N2OEOGBB.js} +386 -1093
- package/dist/chunk-N2OEOGBB.js.map +1 -0
- package/dist/{chunk-EJCDOA37.js → chunk-R4JOBEJU.js} +5 -5
- package/dist/{chunk-EJCDOA37.js.map → chunk-R4JOBEJU.js.map} +1 -1
- package/dist/{chunk-FFHW2JEK.cjs → chunk-RP7YITHX.cjs} +32 -17
- package/dist/chunk-RP7YITHX.cjs.map +1 -0
- package/dist/{chunk-PYJOBZR3.cjs → chunk-SGPXKJ4A.cjs} +60 -60
- package/dist/chunk-SGPXKJ4A.cjs.map +1 -0
- package/dist/{chunk-U5ROKVRF.js → chunk-TQOYM4LN.js} +29 -3
- package/dist/chunk-TQOYM4LN.js.map +1 -0
- package/dist/{chunk-PN37HVAV.cjs → chunk-UESTHN47.cjs} +153 -71
- package/dist/chunk-UESTHN47.cjs.map +1 -0
- package/dist/chunk-VFX3LC76.cjs +183 -0
- package/dist/chunk-VFX3LC76.cjs.map +1 -0
- package/dist/chunk-WEMZM7J7.cjs +270 -0
- package/dist/chunk-WEMZM7J7.cjs.map +1 -0
- package/dist/{chunk-NYQFPGYP.cjs → chunk-WFCECD6Q.cjs} +423 -1139
- package/dist/chunk-WFCECD6Q.cjs.map +1 -0
- package/dist/{chunk-EK6RJ373.cjs → chunk-YQGLVWB2.cjs} +7 -7
- package/dist/{chunk-EK6RJ373.cjs.map → chunk-YQGLVWB2.cjs.map} +1 -1
- package/dist/{chunk-X3244EKP.cjs → chunk-ZFWNO3GE.cjs} +48 -4
- package/dist/chunk-ZFWNO3GE.cjs.map +1 -0
- package/dist/ddl-BSFlbGQF.d.cts +38 -0
- package/dist/ddl-EdkIiFVU.d.ts +38 -0
- package/dist/{extension-types-B78CZfA5.d.cts → extension-types-CwHV-Uk4.d.cts} +4 -4
- package/dist/{extension-types-B78CZfA5.d.ts → extension-types-CwHV-Uk4.d.ts} +4 -4
- package/dist/graph-extension/index.cjs +19 -19
- package/dist/graph-extension/index.d.cts +4 -4
- package/dist/graph-extension/index.d.ts +4 -4
- package/dist/graph-extension/index.js +4 -4
- package/dist/{index-CWdBFWbI.d.ts → index-DzeIiMO3.d.ts} +30 -3
- package/dist/{index-Bilw0pYm.d.cts → index-Ln_KHTGA.d.cts} +30 -3
- package/dist/index.cjs +1542 -1011
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +142 -12
- package/dist/index.d.ts +142 -12
- package/dist/index.js +1138 -643
- package/dist/index.js.map +1 -1
- package/dist/indexes/index.cjs +19 -19
- package/dist/indexes/index.d.cts +9 -9
- package/dist/indexes/index.d.ts +9 -9
- package/dist/indexes/index.js +5 -5
- package/dist/interchange/index.cjs +8 -14
- package/dist/interchange/index.cjs.map +1 -1
- package/dist/interchange/index.d.cts +5 -16
- package/dist/interchange/index.d.ts +5 -16
- package/dist/interchange/index.js +3 -9
- package/dist/interchange/index.js.map +1 -1
- package/dist/{manager-ehLTTNq0.d.ts → manager-BbdyNhkv.d.ts} +2 -2
- package/dist/{manager-c1MGaVVR.d.cts → manager-wTDgjoXG.d.cts} +2 -2
- package/dist/{materialize-indexes-DFavFQah.d.ts → materialize-indexes-lkawaDor.d.ts} +1 -1
- package/dist/{materialize-indexes-BQfaAZKA.d.cts → materialize-indexes-oanE3RU0.d.cts} +1 -1
- package/dist/{ddl-0Ooc2dpL.d.ts → postgres-CK2ByP1q.d.cts} +2 -471
- package/dist/{ddl-Dza3kDrI.d.cts → postgres-ymXYC6Rr.d.ts} +2 -471
- package/dist/profiler/index.cjs +10 -10
- package/dist/profiler/index.d.cts +7 -7
- package/dist/profiler/index.d.ts +7 -7
- package/dist/profiler/index.js +3 -3
- package/dist/schema/index.cjs +33 -33
- package/dist/schema/index.d.cts +7 -7
- package/dist/schema/index.d.ts +7 -7
- package/dist/schema/index.js +10 -10
- package/dist/{sqlite-BxZUPbyD.d.ts → sqlite-DxH1lrwD.d.cts} +2 -468
- package/dist/{sqlite-mvpXjEeB.d.cts → sqlite-R8YGOqVQ.d.ts} +2 -468
- package/dist/{store-Ufc1Eoey.d.ts → store--z1Tmk7U.d.cts} +124 -5
- package/dist/{store-D7YEMg2v.d.cts → store-CNKM334w.d.ts} +124 -5
- package/dist/{types-CMQymcwk.d.cts → types-BBiDqJCU.d.ts} +252 -46
- package/dist/{types-B-sJJ4GQ.d.ts → types-CMvxx2kd.d.ts} +2 -2
- package/dist/{types-CmUA9sal.d.cts → types-D5B6Be5c.d.cts} +2 -2
- package/dist/{types-CQ7xXJMP.d.ts → types-dL-clxO3.d.cts} +252 -46
- package/dist/{where-CtrLu1Zf.d.ts → where-CAo6wsBZ.d.ts} +2 -2
- package/dist/{where-5zf15aFZ.d.cts → where-bJjuOCeV.d.cts} +2 -2
- package/package.json +20 -5
- package/dist/chunk-3EUKJEQ3.js +0 -77
- package/dist/chunk-3EUKJEQ3.js.map +0 -1
- package/dist/chunk-4FJVSF3K.cjs +0 -12
- package/dist/chunk-7V335GHG.cjs.map +0 -1
- package/dist/chunk-FFHW2JEK.cjs.map +0 -1
- package/dist/chunk-HTGDWIDE.cjs +0 -89
- package/dist/chunk-HTGDWIDE.cjs.map +0 -1
- package/dist/chunk-LYRUNG6E.cjs +0 -52
- package/dist/chunk-LYRUNG6E.cjs.map +0 -1
- package/dist/chunk-NMOE2ZEU.cjs.map +0 -1
- package/dist/chunk-NYQFPGYP.cjs.map +0 -1
- package/dist/chunk-NZ5PMBTG.js.map +0 -1
- package/dist/chunk-O57GYGYK.js.map +0 -1
- package/dist/chunk-OYLF3IC7.js.map +0 -1
- package/dist/chunk-PCHTTG42.js +0 -47
- package/dist/chunk-PCHTTG42.js.map +0 -1
- package/dist/chunk-PGU2XKMA.js.map +0 -1
- package/dist/chunk-PN37HVAV.cjs.map +0 -1
- package/dist/chunk-PYJOBZR3.cjs.map +0 -1
- package/dist/chunk-TKM2WDT4.js.map +0 -1
- package/dist/chunk-TSGBRPNE.js.map +0 -1
- package/dist/chunk-U5ROKVRF.js.map +0 -1
- package/dist/chunk-WFUN6DCM.cjs.map +0 -1
- package/dist/chunk-WVQXAFP3.js.map +0 -1
- package/dist/chunk-X3244EKP.cjs.map +0 -1
- package/dist/chunk-YEDQLNVE.cjs.map +0 -1
- package/dist/chunk-ZTREJOGB.js.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { N as NodeType,
|
|
2
|
+
import { N as NodeType, d as EdgeType, U as UniquenessScope, C as Collation, D as DeleteBehavior, e as KindAnnotations, f as Cardinality, g as EndpointExistence, T as TemporalMode, G as GraphExtension, I as IndexEntity, K as KindEntity, a as NullCheckOp, A as AnyEdgeType } from './extension-types-CwHV-Uk4.cjs';
|
|
3
3
|
import { SQL } from 'drizzle-orm';
|
|
4
4
|
import { PgDatabase, PgQueryResultHKT } from 'drizzle-orm/pg-core';
|
|
5
5
|
import { BaseSQLiteDatabase } from 'drizzle-orm/sqlite-core';
|
|
@@ -120,8 +120,6 @@ type SqlTableNames = Readonly<{
|
|
|
120
120
|
nodes: string;
|
|
121
121
|
/** Edges table name (default: "typegraph_edges") */
|
|
122
122
|
edges: string;
|
|
123
|
-
/** Node embeddings table name (default: "typegraph_node_embeddings") */
|
|
124
|
-
embeddings: string;
|
|
125
123
|
/** Node fulltext table name (default: "typegraph_node_fulltext") */
|
|
126
124
|
fulltext: string;
|
|
127
125
|
/** Node uniques table name (default: "typegraph_node_uniques") */
|
|
@@ -138,8 +136,6 @@ type SqlSchema = Readonly<{
|
|
|
138
136
|
nodesTable: SQL;
|
|
139
137
|
/** Get a SQL reference to the edges table */
|
|
140
138
|
edgesTable: SQL;
|
|
141
|
-
/** Get a SQL reference to the embeddings table */
|
|
142
|
-
embeddingsTable: SQL;
|
|
143
139
|
/** Get a SQL reference to the fulltext table */
|
|
144
140
|
fulltextTable: SQL;
|
|
145
141
|
}>;
|
|
@@ -162,7 +158,7 @@ type SqlSchema = Readonly<{
|
|
|
162
158
|
* const schema = createSqlSchema({
|
|
163
159
|
* nodes: "myapp_nodes",
|
|
164
160
|
* edges: "myapp_edges",
|
|
165
|
-
*
|
|
161
|
+
* fulltext: "myapp_fulltext",
|
|
166
162
|
* });
|
|
167
163
|
* ```
|
|
168
164
|
*/
|
|
@@ -171,6 +167,27 @@ declare function createSqlSchema(names?: Partial<SqlTableNames>): SqlSchema;
|
|
|
171
167
|
* Default SqlSchema using standard TypeGraph table names.
|
|
172
168
|
*/
|
|
173
169
|
declare const DEFAULT_SQL_SCHEMA: SqlSchema;
|
|
170
|
+
/**
|
|
171
|
+
* The compiler's resolved view of one declared embedding field — the
|
|
172
|
+
* `(dimensions, metric, indexType)` a {@link VectorStrategy} needs to
|
|
173
|
+
* name and scan the field's typed per-`(kind, field)` storage. Sourced
|
|
174
|
+
* from the registered node schema's `embedding()` declaration when the
|
|
175
|
+
* store builds its compile options.
|
|
176
|
+
*/
|
|
177
|
+
type VectorSlotDescriptor = Readonly<{
|
|
178
|
+
dimensions: number;
|
|
179
|
+
metric: VectorMetric;
|
|
180
|
+
indexType: VectorIndexType;
|
|
181
|
+
}>;
|
|
182
|
+
/**
|
|
183
|
+
* Map of declared embedding slots keyed by {@link vectorSlotKey} -
|
|
184
|
+
* `"<nodeKind>\0<fieldPath>"` (NUL-separated). Carries every `(concrete kind,
|
|
185
|
+
* fieldPath)` that declares an embedding field, so the compiler's
|
|
186
|
+
* `field.similarTo(...)` CTE can UNION ALL the per-field tables for the
|
|
187
|
+
* kinds in an alias that actually declare the field (only
|
|
188
|
+
* `includeSubClasses` yields more than one).
|
|
189
|
+
*/
|
|
190
|
+
type VectorSlotMap = ReadonlyMap<string, VectorSlotDescriptor>;
|
|
174
191
|
|
|
175
192
|
/**
|
|
176
193
|
* A single table TypeGraph owns.
|
|
@@ -348,6 +365,181 @@ interface FulltextStrategy {
|
|
|
348
365
|
declare const tsvectorStrategy: FulltextStrategy;
|
|
349
366
|
declare const fts5Strategy: FulltextStrategy;
|
|
350
367
|
|
|
368
|
+
/**
|
|
369
|
+
* Vector Strategy — pluggable storage + SQL generation for a backend's
|
|
370
|
+
* vector stack. The sibling of {@link FulltextStrategy}: a strategy owns
|
|
371
|
+
* every statement that touches its embedding storage — the per-field DDL,
|
|
372
|
+
* upsert, delete, similarity search, and (optional) ANN index lifecycle —
|
|
373
|
+
* plus the capability advertisement and the distance/score expressions the
|
|
374
|
+
* query compiler splices into its relevance CTE.
|
|
375
|
+
*
|
|
376
|
+
* ## Why a strategy, and why per-(kind, field) storage
|
|
377
|
+
*
|
|
378
|
+
* The spike behind #157 established that "real" ANN on every engine we
|
|
379
|
+
* support converges on a
|
|
380
|
+
* **typed, fixed-dimension structure per `(nodeKind, fieldPath)`**:
|
|
381
|
+
*
|
|
382
|
+
* - pgvector: a `vector(N)` column + HNSW/IVFFlat;
|
|
383
|
+
* - libSQL native: an `F32_BLOB(N)` column + `libsql_vector_idx` +
|
|
384
|
+
* `vector_top_k` (a plain `BLOB` or dimensionless `F32_BLOB` is rejected
|
|
385
|
+
* by the index — the dimension must live in the column type);
|
|
386
|
+
* - sqlite-vec: a `vec0(embedding float[N])` virtual table.
|
|
387
|
+
*
|
|
388
|
+
* The legacy single shared `typegraph_node_embeddings` table (one generic
|
|
389
|
+
* column holding mixed-dimension vectors) can only ever be brute-forced;
|
|
390
|
+
* pgvector was the sole engine that hid this, because its index supplies the
|
|
391
|
+
* dimension via a `::vector(N)` cast expression. So storage is the
|
|
392
|
+
* strategy's to own, slot by slot, rather than a fixed global table.
|
|
393
|
+
*
|
|
394
|
+
* Brute force remains a legitimate, capability-advertised mode (libSQL's
|
|
395
|
+
* `vector_distance_cos` over a column with no index, sqlite-vec's
|
|
396
|
+
* `vec_distance_cosine`): a strategy whose `capabilities.indexTypes` is
|
|
397
|
+
* `["none"]` simply never emits an ANN index and `buildSearch` always scans.
|
|
398
|
+
*/
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* The resolved identity of one embedding field's storage in a graph —
|
|
402
|
+
* everything a strategy needs to DDL, address, and index it.
|
|
403
|
+
*
|
|
404
|
+
* Graph-scoped: each `(graphId, nodeKind, fieldPath)` gets its own physical
|
|
405
|
+
* table. TypeGraph supports many graphs per physical database, and the same
|
|
406
|
+
* `(kind, field)` can carry different embedding dimensions across graphs — a
|
|
407
|
+
* shared per-`(kind, field)` table would collide on the fixed column type
|
|
408
|
+
* (`vector(N)` / `F32_BLOB(N)`). Graph-scoping also makes libSQL's
|
|
409
|
+
* table-global `vector_top_k` per-graph-exact (no cross-graph recall bleed).
|
|
410
|
+
*/
|
|
411
|
+
type VectorSlot = Readonly<{
|
|
412
|
+
/** Graph the embedding belongs to — scopes the physical table. */
|
|
413
|
+
graphId: string;
|
|
414
|
+
/** Node kind owning the embedding field (e.g. `"Document"`). */
|
|
415
|
+
nodeKind: string;
|
|
416
|
+
/** Dot-path of the embedding field within the node props (e.g. `"embedding"`). */
|
|
417
|
+
fieldPath: string;
|
|
418
|
+
/** Fixed vector dimension `N` for this field — carried into the column type. */
|
|
419
|
+
dimensions: number;
|
|
420
|
+
/** Distance metric the field's index is built for. */
|
|
421
|
+
metric: VectorMetric;
|
|
422
|
+
/**
|
|
423
|
+
* Index type to materialize. `"none"` means brute-force only (no ANN
|
|
424
|
+
* index emitted); the strategy still stores and searches the field.
|
|
425
|
+
*/
|
|
426
|
+
indexType: VectorIndexType;
|
|
427
|
+
/**
|
|
428
|
+
* Optional ANN index tuning carried into the index DDL (pgvector
|
|
429
|
+
* `m`/`ef_construction`/`lists`). Present on the create-index / re-embed
|
|
430
|
+
* paths (resolved from the field's `embedding()` declaration); omitted on
|
|
431
|
+
* the write/search ensure paths, where the strategy falls back to defaults.
|
|
432
|
+
*/
|
|
433
|
+
indexParams?: Readonly<{
|
|
434
|
+
m?: number;
|
|
435
|
+
efConstruction?: number;
|
|
436
|
+
lists?: number;
|
|
437
|
+
}>;
|
|
438
|
+
}>;
|
|
439
|
+
/**
|
|
440
|
+
* Derives the `VectorCapabilities` a backend advertises from its active
|
|
441
|
+
* strategy, so the two never drift (mirrors `buildFulltextCapabilities`).
|
|
442
|
+
* The strategy is the single source of truth; there are no per-call-site
|
|
443
|
+
* `SQLITE_VECTOR_*` constants.
|
|
444
|
+
*/
|
|
445
|
+
declare function buildVectorCapabilities(strategy: VectorStrategy): VectorCapabilities;
|
|
446
|
+
/**
|
|
447
|
+
* A pluggable vector implementation. Each strategy is self-contained:
|
|
448
|
+
* given a {@link VectorSlot}, it emits every statement the backend and
|
|
449
|
+
* compiler need — per-field storage DDL, writes, similarity search, ANN
|
|
450
|
+
* index lifecycle — and advertises exactly the metrics and index types it
|
|
451
|
+
* can honor. Adding the Nth backend is one of these objects; no core edits.
|
|
452
|
+
*/
|
|
453
|
+
interface VectorStrategy {
|
|
454
|
+
/** Human-readable identifier used in error messages and telemetry. */
|
|
455
|
+
readonly name: string;
|
|
456
|
+
/**
|
|
457
|
+
* The metrics, index types, and dimension ceiling this strategy honors —
|
|
458
|
+
* advertised verbatim as `backend.capabilities.vector`. Asymmetry across
|
|
459
|
+
* engines is legitimate and explicit here (pgvector has `inner_product`;
|
|
460
|
+
* libSQL/sqlite-vec do not), never a silent runtime failure.
|
|
461
|
+
*/
|
|
462
|
+
readonly capabilities: VectorCapabilities;
|
|
463
|
+
/**
|
|
464
|
+
* Deterministic physical table (or virtual-table) name backing a field in
|
|
465
|
+
* a graph. The compiler references this to scan the right per-field storage,
|
|
466
|
+
* and the backend uses it to route upserts/deletes. Must be a stable,
|
|
467
|
+
* collision-safe SQL identifier derived from `(graphId, nodeKind, fieldPath)`.
|
|
468
|
+
*/
|
|
469
|
+
tableName(graphId: string, nodeKind: string, fieldPath: string): string;
|
|
470
|
+
/**
|
|
471
|
+
* The per-field storage this strategy owns for `slot`, as Drizzle-free
|
|
472
|
+
* `StrategyTableContribution`s (resolved `tableName`, deterministic
|
|
473
|
+
* idempotent `createDdl` for the table **and** its ANN index when the
|
|
474
|
+
* slot's `indexType` warrants one, `runtimeEnsure`). Rides the #129/#135
|
|
475
|
+
* table-contribution + durable-materialization machinery exactly as the
|
|
476
|
+
* FTS5 / tsvector virtual tables do — these are materialized per graph by
|
|
477
|
+
* `materializeIndexes()`, not by global `bootstrapTables`.
|
|
478
|
+
*/
|
|
479
|
+
ownedTables(slot: VectorSlot): readonly StrategyTableContribution[];
|
|
480
|
+
/**
|
|
481
|
+
* Emits the statement(s) that upsert a single embedding into the slot's
|
|
482
|
+
* storage. Multiple statements are allowed for engines that cannot upsert
|
|
483
|
+
* a vector in one statement (e.g. a `vec0` virtual table → DELETE+INSERT).
|
|
484
|
+
*/
|
|
485
|
+
buildUpsert(slot: VectorSlot, params: UpsertEmbeddingParams, timestamp: string): readonly SQL[];
|
|
486
|
+
/** Emits the statement(s) that delete a single embedding from the slot. */
|
|
487
|
+
buildDelete(slot: VectorSlot, params: DeleteEmbeddingParams): readonly SQL[];
|
|
488
|
+
/**
|
|
489
|
+
* Raw DDL statement(s) that drop the slot's entire physical storage
|
|
490
|
+
* (table + ANN index, and any engine-managed shadow tables). Used by the
|
|
491
|
+
* destructive `store.reembedVectorField()` path to recreate a field's
|
|
492
|
+
* storage at a new dimension. Returned as raw strings (like
|
|
493
|
+
* `ownedTables(...).createDdl`) for `backend.executeDdl`; must be idempotent
|
|
494
|
+
* (`IF EXISTS`).
|
|
495
|
+
*/
|
|
496
|
+
buildDropStorage(slot: VectorSlot): readonly string[];
|
|
497
|
+
/**
|
|
498
|
+
* Emits the similarity-search query for the `backend.vectorSearch` path,
|
|
499
|
+
* returning rows shaped `{ node_id, score }` ordered best-first. The
|
|
500
|
+
* strategy picks brute-force vs ANN based on whether `slot.indexType`
|
|
501
|
+
* materialized an index — the caller never branches. `score` follows the
|
|
502
|
+
* shared convention (cosine → similarity `1 - distance`; l2 /
|
|
503
|
+
* inner_product → raw distance), so `coerceVectorScore` / fusion stay
|
|
504
|
+
* dialect-neutral.
|
|
505
|
+
*/
|
|
506
|
+
buildSearch(slot: VectorSlot, params: VectorSearchParams): SQL;
|
|
507
|
+
/**
|
|
508
|
+
* The distance expression over the slot's embedding column, used by the
|
|
509
|
+
* **query compiler** to splice vector relevance into its CTE. This is the
|
|
510
|
+
* one genuinely engine-specific fragment (`vec_distance_cosine` vs
|
|
511
|
+
* `<=>` vs `vector_distance_cos`); the surrounding score / minScore /
|
|
512
|
+
* ORDER BY math is shared (see {@link vectorScoreExpression} etc.).
|
|
513
|
+
*
|
|
514
|
+
* `embeddingColumn` is the already-qualified column SQL; `queryEmbedding`
|
|
515
|
+
* is formatted by the strategy into its engine's literal form.
|
|
516
|
+
*/
|
|
517
|
+
distanceExpression(embeddingColumn: SQL, queryEmbedding: readonly number[], metric: VectorMetric): SQL;
|
|
518
|
+
/**
|
|
519
|
+
* Emits the ANN index creation statement for a slot, or `undefined` when
|
|
520
|
+
* indexing is inline (vec0) or unsupported (brute-force-only strategies).
|
|
521
|
+
* Invoked through `backend.createVectorIndex` during `materializeIndexes`.
|
|
522
|
+
*/
|
|
523
|
+
buildCreateIndex?(slot: VectorSlot, options?: Readonly<{
|
|
524
|
+
concurrent?: boolean;
|
|
525
|
+
}>): SQL | undefined;
|
|
526
|
+
/** Emits the ANN index drop statement, or `undefined` when not applicable. */
|
|
527
|
+
buildDropIndex?(slot: VectorSlot): SQL | undefined;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/**
|
|
531
|
+
* SQL Dialect Abstraction Layer
|
|
532
|
+
*
|
|
533
|
+
* Provides a unified interface for dialect-specific SQL generation.
|
|
534
|
+
* Implementing a new dialect (MySQL, SQL Server, etc.) requires
|
|
535
|
+
* implementing this interface.
|
|
536
|
+
*/
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* Supported SQL dialects.
|
|
540
|
+
*/
|
|
541
|
+
type SqlDialect = "sqlite" | "postgres";
|
|
542
|
+
|
|
351
543
|
/**
|
|
352
544
|
* JSON Schema type (subset used by Zod toJSONSchema).
|
|
353
545
|
*
|
|
@@ -541,19 +733,6 @@ type SqliteExecutionProfileHints = Readonly<{
|
|
|
541
733
|
}>;
|
|
542
734
|
type AnySqliteDatabase = BaseSQLiteDatabase<"sync" | "async", unknown>;
|
|
543
735
|
|
|
544
|
-
/**
|
|
545
|
-
* SQL Dialect Abstraction Layer
|
|
546
|
-
*
|
|
547
|
-
* Provides a unified interface for dialect-specific SQL generation.
|
|
548
|
-
* Implementing a new dialect (MySQL, SQL Server, etc.) requires
|
|
549
|
-
* implementing this interface.
|
|
550
|
-
*/
|
|
551
|
-
|
|
552
|
-
/**
|
|
553
|
-
* Supported SQL dialects.
|
|
554
|
-
*/
|
|
555
|
-
type SqlDialect = "sqlite" | "postgres";
|
|
556
|
-
|
|
557
736
|
/**
|
|
558
737
|
* Backend interface types for TypeGraph storage.
|
|
559
738
|
*
|
|
@@ -618,18 +797,10 @@ type FulltextCapabilities = Readonly<{
|
|
|
618
797
|
* Backend capabilities that vary by dialect.
|
|
619
798
|
*/
|
|
620
799
|
type BackendCapabilities = Readonly<{
|
|
621
|
-
/** Whether the backend supports JSONB type (vs TEXT for JSON) */
|
|
622
|
-
jsonb: boolean;
|
|
623
|
-
/** Whether the backend supports partial indexes */
|
|
624
|
-
partialIndexes: boolean;
|
|
625
|
-
/** Whether the backend supports GIN indexes for JSON */
|
|
626
|
-
ginIndexes: boolean;
|
|
627
|
-
/** Whether the backend supports CTE (WITH) queries */
|
|
628
|
-
cte: boolean;
|
|
629
|
-
/** Whether the backend supports RETURNING clause */
|
|
630
|
-
returning: boolean;
|
|
631
800
|
/** Whether the backend supports atomic transactions (D1 does not) */
|
|
632
801
|
transactions: boolean;
|
|
802
|
+
/** Whether the backend supports SQL window functions such as ROW_NUMBER() */
|
|
803
|
+
windowFunctions: boolean;
|
|
633
804
|
/** Vector search capabilities (undefined if not configured) */
|
|
634
805
|
vector?: VectorCapabilities | undefined;
|
|
635
806
|
/** Fulltext search capabilities (undefined if not configured) */
|
|
@@ -691,19 +862,6 @@ type SchemaVersionRow = Readonly<{
|
|
|
691
862
|
created_at: string;
|
|
692
863
|
is_active: boolean;
|
|
693
864
|
}>;
|
|
694
|
-
/**
|
|
695
|
-
* A row from the typegraph_node_embeddings table.
|
|
696
|
-
*/
|
|
697
|
-
type EmbeddingRow = Readonly<{
|
|
698
|
-
graph_id: string;
|
|
699
|
-
node_kind: string;
|
|
700
|
-
node_id: string;
|
|
701
|
-
field_path: string;
|
|
702
|
-
embedding: readonly number[];
|
|
703
|
-
dimensions: number;
|
|
704
|
-
created_at: string;
|
|
705
|
-
updated_at: string;
|
|
706
|
-
}>;
|
|
707
865
|
/**
|
|
708
866
|
* Parameters for inserting a node.
|
|
709
867
|
*/
|
|
@@ -785,6 +943,14 @@ type HardDeleteEdgeParams = Readonly<{
|
|
|
785
943
|
}>;
|
|
786
944
|
/**
|
|
787
945
|
* Parameters for inserting or updating an embedding.
|
|
946
|
+
*
|
|
947
|
+
* `dimensions`, `metric`, and `indexType` together resolve the slot's
|
|
948
|
+
* typed per-`(nodeKind, fieldPath)` storage (the strategy needs the fixed
|
|
949
|
+
* dimension for the column type, and the metric/index type to address the
|
|
950
|
+
* right ANN structure). The store populates them from the schema's
|
|
951
|
+
* `embedding()` declaration via `getEmbeddingDimensions()` /
|
|
952
|
+
* `getEmbeddingIndex()`; the backend constructs a `VectorSlot` from them
|
|
953
|
+
* and stays graph-agnostic.
|
|
788
954
|
*/
|
|
789
955
|
type UpsertEmbeddingParams = Readonly<{
|
|
790
956
|
graphId: string;
|
|
@@ -793,15 +959,29 @@ type UpsertEmbeddingParams = Readonly<{
|
|
|
793
959
|
fieldPath: string;
|
|
794
960
|
embedding: readonly number[];
|
|
795
961
|
dimensions: number;
|
|
962
|
+
metric: VectorMetric;
|
|
963
|
+
indexType: VectorIndexType;
|
|
796
964
|
}>;
|
|
797
965
|
/**
|
|
798
966
|
* Parameters for deleting an embedding.
|
|
967
|
+
*
|
|
968
|
+
* `dimensions` / `metric` / `indexType` mirror {@link UpsertEmbeddingParams}
|
|
969
|
+
* so the backend can resolve the slot's typed per-`(nodeKind, fieldPath)`
|
|
970
|
+
* storage and idempotently ensure it exists before the DELETE. That
|
|
971
|
+
* matters because a delete can run before any embedding was ever written
|
|
972
|
+
* (e.g. a node hard-deleted having never carried one), and on Postgres a
|
|
973
|
+
* DELETE against a missing relation inside a transaction aborts the whole
|
|
974
|
+
* transaction. The store populates them from the schema's `embedding()`
|
|
975
|
+
* declaration, exactly as for upserts.
|
|
799
976
|
*/
|
|
800
977
|
type DeleteEmbeddingParams = Readonly<{
|
|
801
978
|
graphId: string;
|
|
802
979
|
nodeKind: string;
|
|
803
980
|
nodeId: string;
|
|
804
981
|
fieldPath: string;
|
|
982
|
+
dimensions: number;
|
|
983
|
+
metric: VectorMetric;
|
|
984
|
+
indexType: VectorIndexType;
|
|
805
985
|
}>;
|
|
806
986
|
/**
|
|
807
987
|
* Parameters for vector similarity search.
|
|
@@ -812,6 +992,19 @@ type VectorSearchParams = Readonly<{
|
|
|
812
992
|
fieldPath: string;
|
|
813
993
|
queryEmbedding: readonly number[];
|
|
814
994
|
metric: VectorMetric;
|
|
995
|
+
/**
|
|
996
|
+
* Fixed vector dimension `N` for the searched `(nodeKind, fieldPath)`
|
|
997
|
+
* slot. The store populates it from the schema's `embedding()`
|
|
998
|
+
* declaration via `getEmbeddingDimensions()`; the backend uses it to
|
|
999
|
+
* construct the `VectorSlot` whose typed storage the strategy scans.
|
|
1000
|
+
*/
|
|
1001
|
+
dimensions: number;
|
|
1002
|
+
/**
|
|
1003
|
+
* Index type materialized for this slot. `"none"` means brute-force
|
|
1004
|
+
* only; otherwise the strategy may route through its ANN structure.
|
|
1005
|
+
* The store populates it from `getEmbeddingIndex()`.
|
|
1006
|
+
*/
|
|
1007
|
+
indexType: VectorIndexType;
|
|
815
1008
|
limit: number;
|
|
816
1009
|
minScore?: number;
|
|
817
1010
|
/**
|
|
@@ -1170,6 +1363,16 @@ type GraphBackend = Readonly<{
|
|
|
1170
1363
|
* When absent, the dialect's default strategy is used.
|
|
1171
1364
|
*/
|
|
1172
1365
|
fulltextStrategy?: FulltextStrategy | undefined;
|
|
1366
|
+
/**
|
|
1367
|
+
* Optional vector strategy this backend is wired with. The query
|
|
1368
|
+
* compiler reads it (via `compileQuery` options) to emit per-`(kind,
|
|
1369
|
+
* field)` relevance scans for `field.similarTo(...)` predicates, and
|
|
1370
|
+
* the index-materialization / removal paths read its deterministic
|
|
1371
|
+
* `tableName(...)` to address the right physical per-field storage.
|
|
1372
|
+
* `undefined` when the backend has no vector support (e.g. a generic
|
|
1373
|
+
* SQLite backend without sqlite-vec).
|
|
1374
|
+
*/
|
|
1375
|
+
vectorStrategy?: VectorStrategy | undefined;
|
|
1173
1376
|
insertNode: (params: InsertNodeParams) => Promise<NodeRow>;
|
|
1174
1377
|
insertNodeNoReturn?: (params: InsertNodeParams) => Promise<void>;
|
|
1175
1378
|
insertNodesBatch?: (params: readonly InsertNodeParams[]) => Promise<void>;
|
|
@@ -1234,7 +1437,6 @@ type GraphBackend = Readonly<{
|
|
|
1234
1437
|
setActiveVersion: (params: SetActiveVersionParams) => Promise<void>;
|
|
1235
1438
|
upsertEmbedding?: (params: UpsertEmbeddingParams) => Promise<void>;
|
|
1236
1439
|
deleteEmbedding?: (params: DeleteEmbeddingParams) => Promise<void>;
|
|
1237
|
-
getEmbedding?: (graphId: string, nodeKind: string, nodeId: string, fieldPath: string) => Promise<EmbeddingRow | undefined>;
|
|
1238
1440
|
vectorSearch?: (params: VectorSearchParams) => Promise<readonly VectorSearchResult[]>;
|
|
1239
1441
|
createVectorIndex?: (params: CreateVectorIndexParams) => Promise<void>;
|
|
1240
1442
|
dropVectorIndex?: (params: DropVectorIndexParams) => Promise<void>;
|
|
@@ -1879,8 +2081,12 @@ type VectorSimilarityPredicate = Readonly<{
|
|
|
1879
2081
|
field: FieldRef;
|
|
1880
2082
|
/** The query embedding to compare against */
|
|
1881
2083
|
queryEmbedding: readonly number[];
|
|
1882
|
-
/**
|
|
1883
|
-
|
|
2084
|
+
/**
|
|
2085
|
+
* Similarity metric. Omitted when the caller didn't pass one — the compiler
|
|
2086
|
+
* then uses the field's DECLARED `embedding()` metric (resolved per kind),
|
|
2087
|
+
* falling back to "cosine" only when no declaration is available.
|
|
2088
|
+
*/
|
|
2089
|
+
metric?: VectorMetricType;
|
|
1884
2090
|
/** Maximum number of results to return */
|
|
1885
2091
|
limit: number;
|
|
1886
2092
|
/** Optional minimum similarity score (0-1 for cosine) */
|
|
@@ -2398,4 +2604,4 @@ type RelationalIndexDeclaration = NodeIndexDeclaration | EdgeIndexDeclaration;
|
|
|
2398
2604
|
type IndexDeclaration = RelationalIndexDeclaration | VectorIndexDeclaration;
|
|
2399
2605
|
type SystemColumnName = "graph_id" | "kind" | "id" | "from_kind" | "from_id" | "to_kind" | "to_id" | "deleted_at" | "valid_from" | "valid_to" | "created_at" | "updated_at" | "version";
|
|
2400
2606
|
|
|
2401
|
-
export { type
|
|
2607
|
+
export { type FulltextBatchRow as $, type AnySqliteDatabase as A, type BackendCapabilities as B, type VectorIndexMetric as C, type VectorIndexParams as D, type EdgeIndexConfig as E, type FulltextStrategy as F, type GraphBackend as G, type SchemaVersionRow as H, type IndexDeclaration as I, type JsonPointer as J, type InferenceType as K, type AggregateExpr as L, type MetaEdge as M, type NodeIndexConfig as N, type OntologyRelation as O, type FieldRef as P, type QueryAst as Q, type RelationalIndexDeclaration as R, type SqliteExecutionProfileHints as S, type ComparisonOp as T, type AggregateComparisonPredicate as U, type VectorStrategy as V, type AdoptedTransaction as W, type CommitSchemaVersionExpected as X, type CommitSchemaVersionParams as Y, DEFAULT_SQL_SCHEMA as Z, type DeleteFulltextBatchParams as _, type SqliteTransactionMode as a, type FulltextCapabilities as a0, type FulltextQueryMode as a1, type FulltextSearchParams as a2, type FulltextSearchResult as a3, type HybridFusionOptions as a4, type JsonPointerFor as a5, type JsonPointerInput as a6, type JsonPointerSegment as a7, type JsonPointerSegments as a8, type JsonPointerSegmentsFor as a9, type VectorSlotMap as aA, type ValueType as aB, type PredicateExpression as aC, type VectorMetricType as aD, type Traversal as aE, type NodePredicate as aF, type ProjectedField as aG, type GroupBySpec as aH, type RecursiveCyclePolicy as aI, type TraversalDirection as aJ, type EdgeRow as aK, type NodeRow as aL, type SelectiveField as aM, type ComposableQuery as aN, type SetOperationType as aO, type SetOperation as aP, type VectorMetric as aQ, MAX_JSON_POINTER_DEPTH as aa, type MetaEdgeProperties as ab, type OrderSpec as ac, type ParameterRef as ad, type ResolveJsonPointer as ae, type ResolveJsonPointerSegments as af, type SetActiveVersionParams as ag, type SortDirection as ah, type SqlSchema as ai, type SqlTableNames as aj, type StrategyTableContribution as ak, type TableContribution as al, type TransactionBackend as am, type TraversalExpansion as an, type UpsertFulltextBatchParams as ao, type VectorCapabilities as ap, type VectorSlot as aq, buildVectorCapabilities as ar, createSqlSchema as as, fts5Strategy as at, isMetaEdge as au, joinJsonPointers as av, jsonPointer as aw, normalizeJsonPointer as ax, parseJsonPointer as ay, tsvectorStrategy as az, type AnyPgDatabase as b, type EdgeIndexDeclaration as c, type NodeIndexDeclaration as d, type IndexWhereExpression as e, type SerializedNodeDef as f, type SerializedEdgeDef as g, type SerializedMetaEdge as h, type SerializedOntologyRelation as i, type SerializedClosures as j, type SerializedSchema as k, type SchemaHash as l, type JsonSchema as m, type SerializedOntology as n, type SerializedUniqueConstraint as o, type SqlDialect as p, type EdgeIndexDirection as q, type EdgeIndexWhereBuilder as r, type IndexOrigin as s, type IndexScope as t, type IndexWhereFieldBuilder as u, type IndexWhereInput as v, type NodeIndexWhereBuilder as w, type SystemColumnName as x, type VectorIndexDeclaration as y, type VectorIndexImplementation as z };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as AnyEdgeType, N as NodeType } from './extension-types-
|
|
2
|
-
import { E as EdgeIndexConfig, c as EdgeIndexDeclaration, N as NodeIndexConfig, d as NodeIndexDeclaration, e as IndexWhereExpression } from './types-
|
|
1
|
+
import { A as AnyEdgeType, N as NodeType } from './extension-types-CwHV-Uk4.js';
|
|
2
|
+
import { E as EdgeIndexConfig, c as EdgeIndexDeclaration, N as NodeIndexConfig, d as NodeIndexDeclaration, e as IndexWhereExpression } from './types-BBiDqJCU.js';
|
|
3
3
|
|
|
4
4
|
declare function defineNodeIndex<N extends NodeType>(node: N, config: NodeIndexConfig<N>): NodeIndexDeclaration;
|
|
5
5
|
declare function defineEdgeIndex<E extends AnyEdgeType>(edge: E, config: EdgeIndexConfig<E>): EdgeIndexDeclaration;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as AnyEdgeType, N as NodeType } from './extension-types-
|
|
2
|
-
import { E as EdgeIndexConfig, c as EdgeIndexDeclaration, N as NodeIndexConfig, d as NodeIndexDeclaration, e as IndexWhereExpression } from './types-
|
|
1
|
+
import { A as AnyEdgeType, N as NodeType } from './extension-types-CwHV-Uk4.cjs';
|
|
2
|
+
import { E as EdgeIndexConfig, c as EdgeIndexDeclaration, N as NodeIndexConfig, d as NodeIndexDeclaration, e as IndexWhereExpression } from './types-dL-clxO3.cjs';
|
|
3
3
|
|
|
4
4
|
declare function defineNodeIndex<N extends NodeType>(node: N, config: NodeIndexConfig<N>): NodeIndexDeclaration;
|
|
5
5
|
declare function defineEdgeIndex<E extends AnyEdgeType>(edge: E, config: EdgeIndexConfig<E>): EdgeIndexDeclaration;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nicia-ai/typegraph",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.30.0",
|
|
4
4
|
"description": "TypeScript-first embedded knowledge graph library with ontological reasoning",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -47,6 +47,11 @@
|
|
|
47
47
|
"import": "./dist/backend/postgres/index.js",
|
|
48
48
|
"require": "./dist/backend/postgres/index.cjs"
|
|
49
49
|
},
|
|
50
|
+
"./postgres/pglite": {
|
|
51
|
+
"types": "./dist/backend/postgres/pglite.d.ts",
|
|
52
|
+
"import": "./dist/backend/postgres/pglite.js",
|
|
53
|
+
"require": "./dist/backend/postgres/pglite.cjs"
|
|
54
|
+
},
|
|
50
55
|
"./sqlite/local": {
|
|
51
56
|
"types": "./dist/backend/sqlite/local.d.ts",
|
|
52
57
|
"import": "./dist/backend/sqlite/local.js",
|
|
@@ -92,6 +97,8 @@
|
|
|
92
97
|
"node": ">=22"
|
|
93
98
|
},
|
|
94
99
|
"peerDependencies": {
|
|
100
|
+
"@electric-sql/pglite": ">=0.5.0 <0.6.0",
|
|
101
|
+
"@electric-sql/pglite-pgvector": ">=0.0.2 <1.0.0",
|
|
95
102
|
"@libsql/client": ">=0.6.0",
|
|
96
103
|
"@neondatabase/serverless": ">=0.9.0 <2.0.0",
|
|
97
104
|
"better-sqlite3": ">=9.0.0 <13.0.0",
|
|
@@ -101,6 +108,12 @@
|
|
|
101
108
|
"zod": "^4.0.0"
|
|
102
109
|
},
|
|
103
110
|
"peerDependenciesMeta": {
|
|
111
|
+
"@electric-sql/pglite": {
|
|
112
|
+
"optional": true
|
|
113
|
+
},
|
|
114
|
+
"@electric-sql/pglite-pgvector": {
|
|
115
|
+
"optional": true
|
|
116
|
+
},
|
|
104
117
|
"@libsql/client": {
|
|
105
118
|
"optional": true
|
|
106
119
|
},
|
|
@@ -121,7 +134,9 @@
|
|
|
121
134
|
"nanoid": "^5.1.11"
|
|
122
135
|
},
|
|
123
136
|
"devDependencies": {
|
|
124
|
-
"@cloudflare/vitest-pool-workers": "^0.16.
|
|
137
|
+
"@cloudflare/vitest-pool-workers": "^0.16.12",
|
|
138
|
+
"@electric-sql/pglite": "^0.5.1",
|
|
139
|
+
"@electric-sql/pglite-pgvector": "^0.0.2",
|
|
125
140
|
"@libsql/client": "^0.17.3",
|
|
126
141
|
"@neondatabase/serverless": "^1.1.0",
|
|
127
142
|
"@stryker-mutator/core": "^9.6.1",
|
|
@@ -129,10 +144,10 @@
|
|
|
129
144
|
"@types/better-sqlite3": "^7.6.13",
|
|
130
145
|
"@types/node": "^24.12.0",
|
|
131
146
|
"@types/pg": "^8.20.0",
|
|
132
|
-
"@vitest/coverage-v8": "^4.1.
|
|
147
|
+
"@vitest/coverage-v8": "^4.1.8",
|
|
133
148
|
"better-sqlite3": "^12.10.0",
|
|
134
149
|
"drizzle-orm": "^0.45.2",
|
|
135
|
-
"eslint": "^10.4.
|
|
150
|
+
"eslint": "^10.4.1",
|
|
136
151
|
"fast-check": "^4.8.0",
|
|
137
152
|
"pg": "^8.21.0",
|
|
138
153
|
"postgres": "^3.4.9",
|
|
@@ -140,7 +155,7 @@
|
|
|
140
155
|
"tsd": "^0.33.0",
|
|
141
156
|
"tsup": "^8.5.1",
|
|
142
157
|
"typescript": "^5.9.3",
|
|
143
|
-
"vitest": "^4.1.
|
|
158
|
+
"vitest": "^4.1.8",
|
|
144
159
|
"zod": "^4.4.3",
|
|
145
160
|
"@typegraph/eslint-config": "0.1.0"
|
|
146
161
|
},
|
package/dist/chunk-3EUKJEQ3.js
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { sql } from 'drizzle-orm';
|
|
2
|
-
|
|
3
|
-
// src/query/compiler/utils.ts
|
|
4
|
-
var NODE_COLUMNS = [
|
|
5
|
-
"id",
|
|
6
|
-
"kind",
|
|
7
|
-
"props",
|
|
8
|
-
"version",
|
|
9
|
-
"valid_from",
|
|
10
|
-
"valid_to",
|
|
11
|
-
"created_at",
|
|
12
|
-
"updated_at",
|
|
13
|
-
"deleted_at"
|
|
14
|
-
];
|
|
15
|
-
var EDGE_COLUMNS = [
|
|
16
|
-
"id",
|
|
17
|
-
"kind",
|
|
18
|
-
"from_id",
|
|
19
|
-
"to_id",
|
|
20
|
-
"props",
|
|
21
|
-
"valid_from",
|
|
22
|
-
"valid_to",
|
|
23
|
-
"created_at",
|
|
24
|
-
"updated_at",
|
|
25
|
-
"deleted_at"
|
|
26
|
-
];
|
|
27
|
-
var EMPTY_REQUIRED_COLUMNS = /* @__PURE__ */ new Set();
|
|
28
|
-
function quoteIdentifier(identifier) {
|
|
29
|
-
return sql.raw(`"${identifier.replaceAll('"', '""')}"`);
|
|
30
|
-
}
|
|
31
|
-
function shouldProjectColumn(requiredColumns, column, alwaysRequiredColumns) {
|
|
32
|
-
if (alwaysRequiredColumns?.has(column)) return true;
|
|
33
|
-
if (requiredColumns === void 0) return true;
|
|
34
|
-
return requiredColumns.has(column);
|
|
35
|
-
}
|
|
36
|
-
function addRequiredColumn(requiredColumnsByAlias, alias, column) {
|
|
37
|
-
const existing = requiredColumnsByAlias.get(alias);
|
|
38
|
-
if (existing) {
|
|
39
|
-
existing.add(column);
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
requiredColumnsByAlias.set(alias, /* @__PURE__ */ new Set([column]));
|
|
43
|
-
}
|
|
44
|
-
function markFieldRefAsRequired(requiredColumnsByAlias, field) {
|
|
45
|
-
const column = field.path[0];
|
|
46
|
-
if (column === void 0) return;
|
|
47
|
-
addRequiredColumn(requiredColumnsByAlias, field.alias, column);
|
|
48
|
-
}
|
|
49
|
-
function mapSelectiveSystemFieldToColumn(field) {
|
|
50
|
-
if (field === "fromId") return "from_id";
|
|
51
|
-
if (field === "toId") return "to_id";
|
|
52
|
-
if (field.startsWith("meta.")) {
|
|
53
|
-
return field.slice(5).replaceAll(/([A-Z])/g, "_$1").toLowerCase();
|
|
54
|
-
}
|
|
55
|
-
return field;
|
|
56
|
-
}
|
|
57
|
-
function markSelectiveFieldAsRequired(requiredColumnsByAlias, field) {
|
|
58
|
-
if (field.isSystemField) {
|
|
59
|
-
addRequiredColumn(
|
|
60
|
-
requiredColumnsByAlias,
|
|
61
|
-
field.alias,
|
|
62
|
-
mapSelectiveSystemFieldToColumn(field.field)
|
|
63
|
-
);
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
addRequiredColumn(requiredColumnsByAlias, field.alias, "props");
|
|
67
|
-
}
|
|
68
|
-
function isIdFieldRef(field) {
|
|
69
|
-
return field.path.length === 1 && field.path[0] === "id" && field.jsonPointer === void 0;
|
|
70
|
-
}
|
|
71
|
-
function isAggregateExpr(source) {
|
|
72
|
-
return "__type" in source && source.__type === "aggregate";
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export { EDGE_COLUMNS, EMPTY_REQUIRED_COLUMNS, NODE_COLUMNS, addRequiredColumn, isAggregateExpr, isIdFieldRef, mapSelectiveSystemFieldToColumn, markFieldRefAsRequired, markSelectiveFieldAsRequired, quoteIdentifier, shouldProjectColumn };
|
|
76
|
-
//# sourceMappingURL=chunk-3EUKJEQ3.js.map
|
|
77
|
-
//# sourceMappingURL=chunk-3EUKJEQ3.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/query/compiler/utils.ts"],"names":[],"mappings":";;;AAaO,IAAM,YAAA,GAAe;AAAA,EAC1B,IAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,SAAA;AAAA,EACA,YAAA;AAAA,EACA,UAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA;AACF;AAEO,IAAM,YAAA,GAAe;AAAA,EAC1B,IAAA;AAAA,EACA,MAAA;AAAA,EACA,SAAA;AAAA,EACA,OAAA;AAAA,EACA,OAAA;AAAA,EACA,YAAA;AAAA,EACA,UAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA;AACF;AAGO,IAAM,sBAAA,uBAA6B,GAAA;AAMnC,SAAS,gBAAgB,UAAA,EAAyB;AACvD,EAAA,OAAO,GAAA,CAAI,IAAI,CAAA,CAAA,EAAI,UAAA,CAAW,WAAW,GAAA,EAAK,IAAI,CAAC,CAAA,CAAA,CAAG,CAAA;AACxD;AAcO,SAAS,mBAAA,CACd,eAAA,EACA,MAAA,EACA,qBAAA,EACS;AACT,EAAA,IAAI,qBAAA,EAAuB,GAAA,CAAI,MAAM,CAAA,EAAG,OAAO,IAAA;AAC/C,EAAA,IAAI,eAAA,KAAoB,QAAW,OAAO,IAAA;AAC1C,EAAA,OAAO,eAAA,CAAgB,IAAI,MAAM,CAAA;AACnC;AAMO,SAAS,iBAAA,CACd,sBAAA,EACA,KAAA,EACA,MAAA,EACM;AACN,EAAA,MAAM,QAAA,GAAW,sBAAA,CAAuB,GAAA,CAAI,KAAK,CAAA;AACjD,EAAA,IAAI,QAAA,EAAU;AACZ,IAAA,QAAA,CAAS,IAAI,MAAM,CAAA;AACnB,IAAA;AAAA,EACF;AACA,EAAA,sBAAA,CAAuB,IAAI,KAAA,kBAAO,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;AACrD;AAEO,SAAS,sBAAA,CACd,wBACA,KAAA,EACM;AACN,EAAA,MAAM,MAAA,GAAS,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA;AAC3B,EAAA,IAAI,WAAW,MAAA,EAAW;AAC1B,EAAA,iBAAA,CAAkB,sBAAA,EAAwB,KAAA,CAAM,KAAA,EAAO,MAAM,CAAA;AAC/D;AAEO,SAAS,gCAAgC,KAAA,EAAuB;AACrE,EAAA,IAAI,KAAA,KAAU,UAAU,OAAO,SAAA;AAC/B,EAAA,IAAI,KAAA,KAAU,QAAQ,OAAO,OAAA;AAC7B,EAAA,IAAI,KAAA,CAAM,UAAA,CAAW,OAAO,CAAA,EAAG;AAC7B,IAAA,OAAO,KAAA,CACJ,MAAM,CAAC,CAAA,CACP,WAAW,UAAA,EAAY,KAAK,EAC5B,WAAA,EAAY;AAAA,EACjB;AACA,EAAA,OAAO,KAAA;AACT;AAEO,SAAS,4BAAA,CACd,wBACA,KAAA,EACM;AACN,EAAA,IAAI,MAAM,aAAA,EAAe;AACvB,IAAA,iBAAA;AAAA,MACE,sBAAA;AAAA,MACA,KAAA,CAAM,KAAA;AAAA,MACN,+BAAA,CAAgC,MAAM,KAAK;AAAA,KAC7C;AACA,IAAA;AAAA,EACF;AACA,EAAA,iBAAA,CAAkB,sBAAA,EAAwB,KAAA,CAAM,KAAA,EAAO,OAAO,CAAA;AAChE;AAMO,SAAS,aAAa,KAAA,EAA0B;AACrD,EAAA,OACE,KAAA,CAAM,IAAA,CAAK,MAAA,KAAW,CAAA,IACtB,KAAA,CAAM,KAAK,CAAC,CAAA,KAAM,IAAA,IAClB,KAAA,CAAM,WAAA,KAAgB,MAAA;AAE1B;AAEO,SAAS,gBACd,MAAA,EACyB;AACzB,EAAA,OAAO,QAAA,IAAY,MAAA,IAAU,MAAA,CAAO,MAAA,KAAW,WAAA;AACjD","file":"chunk-3EUKJEQ3.js","sourcesContent":["/**\n * Shared Compiler Utilities\n *\n * Functions and constants shared between the standard and recursive compilers.\n */\nimport { type SQL, sql } from \"drizzle-orm\";\n\nimport { type AggregateExpr, type FieldRef, type SelectiveField } from \"../ast\";\n\n// ============================================================\n// Constants\n// ============================================================\n\nexport const NODE_COLUMNS = [\n \"id\",\n \"kind\",\n \"props\",\n \"version\",\n \"valid_from\",\n \"valid_to\",\n \"created_at\",\n \"updated_at\",\n \"deleted_at\",\n] as const;\n\nexport const EDGE_COLUMNS = [\n \"id\",\n \"kind\",\n \"from_id\",\n \"to_id\",\n \"props\",\n \"valid_from\",\n \"valid_to\",\n \"created_at\",\n \"updated_at\",\n \"deleted_at\",\n] as const;\n\nexport type RequiredColumnsByAlias = ReadonlyMap<string, ReadonlySet<string>>;\nexport const EMPTY_REQUIRED_COLUMNS = new Set<string>();\n\n// ============================================================\n// SQL Helpers\n// ============================================================\n\nexport function quoteIdentifier(identifier: string): SQL {\n return sql.raw(`\"${identifier.replaceAll('\"', '\"\"')}\"`);\n}\n\n// ============================================================\n// Column Projection\n// ============================================================\n\n/**\n * Determines whether a column should be included in the projection.\n *\n * @param requiredColumns - Set of columns required by the query, or undefined to include all.\n * @param column - The column name to check.\n * @param alwaysRequiredColumns - Optional set of columns that are always projected\n * (e.g. join keys in recursive CTEs). Pass only from recursive compiler callers.\n */\nexport function shouldProjectColumn(\n requiredColumns: ReadonlySet<string> | undefined,\n column: string,\n alwaysRequiredColumns?: ReadonlySet<string>,\n): boolean {\n if (alwaysRequiredColumns?.has(column)) return true;\n if (requiredColumns === undefined) return true;\n return requiredColumns.has(column);\n}\n\n// ============================================================\n// Required Column Tracking\n// ============================================================\n\nexport function addRequiredColumn(\n requiredColumnsByAlias: Map<string, Set<string>>,\n alias: string,\n column: string,\n): void {\n const existing = requiredColumnsByAlias.get(alias);\n if (existing) {\n existing.add(column);\n return;\n }\n requiredColumnsByAlias.set(alias, new Set([column]));\n}\n\nexport function markFieldRefAsRequired(\n requiredColumnsByAlias: Map<string, Set<string>>,\n field: FieldRef,\n): void {\n const column = field.path[0];\n if (column === undefined) return;\n addRequiredColumn(requiredColumnsByAlias, field.alias, column);\n}\n\nexport function mapSelectiveSystemFieldToColumn(field: string): string {\n if (field === \"fromId\") return \"from_id\";\n if (field === \"toId\") return \"to_id\";\n if (field.startsWith(\"meta.\")) {\n return field\n .slice(5)\n .replaceAll(/([A-Z])/g, \"_$1\")\n .toLowerCase();\n }\n return field;\n}\n\nexport function markSelectiveFieldAsRequired(\n requiredColumnsByAlias: Map<string, Set<string>>,\n field: SelectiveField,\n): void {\n if (field.isSystemField) {\n addRequiredColumn(\n requiredColumnsByAlias,\n field.alias,\n mapSelectiveSystemFieldToColumn(field.field),\n );\n return;\n }\n addRequiredColumn(requiredColumnsByAlias, field.alias, \"props\");\n}\n\n// ============================================================\n// AST Type Guards\n// ============================================================\n\nexport function isIdFieldRef(field: FieldRef): boolean {\n return (\n field.path.length === 1 &&\n field.path[0] === \"id\" &&\n field.jsonPointer === undefined\n );\n}\n\nexport function isAggregateExpr(\n source: FieldRef | AggregateExpr,\n): source is AggregateExpr {\n return \"__type\" in source && source.__type === \"aggregate\";\n}\n"]}
|
package/dist/chunk-4FJVSF3K.cjs
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var chunkPYJOBZR3_cjs = require('./chunk-PYJOBZR3.cjs');
|
|
4
|
-
|
|
5
|
-
// src/graph-extension/define-graph-extension.ts
|
|
6
|
-
function defineGraphExtension(input) {
|
|
7
|
-
return chunkPYJOBZR3_cjs.unwrap(chunkPYJOBZR3_cjs.validateGraphExtension(input, { strict: true }));
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
exports.defineGraphExtension = defineGraphExtension;
|
|
11
|
-
//# sourceMappingURL=chunk-4FJVSF3K.cjs.map
|
|
12
|
-
//# sourceMappingURL=chunk-4FJVSF3K.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/query/json-pointer.ts"],"names":[],"mappings":"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","file":"chunk-7V335GHG.cjs","sourcesContent":["// JSON Pointer utilities and types.\n\nexport const MAX_JSON_POINTER_DEPTH = 5 as const;\n\nexport type JsonPointer = string & { readonly __jsonPointer: unique symbol };\nexport type JsonPointerSegment = string | number;\nexport type JsonPointerSegments = readonly JsonPointerSegment[];\n\ntype Depth = 0 | 1 | 2 | 3 | 4 | 5;\n\ninterface DepthDecrementMap {\n 0: 0;\n 1: 0;\n 2: 1;\n 3: 2;\n 4: 3;\n 5: 4;\n}\n\ntype Decrement<Current extends Depth> = DepthDecrementMap[Current];\n\ntype NonNegativeIntegerString = Exclude<`${bigint}`, `-${string}`>;\ntype ObjectPointerKey<T> = Exclude<\n Extract<keyof T, string>,\n NonNegativeIntegerString\n>;\n\ntype EncodeTilde<S extends string> =\n S extends `${infer Head}~${infer Tail}` ?\n `${EncodeTilde<Head>}~0${EncodeTilde<Tail>}`\n : S;\n\ntype EncodeSlash<S extends string> =\n S extends `${infer Head}/${infer Tail}` ?\n `${EncodeSlash<Head>}~1${EncodeSlash<Tail>}`\n : S;\n\ntype EncodePointerSegment<S extends string> = EncodeSlash<EncodeTilde<S>>;\n\ntype DecodePointerSegment<S extends string> =\n S extends `${infer Head}~1${infer Tail}` ?\n `${DecodePointerSegment<Head>}/${DecodePointerSegment<Tail>}`\n : S extends `${infer Head}~0${infer Tail}` ?\n `${DecodePointerSegment<Head>}~${DecodePointerSegment<Tail>}`\n : S;\n\ntype PointerForArray<T, Current extends Depth> =\n | `/${NonNegativeIntegerString}`\n | (Current extends 1 ? never\n : `/${NonNegativeIntegerString}${JsonPointerFor<T, Decrement<Current>>}`);\n\ntype PointerForObject<T, Current extends Depth> = {\n [K in ObjectPointerKey<T>]:\n | `/${EncodePointerSegment<K>}`\n | (Current extends 1 ? never\n : `/${EncodePointerSegment<K>}${JsonPointerFor<T[K], Decrement<Current>>}`);\n}[ObjectPointerKey<T>];\n\nexport type JsonPointerFor<T, Current extends Depth = 5> =\n | \"\"\n | (Current extends 0 ? \"\"\n : T extends readonly (infer U)[] ? PointerForArray<U, Current>\n : never)\n | (Current extends 0 ? \"\"\n : T extends Record<string, unknown> ? PointerForObject<T, Current>\n : never);\n\ntype PointerSegmentsForArray<T, Current extends Depth> =\n | readonly [number]\n | (Current extends 1 ? readonly [number]\n : readonly [number, ...JsonPointerSegmentsFor<T, Decrement<Current>>]);\n\ntype PointerSegmentsForObject<T, Current extends Depth> = {\n [K in ObjectPointerKey<T>]:\n | readonly [K]\n | (Current extends 1 ? readonly [K]\n : readonly [K, ...JsonPointerSegmentsFor<T[K], Decrement<Current>>]);\n}[ObjectPointerKey<T>];\n\nexport type JsonPointerSegmentsFor<T, Current extends Depth = 5> =\n | readonly []\n | (Current extends 0 ? readonly []\n : T extends readonly (infer U)[] ? PointerSegmentsForArray<U, Current>\n : never)\n | (Current extends 0 ? readonly []\n : T extends Record<string, unknown> ? PointerSegmentsForObject<T, Current>\n : never);\n\nexport type JsonPointerInput<T> =\n | JsonPointerFor<T>\n | JsonPointerSegmentsFor<T>\n | JsonPointer;\n\nexport type ResolveJsonPointer<T, Pointer extends string> =\n Pointer extends \"\" ? T\n : Pointer extends `/${infer Head}/${infer Tail}` ?\n ResolveJsonPointer<\n ResolvePointerSegment<T, DecodePointerSegment<Head>>,\n `/${Tail}`\n >\n : Pointer extends `/${infer Head}` ?\n ResolvePointerSegment<T, DecodePointerSegment<Head>>\n : unknown;\n\ntype ResolvePointerSegment<T, Segment extends string> =\n T extends readonly (infer U)[] ?\n Segment extends NonNegativeIntegerString ?\n U\n : unknown\n : T extends Record<string, unknown> ?\n Segment extends keyof T ?\n Segment extends NonNegativeIntegerString ?\n unknown\n : T[Segment]\n : unknown\n : unknown;\n\nexport type ResolveJsonPointerSegments<\n T,\n Segments extends readonly JsonPointerSegment[],\n> =\n Segments extends readonly [] ? T\n : Segments extends readonly [infer Head, ...infer Tail] ?\n ResolveJsonPointerSegments<\n ResolvePointerSegment<T, SegmentToString<Head>>,\n Extract<Tail, readonly JsonPointerSegment[]>\n >\n : unknown;\n\ntype SegmentToString<Segment> =\n Segment extends number ? `${Segment}`\n : Segment extends string ? Segment\n : string;\n\nexport function jsonPointer(segments: JsonPointerSegments): JsonPointer {\n if (segments.length > MAX_JSON_POINTER_DEPTH) {\n throw new Error(\n `JSON Pointer exceeds max depth ${MAX_JSON_POINTER_DEPTH}: ${segments.length}`,\n );\n }\n\n if (segments.length === 0) {\n return \"\" as JsonPointer;\n }\n\n const encoded = segments.map((segment) => {\n if (segment === \"-\") {\n throw new Error(\n \"JSON Pointer '-' segment is not allowed for query access\",\n );\n }\n if (typeof segment === \"number\") {\n if (!Number.isInteger(segment) || segment < 0) {\n throw new Error(\n `JSON Pointer index must be a non-negative integer: ${segment}`,\n );\n }\n return segment.toString();\n }\n return encodeJsonPointerSegment(segment);\n });\n\n return `/${encoded.join(\"/\")}` as JsonPointer;\n}\n\nfunction isJsonPointerSegments(\n input: unknown,\n): input is readonly JsonPointerSegment[] {\n return Array.isArray(input);\n}\n\nexport function normalizeJsonPointer<T>(\n input: JsonPointerInput<T>,\n): JsonPointer {\n if (isJsonPointerSegments(input)) {\n return jsonPointer(input);\n }\n\n return assertJsonPointer(input);\n}\n\nexport function parseJsonPointer(pointer: JsonPointer): readonly string[] {\n if (pointer === \"\") {\n return [];\n }\n\n const rawSegments = pointer.slice(1).split(\"/\");\n return rawSegments.map((segment) => decodeJsonPointerSegment(segment));\n}\n\nexport function joinJsonPointers(\n base: JsonPointer | undefined,\n relative: JsonPointer,\n): JsonPointer {\n if (!base || base === \"\") {\n return relative;\n }\n if (relative === \"\") {\n return base;\n }\n\n const combinedSegments = [\n ...parseJsonPointer(base),\n ...parseJsonPointer(relative),\n ];\n return jsonPointer(combinedSegments);\n}\n\nfunction assertJsonPointer(pointer: string): JsonPointer {\n if (pointer !== \"\" && !pointer.startsWith(\"/\")) {\n throw new Error(\"JSON Pointer must be empty or start with '/'\");\n }\n\n const segments = pointer === \"\" ? [] : pointer.slice(1).split(\"/\");\n if (segments.length > MAX_JSON_POINTER_DEPTH) {\n throw new Error(\n `JSON Pointer exceeds max depth ${MAX_JSON_POINTER_DEPTH}: ${segments.length}`,\n );\n }\n\n for (const segment of segments) {\n if (segment === \"-\") {\n throw new Error(\n \"JSON Pointer '-' segment is not allowed for query access\",\n );\n }\n if (!isValidPointerEncoding(segment)) {\n throw new Error(\n `Invalid JSON Pointer escape sequence in segment: ${segment}`,\n );\n }\n }\n\n return pointer as JsonPointer;\n}\n\n/**\n * Escape a single JSON Pointer reference segment per RFC 6901: `~`\n * becomes `~0`, `/` becomes `~1`. Callers join the result with `/`.\n */\nexport function encodeJsonPointerSegment(segment: string): string {\n return segment.replaceAll(\"~\", \"~0\").replaceAll(\"/\", \"~1\");\n}\n\nfunction decodeJsonPointerSegment(segment: string): string {\n return segment.replaceAll(\"~1\", \"/\").replaceAll(\"~0\", \"~\");\n}\n\nfunction isValidPointerEncoding(segment: string): boolean {\n for (let index = 0; index < segment.length; index += 1) {\n if (segment[index] !== \"~\") {\n continue;\n }\n const next = segment[index + 1];\n if (next !== \"0\" && next !== \"1\") {\n return false;\n }\n index += 1;\n }\n return true;\n}\n"]}
|