diff --git a/.changeset/omnigraph-sdk-0-10.md b/.changeset/omnigraph-sdk-0-10.md new file mode 100644 index 0000000..b77d32c --- /dev/null +++ b/.changeset/omnigraph-sdk-0-10.md @@ -0,0 +1,15 @@ +--- +'@modernrelay/orbit-omnigraph': minor +--- + +Omnigraph TS SDK 0.10. + +The adapter (and the demo app) now pin `@modernrelay/omnigraph@0.10.0`. +The SDK surface orbit consumes is signature-stable — `export`, +`invokeQuery`, `ingest`, `snapshot`, `schema`, and every type the adapter +imports are unchanged, and the newly exported `ExportRecord` matches the +NDJSON line shape the loader already parses. The SDK-pinned server +generation moves to 0.10, so the version-drift warning now keys off +0.10.x. Recorded test fixtures were regenerated against a real +omnigraph-server 0.10.0 (the fixture recorder also learned the 0.10 CLI +and wire shapes: per-table load counts, snapshot `datasets` entries). diff --git a/apps/demo/package.json b/apps/demo/package.json index dfadf63..de036fe 100644 --- a/apps/demo/package.json +++ b/apps/demo/package.json @@ -12,7 +12,7 @@ "e2e": "playwright test" }, "dependencies": { - "@modernrelay/omnigraph": "0.9.0", + "@modernrelay/omnigraph": "0.10.0", "@modernrelay/orbit-core": "workspace:*", "@modernrelay/orbit-data": "workspace:*", "@modernrelay/orbit-omnigraph": "workspace:*", diff --git a/fixtures/omnigraph/recorded/commits.json b/fixtures/omnigraph/recorded/commits.json index f5ab271..1719316 100644 --- a/fixtures/omnigraph/recorded/commits.json +++ b/fixtures/omnigraph/recorded/commits.json @@ -1 +1 @@ -{"commits":[{"graph_commit_id":"01KZNTTYMKET9AJ9E2N0TKN9S5","manifest_branch":null,"manifest_version":4,"parent_commit_id":"01KZNTTYCGZXMCCCX8RHKZ7KS2","merged_parent_commit_id":null,"actor_id":"fixture-bot","created_at":1786365442707052},{"graph_commit_id":"01KZNTTYCGZXMCCCX8RHKZ7KS2","manifest_branch":null,"manifest_version":1,"parent_commit_id":null,"merged_parent_commit_id":null,"actor_id":null,"created_at":1786365442448739}]} \ No newline at end of file +{"commits":[{"graph_commit_id":"01M1MCSW52VSBY71WP1S08WRN0","graph_branch":null,"graph_manifest_version":2,"parent_commit_id":"01M1MCSVTPY4990R0A31C2TPHB","merged_parent_commit_id":null,"actor_id":"fixture-bot","created_at":1788464656546250},{"graph_commit_id":"01M1MCSVTPY4990R0A31C2TPHB","graph_branch":null,"graph_manifest_version":1,"parent_commit_id":null,"merged_parent_commit_id":null,"actor_id":null,"created_at":1788464656214342}]} \ No newline at end of file diff --git a/fixtures/omnigraph/recorded/health.json b/fixtures/omnigraph/recorded/health.json index 530b5c6..a806709 100644 --- a/fixtures/omnigraph/recorded/health.json +++ b/fixtures/omnigraph/recorded/health.json @@ -1 +1 @@ -{"status":"ok","version":"0.9.0","internal_schema_version":6} \ No newline at end of file +{"status":"ok","version":"0.10.0","internal_schema_version":6} \ No newline at end of file diff --git a/fixtures/omnigraph/recorded/manifest.json b/fixtures/omnigraph/recorded/manifest.json index 94b3bb0..dcb6bd7 100644 --- a/fixtures/omnigraph/recorded/manifest.json +++ b/fixtures/omnigraph/recorded/manifest.json @@ -1,10 +1,10 @@ { - "recordedAt": "2026-08-10T12:37:23.095Z", - "serverVersion": "0.9.0", + "recordedAt": "2026-09-03T19:44:16.952Z", + "serverVersion": "0.10.0", "graphId": "demo", "branch": "main", - "headBefore": "01KZNTTYMKET9AJ9E2N0TKN9S5", - "headAfter": "01KZNTTYMKET9AJ9E2N0TKN9S5", + "headBefore": "01M1MCSW52VSBY71WP1S08WRN0", + "headAfter": "01M1MCSW52VSBY71WP1S08WRN0", "rowCounts": { "edge:Correlates": 50, "edge:OwnedBy": 60, diff --git a/fixtures/omnigraph/recorded/snapshot.json b/fixtures/omnigraph/recorded/snapshot.json index 0bb692e..665bfc0 100644 --- a/fixtures/omnigraph/recorded/snapshot.json +++ b/fixtures/omnigraph/recorded/snapshot.json @@ -1 +1 @@ -{"branch":"main","manifest_version":4,"internal_schema_version":6,"tables":[{"table_key":"edge:Correlates","table_path":"edges/0000000000000006-0000000000000032","table_version":2,"table_branch":null,"row_count":50},{"table_key":"edge:OwnedBy","table_path":"edges/0000000000000007-0000000000000033","table_version":2,"table_branch":null,"row_count":60},{"table_key":"edge:ParticipatedIn","table_path":"edges/0000000000000008-0000000000000034","table_version":2,"table_branch":null,"row_count":120},{"table_key":"edge:RecordedBy","table_path":"edges/0000000000000009-0000000000000035","table_version":2,"table_branch":null,"row_count":90},{"table_key":"edge:Supports","table_path":"edges/000000000000000a-0000000000000036","table_version":2,"table_branch":null,"row_count":110},{"table_key":"edge:Triggered","table_path":"edges/000000000000000b-0000000000000037","table_version":2,"table_branch":null,"row_count":70},{"table_key":"node:Actor","table_path":"nodes/0000000000000001-000000000000002d","table_version":2,"table_branch":null,"row_count":30},{"table_key":"node:Artifact","table_path":"nodes/0000000000000002-000000000000002e","table_version":2,"table_branch":null,"row_count":60},{"table_key":"node:Decision","table_path":"nodes/0000000000000003-000000000000002f","table_version":2,"table_branch":null,"row_count":60},{"table_key":"node:Signal","table_path":"nodes/0000000000000004-0000000000000030","table_version":2,"table_branch":null,"row_count":60},{"table_key":"node:Trace","table_path":"nodes/0000000000000005-0000000000000031","table_version":2,"table_branch":null,"row_count":90}]} \ No newline at end of file +{"graph_branch":"main","graph_manifest_version":2,"internal_schema_version":6,"datasets":[{"entity_kind":"edge","type_name":"Correlates","dataset_path":"edges/0000000000000006-0000000000000032","published_dataset_version":2,"native_dataset_branch":null,"entity_count":50},{"entity_kind":"edge","type_name":"OwnedBy","dataset_path":"edges/0000000000000007-0000000000000033","published_dataset_version":2,"native_dataset_branch":null,"entity_count":60},{"entity_kind":"edge","type_name":"ParticipatedIn","dataset_path":"edges/0000000000000008-0000000000000034","published_dataset_version":2,"native_dataset_branch":null,"entity_count":120},{"entity_kind":"edge","type_name":"RecordedBy","dataset_path":"edges/0000000000000009-0000000000000035","published_dataset_version":2,"native_dataset_branch":null,"entity_count":90},{"entity_kind":"edge","type_name":"Supports","dataset_path":"edges/000000000000000a-0000000000000036","published_dataset_version":2,"native_dataset_branch":null,"entity_count":110},{"entity_kind":"edge","type_name":"Triggered","dataset_path":"edges/000000000000000b-0000000000000037","published_dataset_version":2,"native_dataset_branch":null,"entity_count":70},{"entity_kind":"node","type_name":"Actor","dataset_path":"nodes/0000000000000001-000000000000002d","published_dataset_version":2,"native_dataset_branch":null,"entity_count":30},{"entity_kind":"node","type_name":"Artifact","dataset_path":"nodes/0000000000000002-000000000000002e","published_dataset_version":2,"native_dataset_branch":null,"entity_count":60},{"entity_kind":"node","type_name":"Decision","dataset_path":"nodes/0000000000000003-000000000000002f","published_dataset_version":2,"native_dataset_branch":null,"entity_count":60},{"entity_kind":"node","type_name":"Signal","dataset_path":"nodes/0000000000000004-0000000000000030","published_dataset_version":2,"native_dataset_branch":null,"entity_count":60},{"entity_kind":"node","type_name":"Trace","dataset_path":"nodes/0000000000000005-0000000000000031","published_dataset_version":2,"native_dataset_branch":null,"entity_count":90}]} \ No newline at end of file diff --git a/packages/omnigraph/package.json b/packages/omnigraph/package.json index 5c38799..f1dac95 100644 --- a/packages/omnigraph/package.json +++ b/packages/omnigraph/package.json @@ -39,7 +39,7 @@ "typecheck": "tsc --noEmit" }, "dependencies": { - "@modernrelay/omnigraph": "0.9.0", + "@modernrelay/omnigraph": "0.10.0", "@modernrelay/orbit-core": "workspace:*" }, "devDependencies": { diff --git a/packages/omnigraph/test/loader.test.ts b/packages/omnigraph/test/loader.test.ts index 14156d5..9397e00 100644 --- a/packages/omnigraph/test/loader.test.ts +++ b/packages/omnigraph/test/loader.test.ts @@ -717,7 +717,7 @@ describe('cancellation and error surface', () => { describe('server and SDK version mismatch surfacing', () => { it('the recorded fixture server and the SDK pin share major.minor — no warning', async () => { // The fixture is regenerated with the same server generation the SDK - // pins (currently 0.9.x) — a mismatch here means the pin and the + // pins (currently 0.10.x) — a mismatch here means the pin and the // fixture drifted apart and one of them needs regenerating/bumping. const { instance, source } = harness(recordedRoutes()); const result = await source.load(instance); @@ -728,15 +728,15 @@ describe('server and SDK version mismatch surfacing', () => { const { instance, source } = harness( recordedRoutes({ 'GET /healthz': json( - JSON.stringify({ status: 'ok', version: '0.10.0', internal_schema_version: 6 }), + JSON.stringify({ status: 'ok', version: '0.11.0', internal_schema_version: 6 }), ), }), ); const result = await source.load(instance); - expect(result.serverVersion).toBe('0.10.0'); - expect(result.warnings.some((w) => w.includes('0.10.0') && w.includes('0.9.0'))).toBe(true); + expect(result.serverVersion).toBe('0.11.0'); + expect(result.warnings.some((w) => w.includes('0.11.0') && w.includes('0.10.0'))).toBe(true); expect(instance.store.getState().nodeCount).toBe(NODE_TOTAL); // load still succeeded }); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 353f7e2..aebf2cc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -39,8 +39,8 @@ importers: apps/demo: dependencies: '@modernrelay/omnigraph': - specifier: 0.9.0 - version: 0.9.0 + specifier: 0.10.0 + version: 0.10.0 '@modernrelay/orbit-core': specifier: workspace:* version: link:../../packages/core @@ -195,8 +195,8 @@ importers: packages/omnigraph: dependencies: '@modernrelay/omnigraph': - specifier: 0.9.0 - version: 0.9.0 + specifier: 0.10.0 + version: 0.10.0 '@modernrelay/orbit-core': specifier: workspace:* version: link:../core @@ -1055,8 +1055,8 @@ packages: '@types/react': '>=16' react: '>=16' - '@modernrelay/omnigraph@0.9.0': - resolution: {integrity: sha512-3FinbZ2knvqj3nnI/Ot/f+8lceQjg0GonLdOVswMSPY3XmXvJ5lDgRo97TO+RcI5ArPesFFNmrSoSL3U6OhKSg==} + '@modernrelay/omnigraph@0.10.0': + resolution: {integrity: sha512-v2iRkfMw4N5MI6V8LHlRDeNZtdyu2otTk+cZpvG/e26BcGVrvWvs0K2M6W9HifvXKk3cm6z9eNyuW9azYQzbIQ==} engines: {node: '>=22'} '@napi-rs/wasm-runtime@1.2.3': @@ -4057,7 +4057,7 @@ snapshots: '@types/react': 18.3.31 react: 18.3.1 - '@modernrelay/omnigraph@0.9.0': {} + '@modernrelay/omnigraph@0.10.0': {} '@napi-rs/wasm-runtime@1.2.3(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0)': dependencies: diff --git a/scripts/omnigraph-fixture.mjs b/scripts/omnigraph-fixture.mjs index 5d0b80b..25c285f 100644 --- a/scripts/omnigraph-fixture.mjs +++ b/scripts/omnigraph-fixture.mjs @@ -19,7 +19,7 @@ * is a true upsert (idempotent re-runs; no @card violations). * 3. Boots `omnigraph-server --cluster... --unauthenticated` on 127.0.0.1:8199, * waits for /healthz, and records the raw HTTP responses (verbatim bytes, - * via curl) for exactly the requests the @modernrelay/omnigraph SDK 0.8.0 + * via curl) for exactly the requests the @modernrelay/omnigraph SDK 0.10.x * issues (graph-scoped paths are prefixed /graphs/): * recorded/health.json GET /healthz * recorded/schema.json GET /graphs/demo/schema @@ -32,7 +32,7 @@ * branch, headBefore/headAfter around the export, per-table rowCounts, * and the verified edge-before-node export line ordering). * - * Requirements: the `omnigraph` CLI and `omnigraph-server` binaries (0.8.x) + * Requirements: the `omnigraph` CLI and `omnigraph-server` binaries (0.10.x) * on PATH, plus curl. When the binaries are absent the script prints a SKIP * message and exits 0 — CI never regenerates fixtures; it consumes the * committed recordings. @@ -313,8 +313,13 @@ async function main() { '--store', STORE, '--as', ACTOR, '--json', ]); const loaded = JSON.parse(loadOut); - console.log(` loaded ${loaded.nodes_loaded} nodes, ${loaded.edges_loaded} edges`); - if (loaded.nodes_loaded !== 300 || loaded.edges_loaded !== 500) { + // 0.10 CLI reports per-table arrays; pre-0.10 had top-level totals. + const sumTables = (tables) => + (tables ?? []).reduce((total, t) => total + (t.entities_loaded ?? 0), 0); + const nodesLoaded = loaded.nodes_loaded ?? sumTables(loaded.nodes); + const edgesLoaded = loaded.edges_loaded ?? sumTables(loaded.edges); + console.log(` loaded ${nodesLoaded} nodes, ${edgesLoaded} edges`); + if (nodesLoaded !== 300 || edgesLoaded !== 500) { throw new Error(`unexpected load counts: ${loadOut}`); } @@ -376,7 +381,16 @@ async function main() { } const snap = JSON.parse(snapshot); - const rowCounts = Object.fromEntries(snap.tables.map((t) => [t.table_key, t.row_count])); + // 0.10 renamed snapshot `tables` (table_key/row_count) to `datasets` + // (entity_kind + type_name / entity_count); keys keep the old + // ':' form either way. + const snapEntries = snap.datasets ?? snap.tables ?? []; + const rowCounts = Object.fromEntries( + snapEntries.map((t) => [ + t.table_key ?? `${t.entity_kind}:${t.type_name}`, + t.row_count ?? t.entity_count, + ]), + ); const manifest = { recordedAt: new Date().toISOString(), serverVersion: JSON.parse(health).version,