@typicalday/firegraph 0.10.0 → 0.11.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 +93 -90
- package/bin/firegraph.mjs +21 -7
- package/dist/{backend-BrqFkbid.d.ts → backend-U-MLShlg.d.ts} +1 -1
- package/dist/{backend-73p5Blx7.d.cts → backend-np4gEVhB.d.cts} +1 -1
- package/dist/backend.d.cts +3 -3
- package/dist/backend.d.ts +3 -3
- package/dist/{chunk-LZOIQHYN.js → chunk-6SB34IPQ.js} +20 -7
- package/dist/chunk-6SB34IPQ.js.map +1 -0
- package/dist/{chunk-SU4FNLC3.js → chunk-EEKWRX5E.js} +1 -1
- package/dist/{chunk-SU4FNLC3.js.map → chunk-EEKWRX5E.js.map} +1 -1
- package/dist/{chunk-YLGXLEUE.js → chunk-GJVVRTQT.js} +5 -14
- package/dist/chunk-GJVVRTQT.js.map +1 -0
- package/dist/cloudflare/index.cjs +151 -27
- package/dist/cloudflare/index.cjs.map +1 -1
- package/dist/cloudflare/index.d.cts +78 -3
- package/dist/cloudflare/index.d.ts +78 -3
- package/dist/cloudflare/index.js +135 -23
- package/dist/cloudflare/index.js.map +1 -1
- package/dist/codegen/index.cjs +4 -13
- package/dist/codegen/index.cjs.map +1 -1
- package/dist/codegen/index.d.cts +1 -1
- package/dist/codegen/index.d.ts +1 -1
- package/dist/codegen/index.js +1 -1
- package/dist/index.cjs +89 -132
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +106 -21
- package/dist/index.d.ts +106 -21
- package/dist/index.js +70 -116
- package/dist/index.js.map +1 -1
- package/dist/query-client/index.cjs.map +1 -1
- package/dist/query-client/index.js +1 -1
- package/dist/{types-DOemdlVA.d.ts → types-BGWxcpI_.d.cts} +75 -1
- package/dist/{types-DOemdlVA.d.cts → types-BGWxcpI_.d.ts} +75 -1
- package/package.json +35 -27
- package/dist/chunk-LZOIQHYN.js.map +0 -1
- package/dist/chunk-YLGXLEUE.js.map +0 -1
- package/dist/editor/client/assets/index-Bq2bfzeY.js +0 -411
- package/dist/editor/client/assets/index-CJ4m_EOL.css +0 -1
- package/dist/editor/client/index.html +0 -16
- package/dist/editor/server/index.mjs +0 -51566
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { S as StorageBackend } from './backend-
|
|
2
|
-
import { G as GraphClientOptions, a as GraphClient, D as DynamicGraphClient, b as DiscoveryResult, R as RegistryEntry, c as GraphRegistry, d as GraphReader, M as MigrationExecutor, e as DynamicRegistryConfig, S as StoredGraphRecord, f as MigrationWriteBack, g as MigrationStep, F as FindEdgesParams, Q as QueryPlan, h as FindNodesParams, i as QueryFilter, j as GraphRecord, k as MigrationFn, l as StoredMigrationStep, T as TraversalBuilder } from './types-
|
|
3
|
-
export { B as BulkBatchError, m as BulkOptions, n as BulkProgress, o as BulkResult, C as CascadeResult, p as DefineTypeOptions, q as DiscoveredEntity, E as EdgeTopology, r as EdgeTypeData, s as FiregraphConfig, t as GraphBatch, u as GraphTransaction, v as GraphWriter, H as HopDefinition, w as HopResult, N as NodeTypeData,
|
|
1
|
+
import { S as StorageBackend } from './backend-np4gEVhB.cjs';
|
|
2
|
+
import { G as GraphClientOptions, a as GraphClient, D as DynamicGraphClient, I as IndexSpec, b as DiscoveryResult, R as RegistryEntry, c as GraphRegistry, d as GraphReader, M as MigrationExecutor, e as DynamicRegistryConfig, S as StoredGraphRecord, f as MigrationWriteBack, g as MigrationStep, F as FindEdgesParams, Q as QueryPlan, h as FindNodesParams, i as QueryFilter, j as GraphRecord, k as MigrationFn, l as StoredMigrationStep, T as TraversalBuilder } from './types-BGWxcpI_.cjs';
|
|
3
|
+
export { B as BulkBatchError, m as BulkOptions, n as BulkProgress, o as BulkResult, C as CascadeResult, p as DefineTypeOptions, q as DiscoveredEntity, E as EdgeTopology, r as EdgeTypeData, s as FiregraphConfig, t as GraphBatch, u as GraphTransaction, v as GraphWriter, H as HopDefinition, w as HopResult, x as IndexFieldSpec, N as NodeTypeData, y as QueryMode, z as QueryOptions, A as ScanProtection, J as TraversalOptions, K as TraversalResult, V as ViewContext, L as ViewDefaultsConfig, O as ViewResolverConfig, W as WhereClause, P as defineConfig, U as resolveView } from './types-BGWxcpI_.cjs';
|
|
4
4
|
export { CodegenOptions, generateTypes } from './codegen/index.cjs';
|
|
5
5
|
import { F as FiregraphError } from './scope-path-B1G3YiA7.cjs';
|
|
6
6
|
export { C as CrossBackendTransactionError, D as DynamicRegistryError, E as EdgeNotFoundError, I as InvalidQueryError, M as MigrationError, N as NodeNotFoundError, Q as QuerySafetyError, R as RegistryScopeError, b as RegistryViolationError, S as StorageScopeSegment, T as TraversalError, V as ValidationError, a as appendStorageScope, i as isAncestorScopeUid, p as parseStorageScope, r as resolveAncestorScope } from './scope-path-B1G3YiA7.cjs';
|
|
@@ -64,6 +64,54 @@ declare function resolveAncestorCollection(collectionPath: string, uid: string):
|
|
|
64
64
|
*/
|
|
65
65
|
declare function isAncestorUid(collectionPath: string, uid: string): boolean;
|
|
66
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Default core index preset.
|
|
69
|
+
*
|
|
70
|
+
* This set covers the query patterns firegraph's query planner emits for
|
|
71
|
+
* built-in operations — `findNodes`, `findEdges`, cascade delete, traversal,
|
|
72
|
+
* and the DO/SQLite path compilers. Apps that need additional indexes
|
|
73
|
+
* (descending timestamps, `data.*` filters, composite fields unique to
|
|
74
|
+
* their query shapes) declare them on `RegistryEntry.indexes` or override
|
|
75
|
+
* this preset wholesale via the backend-specific `coreIndexes` option —
|
|
76
|
+
* `FiregraphDOOptions.coreIndexes` for the DO backend,
|
|
77
|
+
* `BuildSchemaOptions.coreIndexes` for the legacy SQLite backend, and
|
|
78
|
+
* `GenerateIndexOptions.coreIndexes` for the Firestore CLI generator.
|
|
79
|
+
*
|
|
80
|
+
* ## Ownership model
|
|
81
|
+
*
|
|
82
|
+
* This list is firegraph's *recommendation* — not non-negotiable policy.
|
|
83
|
+
* Consumers can:
|
|
84
|
+
*
|
|
85
|
+
* 1. Accept the preset as-is (default).
|
|
86
|
+
* 2. Extend it: `coreIndexes: [...DEFAULT_CORE_INDEXES, ...more]`.
|
|
87
|
+
* 3. Replace it entirely with a tailored set.
|
|
88
|
+
* 4. Disable it (`coreIndexes: []`) and take full responsibility for
|
|
89
|
+
* index coverage — only do this if you're provisioning a complete
|
|
90
|
+
* custom set.
|
|
91
|
+
*
|
|
92
|
+
* ## Per-backend emission
|
|
93
|
+
*
|
|
94
|
+
* The Firestore generator skips single-field entries (Firestore implicitly
|
|
95
|
+
* indexes every field) and emits one composite index per multi-field spec.
|
|
96
|
+
* The SQLite-flavored generators (DO, legacy) emit every spec as-is.
|
|
97
|
+
*
|
|
98
|
+
* ## Why these specific indexes
|
|
99
|
+
*
|
|
100
|
+
* - `aUid` / `bUid` — required for `_fgRemoveNodeCascade`, which scans by
|
|
101
|
+
* each UID side independently. A composite `(aUid, axbType)` also
|
|
102
|
+
* satisfies `aUid`-alone via leading-column prefix, but the single-field
|
|
103
|
+
* form is cheaper for the common case.
|
|
104
|
+
* - `aType` / `bType` — `findNodes({ aType })` and cross-type enumeration.
|
|
105
|
+
* - `(aUid, axbType)` — forward edge lookup (`findEdges({ aUid, axbType })`)
|
|
106
|
+
* and the `get` strategy fallback when only two of three triple fields
|
|
107
|
+
* are present.
|
|
108
|
+
* - `(axbType, bUid)` — reverse edge traversal.
|
|
109
|
+
* - `(aType, axbType)` — type-scoped edge scans (e.g., `findEdges({ aType, axbType })`).
|
|
110
|
+
* - `(axbType, bType)` — scope edges of one relation to a target type.
|
|
111
|
+
*/
|
|
112
|
+
|
|
113
|
+
declare const DEFAULT_CORE_INDEXES: ReadonlyArray<IndexSpec>;
|
|
114
|
+
|
|
67
115
|
/**
|
|
68
116
|
* Entity Discovery — convention-based auto-discovery of entities from
|
|
69
117
|
* a per-entity folder structure.
|
|
@@ -168,6 +216,33 @@ declare function createGraphClient(db: Firestore, collectionPath: string, option
|
|
|
168
216
|
|
|
169
217
|
declare function generateId(): string;
|
|
170
218
|
|
|
219
|
+
/**
|
|
220
|
+
* Firestore composite index generator.
|
|
221
|
+
*
|
|
222
|
+
* Translates firegraph's declarative `IndexSpec[]` (core preset plus per-entry
|
|
223
|
+
* registry indexes) into the `firestore.indexes.json` shape consumed by
|
|
224
|
+
* `firebase deploy --only firestore:indexes`.
|
|
225
|
+
*
|
|
226
|
+
* ## What Firestore needs
|
|
227
|
+
*
|
|
228
|
+
* Firestore auto-indexes every top-level field (including `data.*`) for
|
|
229
|
+
* single-field equality queries — we only need to emit *composite* indexes
|
|
230
|
+
* here. That means:
|
|
231
|
+
*
|
|
232
|
+
* 1. Single-field specs are dropped (Firestore already covers them).
|
|
233
|
+
* 2. Composite specs (two or more fields) get one `FirestoreIndex`.
|
|
234
|
+
* 3. Specs with `where` are dropped with a warning — Firestore composite
|
|
235
|
+
* indexes do not support partial predicates.
|
|
236
|
+
* 4. When a registry entry has `targetGraph` set, every composite is also
|
|
237
|
+
* emitted with `queryScope: 'COLLECTION_GROUP'` under the targetGraph
|
|
238
|
+
* name, so `findEdgesGlobal()` queries across subgraphs can hit an
|
|
239
|
+
* index.
|
|
240
|
+
*
|
|
241
|
+
* The SQLite-flavored backends (DO, legacy) consume the same `IndexSpec[]`
|
|
242
|
+
* via `src/internal/sqlite-index-ddl.ts` but emit every spec (single fields
|
|
243
|
+
* included) as `CREATE INDEX` DDL.
|
|
244
|
+
*/
|
|
245
|
+
|
|
171
246
|
interface FirestoreIndexField {
|
|
172
247
|
fieldPath: string;
|
|
173
248
|
order: 'ASCENDING' | 'DESCENDING';
|
|
@@ -181,25 +256,35 @@ interface FirestoreIndexConfig {
|
|
|
181
256
|
indexes: FirestoreIndex[];
|
|
182
257
|
fieldOverrides: unknown[];
|
|
183
258
|
}
|
|
259
|
+
interface GenerateIndexOptions {
|
|
260
|
+
/**
|
|
261
|
+
* Replaces firegraph's built-in core preset. Defaults to
|
|
262
|
+
* `DEFAULT_CORE_INDEXES`. Pass `[]` to disable core indexes entirely.
|
|
263
|
+
*/
|
|
264
|
+
coreIndexes?: IndexSpec[];
|
|
265
|
+
/**
|
|
266
|
+
* Registry entries supplying per-triple `indexes`. Entries without
|
|
267
|
+
* `indexes` contribute no composites; entries with `targetGraph` also
|
|
268
|
+
* trigger `COLLECTION_GROUP` mirrors under each distinct targetGraph
|
|
269
|
+
* segment name.
|
|
270
|
+
*/
|
|
271
|
+
registryEntries?: ReadonlyArray<RegistryEntry>;
|
|
272
|
+
/**
|
|
273
|
+
* Entity discovery result. Convenience for callers that have a
|
|
274
|
+
* `DiscoveryResult` but not a built registry — treated as if every
|
|
275
|
+
* discovered entity were expanded to its registry entries carrying just
|
|
276
|
+
* `indexes` + `targetGraph`. Mutually usable with `registryEntries`
|
|
277
|
+
* (both are concatenated and deduplicated at the spec level).
|
|
278
|
+
*/
|
|
279
|
+
entities?: DiscoveryResult;
|
|
280
|
+
}
|
|
184
281
|
/**
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
* patterns on node data fields:
|
|
190
|
-
* (aType, axbType, data.{field})
|
|
191
|
-
*
|
|
192
|
-
* When registry entries with `targetGraph` are provided, also generates
|
|
193
|
-
* collection group indexes for `findEdgesGlobal()` queries. The collection
|
|
194
|
-
* group name defaults to `'graph'` (the standard subgraph name) but can be
|
|
195
|
-
* overridden per `targetGraph` value.
|
|
196
|
-
*
|
|
197
|
-
* @param collection - Firestore collection name (e.g. 'graph')
|
|
198
|
-
* @param entities - Optional discovery result for per-entity data field indexes
|
|
199
|
-
* @param registryEntries - Optional registry entries; when any have `targetGraph`,
|
|
200
|
-
* collection group indexes are generated for the distinct subgraph names
|
|
282
|
+
* Build a Firestore index configuration from firegraph's declarative index
|
|
283
|
+
* specs. Deduplicates by field list + scope before emitting. Single-field
|
|
284
|
+
* specs are dropped; partial-index specs (`where` set) are dropped with a
|
|
285
|
+
* one-time warning.
|
|
201
286
|
*/
|
|
202
|
-
declare function generateIndexConfig(collection: string,
|
|
287
|
+
declare function generateIndexConfig(collection: string, options?: GenerateIndexOptions): FirestoreIndexConfig;
|
|
203
288
|
|
|
204
289
|
/**
|
|
205
290
|
* Default result limit applied to findEdges/findNodes queries
|
|
@@ -495,4 +580,4 @@ declare function deserializeFirestoreTypes(data: Record<string, unknown>, db?: F
|
|
|
495
580
|
*/
|
|
496
581
|
declare function createTraversal(reader: GraphClient | GraphReader, startUid: string, registry?: GraphRegistry): TraversalBuilder;
|
|
497
582
|
|
|
498
|
-
export { BOOTSTRAP_ENTRIES, DEFAULT_QUERY_LIMIT, type DiscoverResult, DiscoveryError, DiscoveryResult, type DiscoveryWarning, DynamicGraphClient, DynamicRegistryConfig, EDGE_TYPE_SCHEMA, type FieldMeta, FindEdgesParams, FindNodesParams, FiregraphError, type FirestoreIndex, type FirestoreIndexConfig, type FirestoreIndexField, GraphClient, GraphClientOptions, GraphReader, GraphRecord, GraphRegistry, META_EDGE_TYPE, META_NODE_TYPE, MigrationExecutor, MigrationFn, type MigrationResult, MigrationStep, MigrationWriteBack, NODE_TYPE_SCHEMA, QueryFilter, QueryPlan, type QuerySafetyResult, RegistryEntry, SERIALIZATION_TAG, StoredGraphRecord, StoredMigrationStep, TraversalBuilder, analyzeQuerySafety, applyMigrationChain, buildEdgeQueryPlan, buildEdgeRecord, buildNodeQueryPlan, buildNodeRecord, compileMigrationFn, compileMigrations, compileSchema, computeEdgeDocId, computeNodeDocId, createBootstrapRegistry, createGraphClient, createGraphClientFromBackend, createMergedRegistry, createRegistry, createRegistryFromGraph, createTraversal, defaultExecutor, deserializeFirestoreTypes, destroySandboxWorker, discoverEntities, generateDeterministicUid, generateId, generateIndexConfig, isAncestorUid, isTaggedValue, jsonSchemaToFieldMeta, matchScope, matchScopeAny, migrateRecord, migrateRecords, precompileSource, resolveAncestorCollection, serializeFirestoreTypes, validateMigrationChain };
|
|
583
|
+
export { BOOTSTRAP_ENTRIES, DEFAULT_CORE_INDEXES, DEFAULT_QUERY_LIMIT, type DiscoverResult, DiscoveryError, DiscoveryResult, type DiscoveryWarning, DynamicGraphClient, DynamicRegistryConfig, EDGE_TYPE_SCHEMA, type FieldMeta, FindEdgesParams, FindNodesParams, FiregraphError, type FirestoreIndex, type FirestoreIndexConfig, type FirestoreIndexField, type GenerateIndexOptions, GraphClient, GraphClientOptions, GraphReader, GraphRecord, GraphRegistry, IndexSpec, META_EDGE_TYPE, META_NODE_TYPE, MigrationExecutor, MigrationFn, type MigrationResult, MigrationStep, MigrationWriteBack, NODE_TYPE_SCHEMA, QueryFilter, QueryPlan, type QuerySafetyResult, RegistryEntry, SERIALIZATION_TAG, StoredGraphRecord, StoredMigrationStep, TraversalBuilder, analyzeQuerySafety, applyMigrationChain, buildEdgeQueryPlan, buildEdgeRecord, buildNodeQueryPlan, buildNodeRecord, compileMigrationFn, compileMigrations, compileSchema, computeEdgeDocId, computeNodeDocId, createBootstrapRegistry, createGraphClient, createGraphClientFromBackend, createMergedRegistry, createRegistry, createRegistryFromGraph, createTraversal, defaultExecutor, deserializeFirestoreTypes, destroySandboxWorker, discoverEntities, generateDeterministicUid, generateId, generateIndexConfig, isAncestorUid, isTaggedValue, jsonSchemaToFieldMeta, matchScope, matchScopeAny, migrateRecord, migrateRecords, precompileSource, resolveAncestorCollection, serializeFirestoreTypes, validateMigrationChain };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { S as StorageBackend } from './backend-
|
|
2
|
-
import { G as GraphClientOptions, a as GraphClient, D as DynamicGraphClient, b as DiscoveryResult, R as RegistryEntry, c as GraphRegistry, d as GraphReader, M as MigrationExecutor, e as DynamicRegistryConfig, S as StoredGraphRecord, f as MigrationWriteBack, g as MigrationStep, F as FindEdgesParams, Q as QueryPlan, h as FindNodesParams, i as QueryFilter, j as GraphRecord, k as MigrationFn, l as StoredMigrationStep, T as TraversalBuilder } from './types-
|
|
3
|
-
export { B as BulkBatchError, m as BulkOptions, n as BulkProgress, o as BulkResult, C as CascadeResult, p as DefineTypeOptions, q as DiscoveredEntity, E as EdgeTopology, r as EdgeTypeData, s as FiregraphConfig, t as GraphBatch, u as GraphTransaction, v as GraphWriter, H as HopDefinition, w as HopResult, N as NodeTypeData,
|
|
1
|
+
import { S as StorageBackend } from './backend-U-MLShlg.js';
|
|
2
|
+
import { G as GraphClientOptions, a as GraphClient, D as DynamicGraphClient, I as IndexSpec, b as DiscoveryResult, R as RegistryEntry, c as GraphRegistry, d as GraphReader, M as MigrationExecutor, e as DynamicRegistryConfig, S as StoredGraphRecord, f as MigrationWriteBack, g as MigrationStep, F as FindEdgesParams, Q as QueryPlan, h as FindNodesParams, i as QueryFilter, j as GraphRecord, k as MigrationFn, l as StoredMigrationStep, T as TraversalBuilder } from './types-BGWxcpI_.js';
|
|
3
|
+
export { B as BulkBatchError, m as BulkOptions, n as BulkProgress, o as BulkResult, C as CascadeResult, p as DefineTypeOptions, q as DiscoveredEntity, E as EdgeTopology, r as EdgeTypeData, s as FiregraphConfig, t as GraphBatch, u as GraphTransaction, v as GraphWriter, H as HopDefinition, w as HopResult, x as IndexFieldSpec, N as NodeTypeData, y as QueryMode, z as QueryOptions, A as ScanProtection, J as TraversalOptions, K as TraversalResult, V as ViewContext, L as ViewDefaultsConfig, O as ViewResolverConfig, W as WhereClause, P as defineConfig, U as resolveView } from './types-BGWxcpI_.js';
|
|
4
4
|
export { CodegenOptions, generateTypes } from './codegen/index.js';
|
|
5
5
|
import { F as FiregraphError } from './scope-path-B1G3YiA7.js';
|
|
6
6
|
export { C as CrossBackendTransactionError, D as DynamicRegistryError, E as EdgeNotFoundError, I as InvalidQueryError, M as MigrationError, N as NodeNotFoundError, Q as QuerySafetyError, R as RegistryScopeError, b as RegistryViolationError, S as StorageScopeSegment, T as TraversalError, V as ValidationError, a as appendStorageScope, i as isAncestorScopeUid, p as parseStorageScope, r as resolveAncestorScope } from './scope-path-B1G3YiA7.js';
|
|
@@ -64,6 +64,54 @@ declare function resolveAncestorCollection(collectionPath: string, uid: string):
|
|
|
64
64
|
*/
|
|
65
65
|
declare function isAncestorUid(collectionPath: string, uid: string): boolean;
|
|
66
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Default core index preset.
|
|
69
|
+
*
|
|
70
|
+
* This set covers the query patterns firegraph's query planner emits for
|
|
71
|
+
* built-in operations — `findNodes`, `findEdges`, cascade delete, traversal,
|
|
72
|
+
* and the DO/SQLite path compilers. Apps that need additional indexes
|
|
73
|
+
* (descending timestamps, `data.*` filters, composite fields unique to
|
|
74
|
+
* their query shapes) declare them on `RegistryEntry.indexes` or override
|
|
75
|
+
* this preset wholesale via the backend-specific `coreIndexes` option —
|
|
76
|
+
* `FiregraphDOOptions.coreIndexes` for the DO backend,
|
|
77
|
+
* `BuildSchemaOptions.coreIndexes` for the legacy SQLite backend, and
|
|
78
|
+
* `GenerateIndexOptions.coreIndexes` for the Firestore CLI generator.
|
|
79
|
+
*
|
|
80
|
+
* ## Ownership model
|
|
81
|
+
*
|
|
82
|
+
* This list is firegraph's *recommendation* — not non-negotiable policy.
|
|
83
|
+
* Consumers can:
|
|
84
|
+
*
|
|
85
|
+
* 1. Accept the preset as-is (default).
|
|
86
|
+
* 2. Extend it: `coreIndexes: [...DEFAULT_CORE_INDEXES, ...more]`.
|
|
87
|
+
* 3. Replace it entirely with a tailored set.
|
|
88
|
+
* 4. Disable it (`coreIndexes: []`) and take full responsibility for
|
|
89
|
+
* index coverage — only do this if you're provisioning a complete
|
|
90
|
+
* custom set.
|
|
91
|
+
*
|
|
92
|
+
* ## Per-backend emission
|
|
93
|
+
*
|
|
94
|
+
* The Firestore generator skips single-field entries (Firestore implicitly
|
|
95
|
+
* indexes every field) and emits one composite index per multi-field spec.
|
|
96
|
+
* The SQLite-flavored generators (DO, legacy) emit every spec as-is.
|
|
97
|
+
*
|
|
98
|
+
* ## Why these specific indexes
|
|
99
|
+
*
|
|
100
|
+
* - `aUid` / `bUid` — required for `_fgRemoveNodeCascade`, which scans by
|
|
101
|
+
* each UID side independently. A composite `(aUid, axbType)` also
|
|
102
|
+
* satisfies `aUid`-alone via leading-column prefix, but the single-field
|
|
103
|
+
* form is cheaper for the common case.
|
|
104
|
+
* - `aType` / `bType` — `findNodes({ aType })` and cross-type enumeration.
|
|
105
|
+
* - `(aUid, axbType)` — forward edge lookup (`findEdges({ aUid, axbType })`)
|
|
106
|
+
* and the `get` strategy fallback when only two of three triple fields
|
|
107
|
+
* are present.
|
|
108
|
+
* - `(axbType, bUid)` — reverse edge traversal.
|
|
109
|
+
* - `(aType, axbType)` — type-scoped edge scans (e.g., `findEdges({ aType, axbType })`).
|
|
110
|
+
* - `(axbType, bType)` — scope edges of one relation to a target type.
|
|
111
|
+
*/
|
|
112
|
+
|
|
113
|
+
declare const DEFAULT_CORE_INDEXES: ReadonlyArray<IndexSpec>;
|
|
114
|
+
|
|
67
115
|
/**
|
|
68
116
|
* Entity Discovery — convention-based auto-discovery of entities from
|
|
69
117
|
* a per-entity folder structure.
|
|
@@ -168,6 +216,33 @@ declare function createGraphClient(db: Firestore, collectionPath: string, option
|
|
|
168
216
|
|
|
169
217
|
declare function generateId(): string;
|
|
170
218
|
|
|
219
|
+
/**
|
|
220
|
+
* Firestore composite index generator.
|
|
221
|
+
*
|
|
222
|
+
* Translates firegraph's declarative `IndexSpec[]` (core preset plus per-entry
|
|
223
|
+
* registry indexes) into the `firestore.indexes.json` shape consumed by
|
|
224
|
+
* `firebase deploy --only firestore:indexes`.
|
|
225
|
+
*
|
|
226
|
+
* ## What Firestore needs
|
|
227
|
+
*
|
|
228
|
+
* Firestore auto-indexes every top-level field (including `data.*`) for
|
|
229
|
+
* single-field equality queries — we only need to emit *composite* indexes
|
|
230
|
+
* here. That means:
|
|
231
|
+
*
|
|
232
|
+
* 1. Single-field specs are dropped (Firestore already covers them).
|
|
233
|
+
* 2. Composite specs (two or more fields) get one `FirestoreIndex`.
|
|
234
|
+
* 3. Specs with `where` are dropped with a warning — Firestore composite
|
|
235
|
+
* indexes do not support partial predicates.
|
|
236
|
+
* 4. When a registry entry has `targetGraph` set, every composite is also
|
|
237
|
+
* emitted with `queryScope: 'COLLECTION_GROUP'` under the targetGraph
|
|
238
|
+
* name, so `findEdgesGlobal()` queries across subgraphs can hit an
|
|
239
|
+
* index.
|
|
240
|
+
*
|
|
241
|
+
* The SQLite-flavored backends (DO, legacy) consume the same `IndexSpec[]`
|
|
242
|
+
* via `src/internal/sqlite-index-ddl.ts` but emit every spec (single fields
|
|
243
|
+
* included) as `CREATE INDEX` DDL.
|
|
244
|
+
*/
|
|
245
|
+
|
|
171
246
|
interface FirestoreIndexField {
|
|
172
247
|
fieldPath: string;
|
|
173
248
|
order: 'ASCENDING' | 'DESCENDING';
|
|
@@ -181,25 +256,35 @@ interface FirestoreIndexConfig {
|
|
|
181
256
|
indexes: FirestoreIndex[];
|
|
182
257
|
fieldOverrides: unknown[];
|
|
183
258
|
}
|
|
259
|
+
interface GenerateIndexOptions {
|
|
260
|
+
/**
|
|
261
|
+
* Replaces firegraph's built-in core preset. Defaults to
|
|
262
|
+
* `DEFAULT_CORE_INDEXES`. Pass `[]` to disable core indexes entirely.
|
|
263
|
+
*/
|
|
264
|
+
coreIndexes?: IndexSpec[];
|
|
265
|
+
/**
|
|
266
|
+
* Registry entries supplying per-triple `indexes`. Entries without
|
|
267
|
+
* `indexes` contribute no composites; entries with `targetGraph` also
|
|
268
|
+
* trigger `COLLECTION_GROUP` mirrors under each distinct targetGraph
|
|
269
|
+
* segment name.
|
|
270
|
+
*/
|
|
271
|
+
registryEntries?: ReadonlyArray<RegistryEntry>;
|
|
272
|
+
/**
|
|
273
|
+
* Entity discovery result. Convenience for callers that have a
|
|
274
|
+
* `DiscoveryResult` but not a built registry — treated as if every
|
|
275
|
+
* discovered entity were expanded to its registry entries carrying just
|
|
276
|
+
* `indexes` + `targetGraph`. Mutually usable with `registryEntries`
|
|
277
|
+
* (both are concatenated and deduplicated at the spec level).
|
|
278
|
+
*/
|
|
279
|
+
entities?: DiscoveryResult;
|
|
280
|
+
}
|
|
184
281
|
/**
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
* patterns on node data fields:
|
|
190
|
-
* (aType, axbType, data.{field})
|
|
191
|
-
*
|
|
192
|
-
* When registry entries with `targetGraph` are provided, also generates
|
|
193
|
-
* collection group indexes for `findEdgesGlobal()` queries. The collection
|
|
194
|
-
* group name defaults to `'graph'` (the standard subgraph name) but can be
|
|
195
|
-
* overridden per `targetGraph` value.
|
|
196
|
-
*
|
|
197
|
-
* @param collection - Firestore collection name (e.g. 'graph')
|
|
198
|
-
* @param entities - Optional discovery result for per-entity data field indexes
|
|
199
|
-
* @param registryEntries - Optional registry entries; when any have `targetGraph`,
|
|
200
|
-
* collection group indexes are generated for the distinct subgraph names
|
|
282
|
+
* Build a Firestore index configuration from firegraph's declarative index
|
|
283
|
+
* specs. Deduplicates by field list + scope before emitting. Single-field
|
|
284
|
+
* specs are dropped; partial-index specs (`where` set) are dropped with a
|
|
285
|
+
* one-time warning.
|
|
201
286
|
*/
|
|
202
|
-
declare function generateIndexConfig(collection: string,
|
|
287
|
+
declare function generateIndexConfig(collection: string, options?: GenerateIndexOptions): FirestoreIndexConfig;
|
|
203
288
|
|
|
204
289
|
/**
|
|
205
290
|
* Default result limit applied to findEdges/findNodes queries
|
|
@@ -495,4 +580,4 @@ declare function deserializeFirestoreTypes(data: Record<string, unknown>, db?: F
|
|
|
495
580
|
*/
|
|
496
581
|
declare function createTraversal(reader: GraphClient | GraphReader, startUid: string, registry?: GraphRegistry): TraversalBuilder;
|
|
497
582
|
|
|
498
|
-
export { BOOTSTRAP_ENTRIES, DEFAULT_QUERY_LIMIT, type DiscoverResult, DiscoveryError, DiscoveryResult, type DiscoveryWarning, DynamicGraphClient, DynamicRegistryConfig, EDGE_TYPE_SCHEMA, type FieldMeta, FindEdgesParams, FindNodesParams, FiregraphError, type FirestoreIndex, type FirestoreIndexConfig, type FirestoreIndexField, GraphClient, GraphClientOptions, GraphReader, GraphRecord, GraphRegistry, META_EDGE_TYPE, META_NODE_TYPE, MigrationExecutor, MigrationFn, type MigrationResult, MigrationStep, MigrationWriteBack, NODE_TYPE_SCHEMA, QueryFilter, QueryPlan, type QuerySafetyResult, RegistryEntry, SERIALIZATION_TAG, StoredGraphRecord, StoredMigrationStep, TraversalBuilder, analyzeQuerySafety, applyMigrationChain, buildEdgeQueryPlan, buildEdgeRecord, buildNodeQueryPlan, buildNodeRecord, compileMigrationFn, compileMigrations, compileSchema, computeEdgeDocId, computeNodeDocId, createBootstrapRegistry, createGraphClient, createGraphClientFromBackend, createMergedRegistry, createRegistry, createRegistryFromGraph, createTraversal, defaultExecutor, deserializeFirestoreTypes, destroySandboxWorker, discoverEntities, generateDeterministicUid, generateId, generateIndexConfig, isAncestorUid, isTaggedValue, jsonSchemaToFieldMeta, matchScope, matchScopeAny, migrateRecord, migrateRecords, precompileSource, resolveAncestorCollection, serializeFirestoreTypes, validateMigrationChain };
|
|
583
|
+
export { BOOTSTRAP_ENTRIES, DEFAULT_CORE_INDEXES, DEFAULT_QUERY_LIMIT, type DiscoverResult, DiscoveryError, DiscoveryResult, type DiscoveryWarning, DynamicGraphClient, DynamicRegistryConfig, EDGE_TYPE_SCHEMA, type FieldMeta, FindEdgesParams, FindNodesParams, FiregraphError, type FirestoreIndex, type FirestoreIndexConfig, type FirestoreIndexField, type GenerateIndexOptions, GraphClient, GraphClientOptions, GraphReader, GraphRecord, GraphRegistry, IndexSpec, META_EDGE_TYPE, META_NODE_TYPE, MigrationExecutor, MigrationFn, type MigrationResult, MigrationStep, MigrationWriteBack, NODE_TYPE_SCHEMA, QueryFilter, QueryPlan, type QuerySafetyResult, RegistryEntry, SERIALIZATION_TAG, StoredGraphRecord, StoredMigrationStep, TraversalBuilder, analyzeQuerySafety, applyMigrationChain, buildEdgeQueryPlan, buildEdgeRecord, buildNodeQueryPlan, buildNodeRecord, compileMigrationFn, compileMigrations, compileSchema, computeEdgeDocId, computeNodeDocId, createBootstrapRegistry, createGraphClient, createGraphClientFromBackend, createMergedRegistry, createRegistry, createRegistryFromGraph, createTraversal, defaultExecutor, deserializeFirestoreTypes, destroySandboxWorker, discoverEntities, generateDeterministicUid, generateId, generateIndexConfig, isAncestorUid, isTaggedValue, jsonSchemaToFieldMeta, matchScope, matchScopeAny, migrateRecord, migrateRecords, precompileSource, resolveAncestorCollection, serializeFirestoreTypes, validateMigrationChain };
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
} from "./chunk-TYYPRVIE.js";
|
|
7
7
|
import {
|
|
8
8
|
BOOTSTRAP_ENTRIES,
|
|
9
|
+
DEFAULT_CORE_INDEXES,
|
|
9
10
|
DEFAULT_QUERY_LIMIT,
|
|
10
11
|
EDGE_TYPE_SCHEMA,
|
|
11
12
|
GraphClientImpl,
|
|
@@ -37,7 +38,7 @@ import {
|
|
|
37
38
|
migrateRecords,
|
|
38
39
|
precompileSource,
|
|
39
40
|
validateMigrationChain
|
|
40
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-6SB34IPQ.js";
|
|
41
42
|
import {
|
|
42
43
|
CrossBackendTransactionError,
|
|
43
44
|
DynamicRegistryError,
|
|
@@ -54,11 +55,11 @@ import {
|
|
|
54
55
|
} from "./chunk-R7CRGYY4.js";
|
|
55
56
|
import {
|
|
56
57
|
generateTypes
|
|
57
|
-
} from "./chunk-
|
|
58
|
+
} from "./chunk-GJVVRTQT.js";
|
|
58
59
|
import {
|
|
59
60
|
QueryClient,
|
|
60
61
|
QueryClientError
|
|
61
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-EEKWRX5E.js";
|
|
62
63
|
import {
|
|
63
64
|
SERIALIZATION_TAG,
|
|
64
65
|
deserializeFirestoreTypes,
|
|
@@ -219,7 +220,8 @@ function loadNodeEntity(dir, name) {
|
|
|
219
220
|
sampleData,
|
|
220
221
|
allowedIn: meta?.allowedIn,
|
|
221
222
|
migrations,
|
|
222
|
-
migrationWriteBack: meta?.migrationWriteBack
|
|
223
|
+
migrationWriteBack: meta?.migrationWriteBack,
|
|
224
|
+
indexes: meta?.indexes
|
|
223
225
|
};
|
|
224
226
|
}
|
|
225
227
|
function loadEdgeEntity(dir, name) {
|
|
@@ -256,7 +258,8 @@ function loadEdgeEntity(dir, name) {
|
|
|
256
258
|
allowedIn: meta?.allowedIn,
|
|
257
259
|
targetGraph: topology.targetGraph ?? meta?.targetGraph,
|
|
258
260
|
migrations,
|
|
259
|
-
migrationWriteBack: meta?.migrationWriteBack
|
|
261
|
+
migrationWriteBack: meta?.migrationWriteBack,
|
|
262
|
+
indexes: meta?.indexes
|
|
260
263
|
};
|
|
261
264
|
}
|
|
262
265
|
function getSubdirectories(dir) {
|
|
@@ -783,124 +786,74 @@ function generateId() {
|
|
|
783
786
|
}
|
|
784
787
|
|
|
785
788
|
// src/indexes.ts
|
|
786
|
-
function
|
|
787
|
-
return
|
|
788
|
-
{
|
|
789
|
-
collectionGroup: collection,
|
|
790
|
-
queryScope: "COLLECTION",
|
|
791
|
-
fields: [
|
|
792
|
-
{ fieldPath: "aUid", order: "ASCENDING" },
|
|
793
|
-
{ fieldPath: "axbType", order: "ASCENDING" }
|
|
794
|
-
]
|
|
795
|
-
},
|
|
796
|
-
{
|
|
797
|
-
collectionGroup: collection,
|
|
798
|
-
queryScope: "COLLECTION",
|
|
799
|
-
fields: [
|
|
800
|
-
{ fieldPath: "axbType", order: "ASCENDING" },
|
|
801
|
-
{ fieldPath: "bUid", order: "ASCENDING" }
|
|
802
|
-
]
|
|
803
|
-
},
|
|
804
|
-
{
|
|
805
|
-
collectionGroup: collection,
|
|
806
|
-
queryScope: "COLLECTION",
|
|
807
|
-
fields: [
|
|
808
|
-
{ fieldPath: "aType", order: "ASCENDING" },
|
|
809
|
-
{ fieldPath: "axbType", order: "ASCENDING" }
|
|
810
|
-
]
|
|
811
|
-
},
|
|
812
|
-
{
|
|
813
|
-
collectionGroup: collection,
|
|
814
|
-
queryScope: "COLLECTION",
|
|
815
|
-
fields: [
|
|
816
|
-
{ fieldPath: "axbType", order: "ASCENDING" },
|
|
817
|
-
{ fieldPath: "bType", order: "ASCENDING" }
|
|
818
|
-
]
|
|
819
|
-
}
|
|
820
|
-
];
|
|
789
|
+
function normalizeField(f) {
|
|
790
|
+
return typeof f === "string" ? { path: f, desc: false } : { path: f.path, desc: !!f.desc };
|
|
821
791
|
}
|
|
822
|
-
function
|
|
823
|
-
const
|
|
824
|
-
|
|
825
|
-
return Object.keys(s.properties);
|
|
792
|
+
function specFingerprint(spec, scope) {
|
|
793
|
+
const normalized = spec.fields.map(normalizeField);
|
|
794
|
+
return `${scope}::${JSON.stringify(normalized)}`;
|
|
826
795
|
}
|
|
827
|
-
function
|
|
828
|
-
return
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
]
|
|
836
|
-
},
|
|
837
|
-
{
|
|
838
|
-
collectionGroup: collectionName,
|
|
839
|
-
queryScope: "COLLECTION_GROUP",
|
|
840
|
-
fields: [
|
|
841
|
-
{ fieldPath: "axbType", order: "ASCENDING" },
|
|
842
|
-
{ fieldPath: "bUid", order: "ASCENDING" }
|
|
843
|
-
]
|
|
844
|
-
},
|
|
845
|
-
{
|
|
846
|
-
collectionGroup: collectionName,
|
|
847
|
-
queryScope: "COLLECTION_GROUP",
|
|
848
|
-
fields: [
|
|
849
|
-
{ fieldPath: "aType", order: "ASCENDING" },
|
|
850
|
-
{ fieldPath: "axbType", order: "ASCENDING" }
|
|
851
|
-
]
|
|
852
|
-
},
|
|
853
|
-
{
|
|
854
|
-
collectionGroup: collectionName,
|
|
855
|
-
queryScope: "COLLECTION_GROUP",
|
|
856
|
-
fields: [
|
|
857
|
-
{ fieldPath: "axbType", order: "ASCENDING" },
|
|
858
|
-
{ fieldPath: "bType", order: "ASCENDING" }
|
|
859
|
-
]
|
|
860
|
-
}
|
|
861
|
-
];
|
|
796
|
+
function toFirestoreFields(spec) {
|
|
797
|
+
return spec.fields.map((f) => {
|
|
798
|
+
const n = normalizeField(f);
|
|
799
|
+
return {
|
|
800
|
+
fieldPath: n.path,
|
|
801
|
+
order: n.desc ? "DESCENDING" : "ASCENDING"
|
|
802
|
+
};
|
|
803
|
+
});
|
|
862
804
|
}
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
}
|
|
879
|
-
}
|
|
880
|
-
for (const [, entity] of entities.edges) {
|
|
881
|
-
const fields = extractSchemaFields(entity.schema);
|
|
882
|
-
for (const field of fields) {
|
|
883
|
-
indexes.push({
|
|
884
|
-
collectionGroup: collection,
|
|
885
|
-
queryScope: "COLLECTION",
|
|
886
|
-
fields: [
|
|
887
|
-
{ fieldPath: "aUid", order: "ASCENDING" },
|
|
888
|
-
{ fieldPath: "axbType", order: "ASCENDING" },
|
|
889
|
-
{ fieldPath: `data.${field}`, order: "ASCENDING" }
|
|
890
|
-
]
|
|
891
|
-
});
|
|
892
|
-
}
|
|
805
|
+
var warnedOnPartialIndex = false;
|
|
806
|
+
function generateIndexConfig(collection, options = {}) {
|
|
807
|
+
const core = options.coreIndexes ?? [...DEFAULT_CORE_INDEXES];
|
|
808
|
+
const fromEntries = (options.registryEntries ?? []).flatMap((e) => {
|
|
809
|
+
if (!e.indexes) return [];
|
|
810
|
+
return e.indexes;
|
|
811
|
+
});
|
|
812
|
+
const targetGraphNames = /* @__PURE__ */ new Set();
|
|
813
|
+
for (const entry of options.registryEntries ?? []) {
|
|
814
|
+
if (entry.targetGraph) targetGraphNames.add(entry.targetGraph);
|
|
815
|
+
}
|
|
816
|
+
if (options.entities) {
|
|
817
|
+
for (const [, entity] of options.entities.edges) {
|
|
818
|
+
const tg = entity.targetGraph ?? entity.topology?.targetGraph;
|
|
819
|
+
if (tg) targetGraphNames.add(tg);
|
|
893
820
|
}
|
|
894
821
|
}
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
822
|
+
const allSpecs = [...core, ...fromEntries];
|
|
823
|
+
const seen = /* @__PURE__ */ new Set();
|
|
824
|
+
const indexes = [];
|
|
825
|
+
for (const spec of allSpecs) {
|
|
826
|
+
if (!spec.fields || spec.fields.length < 2) {
|
|
827
|
+
continue;
|
|
828
|
+
}
|
|
829
|
+
if (spec.where) {
|
|
830
|
+
if (!warnedOnPartialIndex) {
|
|
831
|
+
warnedOnPartialIndex = true;
|
|
832
|
+
console.warn(
|
|
833
|
+
"firegraph: IndexSpec.where is ignored by the Firestore generator \u2014 Firestore composite indexes do not support predicates. The SQLite backends will still honor `where`."
|
|
834
|
+
);
|
|
900
835
|
}
|
|
836
|
+
continue;
|
|
901
837
|
}
|
|
902
|
-
|
|
903
|
-
|
|
838
|
+
const fields = toFirestoreFields(spec);
|
|
839
|
+
const colKey = specFingerprint(spec, `col:${collection}`);
|
|
840
|
+
if (!seen.has(colKey)) {
|
|
841
|
+
seen.add(colKey);
|
|
842
|
+
indexes.push({
|
|
843
|
+
collectionGroup: collection,
|
|
844
|
+
queryScope: "COLLECTION",
|
|
845
|
+
fields
|
|
846
|
+
});
|
|
847
|
+
}
|
|
848
|
+
for (const tg of targetGraphNames) {
|
|
849
|
+
const cgKey = specFingerprint(spec, `cg:${tg}`);
|
|
850
|
+
if (seen.has(cgKey)) continue;
|
|
851
|
+
seen.add(cgKey);
|
|
852
|
+
indexes.push({
|
|
853
|
+
collectionGroup: tg,
|
|
854
|
+
queryScope: "COLLECTION_GROUP",
|
|
855
|
+
fields
|
|
856
|
+
});
|
|
904
857
|
}
|
|
905
858
|
}
|
|
906
859
|
return { indexes, fieldOverrides: [] };
|
|
@@ -1226,6 +1179,7 @@ function defineViews(input) {
|
|
|
1226
1179
|
export {
|
|
1227
1180
|
BOOTSTRAP_ENTRIES,
|
|
1228
1181
|
CrossBackendTransactionError,
|
|
1182
|
+
DEFAULT_CORE_INDEXES,
|
|
1229
1183
|
DEFAULT_QUERY_LIMIT,
|
|
1230
1184
|
DiscoveryError,
|
|
1231
1185
|
DynamicRegistryError,
|