@typicalday/firegraph 0.8.0 → 0.10.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.
Files changed (72) hide show
  1. package/dist/backend-73p5Blx7.d.cts +97 -0
  2. package/dist/backend-BrqFkbid.d.ts +97 -0
  3. package/dist/backend.cjs +222 -0
  4. package/dist/backend.cjs.map +1 -0
  5. package/dist/backend.d.cts +122 -0
  6. package/dist/backend.d.ts +122 -0
  7. package/dist/backend.js +136 -0
  8. package/dist/backend.js.map +1 -0
  9. package/dist/{chunk-6OQW5OKO.js → chunk-5753Y42M.js} +12 -4
  10. package/dist/chunk-5753Y42M.js.map +1 -0
  11. package/dist/{chunk-YUXOALMR.js → chunk-LZOIQHYN.js} +69 -92
  12. package/dist/chunk-LZOIQHYN.js.map +1 -0
  13. package/dist/chunk-R7CRGYY4.js +94 -0
  14. package/dist/chunk-R7CRGYY4.js.map +1 -0
  15. package/dist/{chunk-KFA7G37W.js → chunk-SU4FNLC3.js} +32 -30
  16. package/dist/chunk-SU4FNLC3.js.map +1 -0
  17. package/dist/chunk-TYYPRVIE.js +57 -0
  18. package/dist/chunk-TYYPRVIE.js.map +1 -0
  19. package/dist/{do-sqlite.cjs → cloudflare/index.cjs} +1538 -1420
  20. package/dist/cloudflare/index.cjs.map +1 -0
  21. package/dist/cloudflare/index.d.cts +454 -0
  22. package/dist/cloudflare/index.d.ts +454 -0
  23. package/dist/cloudflare/index.js +822 -0
  24. package/dist/cloudflare/index.js.map +1 -0
  25. package/dist/codegen/index.d.cts +1 -1
  26. package/dist/codegen/index.d.ts +1 -1
  27. package/dist/editor/client/assets/index-Bq2bfzeY.js +411 -0
  28. package/dist/editor/client/index.html +1 -1
  29. package/dist/editor/server/index.mjs +6481 -6327
  30. package/dist/index.cjs +165 -44
  31. package/dist/index.cjs.map +1 -1
  32. package/dist/index.d.cts +14 -138
  33. package/dist/index.d.ts +14 -138
  34. package/dist/index.js +31 -22
  35. package/dist/index.js.map +1 -1
  36. package/dist/query-client/index.cjs +30 -28
  37. package/dist/query-client/index.cjs.map +1 -1
  38. package/dist/query-client/index.d.cts +2 -2
  39. package/dist/query-client/index.d.ts +2 -2
  40. package/dist/query-client/index.js +1 -1
  41. package/dist/react.cjs +0 -1
  42. package/dist/react.cjs.map +1 -1
  43. package/dist/react.js +0 -1
  44. package/dist/react.js.map +1 -1
  45. package/dist/scope-path-B1G3YiA7.d.cts +139 -0
  46. package/dist/scope-path-B1G3YiA7.d.ts +139 -0
  47. package/dist/{serialization-C6JNNOCS.js → serialization-ZZ7RSDRX.js} +2 -2
  48. package/dist/svelte.cjs +0 -2
  49. package/dist/svelte.cjs.map +1 -1
  50. package/dist/svelte.js +0 -2
  51. package/dist/svelte.js.map +1 -1
  52. package/dist/{types-BVtx9zLv.d.cts → types-DOemdlVA.d.cts} +20 -2
  53. package/dist/{types-BVtx9zLv.d.ts → types-DOemdlVA.d.ts} +20 -2
  54. package/package.json +39 -40
  55. package/dist/chunk-6OQW5OKO.js.map +0 -1
  56. package/dist/chunk-KFA7G37W.js.map +0 -1
  57. package/dist/chunk-WOAJRVHD.js +0 -699
  58. package/dist/chunk-WOAJRVHD.js.map +0 -1
  59. package/dist/chunk-YUXOALMR.js.map +0 -1
  60. package/dist/d1.cjs +0 -2416
  61. package/dist/d1.cjs.map +0 -1
  62. package/dist/d1.d.cts +0 -54
  63. package/dist/d1.d.ts +0 -54
  64. package/dist/d1.js +0 -75
  65. package/dist/d1.js.map +0 -1
  66. package/dist/do-sqlite.cjs.map +0 -1
  67. package/dist/do-sqlite.d.cts +0 -41
  68. package/dist/do-sqlite.d.ts +0 -41
  69. package/dist/do-sqlite.js +0 -78
  70. package/dist/do-sqlite.js.map +0 -1
  71. package/dist/editor/client/assets/index-tyFcX6qG.js +0 -411
  72. /package/dist/{serialization-C6JNNOCS.js.map → serialization-ZZ7RSDRX.js.map} +0 -0
