@modernrelay/orbit-omnigraph 0.14.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -91,42 +91,14 @@ function findBlockEnd(src, openIdx) {
91
91
  }
92
92
  return n;
93
93
  }
94
- function splitStatements(body) {
95
- const out = [];
96
- let depth = 0;
97
- let current = "";
98
- let i = 0;
99
- const n = body.length;
100
- while (i < n) {
101
- const ch = body.charAt(i);
102
- if (ch === '"') {
103
- current += ch;
104
- i++;
105
- while (i < n) {
106
- const c = body.charAt(i);
107
- current += c;
108
- i++;
109
- if (c === "\\" && i < n) {
110
- current += body.charAt(i);
111
- i++;
112
- } else if (c === '"') break;
113
- }
114
- continue;
115
- }
116
- if (ch === "(" || ch === "[") depth++;
117
- else if (ch === ")" || ch === "]") depth = Math.max(0, depth - 1);
118
- if (ch === "\n" && depth === 0) {
119
- out.push(current);
120
- current = "";
121
- } else {
122
- current += ch;
123
- }
124
- i++;
125
- }
126
- out.push(current);
127
- return out.map((s) => s.trim()).filter((s) => s.length > 0);
128
- }
129
- function scanAnnotations(src, start) {
94
+ var BODY_CONSTRAINT_NAMES = /* @__PURE__ */ new Set([
95
+ "key",
96
+ "unique",
97
+ "index",
98
+ "range",
99
+ "check"
100
+ ]);
101
+ function scanAnnotations(src, start, stopBeforeBodyConstraint = false) {
130
102
  const anns = [];
131
103
  let i = start;
132
104
  const n = src.length;
@@ -134,14 +106,16 @@ function scanAnnotations(src, start) {
134
106
  let j = i;
135
107
  while (j < n && /\s/.test(src.charAt(j))) j++;
136
108
  if (src.charAt(j) !== "@") break;
137
- const m = /^@([A-Za-z_]\w*)/.exec(src.slice(j));
109
+ const m = /^@\s*([A-Za-z_]\w*)/.exec(src.slice(j));
138
110
  if (!m || m[1] === void 0) break;
139
111
  const name = m[1];
140
112
  let end = j + m[0].length;
141
113
  let args;
142
- if (src.charAt(end) === "(") {
114
+ let open = end;
115
+ while (open < n && /\s/.test(src.charAt(open))) open++;
116
+ if (src.charAt(open) === "(") {
143
117
  let depth = 0;
144
- let k = end;
118
+ let k = open;
145
119
  while (k < n) {
146
120
  const ch = src.charAt(k);
147
121
  if (ch === '"') {
@@ -164,9 +138,12 @@ function scanAnnotations(src, start) {
164
138
  }
165
139
  k++;
166
140
  }
167
- args = src.slice(end + 1, k - 1);
141
+ args = src.slice(open + 1, k - 1);
168
142
  end = k;
169
143
  }
144
+ if (stopBeforeBodyConstraint && args !== void 0 && BODY_CONSTRAINT_NAMES.has(name)) {
145
+ break;
146
+ }
170
147
  const entry = { name, raw: src.slice(j, end) };
171
148
  if (args !== void 0) entry.args = args;
172
149
  anns.push(entry);
@@ -218,20 +195,30 @@ function parseTypeRef(text) {
218
195
  i += m[0].length;
219
196
  } else {
220
197
  const close = text.indexOf("]", i);
221
- const end = close === -1 ? n : close + 1;
198
+ const nextLine = text.indexOf("\n", i);
199
+ let end = close === -1 ? n : close + 1;
200
+ if (nextLine !== -1 && nextLine < end) end = nextLine;
222
201
  type = { kind: "unknown", raw: text.slice(i, end).trim() };
223
202
  i = end;
224
203
  }
225
204
  } else {
226
205
  const m = /^([A-Za-z_]\w*)/.exec(text.slice(i));
227
206
  if (!m || m[1] === void 0) {
228
- return { type: { kind: "unknown", raw: text.trim() }, optional: false, end: n };
207
+ const nextLine = text.indexOf("\n", i);
208
+ const end = nextLine === -1 ? n : nextLine;
209
+ return {
210
+ type: { kind: "unknown", raw: text.slice(i, end).trim() },
211
+ optional: false,
212
+ end
213
+ };
229
214
  }
230
215
  const ident = m[1];
231
216
  i += m[0].length;
232
- if ((ident === "enum" || ident === "Vector") && text.charAt(i) === "(") {
217
+ let open = i;
218
+ while (open < n && /\s/.test(text.charAt(open))) open++;
219
+ if ((ident === "enum" || ident === "Vector") && text.charAt(open) === "(") {
233
220
  let depth = 0;
234
- let k = i;
221
+ let k = open;
235
222
  while (k < n) {
236
223
  const ch = text.charAt(k);
237
224
  if (ch === "(") depth++;
@@ -244,7 +231,7 @@ function parseTypeRef(text) {
244
231
  }
245
232
  k++;
246
233
  }
247
- const inner = text.slice(i + 1, k - 1);
234
+ const inner = text.slice(open + 1, k - 1);
248
235
  i = k;
249
236
  if (ident === "enum") {
250
237
  const values = splitArgs(inner).map((v) => v.replace(/^"(.*)"$/s, "$1"));
@@ -260,6 +247,7 @@ function parseTypeRef(text) {
260
247
  }
261
248
  }
262
249
  let optional = false;
250
+ while (i < n && /\s/.test(text.charAt(i))) i++;
263
251
  if (text.charAt(i) === "?") {
264
252
  optional = true;
265
253
  i++;
@@ -269,35 +257,39 @@ function parseTypeRef(text) {
269
257
  function parseBody(body) {
270
258
  const properties = [];
271
259
  const constraints = [];
272
- for (const stmt of splitStatements(body)) {
273
- if (stmt.startsWith("@")) {
274
- const { anns } = scanAnnotations(stmt, 0);
275
- for (const a of anns) constraints.push(a.raw);
260
+ let cursor = body.trimStart();
261
+ while (cursor !== "") {
262
+ if (cursor.startsWith("@")) {
263
+ const { anns: anns2, end: end2 } = scanAnnotations(cursor, 0);
264
+ if (anns2.length === 0 || end2 === 0) break;
265
+ for (const a of anns2) constraints.push(a.raw);
266
+ cursor = cursor.slice(end2).trimStart();
276
267
  continue;
277
268
  }
278
- let cursor = stmt;
279
- for (; ; ) {
280
- const head = /^([A-Za-z_]\w*)\s*:\s*/.exec(cursor);
281
- if (!head || head[1] === void 0) break;
282
- const name = head[1];
283
- const rest = cursor.slice(head[0].length);
284
- const { type, optional, end } = parseTypeRef(rest);
285
- const { anns, end: annsEnd } = scanAnnotations(rest, end);
286
- properties.push({
287
- name,
288
- type,
289
- optional,
290
- key: anns.some((a) => a.name === "key"),
291
- unique: anns.some((a) => a.name === "unique"),
292
- index: anns.some((a) => a.name === "index"),
293
- annotations: anns.map((a) => a.raw)
294
- });
295
- cursor = rest.slice(annsEnd).trimStart();
296
- if (cursor === "") break;
269
+ const head = /^([A-Za-z_]\w*)\s*:\s*/.exec(cursor);
270
+ if (!head || head[1] === void 0) {
271
+ const nextLine = cursor.indexOf("\n");
272
+ if (nextLine === -1) break;
273
+ cursor = cursor.slice(nextLine + 1).trimStart();
274
+ continue;
297
275
  }
276
+ const name = head[1];
277
+ const rest = cursor.slice(head[0].length);
278
+ const { type, optional, end } = parseTypeRef(rest);
279
+ const { anns, end: annsEnd } = scanAnnotations(rest, end, true);
280
+ properties.push({
281
+ name,
282
+ type,
283
+ optional,
284
+ key: anns.some((a) => a.name === "key"),
285
+ unique: anns.some((a) => a.name === "unique"),
286
+ index: anns.some((a) => a.name === "index"),
287
+ annotations: anns.map((a) => a.raw)
288
+ });
289
+ cursor = rest.slice(annsEnd).trimStart();
298
290
  }
299
291
  for (const raw of constraints) {
300
- const m = /^@(key|unique|index)\((.*)\)$/s.exec(raw);
292
+ const m = /^@\s*(key|unique|index)\s*\((.*)\)$/s.exec(raw);
301
293
  if (!m || m[1] === void 0 || m[2] === void 0) continue;
302
294
  const flag = m[1];
303
295
  for (const propName of splitArgs(m[2])) {
@@ -530,5 +522,5 @@ function normalizeEdge(line, schema) {
530
522
  }
531
523
 
532
524
  export { InvalidExportLineError, ORBIT_TYPE_KEY, UnknownEdgeTypeError, bigIntKeyWarnings, classifyExportLine, decodeSourceId, edgeEndpointTypes, encodeSourceId, encodeSyntheticEdgeId, normalizeEdge, normalizeNode, parsePgSchema, schemaFingerprint };
533
- //# sourceMappingURL=chunk-YDRPXYQ7.js.map
534
- //# sourceMappingURL=chunk-YDRPXYQ7.js.map
525
+ //# sourceMappingURL=chunk-WMBDYPK2.js.map
526
+ //# sourceMappingURL=chunk-WMBDYPK2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/idCodec.ts","../src/pgSchema.ts","../src/normalize.ts"],"names":["anns","end","body","braceIdx","blockEnd"],"mappings":"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","file":"chunk-WMBDYPK2.js","sourcesContent":["/**\n * Identity codec.\n *\n * Omnigraph node ids are unique **per type only** (derived from the `@key`\n * tuple within each type's table), so unqualified ids are unsound as orbit\n * `NodeId`s. Every adapter path — nodes, edges, search results, view state,\n * services — MUST qualify ids through this one collision-proof tuple codec.\n * `JSON.stringify` of a fixed-arity string tuple is injective over its inputs\n * (quotes, brackets, commas, and unicode in either component are escaped), so\n * no `(kind, sourceId)` pair can collide with a different pair.\n *\n * Human-readable labels stay separate from identity; there is deliberately no\n * `namespaceIds:false` escape hatch.\n */\n\nexport interface DecodedSourceId {\n /** The namespace component: a node type name or an edge type name. */\n kind: string;\n /** The physical Omnigraph id within that type's table. */\n sourceId: string;\n}\n\n/**\n * Encode a `(kind, sourceId)` pair as a collision-proof orbit id.\n *\n * - Nodes: `encodeSourceId(NodeType, data.id)`\n * - Edges: `encodeSourceId(EdgeName, data.id)`; endpoints use\n * `encodeSourceId(endpointType, from|to)`.\n */\nexport function encodeSourceId(kind: string, sourceId: string): string {\n return JSON.stringify([kind, sourceId]);\n}\n\n/**\n * Decode an id produced by {@link encodeSourceId}.\n *\n * Returns `null` for anything that does not conform exactly (non-JSON input,\n * non-array JSON, wrong arity — including synthetic edge ids, which are\n * 4-tuples — or non-string elements). Never throws.\n */\nexport function decodeSourceId(id: string): DecodedSourceId | null {\n let parsed: unknown;\n try {\n parsed = JSON.parse(id);\n } catch {\n return null;\n }\n if (!Array.isArray(parsed) || parsed.length !== 2) return null;\n const [kind, sourceId] = parsed as unknown[];\n if (typeof kind !== 'string' || typeof sourceId !== 'string') return null;\n return { kind, sourceId };\n}\n\n/**\n * Synthetic edge id for **query-derived** subgraphs.\n *\n * The GQ grammar has no edge variable, so the query path can never surface\n * physical edge ids; query-derived edges are identified by\n * `['synthetic-edge', EdgeName, source, target]` where `source`/`target` are\n * the already-encoded endpoint node ids.\n *\n * Exported for the future query path.\n * Caveats: parallel edges collapse under this scheme, and a dataset\n * MUST NOT mix synthetic ids with physical `/export` ids for the same edges\n * one scheme per dataset, never both. Because a synthetic id is a 4-tuple,\n * {@link decodeSourceId} rejects it (`null`), keeping the two schemes\n * mechanically un-confusable.\n */\nexport function encodeSyntheticEdgeId(edgeName: string, source: string, target: string): string {\n return JSON.stringify(['synthetic-edge', edgeName, source, target]);\n}\n","/**\n * `.pg` schema model + tolerant parser.\n *\n * The adapter needs three things from the graph schema, all served here:\n * 1. edge endpoint-type resolution (export edge lines carry bare `from`/`to`\n * ids without endpoint types),\n * 2. per-property wire-type knowledge for temporal/blob normalization,\n * 3. a stable schema fingerprint for the export revision stamp.\n *\n * The parser is deliberately tolerant: it extracts the declarations it\n * understands (interfaces, node blocks, edge declarations, properties,\n * constraints) and preserves anything else — unknown annotations survive as\n * raw strings, unknown type spellings become `{ kind: 'unknown' }` — so a\n * newer server grammar degrades gracefully instead of failing the load.\n *\n * Browser-safe: no `node:` imports. The fingerprint is a pure FNV-1a 64-bit\n * hash rather than `node:crypto` sha256 so this module can sit on the\n * browser entry's critical path.\n */\n\n// ---------------------------------------------------------------------------\n// Model\n// ---------------------------------------------------------------------------\n\n/** Closed scalar set per the `.pg` grammar (docs/user/schema). */\nexport type PgScalarName =\n | 'String'\n | 'Blob'\n | 'Bool'\n | 'I32'\n | 'I64'\n | 'U32'\n | 'U64'\n | 'F32'\n | 'F64'\n | 'Date'\n | 'DateTime';\n\nexport type PgType =\n | PgScalarName\n | { kind: 'vector'; dim: number }\n | { kind: 'enum'; values: readonly string[] }\n | { kind: 'list'; element: PgScalarName }\n | { kind: 'unknown'; raw: string };\n\nexport interface PgProperty {\n name: string;\n type: PgType;\n /** `T?` nullability. */\n optional: boolean;\n /** Set by inline `@key` or a body-level `@key(...)` naming this property. */\n key: boolean;\n /** Set by inline `@unique` or a body-level `@unique(...)` naming this property. */\n unique: boolean;\n /** Set by inline `@index` or a body-level `@index(...)` naming this property. */\n index: boolean;\n /** Every annotation as written (`'@key'`, `'@embed(\"body\")'`) — unknown ones preserved verbatim. */\n annotations: readonly string[];\n}\n\nexport interface PgInterfaceType {\n name: string;\n properties: readonly PgProperty[];\n /** Body-level constraint declarations preserved verbatim (e.g. `'@unique(a, b)'`). */\n constraints: readonly string[];\n}\n\nexport interface PgNodeType {\n name: string;\n /** Interface names from the `implements` clause (already expanded into `properties`). */\n implements: readonly string[];\n properties: readonly PgProperty[];\n constraints: readonly string[];\n}\n\nexport interface PgEdgeType {\n name: string;\n /** Source (from) node type name. */\n from: string;\n /** Destination (to) node type name. */\n to: string;\n /** Raw `@card` bounds, e.g. `'1..1'`, `'0..*'`. Absent means the default `0..*`. */\n card?: string;\n /** Header annotations as written (including the `@card(...)` one, if any). */\n annotations: readonly string[];\n properties: readonly PgProperty[];\n constraints: readonly string[];\n}\n\nexport interface PgSchema {\n interfaces: readonly PgInterfaceType[];\n nodes: readonly PgNodeType[];\n edges: readonly PgEdgeType[];\n}\n\nconst SCALARS: ReadonlySet<string> = new Set<PgScalarName>([\n 'String',\n 'Blob',\n 'Bool',\n 'I32',\n 'I64',\n 'U32',\n 'U64',\n 'F32',\n 'F64',\n 'Date',\n 'DateTime',\n]);\n\n// ---------------------------------------------------------------------------\n// Lexical helpers (string-aware; `.pg` strings are double-quoted with `\\` escapes)\n// ---------------------------------------------------------------------------\n\n/** Blank out line and block comments, preserving newlines and string literals. */\nfunction stripComments(src: string): string {\n let out = '';\n let i = 0;\n const n = src.length;\n while (i < n) {\n const ch = src.charAt(i);\n if (ch === '\"') {\n out += ch;\n i++;\n while (i < n) {\n const c = src.charAt(i);\n out += c;\n i++;\n if (c === '\\\\' && i < n) {\n out += src.charAt(i);\n i++;\n } else if (c === '\"') break;\n }\n } else if (ch === '/' && src.charAt(i + 1) === '/') {\n while (i < n && src.charAt(i) !== '\\n') i++;\n } else if (ch === '/' && src.charAt(i + 1) === '*') {\n i += 2;\n while (i < n && !(src.charAt(i) === '*' && src.charAt(i + 1) === '/')) {\n out += src.charAt(i) === '\\n' ? '\\n' : ' ';\n i++;\n }\n i += 2;\n } else {\n out += ch;\n i++;\n }\n }\n return out;\n}\n\n/** Index just past the `}` matching the `{` at `openIdx`, or `src.length` if unbalanced. */\nfunction findBlockEnd(src: string, openIdx: number): number {\n let depth = 0;\n let i = openIdx;\n const n = src.length;\n while (i < n) {\n const ch = src.charAt(i);\n if (ch === '\"') {\n i++;\n while (i < n) {\n const c = src.charAt(i);\n i++;\n if (c === '\\\\') i++;\n else if (c === '\"') break;\n }\n continue;\n }\n if (ch === '{') depth++;\n else if (ch === '}') {\n depth--;\n if (depth === 0) return i + 1;\n }\n i++;\n }\n return n;\n}\n\ninterface RawAnnotation {\n name: string;\n args?: string;\n raw: string;\n}\n\nconst BODY_CONSTRAINT_NAMES: ReadonlySet<string> = new Set([\n 'key',\n 'unique',\n 'index',\n 'range',\n 'check',\n]);\n\n/** Scan a run of `@ident` / `@ident(...)` annotations starting at `start`. */\nfunction scanAnnotations(\n src: string,\n start: number,\n stopBeforeBodyConstraint = false,\n): { anns: RawAnnotation[]; end: number } {\n const anns: RawAnnotation[] = [];\n let i = start;\n const n = src.length;\n for (;;) {\n let j = i;\n while (j < n && /\\s/.test(src.charAt(j))) j++;\n if (src.charAt(j) !== '@') break;\n // `annotation` and `body_constraint` spell the sigil and name as\n // separate Pest sequence terms (`\"@\" ~ ident`), so implicit whitespace\n // is legal here too (`@ key`, `@ rename_from (...)`).\n const m = /^@\\s*([A-Za-z_]\\w*)/.exec(src.slice(j));\n if (!m || m[1] === undefined) break;\n const name = m[1];\n let end = j + m[0].length;\n let args: string | undefined;\n // Pest inserts the silent WHITESPACE rule around `~`, so all schema\n // annotations permit whitespace between their name and argument list\n // (`@card (1..1)`, `@embed (\"body\")`, ...). Keep that whitespace in the\n // preserved raw spelling while using the actual `(` as the parse cursor.\n let open = end;\n while (open < n && /\\s/.test(src.charAt(open))) open++;\n if (src.charAt(open) === '(') {\n let depth = 0;\n let k = open;\n while (k < n) {\n const ch = src.charAt(k);\n if (ch === '\"') {\n k++;\n while (k < n) {\n const c = src.charAt(k);\n k++;\n if (c === '\\\\') k++;\n else if (c === '\"') break;\n }\n continue;\n }\n if (ch === '(') depth++;\n else if (ch === ')') {\n depth--;\n if (depth === 0) {\n k++;\n break;\n }\n }\n k++;\n }\n args = src.slice(open + 1, k - 1);\n end = k;\n }\n // In a property declaration these call-shaped keywords begin the next\n // `body_constraint`; the Pest annotation rule explicitly excludes them.\n // Bare `@key`/`@unique`/`@index` remain valid property annotations.\n if (stopBeforeBodyConstraint && args !== undefined && BODY_CONSTRAINT_NAMES.has(name)) {\n break;\n }\n const entry: RawAnnotation = { name, raw: src.slice(j, end) };\n if (args !== undefined) entry.args = args;\n anns.push(entry);\n i = end;\n }\n return { anns, end: i };\n}\n\n/** Split on top-level commas (outside parens/strings), trim, drop empties. */\nfunction splitArgs(args: string): string[] {\n const out: string[] = [];\n let depth = 0;\n let current = '';\n for (let i = 0; i < args.length; i++) {\n const ch = args.charAt(i);\n if (ch === '\"') {\n current += ch;\n i++;\n while (i < args.length) {\n const c = args.charAt(i);\n current += c;\n if (c === '\\\\') {\n i++;\n current += args.charAt(i);\n } else if (c === '\"') break;\n i++;\n }\n continue;\n }\n if (ch === '(' || ch === '[') depth++;\n else if (ch === ')' || ch === ']') depth = Math.max(0, depth - 1);\n if (ch === ',' && depth === 0) {\n out.push(current);\n current = '';\n } else {\n current += ch;\n }\n }\n out.push(current);\n return out.map((s) => s.trim()).filter((s) => s.length > 0);\n}\n\n// ---------------------------------------------------------------------------\n// Statement parsing\n// ---------------------------------------------------------------------------\n\ninterface MutableTypeBody {\n properties: PgProperty[];\n constraints: string[];\n}\n\nfunction parseTypeRef(text: string): { type: PgType; optional: boolean; end: number } {\n let i = 0;\n const n = text.length;\n while (i < n && /\\s/.test(text.charAt(i))) i++;\n let type: PgType;\n if (text.charAt(i) === '[') {\n const m = /^\\[\\s*([A-Za-z_]\\w*)\\s*\\]/.exec(text.slice(i));\n if (m && m[1] !== undefined && SCALARS.has(m[1])) {\n type = { kind: 'list', element: m[1] as PgScalarName };\n i += m[0].length;\n } else {\n const close = text.indexOf(']', i);\n const nextLine = text.indexOf('\\n', i);\n let end = close === -1 ? n : close + 1;\n if (nextLine !== -1 && nextLine < end) end = nextLine;\n type = { kind: 'unknown', raw: text.slice(i, end).trim() };\n i = end;\n }\n } else {\n const m = /^([A-Za-z_]\\w*)/.exec(text.slice(i));\n if (!m || m[1] === undefined) {\n const nextLine = text.indexOf('\\n', i);\n const end = nextLine === -1 ? n : nextLine;\n return {\n type: { kind: 'unknown', raw: text.slice(i, end).trim() },\n optional: false,\n end,\n };\n }\n const ident = m[1];\n i += m[0].length;\n // As with annotations, the server grammar's silent WHITESPACE rule makes\n // `Vector (3)` and `enum (a, b)` equivalent to their compact spellings.\n let open = i;\n while (open < n && /\\s/.test(text.charAt(open))) open++;\n if ((ident === 'enum' || ident === 'Vector') && text.charAt(open) === '(') {\n let depth = 0;\n let k = open;\n while (k < n) {\n const ch = text.charAt(k);\n if (ch === '(') depth++;\n else if (ch === ')') {\n depth--;\n if (depth === 0) {\n k++;\n break;\n }\n }\n k++;\n }\n const inner = text.slice(open + 1, k - 1);\n i = k;\n if (ident === 'enum') {\n const values = splitArgs(inner).map((v) => v.replace(/^\"(.*)\"$/s, '$1'));\n type = { kind: 'enum', values };\n } else {\n const dim = Number.parseInt(inner.trim(), 10);\n type = Number.isFinite(dim)\n ? { kind: 'vector', dim }\n : { kind: 'unknown', raw: `Vector(${inner})` };\n }\n } else if (SCALARS.has(ident)) {\n type = ident as PgScalarName;\n } else {\n type = { kind: 'unknown', raw: ident };\n }\n }\n let optional = false;\n // `type_ref = { core_type ~ \"?\"? }`: implicit whitespace also applies\n // before the optional marker (`String ?`, `[String] ?`, `Vector (3) ?`).\n while (i < n && /\\s/.test(text.charAt(i))) i++;\n if (text.charAt(i) === '?') {\n optional = true;\n i++;\n }\n return { type, optional, end: i };\n}\n\nfunction parseBody(body: string): MutableTypeBody {\n const properties: PgProperty[] = [];\n const constraints: string[] = [];\n // Pest's implicit WHITESPACE includes newlines, so a newline is not a\n // statement delimiter: `String\\n?`, `Vector\\n(3)`, and same-line adjacent\n // declarations are all legal. Consume the body as one token stream.\n let cursor = body.trimStart();\n while (cursor !== '') {\n if (cursor.startsWith('@')) {\n const { anns, end } = scanAnnotations(cursor, 0);\n if (anns.length === 0 || end === 0) break;\n for (const a of anns) constraints.push(a.raw);\n cursor = cursor.slice(end).trimStart();\n continue;\n }\n\n const head = /^([A-Za-z_]\\w*)\\s*:\\s*/.exec(cursor);\n if (!head || head[1] === undefined) {\n // Tolerant recovery: discard only the malformed physical line, then\n // resume. Valid declarations do not need newlines, but this preserves\n // the historical ability to salvage later lines after unknown syntax.\n const nextLine = cursor.indexOf('\\n');\n if (nextLine === -1) break;\n cursor = cursor.slice(nextLine + 1).trimStart();\n continue;\n }\n const name = head[1];\n const rest = cursor.slice(head[0].length);\n const { type, optional, end } = parseTypeRef(rest);\n const { anns, end: annsEnd } = scanAnnotations(rest, end, true);\n properties.push({\n name,\n type,\n optional,\n key: anns.some((a) => a.name === 'key'),\n unique: anns.some((a) => a.name === 'unique'),\n index: anns.some((a) => a.name === 'index'),\n annotations: anns.map((a) => a.raw),\n });\n cursor = rest.slice(annsEnd).trimStart();\n }\n // Body-level @key(a, b) / @unique(a) / @index(a) constraints flag the named properties.\n for (const raw of constraints) {\n const m = /^@\\s*(key|unique|index)\\s*\\((.*)\\)$/s.exec(raw);\n if (!m || m[1] === undefined || m[2] === undefined) continue;\n const flag = m[1] as 'key' | 'unique' | 'index';\n for (const propName of splitArgs(m[2])) {\n const prop = properties.find((p) => p.name === propName);\n if (prop) prop[flag] = true;\n }\n }\n return { properties, constraints };\n}\n\n// ---------------------------------------------------------------------------\n// Top-level parse\n// ---------------------------------------------------------------------------\n\n/**\n * Parse `.pg` source into a {@link PgSchema}. Tolerant by design: malformed\n * or unrecognized declarations are skipped, not fatal; `implements` clauses\n * are expanded into node properties (node-declared properties win on name\n * collisions, matching the server's table layout).\n */\nexport function parsePgSchema(source: string): PgSchema {\n const src = stripComments(source);\n const interfaces: PgInterfaceType[] = [];\n const nodes: (PgNodeType & { properties: PgProperty[] })[] = [];\n const edges: PgEdgeType[] = [];\n\n const headRe = /\\b(interface|node|edge)\\s+([A-Za-z_]\\w*)/g;\n let m: RegExpExecArray | null;\n while ((m = headRe.exec(src)) !== null) {\n const kw = m[1];\n const name = m[2];\n if (kw === undefined || name === undefined) continue;\n let pos = headRe.lastIndex;\n\n if (kw === 'edge') {\n const em = /^\\s*:\\s*([A-Za-z_]\\w*)\\s*->\\s*([A-Za-z_]\\w*)/.exec(src.slice(pos));\n if (!em || em[1] === undefined || em[2] === undefined) continue; // tolerant skip\n pos += em[0].length;\n const { anns, end } = scanAnnotations(src, pos);\n pos = end;\n let body: MutableTypeBody = { properties: [], constraints: [] };\n let braceIdx = pos;\n while (braceIdx < src.length && /\\s/.test(src.charAt(braceIdx))) braceIdx++;\n if (src.charAt(braceIdx) === '{') {\n const blockEnd = findBlockEnd(src, braceIdx);\n body = parseBody(src.slice(braceIdx + 1, blockEnd - 1));\n pos = blockEnd;\n }\n const card = anns.find((a) => a.name === 'card')?.args?.trim();\n const edge: PgEdgeType = {\n name,\n from: em[1],\n to: em[2],\n annotations: anns.map((a) => a.raw),\n properties: body.properties,\n constraints: body.constraints,\n ...(card !== undefined ? { card } : {}),\n };\n edges.push(edge);\n headRe.lastIndex = pos;\n continue;\n }\n\n // interface / node: optional `implements A, B` (node only), then a block.\n let impls: string[] = [];\n // The grammar carries head annotations (`@card`/`@unique` prove the\n // family). `node Account @rename_from(\"User\") { … }` previously hit the\n // tolerant skip and silently dropped the whole declaration.\n // Annotations are consumed (and ignored — migration metadata) on either\n // side of `implements`, through the SAME scanner the body lane uses. It\n // honors nested parens and escaped quotes; a first-`)` regex would\n // truncate `@rename_from(\"User (legacy)\")` and drop the node.\n const skipAnnotations = (): void => {\n pos = scanAnnotations(src, pos).end;\n };\n skipAnnotations();\n if (kw === 'node') {\n const im = /^\\s*implements\\s+([A-Za-z_]\\w*(?:\\s*,\\s*[A-Za-z_]\\w*)*)/.exec(src.slice(pos));\n if (im && im[1] !== undefined) {\n impls = im[1].split(',').map((s) => s.trim());\n pos += im[0].length;\n }\n skipAnnotations();\n }\n let braceIdx = pos;\n while (braceIdx < src.length && /\\s/.test(src.charAt(braceIdx))) braceIdx++;\n if (src.charAt(braceIdx) !== '{') continue; // tolerant skip\n const blockEnd = findBlockEnd(src, braceIdx);\n const body = parseBody(src.slice(braceIdx + 1, blockEnd - 1));\n headRe.lastIndex = blockEnd;\n if (kw === 'interface') {\n interfaces.push({ name, properties: body.properties, constraints: body.constraints });\n } else {\n nodes.push({\n name,\n implements: impls,\n properties: body.properties,\n constraints: body.constraints,\n });\n }\n }\n\n // Expand implements clauses: interface properties precede the node's own,\n // except where the node re-declares a name (node declaration wins).\n for (const node of nodes) {\n if (node.implements.length === 0) continue;\n const own = new Set(node.properties.map((p) => p.name));\n const inherited: PgProperty[] = [];\n for (const ifaceName of node.implements) {\n const iface = interfaces.find((i) => i.name === ifaceName);\n if (!iface) continue; // tolerant: unknown interface\n for (const p of iface.properties) {\n if (!own.has(p.name) && !inherited.some((q) => q.name === p.name)) inherited.push(p);\n }\n }\n node.properties = [...inherited, ...node.properties];\n }\n\n return { interfaces, nodes, edges };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve an edge type's declared endpoint node types. Export edge\n * lines carry bare `from`/`to` ids, so endpoint types come from here. Edge\n * names match exactly first, then case-insensitively (the server matches edge\n * names case-insensitively). Returns `null` for an unknown edge name.\n */\nexport function edgeEndpointTypes(\n schema: PgSchema,\n edgeName: string,\n): { from: string; to: string } | null {\n const lower = edgeName.toLowerCase();\n const edge =\n schema.edges.find((e) => e.name === edgeName) ??\n schema.edges.find((e) => e.name.toLowerCase() === lower);\n return edge ? { from: edge.from, to: edge.to } : null;\n}\n\n/**\n * Stable fingerprint of `.pg` source for the adapter revision stamp: FNV-1a\n * 64-bit over the UTF-8 bytes of the source, as 16 lowercase hex chars.\n *\n * Pure and browser-safe (no `node:crypto`). Hashes the source **verbatim**:\n * any textual change — including comments or whitespace — changes the\n * fingerprint, which is the conservative choice for drift detection.\n */\nexport function schemaFingerprint(source: string): string {\n const MASK64 = 0xffffffffffffffffn;\n let h = 0xcbf29ce484222325n;\n const bytes = new TextEncoder().encode(source);\n for (const b of bytes) {\n h ^= BigInt(b);\n h = (h * 0x100000001b3n) & MASK64;\n }\n return h.toString(16).padStart(16, '0');\n}\n\nexport interface BigIntKeyWarning {\n /** Node or edge type name. */\n type: string;\n /** The hazardous property. */\n property: string;\n}\n\n/**\n * Find `I64`/`U64` properties used as identity (`@key` or named `id`). The\n * HTTP path emits native JSON numbers even past ±2^53, where `JSON.parse`\n * silently rounds them, so two distinct big-int ids can collapse. Surface\n * these hazards before loading.\n */\nexport function bigIntKeyWarnings(schema: PgSchema): BigIntKeyWarning[] {\n const out: BigIntKeyWarning[] = [];\n for (const t of [...schema.nodes, ...schema.edges]) {\n for (const p of t.properties) {\n if ((p.type === 'I64' || p.type === 'U64') && (p.key || p.name === 'id')) {\n out.push({ type: t.name, property: p.name });\n }\n }\n }\n return out;\n}\n","/**\n * Export-line classification and normalization.\n *\n * `/export` streams NDJSON — one JSON object per line, `data` passed through\n * **verbatim** by the SDK. This module turns those lines into orbit\n * `GraphNode`/`GraphEdge` values:\n *\n * - ids are namespaced through the adapter identity codec (`encodeSourceId`),\n * - the node/edge KIND is injected as {@link ORBIT_TYPE_KEY} — namespaced so\n * a schema's own `type` property passes through as ordinary data,\n * - edge endpoint types are resolved from the `.pg` schema because edge lines\n * carry bare `from`/`to` ids,\n * - attr values are normalized to the query-path string forms so\n * generated types and temporal dimensions see one encoding\n * regardless of read path:\n * * `Date` — export sends **days since Unix epoch** (number) →\n * `'YYYY-MM-DD'` (UTC)\n * * `DateTime` — export sends **epoch milliseconds** (number) →\n * ISO 8601 (`'YYYY-MM-DDTHH:MM:SS.mmmZ'`)\n * * `Blob` — inline internal blobs arrive as `'base64:<data>'` →\n * `'data:application/octet-stream;base64,<data>'`;\n * external-URI refs pass through verbatim\n * * everything else — verbatim.\n *\n * Non-finite float sentinels (`'NaN'`/`'Infinity'`/`'-Infinity'`) are a\n * **query-path-only** encoding: a non-finite stored float aborts `/export`\n * server-side, so export-loaded data never contains the sentinels.\n * This module therefore does NOT special-case them.\n */\n\nimport type { GraphEdge, GraphNode } from '@modernrelay/orbit-core';\nimport { encodeSourceId } from './idCodec';\nimport {\n edgeEndpointTypes,\n type PgEdgeType,\n type PgNodeType,\n type PgProperty,\n type PgSchema,\n type PgType,\n} from './pgSchema';\n\n// ---------------------------------------------------------------------------\n// Errors\n// ---------------------------------------------------------------------------\n\n/** An edge line names an edge type the `.pg` schema does not declare. */\nexport class UnknownEdgeTypeError extends Error {\n override readonly name = 'UnknownEdgeTypeError';\n readonly edgeName: string;\n constructor(edgeName: string) {\n super(\n `Unknown edge type '${edgeName}': not declared in the graph schema, so its ` +\n `endpoint node types cannot be resolved.`,\n );\n this.edgeName = edgeName;\n }\n}\n\n/** An export line is structurally unusable (e.g. missing/non-string `data.id`). */\nexport class InvalidExportLineError extends Error {\n override readonly name = 'InvalidExportLineError';\n constructor(message: string) {\n super(message);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Classification\n// ---------------------------------------------------------------------------\n\nexport interface NodeExportLine {\n kind: 'node';\n type: string;\n data: Record<string, unknown>;\n}\n\nexport interface EdgeExportLine {\n kind: 'edge';\n edge: string;\n from: string;\n to: string;\n data: Record<string, unknown>;\n}\n\nexport type ClassifiedExportLine = NodeExportLine | EdgeExportLine | { kind: 'unknown' };\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n\n/**\n * Classify one parsed export line using the adapter's wire shapes:\n * - node line: `{\"type\": \"<NodeType>\", \"data\": {\"id\", …props}}`\n * - edge line: `{\"edge\": \"<EdgeName>\", \"from\": <src id>, \"to\": <dst id>, \"data\": {\"id\", …props}}`\n * Anything else is `{ kind: 'unknown' }`.\n */\nexport function classifyExportLine(line: unknown): ClassifiedExportLine {\n if (!isRecord(line) || !isRecord(line['data'])) return { kind: 'unknown' };\n const data = line['data'];\n if (\n typeof line['edge'] === 'string' &&\n typeof line['from'] === 'string' &&\n typeof line['to'] === 'string'\n ) {\n return { kind: 'edge', edge: line['edge'], from: line['from'], to: line['to'], data };\n }\n if (typeof line['type'] === 'string') {\n return { kind: 'node', type: line['type'], data };\n }\n return { kind: 'unknown' };\n}\n\n// ---------------------------------------------------------------------------\n// Value normalization\n// ---------------------------------------------------------------------------\n\nconst MS_PER_DAY = 86_400_000;\n\n/** Format an epoch-day count as `'YYYY-MM-DD'` (UTC). Handles negative days. */\nfunction formatEpochDay(days: number): string {\n const d = new Date(days * MS_PER_DAY);\n const t = d.getTime();\n if (!Number.isFinite(t)) return String(days); // out of Date range — leave a readable value\n const y = d.getUTCFullYear();\n const year =\n y < 0\n ? `-${String(-y).padStart(6, '0')}`\n : y > 9999\n ? `+${String(y).padStart(6, '0')}`\n : String(y).padStart(4, '0');\n const month = String(d.getUTCMonth() + 1).padStart(2, '0');\n const day = String(d.getUTCDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n}\n\nfunction normalizeValue(type: PgType | undefined, value: unknown): unknown {\n if (type === undefined || value === null || value === undefined) return value;\n if (type === 'Date' && typeof value === 'number' && Number.isInteger(value)) {\n return formatEpochDay(value);\n }\n if (type === 'DateTime' && typeof value === 'number' && Number.isFinite(value)) {\n const d = new Date(value);\n return Number.isFinite(d.getTime()) ? d.toISOString() : value;\n }\n if (type === 'Blob' && typeof value === 'string' && value.startsWith('base64:')) {\n return `data:application/octet-stream;base64,${value.slice('base64:'.length)}`;\n }\n return value;\n}\n\nfunction propTypeMap(t: PgNodeType | PgEdgeType | undefined): ReadonlyMap<string, PgType> {\n const map = new Map<string, PgType>();\n if (t) for (const p of t.properties as readonly PgProperty[]) map.set(p.name, p.type);\n return map;\n}\n\nfunction normalizeData(\n data: Record<string, unknown>,\n types: ReadonlyMap<string, PgType>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n // Source data can carry '__proto__' as an own key (JSON.parse creates it);\n // defineProperty writes the own property, never the setter.\n for (const [k, v] of Object.entries(data)) {\n Object.defineProperty(out, k, {\n value: normalizeValue(types.get(k), v),\n enumerable: true,\n writable: true,\n configurable: true,\n });\n }\n return out;\n}\n\nfunction requireStringId(data: Record<string, unknown>, what: string): string {\n const id = data['id'];\n if (typeof id !== 'string') {\n throw new InvalidExportLineError(\n `${what} export line has ${id === undefined ? 'no' : 'a non-string'} 'data.id' — ` +\n `cannot build a stable orbit id; data.id must be a string.`,\n );\n }\n return id;\n}\n\n// ---------------------------------------------------------------------------\n// Node / edge normalization\n// ---------------------------------------------------------------------------\n\n/**\n * The adapter's node/edge KIND discriminator key.\n *\n * Namespaced on purpose: the adapter injects this field into someone else's\n * data, so it takes the awkward key and leaves the generic word `type` to the\n * schema author, who means something real by it (`Company.type = investor`).\n * A colon is illegal in `.pg` identifiers, so no schema property can ever\n * claim this key — the collision class is closed by construction, and a\n * source-declared `type` now flows through untouched with no preservation\n * mechanism, no warning, and no schema migration. Same convention as\n * GraphQL's `__typename` / JSON-LD's `@type`.\n */\nexport const ORBIT_TYPE_KEY = 'orbit:type';\n\n/**\n * Normalize a node export line to a `GraphNode`:\n * `id = encodeSourceId(type, data.id)`, `attrs = { …data, 'orbit:type' }`\n * with value normalization driven by the schema's property types. A node type\n * absent from the schema is tolerated — its attrs pass through verbatim\n * (identity never needs the schema on the node path).\n */\nexport function normalizeNode(\n line: { type: string; data: Record<string, unknown> },\n schema: PgSchema,\n): GraphNode {\n const nodeType = schema.nodes.find((n) => n.name === line.type);\n const id = encodeSourceId(line.type, requireStringId(line.data, `Node '${line.type}'`));\n return {\n id,\n // The discriminator is adapter-owned identity metadata. It lands LAST so\n // a forward-compatible export field literally named `orbit:type` cannot\n // forge the value the generated attrs unions promise.\n attrs: { ...normalizeData(line.data, propTypeMap(nodeType)), [ORBIT_TYPE_KEY]: line.type },\n };\n}\n\n/**\n * Normalize an edge export line to a `GraphEdge`:\n * `id = encodeSourceId(edge, data.id)`; `source`/`target` namespace the bare\n * `from`/`to` ids with the endpoint node types resolved from the schema.\n * Throws {@link UnknownEdgeTypeError} when the schema does not declare\n * the edge — endpoint identity cannot be constructed without it.\n */\nexport function normalizeEdge(\n line: { edge: string; from: string; to: string; data: Record<string, unknown> },\n schema: PgSchema,\n): GraphEdge {\n const endpoints = edgeEndpointTypes(schema, line.edge);\n if (endpoints === null) throw new UnknownEdgeTypeError(line.edge);\n const lower = line.edge.toLowerCase();\n const edgeType =\n schema.edges.find((e) => e.name === line.edge) ??\n schema.edges.find((e) => e.name.toLowerCase() === lower);\n const id = encodeSourceId(line.edge, requireStringId(line.data, `Edge '${line.edge}'`));\n return {\n id,\n source: encodeSourceId(endpoints.from, line.from),\n target: encodeSourceId(endpoints.to, line.to),\n // As on nodes, the adapter's resolved edge name lands last and always\n // wins the discriminator key; a source `type` property is ordinary data.\n attrs: { ...normalizeData(line.data, propTypeMap(edgeType)), [ORBIT_TYPE_KEY]: line.edge },\n };\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { parsePgSchema, schemaFingerprint, ORBIT_TYPE_KEY } from './chunk-YDRPXYQ7.js';
2
+ import { parsePgSchema, schemaFingerprint, ORBIT_TYPE_KEY } from './chunk-WMBDYPK2.js';
3
3
  import { readFileSync, writeFileSync } from 'fs';
4
4
  import process from 'process';
5
5
  import { Omnigraph } from '@modernrelay/omnigraph';
@@ -79,6 +79,13 @@ function emitPropsInterface(lines, interfaceName, kindLabel, typeName, propertie
79
79
  lines.push(" id: string;");
80
80
  }
81
81
  for (const prop of properties) {
82
+ if (prop.name === "id") {
83
+ lines.push(
84
+ ` /** Physical Omnigraph id \u2014 normalized as a required string regardless of its schema wire type. */`
85
+ );
86
+ lines.push(" id: string;");
87
+ continue;
88
+ }
82
89
  emitProperty(lines, prop);
83
90
  }
84
91
  lines.push("}");
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/codegen.ts","../src/codegen-cli.ts"],"names":[],"mappings":"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","file":"codegen-cli.js","sourcesContent":["/**\n * `.pg` → TypeScript code generation.\n *\n * The `.pg` scalar set is closed, so typed attrs for the `N`/`E` generics\n * generate mechanically: one interface per node/edge type, a `NodeAttrs` /\n * `EdgeAttrs` discriminated union on the adapter-injected `'orbit:type'`\n * field (namespaced so a schema's own `type` property emits as an ordinary\n * member), and a `TypeMap` lookup interface.\n *\n * Generated shapes describe attrs **after** the adapter's wire normalization\n * (the v1 loader rewrites export-path wire values to the query-path string\n * forms before populating attrs — see `normalize.ts`), so one encoding holds\n * regardless of read path:\n *\n * `Date` → `string` (`'YYYY-MM-DD'`)\n * `DateTime` → `string` (ISO 8601, `'YYYY-MM-DDTHH:MM:SS.mmmZ'`)\n * `enum(...)` → string-literal union\n * `I64`/`U64` → `number` (beware silent rounding past ±2^53)\n * `F32`/`F64` → `number`\n * `Vector(n)` → `number[]`\n * `Blob` → `string` (`data:` URI for inline blobs, stored URI refs verbatim)\n * `T?` → `T | null`\n *\n * Output is a self-contained module (no imports), safe under the strictest\n * tsconfig (`strict`, `exactOptionalPropertyTypes`, `verbatimModuleSyntax`,\n * `isolatedModules`). The file carries a DO-NOT-EDIT header with the\n * schema fingerprint. Generation is deterministic — no timestamps — so the\n * output is committable and diff-stable.\n *\n * Browser-safe: no `node:` imports (the CLI wrapper in `codegen-cli.ts` owns\n * file I/O).\n */\n\nimport { ORBIT_TYPE_KEY } from './normalize';\nimport {\n parsePgSchema,\n schemaFingerprint,\n type PgProperty,\n type PgScalarName,\n type PgSchema,\n type PgType,\n} from './pgSchema';\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface GenerateTypesOptions {\n /**\n * Extra provenance lines for the DO-NOT-EDIT banner (e.g. the schema file\n * path or server URL). May be multi-line; lines are comment-prefixed as\n * needed.\n */\n header?: string;\n /**\n * The schema fingerprint of the `.pg` **source** (from\n * {@link schemaFingerprint}). When omitted, a fingerprint of the canonical\n * parsed model is used instead and labelled as such — prefer\n * {@link generateTypesFromPgSource}, which always stamps the source\n * fingerprint.\n */\n fingerprint?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Wire value → TypeScript mapping (post-normalization)\n// ---------------------------------------------------------------------------\n\nconst SCALAR_TS: Record<PgScalarName, string> = {\n String: 'string',\n Blob: 'string',\n Bool: 'boolean',\n I32: 'number',\n I64: 'number',\n U32: 'number',\n U64: 'number',\n F32: 'number',\n F64: 'number',\n Date: 'string',\n DateTime: 'string',\n};\n\n/** Single-quoted TS string literal with escapes. */\nfunction tsStringLiteral(value: string): string {\n return `'${value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\").replace(/\\r/g, '\\\\r').replace(/\\n/g, '\\\\n')}'`;\n}\n\nfunction tsType(type: PgType): string {\n if (typeof type === 'string') return SCALAR_TS[type];\n switch (type.kind) {\n case 'vector':\n return 'number[]';\n case 'enum':\n return type.values.length === 0 ? 'string' : type.values.map(tsStringLiteral).join(' | ');\n case 'list':\n return `${SCALAR_TS[type.element]}[]`;\n case 'unknown':\n return 'unknown';\n }\n}\n\n/** One-line doc note for types whose TS shape hides a wire subtlety. */\nfunction wireNote(type: PgType): string | null {\n if (typeof type === 'string') {\n switch (type) {\n case 'Date':\n return \"`Date` — normalized to 'YYYY-MM-DD' (UTC) on load.\";\n case 'DateTime':\n return '`DateTime` — normalized to ISO 8601 UTC on load.';\n case 'Blob':\n return \"`Blob` — `data:` URI for inline blobs, stored URI refs verbatim.\";\n case 'I64':\n case 'U64':\n return `\\`${type}\\` — JSON numbers round silently past ±2^53.`;\n default:\n return null;\n }\n }\n switch (type.kind) {\n case 'vector':\n return `\\`Vector(${type.dim})\\`.`;\n case 'unknown':\n return `Unrecognized \\`.pg\\` type \\`${type.raw}\\` — value passes through verbatim.`;\n default:\n return null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Emission helpers\n// ---------------------------------------------------------------------------\n\nconst IDENT_RE = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\n\nfunction propertyKey(name: string): string {\n return IDENT_RE.test(name) ? name : tsStringLiteral(name);\n}\n\nfunction emitProperty(lines: string[], prop: PgProperty): void {\n const note = wireNote(prop.type);\n if (note !== null) lines.push(` /** ${note} */`);\n const base = tsType(prop.type);\n lines.push(` ${propertyKey(prop.name)}: ${prop.optional ? `${base} | null` : base};`);\n}\n\nfunction emitPropsInterface(\n lines: string[],\n interfaceName: string,\n kindLabel: 'node' | 'edge',\n typeName: string,\n properties: readonly PgProperty[],\n): void {\n lines.push(`/** Normalized attrs for ${kindLabel} type \\`${typeName}\\`. */`);\n lines.push(`export interface ${interfaceName} {`);\n if (!properties.some((p) => p.name === 'id')) {\n lines.push(\n ` /** Physical Omnigraph id — injected into every export line's \\`data\\`; unique per ${kindLabel} type only. */`,\n );\n lines.push(' id: string;');\n }\n for (const prop of properties) {\n // Every schema property emits normally — including one named `type`: the\n // adapter's discriminator lives at the namespaced ORBIT_TYPE_KEY, so\n // there is nothing to shadow.\n emitProperty(lines, prop);\n }\n lines.push('}');\n lines.push('');\n}\n\nfunction emitAttrsUnion(\n lines: string[],\n unionName: string,\n doc: string,\n members: ReadonlyArray<{ typeName: string; interfaceName: string }>,\n): void {\n lines.push(`/** ${doc} */`);\n if (members.length === 0) {\n lines.push(`export type ${unionName} = never;`);\n } else {\n lines.push(`export type ${unionName} =`);\n members.forEach(({ typeName, interfaceName }, i) => {\n const tail = i === members.length - 1 ? ';' : '';\n lines.push(\n ` | ({ ${tsStringLiteral(ORBIT_TYPE_KEY)}: ${tsStringLiteral(typeName)} } & ${interfaceName})${tail}`,\n );\n });\n }\n lines.push('');\n}\n\nfunction headerBanner(fingerprintLine: string, extra: string | undefined): string[] {\n const lines = [\n '// AUTO-GENERATED — DO NOT EDIT.',\n '//',\n '// .pg → TypeScript typed attrs (wire-normalized), generated by',\n '// @modernrelay/orbit-omnigraph (`orbit-omnigraph-codegen`).',\n `// ${fingerprintLine}`,\n ];\n if (extra !== undefined && extra.length > 0) {\n for (const raw of extra.split('\\n')) {\n lines.push(raw.startsWith('//') ? raw : `// ${raw}`.trimEnd());\n }\n }\n lines.push(\n '//',\n \"// Shapes describe attrs AFTER the adapter's wire normalization (both read\",\n '// paths converge on the query-path string encodings):',\n \"// Date → 'YYYY-MM-DD' · DateTime → ISO 8601 · enum(...) → literal union\",\n '// I64/U64/F32/F64 → number · Vector(n) → number[] · T? → T | null',\n \"// Blob → string ('data:' URI for inline blobs, stored URI for external)\",\n '',\n );\n return lines;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Generate a self-contained TypeScript module of typed attrs from a parsed\n * `.pg` schema: one `<Name>Props` interface per node type, one\n * `<Name>EdgeProps` per edge type (suffixed so a node and an edge sharing a\n * name cannot collide), `NodeAttrs`/`EdgeAttrs` discriminated unions on the\n * adapter-injected `'orbit:type'` field, and a `TypeMap` lookup interface with\n * `NodeTypeName`/`EdgeTypeName` key unions.\n *\n * Deterministic: identical input (schema + options) yields identical output.\n */\nexport function generateTypes(schema: PgSchema, opts?: GenerateTypesOptions): string {\n const fingerprintLine =\n opts?.fingerprint !== undefined\n ? `Schema fingerprint: ${opts.fingerprint}.`\n : `Schema fingerprint: ${schemaFingerprint(JSON.stringify(schema))} (parsed model — regenerate from .pg source for the source fingerprint).`;\n const lines = headerBanner(fingerprintLine, opts?.header);\n\n const nodeMembers = schema.nodes.map((n) => ({\n typeName: n.name,\n interfaceName: `${n.name}Props`,\n }));\n const edgeMembers = schema.edges.map((e) => ({\n typeName: e.name,\n interfaceName: `${e.name}EdgeProps`,\n }));\n\n schema.nodes.forEach((n, i) => {\n const member = nodeMembers[i];\n if (member) emitPropsInterface(lines, member.interfaceName, 'node', n.name, n.properties);\n });\n schema.edges.forEach((e, i) => {\n const member = edgeMembers[i];\n if (member) emitPropsInterface(lines, member.interfaceName, 'edge', e.name, e.properties);\n });\n\n emitAttrsUnion(\n lines,\n 'NodeAttrs',\n \"Discriminated union over every node type's normalized attrs — `'orbit:type'` is injected by the adapter.\",\n nodeMembers,\n );\n emitAttrsUnion(\n lines,\n 'EdgeAttrs',\n \"Discriminated union over every edge type's normalized attrs — `'orbit:type'` is the edge name.\",\n edgeMembers,\n );\n\n lines.push('/** Type-name → props lookup for both kinds (closed sets from the schema — the wire contract). */');\n lines.push('export interface TypeMap {');\n lines.push(' nodes: {');\n for (const m of nodeMembers) lines.push(` ${propertyKey(m.typeName)}: ${m.interfaceName};`);\n lines.push(' };');\n lines.push(' edges: {');\n for (const m of edgeMembers) lines.push(` ${propertyKey(m.typeName)}: ${m.interfaceName};`);\n lines.push(' };');\n lines.push('}');\n lines.push('');\n lines.push(\"export type NodeTypeName = keyof TypeMap['nodes'];\");\n lines.push(\"export type EdgeTypeName = keyof TypeMap['edges'];\");\n lines.push('');\n return lines.join('\\n');\n}\n\n/**\n * Parse `.pg` source and generate typed attrs (see {@link generateTypes}),\n * stamping the header with the source fingerprint\n * ({@link schemaFingerprint} over the verbatim source).\n */\nexport function generateTypesFromPgSource(\n source: string,\n opts?: Omit<GenerateTypesOptions, 'fingerprint'>,\n): string {\n const schema = parsePgSchema(source);\n const options: GenerateTypesOptions = { fingerprint: schemaFingerprint(source) };\n if (opts?.header !== undefined) options.header = opts.header;\n return generateTypes(schema, options);\n}\n","#!/usr/bin/env node\n/**\n * `orbit-omnigraph-codegen` — minimal `.pg` → TypeScript codegen CLI.\n *\n * orbit-omnigraph-codegen <schema.pg> [-o out.ts]\n * orbit-omnigraph-codegen --from-server <baseUrl> --graph <id> [-o out.ts]\n *\n * The first form reads a `.pg` file; the second fetches the active schema\n * from a running omnigraph-server via a plain **unauthenticated** SDK client\n * (`og.schema.get()` returns the raw `.pg` source). Authenticated client\n * construction stays exclusively in the `/server` entry; point\n * this tool at an `--unauthenticated` server or a same-origin proxy.\n *\n * Without `-o`, the generated module goes to stdout.\n */\n\nimport { readFileSync, writeFileSync } from 'node:fs';\nimport process from 'node:process';\nimport { Omnigraph } from '@modernrelay/omnigraph';\nimport { generateTypesFromPgSource } from './codegen';\n\nconst USAGE = `Usage:\n orbit-omnigraph-codegen <schema.pg> [-o <out.ts>]\n orbit-omnigraph-codegen --from-server <baseUrl> --graph <id> [-o <out.ts>]\n\nGenerates TypeScript typed attrs from a .pg schema — read from a\nfile, or fetched from a running omnigraph-server (unauthenticated client).\nWrites to stdout unless -o is given.\n`;\n\ninterface CliArgs {\n schemaPath?: string;\n out?: string;\n fromServer?: string;\n graph?: string;\n}\n\nfunction parseArgs(argv: readonly string[]): CliArgs | string {\n const args: CliArgs = {};\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (arg === undefined) continue;\n switch (arg) {\n case '-h':\n case '--help':\n return 'help';\n case '-o':\n case '--out': {\n const v = argv[++i];\n if (v === undefined) return `missing value for ${arg}`;\n args.out = v;\n break;\n }\n case '--from-server': {\n const v = argv[++i];\n if (v === undefined) return 'missing value for --from-server';\n args.fromServer = v;\n break;\n }\n case '--graph': {\n const v = argv[++i];\n if (v === undefined) return 'missing value for --graph';\n args.graph = v;\n break;\n }\n default:\n if (arg.startsWith('-')) return `unknown option '${arg}'`;\n if (args.schemaPath !== undefined) return `unexpected argument '${arg}'`;\n args.schemaPath = arg;\n }\n }\n if (args.fromServer !== undefined && args.schemaPath !== undefined) {\n return 'pass a schema file OR --from-server, not both';\n }\n if (args.fromServer !== undefined && args.graph === undefined) {\n return '--from-server requires --graph <id> (schema reads are graph-scoped)';\n }\n if (args.fromServer === undefined && args.schemaPath === undefined) {\n return 'no schema given';\n }\n return args;\n}\n\nasync function main(argv: readonly string[]): Promise<number> {\n const parsed = parseArgs(argv);\n if (parsed === 'help') {\n process.stdout.write(USAGE);\n return 0;\n }\n if (typeof parsed === 'string') {\n process.stderr.write(`orbit-omnigraph-codegen: ${parsed}\\n\\n${USAGE}`);\n return 2;\n }\n\n let source: string;\n let provenance: string;\n if (parsed.fromServer !== undefined && parsed.graph !== undefined) {\n const og = new Omnigraph({ baseUrl: parsed.fromServer, graphId: parsed.graph });\n const schema = await og.schema.get();\n source = schema.schemaSource;\n provenance = `Source: ${parsed.fromServer} (graph '${parsed.graph}', GET /schema)`;\n } else if (parsed.schemaPath !== undefined) {\n source = readFileSync(parsed.schemaPath, 'utf8');\n provenance = `Source: ${parsed.schemaPath}`;\n } else {\n // Unreachable: parseArgs guarantees one of the two.\n return 2;\n }\n\n const output = generateTypesFromPgSource(source, { header: provenance });\n if (parsed.out !== undefined) {\n writeFileSync(parsed.out, output);\n process.stderr.write(`orbit-omnigraph-codegen: wrote ${parsed.out}\\n`);\n } else {\n process.stdout.write(output);\n }\n return 0;\n}\n\nmain(process.argv.slice(2)).then(\n (code) => {\n process.exitCode = code;\n },\n (err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n process.stderr.write(`orbit-omnigraph-codegen: ${message}\\n`);\n process.exitCode = 1;\n },\n);\n"]}
1
+ {"version":3,"sources":["../src/codegen.ts","../src/codegen-cli.ts"],"names":[],"mappings":"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","file":"codegen-cli.js","sourcesContent":["/**\n * `.pg` → TypeScript code generation.\n *\n * The `.pg` scalar set is closed, so typed attrs for the `N`/`E` generics\n * generate mechanically: one interface per node/edge type, a `NodeAttrs` /\n * `EdgeAttrs` discriminated union on the adapter-injected `'orbit:type'`\n * field (namespaced so a schema's own `type` property emits as an ordinary\n * member), and a `TypeMap` lookup interface.\n *\n * Generated shapes describe attrs **after** the adapter's wire normalization\n * (the v1 loader rewrites export-path wire values to the query-path string\n * forms before populating attrs — see `normalize.ts`), so one encoding holds\n * regardless of read path:\n *\n * `Date` → `string` (`'YYYY-MM-DD'`)\n * `DateTime` → `string` (ISO 8601, `'YYYY-MM-DDTHH:MM:SS.mmmZ'`)\n * `enum(...)` → string-literal union\n * `I64`/`U64` → `number` (beware silent rounding past ±2^53)\n * `F32`/`F64` → `number`\n * `Vector(n)` → `number[]`\n * `Blob` → `string` (`data:` URI for inline blobs, stored URI refs verbatim)\n * `T?` → `T | null`\n *\n * Output is a self-contained module (no imports), safe under the strictest\n * tsconfig (`strict`, `exactOptionalPropertyTypes`, `verbatimModuleSyntax`,\n * `isolatedModules`). The file carries a DO-NOT-EDIT header with the\n * schema fingerprint. Generation is deterministic — no timestamps — so the\n * output is committable and diff-stable.\n *\n * Browser-safe: no `node:` imports (the CLI wrapper in `codegen-cli.ts` owns\n * file I/O).\n */\n\nimport { ORBIT_TYPE_KEY } from './normalize';\nimport {\n parsePgSchema,\n schemaFingerprint,\n type PgProperty,\n type PgScalarName,\n type PgSchema,\n type PgType,\n} from './pgSchema';\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface GenerateTypesOptions {\n /**\n * Extra provenance lines for the DO-NOT-EDIT banner (e.g. the schema file\n * path or server URL). May be multi-line; lines are comment-prefixed as\n * needed.\n */\n header?: string;\n /**\n * The schema fingerprint of the `.pg` **source** (from\n * {@link schemaFingerprint}). When omitted, a fingerprint of the canonical\n * parsed model is used instead and labelled as such — prefer\n * {@link generateTypesFromPgSource}, which always stamps the source\n * fingerprint.\n */\n fingerprint?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Wire value → TypeScript mapping (post-normalization)\n// ---------------------------------------------------------------------------\n\nconst SCALAR_TS: Record<PgScalarName, string> = {\n String: 'string',\n Blob: 'string',\n Bool: 'boolean',\n I32: 'number',\n I64: 'number',\n U32: 'number',\n U64: 'number',\n F32: 'number',\n F64: 'number',\n Date: 'string',\n DateTime: 'string',\n};\n\n/** Single-quoted TS string literal with escapes. */\nfunction tsStringLiteral(value: string): string {\n return `'${value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\").replace(/\\r/g, '\\\\r').replace(/\\n/g, '\\\\n')}'`;\n}\n\nfunction tsType(type: PgType): string {\n if (typeof type === 'string') return SCALAR_TS[type];\n switch (type.kind) {\n case 'vector':\n return 'number[]';\n case 'enum':\n return type.values.length === 0 ? 'string' : type.values.map(tsStringLiteral).join(' | ');\n case 'list':\n return `${SCALAR_TS[type.element]}[]`;\n case 'unknown':\n return 'unknown';\n }\n}\n\n/** One-line doc note for types whose TS shape hides a wire subtlety. */\nfunction wireNote(type: PgType): string | null {\n if (typeof type === 'string') {\n switch (type) {\n case 'Date':\n return \"`Date` — normalized to 'YYYY-MM-DD' (UTC) on load.\";\n case 'DateTime':\n return '`DateTime` — normalized to ISO 8601 UTC on load.';\n case 'Blob':\n return \"`Blob` — `data:` URI for inline blobs, stored URI refs verbatim.\";\n case 'I64':\n case 'U64':\n return `\\`${type}\\` — JSON numbers round silently past ±2^53.`;\n default:\n return null;\n }\n }\n switch (type.kind) {\n case 'vector':\n return `\\`Vector(${type.dim})\\`.`;\n case 'unknown':\n return `Unrecognized \\`.pg\\` type \\`${type.raw}\\` — value passes through verbatim.`;\n default:\n return null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Emission helpers\n// ---------------------------------------------------------------------------\n\nconst IDENT_RE = /^[A-Za-z_$][A-Za-z0-9_$]*$/;\n\nfunction propertyKey(name: string): string {\n return IDENT_RE.test(name) ? name : tsStringLiteral(name);\n}\n\nfunction emitProperty(lines: string[], prop: PgProperty): void {\n const note = wireNote(prop.type);\n if (note !== null) lines.push(` /** ${note} */`);\n const base = tsType(prop.type);\n lines.push(` ${propertyKey(prop.name)}: ${prop.optional ? `${base} | null` : base};`);\n}\n\nfunction emitPropsInterface(\n lines: string[],\n interfaceName: string,\n kindLabel: 'node' | 'edge',\n typeName: string,\n properties: readonly PgProperty[],\n): void {\n lines.push(`/** Normalized attrs for ${kindLabel} type \\`${typeName}\\`. */`);\n lines.push(`export interface ${interfaceName} {`);\n if (!properties.some((p) => p.name === 'id')) {\n lines.push(\n ` /** Physical Omnigraph id — injected into every export line's \\`data\\`; unique per ${kindLabel} type only. */`,\n );\n lines.push(' id: string;');\n }\n for (const prop of properties) {\n if (prop.name === 'id') {\n // Export normalization requires `data.id` to be a string regardless of\n // a schema declaration. Emitting the declared wire scalar here (for\n // example I64 -> number) would make generated attrs unsound.\n lines.push(\n ` /** Physical Omnigraph id — normalized as a required string regardless of its schema wire type. */`,\n );\n lines.push(' id: string;');\n continue;\n }\n // Every schema property emits normally — including one named `type`: the\n // adapter's discriminator lives at the namespaced ORBIT_TYPE_KEY, so\n // there is nothing to shadow.\n emitProperty(lines, prop);\n }\n lines.push('}');\n lines.push('');\n}\n\nfunction emitAttrsUnion(\n lines: string[],\n unionName: string,\n doc: string,\n members: ReadonlyArray<{ typeName: string; interfaceName: string }>,\n): void {\n lines.push(`/** ${doc} */`);\n if (members.length === 0) {\n lines.push(`export type ${unionName} = never;`);\n } else {\n lines.push(`export type ${unionName} =`);\n members.forEach(({ typeName, interfaceName }, i) => {\n const tail = i === members.length - 1 ? ';' : '';\n lines.push(\n ` | ({ ${tsStringLiteral(ORBIT_TYPE_KEY)}: ${tsStringLiteral(typeName)} } & ${interfaceName})${tail}`,\n );\n });\n }\n lines.push('');\n}\n\nfunction headerBanner(fingerprintLine: string, extra: string | undefined): string[] {\n const lines = [\n '// AUTO-GENERATED — DO NOT EDIT.',\n '//',\n '// .pg → TypeScript typed attrs (wire-normalized), generated by',\n '// @modernrelay/orbit-omnigraph (`orbit-omnigraph-codegen`).',\n `// ${fingerprintLine}`,\n ];\n if (extra !== undefined && extra.length > 0) {\n for (const raw of extra.split('\\n')) {\n lines.push(raw.startsWith('//') ? raw : `// ${raw}`.trimEnd());\n }\n }\n lines.push(\n '//',\n \"// Shapes describe attrs AFTER the adapter's wire normalization (both read\",\n '// paths converge on the query-path string encodings):',\n \"// Date → 'YYYY-MM-DD' · DateTime → ISO 8601 · enum(...) → literal union\",\n '// I64/U64/F32/F64 → number · Vector(n) → number[] · T? → T | null',\n \"// Blob → string ('data:' URI for inline blobs, stored URI for external)\",\n '',\n );\n return lines;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Generate a self-contained TypeScript module of typed attrs from a parsed\n * `.pg` schema: one `<Name>Props` interface per node type, one\n * `<Name>EdgeProps` per edge type (suffixed so a node and an edge sharing a\n * name cannot collide), `NodeAttrs`/`EdgeAttrs` discriminated unions on the\n * adapter-injected `'orbit:type'` field, and a `TypeMap` lookup interface with\n * `NodeTypeName`/`EdgeTypeName` key unions.\n *\n * Deterministic: identical input (schema + options) yields identical output.\n */\nexport function generateTypes(schema: PgSchema, opts?: GenerateTypesOptions): string {\n const fingerprintLine =\n opts?.fingerprint !== undefined\n ? `Schema fingerprint: ${opts.fingerprint}.`\n : `Schema fingerprint: ${schemaFingerprint(JSON.stringify(schema))} (parsed model — regenerate from .pg source for the source fingerprint).`;\n const lines = headerBanner(fingerprintLine, opts?.header);\n\n const nodeMembers = schema.nodes.map((n) => ({\n typeName: n.name,\n interfaceName: `${n.name}Props`,\n }));\n const edgeMembers = schema.edges.map((e) => ({\n typeName: e.name,\n interfaceName: `${e.name}EdgeProps`,\n }));\n\n schema.nodes.forEach((n, i) => {\n const member = nodeMembers[i];\n if (member) emitPropsInterface(lines, member.interfaceName, 'node', n.name, n.properties);\n });\n schema.edges.forEach((e, i) => {\n const member = edgeMembers[i];\n if (member) emitPropsInterface(lines, member.interfaceName, 'edge', e.name, e.properties);\n });\n\n emitAttrsUnion(\n lines,\n 'NodeAttrs',\n \"Discriminated union over every node type's normalized attrs — `'orbit:type'` is injected by the adapter.\",\n nodeMembers,\n );\n emitAttrsUnion(\n lines,\n 'EdgeAttrs',\n \"Discriminated union over every edge type's normalized attrs — `'orbit:type'` is the edge name.\",\n edgeMembers,\n );\n\n lines.push('/** Type-name → props lookup for both kinds (closed sets from the schema — the wire contract). */');\n lines.push('export interface TypeMap {');\n lines.push(' nodes: {');\n for (const m of nodeMembers) lines.push(` ${propertyKey(m.typeName)}: ${m.interfaceName};`);\n lines.push(' };');\n lines.push(' edges: {');\n for (const m of edgeMembers) lines.push(` ${propertyKey(m.typeName)}: ${m.interfaceName};`);\n lines.push(' };');\n lines.push('}');\n lines.push('');\n lines.push(\"export type NodeTypeName = keyof TypeMap['nodes'];\");\n lines.push(\"export type EdgeTypeName = keyof TypeMap['edges'];\");\n lines.push('');\n return lines.join('\\n');\n}\n\n/**\n * Parse `.pg` source and generate typed attrs (see {@link generateTypes}),\n * stamping the header with the source fingerprint\n * ({@link schemaFingerprint} over the verbatim source).\n */\nexport function generateTypesFromPgSource(\n source: string,\n opts?: Omit<GenerateTypesOptions, 'fingerprint'>,\n): string {\n const schema = parsePgSchema(source);\n const options: GenerateTypesOptions = { fingerprint: schemaFingerprint(source) };\n if (opts?.header !== undefined) options.header = opts.header;\n return generateTypes(schema, options);\n}\n","#!/usr/bin/env node\n/**\n * `orbit-omnigraph-codegen` — minimal `.pg` → TypeScript codegen CLI.\n *\n * orbit-omnigraph-codegen <schema.pg> [-o out.ts]\n * orbit-omnigraph-codegen --from-server <baseUrl> --graph <id> [-o out.ts]\n *\n * The first form reads a `.pg` file; the second fetches the active schema\n * from a running omnigraph-server via a plain **unauthenticated** SDK client\n * (`og.schema.get()` returns the raw `.pg` source). Authenticated client\n * construction stays exclusively in the `/server` entry; point\n * this tool at an `--unauthenticated` server or a same-origin proxy.\n *\n * Without `-o`, the generated module goes to stdout.\n */\n\nimport { readFileSync, writeFileSync } from 'node:fs';\nimport process from 'node:process';\nimport { Omnigraph } from '@modernrelay/omnigraph';\nimport { generateTypesFromPgSource } from './codegen';\n\nconst USAGE = `Usage:\n orbit-omnigraph-codegen <schema.pg> [-o <out.ts>]\n orbit-omnigraph-codegen --from-server <baseUrl> --graph <id> [-o <out.ts>]\n\nGenerates TypeScript typed attrs from a .pg schema — read from a\nfile, or fetched from a running omnigraph-server (unauthenticated client).\nWrites to stdout unless -o is given.\n`;\n\ninterface CliArgs {\n schemaPath?: string;\n out?: string;\n fromServer?: string;\n graph?: string;\n}\n\nfunction parseArgs(argv: readonly string[]): CliArgs | string {\n const args: CliArgs = {};\n for (let i = 0; i < argv.length; i++) {\n const arg = argv[i];\n if (arg === undefined) continue;\n switch (arg) {\n case '-h':\n case '--help':\n return 'help';\n case '-o':\n case '--out': {\n const v = argv[++i];\n if (v === undefined) return `missing value for ${arg}`;\n args.out = v;\n break;\n }\n case '--from-server': {\n const v = argv[++i];\n if (v === undefined) return 'missing value for --from-server';\n args.fromServer = v;\n break;\n }\n case '--graph': {\n const v = argv[++i];\n if (v === undefined) return 'missing value for --graph';\n args.graph = v;\n break;\n }\n default:\n if (arg.startsWith('-')) return `unknown option '${arg}'`;\n if (args.schemaPath !== undefined) return `unexpected argument '${arg}'`;\n args.schemaPath = arg;\n }\n }\n if (args.fromServer !== undefined && args.schemaPath !== undefined) {\n return 'pass a schema file OR --from-server, not both';\n }\n if (args.fromServer !== undefined && args.graph === undefined) {\n return '--from-server requires --graph <id> (schema reads are graph-scoped)';\n }\n if (args.fromServer === undefined && args.schemaPath === undefined) {\n return 'no schema given';\n }\n return args;\n}\n\nasync function main(argv: readonly string[]): Promise<number> {\n const parsed = parseArgs(argv);\n if (parsed === 'help') {\n process.stdout.write(USAGE);\n return 0;\n }\n if (typeof parsed === 'string') {\n process.stderr.write(`orbit-omnigraph-codegen: ${parsed}\\n\\n${USAGE}`);\n return 2;\n }\n\n let source: string;\n let provenance: string;\n if (parsed.fromServer !== undefined && parsed.graph !== undefined) {\n const og = new Omnigraph({ baseUrl: parsed.fromServer, graphId: parsed.graph });\n const schema = await og.schema.get();\n source = schema.schemaSource;\n provenance = `Source: ${parsed.fromServer} (graph '${parsed.graph}', GET /schema)`;\n } else if (parsed.schemaPath !== undefined) {\n source = readFileSync(parsed.schemaPath, 'utf8');\n provenance = `Source: ${parsed.schemaPath}`;\n } else {\n // Unreachable: parseArgs guarantees one of the two.\n return 2;\n }\n\n const output = generateTypesFromPgSource(source, { header: provenance });\n if (parsed.out !== undefined) {\n writeFileSync(parsed.out, output);\n process.stderr.write(`orbit-omnigraph-codegen: wrote ${parsed.out}\\n`);\n } else {\n process.stdout.write(output);\n }\n return 0;\n}\n\nmain(process.argv.slice(2)).then(\n (code) => {\n process.exitCode = code;\n },\n (err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n process.stderr.write(`orbit-omnigraph-codegen: ${message}\\n`);\n process.exitCode = 1;\n },\n);\n"]}
package/dist/index.d.ts CHANGED
@@ -324,7 +324,7 @@ interface OmnigraphSourceOptions {
324
324
  * field (wire form `type_names`). Omit to export every table.
325
325
  */
326
326
  typeNames?: readonly string[];
327
- /** Export lines per `IngestBatch` append. Default 2000. */
327
+ /** Export lines per `IngestBatch` append. Must be a positive safe integer. Default 2000. */
328
328
  batchSize?: number;
329
329
  /**
330
330
  * Whole-load byte budget for the atomic replace. Because atomic staging
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { encodeSourceId, parsePgSchema, schemaFingerprint, bigIntKeyWarnings, classifyExportLine, normalizeNode, normalizeEdge } from './chunk-YDRPXYQ7.js';
2
- export { InvalidExportLineError, ORBIT_TYPE_KEY, UnknownEdgeTypeError, bigIntKeyWarnings, classifyExportLine, decodeSourceId, edgeEndpointTypes, encodeSourceId, encodeSyntheticEdgeId, normalizeEdge, normalizeNode, parsePgSchema, schemaFingerprint } from './chunk-YDRPXYQ7.js';
1
+ import { encodeSourceId, parsePgSchema, schemaFingerprint, bigIntKeyWarnings, classifyExportLine, normalizeNode, normalizeEdge } from './chunk-WMBDYPK2.js';
2
+ export { InvalidExportLineError, ORBIT_TYPE_KEY, UnknownEdgeTypeError, bigIntKeyWarnings, classifyExportLine, decodeSourceId, edgeEndpointTypes, encodeSourceId, encodeSyntheticEdgeId, normalizeEdge, normalizeNode, parsePgSchema, schemaFingerprint } from './chunk-WMBDYPK2.js';
3
3
  import { SERVER_VERSION, OmnigraphError } from '@modernrelay/omnigraph';
4
4
  import { OrbitOperationError } from '@modernrelay/orbit-core';
5
5
 
@@ -69,8 +69,11 @@ function pushUnique(warnings, warning) {
69
69
  function createOmnigraphSource(options) {
70
70
  const graphId = options.graphId;
71
71
  const branch = options.branch ?? "main";
72
- const batchSize = Math.max(1, Math.floor(options.batchSize ?? DEFAULT_BATCH_SIZE));
73
- const maxPendingBytes = options.maxPendingBytes ?? DEFAULT_MAX_PENDING_BYTES;
72
+ const batchSize = options.batchSize === void 0 ? DEFAULT_BATCH_SIZE : options.batchSize;
73
+ if (!Number.isSafeInteger(batchSize) || batchSize <= 0) {
74
+ throw new TypeError("createOmnigraphSource: batchSize must be a positive safe integer");
75
+ }
76
+ const maxPendingBytes = options.maxPendingBytes === void 0 ? DEFAULT_MAX_PENDING_BYTES : options.maxPendingBytes;
74
77
  if (!Number.isSafeInteger(maxPendingBytes) || maxPendingBytes <= 0) {
75
78
  throw new TypeError(
76
79
  "createOmnigraphSource: maxPendingBytes must be a positive safe integer"
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/loader.ts","../src/searchService.ts"],"names":["activeSession","throwIfAborted","isAbortError","mapError","OmnigraphError"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * v1 export loader.\n *\n * The organizing rule: graphs load via `og.export` — one streamed\n * NDJSON pass, edge lines first (lexicographic table-key order), driven\n * straight into a `purpose:'replace'` ingest session on the target. Queries\n * never introduce nodes or edges.\n *\n * Revision stamp: the canonical `sourceRevision` hashes\n * `{ graphId, branch, headBefore, headAfter, schemaFingerprint }` (plus the\n * sorted `typeNames` subset when the export is partial), but\n * `headAfter` is only knowable after the stream — while core's\n * `BeginIngestOptions` requires `sourceRevision` up front for a replace\n * session. Resolution: under the rejecting/retrying policies the session\n * begins under the PROVISIONAL revision (the canonical hash with\n * `headAfter:= headBefore`), the stream appends into it, and `headAfter` is\n * captured BEFORE `commit`. `accept-warn` is the exception: normalized\n * batches are buffered until `headAfter` is known, then appended once into a\n * session opened with the canonical FINAL revision:\n *\n * - equal heads → provisional === final; commit cleanly. The session only\n * ever commits a revision whose hash is truthful.\n * - drifted heads → `driftPolicy` decides: `'reject'` aborts the session\n * (graph untouched) and throws {@link OmnigraphDriftError};\n * `'accept-warn'` commits the buffered export under the\n * final revision, records BOTH heads in `dataRef`, and\n * adds a warning;\n * `'retry-once'` aborts and restarts the whole load once\n * (a second drift rejects).\n *\n * This is sound because a replace session is atomic and invisible until\n * commit: nothing is published under a revision the policy did not\n * explicitly accept.\n *\n * Error surface: SDK typed errors never cross this package's public\n * surface — they are mapped to plain `Error`s with a stable `omnigraph:`\n * message prefix.\n */\n\nimport { OmnigraphError, SERVER_VERSION } from '@modernrelay/omnigraph';\nimport type { CallOptions, ExportInput, Omnigraph } from '@modernrelay/omnigraph';\nimport { OrbitOperationError } from '@modernrelay/orbit-core';\nimport type { GraphEdge, GraphNode, IngestBatch, IngestSession } from '@modernrelay/orbit-core';\n\nimport { classifyExportLine, normalizeEdge, normalizeNode } from './normalize';\nimport { bigIntKeyWarnings, parsePgSchema, schemaFingerprint } from './pgSchema';\nimport type { PgSchema } from './pgSchema';\nimport type {\n IngestTarget,\n OmnigraphDataRef,\n OmnigraphLoadResult,\n OmnigraphSourceOptions,\n} from './types';\n\nconst DEFAULT_BATCH_SIZE = 2000;\n\n/**\n * Finite whole-export cap for the necessarily atomic replace session. A\n * whole-graph load stages EVERY row before commit, so this is a total-load\n * memory bound, not a backpressure window — real graphs routinely exceed\n * 100 MB of serialized rows (the intel fixture streams ~128 MB), so the\n * default is deliberately generous; callers with tighter memory budgets pass\n * `maxPendingBytes` explicitly.\n */\nconst DEFAULT_MAX_PENDING_BYTES = 512 * 1024 * 1024;\n\n/** Stateless and safe to reuse; counts serialized UTF-8 rather than UTF-16 code units. */\nconst UTF8_ENCODER = new TextEncoder();\n\n/**\n * Raised when a branch moves during export and the configured drift policy\n * rejects the load. The session is aborted and the target graph is untouched.\n */\nexport class OmnigraphDriftError extends Error {\n override readonly name = 'OmnigraphDriftError';\n readonly graphId: string;\n readonly branch: string;\n readonly headBefore: string;\n readonly headAfter: string;\n constructor(graphId: string, branch: string, headBefore: string, headAfter: string) {\n super(\n `omnigraph: branch '${branch}' of graph '${graphId}' changed during export ` +\n `(head ${headBefore} → ${headAfter}); session aborted per driftPolicy (` +\n `service:omnigraph-source-changed-during-export)`,\n );\n this.graphId = graphId;\n this.branch = branch;\n this.headBefore = headBefore;\n this.headAfter = headAfter;\n }\n}\n\n/** The one load path a v1 source exposes. */\nexport interface OmnigraphSource {\n /**\n * Stream one export of the configured graph/branch into `target` via a\n * `purpose:'replace'` ingest session. Resolves with the revision-stamped\n * result; rejects with the session aborted and the target untouched.\n * `signal` aborts both the HTTP stream and the session.\n */\n load(target: IngestTarget, signal?: AbortSignal): Promise<OmnigraphLoadResult>;\n}\n\n// ---------------------------------------------------------------------------\n// Small pure helpers\n// ---------------------------------------------------------------------------\n\n/** FNV-1a 64-bit over the UTF-8 bytes of `s`, as 16 lowercase hex chars. */\nfunction hash64(s: string): string {\n const MASK64 = 0xffffffffffffffffn;\n let h = 0xcbf29ce484222325n;\n for (const b of new TextEncoder().encode(s)) {\n h ^= BigInt(b);\n h = (h * 0x100000001b3n) & MASK64;\n }\n return h.toString(16).padStart(16, '0');\n}\n\n/**\n * The canonical adapter source revision: a hash of the readable `dataRef` object\n * `{ graphId, branch, headBefore, headAfter, schemaFingerprint, typeNames? }`\n * (`dataRef` itself retains the readable form).\n */\nfunction canonicalSourceRevision(ref: OmnigraphDataRef): string {\n // typeNames joins the tuple ONLY when present, so full-export\n // hashes stay byte-identical to every previously persisted revision.\n const tuple: unknown[] = [\n ref.graphId,\n ref.branch,\n ref.headBefore,\n ref.headAfter,\n ref.schemaFingerprint,\n ];\n if (ref.typeNames !== undefined) tuple.push(ref.typeNames);\n return `og:${hash64(JSON.stringify(tuple))}`;\n}\n\n/** `'0.8.1'` → `'0.8'`; null when unparseable. */\nfunction majorMinor(version: string): string | null {\n const m = /^(\\d+)\\.(\\d+)/.exec(version);\n return m ? `${m[1]}.${m[2]}` : null;\n}\n\n/** CallOptions without an explicit-undefined signal (exactOptionalPropertyTypes). */\nfunction callOpts(signal: AbortSignal | undefined): CallOptions {\n return signal ? { signal } : {};\n}\n\nfunction throwIfAborted(signal: AbortSignal | undefined): void {\n if (signal?.aborted) {\n throw new DOMException('omnigraph: load aborted by caller signal', 'AbortError');\n }\n}\n\nfunction isAbortError(err: unknown): boolean {\n return err instanceof Error && err.name === 'AbortError';\n}\n\n/**\n * SDK typed errors (`NetworkError`, `ConflictError`, …) never leak across the\n * public surface; they rethrow as plain `Error`s with a stable prefix.\n * Abort rejections and this package's own errors pass through unchanged.\n */\nfunction mapError(err: unknown): unknown {\n if (err instanceof OmnigraphError && !isAbortError(err)) {\n return new Error(`omnigraph: ${err.name} (status ${err.status}): ${err.message}`);\n }\n return err;\n}\n\nfunction pushUnique(warnings: string[], warning: string): void {\n if (!warnings.includes(warning)) warnings.push(warning);\n}\n\n// ---------------------------------------------------------------------------\n// createOmnigraphSource\n// ---------------------------------------------------------------------------\n\ninterface AttemptSuccess {\n kind: 'done';\n sourceRevision: string;\n dataRef: OmnigraphDataRef;\n counts: { lines: number; nodes: number; edges: number; bytes: number };\n}\n\ninterface AttemptRetry {\n kind: 'retry';\n}\n\n/**\n * Create a v1 export-backed data source. The client must be\n * preconfigured. In the browser, use a safe same-origin or public client;\n * there is deliberately no `baseUrl`/`token` option here. Authenticated\n * construction lives only in `@modernrelay/orbit-omnigraph/server`.\n */\nexport function createOmnigraphSource(options: OmnigraphSourceOptions): OmnigraphSource {\n const graphId = options.graphId;\n const branch = options.branch ?? 'main';\n const batchSize = Math.max(1, Math.floor(options.batchSize ?? DEFAULT_BATCH_SIZE));\n const maxPendingBytes = options.maxPendingBytes ?? DEFAULT_MAX_PENDING_BYTES;\n if (!Number.isSafeInteger(maxPendingBytes) || maxPendingBytes <= 0) {\n throw new TypeError(\n 'createOmnigraphSource: maxPendingBytes must be a positive safe integer',\n );\n }\n const driftPolicy = options.driftPolicy ?? 'reject';\n const onProgress = options.onProgress;\n // Sorted canonical form: ['B','A'] and ['A','B'] are the SAME subset and\n // must produce the same identity coordinate.\n const typeNames =\n options.typeNames === undefined ? undefined : [...options.typeNames].sort();\n /** Every call is scoped to the graph (SDK cluster routing). */\n const client: Omnigraph = options.client.graph(graphId);\n // A partial export is a DIFFERENT dataset lifetime than the full graph;\n // positions, selection, and history must not carry across subsets.\n const datasetKey =\n typeNames === undefined\n ? `og:${graphId}:${branch}`\n : `og:${graphId}:${branch}:types=${typeNames.join(',')}`;\n\n async function newestHead(signal: AbortSignal | undefined): Promise<string> {\n const commits = await client.commits.list({ branch }, callOpts(signal));\n const newest = commits[0]; // SDK: most recent first\n if (newest === undefined) {\n throw new Error(\n `omnigraph: branch '${branch}' of graph '${graphId}' has no commits — nothing to export`,\n );\n }\n return newest.graphCommitId;\n }\n\n async function runAttempt(\n target: IngestTarget,\n signal: AbortSignal | undefined,\n warnings: string[],\n attempt: number,\n ): Promise<AttemptSuccess | AttemptRetry> {\n throwIfAborted(signal);\n // Pin the target's SOURCE lineage before any remote work: a competing\n // replace/snapshot landing mid-stream must fail the load. Overlay-only\n // model advances are benign for a replace commit (it supersedes overlays\n // anyway), so the CAS base itself is read fresh at each beginIngest\n // pinning it here made long accept-warn streams fail late (and livelock)\n // under unrelated concurrent overlay traffic.\n const baseSource = target.getRevisions().source;\n\n // The before/after head bracket must enclose BOTH the schema read and the\n // export. Otherwise a schema migration between schema.get and the first\n // head sample could look quiescent while we normalize with stale types.\n const headBefore = await newestHead(signal);\n\n // Endpoint-type resolution + wire-type normalization + the fingerprint\n // half of the revision stamp.\n const schemaSource = (await client.schema.get(callOpts(signal))).schemaSource;\n const schema: PgSchema = parsePgSchema(schemaSource);\n const fingerprint = schemaFingerprint(schemaSource);\n for (const hazard of bigIntKeyWarnings(schema)) {\n pushUnique(\n warnings,\n `omnigraph: ${hazard.type}.${hazard.property} is a 64-bit integer used as identity — ` +\n `JSON parsing silently rounds values past ±2^53, which can collapse distinct ids`,\n );\n }\n // NOTE: a schema-declared `type` property needs no warning — the\n // adapter's discriminator lives at the namespaced ORBIT_TYPE_KEY, so the\n // source's own `type` loads as ordinary data with nothing to report.\n\n const provisionalRef: OmnigraphDataRef = {\n graphId,\n branch,\n headBefore,\n headAfter: headBefore, // provisional: assume quiescence, verify after the stream\n schemaFingerprint: fingerprint,\n ...(typeNames !== undefined ? { typeNames } : {}),\n };\n const provisionalRevision = canonicalSourceRevision(provisionalRef);\n\n function beginSession(sourceRevision: string): IngestSession {\n const now = target.getRevisions();\n if (now.source !== baseSource) {\n throw new Error(\n `omnigraph: the target's source lineage changed while the load was streaming ` +\n `(a competing replace or snapshot landed); aborting instead of overwriting it`,\n );\n }\n return target.beginIngest({\n purpose: 'replace',\n datasetKey,\n sourceRevision,\n baseModelRevision: now.model,\n maxPendingBytes,\n });\n }\n\n // `accept-warn` cannot open a truthful session until headAfter is known.\n // Buffer only that opt-in policy; rejecting/retrying loads keep streaming\n // directly into the atomic target under the provisional revision.\n let session: IngestSession | undefined =\n driftPolicy === 'accept-warn' ? undefined : beginSession(provisionalRevision);\n const requestId = hash64(`${datasetKey}|${provisionalRevision}|${attempt}`);\n\n interface BufferedBatch {\n nodes: GraphNode[];\n edges: GraphEdge[];\n bytes: number;\n progress: { lines: number; nodes: number; edges: number; bytes: number };\n }\n const bufferedBatches: Array<BufferedBatch | undefined> | undefined =\n driftPolicy === 'accept-warn' ? [] : undefined;\n\n let lines = 0;\n let nodeCount = 0;\n let edgeCount = 0;\n let bytes = 0;\n let unknown = 0;\n let sequence = 0;\n let pendingNodes: GraphNode[] = [];\n let pendingEdges: GraphEdge[] = [];\n let pendingBytes = 0;\n let acceptedBytes = 0;\n\n /**\n * Replace ingestion is atomic, so neither core staging nor accept-warn's\n * adapter buffer can drain before commit. Enforce the same finite\n * whole-load budget before retaining the next normalized row.\n */\n function accountAcceptedBytes(lineBytes: number): void {\n const next = acceptedBytes + lineBytes;\n if (next > maxPendingBytes) {\n throw new OrbitOperationError(\n { code: 'queue-overflow', queuedBytes: next, limit: maxPendingBytes },\n `omnigraph: export rows require at least ${next} bytes, exceeding ` +\n `maxPendingBytes ${maxPendingBytes}; load aborted before commit`,\n );\n }\n acceptedBytes = next;\n pendingBytes += lineBytes;\n }\n\n /** Await every append; retain bounded adapter-side pending batches. */\n async function flush(): Promise<void> {\n if (pendingNodes.length === 0 && pendingEdges.length === 0) return;\n const nodes = pendingNodes;\n const edges = pendingEdges;\n const batchBytes = pendingBytes;\n const progress = { lines, nodes: nodeCount, edges: edgeCount, bytes };\n pendingNodes = [];\n pendingEdges = [];\n pendingBytes = 0;\n\n if (bufferedBatches !== undefined) {\n bufferedBatches.push({ nodes, edges, bytes: batchBytes, progress });\n return;\n }\n\n const activeSession = session;\n if (activeSession === undefined) throw new Error('omnigraph: internal missing ingest session');\n const batch: IngestBatch = {\n sequence,\n batchId: `og:${requestId}:${sequence}`,\n bytes: batchBytes,\n };\n if (edges.length > 0) batch.edges = edges;\n if (nodes.length > 0) batch.nodes = nodes;\n sequence += 1;\n await activeSession.append(batch);\n onProgress?.(progress);\n }\n\n /** Commit buffered accept-warn rows once, under the now-known final revision. */\n async function commitBuffered(sourceRevision: string): Promise<void> {\n if (bufferedBatches === undefined) {\n throw new Error('omnigraph: internal missing accept-warn batch buffer');\n }\n const finalSession = beginSession(sourceRevision);\n session = finalSession;\n const finalRequestId = hash64(`${datasetKey}|${sourceRevision}|${attempt}`);\n for (let i = 0; i < bufferedBatches.length; i++) {\n throwIfAborted(signal);\n const buffered = bufferedBatches[i];\n if (buffered === undefined) continue;\n // Release the buffer's array slot as soon as ownership passes to the\n // target session; the local `buffered` reference dies this iteration.\n bufferedBatches[i] = undefined;\n const batch: IngestBatch = {\n sequence: i,\n batchId: `og:${finalRequestId}:${i}`,\n bytes: buffered.bytes,\n };\n if (buffered.edges.length > 0) batch.edges = buffered.edges;\n if (buffered.nodes.length > 0) batch.nodes = buffered.nodes;\n await finalSession.append(batch);\n onProgress?.(buffered.progress);\n }\n bufferedBatches.length = 0;\n await finalSession.commit();\n }\n\n // Bind the iterator ONCE and\n // make sure early exits cancel the underlying stream via `return`.\n const exportInput: ExportInput = { branch, ...(typeNames !== undefined ? { typeNames } : {}) };\n const iterator = client\n .export<Record<string, unknown>>(exportInput, callOpts(signal))\n [Symbol.asyncIterator]();\n\n try {\n for (;;) {\n throwIfAborted(signal);\n const step = await iterator.next();\n if (step.done === true) break;\n const line = step.value;\n lines += 1;\n // The SDK exposes parsed rows rather than raw chunks. Re-serialize to\n // UTF-8 and include one NDJSON newline: a conservative, consistent\n // accounting unit for progress, batches, and the whole-load cap.\n const lineBytes = UTF8_ENCODER.encode(JSON.stringify(line)).byteLength + 1;\n bytes += lineBytes;\n const classified = classifyExportLine(line);\n if (classified.kind === 'node') {\n const node = normalizeNode(classified, schema);\n accountAcceptedBytes(lineBytes);\n pendingNodes.push(node);\n nodeCount += 1;\n } else if (classified.kind === 'edge') {\n const edge = normalizeEdge(classified, schema);\n accountAcceptedBytes(lineBytes);\n pendingEdges.push(edge);\n edgeCount += 1;\n } else {\n unknown += 1;\n }\n if (pendingNodes.length + pendingEdges.length >= batchSize) await flush();\n }\n await flush();\n\n if (unknown > 0) {\n pushUnique(warnings, `omnigraph: skipped ${unknown} unrecognized export line(s)`);\n }\n\n // Revision stamp, second half: the head AFTER the stream, captured\n // BEFORE commit.\n throwIfAborted(signal);\n const headAfter = await newestHead(signal);\n const counts = { lines, nodes: nodeCount, edges: edgeCount, bytes };\n\n if (driftPolicy === 'accept-warn') {\n const finalRef: OmnigraphDataRef = { ...provisionalRef, headAfter };\n const finalRevision = canonicalSourceRevision(finalRef);\n if (headAfter !== headBefore) {\n pushUnique(\n warnings,\n `omnigraph: branch '${branch}' advanced during export (head ${headBefore} → ` +\n `${headAfter}); committed under the canonical final revision per ` +\n `driftPolicy:'accept-warn' — dataRef records both heads`,\n );\n }\n await commitBuffered(finalRevision);\n return { kind: 'done', sourceRevision: finalRevision, dataRef: finalRef, counts };\n }\n\n if (headAfter === headBefore) {\n const activeSession = session;\n if (activeSession === undefined) throw new Error('omnigraph: internal missing ingest session');\n await activeSession.commit();\n return { kind: 'done', sourceRevision: provisionalRevision, dataRef: provisionalRef, counts };\n }\n\n // Branch drift maps to service:omnigraph-source-changed-during-export.\n const activeSession = session;\n if (activeSession === undefined) throw new Error('omnigraph: internal missing ingest session');\n await activeSession.abort('omnigraph: source changed during export');\n if (driftPolicy === 'retry-once' && attempt === 1) {\n pushUnique(\n warnings,\n `omnigraph: branch '${branch}' advanced during export (head ${headBefore} → ` +\n `${headAfter}); load restarted once per driftPolicy:'retry-once'`,\n );\n return { kind: 'retry' };\n }\n throw new OmnigraphDriftError(graphId, branch, headBefore, headAfter);\n } catch (err) {\n if (session?.state === 'open') {\n try {\n await session.abort(err);\n } catch {\n // the original failure wins\n }\n }\n throw mapError(err);\n } finally {\n // Cancel the underlying NDJSON stream on any non-exhausted exit.\n try {\n await iterator.return?.();\n } catch {\n // stream teardown must never mask the outcome\n }\n }\n }\n\n async function load(target: IngestTarget, signal?: AbortSignal): Promise<OmnigraphLoadResult> {\n const warnings: string[] = [];\n\n // Surface an SDK/server major.minor mismatch as a warning, never a hard\n // failure.\n let serverVersion: string;\n try {\n serverVersion = (await client.health(callOpts(signal))).version;\n } catch (err) {\n throw mapError(err);\n }\n const server = majorMinor(serverVersion);\n const sdk = majorMinor(SERVER_VERSION);\n if (server === null || server !== sdk) {\n warnings.push(\n `omnigraph: server version ${serverVersion} does not match the SDK-pinned server ` +\n `version ${SERVER_VERSION} (major.minor differ) — SDK behavior is undefined ` +\n `against this server`,\n );\n }\n\n for (let attempt = 1; ; attempt += 1) {\n let outcome: AttemptSuccess | AttemptRetry;\n try {\n outcome = await runAttempt(target, signal, warnings, attempt);\n } catch (err) {\n // Covers SDK errors thrown before the session/stream phase\n // (schema.get, commits.list); mapError is a no-op on already-mapped\n // or package-owned errors.\n throw mapError(err);\n }\n if (outcome.kind === 'retry') continue;\n return {\n sourceRevision: outcome.sourceRevision,\n dataRef: outcome.dataRef,\n counts: outcome.counts,\n serverVersion,\n warnings,\n };\n }\n }\n\n return { load };\n}\n","/**\n * Stored-query `SearchService` integration.\n *\n * A stored query using `bm25`/`fuzzy`/`nearest`/`rrf` with\n * `order { score desc } limit K` returns entity rows plus a score column; this\n * module wires it as a `SearchService` via\n * `og.queries.invoke(name, { params, branch })`, passing\n * `RequestContext.signal` through SDK `CallOptions`. Core performs revision\n * admission — the service only declares `revisionDependencies: ['source']`\n * (results come from the server-side branch, so they are invalidated by a\n * source change, never by client-side model/scope drift).\n *\n * Identity: Omnigraph ids are unique per type only, and a query row\n * carries no type discriminator of its own — so the adapter REQUIRES a\n * caller-supplied column→node-type mapping (`typeOf`), either a\n * `{ column: NodeType }` record keyed by the projection columns that hold\n * bare-variable node structs, or a per-row function. Every returned id is\n * qualified through `encodeSourceId(nodeType, physicalId)` — the same codec\n * every other adapter path uses — so results round-trip `decodeSourceId` and\n * match export-loaded node ids exactly.\n *\n * Partial-load caveat: search runs server-side over the whole branch, so a\n * partial export load can return ids outside the loaded set.\n * `activateSearchResult` classifies those as `'not-loaded'`; constrain the\n * stored query to the loaded types, or load the full graph, to avoid the\n * mismatch.\n *\n * Error surface: SDK typed errors never cross this package's public\n * surface — they rethrow as plain `Error`s with the stable `omnigraph:`\n * prefix. Abort rejections pass through unchanged.\n */\n\nimport { OmnigraphError } from '@modernrelay/omnigraph';\nimport type { InvokeQueryInput, Omnigraph } from '@modernrelay/omnigraph';\nimport type { RequestContext, SearchResult, SearchService } from '@modernrelay/orbit-core';\n\nimport { encodeSourceId } from './idCodec';\n\n/** One stored-query result row: projection column → value. Bare-variable\n * projections (`return { $s }`) hold whole-node structs including `id`. */\nexport type OmnigraphSearchRow = Record<string, unknown>;\n\n/**\n * The required column→node-type mapping:\n *\n * - a record `{ '$s': 'Signal' }` — the FIRST listed column present in a row\n * with a node struct supplies the physical id, encoded under the mapped\n * type name;\n * - or a per-row function returning the node type name — the row's first\n * node-struct column (row key order) supplies the physical id.\n */\nexport type OmnigraphSearchTypeOf =\n | ((row: OmnigraphSearchRow) => string)\n | Readonly<Record<string, string>>;\n\nexport interface OmnigraphSearchServiceOptions<N = Record<string, unknown>> {\n /** A **preconfigured** SDK client — no `baseUrl`/`token` here. */\n client: Omnigraph;\n /** Cluster graph id; the invoke is scoped via `client.graph(graphId)`. */\n graphId: string;\n /** Branch the stored query reads. Default `'main'`. */\n branch?: string;\n /** Registry name of the stored search query (`POST /queries/{name}`).\n * Invoking a known name works whether or not it is `mcp.expose`d. */\n queryName: string;\n /** Builds the stored query's `params` object from the call.\n * Default: `(q, limit) => ({ q, limit })`. */\n params?: (q: string, limit: number) => Record<string, unknown>;\n /** REQUIRED mapping from row to node type — see\n * {@link OmnigraphSearchTypeOf}. */\n typeOf: OmnigraphSearchTypeOf;\n /** Column whose value becomes `label` (String-coerced when present).\n * Default: the first string-valued column in row key order. */\n labelColumn?: string;\n /** Full custom row→result escape hatch: overrides the default mapping\n * (including `typeOf`/`labelColumn`); return `null` to skip a row. The\n * returned `id` MUST already be type-qualified via `encodeSourceId`. */\n mapRow?: (row: OmnigraphSearchRow) => SearchResult<N> | null;\n}\n\n// ---------------------------------------------------------------------------\n// Small pure helpers\n// ---------------------------------------------------------------------------\n\nfunction defaultParams(q: string, limit: number): Record<string, unknown> {\n return { q, limit };\n}\n\nfunction throwIfAborted(signal: AbortSignal, queryName: string): void {\n if (signal.aborted) {\n throw new DOMException(\n `omnigraph: search query '${queryName}' aborted by request signal`,\n 'AbortError',\n );\n }\n}\n\nfunction isAbortError(err: unknown): boolean {\n return err instanceof Error && err.name === 'AbortError';\n}\n\n/** SDK typed errors rethrow as plain prefixed `Error`s; abort rejections\n * and everything else pass through unchanged. */\nfunction mapError(err: unknown): unknown {\n if (err instanceof OmnigraphError && !isAbortError(err)) {\n return new Error(`omnigraph: ${err.name} (status ${err.status}): ${err.message}`);\n }\n return err;\n}\n\n/** A bare-variable projection value: a whole-node struct carrying its\n * physical id (`return { $s }` yields `{ id,...props }`). */\nfunction isNodeStruct(value: unknown): value is { id: string } {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n typeof (value as { id?: unknown }).id === 'string'\n );\n}\n\n/** The invoke response must be a READ envelope with tabular rows — a stored\n * mutation (Change envelope) or malformed body is a hard error. */\nfunction extractRows(response: unknown, queryName: string): readonly OmnigraphSearchRow[] {\n const rows = (response as { rows?: unknown }).rows;\n if (!Array.isArray(rows)) {\n throw new Error(\n `omnigraph: stored query '${queryName}' did not return a read envelope with rows — ` +\n `the configured search query must be a stored READ query (not a mutation)`,\n );\n }\n for (const row of rows) {\n if (typeof row !== 'object' || row === null || Array.isArray(row)) {\n throw new Error(\n `omnigraph: stored query '${queryName}' returned a non-object row — ` +\n `expected column→value row objects`,\n );\n }\n }\n return rows as OmnigraphSearchRow[];\n}\n\ninterface ResolvedIdentity {\n kind: string;\n sourceId: string;\n}\n\n/** Resolve the `(nodeType, physicalId)` pair for one row via `typeOf`. */\nfunction resolveIdentity(\n row: OmnigraphSearchRow,\n typeOf: OmnigraphSearchTypeOf,\n queryName: string,\n): ResolvedIdentity {\n if (typeof typeOf === 'function') {\n const kind = typeOf(row);\n if (typeof kind !== 'string' || kind.length === 0) {\n throw new Error(\n `omnigraph: typeOf returned ${JSON.stringify(kind)} for a '${queryName}' search row — ` +\n `typeOf must return a non-empty node type name`,\n );\n }\n for (const key of Object.keys(row)) {\n const value = row[key];\n if (isNodeStruct(value)) return { kind, sourceId: value.id };\n }\n throw new Error(\n `omnigraph: '${queryName}' search row has no node-struct column (an object with a ` +\n `string 'id') — project the matched entity bare (return { $s }) so its physical ` +\n `id is available`,\n );\n }\n for (const [column, kind] of Object.entries(typeOf)) {\n const value = row[column];\n if (isNodeStruct(value)) return { kind, sourceId: value.id };\n }\n throw new Error(\n `omnigraph: '${queryName}' search row has no node struct under the mapped column(s) ` +\n `${JSON.stringify(Object.keys(typeOf))} — the typeOf record must key the ` +\n `columns that contain bare-variable node projections`,\n );\n}\n\n// ---------------------------------------------------------------------------\n// createOmnigraphSearchService\n// ---------------------------------------------------------------------------\n\n/**\n * Create the stored-query search service. Plug it into core as\n * `services.search`; the instance owns `RequestContext` creation,\n * revision-keyed caching, supersede cancellation, and stale-result rejection\n * at admission.\n */\nexport function createOmnigraphSearchService<N = Record<string, unknown>>(\n options: OmnigraphSearchServiceOptions<N>,\n): SearchService<N> {\n const { graphId, queryName, typeOf, labelColumn, mapRow } = options;\n const branch = options.branch ?? 'main';\n const buildParams = options.params ?? defaultParams;\n /** Every call is scoped to the graph (SDK cluster routing). */\n const client: Omnigraph = options.client.graph(graphId);\n\n function mapRowDefault(row: OmnigraphSearchRow): SearchResult<N> {\n const { kind, sourceId } = resolveIdentity(row, typeOf, queryName);\n const result: SearchResult<N> = { id: encodeSourceId(kind, sourceId) };\n\n const score = row['score'];\n if (typeof score === 'number' && Number.isFinite(score)) result.score = score;\n\n if (labelColumn !== undefined) {\n const value = row[labelColumn];\n if (typeof value === 'string' || typeof value === 'number') result.label = String(value);\n } else {\n for (const key of Object.keys(row)) {\n if (key === 'score') continue; // the score lane never doubles as a label\n const value = row[key];\n if (typeof value === 'string') {\n result.label = value;\n break;\n }\n }\n }\n return result;\n }\n\n return {\n revisionDependencies: ['source'],\n async search(\n q: string,\n searchOptions: { limit: number },\n ctx: RequestContext,\n ): Promise<readonly SearchResult<N>[]> {\n throwIfAborted(ctx.signal, queryName);\n const limit = Number.isFinite(searchOptions.limit) ? Math.floor(searchOptions.limit) : 0;\n if (q.length === 0 || limit <= 0) return [];\n\n const input: InvokeQueryInput = { branch, params: buildParams(q, limit) };\n let response: unknown;\n try {\n response = await client.queries.invoke(queryName, input, { signal: ctx.signal });\n } catch (err) {\n throw mapError(err);\n }\n throwIfAborted(ctx.signal, queryName);\n\n const rows = extractRows(response, queryName);\n const results: SearchResult<N>[] = [];\n for (const row of rows) {\n if (results.length >= limit) break; // defensive cap — the query owns K\n const mapped = mapRow !== undefined ? mapRow(row) : mapRowDefault(row);\n if (mapped !== null) results.push(mapped);\n }\n return results;\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/loader.ts","../src/searchService.ts"],"names":["activeSession","throwIfAborted","isAbortError","mapError","OmnigraphError"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * v1 export loader.\n *\n * The organizing rule: graphs load via `og.export` — one streamed\n * NDJSON pass, edge lines first (lexicographic table-key order), driven\n * straight into a `purpose:'replace'` ingest session on the target. Queries\n * never introduce nodes or edges.\n *\n * Revision stamp: the canonical `sourceRevision` hashes\n * `{ graphId, branch, headBefore, headAfter, schemaFingerprint }` (plus the\n * sorted `typeNames` subset when the export is partial), but\n * `headAfter` is only knowable after the stream — while core's\n * `BeginIngestOptions` requires `sourceRevision` up front for a replace\n * session. Resolution: under the rejecting/retrying policies the session\n * begins under the PROVISIONAL revision (the canonical hash with\n * `headAfter:= headBefore`), the stream appends into it, and `headAfter` is\n * captured BEFORE `commit`. `accept-warn` is the exception: normalized\n * batches are buffered until `headAfter` is known, then appended once into a\n * session opened with the canonical FINAL revision:\n *\n * - equal heads → provisional === final; commit cleanly. The session only\n * ever commits a revision whose hash is truthful.\n * - drifted heads → `driftPolicy` decides: `'reject'` aborts the session\n * (graph untouched) and throws {@link OmnigraphDriftError};\n * `'accept-warn'` commits the buffered export under the\n * final revision, records BOTH heads in `dataRef`, and\n * adds a warning;\n * `'retry-once'` aborts and restarts the whole load once\n * (a second drift rejects).\n *\n * This is sound because a replace session is atomic and invisible until\n * commit: nothing is published under a revision the policy did not\n * explicitly accept.\n *\n * Error surface: SDK typed errors never cross this package's public\n * surface — they are mapped to plain `Error`s with a stable `omnigraph:`\n * message prefix.\n */\n\nimport { OmnigraphError, SERVER_VERSION } from '@modernrelay/omnigraph';\nimport type { CallOptions, ExportInput, Omnigraph } from '@modernrelay/omnigraph';\nimport { OrbitOperationError } from '@modernrelay/orbit-core';\nimport type { GraphEdge, GraphNode, IngestBatch, IngestSession } from '@modernrelay/orbit-core';\n\nimport { classifyExportLine, normalizeEdge, normalizeNode } from './normalize';\nimport { bigIntKeyWarnings, parsePgSchema, schemaFingerprint } from './pgSchema';\nimport type { PgSchema } from './pgSchema';\nimport type {\n IngestTarget,\n OmnigraphDataRef,\n OmnigraphLoadResult,\n OmnigraphSourceOptions,\n} from './types';\n\nconst DEFAULT_BATCH_SIZE = 2000;\n\n/**\n * Finite whole-export cap for the necessarily atomic replace session. A\n * whole-graph load stages EVERY row before commit, so this is a total-load\n * memory bound, not a backpressure window — real graphs routinely exceed\n * 100 MB of serialized rows (the intel fixture streams ~128 MB), so the\n * default is deliberately generous; callers with tighter memory budgets pass\n * `maxPendingBytes` explicitly.\n */\nconst DEFAULT_MAX_PENDING_BYTES = 512 * 1024 * 1024;\n\n/** Stateless and safe to reuse; counts serialized UTF-8 rather than UTF-16 code units. */\nconst UTF8_ENCODER = new TextEncoder();\n\n/**\n * Raised when a branch moves during export and the configured drift policy\n * rejects the load. The session is aborted and the target graph is untouched.\n */\nexport class OmnigraphDriftError extends Error {\n override readonly name = 'OmnigraphDriftError';\n readonly graphId: string;\n readonly branch: string;\n readonly headBefore: string;\n readonly headAfter: string;\n constructor(graphId: string, branch: string, headBefore: string, headAfter: string) {\n super(\n `omnigraph: branch '${branch}' of graph '${graphId}' changed during export ` +\n `(head ${headBefore} → ${headAfter}); session aborted per driftPolicy (` +\n `service:omnigraph-source-changed-during-export)`,\n );\n this.graphId = graphId;\n this.branch = branch;\n this.headBefore = headBefore;\n this.headAfter = headAfter;\n }\n}\n\n/** The one load path a v1 source exposes. */\nexport interface OmnigraphSource {\n /**\n * Stream one export of the configured graph/branch into `target` via a\n * `purpose:'replace'` ingest session. Resolves with the revision-stamped\n * result; rejects with the session aborted and the target untouched.\n * `signal` aborts both the HTTP stream and the session.\n */\n load(target: IngestTarget, signal?: AbortSignal): Promise<OmnigraphLoadResult>;\n}\n\n// ---------------------------------------------------------------------------\n// Small pure helpers\n// ---------------------------------------------------------------------------\n\n/** FNV-1a 64-bit over the UTF-8 bytes of `s`, as 16 lowercase hex chars. */\nfunction hash64(s: string): string {\n const MASK64 = 0xffffffffffffffffn;\n let h = 0xcbf29ce484222325n;\n for (const b of new TextEncoder().encode(s)) {\n h ^= BigInt(b);\n h = (h * 0x100000001b3n) & MASK64;\n }\n return h.toString(16).padStart(16, '0');\n}\n\n/**\n * The canonical adapter source revision: a hash of the readable `dataRef` object\n * `{ graphId, branch, headBefore, headAfter, schemaFingerprint, typeNames? }`\n * (`dataRef` itself retains the readable form).\n */\nfunction canonicalSourceRevision(ref: OmnigraphDataRef): string {\n // typeNames joins the tuple ONLY when present, so full-export\n // hashes stay byte-identical to every previously persisted revision.\n const tuple: unknown[] = [\n ref.graphId,\n ref.branch,\n ref.headBefore,\n ref.headAfter,\n ref.schemaFingerprint,\n ];\n if (ref.typeNames !== undefined) tuple.push(ref.typeNames);\n return `og:${hash64(JSON.stringify(tuple))}`;\n}\n\n/** `'0.8.1'` → `'0.8'`; null when unparseable. */\nfunction majorMinor(version: string): string | null {\n const m = /^(\\d+)\\.(\\d+)/.exec(version);\n return m ? `${m[1]}.${m[2]}` : null;\n}\n\n/** CallOptions without an explicit-undefined signal (exactOptionalPropertyTypes). */\nfunction callOpts(signal: AbortSignal | undefined): CallOptions {\n return signal ? { signal } : {};\n}\n\nfunction throwIfAborted(signal: AbortSignal | undefined): void {\n if (signal?.aborted) {\n throw new DOMException('omnigraph: load aborted by caller signal', 'AbortError');\n }\n}\n\nfunction isAbortError(err: unknown): boolean {\n return err instanceof Error && err.name === 'AbortError';\n}\n\n/**\n * SDK typed errors (`NetworkError`, `ConflictError`, …) never leak across the\n * public surface; they rethrow as plain `Error`s with a stable prefix.\n * Abort rejections and this package's own errors pass through unchanged.\n */\nfunction mapError(err: unknown): unknown {\n if (err instanceof OmnigraphError && !isAbortError(err)) {\n return new Error(`omnigraph: ${err.name} (status ${err.status}): ${err.message}`);\n }\n return err;\n}\n\nfunction pushUnique(warnings: string[], warning: string): void {\n if (!warnings.includes(warning)) warnings.push(warning);\n}\n\n// ---------------------------------------------------------------------------\n// createOmnigraphSource\n// ---------------------------------------------------------------------------\n\ninterface AttemptSuccess {\n kind: 'done';\n sourceRevision: string;\n dataRef: OmnigraphDataRef;\n counts: { lines: number; nodes: number; edges: number; bytes: number };\n}\n\ninterface AttemptRetry {\n kind: 'retry';\n}\n\n/**\n * Create a v1 export-backed data source. The client must be\n * preconfigured. In the browser, use a safe same-origin or public client;\n * there is deliberately no `baseUrl`/`token` option here. Authenticated\n * construction lives only in `@modernrelay/orbit-omnigraph/server`.\n */\nexport function createOmnigraphSource(options: OmnigraphSourceOptions): OmnigraphSource {\n const graphId = options.graphId;\n const branch = options.branch ?? 'main';\n const batchSize =\n options.batchSize === undefined ? DEFAULT_BATCH_SIZE : options.batchSize;\n if (!Number.isSafeInteger(batchSize) || batchSize <= 0) {\n throw new TypeError('createOmnigraphSource: batchSize must be a positive safe integer');\n }\n const maxPendingBytes =\n options.maxPendingBytes === undefined ? DEFAULT_MAX_PENDING_BYTES : options.maxPendingBytes;\n if (!Number.isSafeInteger(maxPendingBytes) || maxPendingBytes <= 0) {\n throw new TypeError(\n 'createOmnigraphSource: maxPendingBytes must be a positive safe integer',\n );\n }\n const driftPolicy = options.driftPolicy ?? 'reject';\n const onProgress = options.onProgress;\n // Sorted canonical form: ['B','A'] and ['A','B'] are the SAME subset and\n // must produce the same identity coordinate.\n const typeNames =\n options.typeNames === undefined ? undefined : [...options.typeNames].sort();\n /** Every call is scoped to the graph (SDK cluster routing). */\n const client: Omnigraph = options.client.graph(graphId);\n // A partial export is a DIFFERENT dataset lifetime than the full graph;\n // positions, selection, and history must not carry across subsets.\n const datasetKey =\n typeNames === undefined\n ? `og:${graphId}:${branch}`\n : `og:${graphId}:${branch}:types=${typeNames.join(',')}`;\n\n async function newestHead(signal: AbortSignal | undefined): Promise<string> {\n const commits = await client.commits.list({ branch }, callOpts(signal));\n const newest = commits[0]; // SDK: most recent first\n if (newest === undefined) {\n throw new Error(\n `omnigraph: branch '${branch}' of graph '${graphId}' has no commits — nothing to export`,\n );\n }\n return newest.graphCommitId;\n }\n\n async function runAttempt(\n target: IngestTarget,\n signal: AbortSignal | undefined,\n warnings: string[],\n attempt: number,\n ): Promise<AttemptSuccess | AttemptRetry> {\n throwIfAborted(signal);\n // Pin the target's SOURCE lineage before any remote work: a competing\n // replace/snapshot landing mid-stream must fail the load. Overlay-only\n // model advances are benign for a replace commit (it supersedes overlays\n // anyway), so the CAS base itself is read fresh at each beginIngest\n // pinning it here made long accept-warn streams fail late (and livelock)\n // under unrelated concurrent overlay traffic.\n const baseSource = target.getRevisions().source;\n\n // The before/after head bracket must enclose BOTH the schema read and the\n // export. Otherwise a schema migration between schema.get and the first\n // head sample could look quiescent while we normalize with stale types.\n const headBefore = await newestHead(signal);\n\n // Endpoint-type resolution + wire-type normalization + the fingerprint\n // half of the revision stamp.\n const schemaSource = (await client.schema.get(callOpts(signal))).schemaSource;\n const schema: PgSchema = parsePgSchema(schemaSource);\n const fingerprint = schemaFingerprint(schemaSource);\n for (const hazard of bigIntKeyWarnings(schema)) {\n pushUnique(\n warnings,\n `omnigraph: ${hazard.type}.${hazard.property} is a 64-bit integer used as identity — ` +\n `JSON parsing silently rounds values past ±2^53, which can collapse distinct ids`,\n );\n }\n // NOTE: a schema-declared `type` property needs no warning — the\n // adapter's discriminator lives at the namespaced ORBIT_TYPE_KEY, so the\n // source's own `type` loads as ordinary data with nothing to report.\n\n const provisionalRef: OmnigraphDataRef = {\n graphId,\n branch,\n headBefore,\n headAfter: headBefore, // provisional: assume quiescence, verify after the stream\n schemaFingerprint: fingerprint,\n ...(typeNames !== undefined ? { typeNames } : {}),\n };\n const provisionalRevision = canonicalSourceRevision(provisionalRef);\n\n function beginSession(sourceRevision: string): IngestSession {\n const now = target.getRevisions();\n if (now.source !== baseSource) {\n throw new Error(\n `omnigraph: the target's source lineage changed while the load was streaming ` +\n `(a competing replace or snapshot landed); aborting instead of overwriting it`,\n );\n }\n return target.beginIngest({\n purpose: 'replace',\n datasetKey,\n sourceRevision,\n baseModelRevision: now.model,\n maxPendingBytes,\n });\n }\n\n // `accept-warn` cannot open a truthful session until headAfter is known.\n // Buffer only that opt-in policy; rejecting/retrying loads keep streaming\n // directly into the atomic target under the provisional revision.\n let session: IngestSession | undefined =\n driftPolicy === 'accept-warn' ? undefined : beginSession(provisionalRevision);\n const requestId = hash64(`${datasetKey}|${provisionalRevision}|${attempt}`);\n\n interface BufferedBatch {\n nodes: GraphNode[];\n edges: GraphEdge[];\n bytes: number;\n progress: { lines: number; nodes: number; edges: number; bytes: number };\n }\n const bufferedBatches: Array<BufferedBatch | undefined> | undefined =\n driftPolicy === 'accept-warn' ? [] : undefined;\n\n let lines = 0;\n let nodeCount = 0;\n let edgeCount = 0;\n let bytes = 0;\n let unknown = 0;\n let sequence = 0;\n let pendingNodes: GraphNode[] = [];\n let pendingEdges: GraphEdge[] = [];\n let pendingBytes = 0;\n let acceptedBytes = 0;\n\n /**\n * Replace ingestion is atomic, so neither core staging nor accept-warn's\n * adapter buffer can drain before commit. Enforce the same finite\n * whole-load budget before retaining the next normalized row.\n */\n function accountAcceptedBytes(lineBytes: number): void {\n const next = acceptedBytes + lineBytes;\n if (next > maxPendingBytes) {\n throw new OrbitOperationError(\n { code: 'queue-overflow', queuedBytes: next, limit: maxPendingBytes },\n `omnigraph: export rows require at least ${next} bytes, exceeding ` +\n `maxPendingBytes ${maxPendingBytes}; load aborted before commit`,\n );\n }\n acceptedBytes = next;\n pendingBytes += lineBytes;\n }\n\n /** Await every append; retain bounded adapter-side pending batches. */\n async function flush(): Promise<void> {\n if (pendingNodes.length === 0 && pendingEdges.length === 0) return;\n const nodes = pendingNodes;\n const edges = pendingEdges;\n const batchBytes = pendingBytes;\n const progress = { lines, nodes: nodeCount, edges: edgeCount, bytes };\n pendingNodes = [];\n pendingEdges = [];\n pendingBytes = 0;\n\n if (bufferedBatches !== undefined) {\n bufferedBatches.push({ nodes, edges, bytes: batchBytes, progress });\n return;\n }\n\n const activeSession = session;\n if (activeSession === undefined) throw new Error('omnigraph: internal missing ingest session');\n const batch: IngestBatch = {\n sequence,\n batchId: `og:${requestId}:${sequence}`,\n bytes: batchBytes,\n };\n if (edges.length > 0) batch.edges = edges;\n if (nodes.length > 0) batch.nodes = nodes;\n sequence += 1;\n await activeSession.append(batch);\n onProgress?.(progress);\n }\n\n /** Commit buffered accept-warn rows once, under the now-known final revision. */\n async function commitBuffered(sourceRevision: string): Promise<void> {\n if (bufferedBatches === undefined) {\n throw new Error('omnigraph: internal missing accept-warn batch buffer');\n }\n const finalSession = beginSession(sourceRevision);\n session = finalSession;\n const finalRequestId = hash64(`${datasetKey}|${sourceRevision}|${attempt}`);\n for (let i = 0; i < bufferedBatches.length; i++) {\n throwIfAborted(signal);\n const buffered = bufferedBatches[i];\n if (buffered === undefined) continue;\n // Release the buffer's array slot as soon as ownership passes to the\n // target session; the local `buffered` reference dies this iteration.\n bufferedBatches[i] = undefined;\n const batch: IngestBatch = {\n sequence: i,\n batchId: `og:${finalRequestId}:${i}`,\n bytes: buffered.bytes,\n };\n if (buffered.edges.length > 0) batch.edges = buffered.edges;\n if (buffered.nodes.length > 0) batch.nodes = buffered.nodes;\n await finalSession.append(batch);\n onProgress?.(buffered.progress);\n }\n bufferedBatches.length = 0;\n await finalSession.commit();\n }\n\n // Bind the iterator ONCE and\n // make sure early exits cancel the underlying stream via `return`.\n const exportInput: ExportInput = { branch, ...(typeNames !== undefined ? { typeNames } : {}) };\n const iterator = client\n .export<Record<string, unknown>>(exportInput, callOpts(signal))\n [Symbol.asyncIterator]();\n\n try {\n for (;;) {\n throwIfAborted(signal);\n const step = await iterator.next();\n if (step.done === true) break;\n const line = step.value;\n lines += 1;\n // The SDK exposes parsed rows rather than raw chunks. Re-serialize to\n // UTF-8 and include one NDJSON newline: a conservative, consistent\n // accounting unit for progress, batches, and the whole-load cap.\n const lineBytes = UTF8_ENCODER.encode(JSON.stringify(line)).byteLength + 1;\n bytes += lineBytes;\n const classified = classifyExportLine(line);\n if (classified.kind === 'node') {\n const node = normalizeNode(classified, schema);\n accountAcceptedBytes(lineBytes);\n pendingNodes.push(node);\n nodeCount += 1;\n } else if (classified.kind === 'edge') {\n const edge = normalizeEdge(classified, schema);\n accountAcceptedBytes(lineBytes);\n pendingEdges.push(edge);\n edgeCount += 1;\n } else {\n unknown += 1;\n }\n if (pendingNodes.length + pendingEdges.length >= batchSize) await flush();\n }\n await flush();\n\n if (unknown > 0) {\n pushUnique(warnings, `omnigraph: skipped ${unknown} unrecognized export line(s)`);\n }\n\n // Revision stamp, second half: the head AFTER the stream, captured\n // BEFORE commit.\n throwIfAborted(signal);\n const headAfter = await newestHead(signal);\n const counts = { lines, nodes: nodeCount, edges: edgeCount, bytes };\n\n if (driftPolicy === 'accept-warn') {\n const finalRef: OmnigraphDataRef = { ...provisionalRef, headAfter };\n const finalRevision = canonicalSourceRevision(finalRef);\n if (headAfter !== headBefore) {\n pushUnique(\n warnings,\n `omnigraph: branch '${branch}' advanced during export (head ${headBefore} → ` +\n `${headAfter}); committed under the canonical final revision per ` +\n `driftPolicy:'accept-warn' — dataRef records both heads`,\n );\n }\n await commitBuffered(finalRevision);\n return { kind: 'done', sourceRevision: finalRevision, dataRef: finalRef, counts };\n }\n\n if (headAfter === headBefore) {\n const activeSession = session;\n if (activeSession === undefined) throw new Error('omnigraph: internal missing ingest session');\n await activeSession.commit();\n return { kind: 'done', sourceRevision: provisionalRevision, dataRef: provisionalRef, counts };\n }\n\n // Branch drift maps to service:omnigraph-source-changed-during-export.\n const activeSession = session;\n if (activeSession === undefined) throw new Error('omnigraph: internal missing ingest session');\n await activeSession.abort('omnigraph: source changed during export');\n if (driftPolicy === 'retry-once' && attempt === 1) {\n pushUnique(\n warnings,\n `omnigraph: branch '${branch}' advanced during export (head ${headBefore} → ` +\n `${headAfter}); load restarted once per driftPolicy:'retry-once'`,\n );\n return { kind: 'retry' };\n }\n throw new OmnigraphDriftError(graphId, branch, headBefore, headAfter);\n } catch (err) {\n if (session?.state === 'open') {\n try {\n await session.abort(err);\n } catch {\n // the original failure wins\n }\n }\n throw mapError(err);\n } finally {\n // Cancel the underlying NDJSON stream on any non-exhausted exit.\n try {\n await iterator.return?.();\n } catch {\n // stream teardown must never mask the outcome\n }\n }\n }\n\n async function load(target: IngestTarget, signal?: AbortSignal): Promise<OmnigraphLoadResult> {\n const warnings: string[] = [];\n\n // Surface an SDK/server major.minor mismatch as a warning, never a hard\n // failure.\n let serverVersion: string;\n try {\n serverVersion = (await client.health(callOpts(signal))).version;\n } catch (err) {\n throw mapError(err);\n }\n const server = majorMinor(serverVersion);\n const sdk = majorMinor(SERVER_VERSION);\n if (server === null || server !== sdk) {\n warnings.push(\n `omnigraph: server version ${serverVersion} does not match the SDK-pinned server ` +\n `version ${SERVER_VERSION} (major.minor differ) — SDK behavior is undefined ` +\n `against this server`,\n );\n }\n\n for (let attempt = 1; ; attempt += 1) {\n let outcome: AttemptSuccess | AttemptRetry;\n try {\n outcome = await runAttempt(target, signal, warnings, attempt);\n } catch (err) {\n // Covers SDK errors thrown before the session/stream phase\n // (schema.get, commits.list); mapError is a no-op on already-mapped\n // or package-owned errors.\n throw mapError(err);\n }\n if (outcome.kind === 'retry') continue;\n return {\n sourceRevision: outcome.sourceRevision,\n dataRef: outcome.dataRef,\n counts: outcome.counts,\n serverVersion,\n warnings,\n };\n }\n }\n\n return { load };\n}\n","/**\n * Stored-query `SearchService` integration.\n *\n * A stored query using `bm25`/`fuzzy`/`nearest`/`rrf` with\n * `order { score desc } limit K` returns entity rows plus a score column; this\n * module wires it as a `SearchService` via\n * `og.queries.invoke(name, { params, branch })`, passing\n * `RequestContext.signal` through SDK `CallOptions`. Core performs revision\n * admission — the service only declares `revisionDependencies: ['source']`\n * (results come from the server-side branch, so they are invalidated by a\n * source change, never by client-side model/scope drift).\n *\n * Identity: Omnigraph ids are unique per type only, and a query row\n * carries no type discriminator of its own — so the adapter REQUIRES a\n * caller-supplied column→node-type mapping (`typeOf`), either a\n * `{ column: NodeType }` record keyed by the projection columns that hold\n * bare-variable node structs, or a per-row function. Every returned id is\n * qualified through `encodeSourceId(nodeType, physicalId)` — the same codec\n * every other adapter path uses — so results round-trip `decodeSourceId` and\n * match export-loaded node ids exactly.\n *\n * Partial-load caveat: search runs server-side over the whole branch, so a\n * partial export load can return ids outside the loaded set.\n * `activateSearchResult` classifies those as `'not-loaded'`; constrain the\n * stored query to the loaded types, or load the full graph, to avoid the\n * mismatch.\n *\n * Error surface: SDK typed errors never cross this package's public\n * surface — they rethrow as plain `Error`s with the stable `omnigraph:`\n * prefix. Abort rejections pass through unchanged.\n */\n\nimport { OmnigraphError } from '@modernrelay/omnigraph';\nimport type { InvokeQueryInput, Omnigraph } from '@modernrelay/omnigraph';\nimport type { RequestContext, SearchResult, SearchService } from '@modernrelay/orbit-core';\n\nimport { encodeSourceId } from './idCodec';\n\n/** One stored-query result row: projection column → value. Bare-variable\n * projections (`return { $s }`) hold whole-node structs including `id`. */\nexport type OmnigraphSearchRow = Record<string, unknown>;\n\n/**\n * The required column→node-type mapping:\n *\n * - a record `{ '$s': 'Signal' }` — the FIRST listed column present in a row\n * with a node struct supplies the physical id, encoded under the mapped\n * type name;\n * - or a per-row function returning the node type name — the row's first\n * node-struct column (row key order) supplies the physical id.\n */\nexport type OmnigraphSearchTypeOf =\n | ((row: OmnigraphSearchRow) => string)\n | Readonly<Record<string, string>>;\n\nexport interface OmnigraphSearchServiceOptions<N = Record<string, unknown>> {\n /** A **preconfigured** SDK client — no `baseUrl`/`token` here. */\n client: Omnigraph;\n /** Cluster graph id; the invoke is scoped via `client.graph(graphId)`. */\n graphId: string;\n /** Branch the stored query reads. Default `'main'`. */\n branch?: string;\n /** Registry name of the stored search query (`POST /queries/{name}`).\n * Invoking a known name works whether or not it is `mcp.expose`d. */\n queryName: string;\n /** Builds the stored query's `params` object from the call.\n * Default: `(q, limit) => ({ q, limit })`. */\n params?: (q: string, limit: number) => Record<string, unknown>;\n /** REQUIRED mapping from row to node type — see\n * {@link OmnigraphSearchTypeOf}. */\n typeOf: OmnigraphSearchTypeOf;\n /** Column whose value becomes `label` (String-coerced when present).\n * Default: the first string-valued column in row key order. */\n labelColumn?: string;\n /** Full custom row→result escape hatch: overrides the default mapping\n * (including `typeOf`/`labelColumn`); return `null` to skip a row. The\n * returned `id` MUST already be type-qualified via `encodeSourceId`. */\n mapRow?: (row: OmnigraphSearchRow) => SearchResult<N> | null;\n}\n\n// ---------------------------------------------------------------------------\n// Small pure helpers\n// ---------------------------------------------------------------------------\n\nfunction defaultParams(q: string, limit: number): Record<string, unknown> {\n return { q, limit };\n}\n\nfunction throwIfAborted(signal: AbortSignal, queryName: string): void {\n if (signal.aborted) {\n throw new DOMException(\n `omnigraph: search query '${queryName}' aborted by request signal`,\n 'AbortError',\n );\n }\n}\n\nfunction isAbortError(err: unknown): boolean {\n return err instanceof Error && err.name === 'AbortError';\n}\n\n/** SDK typed errors rethrow as plain prefixed `Error`s; abort rejections\n * and everything else pass through unchanged. */\nfunction mapError(err: unknown): unknown {\n if (err instanceof OmnigraphError && !isAbortError(err)) {\n return new Error(`omnigraph: ${err.name} (status ${err.status}): ${err.message}`);\n }\n return err;\n}\n\n/** A bare-variable projection value: a whole-node struct carrying its\n * physical id (`return { $s }` yields `{ id,...props }`). */\nfunction isNodeStruct(value: unknown): value is { id: string } {\n return (\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n typeof (value as { id?: unknown }).id === 'string'\n );\n}\n\n/** The invoke response must be a READ envelope with tabular rows — a stored\n * mutation (Change envelope) or malformed body is a hard error. */\nfunction extractRows(response: unknown, queryName: string): readonly OmnigraphSearchRow[] {\n const rows = (response as { rows?: unknown }).rows;\n if (!Array.isArray(rows)) {\n throw new Error(\n `omnigraph: stored query '${queryName}' did not return a read envelope with rows — ` +\n `the configured search query must be a stored READ query (not a mutation)`,\n );\n }\n for (const row of rows) {\n if (typeof row !== 'object' || row === null || Array.isArray(row)) {\n throw new Error(\n `omnigraph: stored query '${queryName}' returned a non-object row — ` +\n `expected column→value row objects`,\n );\n }\n }\n return rows as OmnigraphSearchRow[];\n}\n\ninterface ResolvedIdentity {\n kind: string;\n sourceId: string;\n}\n\n/** Resolve the `(nodeType, physicalId)` pair for one row via `typeOf`. */\nfunction resolveIdentity(\n row: OmnigraphSearchRow,\n typeOf: OmnigraphSearchTypeOf,\n queryName: string,\n): ResolvedIdentity {\n if (typeof typeOf === 'function') {\n const kind = typeOf(row);\n if (typeof kind !== 'string' || kind.length === 0) {\n throw new Error(\n `omnigraph: typeOf returned ${JSON.stringify(kind)} for a '${queryName}' search row — ` +\n `typeOf must return a non-empty node type name`,\n );\n }\n for (const key of Object.keys(row)) {\n const value = row[key];\n if (isNodeStruct(value)) return { kind, sourceId: value.id };\n }\n throw new Error(\n `omnigraph: '${queryName}' search row has no node-struct column (an object with a ` +\n `string 'id') — project the matched entity bare (return { $s }) so its physical ` +\n `id is available`,\n );\n }\n for (const [column, kind] of Object.entries(typeOf)) {\n const value = row[column];\n if (isNodeStruct(value)) return { kind, sourceId: value.id };\n }\n throw new Error(\n `omnigraph: '${queryName}' search row has no node struct under the mapped column(s) ` +\n `${JSON.stringify(Object.keys(typeOf))} — the typeOf record must key the ` +\n `columns that contain bare-variable node projections`,\n );\n}\n\n// ---------------------------------------------------------------------------\n// createOmnigraphSearchService\n// ---------------------------------------------------------------------------\n\n/**\n * Create the stored-query search service. Plug it into core as\n * `services.search`; the instance owns `RequestContext` creation,\n * revision-keyed caching, supersede cancellation, and stale-result rejection\n * at admission.\n */\nexport function createOmnigraphSearchService<N = Record<string, unknown>>(\n options: OmnigraphSearchServiceOptions<N>,\n): SearchService<N> {\n const { graphId, queryName, typeOf, labelColumn, mapRow } = options;\n const branch = options.branch ?? 'main';\n const buildParams = options.params ?? defaultParams;\n /** Every call is scoped to the graph (SDK cluster routing). */\n const client: Omnigraph = options.client.graph(graphId);\n\n function mapRowDefault(row: OmnigraphSearchRow): SearchResult<N> {\n const { kind, sourceId } = resolveIdentity(row, typeOf, queryName);\n const result: SearchResult<N> = { id: encodeSourceId(kind, sourceId) };\n\n const score = row['score'];\n if (typeof score === 'number' && Number.isFinite(score)) result.score = score;\n\n if (labelColumn !== undefined) {\n const value = row[labelColumn];\n if (typeof value === 'string' || typeof value === 'number') result.label = String(value);\n } else {\n for (const key of Object.keys(row)) {\n if (key === 'score') continue; // the score lane never doubles as a label\n const value = row[key];\n if (typeof value === 'string') {\n result.label = value;\n break;\n }\n }\n }\n return result;\n }\n\n return {\n revisionDependencies: ['source'],\n async search(\n q: string,\n searchOptions: { limit: number },\n ctx: RequestContext,\n ): Promise<readonly SearchResult<N>[]> {\n throwIfAborted(ctx.signal, queryName);\n const limit = Number.isFinite(searchOptions.limit) ? Math.floor(searchOptions.limit) : 0;\n if (q.length === 0 || limit <= 0) return [];\n\n const input: InvokeQueryInput = { branch, params: buildParams(q, limit) };\n let response: unknown;\n try {\n response = await client.queries.invoke(queryName, input, { signal: ctx.signal });\n } catch (err) {\n throw mapError(err);\n }\n throwIfAborted(ctx.signal, queryName);\n\n const rows = extractRows(response, queryName);\n const results: SearchResult<N>[] = [];\n for (const row of rows) {\n if (results.length >= limit) break; // defensive cap — the query owns K\n const mapped = mapRow !== undefined ? mapRow(row) : mapRowDefault(row);\n if (mapped !== null) results.push(mapped);\n }\n return results;\n },\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modernrelay/orbit-omnigraph",
3
- "version": "0.14.0",
3
+ "version": "0.15.0",
4
4
  "description": "Omnigraph adapter for Orbit: og.export() loader with drift policies, .pg schema parser, and typed codegen.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -31,7 +31,7 @@
31
31
  },
32
32
  "dependencies": {
33
33
  "@modernrelay/omnigraph": "0.9.0",
34
- "@modernrelay/orbit-core": "0.14.0"
34
+ "@modernrelay/orbit-core": "0.15.0"
35
35
  },
36
36
  "devDependencies": {
37
37
  "typescript": "^5.6.0",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/idCodec.ts","../src/pgSchema.ts","../src/normalize.ts"],"names":["body","braceIdx","blockEnd"],"mappings":"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","file":"chunk-YDRPXYQ7.js","sourcesContent":["/**\n * Identity codec.\n *\n * Omnigraph node ids are unique **per type only** (derived from the `@key`\n * tuple within each type's table), so unqualified ids are unsound as orbit\n * `NodeId`s. Every adapter path — nodes, edges, search results, view state,\n * services — MUST qualify ids through this one collision-proof tuple codec.\n * `JSON.stringify` of a fixed-arity string tuple is injective over its inputs\n * (quotes, brackets, commas, and unicode in either component are escaped), so\n * no `(kind, sourceId)` pair can collide with a different pair.\n *\n * Human-readable labels stay separate from identity; there is deliberately no\n * `namespaceIds:false` escape hatch.\n */\n\nexport interface DecodedSourceId {\n /** The namespace component: a node type name or an edge type name. */\n kind: string;\n /** The physical Omnigraph id within that type's table. */\n sourceId: string;\n}\n\n/**\n * Encode a `(kind, sourceId)` pair as a collision-proof orbit id.\n *\n * - Nodes: `encodeSourceId(NodeType, data.id)`\n * - Edges: `encodeSourceId(EdgeName, data.id)`; endpoints use\n * `encodeSourceId(endpointType, from|to)`.\n */\nexport function encodeSourceId(kind: string, sourceId: string): string {\n return JSON.stringify([kind, sourceId]);\n}\n\n/**\n * Decode an id produced by {@link encodeSourceId}.\n *\n * Returns `null` for anything that does not conform exactly (non-JSON input,\n * non-array JSON, wrong arity — including synthetic edge ids, which are\n * 4-tuples — or non-string elements). Never throws.\n */\nexport function decodeSourceId(id: string): DecodedSourceId | null {\n let parsed: unknown;\n try {\n parsed = JSON.parse(id);\n } catch {\n return null;\n }\n if (!Array.isArray(parsed) || parsed.length !== 2) return null;\n const [kind, sourceId] = parsed as unknown[];\n if (typeof kind !== 'string' || typeof sourceId !== 'string') return null;\n return { kind, sourceId };\n}\n\n/**\n * Synthetic edge id for **query-derived** subgraphs.\n *\n * The GQ grammar has no edge variable, so the query path can never surface\n * physical edge ids; query-derived edges are identified by\n * `['synthetic-edge', EdgeName, source, target]` where `source`/`target` are\n * the already-encoded endpoint node ids.\n *\n * Exported for the future query path.\n * Caveats: parallel edges collapse under this scheme, and a dataset\n * MUST NOT mix synthetic ids with physical `/export` ids for the same edges\n * one scheme per dataset, never both. Because a synthetic id is a 4-tuple,\n * {@link decodeSourceId} rejects it (`null`), keeping the two schemes\n * mechanically un-confusable.\n */\nexport function encodeSyntheticEdgeId(edgeName: string, source: string, target: string): string {\n return JSON.stringify(['synthetic-edge', edgeName, source, target]);\n}\n","/**\n * `.pg` schema model + tolerant parser.\n *\n * The adapter needs three things from the graph schema, all served here:\n * 1. edge endpoint-type resolution (export edge lines carry bare `from`/`to`\n * ids without endpoint types),\n * 2. per-property wire-type knowledge for temporal/blob normalization,\n * 3. a stable schema fingerprint for the export revision stamp.\n *\n * The parser is deliberately tolerant: it extracts the declarations it\n * understands (interfaces, node blocks, edge declarations, properties,\n * constraints) and preserves anything else — unknown annotations survive as\n * raw strings, unknown type spellings become `{ kind: 'unknown' }` — so a\n * newer server grammar degrades gracefully instead of failing the load.\n *\n * Browser-safe: no `node:` imports. The fingerprint is a pure FNV-1a 64-bit\n * hash rather than `node:crypto` sha256 so this module can sit on the\n * browser entry's critical path.\n */\n\n// ---------------------------------------------------------------------------\n// Model\n// ---------------------------------------------------------------------------\n\n/** Closed scalar set per the `.pg` grammar (docs/user/schema). */\nexport type PgScalarName =\n | 'String'\n | 'Blob'\n | 'Bool'\n | 'I32'\n | 'I64'\n | 'U32'\n | 'U64'\n | 'F32'\n | 'F64'\n | 'Date'\n | 'DateTime';\n\nexport type PgType =\n | PgScalarName\n | { kind: 'vector'; dim: number }\n | { kind: 'enum'; values: readonly string[] }\n | { kind: 'list'; element: PgScalarName }\n | { kind: 'unknown'; raw: string };\n\nexport interface PgProperty {\n name: string;\n type: PgType;\n /** `T?` nullability. */\n optional: boolean;\n /** Set by inline `@key` or a body-level `@key(...)` naming this property. */\n key: boolean;\n /** Set by inline `@unique` or a body-level `@unique(...)` naming this property. */\n unique: boolean;\n /** Set by inline `@index` or a body-level `@index(...)` naming this property. */\n index: boolean;\n /** Every annotation as written (`'@key'`, `'@embed(\"body\")'`) — unknown ones preserved verbatim. */\n annotations: readonly string[];\n}\n\nexport interface PgInterfaceType {\n name: string;\n properties: readonly PgProperty[];\n /** Body-level constraint declarations preserved verbatim (e.g. `'@unique(a, b)'`). */\n constraints: readonly string[];\n}\n\nexport interface PgNodeType {\n name: string;\n /** Interface names from the `implements` clause (already expanded into `properties`). */\n implements: readonly string[];\n properties: readonly PgProperty[];\n constraints: readonly string[];\n}\n\nexport interface PgEdgeType {\n name: string;\n /** Source (from) node type name. */\n from: string;\n /** Destination (to) node type name. */\n to: string;\n /** Raw `@card` bounds, e.g. `'1..1'`, `'0..*'`. Absent means the default `0..*`. */\n card?: string;\n /** Header annotations as written (including the `@card(...)` one, if any). */\n annotations: readonly string[];\n properties: readonly PgProperty[];\n constraints: readonly string[];\n}\n\nexport interface PgSchema {\n interfaces: readonly PgInterfaceType[];\n nodes: readonly PgNodeType[];\n edges: readonly PgEdgeType[];\n}\n\nconst SCALARS: ReadonlySet<string> = new Set<PgScalarName>([\n 'String',\n 'Blob',\n 'Bool',\n 'I32',\n 'I64',\n 'U32',\n 'U64',\n 'F32',\n 'F64',\n 'Date',\n 'DateTime',\n]);\n\n// ---------------------------------------------------------------------------\n// Lexical helpers (string-aware; `.pg` strings are double-quoted with `\\` escapes)\n// ---------------------------------------------------------------------------\n\n/** Blank out line and block comments, preserving newlines and string literals. */\nfunction stripComments(src: string): string {\n let out = '';\n let i = 0;\n const n = src.length;\n while (i < n) {\n const ch = src.charAt(i);\n if (ch === '\"') {\n out += ch;\n i++;\n while (i < n) {\n const c = src.charAt(i);\n out += c;\n i++;\n if (c === '\\\\' && i < n) {\n out += src.charAt(i);\n i++;\n } else if (c === '\"') break;\n }\n } else if (ch === '/' && src.charAt(i + 1) === '/') {\n while (i < n && src.charAt(i) !== '\\n') i++;\n } else if (ch === '/' && src.charAt(i + 1) === '*') {\n i += 2;\n while (i < n && !(src.charAt(i) === '*' && src.charAt(i + 1) === '/')) {\n out += src.charAt(i) === '\\n' ? '\\n' : ' ';\n i++;\n }\n i += 2;\n } else {\n out += ch;\n i++;\n }\n }\n return out;\n}\n\n/** Index just past the `}` matching the `{` at `openIdx`, or `src.length` if unbalanced. */\nfunction findBlockEnd(src: string, openIdx: number): number {\n let depth = 0;\n let i = openIdx;\n const n = src.length;\n while (i < n) {\n const ch = src.charAt(i);\n if (ch === '\"') {\n i++;\n while (i < n) {\n const c = src.charAt(i);\n i++;\n if (c === '\\\\') i++;\n else if (c === '\"') break;\n }\n continue;\n }\n if (ch === '{') depth++;\n else if (ch === '}') {\n depth--;\n if (depth === 0) return i + 1;\n }\n i++;\n }\n return n;\n}\n\n/** Split a block body into statements at newlines that sit outside parens/brackets/strings. */\nfunction splitStatements(body: string): string[] {\n const out: string[] = [];\n let depth = 0;\n let current = '';\n let i = 0;\n const n = body.length;\n while (i < n) {\n const ch = body.charAt(i);\n if (ch === '\"') {\n current += ch;\n i++;\n while (i < n) {\n const c = body.charAt(i);\n current += c;\n i++;\n if (c === '\\\\' && i < n) {\n current += body.charAt(i);\n i++;\n } else if (c === '\"') break;\n }\n continue;\n }\n if (ch === '(' || ch === '[') depth++;\n else if (ch === ')' || ch === ']') depth = Math.max(0, depth - 1);\n if (ch === '\\n' && depth === 0) {\n out.push(current);\n current = '';\n } else {\n current += ch;\n }\n i++;\n }\n out.push(current);\n return out.map((s) => s.trim()).filter((s) => s.length > 0);\n}\n\ninterface RawAnnotation {\n name: string;\n args?: string;\n raw: string;\n}\n\n/** Scan a run of `@ident` / `@ident(...)` annotations starting at `start`. */\nfunction scanAnnotations(src: string, start: number): { anns: RawAnnotation[]; end: number } {\n const anns: RawAnnotation[] = [];\n let i = start;\n const n = src.length;\n for (;;) {\n let j = i;\n while (j < n && /\\s/.test(src.charAt(j))) j++;\n if (src.charAt(j) !== '@') break;\n const m = /^@([A-Za-z_]\\w*)/.exec(src.slice(j));\n if (!m || m[1] === undefined) break;\n const name = m[1];\n let end = j + m[0].length;\n let args: string | undefined;\n if (src.charAt(end) === '(') {\n let depth = 0;\n let k = end;\n while (k < n) {\n const ch = src.charAt(k);\n if (ch === '\"') {\n k++;\n while (k < n) {\n const c = src.charAt(k);\n k++;\n if (c === '\\\\') k++;\n else if (c === '\"') break;\n }\n continue;\n }\n if (ch === '(') depth++;\n else if (ch === ')') {\n depth--;\n if (depth === 0) {\n k++;\n break;\n }\n }\n k++;\n }\n args = src.slice(end + 1, k - 1);\n end = k;\n }\n const entry: RawAnnotation = { name, raw: src.slice(j, end) };\n if (args !== undefined) entry.args = args;\n anns.push(entry);\n i = end;\n }\n return { anns, end: i };\n}\n\n/** Split on top-level commas (outside parens/strings), trim, drop empties. */\nfunction splitArgs(args: string): string[] {\n const out: string[] = [];\n let depth = 0;\n let current = '';\n for (let i = 0; i < args.length; i++) {\n const ch = args.charAt(i);\n if (ch === '\"') {\n current += ch;\n i++;\n while (i < args.length) {\n const c = args.charAt(i);\n current += c;\n if (c === '\\\\') {\n i++;\n current += args.charAt(i);\n } else if (c === '\"') break;\n i++;\n }\n continue;\n }\n if (ch === '(' || ch === '[') depth++;\n else if (ch === ')' || ch === ']') depth = Math.max(0, depth - 1);\n if (ch === ',' && depth === 0) {\n out.push(current);\n current = '';\n } else {\n current += ch;\n }\n }\n out.push(current);\n return out.map((s) => s.trim()).filter((s) => s.length > 0);\n}\n\n// ---------------------------------------------------------------------------\n// Statement parsing\n// ---------------------------------------------------------------------------\n\ninterface MutableTypeBody {\n properties: PgProperty[];\n constraints: string[];\n}\n\nfunction parseTypeRef(text: string): { type: PgType; optional: boolean; end: number } {\n let i = 0;\n const n = text.length;\n while (i < n && /\\s/.test(text.charAt(i))) i++;\n let type: PgType;\n if (text.charAt(i) === '[') {\n const m = /^\\[\\s*([A-Za-z_]\\w*)\\s*\\]/.exec(text.slice(i));\n if (m && m[1] !== undefined && SCALARS.has(m[1])) {\n type = { kind: 'list', element: m[1] as PgScalarName };\n i += m[0].length;\n } else {\n const close = text.indexOf(']', i);\n const end = close === -1 ? n : close + 1;\n type = { kind: 'unknown', raw: text.slice(i, end).trim() };\n i = end;\n }\n } else {\n const m = /^([A-Za-z_]\\w*)/.exec(text.slice(i));\n if (!m || m[1] === undefined) {\n return { type: { kind: 'unknown', raw: text.trim() }, optional: false, end: n };\n }\n const ident = m[1];\n i += m[0].length;\n if ((ident === 'enum' || ident === 'Vector') && text.charAt(i) === '(') {\n let depth = 0;\n let k = i;\n while (k < n) {\n const ch = text.charAt(k);\n if (ch === '(') depth++;\n else if (ch === ')') {\n depth--;\n if (depth === 0) {\n k++;\n break;\n }\n }\n k++;\n }\n const inner = text.slice(i + 1, k - 1);\n i = k;\n if (ident === 'enum') {\n const values = splitArgs(inner).map((v) => v.replace(/^\"(.*)\"$/s, '$1'));\n type = { kind: 'enum', values };\n } else {\n const dim = Number.parseInt(inner.trim(), 10);\n type = Number.isFinite(dim)\n ? { kind: 'vector', dim }\n : { kind: 'unknown', raw: `Vector(${inner})` };\n }\n } else if (SCALARS.has(ident)) {\n type = ident as PgScalarName;\n } else {\n type = { kind: 'unknown', raw: ident };\n }\n }\n let optional = false;\n if (text.charAt(i) === '?') {\n optional = true;\n i++;\n }\n return { type, optional, end: i };\n}\n\nfunction parseBody(body: string): MutableTypeBody {\n const properties: PgProperty[] = [];\n const constraints: string[] = [];\n for (const stmt of splitStatements(body)) {\n if (stmt.startsWith('@')) {\n const { anns } = scanAnnotations(stmt, 0);\n for (const a of anns) constraints.push(a.raw);\n continue;\n }\n // A statement may carry SEVERAL whitespace-separated properties\n // (`id: String when: DateTime`); a single parse would keep only the first\n // and silently drop the rest. Loop until the trailer\n // stops looking like another property head; junk trailers stay\n // tolerant-skipped as before.\n let cursor = stmt;\n for (;;) {\n const head = /^([A-Za-z_]\\w*)\\s*:\\s*/.exec(cursor);\n if (!head || head[1] === undefined) break; // tolerant: skip unrecognized statements\n const name = head[1];\n const rest = cursor.slice(head[0].length);\n const { type, optional, end } = parseTypeRef(rest);\n const { anns, end: annsEnd } = scanAnnotations(rest, end);\n properties.push({\n name,\n type,\n optional,\n key: anns.some((a) => a.name === 'key'),\n unique: anns.some((a) => a.name === 'unique'),\n index: anns.some((a) => a.name === 'index'),\n annotations: anns.map((a) => a.raw),\n });\n cursor = rest.slice(annsEnd).trimStart();\n if (cursor === '') break;\n }\n }\n // Body-level @key(a, b) / @unique(a) / @index(a) constraints flag the named properties.\n for (const raw of constraints) {\n const m = /^@(key|unique|index)\\((.*)\\)$/s.exec(raw);\n if (!m || m[1] === undefined || m[2] === undefined) continue;\n const flag = m[1] as 'key' | 'unique' | 'index';\n for (const propName of splitArgs(m[2])) {\n const prop = properties.find((p) => p.name === propName);\n if (prop) prop[flag] = true;\n }\n }\n return { properties, constraints };\n}\n\n// ---------------------------------------------------------------------------\n// Top-level parse\n// ---------------------------------------------------------------------------\n\n/**\n * Parse `.pg` source into a {@link PgSchema}. Tolerant by design: malformed\n * or unrecognized declarations are skipped, not fatal; `implements` clauses\n * are expanded into node properties (node-declared properties win on name\n * collisions, matching the server's table layout).\n */\nexport function parsePgSchema(source: string): PgSchema {\n const src = stripComments(source);\n const interfaces: PgInterfaceType[] = [];\n const nodes: (PgNodeType & { properties: PgProperty[] })[] = [];\n const edges: PgEdgeType[] = [];\n\n const headRe = /\\b(interface|node|edge)\\s+([A-Za-z_]\\w*)/g;\n let m: RegExpExecArray | null;\n while ((m = headRe.exec(src)) !== null) {\n const kw = m[1];\n const name = m[2];\n if (kw === undefined || name === undefined) continue;\n let pos = headRe.lastIndex;\n\n if (kw === 'edge') {\n const em = /^\\s*:\\s*([A-Za-z_]\\w*)\\s*->\\s*([A-Za-z_]\\w*)/.exec(src.slice(pos));\n if (!em || em[1] === undefined || em[2] === undefined) continue; // tolerant skip\n pos += em[0].length;\n const { anns, end } = scanAnnotations(src, pos);\n pos = end;\n let body: MutableTypeBody = { properties: [], constraints: [] };\n let braceIdx = pos;\n while (braceIdx < src.length && /\\s/.test(src.charAt(braceIdx))) braceIdx++;\n if (src.charAt(braceIdx) === '{') {\n const blockEnd = findBlockEnd(src, braceIdx);\n body = parseBody(src.slice(braceIdx + 1, blockEnd - 1));\n pos = blockEnd;\n }\n const card = anns.find((a) => a.name === 'card')?.args?.trim();\n const edge: PgEdgeType = {\n name,\n from: em[1],\n to: em[2],\n annotations: anns.map((a) => a.raw),\n properties: body.properties,\n constraints: body.constraints,\n ...(card !== undefined ? { card } : {}),\n };\n edges.push(edge);\n headRe.lastIndex = pos;\n continue;\n }\n\n // interface / node: optional `implements A, B` (node only), then a block.\n let impls: string[] = [];\n // The grammar carries head annotations (`@card`/`@unique` prove the\n // family). `node Account @rename_from(\"User\") { … }` previously hit the\n // tolerant skip and silently dropped the whole declaration.\n // Annotations are consumed (and ignored — migration metadata) on either\n // side of `implements`, through the SAME scanner the body lane uses. It\n // honors nested parens and escaped quotes; a first-`)` regex would\n // truncate `@rename_from(\"User (legacy)\")` and drop the node.\n const skipAnnotations = (): void => {\n pos = scanAnnotations(src, pos).end;\n };\n skipAnnotations();\n if (kw === 'node') {\n const im = /^\\s*implements\\s+([A-Za-z_]\\w*(?:\\s*,\\s*[A-Za-z_]\\w*)*)/.exec(src.slice(pos));\n if (im && im[1] !== undefined) {\n impls = im[1].split(',').map((s) => s.trim());\n pos += im[0].length;\n }\n skipAnnotations();\n }\n let braceIdx = pos;\n while (braceIdx < src.length && /\\s/.test(src.charAt(braceIdx))) braceIdx++;\n if (src.charAt(braceIdx) !== '{') continue; // tolerant skip\n const blockEnd = findBlockEnd(src, braceIdx);\n const body = parseBody(src.slice(braceIdx + 1, blockEnd - 1));\n headRe.lastIndex = blockEnd;\n if (kw === 'interface') {\n interfaces.push({ name, properties: body.properties, constraints: body.constraints });\n } else {\n nodes.push({\n name,\n implements: impls,\n properties: body.properties,\n constraints: body.constraints,\n });\n }\n }\n\n // Expand implements clauses: interface properties precede the node's own,\n // except where the node re-declares a name (node declaration wins).\n for (const node of nodes) {\n if (node.implements.length === 0) continue;\n const own = new Set(node.properties.map((p) => p.name));\n const inherited: PgProperty[] = [];\n for (const ifaceName of node.implements) {\n const iface = interfaces.find((i) => i.name === ifaceName);\n if (!iface) continue; // tolerant: unknown interface\n for (const p of iface.properties) {\n if (!own.has(p.name) && !inherited.some((q) => q.name === p.name)) inherited.push(p);\n }\n }\n node.properties = [...inherited, ...node.properties];\n }\n\n return { interfaces, nodes, edges };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve an edge type's declared endpoint node types. Export edge\n * lines carry bare `from`/`to` ids, so endpoint types come from here. Edge\n * names match exactly first, then case-insensitively (the server matches edge\n * names case-insensitively). Returns `null` for an unknown edge name.\n */\nexport function edgeEndpointTypes(\n schema: PgSchema,\n edgeName: string,\n): { from: string; to: string } | null {\n const lower = edgeName.toLowerCase();\n const edge =\n schema.edges.find((e) => e.name === edgeName) ??\n schema.edges.find((e) => e.name.toLowerCase() === lower);\n return edge ? { from: edge.from, to: edge.to } : null;\n}\n\n/**\n * Stable fingerprint of `.pg` source for the adapter revision stamp: FNV-1a\n * 64-bit over the UTF-8 bytes of the source, as 16 lowercase hex chars.\n *\n * Pure and browser-safe (no `node:crypto`). Hashes the source **verbatim**:\n * any textual change — including comments or whitespace — changes the\n * fingerprint, which is the conservative choice for drift detection.\n */\nexport function schemaFingerprint(source: string): string {\n const MASK64 = 0xffffffffffffffffn;\n let h = 0xcbf29ce484222325n;\n const bytes = new TextEncoder().encode(source);\n for (const b of bytes) {\n h ^= BigInt(b);\n h = (h * 0x100000001b3n) & MASK64;\n }\n return h.toString(16).padStart(16, '0');\n}\n\nexport interface BigIntKeyWarning {\n /** Node or edge type name. */\n type: string;\n /** The hazardous property. */\n property: string;\n}\n\n/**\n * Find `I64`/`U64` properties used as identity (`@key` or named `id`). The\n * HTTP path emits native JSON numbers even past ±2^53, where `JSON.parse`\n * silently rounds them, so two distinct big-int ids can collapse. Surface\n * these hazards before loading.\n */\nexport function bigIntKeyWarnings(schema: PgSchema): BigIntKeyWarning[] {\n const out: BigIntKeyWarning[] = [];\n for (const t of [...schema.nodes, ...schema.edges]) {\n for (const p of t.properties) {\n if ((p.type === 'I64' || p.type === 'U64') && (p.key || p.name === 'id')) {\n out.push({ type: t.name, property: p.name });\n }\n }\n }\n return out;\n}\n","/**\n * Export-line classification and normalization.\n *\n * `/export` streams NDJSON — one JSON object per line, `data` passed through\n * **verbatim** by the SDK. This module turns those lines into orbit\n * `GraphNode`/`GraphEdge` values:\n *\n * - ids are namespaced through the adapter identity codec (`encodeSourceId`),\n * - the node/edge KIND is injected as {@link ORBIT_TYPE_KEY} — namespaced so\n * a schema's own `type` property passes through as ordinary data,\n * - edge endpoint types are resolved from the `.pg` schema because edge lines\n * carry bare `from`/`to` ids,\n * - attr values are normalized to the query-path string forms so\n * generated types and temporal dimensions see one encoding\n * regardless of read path:\n * * `Date` — export sends **days since Unix epoch** (number) →\n * `'YYYY-MM-DD'` (UTC)\n * * `DateTime` — export sends **epoch milliseconds** (number) →\n * ISO 8601 (`'YYYY-MM-DDTHH:MM:SS.mmmZ'`)\n * * `Blob` — inline internal blobs arrive as `'base64:<data>'` →\n * `'data:application/octet-stream;base64,<data>'`;\n * external-URI refs pass through verbatim\n * * everything else — verbatim.\n *\n * Non-finite float sentinels (`'NaN'`/`'Infinity'`/`'-Infinity'`) are a\n * **query-path-only** encoding: a non-finite stored float aborts `/export`\n * server-side, so export-loaded data never contains the sentinels.\n * This module therefore does NOT special-case them.\n */\n\nimport type { GraphEdge, GraphNode } from '@modernrelay/orbit-core';\nimport { encodeSourceId } from './idCodec';\nimport {\n edgeEndpointTypes,\n type PgEdgeType,\n type PgNodeType,\n type PgProperty,\n type PgSchema,\n type PgType,\n} from './pgSchema';\n\n// ---------------------------------------------------------------------------\n// Errors\n// ---------------------------------------------------------------------------\n\n/** An edge line names an edge type the `.pg` schema does not declare. */\nexport class UnknownEdgeTypeError extends Error {\n override readonly name = 'UnknownEdgeTypeError';\n readonly edgeName: string;\n constructor(edgeName: string) {\n super(\n `Unknown edge type '${edgeName}': not declared in the graph schema, so its ` +\n `endpoint node types cannot be resolved.`,\n );\n this.edgeName = edgeName;\n }\n}\n\n/** An export line is structurally unusable (e.g. missing/non-string `data.id`). */\nexport class InvalidExportLineError extends Error {\n override readonly name = 'InvalidExportLineError';\n constructor(message: string) {\n super(message);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Classification\n// ---------------------------------------------------------------------------\n\nexport interface NodeExportLine {\n kind: 'node';\n type: string;\n data: Record<string, unknown>;\n}\n\nexport interface EdgeExportLine {\n kind: 'edge';\n edge: string;\n from: string;\n to: string;\n data: Record<string, unknown>;\n}\n\nexport type ClassifiedExportLine = NodeExportLine | EdgeExportLine | { kind: 'unknown' };\n\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === 'object' && v !== null && !Array.isArray(v);\n}\n\n/**\n * Classify one parsed export line using the adapter's wire shapes:\n * - node line: `{\"type\": \"<NodeType>\", \"data\": {\"id\", …props}}`\n * - edge line: `{\"edge\": \"<EdgeName>\", \"from\": <src id>, \"to\": <dst id>, \"data\": {\"id\", …props}}`\n * Anything else is `{ kind: 'unknown' }`.\n */\nexport function classifyExportLine(line: unknown): ClassifiedExportLine {\n if (!isRecord(line) || !isRecord(line['data'])) return { kind: 'unknown' };\n const data = line['data'];\n if (\n typeof line['edge'] === 'string' &&\n typeof line['from'] === 'string' &&\n typeof line['to'] === 'string'\n ) {\n return { kind: 'edge', edge: line['edge'], from: line['from'], to: line['to'], data };\n }\n if (typeof line['type'] === 'string') {\n return { kind: 'node', type: line['type'], data };\n }\n return { kind: 'unknown' };\n}\n\n// ---------------------------------------------------------------------------\n// Value normalization\n// ---------------------------------------------------------------------------\n\nconst MS_PER_DAY = 86_400_000;\n\n/** Format an epoch-day count as `'YYYY-MM-DD'` (UTC). Handles negative days. */\nfunction formatEpochDay(days: number): string {\n const d = new Date(days * MS_PER_DAY);\n const t = d.getTime();\n if (!Number.isFinite(t)) return String(days); // out of Date range — leave a readable value\n const y = d.getUTCFullYear();\n const year =\n y < 0\n ? `-${String(-y).padStart(6, '0')}`\n : y > 9999\n ? `+${String(y).padStart(6, '0')}`\n : String(y).padStart(4, '0');\n const month = String(d.getUTCMonth() + 1).padStart(2, '0');\n const day = String(d.getUTCDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n}\n\nfunction normalizeValue(type: PgType | undefined, value: unknown): unknown {\n if (type === undefined || value === null || value === undefined) return value;\n if (type === 'Date' && typeof value === 'number' && Number.isInteger(value)) {\n return formatEpochDay(value);\n }\n if (type === 'DateTime' && typeof value === 'number' && Number.isFinite(value)) {\n const d = new Date(value);\n return Number.isFinite(d.getTime()) ? d.toISOString() : value;\n }\n if (type === 'Blob' && typeof value === 'string' && value.startsWith('base64:')) {\n return `data:application/octet-stream;base64,${value.slice('base64:'.length)}`;\n }\n return value;\n}\n\nfunction propTypeMap(t: PgNodeType | PgEdgeType | undefined): ReadonlyMap<string, PgType> {\n const map = new Map<string, PgType>();\n if (t) for (const p of t.properties as readonly PgProperty[]) map.set(p.name, p.type);\n return map;\n}\n\nfunction normalizeData(\n data: Record<string, unknown>,\n types: ReadonlyMap<string, PgType>,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n // Source data can carry '__proto__' as an own key (JSON.parse creates it);\n // defineProperty writes the own property, never the setter.\n for (const [k, v] of Object.entries(data)) {\n Object.defineProperty(out, k, {\n value: normalizeValue(types.get(k), v),\n enumerable: true,\n writable: true,\n configurable: true,\n });\n }\n return out;\n}\n\nfunction requireStringId(data: Record<string, unknown>, what: string): string {\n const id = data['id'];\n if (typeof id !== 'string') {\n throw new InvalidExportLineError(\n `${what} export line has ${id === undefined ? 'no' : 'a non-string'} 'data.id' — ` +\n `cannot build a stable orbit id; data.id must be a string.`,\n );\n }\n return id;\n}\n\n// ---------------------------------------------------------------------------\n// Node / edge normalization\n// ---------------------------------------------------------------------------\n\n/**\n * The adapter's node/edge KIND discriminator key.\n *\n * Namespaced on purpose: the adapter injects this field into someone else's\n * data, so it takes the awkward key and leaves the generic word `type` to the\n * schema author, who means something real by it (`Company.type = investor`).\n * A colon is illegal in `.pg` identifiers, so no schema property can ever\n * claim this key — the collision class is closed by construction, and a\n * source-declared `type` now flows through untouched with no preservation\n * mechanism, no warning, and no schema migration. Same convention as\n * GraphQL's `__typename` / JSON-LD's `@type`.\n */\nexport const ORBIT_TYPE_KEY = 'orbit:type';\n\n/**\n * Normalize a node export line to a `GraphNode`:\n * `id = encodeSourceId(type, data.id)`, `attrs = { …data, 'orbit:type' }`\n * with value normalization driven by the schema's property types. A node type\n * absent from the schema is tolerated — its attrs pass through verbatim\n * (identity never needs the schema on the node path).\n */\nexport function normalizeNode(\n line: { type: string; data: Record<string, unknown> },\n schema: PgSchema,\n): GraphNode {\n const nodeType = schema.nodes.find((n) => n.name === line.type);\n const id = encodeSourceId(line.type, requireStringId(line.data, `Node '${line.type}'`));\n return {\n id,\n // The discriminator is adapter-owned identity metadata. It lands LAST so\n // a forward-compatible export field literally named `orbit:type` cannot\n // forge the value the generated attrs unions promise.\n attrs: { ...normalizeData(line.data, propTypeMap(nodeType)), [ORBIT_TYPE_KEY]: line.type },\n };\n}\n\n/**\n * Normalize an edge export line to a `GraphEdge`:\n * `id = encodeSourceId(edge, data.id)`; `source`/`target` namespace the bare\n * `from`/`to` ids with the endpoint node types resolved from the schema.\n * Throws {@link UnknownEdgeTypeError} when the schema does not declare\n * the edge — endpoint identity cannot be constructed without it.\n */\nexport function normalizeEdge(\n line: { edge: string; from: string; to: string; data: Record<string, unknown> },\n schema: PgSchema,\n): GraphEdge {\n const endpoints = edgeEndpointTypes(schema, line.edge);\n if (endpoints === null) throw new UnknownEdgeTypeError(line.edge);\n const lower = line.edge.toLowerCase();\n const edgeType =\n schema.edges.find((e) => e.name === line.edge) ??\n schema.edges.find((e) => e.name.toLowerCase() === lower);\n const id = encodeSourceId(line.edge, requireStringId(line.data, `Edge '${line.edge}'`));\n return {\n id,\n source: encodeSourceId(endpoints.from, line.from),\n target: encodeSourceId(endpoints.to, line.to),\n // As on nodes, the adapter's resolved edge name lands last and always\n // wins the discriminator key; a source `type` property is ordinary data.\n attrs: { ...normalizeData(line.data, propTypeMap(edgeType)), [ORBIT_TYPE_KEY]: line.edge },\n };\n}\n"]}