@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/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Firestore } from '@google-cloud/firestore';
2
- import { G as GraphClientOptions, D as DynamicRegistryConfig, a as DynamicGraphClient, b as GraphClient, R as RegistryEntry, c as DiscoveryResult, d as GraphRegistry, e as GraphReader, f as GraphRecord, F as FindEdgesParams, Q as QueryPlan, g as FindNodesParams, T as TraversalBuilder, h as QueryFilter } from './index-CQkofEC_.cjs';
3
- export { B as BulkBatchError, i as BulkOptions, j as BulkProgress, k as BulkResult, C as CascadeResult, l as CodegenOptions, m as DefineTypeOptions, n as DiscoveredEntity, E as EdgeTopology, o as EdgeTypeData, p as FiregraphConfig, q as GraphBatch, r as GraphTransaction, s as GraphWriter, H as HopDefinition, t as HopResult, N as NodeTypeData, u as QueryMode, v as QueryOptions, S as ScanProtection, w as StoredGraphRecord, x as TraversalOptions, y as TraversalResult, V as ViewContext, z as ViewDefaultsConfig, A as ViewResolverConfig, W as WhereClause, I as defineConfig, J as generateTypes, K as resolveView } from './index-CQkofEC_.cjs';
2
+ import { G as GraphClientOptions, D as DynamicRegistryConfig, a as DynamicGraphClient, b as GraphClient, c as GraphRegistry, R as RegistryEntry, d as DiscoveryResult, e as GraphReader, f as GraphRecord, F as FindEdgesParams, Q as QueryPlan, g as FindNodesParams, T as TraversalBuilder, h as QueryFilter } from './index-DR3jF5_b.cjs';
3
+ export { B as BulkBatchError, i as BulkOptions, j as BulkProgress, k as BulkResult, C as CascadeResult, l as CodegenOptions, m as DefineTypeOptions, n as DiscoveredEntity, E as EdgeTopology, o as EdgeTypeData, p as FiregraphConfig, q as GraphBatch, r as GraphTransaction, s as GraphWriter, H as HopDefinition, t as HopResult, N as NodeTypeData, u as QueryMode, v as QueryOptions, S as ScanProtection, w as StoredGraphRecord, x as TraversalOptions, y as TraversalResult, V as ViewContext, z as ViewDefaultsConfig, A as ViewResolverConfig, W as WhereClause, I as defineConfig, J as generateTypes, K as resolveView } from './index-DR3jF5_b.cjs';
4
4
  export { E as EntityViewConfig, a as EntityViewMeta, V as ViewComponentClass, b as ViewMeta, c as ViewRegistry, d as ViewRegistryInput, e as defineViews } from './views-DL60k0cf.cjs';
5
5
  export { Q as QueryClient, a as QueryClientError, b as QueryClientErrorCode, c as QueryClientOptions } from './client-Bk2Cm6xv.cjs';
6
6
 
