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
- assertTimelineAuthorityRefs(contexts, commits);
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
- assertTimelineAuthorityRefs(migratedContexts, currentCommits);
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 assertTimelineAuthorityRefs(contexts, commits) {
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
- for (const context of contexts) {
322
- if (!heads.has(context.baselineHead) || !heads.has(context.parentHead))
323
- throw new Error("Released play timeline references an unknown Authority endpoint");
324
- for (const event of context.events) {
325
- if ("committedHead" in event &&
326
- event.committedHead !== undefined &&
327
- !heads.has(event.committedHead))
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) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "narraeon",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "A local-first workspace for living worlds.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",