@typicalday/firegraph 0.3.0 → 0.4.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 CHANGED
@@ -340,7 +340,7 @@ Key behaviors:
340
340
  - **After `reloadRegistry()`**: Domain writes are validated against the compiled registry. Unknown types are always rejected.
341
341
  - **Upsert semantics**: Calling `defineNodeType('tour', ...)` twice overwrites the previous definition. After reloading, the latest schema is used.
342
342
  - **Separate collection**: Meta-nodes can be stored in a different collection via `registryMode: { mode: 'dynamic', collection: 'meta' }`.
343
- - **Mutual exclusivity**: `registry` (static) and `registryMode` (dynamic) cannot be used together.
343
+ - **Merged mode**: Provide both `registry` (static) and `registryMode` (dynamic) to get a merged registry where static entries take priority and dynamic definitions can only add new types — not override existing ones.
344
344
 
345
345
  Dynamic registry returns a `DynamicGraphClient` which extends `GraphClient` with `defineNodeType()`, `defineEdgeType()`, and `reloadRegistry()`. Transactions and batches also validate against the compiled dynamic registry.
346
346
 
@@ -1,2 +1,2 @@
1
- export { l as CodegenOptions, J as generateTypes } from '../index-CQkofEC_.cjs';
1
+ export { l as CodegenOptions, J as generateTypes } from '../index-DR3jF5_b.cjs';
2
2
  import '@google-cloud/firestore';
@@ -1,2 +1,2 @@
1
- export { l as CodegenOptions, J as generateTypes } from '../index-CQkofEC_.js';
1
+ export { l as CodegenOptions, J as generateTypes } from '../index-DR3jF5_b.js';
2
2
  import '@google-cloud/firestore';
@@ -30072,6 +30072,9 @@ function matchSegments(path4, pi, pattern, qi) {
30072
30072
  function tripleKey(aType, axbType, bType) {
30073
30073
  return `${aType}:${axbType}:${bType}`;
30074
30074
  }
30075
+ function tripleKeyFor(e) {
30076
+ return tripleKey(e.aType, e.axbType, e.bType);
30077
+ }
30075
30078
  function createRegistry(input) {
30076
30079
  const map2 = /* @__PURE__ */ new Map();
30077
30080
  let entries;
@@ -30138,6 +30141,45 @@ function createRegistry(input) {
30138
30141
  }
30139
30142
  };
30140
30143
  }