package/dist/index.cjs CHANGED
@@ -66,10 +66,18 @@ function serializeValue(value) {
66
66
  if (value === null || value === void 0) return value;
67
67
  if (typeof value !== "object") return value;
68
68
  if (isTimestamp(value)) {
69
- return { [SERIALIZATION_TAG]: "Timestamp", seconds: value.seconds, nanoseconds: value.nanoseconds };
69
+ return {
70
+ [SERIALIZATION_TAG]: "Timestamp",
71
+ seconds: value.seconds,
72
+ nanoseconds: value.nanoseconds
73
+ };
70
74
  }
71
75
  if (isGeoPoint(value)) {
72
- return { [SERIALIZATION_TAG]: "GeoPoint", latitude: value.latitude, longitude: value.longitude };
76
+ return {
77
+ [SERIALIZATION_TAG]: "GeoPoint",
78
+ latitude: value.latitude,
79
+ longitude: value.longitude
80
+ };
73
81
  }
74
82
  if (isDocumentReference(value)) {
75
83
  return { [SERIALIZATION_TAG]: "DocumentReference", path: value.path };
@@ -150,6 +158,7 @@ var init_serialization = __esm({
150
158
  var index_exports = {};
151
159
  __export(index_exports, {
152
160
  BOOTSTRAP_ENTRIES: () => BOOTSTRAP_ENTRIES,
161
+ CrossBackendTransactionError: () => CrossBackendTransactionError,
153
162
  DEFAULT_QUERY_LIMIT: () => DEFAULT_QUERY_LIMIT,
154
163
  DiscoveryError: () => DiscoveryError,
155
164
  DynamicRegistryError: () => DynamicRegistryError,
@@ -171,6 +180,7 @@ __export(index_exports, {
171
180
  TraversalError: () => TraversalError,
172
181
  ValidationError: () => ValidationError,
173
182
  analyzeQuerySafety: () => analyzeQuerySafety,
183
+ appendStorageScope: () => appendStorageScope,
174
184
  applyMigrationChain: () => applyMigrationChain,
175
185
  buildEdgeQueryPlan: () => buildEdgeQueryPlan,
176
186
  buildEdgeRecord: () => buildEdgeRecord,
@@ -198,6 +208,7 @@ __export(index_exports, {
198
208
  generateId: () => generateId,
199
209
  generateIndexConfig: () => generateIndexConfig,
200
210
  generateTypes: () => generateTypes,
211
+ isAncestorScopeUid: () => isAncestorScopeUid,
201
212
  isAncestorUid: () => isAncestorUid,
202
213
  isTaggedValue: () => isTaggedValue,
203
214
  jsonSchemaToFieldMeta: () => jsonSchemaToFieldMeta,
@@ -205,8 +216,10 @@ __export(index_exports, {
205
216
  matchScopeAny: () => matchScopeAny,
206
217
  migrateRecord: () => migrateRecord,
207
218
  migrateRecords: () => migrateRecords,
219
+ parseStorageScope: () => parseStorageScope,
208
220
  precompileSource: () => precompileSource,
209
221
  resolveAncestorCollection: () => resolveAncestorCollection,
222
+ resolveAncestorScope: () => resolveAncestorScope,
210
223
  resolveView: () => resolveView,
211
224
  serializeFirestoreTypes: () => serializeFirestoreTypes,
212
225
  validateMigrationChain: () => validateMigrationChain
@@ -331,10 +344,7 @@ var ValidationError = class extends FiregraphError {
331
344
  };
332
345
  var RegistryViolationError = class extends FiregraphError {
333
346
  constructor(aType, axbType, bType) {
334
- super(
335
- `Unregistered triple: (${aType}) -[${axbType}]-> (${bType})`,
336
- "REGISTRY_VIOLATION"
337
- );
347
+ super(`Unregistered triple: (${aType}) -[${axbType}]-> (${bType})`, "REGISTRY_VIOLATION");
338
348
  this.name = "RegistryViolationError";
339
349
  }
340
350
  };
@@ -377,6 +387,12 @@ var MigrationError = class extends FiregraphError {
377
387
  this.name = "MigrationError";
378
388
  }
379
389
  };
390
+ var CrossBackendTransactionError = class extends FiregraphError {
391
+ constructor(message) {
392
+ super(message, "CROSS_BACKEND_TRANSACTION");
393
+ this.name = "CrossBackendTransactionError";
394
+ }
395
+ };
380
396
 
381
397
  // src/json-schema.ts
382
398
  var import_ajv = __toESM(require("ajv"), 1);
@@ -398,9 +414,7 @@ function compileSchema(schema, label) {
398
414
  }
399
415
  function jsonSchemaToFieldMeta(schema) {
400
416
  if (!schema || schema.type !== "object" || !schema.properties) return [];
401
- const requiredSet = new Set(
402
- Array.isArray(schema.required) ? schema.required : []
403
- );
417
+ const requiredSet = new Set(Array.isArray(schema.required) ? schema.required : []);
404
418
  return Object.entries(schema.properties).map(
405
419
  ([name, prop]) => propertyToFieldMeta(name, prop, requiredSet.has(name))
406
420
  );
@@ -643,6 +657,28 @@ function createRegistry(input) {
643
657
  for (const [key, arr] of axbBuild) {
644
658
  axbIndex.set(key, Object.freeze(arr));
645
659
  }
660
+ const topologyIndex = /* @__PURE__ */ new Map();
661
+ const topologyBuild = /* @__PURE__ */ new Map();
662
+ const topologySeen = /* @__PURE__ */ new Map();
663
+ for (const entry of entries) {
664
+ if (!entry.targetGraph) continue;
665
+ let seen = topologySeen.get(entry.aType);
666
+ if (!seen) {
667
+ seen = /* @__PURE__ */ new Set();
668
+ topologySeen.set(entry.aType, seen);
669
+ }
670
+ if (seen.has(entry.targetGraph)) continue;
671
+ seen.add(entry.targetGraph);
672
+ const existing = topologyBuild.get(entry.aType);
673
+ if (existing) {
674
+ existing.push(entry);
675
+ } else {
676
+ topologyBuild.set(entry.aType, [entry]);
677
+ }
678
+ }
679
+ for (const [key, arr] of topologyBuild) {
680
+ topologyIndex.set(key, Object.freeze(arr));
681
+ }
646
682
  return {
647
683
  lookup(aType, axbType, bType) {
648
684
  return map.get(tripleKey(aType, axbType, bType))?.entry;
@@ -650,6 +686,9 @@ function createRegistry(input) {
650
686
  lookupByAxbType(axbType) {
651
687
  return axbIndex.get(axbType) ?? [];
652
688
  },
689
+ getSubgraphTopology(aType) {
690
+ return topologyIndex.get(aType) ?? [];
691
+ },
653
692
  validate(aType, axbType, bType, data, scopePath) {
654
693
  const rec = map.get(tripleKey(aType, axbType, bType));
655
694
  if (!rec) {
@@ -697,6 +736,21 @@ function createMergedRegistry(base, extension) {
697
736
  }
698
737
  return Object.freeze(merged);
699
738
  },
739
+ getSubgraphTopology(aType) {
740
+ const baseResults = base.getSubgraphTopology(aType);
741
+ const extResults = extension.getSubgraphTopology(aType);
742
+ if (extResults.length === 0) return baseResults;
743
+ if (baseResults.length === 0) return extResults;
744
+ const seen = new Set(baseResults.map((e) => e.targetGraph));
745
+ const merged = [...baseResults];
746
+ for (const entry of extResults) {
747
+ if (!seen.has(entry.targetGraph)) {
748
+ seen.add(entry.targetGraph);
749
+ merged.push(entry);
750
+ }
751
+ }
752
+ return Object.freeze(merged);
753
+ },
700
754
  validate(aType, axbType, bType, data, scopePath) {
701
755
  if (baseKeys.has(tripleKey(aType, axbType, bType))) {
702
756
  return base.validate(aType, axbType, bType, data, scopePath);
@@ -1429,6 +1483,21 @@ var GraphClientImpl = class _GraphClientImpl {
1429
1483
  getBackend() {
1430
1484
  return this.backend;
1431
1485
  }
1486
+ /**
1487
+ * Snapshot of the currently-effective registry. Returns the merged view
1488
+ * used for domain-type validation and migration — in dynamic mode this is
1489
+ * `dynamicRegistry ?? staticRegistry ?? bootstrapRegistry`, so callers see
1490
+ * updates after `reloadRegistry()` without having to re-resolve anything.
1491
+ *
1492
+ * Exposed for backends that need topology access during bulk operations
1493
+ * (e.g. the Cloudflare DO backend's cross-DO cascade). Not part of the
1494
+ * public `GraphClient` surface.
1495
+ *
1496
+ * @internal
1497
+ */
1498
+ getRegistrySnapshot() {
1499
+ return this.getCombinedRegistry();
1500
+ }
1432
1501
  // ---------------------------------------------------------------------------
1433
1502
  // Registry routing
1434
1503
  // ---------------------------------------------------------------------------
@@ -2035,14 +2104,10 @@ function loadEdgeEntity(dir, name) {
2035
2104
  }
2036
2105
  const topology = readJson(edgePath);
2037
2106
  if (!topology.from) {
2038
- throw new DiscoveryError(
2039
- `edge.json for "${name}" is missing required "from" field`
2040
- );
2107
+ throw new DiscoveryError(`edge.json for "${name}" is missing required "from" field`);
2041
2108
  }
2042
2109
  if (!topology.to) {
2043
- throw new DiscoveryError(
2044
- `edge.json for "${name}" is missing required "to" field`
2045
- );
2110
+ throw new DiscoveryError(`edge.json for "${name}" is missing required "to" field`);
2046
2111
  }
2047
2112
  const meta = readJsonIfExists((0, import_node_path.join)(dir, "meta.json"));
2048
2113
  const sampleData = readJsonIfExists((0, import_node_path.join)(dir, "sample.json"));
@@ -2719,6 +2784,26 @@ function generateIndexConfig(collection, entities, registryEntries) {
2719
2784
  // src/query-client/client.ts
2720
2785
  var import_node_http = __toESM(require("http"), 1);
2721
2786
 
2787
+ // src/query-client/config.ts
2788
+ var import_node_fs2 = require("fs");
2789
+ var import_node_path2 = require("path");
2790
+ var CONFIG_FILES = ["firegraph.config.ts", "firegraph.config.js", "firegraph.config.mjs"];
2791
+ var DEFAULT_PORT = 3884;
2792
+ function readEditorPort(cwd) {
2793
+ const dir = cwd ?? process.cwd();
2794
+ for (const name of CONFIG_FILES) {
2795
+ try {
2796
+ const content = (0, import_node_fs2.readFileSync)((0, import_node_path2.join)(dir, name), "utf8");
2797
+ const editorBlock = content.match(/editor\s*:\s*\{[^}]*\}/s)?.[0] ?? "";
2798
+ const portMatch = editorBlock.match(/port\s*:\s*(\d+)/);
2799
+ if (portMatch) return parseInt(portMatch[1], 10);
2800
+ } catch {
2801
+ continue;
2802
+ }
2803
+ }
2804
+ return DEFAULT_PORT;
2805
+ }
2806
+
2722
2807
  // src/query-client/shaping.ts
2723
2808
  function summarizeRecord(r) {
2724
2809
  if (!r) return null;
@@ -2745,26 +2830,6 @@ function summarizeEdge(r) {
2745
2830
  return out;
2746
2831
  }
2747
2832
 
2748
- // src/query-client/config.ts
2749
- var import_node_fs2 = require("fs");
2750
- var import_node_path2 = require("path");
2751
- var CONFIG_FILES = ["firegraph.config.ts", "firegraph.config.js", "firegraph.config.mjs"];
2752
- var DEFAULT_PORT = 3884;
2753
- function readEditorPort(cwd) {
2754
- const dir = cwd ?? process.cwd();
2755
- for (const name of CONFIG_FILES) {
2756
- try {
2757
- const content = (0, import_node_fs2.readFileSync)((0, import_node_path2.join)(dir, name), "utf8");
2758
- const editorBlock = content.match(/editor\s*:\s*\{[^}]*\}/s)?.[0] ?? "";
2759
- const portMatch = editorBlock.match(/port\s*:\s*(\d+)/);
2760
- if (portMatch) return parseInt(portMatch[1], 10);
2761
- } catch {
2762
- continue;
2763
- }
2764
- }
2765
- return DEFAULT_PORT;
2766
- }
2767
-
2768
2833
  // src/query-client/client.ts
2769
2834
  var QueryClientError = class extends Error {
2770
2835
  constructor(message, code) {
@@ -2963,14 +3028,16 @@ var QueryClient = class {
2963
3028
  }
2964
3029
  const data = await this.mutate("traverse", input);
2965
3030
  return {
2966
- hops: (data.hops ?? []).map((h) => ({
2967
- relation: h.axbType,
2968
- direction: h.direction,
2969
- depth: h.depth,
2970
- edgeCount: (h.edges ?? []).length,
2971
- edges: (h.edges ?? []).map(summarizeEdge).filter(Boolean),
2972
- truncated: h.truncated ?? false
2973
- })),
3031
+ hops: (data.hops ?? []).map(
3032
+ (h) => ({
3033
+ relation: h.axbType,
3034
+ direction: h.direction,
3035
+ depth: h.depth,
3036
+ edgeCount: (h.edges ?? []).length,
3037
+ edges: (h.edges ?? []).map(summarizeEdge).filter(Boolean),
3038
+ truncated: h.truncated ?? false
3039
+ })
3040
+ ),
2974
3041
  totalReads: data.totalReads ?? 0,
2975
3042
  truncated: data.truncated ?? false
2976
3043
  };
@@ -3021,6 +3088,56 @@ function buildEdgeRecord(aType, aUid, axbType, bType, bUid, data) {
3021
3088
  };
3022
3089
  }
3023
3090
 
3091
+ // src/scope-path.ts
3092
+ function parseStorageScope(scope) {
3093
+ if (scope === "") return [];
3094
+ const parts = scope.split("/");
3095
+ if (parts.length % 2 !== 0) {
3096
+ throw new Error(
3097
+ `INVALID_SCOPE_PATH: storage-scope "${scope}" has an odd number of segments; expected interleaved <uid>/<name> pairs.`
3098
+ );
3099
+ }
3100
+ const out = [];
3101
+ for (let i = 0; i < parts.length; i += 2) {
3102
+ const uid = parts[i];
3103
+ const name = parts[i + 1];
3104
+ if (!uid || !name) {
3105
+ throw new Error(
3106
+ `INVALID_SCOPE_PATH: storage-scope "${scope}" contains an empty segment at position ${i}.`
3107
+ );
3108
+ }
3109
+ out.push({ uid, name });
3110
+ }
3111
+ return out;
3112
+ }
3113
+ function resolveAncestorScope(storageScope, uid) {
3114
+ if (!uid) return null;
3115
+ if (storageScope === "") return null;
3116
+ const parts = storageScope.split("/");
3117
+ for (let i = 0; i < parts.length; i += 2) {
3118
+ if (parts[i] === uid) {
3119
+ return i === 0 ? "" : parts.slice(0, i).join("/");
3120
+ }
3121
+ }
3122
+ return null;
3123
+ }
3124
+ function isAncestorScopeUid(storageScope, uid) {
3125
+ return resolveAncestorScope(storageScope, uid) !== null;
3126
+ }
3127
+ function appendStorageScope(parentScope, uid, name) {
3128
+ if (!uid || uid.includes("/")) {
3129
+ throw new Error(
3130
+ `INVALID_SCOPE_PATH: uid must be non-empty and must not contain "/": got "${uid}".`
3131
+ );
3132
+ }
3133
+ if (!name || name.includes("/")) {
3134
+ throw new Error(
3135
+ `INVALID_SCOPE_PATH: name must be non-empty and must not contain "/": got "${name}".`
3136
+ );
3137
+ }
3138
+ return parentScope ? `${parentScope}/${uid}/${name}` : `${uid}/${name}`;
3139
+ }
3140
+
3024
3141
  // src/index.ts
3025
3142
  init_serialization();
3026
3143
 
@@ -3228,7 +3345,6 @@ function getCustomElements() {
3228
3345
  function resilientView(ViewClass, tagName) {
3229
3346
  const g = globalThis;
3230
3347
  if (!g.HTMLElement) return ViewClass;
3231
- const Base = g.HTMLElement;
3232
3348
  const Wrapped = class extends ViewClass {
3233
3349
  connectedCallback() {
3234
3350
  try {
@@ -3316,6 +3432,7 @@ function defineViews(input) {
3316
3432
  // Annotate the CommonJS export names for ESM import in node:
3317
3433
  0 && (module.exports = {
3318
3434
  BOOTSTRAP_ENTRIES,
3435
+ CrossBackendTransactionError,
3319
3436
  DEFAULT_QUERY_LIMIT,
3320
3437
  DiscoveryError,
3321
3438
  DynamicRegistryError,
@@ -3337,6 +3454,7 @@ function defineViews(input) {
3337
3454
  TraversalError,
3338
3455
  ValidationError,
3339
3456
  analyzeQuerySafety,
3457
+ appendStorageScope,
3340
3458
  applyMigrationChain,
3341
3459
  buildEdgeQueryPlan,
3342
3460
  buildEdgeRecord,
@@ -3364,6 +3482,7 @@ function defineViews(input) {
3364
3482
  generateId,
3365
3483
  generateIndexConfig,
3366
3484
  generateTypes,
3485
+ isAncestorScopeUid,
3367
3486
  isAncestorUid,
3368
3487
  isTaggedValue,
3369
3488
  jsonSchemaToFieldMeta,
@@ -3371,8 +3490,10 @@ function defineViews(input) {
3371
3490
  matchScopeAny,
3372
3491
  migrateRecord,
3373
3492
  migrateRecords,
3493
+ parseStorageScope,
3374
3494
  precompileSource,
3375
3495
  resolveAncestorCollection,
3496
+ resolveAncestorScope,
3376
3497
  resolveView,
3377
3498
  serializeFirestoreTypes,
3378
3499
  validateMigrationChain