@@ -26,6 +26,17 @@ declare function createGraphClient(db: Firestore, collectionPath: string, option
26
26
  * ```
27
27
  */
28
28
  declare function createRegistry(input: RegistryEntry[] | DiscoveryResult): GraphRegistry;
29
+ /**
30
+ * Create a merged registry where `base` entries take priority and `extension`
31
+ * entries fill in gaps. Lookups and validation check `base` first; only if the
32
+ * triple is not found there does the merged registry fall through to
33
+ * `extension`.
34
+ *
35
+ * The `entries()` method returns a deduplicated list (base wins on collision).
36
+ * The `lookupByAxbType()` method merges results from both registries,
37
+ * deduplicating by triple key with base entries winning.
38
+ */
39
+ declare function createMergedRegistry(base: GraphRegistry, extension: GraphRegistry): GraphRegistry;
29
40
 
30
41
  /** The aType used for node type definition meta-nodes. */
31
42
  declare const META_NODE_TYPE = "nodeType";
@@ -336,4 +347,4 @@ declare function analyzeQuerySafety(filters: QueryFilter[]): QuerySafetyResult;
336
347
  */
337
348
  declare const DEFAULT_QUERY_LIMIT = 500;
338
349
 
339
- export { BOOTSTRAP_ENTRIES, DEFAULT_QUERY_LIMIT, type DiscoverResult, DiscoveryError, DiscoveryResult, type DiscoveryWarning, DynamicGraphClient, DynamicRegistryConfig, DynamicRegistryError, EDGE_TYPE_SCHEMA, EdgeNotFoundError, type FieldMeta, FindEdgesParams, FindNodesParams, FiregraphError, type FirestoreIndex, type FirestoreIndexConfig, type FirestoreIndexField, GraphClient, GraphClientOptions, GraphReader, GraphRecord, GraphRegistry, InvalidQueryError, META_EDGE_TYPE, META_NODE_TYPE, NODE_TYPE_SCHEMA, NodeNotFoundError, QueryFilter, QueryPlan, QuerySafetyError, type QuerySafetyResult, RegistryEntry, RegistryScopeError, RegistryViolationError, TraversalBuilder, TraversalError, ValidationError, analyzeQuerySafety, buildEdgeQueryPlan, buildEdgeRecord, buildNodeQueryPlan, buildNodeRecord, compileSchema, computeEdgeDocId, computeNodeDocId, createBootstrapRegistry, createGraphClient, createRegistry, createRegistryFromGraph, createTraversal, discoverEntities, generateDeterministicUid, generateId, generateIndexConfig, isAncestorUid, jsonSchemaToFieldMeta, matchScope, matchScopeAny, resolveAncestorCollection };
350
+ export { BOOTSTRAP_ENTRIES, DEFAULT_QUERY_LIMIT, type DiscoverResult, DiscoveryError, DiscoveryResult, type DiscoveryWarning, DynamicGraphClient, DynamicRegistryConfig, DynamicRegistryError, EDGE_TYPE_SCHEMA, EdgeNotFoundError, type FieldMeta, FindEdgesParams, FindNodesParams, FiregraphError, type FirestoreIndex, type FirestoreIndexConfig, type FirestoreIndexField, GraphClient, GraphClientOptions, GraphReader, GraphRecord, GraphRegistry, InvalidQueryError, META_EDGE_TYPE, META_NODE_TYPE, NODE_TYPE_SCHEMA, NodeNotFoundError, QueryFilter, QueryPlan, QuerySafetyError, type QuerySafetyResult, RegistryEntry, RegistryScopeError, RegistryViolationError, TraversalBuilder, TraversalError, ValidationError, analyzeQuerySafety, buildEdgeQueryPlan, buildEdgeRecord, buildNodeQueryPlan, buildNodeRecord, compileSchema, computeEdgeDocId, computeNodeDocId, createBootstrapRegistry, createGraphClient, createMergedRegistry, createRegistry, createRegistryFromGraph, createTraversal, discoverEntities, generateDeterministicUid, generateId, generateIndexConfig, isAncestorUid, jsonSchemaToFieldMeta, matchScope, matchScopeAny, resolveAncestorCollection };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Firestore } from '@google-cloud/firestore';
2
- import { G as GraphClientOptions, D as DynamicRegistryConfig, a as DynamicGraphClient, b as GraphClient, R as RegistryEntry, c as DiscoveryResult, d as GraphRegistry, e as GraphReader, f as GraphRecord, F as FindEdgesParams, Q as QueryPlan, g as FindNodesParams, T as TraversalBuilder, h as QueryFilter } from './index-CQkofEC_.js';
3
- export { B as BulkBatchError, i as BulkOptions, j as BulkProgress, k as BulkResult, C as CascadeResult, l as CodegenOptions, m as DefineTypeOptions, n as DiscoveredEntity, E as EdgeTopology, o as EdgeTypeData, p as FiregraphConfig, q as GraphBatch, r as GraphTransaction, s as GraphWriter, H as HopDefinition, t as HopResult, N as NodeTypeData, u as QueryMode, v as QueryOptions, S as ScanProtection, w as StoredGraphRecord, x as TraversalOptions, y as TraversalResult, V as ViewContext, z as ViewDefaultsConfig, A as ViewResolverConfig, W as WhereClause, I as defineConfig, J as generateTypes, K as resolveView } from './index-CQkofEC_.js';
2
+ import { G as GraphClientOptions, D as DynamicRegistryConfig, a as DynamicGraphClient, b as GraphClient, c as GraphRegistry, R as RegistryEntry, d as DiscoveryResult, e as GraphReader, f as GraphRecord, F as FindEdgesParams, Q as QueryPlan, g as FindNodesParams, T as TraversalBuilder, h as QueryFilter } from './index-DR3jF5_b.js';
3
+ export { B as BulkBatchError, i as BulkOptions, j as BulkProgress, k as BulkResult, C as CascadeResult, l as CodegenOptions, m as DefineTypeOptions, n as DiscoveredEntity, E as EdgeTopology, o as EdgeTypeData, p as FiregraphConfig, q as GraphBatch, r as GraphTransaction, s as GraphWriter, H as HopDefinition, t as HopResult, N as NodeTypeData, u as QueryMode, v as QueryOptions, S as ScanProtection, w as StoredGraphRecord, x as TraversalOptions, y as TraversalResult, V as ViewContext, z as ViewDefaultsConfig, A as ViewResolverConfig, W as WhereClause, I as defineConfig, J as generateTypes, K as resolveView } from './index-DR3jF5_b.js';
4
4
  export { E as EntityViewConfig, a as EntityViewMeta, V as ViewComponentClass, b as ViewMeta, c as ViewRegistry, d as ViewRegistryInput, e as defineViews } from './views-DL60k0cf.js';
5
5
  export { Q as QueryClient, a as QueryClientError, b as QueryClientErrorCode, c as QueryClientOptions } from './client-Bk2Cm6xv.js';
6
6
 
@@ -26,6 +26,17 @@ declare function createGraphClient(db: Firestore, collectionPath: string, option
26
26
  * ```
27
27
  */
28
28
  declare function createRegistry(input: RegistryEntry[] | DiscoveryResult): GraphRegistry;
29
+ /**
30
+ * Create a merged registry where `base` entries take priority and `extension`
31
+ * entries fill in gaps. Lookups and validation check `base` first; only if the
32
+ * triple is not found there does the merged registry fall through to
33
+ * `extension`.
34
+ *
35
+ * The `entries()` method returns a deduplicated list (base wins on collision).
36
+ * The `lookupByAxbType()` method merges results from both registries,
37
+ * deduplicating by triple key with base entries winning.
38
+ */
39
+ declare function createMergedRegistry(base: GraphRegistry, extension: GraphRegistry): GraphRegistry;
29
40
 
30
41
  /** The aType used for node type definition meta-nodes. */
31
42
  declare const META_NODE_TYPE = "nodeType";
@@ -336,4 +347,4 @@ declare function analyzeQuerySafety(filters: QueryFilter[]): QuerySafetyResult;
336
347
  */
337
348
  declare const DEFAULT_QUERY_LIMIT = 500;
338
349
 
339
- export { BOOTSTRAP_ENTRIES, DEFAULT_QUERY_LIMIT, type DiscoverResult, DiscoveryError, DiscoveryResult, type DiscoveryWarning, DynamicGraphClient, DynamicRegistryConfig, DynamicRegistryError, EDGE_TYPE_SCHEMA, EdgeNotFoundError, type FieldMeta, FindEdgesParams, FindNodesParams, FiregraphError, type FirestoreIndex, type FirestoreIndexConfig, type FirestoreIndexField, GraphClient, GraphClientOptions, GraphReader, GraphRecord, GraphRegistry, InvalidQueryError, META_EDGE_TYPE, META_NODE_TYPE, NODE_TYPE_SCHEMA, NodeNotFoundError, QueryFilter, QueryPlan, QuerySafetyError, type QuerySafetyResult, RegistryEntry, RegistryScopeError, RegistryViolationError, TraversalBuilder, TraversalError, ValidationError, analyzeQuerySafety, buildEdgeQueryPlan, buildEdgeRecord, buildNodeQueryPlan, buildNodeRecord, compileSchema, computeEdgeDocId, computeNodeDocId, createBootstrapRegistry, createGraphClient, createRegistry, createRegistryFromGraph, createTraversal, discoverEntities, generateDeterministicUid, generateId, generateIndexConfig, isAncestorUid, jsonSchemaToFieldMeta, matchScope, matchScopeAny, resolveAncestorCollection };
350
+ export { BOOTSTRAP_ENTRIES, DEFAULT_QUERY_LIMIT, type DiscoverResult, DiscoveryError, DiscoveryResult, type DiscoveryWarning, DynamicGraphClient, DynamicRegistryConfig, DynamicRegistryError, EDGE_TYPE_SCHEMA, EdgeNotFoundError, type FieldMeta, FindEdgesParams, FindNodesParams, FiregraphError, type FirestoreIndex, type FirestoreIndexConfig, type FirestoreIndexField, GraphClient, GraphClientOptions, GraphReader, GraphRecord, GraphRegistry, InvalidQueryError, META_EDGE_TYPE, META_NODE_TYPE, NODE_TYPE_SCHEMA, NodeNotFoundError, QueryFilter, QueryPlan, QuerySafetyError, type QuerySafetyResult, RegistryEntry, RegistryScopeError, RegistryViolationError, TraversalBuilder, TraversalError, ValidationError, analyzeQuerySafety, buildEdgeQueryPlan, buildEdgeRecord, buildNodeQueryPlan, buildNodeRecord, compileSchema, computeEdgeDocId, computeNodeDocId, createBootstrapRegistry, createGraphClient, createMergedRegistry, createRegistry, createRegistryFromGraph, createTraversal, discoverEntities, generateDeterministicUid, generateId, generateIndexConfig, isAncestorUid, jsonSchemaToFieldMeta, matchScope, matchScopeAny, resolveAncestorCollection };
package/dist/index.js CHANGED
@@ -773,6 +773,9 @@ function matchSegments(path, pi, pattern, qi) {
773
773
  function tripleKey(aType, axbType, bType) {
774
774
  return `${aType}:${axbType}:${bType}`;
775
775
  }
776
+ function tripleKeyFor(e) {
777
+ return tripleKey(e.aType, e.axbType, e.bType);
778
+ }
776
779
  function createRegistry(input) {
777
780
  const map = /* @__PURE__ */ new Map();
778
781
  let entries;
@@ -839,6 +842,45 @@ function createRegistry(input) {
839
842
  }
840
843
  };
841
844
  }
845
+ function createMergedRegistry(base, extension) {
846
+ const baseKeys = new Set(base.entries().map(tripleKeyFor));
847
+ return {
848
+ lookup(aType, axbType, bType) {
849
+ return base.lookup(aType, axbType, bType) ?? extension.lookup(aType, axbType, bType);
850
+ },
851
+ lookupByAxbType(axbType) {
852
+ const baseResults = base.lookupByAxbType(axbType);
853
+ const extResults = extension.lookupByAxbType(axbType);
854
+ if (extResults.length === 0) return baseResults;
855
+ if (baseResults.length === 0) return extResults;
856
+ const seen = new Set(baseResults.map(tripleKeyFor));
857
+ const merged = [...baseResults];
858
+ for (const entry of extResults) {
859
+ if (!seen.has(tripleKeyFor(entry))) {
860
+ merged.push(entry);
861
+ }
862
+ }
863
+ return Object.freeze(merged);
864
+ },
865
+ validate(aType, axbType, bType, data, scopePath) {
866
+ if (baseKeys.has(tripleKey(aType, axbType, bType))) {
867
+ return base.validate(aType, axbType, bType, data, scopePath);
868
+ }
869
+ return extension.validate(aType, axbType, bType, data, scopePath);
870
+ },
871
+ entries() {
872
+ const extEntries = extension.entries();
873
+ if (extEntries.length === 0) return base.entries();
874
+ const merged = [...base.entries()];
875
+ for (const entry of extEntries) {
876
+ if (!baseKeys.has(tripleKeyFor(entry))) {
877
+ merged.push(entry);
878
+ }
879
+ }
880
+ return Object.freeze(merged);
881
+ }
882
+ };
883
+ }
842
884
  function discoveryToEntries(discovery) {
843
885
  const entries = [];
844
886
  for (const [name, entity] of discovery.nodes) {
@@ -1005,14 +1047,12 @@ var GraphClientImpl = class _GraphClientImpl {
1005
1047
  this.db = db;
1006
1048
  this.scopePath = scopePath;
1007
1049
  this.adapter = createFirestoreAdapter(db, collectionPath);
1008
- if (options?.registry && options?.registryMode) {
1009
- throw new DynamicRegistryError(
1010
- 'Cannot provide both "registry" and "registryMode". Use "registry" for static mode or "registryMode" for dynamic mode.'
1011
- );
1012
- }
1013
1050
  if (options?.registryMode) {
1014
1051
  this.dynamicConfig = options.registryMode;
1015
1052
  this.bootstrapRegistry = createBootstrapRegistry();
1053
+ if (options.registry) {
1054
+ this.staticRegistry = options.registry;
1055
+ }
1016
1056
  const metaCollectionPath = options.registryMode.collection;
1017
1057
  if (metaCollectionPath && metaCollectionPath !== collectionPath) {
1018
1058
  this.metaAdapter = createFirestoreAdapter(db, metaCollectionPath);
@@ -1064,18 +1104,20 @@ var GraphClientImpl = class _GraphClientImpl {
1064
1104
  /**
1065
1105
  * Get the appropriate registry for validating a write to the given type.
1066
1106
  *
1067
- * - Static mode: returns staticRegistry (or undefined if none set)
1068
- * - Dynamic mode:
1107
+ * - Static-only mode: returns staticRegistry (or undefined if none set)
1108
+ * - Dynamic mode (pure or merged):
1069
1109
  * - Meta-types (nodeType, edgeType): validated against bootstrapRegistry
1070
1110
  * - Domain types: validated against dynamicRegistry (falls back to
1071
1111
  * bootstrapRegistry which rejects unknown types)
1112
+ * - Merged mode: dynamicRegistry is a merged wrapper (static + dynamic
1113
+ * extension), so static entries take priority automatically.
1072
1114
  */
1073
1115
  getRegistryForType(aType) {
1074
1116
  if (!this.dynamicConfig) return this.staticRegistry;
1075
1117
  if (aType === META_NODE_TYPE || aType === META_EDGE_TYPE) {
1076
1118
  return this.bootstrapRegistry;
1077
1119
  }
1078
- return this.dynamicRegistry ?? this.bootstrapRegistry;
1120
+ return this.dynamicRegistry ?? this.staticRegistry ?? this.bootstrapRegistry;
1079
1121
  }
1080
1122
  /**
1081
1123
  * Get the Firestore adapter for writing the given type.
@@ -1089,13 +1131,13 @@ var GraphClientImpl = class _GraphClientImpl {
1089
1131
  }
1090
1132
  /**
1091
1133
  * Get the combined registry for transaction/batch context.
1092
- * In static mode, returns staticRegistry.
1134
+ * In static-only mode, returns staticRegistry.
1093
1135
  * In dynamic mode, returns dynamicRegistry (which includes bootstrap entries)
1094
- * or bootstrapRegistry if not yet reloaded.
1136
+ * or falls back to staticRegistry (merged mode) or bootstrapRegistry.
1095
1137
  */
1096
1138
  getCombinedRegistry() {
1097
1139
  if (!this.dynamicConfig) return this.staticRegistry;
1098
- return this.dynamicRegistry ?? this.bootstrapRegistry;
1140
+ return this.dynamicRegistry ?? this.staticRegistry ?? this.bootstrapRegistry;
1099
1141
  }
1100
1142
  // ---------------------------------------------------------------------------
1101
1143
  // Query dispatch
@@ -1292,6 +1334,11 @@ var GraphClientImpl = class _GraphClientImpl {
1292
1334
  `Cannot define type "${name}": this name is reserved for the meta-registry.`
1293
1335
  );
1294
1336
  }
1337
+ if (this.staticRegistry?.lookup(name, NODE_RELATION, name)) {
1338
+ throw new DynamicRegistryError(
1339
+ `Cannot define node type "${name}": already defined in the static registry.`
1340
+ );
1341
+ }
1295
1342
  const uid = generateDeterministicUid(META_NODE_TYPE, name);
1296
1343
  const data = { name, jsonSchema };
1297
1344
  if (description !== void 0) data.description = description;
@@ -1313,6 +1360,19 @@ var GraphClientImpl = class _GraphClientImpl {
1313
1360
  `Cannot define type "${name}": this name is reserved for the meta-registry.`
1314
1361
  );
1315
1362
  }
1363
+ if (this.staticRegistry) {
1364
+ const fromTypes = Array.isArray(topology.from) ? topology.from : [topology.from];
1365
+ const toTypes = Array.isArray(topology.to) ? topology.to : [topology.to];
1366
+ for (const aType of fromTypes) {
1367
+ for (const bType of toTypes) {
1368
+ if (this.staticRegistry.lookup(aType, name, bType)) {
1369
+ throw new DynamicRegistryError(
1370
+ `Cannot define edge type "${name}" for (${aType}) -> (${bType}): already defined in the static registry.`
1371
+ );
1372
+ }
1373
+ }
1374
+ }
1375
+ }
1316
1376
  const uid = generateDeterministicUid(META_EDGE_TYPE, name);
1317
1377
  const data = {
1318
1378
  name,
@@ -1337,7 +1397,12 @@ var GraphClientImpl = class _GraphClientImpl {
1337
1397
  );
1338
1398
  }
1339
1399
  const reader = this.createMetaReader();
1340
- this.dynamicRegistry = await createRegistryFromGraph(reader);
1400
+ const dynamicOnly = await createRegistryFromGraph(reader);
1401
+ if (this.staticRegistry) {
1402
+ this.dynamicRegistry = createMergedRegistry(this.staticRegistry, dynamicOnly);
1403
+ } else {
1404
+ this.dynamicRegistry = dynamicOnly;
1405
+ }
1341
1406
  }
1342
1407
  /**
1343
1408
  * Create a GraphReader for the meta-collection.
@@ -2038,6 +2103,7 @@ export {
2038
2103
  computeNodeDocId,
2039
2104
  createBootstrapRegistry,
2040
2105
  createGraphClient,
2106
+ createMergedRegistry,
2041
2107
  createRegistry,
2042
2108
  createRegistryFromGraph,
2043
2109
  createTraversal,