30144
+ function createMergedRegistry(base, extension) {
30145
+ const baseKeys = new Set(base.entries().map(tripleKeyFor));
30146
+ return {
30147
+ lookup(aType, axbType, bType) {
30148
+ return base.lookup(aType, axbType, bType) ?? extension.lookup(aType, axbType, bType);
30149
+ },
30150
+ lookupByAxbType(axbType) {
30151
+ const baseResults = base.lookupByAxbType(axbType);
30152
+ const extResults = extension.lookupByAxbType(axbType);
30153
+ if (extResults.length === 0) return baseResults;
30154
+ if (baseResults.length === 0) return extResults;
30155
+ const seen = new Set(baseResults.map(tripleKeyFor));
30156
+ const merged = [...baseResults];
30157
+ for (const entry of extResults) {
30158
+ if (!seen.has(tripleKeyFor(entry))) {
30159
+ merged.push(entry);
30160
+ }
30161
+ }
30162
+ return Object.freeze(merged);
30163
+ },
30164
+ validate(aType, axbType, bType, data, scopePath) {
30165
+ if (baseKeys.has(tripleKey(aType, axbType, bType))) {
30166
+ return base.validate(aType, axbType, bType, data, scopePath);
30167
+ }
30168
+ return extension.validate(aType, axbType, bType, data, scopePath);
30169
+ },
30170
+ entries() {
30171
+ const extEntries = extension.entries();
30172
+ if (extEntries.length === 0) return base.entries();
30173
+ const merged = [...base.entries()];
30174
+ for (const entry of extEntries) {
30175
+ if (!baseKeys.has(tripleKeyFor(entry))) {
30176
+ merged.push(entry);
30177
+ }
30178
+ }
30179
+ return Object.freeze(merged);
30180
+ }
30181
+ };
30182
+ }
30141
30183
  function discoveryToEntries(discovery) {
30142
30184
  const entries = [];
30143
30185
  for (const [name, entity] of discovery.nodes) {
@@ -30304,14 +30346,12 @@ var GraphClientImpl = class _GraphClientImpl {
30304
30346
  this.db = db2;
30305
30347
  this.scopePath = scopePath;
30306
30348
  this.adapter = createFirestoreAdapter(db2, collectionPath);
30307
- if (options?.registry && options?.registryMode) {
30308
- throw new DynamicRegistryError(
30309
- 'Cannot provide both "registry" and "registryMode". Use "registry" for static mode or "registryMode" for dynamic mode.'
30310
- );
30311
- }
30312
30349
  if (options?.registryMode) {
30313
30350
  this.dynamicConfig = options.registryMode;
30314
30351
  this.bootstrapRegistry = createBootstrapRegistry();
30352
+ if (options.registry) {
30353
+ this.staticRegistry = options.registry;
30354
+ }
30315
30355
  const metaCollectionPath = options.registryMode.collection;
30316
30356
  if (metaCollectionPath && metaCollectionPath !== collectionPath) {
30317
30357
  this.metaAdapter = createFirestoreAdapter(db2, metaCollectionPath);
@@ -30363,18 +30403,20 @@ var GraphClientImpl = class _GraphClientImpl {
30363
30403
  /**
30364
30404
  * Get the appropriate registry for validating a write to the given type.
30365
30405
  *
30366
- * - Static mode: returns staticRegistry (or undefined if none set)
30367
- * - Dynamic mode:
30406
+ * - Static-only mode: returns staticRegistry (or undefined if none set)
30407
+ * - Dynamic mode (pure or merged):
30368
30408
  * - Meta-types (nodeType, edgeType): validated against bootstrapRegistry
30369
30409
  * - Domain types: validated against dynamicRegistry (falls back to
30370
30410
  * bootstrapRegistry which rejects unknown types)
30411
+ * - Merged mode: dynamicRegistry is a merged wrapper (static + dynamic
30412
+ * extension), so static entries take priority automatically.
30371
30413
  */
30372
30414
  getRegistryForType(aType) {
30373
30415
  if (!this.dynamicConfig) return this.staticRegistry;
30374
30416
  if (aType === META_NODE_TYPE || aType === META_EDGE_TYPE) {
30375
30417
  return this.bootstrapRegistry;
30376
30418
  }
30377
- return this.dynamicRegistry ?? this.bootstrapRegistry;
30419
+ return this.dynamicRegistry ?? this.staticRegistry ?? this.bootstrapRegistry;
30378
30420
  }
30379
30421
  /**
30380
30422
  * Get the Firestore adapter for writing the given type.
@@ -30388,13 +30430,13 @@ var GraphClientImpl = class _GraphClientImpl {
30388
30430
  }
30389
30431
  /**
30390
30432
  * Get the combined registry for transaction/batch context.
30391
- * In static mode, returns staticRegistry.
30433
+ * In static-only mode, returns staticRegistry.
30392
30434
  * In dynamic mode, returns dynamicRegistry (which includes bootstrap entries)
30393
- * or bootstrapRegistry if not yet reloaded.
30435
+ * or falls back to staticRegistry (merged mode) or bootstrapRegistry.
30394
30436
  */
30395
30437
  getCombinedRegistry() {
30396
30438
  if (!this.dynamicConfig) return this.staticRegistry;
30397
- return this.dynamicRegistry ?? this.bootstrapRegistry;
30439
+ return this.dynamicRegistry ?? this.staticRegistry ?? this.bootstrapRegistry;
30398
30440
  }
30399
30441
  // ---------------------------------------------------------------------------
30400
30442
  // Query dispatch
@@ -30591,6 +30633,11 @@ var GraphClientImpl = class _GraphClientImpl {
30591
30633
  `Cannot define type "${name}": this name is reserved for the meta-registry.`
30592
30634
  );
30593
30635
  }
30636
+ if (this.staticRegistry?.lookup(name, NODE_RELATION, name)) {
30637
+ throw new DynamicRegistryError(
30638
+ `Cannot define node type "${name}": already defined in the static registry.`
30639
+ );
30640
+ }
30594
30641
  const uid = generateDeterministicUid(META_NODE_TYPE, name);
30595
30642
  const data = { name, jsonSchema };
30596
30643
  if (description !== void 0) data.description = description;
@@ -30612,6 +30659,19 @@ var GraphClientImpl = class _GraphClientImpl {
30612
30659
  `Cannot define type "${name}": this name is reserved for the meta-registry.`
30613
30660
  );
30614
30661
  }
30662
+ if (this.staticRegistry) {
30663
+ const fromTypes = Array.isArray(topology.from) ? topology.from : [topology.from];
30664
+ const toTypes = Array.isArray(topology.to) ? topology.to : [topology.to];
30665
+ for (const aType of fromTypes) {
30666
+ for (const bType of toTypes) {
30667
+ if (this.staticRegistry.lookup(aType, name, bType)) {
30668
+ throw new DynamicRegistryError(
30669
+ `Cannot define edge type "${name}" for (${aType}) -> (${bType}): already defined in the static registry.`
30670
+ );
30671
+ }
30672
+ }
30673
+ }
30674
+ }
30615
30675
  const uid = generateDeterministicUid(META_EDGE_TYPE, name);
30616
30676
  const data = {
30617
30677
  name,
@@ -30636,7 +30696,12 @@ var GraphClientImpl = class _GraphClientImpl {
30636
30696
  );
30637
30697
  }
30638
30698
  const reader = this.createMetaReader();
30639
- this.dynamicRegistry = await createRegistryFromGraph(reader);
30699
+ const dynamicOnly = await createRegistryFromGraph(reader);
30700
+ if (this.staticRegistry) {
30701
+ this.dynamicRegistry = createMergedRegistry(this.staticRegistry, dynamicOnly);
30702
+ } else {
30703
+ this.dynamicRegistry = dynamicOnly;
30704
+ }
30640
30705
  }
30641
30706
  /**
30642
30707
  * Create a GraphReader for the meta-collection.
@@ -316,7 +316,16 @@ interface EdgeTypeData {
316
316
  }
317
317
  type ScanProtection = 'error' | 'warn' | 'off';
318
318
  interface GraphClientOptions {
319
- /** Static registry built from code/discovery. Ignored if registryMode is set. */
319
+ /**
320
+ * Static registry built from code/discovery.
321
+ *
322
+ * When provided alone, all writes are validated against this registry.
323
+ *
324
+ * When provided together with `registryMode`, operates in **merged mode**:
325
+ * static entries take priority and cannot be overridden by dynamic
326
+ * definitions. Dynamic definitions can only add new types. The merged
327
+ * client is returned as a `DynamicGraphClient`.
328
+ */
320
329
  registry?: GraphRegistry;
321
330
  /** Dynamic registry mode — type definitions stored as graph data. */
322
331
  registryMode?: DynamicRegistryConfig;
@@ -531,4 +540,4 @@ interface CodegenOptions {
531
540
  */
532
541
  declare function generateTypes(discovery: DiscoveryResult, options?: CodegenOptions): Promise<string>;
533
542
 
534
- export { type ViewResolverConfig as A, type BulkBatchError as B, type CascadeResult as C, type DynamicRegistryConfig as D, type EdgeTopology as E, type FindEdgesParams as F, type GraphClientOptions as G, type HopDefinition as H, defineConfig as I, generateTypes as J, resolveView as K, type NodeTypeData as N, type QueryPlan as Q, type RegistryEntry as R, type ScanProtection as S, type TraversalBuilder as T, type ViewContext as V, type WhereClause as W, type DynamicGraphClient as a, type GraphClient as b, type DiscoveryResult as c, type GraphRegistry as d, type GraphReader as e, type GraphRecord as f, type FindNodesParams as g, type QueryFilter as h, type BulkOptions as i, type BulkProgress as j, type BulkResult as k, type CodegenOptions as l, type DefineTypeOptions as m, type DiscoveredEntity as n, type EdgeTypeData as o, type FiregraphConfig as p, type GraphBatch as q, type GraphTransaction as r, type GraphWriter as s, type HopResult as t, type QueryMode as u, type QueryOptions as v, type StoredGraphRecord as w, type TraversalOptions as x, type TraversalResult as y, type ViewDefaultsConfig as z };
543
+ export { type ViewResolverConfig as A, type BulkBatchError as B, type CascadeResult as C, type DynamicRegistryConfig as D, type EdgeTopology as E, type FindEdgesParams as F, type GraphClientOptions as G, type HopDefinition as H, defineConfig as I, generateTypes as J, resolveView as K, type NodeTypeData as N, type QueryPlan as Q, type RegistryEntry as R, type ScanProtection as S, type TraversalBuilder as T, type ViewContext as V, type WhereClause as W, type DynamicGraphClient as a, type GraphClient as b, type GraphRegistry as c, type DiscoveryResult as d, type GraphReader as e, type GraphRecord as f, type FindNodesParams as g, type QueryFilter as h, type BulkOptions as i, type BulkProgress as j, type BulkResult as k, type CodegenOptions as l, type DefineTypeOptions as m, type DiscoveredEntity as n, type EdgeTypeData as o, type FiregraphConfig as p, type GraphBatch as q, type GraphTransaction as r, type GraphWriter as s, type HopResult as t, type QueryMode as u, type QueryOptions as v, type StoredGraphRecord as w, type TraversalOptions as x, type TraversalResult as y, type ViewDefaultsConfig as z };
@@ -316,7 +316,16 @@ interface EdgeTypeData {
316
316
  }
317
317
  type ScanProtection = 'error' | 'warn' | 'off';
318
318
  interface GraphClientOptions {
319
- /** Static registry built from code/discovery. Ignored if registryMode is set. */
319
+ /**
320
+ * Static registry built from code/discovery.
321
+ *
322
+ * When provided alone, all writes are validated against this registry.
323
+ *
324
+ * When provided together with `registryMode`, operates in **merged mode**:
325
+ * static entries take priority and cannot be overridden by dynamic
326
+ * definitions. Dynamic definitions can only add new types. The merged
327
+ * client is returned as a `DynamicGraphClient`.
328
+ */
320
329
  registry?: GraphRegistry;
321
330
  /** Dynamic registry mode — type definitions stored as graph data. */
322
331
  registryMode?: DynamicRegistryConfig;
@@ -531,4 +540,4 @@ interface CodegenOptions {
531
540
  */
532
541
  declare function generateTypes(discovery: DiscoveryResult, options?: CodegenOptions): Promise<string>;
533
542
 
534
- export { type ViewResolverConfig as A, type BulkBatchError as B, type CascadeResult as C, type DynamicRegistryConfig as D, type EdgeTopology as E, type FindEdgesParams as F, type GraphClientOptions as G, type HopDefinition as H, defineConfig as I, generateTypes as J, resolveView as K, type NodeTypeData as N, type QueryPlan as Q, type RegistryEntry as R, type ScanProtection as S, type TraversalBuilder as T, type ViewContext as V, type WhereClause as W, type DynamicGraphClient as a, type GraphClient as b, type DiscoveryResult as c, type GraphRegistry as d, type GraphReader as e, type GraphRecord as f, type FindNodesParams as g, type QueryFilter as h, type BulkOptions as i, type BulkProgress as j, type BulkResult as k, type CodegenOptions as l, type DefineTypeOptions as m, type DiscoveredEntity as n, type EdgeTypeData as o, type FiregraphConfig as p, type GraphBatch as q, type GraphTransaction as r, type GraphWriter as s, type HopResult as t, type QueryMode as u, type QueryOptions as v, type StoredGraphRecord as w, type TraversalOptions as x, type TraversalResult as y, type ViewDefaultsConfig as z };
543
+ export { type ViewResolverConfig as A, type BulkBatchError as B, type CascadeResult as C, type DynamicRegistryConfig as D, type EdgeTopology as E, type FindEdgesParams as F, type GraphClientOptions as G, type HopDefinition as H, defineConfig as I, generateTypes as J, resolveView as K, type NodeTypeData as N, type QueryPlan as Q, type RegistryEntry as R, type ScanProtection as S, type TraversalBuilder as T, type ViewContext as V, type WhereClause as W, type DynamicGraphClient as a, type GraphClient as b, type GraphRegistry as c, type DiscoveryResult as d, type GraphReader as e, type GraphRecord as f, type FindNodesParams as g, type QueryFilter as h, type BulkOptions as i, type BulkProgress as j, type BulkResult as k, type CodegenOptions as l, type DefineTypeOptions as m, type DiscoveredEntity as n, type EdgeTypeData as o, type FiregraphConfig as p, type GraphBatch as q, type GraphTransaction as r, type GraphWriter as s, type HopResult as t, type QueryMode as u, type QueryOptions as v, type StoredGraphRecord as w, type TraversalOptions as x, type TraversalResult as y, type ViewDefaultsConfig as z };
package/dist/index.cjs CHANGED
@@ -59,6 +59,7 @@ __export(index_exports, {
59
59
  computeNodeDocId: () => computeNodeDocId,
60
60
  createBootstrapRegistry: () => createBootstrapRegistry,
61
61
  createGraphClient: () => createGraphClient,
62
+ createMergedRegistry: () => createMergedRegistry,
62
63
  createRegistry: () => createRegistry,
63
64
  createRegistryFromGraph: () => createRegistryFromGraph,
64
65
  createTraversal: () => createTraversal,
@@ -845,6 +846,9 @@ function matchSegments(path, pi, pattern, qi) {
845
846
  function tripleKey(aType, axbType, bType) {
846
847
  return `${aType}:${axbType}:${bType}`;
847
848
  }
849
+ function tripleKeyFor(e) {
850
+ return tripleKey(e.aType, e.axbType, e.bType);
851
+ }
848
852
  function createRegistry(input) {
849
853
  const map = /* @__PURE__ */ new Map();
850
854
  let entries;
@@ -911,6 +915,45 @@ function createRegistry(input) {
911
915
  }
912
916
  };
913
917
  }
918
+ function createMergedRegistry(base, extension) {
919
+ const baseKeys = new Set(base.entries().map(tripleKeyFor));
920
+ return {
921
+ lookup(aType, axbType, bType) {
922
+ return base.lookup(aType, axbType, bType) ?? extension.lookup(aType, axbType, bType);
923
+ },
924
+ lookupByAxbType(axbType) {
925
+ const baseResults = base.lookupByAxbType(axbType);
926
+ const extResults = extension.lookupByAxbType(axbType);
927
+ if (extResults.length === 0) return baseResults;
928
+ if (baseResults.length === 0) return extResults;
929
+ const seen = new Set(baseResults.map(tripleKeyFor));
930
+ const merged = [...baseResults];
931
+ for (const entry of extResults) {
932
+ if (!seen.has(tripleKeyFor(entry))) {
933
+ merged.push(entry);
934
+ }
935
+ }
936
+ return Object.freeze(merged);
937
+ },
938
+ validate(aType, axbType, bType, data, scopePath) {
939
+ if (baseKeys.has(tripleKey(aType, axbType, bType))) {
940
+ return base.validate(aType, axbType, bType, data, scopePath);
941
+ }
942
+ return extension.validate(aType, axbType, bType, data, scopePath);
943
+ },
944
+ entries() {
945
+ const extEntries = extension.entries();
946
+ if (extEntries.length === 0) return base.entries();
947
+ const merged = [...base.entries()];
948
+ for (const entry of extEntries) {
949
+ if (!baseKeys.has(tripleKeyFor(entry))) {
950
+ merged.push(entry);
951
+ }
952
+ }
953
+ return Object.freeze(merged);
954
+ }
955
+ };
956
+ }
914
957
  function discoveryToEntries(discovery) {
915
958
  const entries = [];
916
959
  for (const [name, entity] of discovery.nodes) {
@@ -1077,14 +1120,12 @@ var GraphClientImpl = class _GraphClientImpl {
1077
1120
  this.db = db;
1078
1121
  this.scopePath = scopePath;
1079
1122
  this.adapter = createFirestoreAdapter(db, collectionPath);
1080
- if (options?.registry && options?.registryMode) {
1081
- throw new DynamicRegistryError(
1082
- 'Cannot provide both "registry" and "registryMode". Use "registry" for static mode or "registryMode" for dynamic mode.'
1083
- );
1084
- }
1085
1123
  if (options?.registryMode) {
1086
1124
  this.dynamicConfig = options.registryMode;
1087
1125
  this.bootstrapRegistry = createBootstrapRegistry();
1126
+ if (options.registry) {
1127
+ this.staticRegistry = options.registry;
1128
+ }
1088
1129
  const metaCollectionPath = options.registryMode.collection;
1089
1130
  if (metaCollectionPath && metaCollectionPath !== collectionPath) {
1090
1131
  this.metaAdapter = createFirestoreAdapter(db, metaCollectionPath);
@@ -1136,18 +1177,20 @@ var GraphClientImpl = class _GraphClientImpl {
1136
1177
  /**
1137
1178
  * Get the appropriate registry for validating a write to the given type.
1138
1179
  *
1139
- * - Static mode: returns staticRegistry (or undefined if none set)
1140
- * - Dynamic mode:
1180
+ * - Static-only mode: returns staticRegistry (or undefined if none set)
1181
+ * - Dynamic mode (pure or merged):
1141
1182
  * - Meta-types (nodeType, edgeType): validated against bootstrapRegistry
1142
1183
  * - Domain types: validated against dynamicRegistry (falls back to
1143
1184
  * bootstrapRegistry which rejects unknown types)
1185
+ * - Merged mode: dynamicRegistry is a merged wrapper (static + dynamic
1186
+ * extension), so static entries take priority automatically.
1144
1187
  */
1145
1188
  getRegistryForType(aType) {
1146
1189
  if (!this.dynamicConfig) return this.staticRegistry;
1147
1190
  if (aType === META_NODE_TYPE || aType === META_EDGE_TYPE) {
1148
1191
  return this.bootstrapRegistry;
1149
1192
  }
1150
- return this.dynamicRegistry ?? this.bootstrapRegistry;
1193
+ return this.dynamicRegistry ?? this.staticRegistry ?? this.bootstrapRegistry;
1151
1194
  }
1152
1195
  /**
1153
1196
  * Get the Firestore adapter for writing the given type.
@@ -1161,13 +1204,13 @@ var GraphClientImpl = class _GraphClientImpl {
1161
1204
  }
1162
1205
  /**
1163
1206
  * Get the combined registry for transaction/batch context.
1164
- * In static mode, returns staticRegistry.
1207
+ * In static-only mode, returns staticRegistry.
1165
1208
  * In dynamic mode, returns dynamicRegistry (which includes bootstrap entries)
1166
- * or bootstrapRegistry if not yet reloaded.
1209
+ * or falls back to staticRegistry (merged mode) or bootstrapRegistry.
1167
1210
  */
1168
1211
  getCombinedRegistry() {
1169
1212
  if (!this.dynamicConfig) return this.staticRegistry;
1170
- return this.dynamicRegistry ?? this.bootstrapRegistry;
1213
+ return this.dynamicRegistry ?? this.staticRegistry ?? this.bootstrapRegistry;
1171
1214
  }
1172
1215
  // ---------------------------------------------------------------------------
1173
1216
  // Query dispatch
@@ -1364,6 +1407,11 @@ var GraphClientImpl = class _GraphClientImpl {
1364
1407
  `Cannot define type "${name}": this name is reserved for the meta-registry.`
1365
1408
  );
1366
1409
  }
1410
+ if (this.staticRegistry?.lookup(name, NODE_RELATION, name)) {
1411
+ throw new DynamicRegistryError(
1412
+ `Cannot define node type "${name}": already defined in the static registry.`
1413
+ );
1414
+ }
1367
1415
  const uid = generateDeterministicUid(META_NODE_TYPE, name);
1368
1416
  const data = { name, jsonSchema };
1369
1417
  if (description !== void 0) data.description = description;
@@ -1385,6 +1433,19 @@ var GraphClientImpl = class _GraphClientImpl {
1385
1433
  `Cannot define type "${name}": this name is reserved for the meta-registry.`
1386
1434
  );
1387
1435
  }
1436
+ if (this.staticRegistry) {
1437
+ const fromTypes = Array.isArray(topology.from) ? topology.from : [topology.from];
1438
+ const toTypes = Array.isArray(topology.to) ? topology.to : [topology.to];
1439
+ for (const aType of fromTypes) {
1440
+ for (const bType of toTypes) {
1441
+ if (this.staticRegistry.lookup(aType, name, bType)) {
1442
+ throw new DynamicRegistryError(
1443
+ `Cannot define edge type "${name}" for (${aType}) -> (${bType}): already defined in the static registry.`
1444
+ );
1445
+ }
1446
+ }
1447
+ }
1448
+ }
1388
1449
  const uid = generateDeterministicUid(META_EDGE_TYPE, name);
1389
1450
  const data = {
1390
1451
  name,
@@ -1409,7 +1470,12 @@ var GraphClientImpl = class _GraphClientImpl {
1409
1470
  );
1410
1471
  }
1411
1472
  const reader = this.createMetaReader();
1412
- this.dynamicRegistry = await createRegistryFromGraph(reader);
1473
+ const dynamicOnly = await createRegistryFromGraph(reader);
1474
+ if (this.staticRegistry) {
1475
+ this.dynamicRegistry = createMergedRegistry(this.staticRegistry, dynamicOnly);
1476
+ } else {
1477
+ this.dynamicRegistry = dynamicOnly;
1478
+ }
1413
1479
  }
1414
1480
  /**
1415
1481
  * Create a GraphReader for the meta-collection.
@@ -2431,6 +2497,7 @@ var QueryClient = class {
2431
2497
  computeNodeDocId,
2432
2498
  createBootstrapRegistry,
2433
2499
  createGraphClient,
2500
+ createMergedRegistry,
2434
2501
  createRegistry,
2435
2502
  createRegistryFromGraph,
2436
2503
  createTraversal,