narraeon 0.3.0 → 0.3.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.
|
@@ -43,7 +43,7 @@ export class FileNativeWorldStorageMigrator {
|
|
|
43
43
|
if ((commits.at(-1)?.operationId ?? null) !== current.operationId)
|
|
44
44
|
throw new Error("Current Authority head operation does not match its immutable tip");
|
|
45
45
|
const contexts = await this.#timeline.readAllContexts(worldId);
|
|
46
|
-
|
|
46
|
+
assertCurrentTimelineAuthorityRefs(contexts, commits);
|
|
47
47
|
const checkpoint = await migrateMaterializedCheckpoint(runtimeRoot, commits);
|
|
48
48
|
return this.#migrateCurrentAuthority({
|
|
49
49
|
worldId,
|
|
@@ -81,7 +81,7 @@ export class FileNativeWorldStorageMigrator {
|
|
|
81
81
|
const migratedContexts = await this.#timeline.readAllContexts(worldId);
|
|
82
82
|
if (migratedContexts.length !== callChainContexts)
|
|
83
83
|
throw new Error("Released play timeline migration changed its context closure");
|
|
84
|
-
|
|
84
|
+
assertCurrentTimelineAuthorityRefs(migratedContexts, currentCommits);
|
|
85
85
|
for (const commit of currentCommits)
|
|
86
86
|
await publishImmutableJson(join(runtimeRoot, "play-commits", `${currentCommitDigest(commit)}.json`), commit);
|
|
87
87
|
const checkpoint = await migrateMaterializedCheckpoint(runtimeRoot, currentCommits);
|
|
@@ -316,17 +316,24 @@ function applyReleasedTransition(basis, source, historyAppend, nextMaterials) {
|
|
|
316
316
|
additionalMaterials: structuredClone([...nextMaterials]),
|
|
317
317
|
};
|
|
318
318
|
}
|
|
319
|
-
function
|
|
319
|
+
function assertCurrentTimelineAuthorityRefs(contexts, commits) {
|
|
320
|
+
// Released clone-and-remap forks retained their inherited page/model trace
|
|
321
|
+
// prefix while absorbing the selected source history into the target
|
|
322
|
+
// genesis. Older contexts can therefore carry source-world commit aliases
|
|
323
|
+
// that never belonged to the target Authority. They are immutable display
|
|
324
|
+
// history; only the current context is a continuation boundary owned by the
|
|
325
|
+
// target world and must resolve against its Authority.
|
|
326
|
+
const context = contexts.at(-1);
|
|
327
|
+
if (context === undefined)
|
|
328
|
+
return;
|
|
320
329
|
const heads = new Set(["genesis", ...commits.map(({ head }) => head)]);
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
throw new Error("Released play event references an unknown Authority endpoint");
|
|
329
|
-
}
|
|
330
|
+
if (!heads.has(context.baselineHead) || !heads.has(context.parentHead))
|
|
331
|
+
throw new Error("Released play timeline references an unknown Authority endpoint");
|
|
332
|
+
for (const event of context.events) {
|
|
333
|
+
if ("committedHead" in event &&
|
|
334
|
+
event.committedHead !== undefined &&
|
|
335
|
+
!heads.has(event.committedHead))
|
|
336
|
+
throw new Error("Released play event references an unknown Authority endpoint");
|
|
330
337
|
}
|
|
331
338
|
}
|
|
332
339
|
async function readCurrentAuthority(worldRoot, head) {
|