@typicalday/firegraph 0.14.1 → 0.15.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/README.md +23 -3
- package/dist/{backend-DuvHGgK1.d.cts → backend-BpYLdwCW.d.cts} +1 -1
- package/dist/{backend-DuvHGgK1.d.ts → backend-BpYLdwCW.d.ts} +1 -1
- package/dist/backend-CvImIwTY.d.cts +137 -0
- package/dist/backend-YH5HtawN.d.ts +137 -0
- package/dist/backend.d.cts +2 -2
- package/dist/backend.d.ts +2 -2
- package/dist/{chunk-3AHHXMWX.js → chunk-5HIRYV2S.js} +12 -35
- package/dist/chunk-5HIRYV2S.js.map +1 -0
- package/dist/{chunk-DJI3VXXA.js → chunk-7IEZ6IYY.js} +2 -2
- package/dist/chunk-7IEZ6IYY.js.map +1 -0
- package/dist/chunk-FODIMIWY.js +721 -0
- package/dist/chunk-FODIMIWY.js.map +1 -0
- package/dist/chunk-NGAJCALM.js +34 -0
- package/dist/chunk-NGAJCALM.js.map +1 -0
- package/dist/chunk-ULRDQ6HZ.js +862 -0
- package/dist/chunk-ULRDQ6HZ.js.map +1 -0
- package/dist/{client-BKi3vk0Q.d.ts → client-B5o39X79.d.ts} +1 -1
- package/dist/{client-BrsaXtDV.d.cts → client-BGHwxwPg.d.cts} +1 -1
- package/dist/{client-Bk2Cm6xv.d.cts → client-DoyEdJ5w.d.cts} +1 -1
- package/dist/{client-Bk2Cm6xv.d.ts → client-DoyEdJ5w.d.ts} +1 -1
- package/dist/cloudflare/index.cjs +148 -158
- package/dist/cloudflare/index.cjs.map +1 -1
- package/dist/cloudflare/index.d.cts +73 -70
- package/dist/cloudflare/index.d.ts +73 -70
- package/dist/cloudflare/index.js +53 -588
- package/dist/cloudflare/index.js.map +1 -1
- package/dist/codegen/index.d.cts +1 -1
- package/dist/codegen/index.d.ts +1 -1
- package/dist/firestore-enterprise/index.cjs.map +1 -1
- package/dist/firestore-enterprise/index.d.cts +3 -3
- package/dist/firestore-enterprise/index.d.ts +3 -3
- package/dist/firestore-enterprise/index.js +5 -3
- package/dist/firestore-enterprise/index.js.map +1 -1
- package/dist/firestore-standard/index.cjs.map +1 -1
- package/dist/firestore-standard/index.d.cts +3 -3
- package/dist/firestore-standard/index.d.ts +3 -3
- package/dist/firestore-standard/index.js +3 -2
- package/dist/firestore-standard/index.js.map +1 -1
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/query-client/index.d.cts +2 -2
- package/dist/query-client/index.d.ts +2 -2
- package/dist/{registry-Bc7h6WTM.d.cts → registry-BGh7Jqpb.d.cts} +2 -2
- package/dist/{registry-C2KUPVZj.d.ts → registry-tKTb5Kx1.d.ts} +2 -2
- package/dist/sqlite/index.cjs +578 -371
- package/dist/sqlite/index.cjs.map +1 -1
- package/dist/sqlite/index.d.cts +4 -110
- package/dist/sqlite/index.d.ts +4 -110
- package/dist/sqlite/index.js +7 -1144
- package/dist/sqlite/index.js.map +1 -1
- package/dist/sqlite/local.cjs +1835 -0
- package/dist/sqlite/local.cjs.map +1 -0
- package/dist/sqlite/local.d.cts +83 -0
- package/dist/sqlite/local.d.ts +83 -0
- package/dist/sqlite/local.js +121 -0
- package/dist/sqlite/local.js.map +1 -0
- package/package.json +15 -1
- package/dist/chunk-3AHHXMWX.js.map +0 -1
- package/dist/chunk-DJI3VXXA.js.map +0 -1
- package/dist/chunk-NNBSUOOF.js +0 -289
- package/dist/chunk-NNBSUOOF.js.map +0 -1
package/README.md
CHANGED
|
@@ -833,6 +833,8 @@ const allAssignments = await g.findEdgesGlobal(
|
|
|
833
833
|
|
|
834
834
|
This uses Firestore collection group queries and requires collection group indexes. The collection name defaults to the last segment of the client's collection path if omitted.
|
|
835
835
|
|
|
836
|
+
Firestore-only: the SQLite backend uses a table-per-graph layout with no cross-table index, so it omits `findEdgesGlobal` entirely (calling it throws `UNSUPPORTED_OPERATION`).
|
|
837
|
+
|
|
836
838
|
#### Multi-Hop Limitation
|
|
837
839
|
|
|
838
840
|
Each hop carries its reader context forward — if hop 1 crosses into a subgraph, hop 2 stays in that subgraph. To return to the root or traverse a different subgraph, create a separate traversal from the desired client:
|
|
@@ -1140,18 +1142,36 @@ The match on `FIRESTORE_EMULATOR_EDITION` is case-insensitive and whitespace-tri
|
|
|
1140
1142
|
|
|
1141
1143
|
### SQLite Backend (`firegraph/sqlite`)
|
|
1142
1144
|
|
|
1143
|
-
|
|
1145
|
+
Table-per-graph SQLite backend for Node.js (`better-sqlite3`) and Cloudflare D1. There is no `scope` column — the root graph lives in `tableName` itself and each subgraph gets its own physical table, tracked in a small `<tableName>_graphs` catalog. Schema (tables, indexes, catalog) is bootstrapped lazily on first use; no manual DDL step. Supports all four core capabilities plus `query.aggregate`, `query.select`, `query.join`, `query.dml`, and `raw.sql`. Does not support `search.*` or `findEdgesGlobal` (no cross-table index).
|
|
1144
1146
|
|
|
1145
1147
|
```typescript
|
|
1146
1148
|
import { createSqliteBackend } from 'firegraph/sqlite';
|
|
1147
|
-
import {
|
|
1149
|
+
import { createGraphClient } from 'firegraph';
|
|
1148
1150
|
|
|
1149
1151
|
const backend = createSqliteBackend(executor, 'graph');
|
|
1150
|
-
const g =
|
|
1152
|
+
const g = createGraphClient(backend, { registry });
|
|
1151
1153
|
```
|
|
1152
1154
|
|
|
1153
1155
|
Note: `core.transactions` is only declared when `executor.transaction` is defined — `better-sqlite3` provides this, but Cloudflare D1 does not.
|
|
1154
1156
|
|
|
1157
|
+
### Local SQLite Files (`firegraph/sqlite-local`)
|
|
1158
|
+
|
|
1159
|
+
For a local graph database in a single SQLite file, use the better-sqlite3 factory. It opens (or wraps) a database, applies `journal_mode = WAL` and a `busy_timeout`, and returns a ready-to-use backend. Requires the optional peer dependency `better-sqlite3` (loaded via dynamic `import()`, so this subpath is safe to reference from code that also targets D1/workerd — just don't bundle it there).
|
|
1160
|
+
|
|
1161
|
+
```typescript
|
|
1162
|
+
import { createLocalSqliteBackend } from 'firegraph/sqlite-local';
|
|
1163
|
+
import { createGraphClient } from 'firegraph';
|
|
1164
|
+
|
|
1165
|
+
const { backend, db, close } = await createLocalSqliteBackend('./graph.db', {
|
|
1166
|
+
tableName: 'graph', // default 'firegraph'
|
|
1167
|
+
});
|
|
1168
|
+
const g = createGraphClient(backend, { registry });
|
|
1169
|
+
// ... use the client; `db` is the raw better-sqlite3 Database if needed ...
|
|
1170
|
+
close();
|
|
1171
|
+
```
|
|
1172
|
+
|
|
1173
|
+
`createLocalSqliteBackend` also accepts an already-open better-sqlite3 `Database` (in which case `close()` is a no-op — the caller owns the lifecycle), `':memory:'` for ephemeral graphs, a `pragmas` map for extra tuning, and `fileMustExist: true` to refuse creating new files. `createBetterSqliteExecutor(db)` is exported separately for wiring `createSqliteBackend` directly.
|
|
1174
|
+
|
|
1155
1175
|
### Cloudflare Durable Object Backend (`firegraph/cloudflare`)
|
|
1156
1176
|
|
|
1157
1177
|
Runs inside a Durable Object via `state.storage.sql`. Same capability set as SQLite minus `core.transactions` (the DO's single-threaded executor cannot block on transaction callbacks) and `raw.sql` (the DO SQL surface is hidden behind RPC).
|
|
@@ -1894,4 +1894,4 @@ interface StorageBackend<C extends Capability = Capability> {
|
|
|
1894
1894
|
geoSearch?(params: GeoSearchParams): Promise<StoredGraphRecord[]>;
|
|
1895
1895
|
}
|
|
1896
1896
|
|
|
1897
|
-
export { type
|
|
1897
|
+
export { type DiscoveredEntity as $, type AggregateSpec as A, type BackendCapabilities as B, type Capability as C, DELETE_FIELD as D, type ExpandParams as E, type FindEdgesParams as F, type GraphClientOptions as G, type MigrationWriteBack as H, type IndexSpec as I, type JoinExtension as J, type MigrationStep as K, type QueryPlan as L, type MigrationExecutor as M, type FindNodesParams as N, type MigrationFn as O, type StoredMigrationStep as P, type QueryFilter as Q, type RegistryEntry as R, type StorageBackend as S, type TransactionBackend as T, type UpdatePayload as U, type TraversalBuilder as V, type WritableRecord as W, type BulkBatchError as X, type BulkProgress as Y, type CoreGraphClient as Z, type DefineTypeOptions as _, type BatchBackend as a, type DistanceMeasure as a0, type DynamicGraphMethods as a1, type EdgeTopology as a2, type EdgeTypeData as a3, type FindEdgesProjectedParams as a4, type FindNearestParams as a5, type FiregraphConfig as a6, type FullTextSearchExtension as a7, type GeoExtension as a8, type GraphBatch as a9, type GraphRecord as aa, type GraphTransaction as ab, type GraphWriter as ac, type HopDefinition as ad, type HopResult as ae, type IndexFieldSpec as af, type NodeTypeData as ag, type ProjectedRow as ah, type QueryMode as ai, type RawFirestoreExtension as aj, type RawSqlExtension as ak, type RealtimeListenExtension as al, type ScanProtection as am, type SelectExtension as an, type TraversalOptions as ao, type TraversalResult as ap, type VectorExtension as aq, type ViewContext as ar, type ViewDefaultsConfig as as, type ViewResolverConfig as at, type WhereClause as au, defineConfig as av, resolveView as aw, type BulkUpdatePatch as b, type DataPathOp as c, type DmlExtension as d, type ExpandResult as e, type WriteMode as f, createCapabilities as g, deleteField as h, flattenPatch as i, intersectCapabilities as j, isDeleteSentinel as k, type DiscoveryResult as l, type DynamicRegistryConfig as m, type DynamicGraphClient as n, type GraphClient as o, type GraphRegistry as p, type GraphReader as q, type QueryOptions as r, type CascadeResult as s, type BulkOptions as t, type BulkResult as u, type StoredGraphRecord as v, type AggregateExtension as w, type AggregateField as x, type AggregateOp as y, type AggregateResult as z };
|
|
@@ -1894,4 +1894,4 @@ interface StorageBackend<C extends Capability = Capability> {
|
|
|
1894
1894
|
geoSearch?(params: GeoSearchParams): Promise<StoredGraphRecord[]>;
|
|
1895
1895
|
}
|
|
1896
1896
|
|
|
1897
|
-
export { type
|
|
1897
|
+
export { type DiscoveredEntity as $, type AggregateSpec as A, type BackendCapabilities as B, type Capability as C, DELETE_FIELD as D, type ExpandParams as E, type FindEdgesParams as F, type GraphClientOptions as G, type MigrationWriteBack as H, type IndexSpec as I, type JoinExtension as J, type MigrationStep as K, type QueryPlan as L, type MigrationExecutor as M, type FindNodesParams as N, type MigrationFn as O, type StoredMigrationStep as P, type QueryFilter as Q, type RegistryEntry as R, type StorageBackend as S, type TransactionBackend as T, type UpdatePayload as U, type TraversalBuilder as V, type WritableRecord as W, type BulkBatchError as X, type BulkProgress as Y, type CoreGraphClient as Z, type DefineTypeOptions as _, type BatchBackend as a, type DistanceMeasure as a0, type DynamicGraphMethods as a1, type EdgeTopology as a2, type EdgeTypeData as a3, type FindEdgesProjectedParams as a4, type FindNearestParams as a5, type FiregraphConfig as a6, type FullTextSearchExtension as a7, type GeoExtension as a8, type GraphBatch as a9, type GraphRecord as aa, type GraphTransaction as ab, type GraphWriter as ac, type HopDefinition as ad, type HopResult as ae, type IndexFieldSpec as af, type NodeTypeData as ag, type ProjectedRow as ah, type QueryMode as ai, type RawFirestoreExtension as aj, type RawSqlExtension as ak, type RealtimeListenExtension as al, type ScanProtection as am, type SelectExtension as an, type TraversalOptions as ao, type TraversalResult as ap, type VectorExtension as aq, type ViewContext as ar, type ViewDefaultsConfig as as, type ViewResolverConfig as at, type WhereClause as au, defineConfig as av, resolveView as aw, type BulkUpdatePatch as b, type DataPathOp as c, type DmlExtension as d, type ExpandResult as e, type WriteMode as f, createCapabilities as g, deleteField as h, flattenPatch as i, intersectCapabilities as j, isDeleteSentinel as k, type DiscoveryResult as l, type DynamicRegistryConfig as m, type DynamicGraphClient as n, type GraphClient as o, type GraphRegistry as p, type GraphReader as q, type QueryOptions as r, type CascadeResult as s, type BulkOptions as t, type BulkResult as u, type StoredGraphRecord as v, type AggregateExtension as w, type AggregateField as x, type AggregateOp as y, type AggregateResult as z };
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { p as GraphRegistry, I as IndexSpec, S as StorageBackend } from './backend-BpYLdwCW.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Driver-level SQLite abstraction.
|
|
5
|
+
*
|
|
6
|
+
* The `SqliteBackend` only depends on this interface, not on any particular
|
|
7
|
+
* SQLite driver. Callers wire up whichever driver suits their runtime —
|
|
8
|
+
* `better-sqlite3` in Node tests, D1 in Workers, DO SQLite inside a Durable
|
|
9
|
+
* Object, etc. — and `createSqliteBackend` composes the rest.
|
|
10
|
+
*
|
|
11
|
+
* Some drivers are fully async with native atomic batches (e.g. D1); others
|
|
12
|
+
* are synchronous and wrap `run`/`all` in immediately-resolved promises while
|
|
13
|
+
* providing interactive transactions via a sync primitive (e.g. DO SQLite's
|
|
14
|
+
* `transactionSync`). Both shapes fit behind this interface.
|
|
15
|
+
*/
|
|
16
|
+
interface SqliteExecutor {
|
|
17
|
+
/** Run a query and return all rows. */
|
|
18
|
+
all(sql: string, params: unknown[]): Promise<Record<string, unknown>[]>;
|
|
19
|
+
/** Run a write statement. */
|
|
20
|
+
run(sql: string, params: unknown[]): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Execute a list of write statements atomically. Drivers that lack
|
|
23
|
+
* native batch support (e.g., a wrapped synchronous SQLite) should still
|
|
24
|
+
* implement this so `BatchBackend.commit()` works.
|
|
25
|
+
*/
|
|
26
|
+
batch(statements: ReadonlyArray<{
|
|
27
|
+
sql: string;
|
|
28
|
+
params: unknown[];
|
|
29
|
+
}>): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Run an interactive transaction. Optional — if absent, the SqliteBackend
|
|
32
|
+
* throws on `runTransaction()`. D1 has no interactive transactions.
|
|
33
|
+
*/
|
|
34
|
+
transaction?<T>(fn: (tx: SqliteTxExecutor) => Promise<T>): Promise<T>;
|
|
35
|
+
/**
|
|
36
|
+
* Maximum statements the driver will accept in a single `batch()` call.
|
|
37
|
+
* The backend uses this to chunk large bulk operations (cascade delete,
|
|
38
|
+
* bulkRemoveEdges) so a hub node with thousands of edges doesn't trip the
|
|
39
|
+
* driver's hard limit. D1 caps at ~100 statements per batch; DO SQLite has
|
|
40
|
+
* no documented cap (a single `transactionSync` over many statements is
|
|
41
|
+
* fine). When `undefined`, the backend submits all statements in one batch
|
|
42
|
+
* (preserving cross-batch atomicity for drivers that support it).
|
|
43
|
+
*/
|
|
44
|
+
readonly maxBatchSize?: number;
|
|
45
|
+
/**
|
|
46
|
+
* Maximum total bound parameters the driver will accept across one
|
|
47
|
+
* `batch()` call. D1 caps at ~1000 bound parameters per batch — separate
|
|
48
|
+
* from `maxBatchSize`. Most cascade/bulk batches consist of 2-param
|
|
49
|
+
* `DELETE` statements so this rarely triggers, but driver authors should
|
|
50
|
+
* declare it for safety. When `undefined`, the backend doesn't split on
|
|
51
|
+
* parameter count.
|
|
52
|
+
*/
|
|
53
|
+
readonly maxBatchParams?: number;
|
|
54
|
+
}
|
|
55
|
+
interface SqliteTxExecutor {
|
|
56
|
+
all(sql: string, params: unknown[]): Promise<Record<string, unknown>[]>;
|
|
57
|
+
run(sql: string, params: unknown[]): Promise<void>;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* SQLite implementation of `StorageBackend`.
|
|
62
|
+
*
|
|
63
|
+
* Table-per-graph design: the root graph lives in `tableName`, and each
|
|
64
|
+
* subgraph lives in its own physical table (`<tableName>_g_<mangled scope>`,
|
|
65
|
+
* see `tableForScope`). There is no `scope` column — the table a row lives
|
|
66
|
+
* in *is* its scope, exactly like the Cloudflare DO edition where each
|
|
67
|
+
* subgraph is its own Durable Object.
|
|
68
|
+
*
|
|
69
|
+
* A small catalog table (`<tableName>_graphs`) records every graph's
|
|
70
|
+
* storage scope → table mapping. Cascade delete prefix-matches descendant
|
|
71
|
+
* scopes in the catalog and drops each listed table — no registry topology
|
|
72
|
+
* required.
|
|
73
|
+
*
|
|
74
|
+
* Schema is ensured lazily: the first operation on a backend instance runs
|
|
75
|
+
* `CREATE TABLE IF NOT EXISTS` for the graph's table, its indexes, and the
|
|
76
|
+
* catalog, then registers the graph in the catalog. Callers no longer
|
|
77
|
+
* pre-create tables.
|
|
78
|
+
*/
|
|
79
|
+
|
|
80
|
+
interface SqliteBackendOptions {
|
|
81
|
+
/** Logical scope path (chained subgraph names) — used for `allowedIn` matching. */
|
|
82
|
+
scopePath?: string;
|
|
83
|
+
/**
|
|
84
|
+
* Internal storage scope (interleaved parent-uid/name path). Determines
|
|
85
|
+
* which physical table this backend reads and writes — `''` (the default)
|
|
86
|
+
* is the root graph in `tableName` itself.
|
|
87
|
+
*
|
|
88
|
+
* @internal Used by `subgraph()` to derive child backends. Setting it
|
|
89
|
+
* directly bypasses catalog registration consistency checks (the graph
|
|
90
|
+
* still self-registers, but ancestors are not validated) — always derive
|
|
91
|
+
* subgraph backends via `subgraph()` instead.
|
|
92
|
+
*/
|
|
93
|
+
storageScope?: string;
|
|
94
|
+
/**
|
|
95
|
+
* Registry contributing per-entry `indexes` declarations, applied to
|
|
96
|
+
* every graph table this backend (and its subgraphs) lazily creates.
|
|
97
|
+
*/
|
|
98
|
+
registry?: GraphRegistry;
|
|
99
|
+
/**
|
|
100
|
+
* Replaces the built-in core index preset for lazily created tables.
|
|
101
|
+
* Pass `[]` to disable core indexes entirely.
|
|
102
|
+
*/
|
|
103
|
+
coreIndexes?: IndexSpec[];
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Capability union declared by the SQLite-backed `StorageBackend`.
|
|
107
|
+
*
|
|
108
|
+
* `core.transactions` is part of the static union because `runTransaction`
|
|
109
|
+
* is always present as a method on the class. The runtime cap-set determines
|
|
110
|
+
* whether that method is *functional*: D1 leaves `executor.transaction`
|
|
111
|
+
* undefined and the call throws `UNSUPPORTED_OPERATION`; DO SQLite and
|
|
112
|
+
* better-sqlite3 wire the executor and the call works. The static type
|
|
113
|
+
* therefore promises only that the method exists — callers that care about
|
|
114
|
+
* portability check `client.capabilities.has('core.transactions')` before
|
|
115
|
+
* opening a tx, and code that runs against an unknown driver can rely on the
|
|
116
|
+
* runtime guard inside `runTransaction`.
|
|
117
|
+
*
|
|
118
|
+
* The `query.*` extension capabilities follow the same conservative
|
|
119
|
+
* declaration rule as the cap descriptor itself — only land in the union
|
|
120
|
+
* when the corresponding method is actually wired up. Today that's
|
|
121
|
+
* `query.aggregate` (Phase 4), `query.dml` (Phase 5), `query.join`
|
|
122
|
+
* (Phase 6 — fan-out via `IN (…)` in one statement), and `query.select`
|
|
123
|
+
* (Phase 7 — server-side projection via `json_extract`).
|
|
124
|
+
*/
|
|
125
|
+
type SqliteCapability = 'core.read' | 'core.write' | 'core.transactions' | 'core.batch' | 'core.subgraph' | 'query.aggregate' | 'query.dml' | 'query.join' | 'query.select' | 'raw.sql';
|
|
126
|
+
/**
|
|
127
|
+
* Create a SQLite-backed `StorageBackend`.
|
|
128
|
+
*
|
|
129
|
+
* `tableName` is the root graph's table; subgraphs get their own tables
|
|
130
|
+
* derived from it (see `tableForScope`). Schema (tables, indexes, and the
|
|
131
|
+
* graph catalog) is created lazily on first use — no manual DDL step.
|
|
132
|
+
* Pass `options.registry` so per-entry `indexes` declarations land in
|
|
133
|
+
* every lazily created table.
|
|
134
|
+
*/
|
|
135
|
+
declare function createSqliteBackend(executor: SqliteExecutor, tableName: string, options?: SqliteBackendOptions): StorageBackend<SqliteCapability>;
|
|
136
|
+
|
|
137
|
+
export { type SqliteBackendOptions as S, type SqliteCapability as a, type SqliteExecutor as b, createSqliteBackend as c };
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { p as GraphRegistry, I as IndexSpec, S as StorageBackend } from './backend-BpYLdwCW.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Driver-level SQLite abstraction.
|
|
5
|
+
*
|
|
6
|
+
* The `SqliteBackend` only depends on this interface, not on any particular
|
|
7
|
+
* SQLite driver. Callers wire up whichever driver suits their runtime —
|
|
8
|
+
* `better-sqlite3` in Node tests, D1 in Workers, DO SQLite inside a Durable
|
|
9
|
+
* Object, etc. — and `createSqliteBackend` composes the rest.
|
|
10
|
+
*
|
|
11
|
+
* Some drivers are fully async with native atomic batches (e.g. D1); others
|
|
12
|
+
* are synchronous and wrap `run`/`all` in immediately-resolved promises while
|
|
13
|
+
* providing interactive transactions via a sync primitive (e.g. DO SQLite's
|
|
14
|
+
* `transactionSync`). Both shapes fit behind this interface.
|
|
15
|
+
*/
|
|
16
|
+
interface SqliteExecutor {
|
|
17
|
+
/** Run a query and return all rows. */
|
|
18
|
+
all(sql: string, params: unknown[]): Promise<Record<string, unknown>[]>;
|
|
19
|
+
/** Run a write statement. */
|
|
20
|
+
run(sql: string, params: unknown[]): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Execute a list of write statements atomically. Drivers that lack
|
|
23
|
+
* native batch support (e.g., a wrapped synchronous SQLite) should still
|
|
24
|
+
* implement this so `BatchBackend.commit()` works.
|
|
25
|
+
*/
|
|
26
|
+
batch(statements: ReadonlyArray<{
|
|
27
|
+
sql: string;
|
|
28
|
+
params: unknown[];
|
|
29
|
+
}>): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Run an interactive transaction. Optional — if absent, the SqliteBackend
|
|
32
|
+
* throws on `runTransaction()`. D1 has no interactive transactions.
|
|
33
|
+
*/
|
|
34
|
+
transaction?<T>(fn: (tx: SqliteTxExecutor) => Promise<T>): Promise<T>;
|
|
35
|
+
/**
|
|
36
|
+
* Maximum statements the driver will accept in a single `batch()` call.
|
|
37
|
+
* The backend uses this to chunk large bulk operations (cascade delete,
|
|
38
|
+
* bulkRemoveEdges) so a hub node with thousands of edges doesn't trip the
|
|
39
|
+
* driver's hard limit. D1 caps at ~100 statements per batch; DO SQLite has
|
|
40
|
+
* no documented cap (a single `transactionSync` over many statements is
|
|
41
|
+
* fine). When `undefined`, the backend submits all statements in one batch
|
|
42
|
+
* (preserving cross-batch atomicity for drivers that support it).
|
|
43
|
+
*/
|
|
44
|
+
readonly maxBatchSize?: number;
|
|
45
|
+
/**
|
|
46
|
+
* Maximum total bound parameters the driver will accept across one
|
|
47
|
+
* `batch()` call. D1 caps at ~1000 bound parameters per batch — separate
|
|
48
|
+
* from `maxBatchSize`. Most cascade/bulk batches consist of 2-param
|
|
49
|
+
* `DELETE` statements so this rarely triggers, but driver authors should
|
|
50
|
+
* declare it for safety. When `undefined`, the backend doesn't split on
|
|
51
|
+
* parameter count.
|
|
52
|
+
*/
|
|
53
|
+
readonly maxBatchParams?: number;
|
|
54
|
+
}
|
|
55
|
+
interface SqliteTxExecutor {
|
|
56
|
+
all(sql: string, params: unknown[]): Promise<Record<string, unknown>[]>;
|
|
57
|
+
run(sql: string, params: unknown[]): Promise<void>;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* SQLite implementation of `StorageBackend`.
|
|
62
|
+
*
|
|
63
|
+
* Table-per-graph design: the root graph lives in `tableName`, and each
|
|
64
|
+
* subgraph lives in its own physical table (`<tableName>_g_<mangled scope>`,
|
|
65
|
+
* see `tableForScope`). There is no `scope` column — the table a row lives
|
|
66
|
+
* in *is* its scope, exactly like the Cloudflare DO edition where each
|
|
67
|
+
* subgraph is its own Durable Object.
|
|
68
|
+
*
|
|
69
|
+
* A small catalog table (`<tableName>_graphs`) records every graph's
|
|
70
|
+
* storage scope → table mapping. Cascade delete prefix-matches descendant
|
|
71
|
+
* scopes in the catalog and drops each listed table — no registry topology
|
|
72
|
+
* required.
|
|
73
|
+
*
|
|
74
|
+
* Schema is ensured lazily: the first operation on a backend instance runs
|
|
75
|
+
* `CREATE TABLE IF NOT EXISTS` for the graph's table, its indexes, and the
|
|
76
|
+
* catalog, then registers the graph in the catalog. Callers no longer
|
|
77
|
+
* pre-create tables.
|
|
78
|
+
*/
|
|
79
|
+
|
|
80
|
+
interface SqliteBackendOptions {
|
|
81
|
+
/** Logical scope path (chained subgraph names) — used for `allowedIn` matching. */
|
|
82
|
+
scopePath?: string;
|
|
83
|
+
/**
|
|
84
|
+
* Internal storage scope (interleaved parent-uid/name path). Determines
|
|
85
|
+
* which physical table this backend reads and writes — `''` (the default)
|
|
86
|
+
* is the root graph in `tableName` itself.
|
|
87
|
+
*
|
|
88
|
+
* @internal Used by `subgraph()` to derive child backends. Setting it
|
|
89
|
+
* directly bypasses catalog registration consistency checks (the graph
|
|
90
|
+
* still self-registers, but ancestors are not validated) — always derive
|
|
91
|
+
* subgraph backends via `subgraph()` instead.
|
|
92
|
+
*/
|
|
93
|
+
storageScope?: string;
|
|
94
|
+
/**
|
|
95
|
+
* Registry contributing per-entry `indexes` declarations, applied to
|
|
96
|
+
* every graph table this backend (and its subgraphs) lazily creates.
|
|
97
|
+
*/
|
|
98
|
+
registry?: GraphRegistry;
|
|
99
|
+
/**
|
|
100
|
+
* Replaces the built-in core index preset for lazily created tables.
|
|
101
|
+
* Pass `[]` to disable core indexes entirely.
|
|
102
|
+
*/
|
|
103
|
+
coreIndexes?: IndexSpec[];
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Capability union declared by the SQLite-backed `StorageBackend`.
|
|
107
|
+
*
|
|
108
|
+
* `core.transactions` is part of the static union because `runTransaction`
|
|
109
|
+
* is always present as a method on the class. The runtime cap-set determines
|
|
110
|
+
* whether that method is *functional*: D1 leaves `executor.transaction`
|
|
111
|
+
* undefined and the call throws `UNSUPPORTED_OPERATION`; DO SQLite and
|
|
112
|
+
* better-sqlite3 wire the executor and the call works. The static type
|
|
113
|
+
* therefore promises only that the method exists — callers that care about
|
|
114
|
+
* portability check `client.capabilities.has('core.transactions')` before
|
|
115
|
+
* opening a tx, and code that runs against an unknown driver can rely on the
|
|
116
|
+
* runtime guard inside `runTransaction`.
|
|
117
|
+
*
|
|
118
|
+
* The `query.*` extension capabilities follow the same conservative
|
|
119
|
+
* declaration rule as the cap descriptor itself — only land in the union
|
|
120
|
+
* when the corresponding method is actually wired up. Today that's
|
|
121
|
+
* `query.aggregate` (Phase 4), `query.dml` (Phase 5), `query.join`
|
|
122
|
+
* (Phase 6 — fan-out via `IN (…)` in one statement), and `query.select`
|
|
123
|
+
* (Phase 7 — server-side projection via `json_extract`).
|
|
124
|
+
*/
|
|
125
|
+
type SqliteCapability = 'core.read' | 'core.write' | 'core.transactions' | 'core.batch' | 'core.subgraph' | 'query.aggregate' | 'query.dml' | 'query.join' | 'query.select' | 'raw.sql';
|
|
126
|
+
/**
|
|
127
|
+
* Create a SQLite-backed `StorageBackend`.
|
|
128
|
+
*
|
|
129
|
+
* `tableName` is the root graph's table; subgraphs get their own tables
|
|
130
|
+
* derived from it (see `tableForScope`). Schema (tables, indexes, and the
|
|
131
|
+
* graph catalog) is created lazily on first use — no manual DDL step.
|
|
132
|
+
* Pass `options.registry` so per-entry `indexes` declarations land in
|
|
133
|
+
* every lazily created table.
|
|
134
|
+
*/
|
|
135
|
+
declare function createSqliteBackend(executor: SqliteExecutor, tableName: string, options?: SqliteBackendOptions): StorageBackend<SqliteCapability>;
|
|
136
|
+
|
|
137
|
+
export { type SqliteBackendOptions as S, type SqliteCapability as a, type SqliteExecutor as b, createSqliteBackend as c };
|
package/dist/backend.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { C as CapabilityNotSupportedError, a as CrossBackendTransactionError } from './errors-BRc3I_eH.cjs';
|
|
2
|
-
import { S as StorageBackend, B as BackendCapabilities } from './backend-
|
|
3
|
-
export { a as BatchBackend, b as BulkUpdatePatch, D as DELETE_FIELD, c as DataPathOp, d as DmlExtension, E as ExpandParams, e as ExpandResult, J as JoinExtension, T as TransactionBackend, U as UpdatePayload, W as WritableRecord, f as WriteMode, g as createCapabilities, h as deleteField, i as flattenPatch, j as intersectCapabilities, k as isDeleteSentinel } from './backend-
|
|
2
|
+
import { S as StorageBackend, B as BackendCapabilities } from './backend-BpYLdwCW.cjs';
|
|
3
|
+
export { a as BatchBackend, b as BulkUpdatePatch, D as DELETE_FIELD, c as DataPathOp, d as DmlExtension, E as ExpandParams, e as ExpandResult, J as JoinExtension, T as TransactionBackend, U as UpdatePayload, W as WritableRecord, f as WriteMode, g as createCapabilities, h as deleteField, i as flattenPatch, j as intersectCapabilities, k as isDeleteSentinel } from './backend-BpYLdwCW.cjs';
|
|
4
4
|
export { S as StorageScopeSegment, a as appendStorageScope, i as isAncestorScopeUid, p as parseStorageScope, r as resolveAncestorScope } from './scope-path-CROFZGr9.cjs';
|
|
5
5
|
import '@google-cloud/firestore';
|
|
6
6
|
|
package/dist/backend.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { C as CapabilityNotSupportedError, a as CrossBackendTransactionError } from './errors-BRc3I_eH.js';
|
|
2
|
-
import { S as StorageBackend, B as BackendCapabilities } from './backend-
|
|
3
|
-
export { a as BatchBackend, b as BulkUpdatePatch, D as DELETE_FIELD, c as DataPathOp, d as DmlExtension, E as ExpandParams, e as ExpandResult, J as JoinExtension, T as TransactionBackend, U as UpdatePayload, W as WritableRecord, f as WriteMode, g as createCapabilities, h as deleteField, i as flattenPatch, j as intersectCapabilities, k as isDeleteSentinel } from './backend-
|
|
2
|
+
import { S as StorageBackend, B as BackendCapabilities } from './backend-BpYLdwCW.js';
|
|
3
|
+
export { a as BatchBackend, b as BulkUpdatePatch, D as DELETE_FIELD, c as DataPathOp, d as DmlExtension, E as ExpandParams, e as ExpandResult, J as JoinExtension, T as TransactionBackend, U as UpdatePayload, W as WritableRecord, f as WriteMode, g as createCapabilities, h as deleteField, i as flattenPatch, j as intersectCapabilities, k as isDeleteSentinel } from './backend-BpYLdwCW.js';
|
|
4
4
|
export { S as StorageScopeSegment, a as appendStorageScope, i as isAncestorScopeUid, p as parseStorageScope, r as resolveAncestorScope } from './scope-path-CROFZGr9.js';
|
|
5
5
|
import '@google-cloud/firestore';
|
|
6
6
|
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BUILTIN_FIELDS,
|
|
3
|
+
DEFAULT_QUERY_LIMIT,
|
|
4
|
+
NODE_RELATION,
|
|
5
|
+
computeEdgeDocId,
|
|
6
|
+
computeNodeDocId
|
|
7
|
+
} from "./chunk-NGAJCALM.js";
|
|
1
8
|
import {
|
|
2
9
|
DynamicRegistryError,
|
|
3
10
|
FiregraphError,
|
|
@@ -11,32 +18,6 @@ import {
|
|
|
11
18
|
flattenPatch
|
|
12
19
|
} from "./chunk-SIHE4UY4.js";
|
|
13
20
|
|
|
14
|
-
// src/internal/constants.ts
|
|
15
|
-
var NODE_RELATION = "is";
|
|
16
|
-
var DEFAULT_QUERY_LIMIT = 500;
|
|
17
|
-
var BUILTIN_FIELDS = /* @__PURE__ */ new Set([
|
|
18
|
-
"aType",
|
|
19
|
-
"aUid",
|
|
20
|
-
"axbType",
|
|
21
|
-
"bType",
|
|
22
|
-
"bUid",
|
|
23
|
-
"createdAt",
|
|
24
|
-
"updatedAt"
|
|
25
|
-
]);
|
|
26
|
-
var SHARD_SEPARATOR = ":";
|
|
27
|
-
|
|
28
|
-
// src/docid.ts
|
|
29
|
-
import { createHash } from "crypto";
|
|
30
|
-
function computeNodeDocId(uid) {
|
|
31
|
-
return uid;
|
|
32
|
-
}
|
|
33
|
-
function computeEdgeDocId(aUid, axbType, bUid) {
|
|
34
|
-
const composite = `${aUid}${SHARD_SEPARATOR}${axbType}${SHARD_SEPARATOR}${bUid}`;
|
|
35
|
-
const hash = createHash("sha256").update(composite).digest("hex");
|
|
36
|
-
const shard = hash[0];
|
|
37
|
-
return `${shard}${SHARD_SEPARATOR}${aUid}${SHARD_SEPARATOR}${axbType}${SHARD_SEPARATOR}${bUid}`;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
21
|
// src/json-schema.ts
|
|
41
22
|
import { Validator } from "@cfworker/json-schema";
|
|
42
23
|
var MAX_RENDERED_ERRORS = 20;
|
|
@@ -469,7 +450,7 @@ function discoveryToEntries(discovery) {
|
|
|
469
450
|
}
|
|
470
451
|
|
|
471
452
|
// src/sandbox.ts
|
|
472
|
-
import { createHash
|
|
453
|
+
import { createHash } from "crypto";
|
|
473
454
|
var _worker = null;
|
|
474
455
|
var _requestId = 0;
|
|
475
456
|
var _pending = /* @__PURE__ */ new Map();
|
|
@@ -646,7 +627,7 @@ function getExecutorCache(executor) {
|
|
|
646
627
|
return cache;
|
|
647
628
|
}
|
|
648
629
|
function hashSource(source) {
|
|
649
|
-
return
|
|
630
|
+
return createHash("sha256").update(source).digest("hex");
|
|
650
631
|
}
|
|
651
632
|
var _serializationModule = null;
|
|
652
633
|
async function loadSerialization() {
|
|
@@ -714,7 +695,7 @@ async function destroySandboxWorker() {
|
|
|
714
695
|
}
|
|
715
696
|
|
|
716
697
|
// src/dynamic-registry.ts
|
|
717
|
-
import { createHash as
|
|
698
|
+
import { createHash as createHash2 } from "crypto";
|
|
718
699
|
var META_NODE_TYPE = "nodeType";
|
|
719
700
|
var META_EDGE_TYPE = "edgeType";
|
|
720
701
|
var STORED_MIGRATION_STEP_SCHEMA = {
|
|
@@ -800,7 +781,7 @@ function createBootstrapRegistry() {
|
|
|
800
781
|
return _bootstrapRegistry;
|
|
801
782
|
}
|
|
802
783
|
function generateDeterministicUid(metaType, name) {
|
|
803
|
-
const hash =
|
|
784
|
+
const hash = createHash2("sha256").update(`${metaType}:${name}`).digest("base64url");
|
|
804
785
|
return hash.slice(0, 21);
|
|
805
786
|
}
|
|
806
787
|
async function createRegistryFromGraph(reader, executor) {
|
|
@@ -2023,10 +2004,6 @@ function generateId() {
|
|
|
2023
2004
|
}
|
|
2024
2005
|
|
|
2025
2006
|
export {
|
|
2026
|
-
NODE_RELATION,
|
|
2027
|
-
DEFAULT_QUERY_LIMIT,
|
|
2028
|
-
computeNodeDocId,
|
|
2029
|
-
computeEdgeDocId,
|
|
2030
2007
|
compileSchema,
|
|
2031
2008
|
jsonSchemaToFieldMeta,
|
|
2032
2009
|
applyMigrationChain,
|
|
@@ -2057,4 +2034,4 @@ export {
|
|
|
2057
2034
|
createGraphClientFromBackend,
|
|
2058
2035
|
generateId
|
|
2059
2036
|
};
|
|
2060
|
-
//# sourceMappingURL=chunk-
|
|
2037
|
+
//# sourceMappingURL=chunk-5HIRYV2S.js.map
|