@nicia-ai/typegraph 0.66.1 → 0.67.1
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/CHANGELOG.md +24 -0
- package/README.md +15 -0
- package/dist/backend/drizzle/engine/index.cjs +6 -6
- package/dist/backend/drizzle/engine/index.js +1 -1
- package/dist/backend/postgres/index.cjs +15 -15
- package/dist/backend/postgres/index.js +1 -1
- package/dist/backend/postgres/pglite-store.cjs +1 -1
- package/dist/backend/postgres/pglite-store.js +1 -1
- package/dist/backend/postgres/pglite.cjs +3 -3
- package/dist/backend/postgres/pglite.js +2 -2
- package/dist/backend/sqlite/index.cjs +14 -14
- package/dist/backend/sqlite/index.js +1 -1
- package/dist/backend/sqlite/libsql.cjs +6 -6
- package/dist/backend/sqlite/libsql.js +1 -1
- package/dist/backend/sqlite/local-store.cjs +1 -1
- package/dist/backend/sqlite/local-store.js +1 -1
- package/dist/backend/sqlite/local.cjs +3 -3
- package/dist/backend/sqlite/local.js +2 -2
- package/dist/{chunk-TR7QTODF.js → chunk-55DGFZYC.js} +3 -3
- package/dist/{chunk-TR7QTODF.js.map → chunk-55DGFZYC.js.map} +1 -1
- package/dist/{chunk-WB55URNM.js → chunk-6CKSTY2D.js} +7 -3
- package/dist/chunk-6CKSTY2D.js.map +1 -0
- package/dist/{chunk-ZONDBN6H.js → chunk-6DY26DPE.js} +3 -3
- package/dist/{chunk-ZONDBN6H.js.map → chunk-6DY26DPE.js.map} +1 -1
- package/dist/{chunk-YHMXF7OZ.js → chunk-6J3VUPI6.js} +3 -3
- package/dist/{chunk-YHMXF7OZ.js.map → chunk-6J3VUPI6.js.map} +1 -1
- package/dist/{chunk-MN325MG4.cjs → chunk-7MQL7FEN.cjs} +11 -2
- package/dist/chunk-7MQL7FEN.cjs.map +1 -0
- package/dist/{chunk-WWSYGZED.cjs → chunk-E6XL3KMZ.cjs} +6 -6
- package/dist/{chunk-WWSYGZED.cjs.map → chunk-E6XL3KMZ.cjs.map} +1 -1
- package/dist/{chunk-SSDHR2C2.js → chunk-EFSXK3DW.js} +3 -3
- package/dist/{chunk-SSDHR2C2.js.map → chunk-EFSXK3DW.js.map} +1 -1
- package/dist/{chunk-2DJKHZQ4.js → chunk-EORFWD6O.js} +11 -2
- package/dist/chunk-EORFWD6O.js.map +1 -0
- package/dist/{chunk-Y4X6ODVY.cjs → chunk-FS2GVO2T.cjs} +56 -56
- package/dist/{chunk-Y4X6ODVY.cjs.map → chunk-FS2GVO2T.cjs.map} +1 -1
- package/dist/{chunk-K7YACILO.cjs → chunk-GXHEGNI6.cjs} +9 -9
- package/dist/{chunk-K7YACILO.cjs.map → chunk-GXHEGNI6.cjs.map} +1 -1
- package/dist/{chunk-BX42F7IJ.cjs → chunk-SSDLQPMY.cjs} +7 -2
- package/dist/chunk-SSDLQPMY.cjs.map +1 -0
- package/dist/{chunk-ANMCKLZQ.cjs → chunk-ZRIXU33S.cjs} +12 -12
- package/dist/{chunk-ANMCKLZQ.cjs.map → chunk-ZRIXU33S.cjs.map} +1 -1
- package/dist/graph-merge/index.cjs +500 -26
- package/dist/graph-merge/index.cjs.map +1 -1
- package/dist/graph-merge/index.d.cts +384 -2
- package/dist/graph-merge/index.d.ts +384 -2
- package/dist/graph-merge/index.js +485 -15
- package/dist/graph-merge/index.js.map +1 -1
- package/dist/index.cjs +63 -63
- package/dist/index.js +3 -3
- package/dist/{local-store-impl-ERPNYOCL.js → local-store-impl-CCMWTLGY.js} +6 -6
- package/dist/{local-store-impl-ERPNYOCL.js.map → local-store-impl-CCMWTLGY.js.map} +1 -1
- package/dist/{local-store-impl-OUINMCYI.cjs → local-store-impl-GI6S4J6B.cjs} +9 -9
- package/dist/{local-store-impl-OUINMCYI.cjs.map → local-store-impl-GI6S4J6B.cjs.map} +1 -1
- package/dist/{pglite-store-impl-Z3SOOP75.cjs → pglite-store-impl-HAPAJUIO.cjs} +9 -9
- package/dist/{pglite-store-impl-Z3SOOP75.cjs.map → pglite-store-impl-HAPAJUIO.cjs.map} +1 -1
- package/dist/{pglite-store-impl-DUJBQZS5.js → pglite-store-impl-HDLFOZWS.js} +6 -6
- package/dist/{pglite-store-impl-DUJBQZS5.js.map → pglite-store-impl-HDLFOZWS.js.map} +1 -1
- package/dist/schema/index.cjs +27 -27
- package/dist/schema/index.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-2DJKHZQ4.js.map +0 -1
- package/dist/chunk-BX42F7IJ.cjs.map +0 -1
- package/dist/chunk-MN325MG4.cjs.map +0 -1
- package/dist/chunk-WB55URNM.js.map +0 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkFS2GVO2T_cjs = require('../chunk-FS2GVO2T.cjs');
|
|
4
4
|
require('../chunk-76OB5RSH.cjs');
|
|
5
5
|
var chunk3HMEGR7U_cjs = require('../chunk-3HMEGR7U.cjs');
|
|
6
6
|
require('../chunk-2XQYRCPM.cjs');
|
|
@@ -11,7 +11,7 @@ require('../chunk-I7SBZJI2.cjs');
|
|
|
11
11
|
require('../chunk-G7OKJDMG.cjs');
|
|
12
12
|
require('../chunk-R255UE5U.cjs');
|
|
13
13
|
require('../chunk-MRUOOAIQ.cjs');
|
|
14
|
-
var
|
|
14
|
+
var chunkSSDLQPMY_cjs = require('../chunk-SSDLQPMY.cjs');
|
|
15
15
|
require('../chunk-6YKISECL.cjs');
|
|
16
16
|
var chunkICOTLZBV_cjs = require('../chunk-ICOTLZBV.cjs');
|
|
17
17
|
var chunkEBQX7MYL_cjs = require('../chunk-EBQX7MYL.cjs');
|
|
@@ -1867,7 +1867,7 @@ async function computeSchemaComponent(store) {
|
|
|
1867
1867
|
chunk6B3LQUYG_cjs.storeBackend(store),
|
|
1868
1868
|
store.graphId
|
|
1869
1869
|
);
|
|
1870
|
-
return
|
|
1870
|
+
return chunkSSDLQPMY_cjs.computeSchemaHash(chunkSSDLQPMY_cjs.serializeSchema(store.graph, version));
|
|
1871
1871
|
}
|
|
1872
1872
|
function byDigestEntry(left, right) {
|
|
1873
1873
|
const byKind = chunkNYWU6CBZ_cjs.compareStrings(left.kind, right.kind);
|
|
@@ -2084,6 +2084,14 @@ async function lineageDeltaSinceAnchor(baseStore, base) {
|
|
|
2084
2084
|
|
|
2085
2085
|
// src/graph-merge/working-copy.ts
|
|
2086
2086
|
var CLONE_IMPORT_BATCH_SIZE = 1e3;
|
|
2087
|
+
async function assertWorkingCopyMatchesBase(workingCopy, base) {
|
|
2088
|
+
const workingCopyVersion = await computeBaseVersion(workingCopy);
|
|
2089
|
+
if (workingCopyVersion === base) return;
|
|
2090
|
+
throw new BranchError(
|
|
2091
|
+
"Working copy does not match its base: computeBaseVersion disagrees between the host-created store and the base store it was forked from. The host may have forked a different revision or the source may have advanced while the fork was being allocated.",
|
|
2092
|
+
{ details: { workingCopyVersion, baseVersion: base } }
|
|
2093
|
+
);
|
|
2094
|
+
}
|
|
2087
2095
|
function cloneWorkingCopyStrategy(makeBackend) {
|
|
2088
2096
|
return cloneWorkingCopyWithGraphStrategy(
|
|
2089
2097
|
makeBackend,
|
|
@@ -2101,7 +2109,7 @@ function cloneWorkingCopyWithGraphStrategy(makeBackend, graphForClone) {
|
|
|
2101
2109
|
create: async (baseStore) => {
|
|
2102
2110
|
const backend = await makeBackend();
|
|
2103
2111
|
try {
|
|
2104
|
-
const [freshStore] = await
|
|
2112
|
+
const [freshStore] = await chunkFS2GVO2T_cjs.createStoreWithSchema(
|
|
2105
2113
|
graphForClone(baseStore),
|
|
2106
2114
|
backend,
|
|
2107
2115
|
{
|
|
@@ -2235,14 +2243,8 @@ function forkedWorkingCopyStrategy(options) {
|
|
|
2235
2243
|
{ details: { inheritedTables, connectedTables } }
|
|
2236
2244
|
);
|
|
2237
2245
|
}
|
|
2238
|
-
const forkStore =
|
|
2239
|
-
|
|
2240
|
-
if (forkVersion !== base) {
|
|
2241
|
-
throw new BranchError(
|
|
2242
|
-
"Fork does not match its base: computeBaseVersion disagrees between the forked store and the base store it was forked from. This fence proves base-token equality (schema plus a revision anchor, or a live-content fingerprint) at the instant the fork was taken, not byte-for-byte physical identity \u2014 a working-copy fork is trusted to provide that.",
|
|
2243
|
-
{ details: { forkVersion, baseVersion: base } }
|
|
2244
|
-
);
|
|
2245
|
-
}
|
|
2246
|
+
const forkStore = chunkFS2GVO2T_cjs.createStore(baseStore.graph, backend, forkOptions);
|
|
2247
|
+
await assertWorkingCopyMatchesBase(forkStore, base);
|
|
2246
2248
|
return forkStore;
|
|
2247
2249
|
} catch (error) {
|
|
2248
2250
|
try {
|
|
@@ -2305,11 +2307,7 @@ async function branch(baseStore, makeBackend, options, strategy) {
|
|
|
2305
2307
|
}
|
|
2306
2308
|
async function captureBranchForkState(store) {
|
|
2307
2309
|
try {
|
|
2308
|
-
|
|
2309
|
-
const schemaAnchor = schemaRow === void 0 ? void 0 : { version: schemaRow.version, hash: schemaRow.schema_hash };
|
|
2310
|
-
const lineage = chunk6B3LQUYG_cjs.resolveLineage(store);
|
|
2311
|
-
const forkRevision = lineage === void 0 ? void 0 : await lineage.revision(chunk6B3LQUYG_cjs.storeBackend(store));
|
|
2312
|
-
return { schemaAnchor, forkRevision };
|
|
2310
|
+
return await readBranchForkState(store);
|
|
2313
2311
|
} catch (error) {
|
|
2314
2312
|
try {
|
|
2315
2313
|
await chunk6B3LQUYG_cjs.storeBackend(store).close();
|
|
@@ -2318,6 +2316,13 @@ async function captureBranchForkState(store) {
|
|
|
2318
2316
|
throw error;
|
|
2319
2317
|
}
|
|
2320
2318
|
}
|
|
2319
|
+
async function readBranchForkState(store) {
|
|
2320
|
+
const schemaRow = await chunk6B3LQUYG_cjs.storeBackend(store).getActiveSchema(store.graphId);
|
|
2321
|
+
const schemaAnchor = schemaRow === void 0 ? void 0 : { version: schemaRow.version, hash: schemaRow.schema_hash };
|
|
2322
|
+
const lineage = chunk6B3LQUYG_cjs.resolveLineage(store);
|
|
2323
|
+
const forkRevision = lineage === void 0 ? void 0 : await lineage.revision(chunk6B3LQUYG_cjs.storeBackend(store));
|
|
2324
|
+
return { schemaAnchor, forkRevision };
|
|
2325
|
+
}
|
|
2321
2326
|
|
|
2322
2327
|
// src/graph-merge/evolution-target.ts
|
|
2323
2328
|
function evolutionPlanningTarget(store, plan) {
|
|
@@ -2426,8 +2431,8 @@ async function assertMergeTransactionPristine(target, txBackend) {
|
|
|
2426
2431
|
|
|
2427
2432
|
// src/graph-merge/apply-callbacks.ts
|
|
2428
2433
|
var NODE_READ_NAMES = [
|
|
2429
|
-
...
|
|
2430
|
-
...
|
|
2434
|
+
...chunkFS2GVO2T_cjs.NODE_TEMPORAL_READ_NAMES,
|
|
2435
|
+
...chunkFS2GVO2T_cjs.CURRENT_ONLY_READ_NAMES
|
|
2431
2436
|
];
|
|
2432
2437
|
function pickReadMethods(source, names) {
|
|
2433
2438
|
return Object.fromEntries(names.map((name) => [name, source[name]]));
|
|
@@ -2445,12 +2450,12 @@ function mergePlanReadContext(tx, graph) {
|
|
|
2445
2450
|
kind,
|
|
2446
2451
|
pickReadMethods(
|
|
2447
2452
|
chunkBXHAPCQG_cjs.requireDefined(tx.edges[kind]),
|
|
2448
|
-
|
|
2453
|
+
chunkFS2GVO2T_cjs.EDGE_TEMPORAL_READ_NAMES
|
|
2449
2454
|
)
|
|
2450
2455
|
])
|
|
2451
2456
|
),
|
|
2452
2457
|
..."identity" in tx ? {
|
|
2453
|
-
identity: pickReadMethods(tx.identity,
|
|
2458
|
+
identity: pickReadMethods(tx.identity, chunkFS2GVO2T_cjs.IDENTITY_READ_NAMES)
|
|
2454
2459
|
} : {}
|
|
2455
2460
|
};
|
|
2456
2461
|
}
|
|
@@ -5280,7 +5285,7 @@ async function openProvenanceStore(...args) {
|
|
|
5280
5285
|
throw provenanceGraphIdCollision(graph.id, targetGraphId, claim.reason);
|
|
5281
5286
|
}
|
|
5282
5287
|
}
|
|
5283
|
-
const [store] = await
|
|
5288
|
+
const [store] = await chunkFS2GVO2T_cjs.createStoreWithSchema(graph, backend);
|
|
5284
5289
|
return store;
|
|
5285
5290
|
}
|
|
5286
5291
|
async function claimSidecarOwnership(backend, graph, targetGraphId) {
|
|
@@ -5350,14 +5355,14 @@ async function inspectSidecarGraphId(port, graph, targetGraphId) {
|
|
|
5350
5355
|
if (activeSchema === void 0) {
|
|
5351
5356
|
return { state: "refuse", reason: "application-graph" };
|
|
5352
5357
|
}
|
|
5353
|
-
const ownedHash = await
|
|
5354
|
-
|
|
5358
|
+
const ownedHash = await chunkSSDLQPMY_cjs.computeSchemaHash(
|
|
5359
|
+
chunkSSDLQPMY_cjs.serializeSchema(graph, activeSchema.version)
|
|
5355
5360
|
);
|
|
5356
5361
|
if (activeSchema.schema_hash === ownedHash) {
|
|
5357
5362
|
return { state: "refuse", reason: "unowned-exact-schema-graph" };
|
|
5358
5363
|
}
|
|
5359
|
-
const legacyHash = await
|
|
5360
|
-
|
|
5364
|
+
const legacyHash = await chunkSSDLQPMY_cjs.computeSchemaHash(
|
|
5365
|
+
chunkSSDLQPMY_cjs.serializeSchema(buildProvenanceGraph(targetGraphId), activeSchema.version)
|
|
5361
5366
|
);
|
|
5362
5367
|
if (activeSchema.schema_hash !== legacyHash) {
|
|
5363
5368
|
return { state: "refuse", reason: "application-graph" };
|
|
@@ -10263,6 +10268,471 @@ function asReviewError(error) {
|
|
|
10263
10268
|
);
|
|
10264
10269
|
}
|
|
10265
10270
|
|
|
10271
|
+
// src/graph-merge/durable-branch.ts
|
|
10272
|
+
async function branchDurable(baseStore, strategy, options) {
|
|
10273
|
+
let base;
|
|
10274
|
+
let id;
|
|
10275
|
+
try {
|
|
10276
|
+
base = await computeBaseVersion(baseStore);
|
|
10277
|
+
id = options?.id ?? asBranchId(chunk6B3LQUYG_cjs.generateId());
|
|
10278
|
+
} catch (error) {
|
|
10279
|
+
return chunkHQU2SE74_cjs.err(
|
|
10280
|
+
new BranchError(
|
|
10281
|
+
"Failed to stamp the durable branch base version for the base store.",
|
|
10282
|
+
{ cause: error }
|
|
10283
|
+
)
|
|
10284
|
+
);
|
|
10285
|
+
}
|
|
10286
|
+
let created;
|
|
10287
|
+
try {
|
|
10288
|
+
created = await strategy.create(baseStore, base, id);
|
|
10289
|
+
} catch (error) {
|
|
10290
|
+
return chunkHQU2SE74_cjs.err(
|
|
10291
|
+
new BranchError(
|
|
10292
|
+
"Failed to create durable working-copy branch of base store",
|
|
10293
|
+
{ cause: error }
|
|
10294
|
+
)
|
|
10295
|
+
);
|
|
10296
|
+
}
|
|
10297
|
+
let forkState;
|
|
10298
|
+
let definitionHash;
|
|
10299
|
+
try {
|
|
10300
|
+
await assertDurableWorkingCopyMatchesBase(baseStore, created.store, base);
|
|
10301
|
+
forkState = await readBranchForkState(created.store);
|
|
10302
|
+
definitionHash = await chunkSSDLQPMY_cjs.getGraphDefinitionHash(created.store.graph);
|
|
10303
|
+
} catch (error) {
|
|
10304
|
+
return chunkHQU2SE74_cjs.err(await abandonAllocation(strategy, created, id, error));
|
|
10305
|
+
}
|
|
10306
|
+
const origin = {
|
|
10307
|
+
graphId: created.store.graphId,
|
|
10308
|
+
definitionHash,
|
|
10309
|
+
branchId: id,
|
|
10310
|
+
base,
|
|
10311
|
+
schemaAnchor: forkState.schemaAnchor,
|
|
10312
|
+
forkRevision: forkState.forkRevision
|
|
10313
|
+
};
|
|
10314
|
+
try {
|
|
10315
|
+
await strategy.seal(created.descriptor, origin);
|
|
10316
|
+
} catch (error) {
|
|
10317
|
+
return chunkHQU2SE74_cjs.err(await abandonAllocation(strategy, created, id, error));
|
|
10318
|
+
}
|
|
10319
|
+
const branch2 = {
|
|
10320
|
+
id,
|
|
10321
|
+
base,
|
|
10322
|
+
store: created.store,
|
|
10323
|
+
close: coalescedDurableClose(created.store, created.access),
|
|
10324
|
+
...forkState.schemaAnchor === void 0 ? { schemaAnchor: void 0 } : { schemaAnchor: forkState.schemaAnchor },
|
|
10325
|
+
...forkState.forkRevision === void 0 ? {} : { forkRevision: forkState.forkRevision }
|
|
10326
|
+
};
|
|
10327
|
+
const descriptor = {
|
|
10328
|
+
kind: strategy.type,
|
|
10329
|
+
version: strategy.version,
|
|
10330
|
+
graphId: created.store.graphId,
|
|
10331
|
+
definitionHash,
|
|
10332
|
+
branchId: id,
|
|
10333
|
+
base,
|
|
10334
|
+
store: created.descriptor,
|
|
10335
|
+
...forkState.schemaAnchor === void 0 ? { schemaAnchor: void 0 } : { schemaAnchor: forkState.schemaAnchor },
|
|
10336
|
+
...forkState.forkRevision === void 0 ? {} : { forkRevision: forkState.forkRevision }
|
|
10337
|
+
};
|
|
10338
|
+
return chunkHQU2SE74_cjs.ok({ branch: branch2, descriptor });
|
|
10339
|
+
}
|
|
10340
|
+
async function assertDurableWorkingCopyMatchesBase(baseStore, workingCopy, base) {
|
|
10341
|
+
const sourceVersionBeforeDiff = await computeBaseVersion(baseStore);
|
|
10342
|
+
if (sourceVersionBeforeDiff !== base) {
|
|
10343
|
+
throw new BranchError(
|
|
10344
|
+
"Base store changed while the durable working copy was being allocated.",
|
|
10345
|
+
{
|
|
10346
|
+
details: {
|
|
10347
|
+
baseVersion: base,
|
|
10348
|
+
liveBaseVersion: sourceVersionBeforeDiff
|
|
10349
|
+
}
|
|
10350
|
+
}
|
|
10351
|
+
);
|
|
10352
|
+
}
|
|
10353
|
+
if (workingCopy.graphId !== baseStore.graphId) {
|
|
10354
|
+
throw new BranchError(
|
|
10355
|
+
"Durable working copy belongs to a different graph than its base store.",
|
|
10356
|
+
{
|
|
10357
|
+
details: {
|
|
10358
|
+
expectedGraphId: baseStore.graphId,
|
|
10359
|
+
receivedGraphId: workingCopy.graphId
|
|
10360
|
+
}
|
|
10361
|
+
}
|
|
10362
|
+
);
|
|
10363
|
+
}
|
|
10364
|
+
const workingCopyVersion = await computeBaseVersion(workingCopy);
|
|
10365
|
+
if (workingCopyVersion === base) return;
|
|
10366
|
+
if (schemaComponentOf(workingCopyVersion) !== schemaComponentOf(base)) {
|
|
10367
|
+
throw new BranchError(
|
|
10368
|
+
"Durable working copy schema does not match its stamped base schema.",
|
|
10369
|
+
{
|
|
10370
|
+
details: {
|
|
10371
|
+
baseSchema: schemaComponentOf(base),
|
|
10372
|
+
workingCopySchema: schemaComponentOf(workingCopyVersion)
|
|
10373
|
+
}
|
|
10374
|
+
}
|
|
10375
|
+
);
|
|
10376
|
+
}
|
|
10377
|
+
const diff = await diffAgainstBase(baseStore, workingCopy, false);
|
|
10378
|
+
const sourceVersionAfterDiff = await computeBaseVersion(baseStore);
|
|
10379
|
+
if (sourceVersionAfterDiff !== base) {
|
|
10380
|
+
throw new BranchError(
|
|
10381
|
+
"Base store changed while the durable working copy was being verified.",
|
|
10382
|
+
{
|
|
10383
|
+
details: {
|
|
10384
|
+
baseVersion: base,
|
|
10385
|
+
liveBaseVersion: sourceVersionAfterDiff
|
|
10386
|
+
}
|
|
10387
|
+
}
|
|
10388
|
+
);
|
|
10389
|
+
}
|
|
10390
|
+
const changed = diff.nodes.new.length > 0 || diff.nodes.modified.length > 0 || diff.nodes.deleted.length > 0 || diff.nodes.windowed.length > 0 || diff.edges.new.length > 0 || diff.edges.modified.length > 0 || diff.edges.deleted.length > 0 || diff.edges.windowed.length > 0 || diff.identity.new.length > 0 || diff.identity.retracted.length > 0;
|
|
10391
|
+
if (!changed) return;
|
|
10392
|
+
throw new BranchError(
|
|
10393
|
+
"Durable working copy does not match its base: the stamped graph state differs.",
|
|
10394
|
+
{
|
|
10395
|
+
details: {
|
|
10396
|
+
baseVersion: base,
|
|
10397
|
+
workingCopyVersion,
|
|
10398
|
+
changedNodes: diff.nodes.new.length + diff.nodes.modified.length + diff.nodes.deleted.length + diff.nodes.windowed.length,
|
|
10399
|
+
changedEdges: diff.edges.new.length + diff.edges.modified.length + diff.edges.deleted.length + diff.edges.windowed.length,
|
|
10400
|
+
changedIdentityAssertions: diff.identity.new.length + diff.identity.retracted.length
|
|
10401
|
+
}
|
|
10402
|
+
}
|
|
10403
|
+
);
|
|
10404
|
+
}
|
|
10405
|
+
async function reopenDurableBranch(graph, descriptor, strategy) {
|
|
10406
|
+
const refusal = durableDescriptorRefusal(descriptor, strategy);
|
|
10407
|
+
if (refusal !== void 0) return chunkHQU2SE74_cjs.err(refusal);
|
|
10408
|
+
if (descriptor.graphId !== graph.id) {
|
|
10409
|
+
return chunkHQU2SE74_cjs.err(
|
|
10410
|
+
new BranchError(
|
|
10411
|
+
`Durable branch descriptor belongs to graph "${descriptor.graphId}", not "${graph.id}".`,
|
|
10412
|
+
{
|
|
10413
|
+
details: { descriptorGraphId: descriptor.graphId, graphId: graph.id }
|
|
10414
|
+
}
|
|
10415
|
+
)
|
|
10416
|
+
);
|
|
10417
|
+
}
|
|
10418
|
+
let reopened;
|
|
10419
|
+
try {
|
|
10420
|
+
reopened = await strategy.reopen(graph, descriptor.store);
|
|
10421
|
+
} catch (error) {
|
|
10422
|
+
return chunkHQU2SE74_cjs.err(
|
|
10423
|
+
new BranchError(
|
|
10424
|
+
`Failed to reopen durable working copy for branch "${descriptor.branchId}": ${describeCause(error)}`,
|
|
10425
|
+
{
|
|
10426
|
+
cause: error,
|
|
10427
|
+
details: { branchId: descriptor.branchId, graphId: graph.id },
|
|
10428
|
+
suggestion: "Confirm the persistent working copy still exists and is reachable by the strategy, then retry."
|
|
10429
|
+
}
|
|
10430
|
+
)
|
|
10431
|
+
);
|
|
10432
|
+
}
|
|
10433
|
+
const { access, store, origin } = reopened;
|
|
10434
|
+
try {
|
|
10435
|
+
if (store.graphId !== graph.id) {
|
|
10436
|
+
throw new BranchError(
|
|
10437
|
+
`Reopened working copy belongs to graph "${store.graphId}", not "${graph.id}".`,
|
|
10438
|
+
{
|
|
10439
|
+
details: {
|
|
10440
|
+
branchId: descriptor.branchId,
|
|
10441
|
+
reopenedGraphId: store.graphId,
|
|
10442
|
+
graphId: graph.id
|
|
10443
|
+
}
|
|
10444
|
+
}
|
|
10445
|
+
);
|
|
10446
|
+
}
|
|
10447
|
+
const descriptorOrigin = durableOriginOfDescriptor(descriptor);
|
|
10448
|
+
if (!durableOriginsEqual(descriptorOrigin, origin)) {
|
|
10449
|
+
throw new BranchError(
|
|
10450
|
+
`Durable branch descriptor does not match the working copy the host attested for its store locator: the descriptor's TypeGraph fences disagree with the origin recorded at fork. This is a tampered, relabeled, or wrong-branch descriptor.`,
|
|
10451
|
+
{
|
|
10452
|
+
details: {
|
|
10453
|
+
branchId: descriptor.branchId,
|
|
10454
|
+
descriptorOrigin,
|
|
10455
|
+
attestedOrigin: origin
|
|
10456
|
+
}
|
|
10457
|
+
}
|
|
10458
|
+
);
|
|
10459
|
+
}
|
|
10460
|
+
await assertGraphMatchesAttestedOrigin(graph, origin);
|
|
10461
|
+
return chunkHQU2SE74_cjs.ok(rebuildBranch(store, access, descriptor));
|
|
10462
|
+
} catch (error) {
|
|
10463
|
+
await closeDurableQuietly(store, access);
|
|
10464
|
+
return chunkHQU2SE74_cjs.err(
|
|
10465
|
+
error instanceof BranchError ? error : new BranchError(
|
|
10466
|
+
`Failed to reattach durable working copy for branch "${descriptor.branchId}": ${describeCause(error)}`,
|
|
10467
|
+
{ cause: error, details: { branchId: descriptor.branchId } }
|
|
10468
|
+
)
|
|
10469
|
+
);
|
|
10470
|
+
}
|
|
10471
|
+
}
|
|
10472
|
+
async function destroyDurableBranch(descriptor, strategy) {
|
|
10473
|
+
const refusal = durableDescriptorRefusal(descriptor, strategy);
|
|
10474
|
+
if (refusal !== void 0) return chunkHQU2SE74_cjs.err(refusal);
|
|
10475
|
+
try {
|
|
10476
|
+
await strategy.destroy(
|
|
10477
|
+
descriptor.store,
|
|
10478
|
+
durableOriginOfDescriptor(descriptor)
|
|
10479
|
+
);
|
|
10480
|
+
return chunkHQU2SE74_cjs.ok(void 0);
|
|
10481
|
+
} catch (error) {
|
|
10482
|
+
return chunkHQU2SE74_cjs.err(
|
|
10483
|
+
new BranchError(
|
|
10484
|
+
`Failed to destroy durable working copy for branch "${descriptor.branchId}": ${describeCause(error)}`,
|
|
10485
|
+
{ cause: error, details: { branchId: descriptor.branchId } }
|
|
10486
|
+
)
|
|
10487
|
+
);
|
|
10488
|
+
}
|
|
10489
|
+
}
|
|
10490
|
+
async function abandonAllocation(strategy, created, branchId, cause) {
|
|
10491
|
+
await closeDurableQuietly(created.store, created.access);
|
|
10492
|
+
let aborted = false;
|
|
10493
|
+
try {
|
|
10494
|
+
await strategy.abort(created.descriptor);
|
|
10495
|
+
aborted = true;
|
|
10496
|
+
} catch {
|
|
10497
|
+
}
|
|
10498
|
+
return new BranchError(
|
|
10499
|
+
aborted ? `Failed to finish durable working-copy branch "${branchId}" after the host allocated it; the opened store was closed and the persistent allocation was aborted.` : `Failed to finish durable working-copy branch "${branchId}" after the host allocated it; the opened store was closed, but the host could NOT abort the persistent allocation, which may survive as an orphan.`,
|
|
10500
|
+
{
|
|
10501
|
+
cause,
|
|
10502
|
+
details: {
|
|
10503
|
+
branchId,
|
|
10504
|
+
strategyType: strategy.type,
|
|
10505
|
+
allocationAborted: aborted
|
|
10506
|
+
},
|
|
10507
|
+
...aborted ? {} : {
|
|
10508
|
+
suggestion: "The strategy's abort failed, so the persistent allocation for `details.branchId` may still exist. Inspect or remove it through the strategy's operator tooling."
|
|
10509
|
+
}
|
|
10510
|
+
}
|
|
10511
|
+
);
|
|
10512
|
+
}
|
|
10513
|
+
function durableDescriptorRefusal(descriptor, strategy) {
|
|
10514
|
+
if (typeof descriptor !== "object" || descriptor === null || Array.isArray(descriptor)) {
|
|
10515
|
+
return new BranchError("Durable branch descriptor must be a JSON object.", {
|
|
10516
|
+
details: { strategyType: strategy.type }
|
|
10517
|
+
});
|
|
10518
|
+
}
|
|
10519
|
+
const record = descriptor;
|
|
10520
|
+
if (record["kind"] !== strategy.type) {
|
|
10521
|
+
return new BranchError(
|
|
10522
|
+
`Durable branch descriptor belongs to strategy "${String(record["kind"])}", not "${strategy.type}".`,
|
|
10523
|
+
{
|
|
10524
|
+
details: {
|
|
10525
|
+
descriptorKind: record["kind"],
|
|
10526
|
+
strategyType: strategy.type
|
|
10527
|
+
}
|
|
10528
|
+
}
|
|
10529
|
+
);
|
|
10530
|
+
}
|
|
10531
|
+
if (record["version"] !== strategy.version) {
|
|
10532
|
+
return new BranchError(
|
|
10533
|
+
`Durable branch descriptor version ${String(record["version"])} is not supported by strategy "${strategy.type}" (expected ${strategy.version}).`,
|
|
10534
|
+
{
|
|
10535
|
+
details: {
|
|
10536
|
+
descriptorVersion: record["version"],
|
|
10537
|
+
strategyVersion: strategy.version
|
|
10538
|
+
}
|
|
10539
|
+
}
|
|
10540
|
+
);
|
|
10541
|
+
}
|
|
10542
|
+
for (const key of [
|
|
10543
|
+
"graphId",
|
|
10544
|
+
"definitionHash",
|
|
10545
|
+
"branchId",
|
|
10546
|
+
"base"
|
|
10547
|
+
]) {
|
|
10548
|
+
const value = record[key];
|
|
10549
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
10550
|
+
return new BranchError(
|
|
10551
|
+
`Durable branch descriptor is malformed: "${key}" must be a non-empty string.`,
|
|
10552
|
+
{ details: { key, strategyType: strategy.type } }
|
|
10553
|
+
);
|
|
10554
|
+
}
|
|
10555
|
+
}
|
|
10556
|
+
if (!("store" in record)) {
|
|
10557
|
+
return new BranchError(
|
|
10558
|
+
"Durable branch descriptor is malformed: no strategy store locator.",
|
|
10559
|
+
{ details: { strategyType: strategy.type } }
|
|
10560
|
+
);
|
|
10561
|
+
}
|
|
10562
|
+
if (record["schemaAnchor"] !== void 0) {
|
|
10563
|
+
const anchor = record["schemaAnchor"];
|
|
10564
|
+
if (typeof anchor !== "object" || anchor === null || typeof anchor["version"] !== "number" || typeof anchor["hash"] !== "string") {
|
|
10565
|
+
return new BranchError(
|
|
10566
|
+
"Durable branch descriptor is malformed: schemaAnchor must be { version: number; hash: string }.",
|
|
10567
|
+
{ details: { strategyType: strategy.type } }
|
|
10568
|
+
);
|
|
10569
|
+
}
|
|
10570
|
+
}
|
|
10571
|
+
if (record["forkRevision"] !== void 0 && typeof record["forkRevision"] !== "string") {
|
|
10572
|
+
return new BranchError(
|
|
10573
|
+
"Durable branch descriptor is malformed: forkRevision must be a string.",
|
|
10574
|
+
{ details: { strategyType: strategy.type } }
|
|
10575
|
+
);
|
|
10576
|
+
}
|
|
10577
|
+
return void 0;
|
|
10578
|
+
}
|
|
10579
|
+
function durableOriginOfDescriptor(descriptor) {
|
|
10580
|
+
return {
|
|
10581
|
+
graphId: descriptor.graphId,
|
|
10582
|
+
definitionHash: descriptor.definitionHash,
|
|
10583
|
+
branchId: descriptor.branchId,
|
|
10584
|
+
base: descriptor.base,
|
|
10585
|
+
schemaAnchor: descriptor.schemaAnchor,
|
|
10586
|
+
forkRevision: descriptor.forkRevision
|
|
10587
|
+
};
|
|
10588
|
+
}
|
|
10589
|
+
function durableOriginsEqual(descriptor, attested) {
|
|
10590
|
+
return descriptor.graphId === attested.graphId && descriptor.definitionHash === attested.definitionHash && descriptor.branchId === attested.branchId && descriptor.base === attested.base && schemaAnchorsEqual(descriptor.schemaAnchor, attested.schemaAnchor) && descriptor.forkRevision === attested.forkRevision;
|
|
10591
|
+
}
|
|
10592
|
+
function schemaAnchorsEqual(left, right) {
|
|
10593
|
+
if (left === void 0 || right === void 0) return left === right;
|
|
10594
|
+
return left.version === right.version && left.hash === right.hash;
|
|
10595
|
+
}
|
|
10596
|
+
async function assertGraphMatchesAttestedOrigin(graph, origin) {
|
|
10597
|
+
if (graph.id !== origin.graphId) {
|
|
10598
|
+
throw new BranchError(
|
|
10599
|
+
`The supplied graph "${graph.id}" is not the graph the durable working copy was forked from ("${origin.graphId}").`,
|
|
10600
|
+
{
|
|
10601
|
+
details: {
|
|
10602
|
+
graphId: graph.id,
|
|
10603
|
+
attestedGraphId: origin.graphId
|
|
10604
|
+
}
|
|
10605
|
+
}
|
|
10606
|
+
);
|
|
10607
|
+
}
|
|
10608
|
+
const graphHash = await chunkSSDLQPMY_cjs.getGraphDefinitionHash(graph);
|
|
10609
|
+
if (graphHash !== origin.definitionHash) {
|
|
10610
|
+
throw new BranchError(
|
|
10611
|
+
`The supplied graph definition is incompatible with the durable working copy's host-attested fork-time definition: it hashes differently, so it is a different graph definition even though it reuses graph id "${graph.id}". This identity check is attested independently of any committed schema anchor, so it also protects an unmanaged working copy.`,
|
|
10612
|
+
{
|
|
10613
|
+
details: {
|
|
10614
|
+
graphId: graph.id,
|
|
10615
|
+
attestedDefinitionHash: origin.definitionHash,
|
|
10616
|
+
graphHash
|
|
10617
|
+
}
|
|
10618
|
+
}
|
|
10619
|
+
);
|
|
10620
|
+
}
|
|
10621
|
+
}
|
|
10622
|
+
function rebuildBranch(store, access, descriptor) {
|
|
10623
|
+
return {
|
|
10624
|
+
id: descriptor.branchId,
|
|
10625
|
+
base: descriptor.base,
|
|
10626
|
+
store,
|
|
10627
|
+
close: coalescedDurableClose(store, access),
|
|
10628
|
+
schemaAnchor: descriptor.schemaAnchor,
|
|
10629
|
+
...descriptor.forkRevision === void 0 ? {} : { forkRevision: descriptor.forkRevision }
|
|
10630
|
+
};
|
|
10631
|
+
}
|
|
10632
|
+
function coalescedDurableClose(store, access) {
|
|
10633
|
+
const closeBackend = coalescedWorkingCopyClose(store);
|
|
10634
|
+
let complete = false;
|
|
10635
|
+
let accessReleased = false;
|
|
10636
|
+
let inFlight;
|
|
10637
|
+
return async () => {
|
|
10638
|
+
if (complete) return;
|
|
10639
|
+
inFlight ??= (async () => {
|
|
10640
|
+
await closeBackend();
|
|
10641
|
+
if (access.kind === "exclusive" && !accessReleased) {
|
|
10642
|
+
await access.release();
|
|
10643
|
+
accessReleased = true;
|
|
10644
|
+
}
|
|
10645
|
+
complete = true;
|
|
10646
|
+
})().finally(() => {
|
|
10647
|
+
inFlight = void 0;
|
|
10648
|
+
});
|
|
10649
|
+
await inFlight;
|
|
10650
|
+
};
|
|
10651
|
+
}
|
|
10652
|
+
async function closeDurableQuietly(store, access) {
|
|
10653
|
+
try {
|
|
10654
|
+
await coalescedDurableClose(store, access)();
|
|
10655
|
+
} catch {
|
|
10656
|
+
}
|
|
10657
|
+
}
|
|
10658
|
+
|
|
10659
|
+
// src/graph-merge/durable-merge.ts
|
|
10660
|
+
async function applyDurableMergePlan(args) {
|
|
10661
|
+
const { branch: branch2, descriptor, plan, strategy, target } = args;
|
|
10662
|
+
const options = args.options ?? {};
|
|
10663
|
+
const refusal = durableDescriptorRefusal(descriptor, strategy);
|
|
10664
|
+
if (refusal !== void 0) {
|
|
10665
|
+
return chunkHQU2SE74_cjs.err(
|
|
10666
|
+
new MergeError("Durable merge descriptor validation failed.", {
|
|
10667
|
+
cause: refusal
|
|
10668
|
+
})
|
|
10669
|
+
);
|
|
10670
|
+
}
|
|
10671
|
+
let artifact;
|
|
10672
|
+
const descriptorOrigin = durableOriginOfDescriptor(descriptor);
|
|
10673
|
+
try {
|
|
10674
|
+
artifact = await validateMergePlanForTarget(target, plan);
|
|
10675
|
+
const branchOrigin = {
|
|
10676
|
+
graphId: branch2.store.graphId,
|
|
10677
|
+
definitionHash: await chunkSSDLQPMY_cjs.getGraphDefinitionHash(branch2.store.graph),
|
|
10678
|
+
branchId: branch2.id,
|
|
10679
|
+
base: branch2.base,
|
|
10680
|
+
schemaAnchor: branch2.schemaAnchor,
|
|
10681
|
+
forkRevision: branch2.forkRevision
|
|
10682
|
+
};
|
|
10683
|
+
if (!durableOriginsEqual(branchOrigin, descriptorOrigin)) {
|
|
10684
|
+
throw new MergeError(
|
|
10685
|
+
"The durable branch handle does not match the descriptor supplied for native merge.",
|
|
10686
|
+
{
|
|
10687
|
+
details: {
|
|
10688
|
+
branchOrigin,
|
|
10689
|
+
descriptorOrigin
|
|
10690
|
+
}
|
|
10691
|
+
}
|
|
10692
|
+
);
|
|
10693
|
+
}
|
|
10694
|
+
} catch (error) {
|
|
10695
|
+
return chunkHQU2SE74_cjs.err(
|
|
10696
|
+
error instanceof MergeError ? error : new MergeError(
|
|
10697
|
+
`Durable merge validation failed: ${describeCause(error)}`,
|
|
10698
|
+
{ cause: error }
|
|
10699
|
+
)
|
|
10700
|
+
);
|
|
10701
|
+
}
|
|
10702
|
+
const usePortableApply = () => applyMergePlan(target, artifact, options);
|
|
10703
|
+
const hasCallbacks = options.beforeApply !== void 0 || options.afterApply !== void 0;
|
|
10704
|
+
if (strategy.merge === void 0 || hasCallbacks || artifact.provenance.persist) {
|
|
10705
|
+
return usePortableApply();
|
|
10706
|
+
}
|
|
10707
|
+
let nativeResult;
|
|
10708
|
+
try {
|
|
10709
|
+
nativeResult = await strategy.merge({
|
|
10710
|
+
target,
|
|
10711
|
+
branch: branch2,
|
|
10712
|
+
descriptor: descriptor.store,
|
|
10713
|
+
expectedOrigin: descriptorOrigin,
|
|
10714
|
+
plan: artifact
|
|
10715
|
+
});
|
|
10716
|
+
} catch (error) {
|
|
10717
|
+
return chunkHQU2SE74_cjs.err(
|
|
10718
|
+
new MergeError(
|
|
10719
|
+
`Host-native durable merge failed: ${describeCause(error)}`,
|
|
10720
|
+
{
|
|
10721
|
+
cause: error,
|
|
10722
|
+
suggestion: "Inspect the host-native merge state before retrying. TypeGraph does not run the portable fallback after an uncertain or failed native attempt because the host may have applied a partial change."
|
|
10723
|
+
}
|
|
10724
|
+
)
|
|
10725
|
+
);
|
|
10726
|
+
}
|
|
10727
|
+
if (nativeResult.outcome === "unsupported") return usePortableApply();
|
|
10728
|
+
return chunkHQU2SE74_cjs.ok(
|
|
10729
|
+
reportFromArtifact(artifact, nativeResult.merged, [
|
|
10730
|
+
...artifact.review.warnings,
|
|
10731
|
+
...nativeResult.warnings ?? []
|
|
10732
|
+
])
|
|
10733
|
+
);
|
|
10734
|
+
}
|
|
10735
|
+
|
|
10266
10736
|
// src/graph-merge/evolution-branch.ts
|
|
10267
10737
|
async function branchForEvolution(store, plan, makeBackend, options) {
|
|
10268
10738
|
try {
|
|
@@ -10322,16 +10792,19 @@ exports.SimilarityUnavailableError = SimilarityUnavailableError;
|
|
|
10322
10792
|
exports.StaleMergePlanError = StaleMergePlanError;
|
|
10323
10793
|
exports.UnsupportedMergePlanVersionError = UnsupportedMergePlanVersionError;
|
|
10324
10794
|
exports.VALIDITY_END_TARGET_PRECEDENCE = VALIDITY_END_TARGET_PRECEDENCE;
|
|
10795
|
+
exports.applyDurableMergePlan = applyDurableMergePlan;
|
|
10325
10796
|
exports.applyMergePlan = applyMergePlan;
|
|
10326
10797
|
exports.applyMergePlanInTransaction = applyMergePlanInTransaction;
|
|
10327
10798
|
exports.asBaseVersion = asBaseVersion;
|
|
10328
10799
|
exports.asBranchId = asBranchId;
|
|
10329
10800
|
exports.branch = branch;
|
|
10801
|
+
exports.branchDurable = branchDurable;
|
|
10330
10802
|
exports.branchForEvolution = branchForEvolution;
|
|
10331
10803
|
exports.captureCandidateWriteSetTarget = captureCandidateWriteSetTarget;
|
|
10332
10804
|
exports.captureCandidateWriteSetTargetForEvolution = captureCandidateWriteSetTargetForEvolution;
|
|
10333
10805
|
exports.cloneWorkingCopyStrategy = cloneWorkingCopyStrategy;
|
|
10334
10806
|
exports.computeBaseVersion = computeBaseVersion;
|
|
10807
|
+
exports.destroyDurableBranch = destroyDurableBranch;
|
|
10335
10808
|
exports.forkedWorkingCopyStrategy = forkedWorkingCopyStrategy;
|
|
10336
10809
|
exports.ingestionBranch = ingestionBranch;
|
|
10337
10810
|
exports.merge = merge;
|
|
@@ -10347,6 +10820,7 @@ exports.planMergeForEvolution = planMergeForEvolution;
|
|
|
10347
10820
|
exports.planMergeIncremental = planMergeIncremental;
|
|
10348
10821
|
exports.provenanceGraphId = provenanceGraphId;
|
|
10349
10822
|
exports.readProvenance = readProvenance;
|
|
10823
|
+
exports.reopenDurableBranch = reopenDurableBranch;
|
|
10350
10824
|
exports.revalidateCandidateWriteSetReview = revalidateCandidateWriteSetReview;
|
|
10351
10825
|
//# sourceMappingURL=index.cjs.map
|
|
10352
10826
|
//# sourceMappingURL=index.cjs.map
|