@modernrelay/orbit-omnigraph 0.13.6 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -39
- package/dist/{chunk-NT5KJVIT.js → chunk-YDRPXYQ7.js} +5 -5
- package/dist/chunk-YDRPXYQ7.js.map +1 -0
- package/dist/codegen-cli.js +14 -14
- package/dist/codegen-cli.js.map +1 -1
- package/dist/index.d.ts +112 -112
- package/dist/index.js +13 -13
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +9 -9
- package/dist/server.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-NT5KJVIT.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { GraphEdge, GraphNode, BeginIngestOptions, IngestSession, Revisions, Gra
|
|
|
2
2
|
import { Omnigraph } from '@modernrelay/omnigraph';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Identity codec
|
|
5
|
+
* Identity codec.
|
|
6
6
|
*
|
|
7
7
|
* Omnigraph node ids are unique **per type only** (derived from the `@key`
|
|
8
8
|
* tuple within each type's table), so unqualified ids are unsound as orbit
|
|
@@ -13,7 +13,7 @@ import { Omnigraph } from '@modernrelay/omnigraph';
|
|
|
13
13
|
* no `(kind, sourceId)` pair can collide with a different pair.
|
|
14
14
|
*
|
|
15
15
|
* Human-readable labels stay separate from identity; there is deliberately no
|
|
16
|
-
* `namespaceIds:false` escape hatch
|
|
16
|
+
* `namespaceIds:false` escape hatch.
|
|
17
17
|
*/
|
|
18
18
|
interface DecodedSourceId {
|
|
19
19
|
/** The namespace component: a node type name or an edge type name. */
|
|
@@ -26,7 +26,7 @@ interface DecodedSourceId {
|
|
|
26
26
|
*
|
|
27
27
|
* - Nodes: `encodeSourceId(NodeType, data.id)`
|
|
28
28
|
* - Edges: `encodeSourceId(EdgeName, data.id)`; endpoints use
|
|
29
|
-
*
|
|
29
|
+
* `encodeSourceId(endpointType, from|to)`.
|
|
30
30
|
*/
|
|
31
31
|
declare function encodeSourceId(kind: string, sourceId: string): string;
|
|
32
32
|
/**
|
|
@@ -38,16 +38,16 @@ declare function encodeSourceId(kind: string, sourceId: string): string;
|
|
|
38
38
|
*/
|
|
39
39
|
declare function decodeSourceId(id: string): DecodedSourceId | null;
|
|
40
40
|
/**
|
|
41
|
-
* Synthetic edge id for **query-derived** subgraphs
|
|
41
|
+
* Synthetic edge id for **query-derived** subgraphs.
|
|
42
42
|
*
|
|
43
43
|
* The GQ grammar has no edge variable, so the query path can never surface
|
|
44
44
|
* physical edge ids; query-derived edges are identified by
|
|
45
45
|
* `['synthetic-edge', EdgeName, source, target]` where `source`/`target` are
|
|
46
46
|
* the already-encoded endpoint node ids.
|
|
47
47
|
*
|
|
48
|
-
* Exported for the future query path
|
|
49
|
-
* Caveats
|
|
50
|
-
* MUST NOT mix synthetic ids with physical `/export` ids for the same edges
|
|
48
|
+
* Exported for the future query path.
|
|
49
|
+
* Caveats: parallel edges collapse under this scheme, and a dataset
|
|
50
|
+
* MUST NOT mix synthetic ids with physical `/export` ids for the same edges
|
|
51
51
|
* one scheme per dataset, never both. Because a synthetic id is a 4-tuple,
|
|
52
52
|
* {@link decodeSourceId} rejects it (`null`), keeping the two schemes
|
|
53
53
|
* mechanically un-confusable.
|
|
@@ -55,13 +55,13 @@ declare function decodeSourceId(id: string): DecodedSourceId | null;
|
|
|
55
55
|
declare function encodeSyntheticEdgeId(edgeName: string, source: string, target: string): string;
|
|
56
56
|
|
|
57
57
|
/**
|
|
58
|
-
* `.pg` schema model + tolerant parser
|
|
58
|
+
* `.pg` schema model + tolerant parser.
|
|
59
59
|
*
|
|
60
60
|
* The adapter needs three things from the graph schema, all served here:
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
61
|
+
* 1. edge endpoint-type resolution (export edge lines carry bare `from`/`to`
|
|
62
|
+
* ids without endpoint types),
|
|
63
|
+
* 2. per-property wire-type knowledge for temporal/blob normalization,
|
|
64
|
+
* 3. a stable schema fingerprint for the export revision stamp.
|
|
65
65
|
*
|
|
66
66
|
* The parser is deliberately tolerant: it extracts the declarations it
|
|
67
67
|
* understands (interfaces, node blocks, edge declarations, properties,
|
|
@@ -141,7 +141,7 @@ interface PgSchema {
|
|
|
141
141
|
*/
|
|
142
142
|
declare function parsePgSchema(source: string): PgSchema;
|
|
143
143
|
/**
|
|
144
|
-
* Resolve an edge type's declared endpoint node types
|
|
144
|
+
* Resolve an edge type's declared endpoint node types. Export edge
|
|
145
145
|
* lines carry bare `from`/`to` ids, so endpoint types come from here. Edge
|
|
146
146
|
* names match exactly first, then case-insensitively (the server matches edge
|
|
147
147
|
* names case-insensitively). Returns `null` for an unknown edge name.
|
|
@@ -151,7 +151,7 @@ declare function edgeEndpointTypes(schema: PgSchema, edgeName: string): {
|
|
|
151
151
|
to: string;
|
|
152
152
|
} | null;
|
|
153
153
|
/**
|
|
154
|
-
* Stable fingerprint of `.pg` source for the
|
|
154
|
+
* Stable fingerprint of `.pg` source for the adapter revision stamp: FNV-1a
|
|
155
155
|
* 64-bit over the UTF-8 bytes of the source, as 16 lowercase hex chars.
|
|
156
156
|
*
|
|
157
157
|
* Pure and browser-safe (no `node:crypto`). Hashes the source **verbatim**:
|
|
@@ -166,44 +166,44 @@ interface BigIntKeyWarning {
|
|
|
166
166
|
property: string;
|
|
167
167
|
}
|
|
168
168
|
/**
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
169
|
+
* Find `I64`/`U64` properties used as identity (`@key` or named `id`). The
|
|
170
|
+
* HTTP path emits native JSON numbers even past ±2^53, where `JSON.parse`
|
|
171
|
+
* silently rounds them, so two distinct big-int ids can collapse. Surface
|
|
172
|
+
* these hazards before loading.
|
|
173
173
|
*/
|
|
174
174
|
declare function bigIntKeyWarnings(schema: PgSchema): BigIntKeyWarning[];
|
|
175
175
|
|
|
176
176
|
/**
|
|
177
|
-
* Export-line classification and normalization
|
|
177
|
+
* Export-line classification and normalization.
|
|
178
178
|
*
|
|
179
179
|
* `/export` streams NDJSON — one JSON object per line, `data` passed through
|
|
180
180
|
* **verbatim** by the SDK. This module turns those lines into orbit
|
|
181
181
|
* `GraphNode`/`GraphEdge` values:
|
|
182
182
|
*
|
|
183
|
-
*
|
|
184
|
-
*
|
|
185
|
-
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
*
|
|
190
|
-
*
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
183
|
+
* - ids are namespaced through the adapter identity codec (`encodeSourceId`),
|
|
184
|
+
* - the node/edge KIND is injected as {@link ORBIT_TYPE_KEY} — namespaced so
|
|
185
|
+
* a schema's own `type` property passes through as ordinary data,
|
|
186
|
+
* - edge endpoint types are resolved from the `.pg` schema because edge lines
|
|
187
|
+
* carry bare `from`/`to` ids,
|
|
188
|
+
* - attr values are normalized to the query-path string forms so
|
|
189
|
+
* generated types and temporal dimensions see one encoding
|
|
190
|
+
* regardless of read path:
|
|
191
|
+
* * `Date` — export sends **days since Unix epoch** (number) →
|
|
192
|
+
* `'YYYY-MM-DD'` (UTC)
|
|
193
|
+
* * `DateTime` — export sends **epoch milliseconds** (number) →
|
|
194
|
+
* ISO 8601 (`'YYYY-MM-DDTHH:MM:SS.mmmZ'`)
|
|
195
|
+
* * `Blob` — inline internal blobs arrive as `'base64:<data>'` →
|
|
196
|
+
* `'data:application/octet-stream;base64,<data>'`;
|
|
197
|
+
* external-URI refs pass through verbatim
|
|
198
|
+
* * everything else — verbatim.
|
|
199
199
|
*
|
|
200
200
|
* Non-finite float sentinels (`'NaN'`/`'Infinity'`/`'-Infinity'`) are a
|
|
201
201
|
* **query-path-only** encoding: a non-finite stored float aborts `/export`
|
|
202
|
-
* server-side, so export-loaded data never contains the sentinels
|
|
202
|
+
* server-side, so export-loaded data never contains the sentinels.
|
|
203
203
|
* This module therefore does NOT special-case them.
|
|
204
204
|
*/
|
|
205
205
|
|
|
206
|
-
/** An edge line names an edge type the `.pg` schema does not declare
|
|
206
|
+
/** An edge line names an edge type the `.pg` schema does not declare. */
|
|
207
207
|
declare class UnknownEdgeTypeError extends Error {
|
|
208
208
|
readonly name = "UnknownEdgeTypeError";
|
|
209
209
|
readonly edgeName: string;
|
|
@@ -230,14 +230,14 @@ type ClassifiedExportLine = NodeExportLine | EdgeExportLine | {
|
|
|
230
230
|
kind: 'unknown';
|
|
231
231
|
};
|
|
232
232
|
/**
|
|
233
|
-
* Classify one parsed export line
|
|
234
|
-
*
|
|
235
|
-
*
|
|
233
|
+
* Classify one parsed export line using the adapter's wire shapes:
|
|
234
|
+
* - node line: `{"type": "<NodeType>", "data": {"id", …props}}`
|
|
235
|
+
* - edge line: `{"edge": "<EdgeName>", "from": <src id>, "to": <dst id>, "data": {"id", …props}}`
|
|
236
236
|
* Anything else is `{ kind: 'unknown' }`.
|
|
237
237
|
*/
|
|
238
238
|
declare function classifyExportLine(line: unknown): ClassifiedExportLine;
|
|
239
239
|
/**
|
|
240
|
-
* The adapter's node/edge KIND discriminator key
|
|
240
|
+
* The adapter's node/edge KIND discriminator key.
|
|
241
241
|
*
|
|
242
242
|
* Namespaced on purpose: the adapter injects this field into someone else's
|
|
243
243
|
* data, so it takes the awkward key and leaves the generic word `type` to the
|
|
@@ -252,8 +252,8 @@ declare const ORBIT_TYPE_KEY = "orbit:type";
|
|
|
252
252
|
/**
|
|
253
253
|
* Normalize a node export line to a `GraphNode`:
|
|
254
254
|
* `id = encodeSourceId(type, data.id)`, `attrs = { …data, 'orbit:type' }`
|
|
255
|
-
* with
|
|
256
|
-
*
|
|
255
|
+
* with value normalization driven by the schema's property types. A node type
|
|
256
|
+
* absent from the schema is tolerated — its attrs pass through verbatim
|
|
257
257
|
* (identity never needs the schema on the node path).
|
|
258
258
|
*/
|
|
259
259
|
declare function normalizeNode(line: {
|
|
@@ -263,8 +263,8 @@ declare function normalizeNode(line: {
|
|
|
263
263
|
/**
|
|
264
264
|
* Normalize an edge export line to a `GraphEdge`:
|
|
265
265
|
* `id = encodeSourceId(edge, data.id)`; `source`/`target` namespace the bare
|
|
266
|
-
* `from`/`to` ids with the endpoint node types resolved from the schema
|
|
267
|
-
*
|
|
266
|
+
* `from`/`to` ids with the endpoint node types resolved from the schema.
|
|
267
|
+
* Throws {@link UnknownEdgeTypeError} when the schema does not declare
|
|
268
268
|
* the edge — endpoint identity cannot be constructed without it.
|
|
269
269
|
*/
|
|
270
270
|
declare function normalizeEdge(line: {
|
|
@@ -275,14 +275,14 @@ declare function normalizeEdge(line: {
|
|
|
275
275
|
}, schema: PgSchema): GraphEdge;
|
|
276
276
|
|
|
277
277
|
/**
|
|
278
|
-
* Public types for the v1 export loader
|
|
278
|
+
* Public types for the v1 export loader.
|
|
279
279
|
*
|
|
280
|
-
* The organizing rule of the v1 adapter
|
|
281
|
-
* queries only ever resolve ids. These types describe that one load path
|
|
280
|
+
* The organizing rule of the v1 adapter: graphs load via `og.export()`;
|
|
281
|
+
* queries only ever resolve ids. These types describe that one load path
|
|
282
282
|
* its options, its ingestion target seam, and its revision-stamped result.
|
|
283
283
|
*/
|
|
284
284
|
|
|
285
|
-
/** Cumulative progress, reported after every appended batch
|
|
285
|
+
/** Cumulative progress, reported after every appended batch. */
|
|
286
286
|
interface OmnigraphLoadProgress {
|
|
287
287
|
/** Export lines consumed so far (nodes + edges + skipped unknowns). */
|
|
288
288
|
lines: number;
|
|
@@ -294,33 +294,33 @@ interface OmnigraphLoadProgress {
|
|
|
294
294
|
bytes: number;
|
|
295
295
|
}
|
|
296
296
|
/**
|
|
297
|
-
*
|
|
298
|
-
*
|
|
297
|
+
* Revision-stamp drift policy: what to do when the branch head observed after
|
|
298
|
+
* the export stream differs from the head observed before it.
|
|
299
299
|
*
|
|
300
300
|
* - `'reject'` (default): abort the session and throw — the graph is left
|
|
301
|
-
*
|
|
301
|
+
* untouched. The right choice for durable/shareable sessions.
|
|
302
302
|
* - `'accept-warn'`: buffer the export, then commit under the canonical final
|
|
303
|
-
*
|
|
304
|
-
*
|
|
303
|
+
* revision once `headAfter` is known; both heads are recorded in `dataRef`
|
|
304
|
+
* and a warning is added when they differ.
|
|
305
305
|
* - `'retry-once'`: abort, restart the whole load once; a second drift
|
|
306
|
-
*
|
|
306
|
+
* rejects.
|
|
307
307
|
*/
|
|
308
308
|
type OmnigraphDriftPolicy = 'reject' | 'accept-warn' | 'retry-once';
|
|
309
309
|
interface OmnigraphSourceOptions {
|
|
310
310
|
/**
|
|
311
311
|
* A **preconfigured** SDK client. In the browser this must be a safe
|
|
312
312
|
* same-origin or public client — this option surface deliberately accepts
|
|
313
|
-
* no `baseUrl`/`token` pair
|
|
313
|
+
* no `baseUrl`/`token` pair: authenticated client construction lives
|
|
314
314
|
* ONLY in `@modernrelay/orbit-omnigraph/server`
|
|
315
315
|
* (`createOmnigraphServerClient`), which is excluded from client bundles.
|
|
316
316
|
*/
|
|
317
317
|
client: Omnigraph;
|
|
318
318
|
/** Cluster graph id; every call is scoped to it via `client.graph(graphId)`. */
|
|
319
319
|
graphId: string;
|
|
320
|
-
/** Branch to export
|
|
320
|
+
/** Branch to export. Default `'main'`. */
|
|
321
321
|
branch?: string;
|
|
322
322
|
/**
|
|
323
|
-
* Partial per-type load
|
|
323
|
+
* Partial per-type load: forwarded as the SDK `ExportInput.typeNames`
|
|
324
324
|
* field (wire form `type_names`). Omit to export every table.
|
|
325
325
|
*/
|
|
326
326
|
typeNames?: readonly string[];
|
|
@@ -330,17 +330,17 @@ interface OmnigraphSourceOptions {
|
|
|
330
330
|
* Whole-load byte budget for the atomic replace. Because atomic staging
|
|
331
331
|
* cannot drain before commit, exceeding this finite cap aborts the load
|
|
332
332
|
* without publishing a partial graph. Must be a positive safe integer.
|
|
333
|
-
* Default
|
|
333
|
+
* Default 512 MiB.
|
|
334
334
|
*/
|
|
335
335
|
maxPendingBytes?: number;
|
|
336
|
-
/**
|
|
336
|
+
/** Revision-stamp drift policy. Default `'reject'`. */
|
|
337
337
|
driftPolicy?: OmnigraphDriftPolicy;
|
|
338
338
|
/** Called after every appended batch with cumulative counts. */
|
|
339
339
|
onProgress?: (p: OmnigraphLoadProgress) => void;
|
|
340
340
|
}
|
|
341
341
|
/**
|
|
342
|
-
*
|
|
343
|
-
* canonical `sourceRevision` hash
|
|
342
|
+
* Branch-based view-state `dataRef`. This is the readable object behind the
|
|
343
|
+
* canonical `sourceRevision` hash, retained so hosts can display or persist the
|
|
344
344
|
* exact coordinates a session was loaded from. `headBefore !== headAfter`
|
|
345
345
|
* only ever appears under `driftPolicy: 'accept-warn'`.
|
|
346
346
|
*/
|
|
@@ -355,8 +355,8 @@ interface OmnigraphDataRef {
|
|
|
355
355
|
schemaFingerprint: string;
|
|
356
356
|
/**
|
|
357
357
|
* Sorted node-type subset of a PARTIAL export; absent = full export.
|
|
358
|
-
* Part of the identity coordinate
|
|
359
|
-
*
|
|
358
|
+
* Part of the identity coordinate: two partial exports at the same head
|
|
359
|
+
* differing only by types must never replay as one another.
|
|
360
360
|
*/
|
|
361
361
|
typeNames?: readonly string[];
|
|
362
362
|
}
|
|
@@ -369,9 +369,9 @@ interface OmnigraphLoadCounts {
|
|
|
369
369
|
}
|
|
370
370
|
interface OmnigraphLoadResult {
|
|
371
371
|
/**
|
|
372
|
-
* The committed source coordinate: the canonical hash of `dataRef
|
|
372
|
+
* The committed source coordinate: the canonical hash of `dataRef`.
|
|
373
373
|
* Stable across identical replays — a second load of a quiescent branch
|
|
374
|
-
* commits idempotently (
|
|
374
|
+
* commits idempotently (the same `{datasetKey, sourceRevision}` publishes
|
|
375
375
|
* nothing).
|
|
376
376
|
*/
|
|
377
377
|
sourceRevision: string;
|
|
@@ -380,14 +380,14 @@ interface OmnigraphLoadResult {
|
|
|
380
380
|
/** `og.health().version` — the server build the load ran against. */
|
|
381
381
|
serverVersion: string;
|
|
382
382
|
/**
|
|
383
|
-
* Non-fatal observations: SDK/server major.minor mismatch
|
|
384
|
-
* drift
|
|
383
|
+
* Non-fatal observations: SDK/server major.minor mismatch, accepted
|
|
384
|
+
* drift, big-int identity hazards, and skipped unknown lines. Never
|
|
385
385
|
* hides a retry or accepted-drift decision.
|
|
386
386
|
*/
|
|
387
387
|
warnings: string[];
|
|
388
388
|
}
|
|
389
389
|
/**
|
|
390
|
-
* Minimal structural ingestion target
|
|
390
|
+
* Minimal structural ingestion target — deliberately decoupled from
|
|
391
391
|
* `GraphInstance`. The loader needs exactly the ingest seam and nothing else,
|
|
392
392
|
* so any object with these members works: a real `GraphInstance` (which
|
|
393
393
|
* satisfies this interface structurally), a recorder, or a headless pipeline.
|
|
@@ -399,48 +399,47 @@ interface IngestTarget {
|
|
|
399
399
|
}
|
|
400
400
|
|
|
401
401
|
/**
|
|
402
|
-
* v1 export loader
|
|
402
|
+
* v1 export loader.
|
|
403
403
|
*
|
|
404
|
-
* The organizing rule
|
|
404
|
+
* The organizing rule: graphs load via `og.export` — one streamed
|
|
405
405
|
* NDJSON pass, edge lines first (lexicographic table-key order), driven
|
|
406
406
|
* straight into a `purpose:'replace'` ingest session on the target. Queries
|
|
407
407
|
* never introduce nodes or edges.
|
|
408
408
|
*
|
|
409
|
-
* Revision stamp
|
|
409
|
+
* Revision stamp: the canonical `sourceRevision` hashes
|
|
410
410
|
* `{ graphId, branch, headBefore, headAfter, schemaFingerprint }` (plus the
|
|
411
|
-
* sorted `typeNames` subset when the export is partial
|
|
411
|
+
* sorted `typeNames` subset when the export is partial), but
|
|
412
412
|
* `headAfter` is only knowable after the stream — while core's
|
|
413
413
|
* `BeginIngestOptions` requires `sourceRevision` up front for a replace
|
|
414
414
|
* session. Resolution: under the rejecting/retrying policies the session
|
|
415
415
|
* begins under the PROVISIONAL revision (the canonical hash with
|
|
416
|
-
* `headAfter
|
|
417
|
-
* captured BEFORE `commit
|
|
416
|
+
* `headAfter:= headBefore`), the stream appends into it, and `headAfter` is
|
|
417
|
+
* captured BEFORE `commit`. `accept-warn` is the exception: normalized
|
|
418
418
|
* batches are buffered until `headAfter` is known, then appended once into a
|
|
419
419
|
* session opened with the canonical FINAL revision:
|
|
420
420
|
*
|
|
421
|
-
*
|
|
422
|
-
*
|
|
423
|
-
*
|
|
424
|
-
*
|
|
425
|
-
*
|
|
426
|
-
*
|
|
427
|
-
*
|
|
428
|
-
*
|
|
429
|
-
*
|
|
421
|
+
* - equal heads → provisional === final; commit cleanly. The session only
|
|
422
|
+
* ever commits a revision whose hash is truthful.
|
|
423
|
+
* - drifted heads → `driftPolicy` decides: `'reject'` aborts the session
|
|
424
|
+
* (graph untouched) and throws {@link OmnigraphDriftError};
|
|
425
|
+
* `'accept-warn'` commits the buffered export under the
|
|
426
|
+
* final revision, records BOTH heads in `dataRef`, and
|
|
427
|
+
* adds a warning;
|
|
428
|
+
* `'retry-once'` aborts and restarts the whole load once
|
|
429
|
+
* (a second drift rejects).
|
|
430
430
|
*
|
|
431
431
|
* This is sound because a replace session is atomic and invisible until
|
|
432
|
-
* commit
|
|
432
|
+
* commit: nothing is published under a revision the policy did not
|
|
433
433
|
* explicitly accept.
|
|
434
434
|
*
|
|
435
|
-
* Error surface
|
|
435
|
+
* Error surface: SDK typed errors never cross this package's public
|
|
436
436
|
* surface — they are mapped to plain `Error`s with a stable `omnigraph:`
|
|
437
437
|
* message prefix.
|
|
438
438
|
*/
|
|
439
439
|
|
|
440
440
|
/**
|
|
441
|
-
*
|
|
442
|
-
*
|
|
443
|
-
* session was aborted, and the target graph is untouched.
|
|
441
|
+
* Raised when a branch moves during export and the configured drift policy
|
|
442
|
+
* rejects the load. The session is aborted and the target graph is untouched.
|
|
444
443
|
*/
|
|
445
444
|
declare class OmnigraphDriftError extends Error {
|
|
446
445
|
readonly name = "OmnigraphDriftError";
|
|
@@ -450,7 +449,7 @@ declare class OmnigraphDriftError extends Error {
|
|
|
450
449
|
readonly headAfter: string;
|
|
451
450
|
constructor(graphId: string, branch: string, headBefore: string, headAfter: string);
|
|
452
451
|
}
|
|
453
|
-
/** The one load path a v1 source exposes
|
|
452
|
+
/** The one load path a v1 source exposes. */
|
|
454
453
|
interface OmnigraphSource {
|
|
455
454
|
/**
|
|
456
455
|
* Stream one export of the configured graph/branch into `target` via a
|
|
@@ -461,26 +460,26 @@ interface OmnigraphSource {
|
|
|
461
460
|
load(target: IngestTarget, signal?: AbortSignal): Promise<OmnigraphLoadResult>;
|
|
462
461
|
}
|
|
463
462
|
/**
|
|
464
|
-
* Create a v1 export-backed data source
|
|
465
|
-
* preconfigured
|
|
463
|
+
* Create a v1 export-backed data source. The client must be
|
|
464
|
+
* preconfigured. In the browser, use a safe same-origin or public client;
|
|
466
465
|
* there is deliberately no `baseUrl`/`token` option here. Authenticated
|
|
467
466
|
* construction lives only in `@modernrelay/orbit-omnigraph/server`.
|
|
468
467
|
*/
|
|
469
468
|
declare function createOmnigraphSource(options: OmnigraphSourceOptions): OmnigraphSource;
|
|
470
469
|
|
|
471
470
|
/**
|
|
472
|
-
*
|
|
471
|
+
* Stored-query `SearchService` integration.
|
|
473
472
|
*
|
|
474
473
|
* A stored query using `bm25`/`fuzzy`/`nearest`/`rrf` with
|
|
475
474
|
* `order { score desc } limit K` returns entity rows plus a score column; this
|
|
476
|
-
* module wires it as a
|
|
475
|
+
* module wires it as a `SearchService` via
|
|
477
476
|
* `og.queries.invoke(name, { params, branch })`, passing
|
|
478
477
|
* `RequestContext.signal` through SDK `CallOptions`. Core performs revision
|
|
479
478
|
* admission — the service only declares `revisionDependencies: ['source']`
|
|
480
479
|
* (results come from the server-side branch, so they are invalidated by a
|
|
481
480
|
* source change, never by client-side model/scope drift).
|
|
482
481
|
*
|
|
483
|
-
* Identity
|
|
482
|
+
* Identity: Omnigraph ids are unique per type only, and a query row
|
|
484
483
|
* carries no type discriminator of its own — so the adapter REQUIRES a
|
|
485
484
|
* caller-supplied column→node-type mapping (`typeOf`), either a
|
|
486
485
|
* `{ column: NodeType }` record keyed by the projection columns that hold
|
|
@@ -489,12 +488,13 @@ declare function createOmnigraphSource(options: OmnigraphSourceOptions): Omnigra
|
|
|
489
488
|
* every other adapter path uses — so results round-trip `decodeSourceId` and
|
|
490
489
|
* match export-loaded node ids exactly.
|
|
491
490
|
*
|
|
492
|
-
*
|
|
493
|
-
*
|
|
494
|
-
* classifies those as `'not-loaded'
|
|
495
|
-
* query to the loaded types, or load the full graph, to avoid the
|
|
491
|
+
* Partial-load caveat: search runs server-side over the whole branch, so a
|
|
492
|
+
* partial export load can return ids outside the loaded set.
|
|
493
|
+
* `activateSearchResult` classifies those as `'not-loaded'`; constrain the
|
|
494
|
+
* stored query to the loaded types, or load the full graph, to avoid the
|
|
495
|
+
* mismatch.
|
|
496
496
|
*
|
|
497
|
-
* Error surface
|
|
497
|
+
* Error surface: SDK typed errors never cross this package's public
|
|
498
498
|
* surface — they rethrow as plain `Error`s with the stable `omnigraph:`
|
|
499
499
|
* prefix. Abort rejections pass through unchanged.
|
|
500
500
|
*/
|
|
@@ -503,44 +503,44 @@ declare function createOmnigraphSource(options: OmnigraphSourceOptions): Omnigra
|
|
|
503
503
|
* projections (`return { $s }`) hold whole-node structs including `id`. */
|
|
504
504
|
type OmnigraphSearchRow = Record<string, unknown>;
|
|
505
505
|
/**
|
|
506
|
-
* The required
|
|
506
|
+
* The required column→node-type mapping:
|
|
507
507
|
*
|
|
508
508
|
* - a record `{ '$s': 'Signal' }` — the FIRST listed column present in a row
|
|
509
|
-
*
|
|
510
|
-
*
|
|
509
|
+
* with a node struct supplies the physical id, encoded under the mapped
|
|
510
|
+
* type name;
|
|
511
511
|
* - or a per-row function returning the node type name — the row's first
|
|
512
|
-
*
|
|
512
|
+
* node-struct column (row key order) supplies the physical id.
|
|
513
513
|
*/
|
|
514
514
|
type OmnigraphSearchTypeOf = ((row: OmnigraphSearchRow) => string) | Readonly<Record<string, string>>;
|
|
515
515
|
interface OmnigraphSearchServiceOptions<N = Record<string, unknown>> {
|
|
516
|
-
/** A **preconfigured** SDK client
|
|
516
|
+
/** A **preconfigured** SDK client — no `baseUrl`/`token` here. */
|
|
517
517
|
client: Omnigraph;
|
|
518
518
|
/** Cluster graph id; the invoke is scoped via `client.graph(graphId)`. */
|
|
519
519
|
graphId: string;
|
|
520
|
-
/** Branch the stored query reads
|
|
520
|
+
/** Branch the stored query reads. Default `'main'`. */
|
|
521
521
|
branch?: string;
|
|
522
522
|
/** Registry name of the stored search query (`POST /queries/{name}`).
|
|
523
523
|
* Invoking a known name works whether or not it is `mcp.expose`d. */
|
|
524
524
|
queryName: string;
|
|
525
|
-
/** Builds the stored query's `params` object from the
|
|
525
|
+
/** Builds the stored query's `params` object from the call.
|
|
526
526
|
* Default: `(q, limit) => ({ q, limit })`. */
|
|
527
527
|
params?: (q: string, limit: number) => Record<string, unknown>;
|
|
528
|
-
/** REQUIRED
|
|
528
|
+
/** REQUIRED mapping from row to node type — see
|
|
529
529
|
* {@link OmnigraphSearchTypeOf}. */
|
|
530
530
|
typeOf: OmnigraphSearchTypeOf;
|
|
531
|
-
/** Column whose value becomes `label` (String
|
|
531
|
+
/** Column whose value becomes `label` (String-coerced when present).
|
|
532
532
|
* Default: the first string-valued column in row key order. */
|
|
533
533
|
labelColumn?: string;
|
|
534
534
|
/** Full custom row→result escape hatch: overrides the default mapping
|
|
535
535
|
* (including `typeOf`/`labelColumn`); return `null` to skip a row. The
|
|
536
|
-
* returned `id` MUST already be
|
|
536
|
+
* returned `id` MUST already be type-qualified via `encodeSourceId`. */
|
|
537
537
|
mapRow?: (row: OmnigraphSearchRow) => SearchResult<N> | null;
|
|
538
538
|
}
|
|
539
539
|
/**
|
|
540
|
-
* Create the
|
|
540
|
+
* Create the stored-query search service. Plug it into core as
|
|
541
541
|
* `services.search`; the instance owns `RequestContext` creation,
|
|
542
542
|
* revision-keyed caching, supersede cancellation, and stale-result rejection
|
|
543
|
-
* at admission
|
|
543
|
+
* at admission.
|
|
544
544
|
*/
|
|
545
545
|
declare function createOmnigraphSearchService<N = Record<string, unknown>>(options: OmnigraphSearchServiceOptions<N>): SearchService<N>;
|
|
546
546
|
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { encodeSourceId, parsePgSchema, schemaFingerprint, bigIntKeyWarnings, classifyExportLine, normalizeNode, normalizeEdge } from './chunk-
|
|
2
|
-
export { InvalidExportLineError, ORBIT_TYPE_KEY, UnknownEdgeTypeError, bigIntKeyWarnings, classifyExportLine, decodeSourceId, edgeEndpointTypes, encodeSourceId, encodeSyntheticEdgeId, normalizeEdge, normalizeNode, parsePgSchema, schemaFingerprint } from './chunk-
|
|
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';
|
|
3
3
|
import { SERVER_VERSION, OmnigraphError } from '@modernrelay/omnigraph';
|
|
4
4
|
import { OrbitOperationError } from '@modernrelay/orbit-core';
|
|
5
5
|
|
|
@@ -14,7 +14,7 @@ var OmnigraphDriftError = class extends Error {
|
|
|
14
14
|
headAfter;
|
|
15
15
|
constructor(graphId, branch, headBefore, headAfter) {
|
|
16
16
|
super(
|
|
17
|
-
`omnigraph: branch '${branch}' of graph '${graphId}' changed during export (head ${headBefore} \u2192 ${headAfter}); session aborted per driftPolicy (
|
|
17
|
+
`omnigraph: branch '${branch}' of graph '${graphId}' changed during export (head ${headBefore} \u2192 ${headAfter}); session aborted per driftPolicy (service:omnigraph-source-changed-during-export)`
|
|
18
18
|
);
|
|
19
19
|
this.graphId = graphId;
|
|
20
20
|
this.branch = branch;
|
|
@@ -101,7 +101,7 @@ function createOmnigraphSource(options) {
|
|
|
101
101
|
for (const hazard of bigIntKeyWarnings(schema)) {
|
|
102
102
|
pushUnique(
|
|
103
103
|
warnings,
|
|
104
|
-
`omnigraph: ${hazard.type}.${hazard.property} is a 64-bit integer used as identity \u2014 JSON parsing silently rounds values past \xB12^53, which can collapse distinct ids
|
|
104
|
+
`omnigraph: ${hazard.type}.${hazard.property} is a 64-bit integer used as identity \u2014 JSON parsing silently rounds values past \xB12^53, which can collapse distinct ids`
|
|
105
105
|
);
|
|
106
106
|
}
|
|
107
107
|
const provisionalRef = {
|
|
@@ -233,7 +233,7 @@ function createOmnigraphSource(options) {
|
|
|
233
233
|
}
|
|
234
234
|
await flush();
|
|
235
235
|
if (unknown > 0) {
|
|
236
|
-
pushUnique(warnings, `omnigraph: skipped ${unknown} unrecognized export line(s)
|
|
236
|
+
pushUnique(warnings, `omnigraph: skipped ${unknown} unrecognized export line(s)`);
|
|
237
237
|
}
|
|
238
238
|
throwIfAborted(signal);
|
|
239
239
|
const headAfter = await newestHead(signal);
|
|
@@ -244,7 +244,7 @@ function createOmnigraphSource(options) {
|
|
|
244
244
|
if (headAfter !== headBefore) {
|
|
245
245
|
pushUnique(
|
|
246
246
|
warnings,
|
|
247
|
-
`omnigraph: branch '${branch}' advanced during export (head ${headBefore} \u2192 ${headAfter}); committed under the canonical final revision per driftPolicy:'accept-warn' \u2014 dataRef records both heads
|
|
247
|
+
`omnigraph: branch '${branch}' advanced during export (head ${headBefore} \u2192 ${headAfter}); committed under the canonical final revision per driftPolicy:'accept-warn' \u2014 dataRef records both heads`
|
|
248
248
|
);
|
|
249
249
|
}
|
|
250
250
|
await commitBuffered(finalRevision);
|
|
@@ -258,11 +258,11 @@ function createOmnigraphSource(options) {
|
|
|
258
258
|
}
|
|
259
259
|
const activeSession = session;
|
|
260
260
|
if (activeSession === void 0) throw new Error("omnigraph: internal missing ingest session");
|
|
261
|
-
await activeSession.abort("omnigraph: source changed during export
|
|
261
|
+
await activeSession.abort("omnigraph: source changed during export");
|
|
262
262
|
if (driftPolicy === "retry-once" && attempt === 1) {
|
|
263
263
|
pushUnique(
|
|
264
264
|
warnings,
|
|
265
|
-
`omnigraph: branch '${branch}' advanced during export (head ${headBefore} \u2192 ${headAfter}); load restarted once per driftPolicy:'retry-once'
|
|
265
|
+
`omnigraph: branch '${branch}' advanced during export (head ${headBefore} \u2192 ${headAfter}); load restarted once per driftPolicy:'retry-once'`
|
|
266
266
|
);
|
|
267
267
|
return { kind: "retry" };
|
|
268
268
|
}
|
|
@@ -294,7 +294,7 @@ function createOmnigraphSource(options) {
|
|
|
294
294
|
const sdk = majorMinor(SERVER_VERSION);
|
|
295
295
|
if (server === null || server !== sdk) {
|
|
296
296
|
warnings.push(
|
|
297
|
-
`omnigraph: server version ${serverVersion} does not match the SDK-pinned server version ${SERVER_VERSION} (major.minor differ) \u2014 SDK behavior is undefined against this server
|
|
297
|
+
`omnigraph: server version ${serverVersion} does not match the SDK-pinned server version ${SERVER_VERSION} (major.minor differ) \u2014 SDK behavior is undefined against this server`
|
|
298
298
|
);
|
|
299
299
|
}
|
|
300
300
|
for (let attempt = 1; ; attempt += 1) {
|
|
@@ -343,7 +343,7 @@ function extractRows(response, queryName) {
|
|
|
343
343
|
const rows = response.rows;
|
|
344
344
|
if (!Array.isArray(rows)) {
|
|
345
345
|
throw new Error(
|
|
346
|
-
`omnigraph: stored query '${queryName}' did not return a read envelope with rows \u2014 the
|
|
346
|
+
`omnigraph: stored query '${queryName}' did not return a read envelope with rows \u2014 the configured search query must be a stored READ query (not a mutation)`
|
|
347
347
|
);
|
|
348
348
|
}
|
|
349
349
|
for (const row of rows) {
|
|
@@ -360,7 +360,7 @@ function resolveIdentity(row, typeOf, queryName) {
|
|
|
360
360
|
const kind = typeOf(row);
|
|
361
361
|
if (typeof kind !== "string" || kind.length === 0) {
|
|
362
362
|
throw new Error(
|
|
363
|
-
`omnigraph: typeOf returned ${JSON.stringify(kind)} for a '${queryName}' search row \u2014
|
|
363
|
+
`omnigraph: typeOf returned ${JSON.stringify(kind)} for a '${queryName}' search row \u2014 typeOf must return a non-empty node type name`
|
|
364
364
|
);
|
|
365
365
|
}
|
|
366
366
|
for (const key of Object.keys(row)) {
|
|
@@ -368,7 +368,7 @@ function resolveIdentity(row, typeOf, queryName) {
|
|
|
368
368
|
if (isNodeStruct(value)) return { kind, sourceId: value.id };
|
|
369
369
|
}
|
|
370
370
|
throw new Error(
|
|
371
|
-
`omnigraph: '${queryName}' search row has no node-struct column (an object with a string 'id') \u2014 project the matched entity bare (return { $s }) so its physical id is available
|
|
371
|
+
`omnigraph: '${queryName}' search row has no node-struct column (an object with a string 'id') \u2014 project the matched entity bare (return { $s }) so its physical id is available`
|
|
372
372
|
);
|
|
373
373
|
}
|
|
374
374
|
for (const [column, kind] of Object.entries(typeOf)) {
|
|
@@ -376,7 +376,7 @@ function resolveIdentity(row, typeOf, queryName) {
|
|
|
376
376
|
if (isNodeStruct(value)) return { kind, sourceId: value.id };
|
|
377
377
|
}
|
|
378
378
|
throw new Error(
|
|
379
|
-
`omnigraph: '${queryName}' search row has no node struct under the mapped column(s) ${JSON.stringify(Object.keys(typeOf))} \u2014 the typeOf record must key the bare-variable
|
|
379
|
+
`omnigraph: '${queryName}' search row has no node struct under the mapped column(s) ${JSON.stringify(Object.keys(typeOf))} \u2014 the typeOf record must key the columns that contain bare-variable node projections`
|
|
380
380
|
);
|
|
381
381
|
}
|
|
382
382
|
function createOmnigraphSearchService(options) {
|