map/src/mapPatchWorker.js
2026-08-11 21:51:07 +09:00

2764 lines
130 KiB
JavaScript

import {
buildRawPatchTerrainScoutRequest,
capturePatchTransactionSnapshot,
evaluatePatchDraftCandidate,
generatePatch,
generatePatchAsync,
preparePatchOperationContext,
restorePatchTransactionSnapshot,
} from "./mapPatch.js";
import { collectTransferableBuffers } from "./transferUtils.js";
import { applyCommittedWorldDelta, hashCommittedWorld } from "./committedWorldDelta.js";
export { applyCommittedWorldDelta as applyCommittedMirrorDelta, hashCommittedWorld } from "./committedWorldDelta.js";
let persistentCommittedMirror = null;
let persistentCommittedRevision = -1;
let pendingMirrorBootstrap = null;
const pendingApplyDeltas = new Map();
const rawCandidateWorkerSlots = [];
const rawCandidateWorkerTerminations = [];
let rawCandidateTaskSerial = 0;
function normalizeWorkerTermination(value) {
return Promise.resolve(value).catch(() => undefined);
}
function destroyRawCandidateWorkerSlot(index, reason = "Raw patch candidate worker was terminated.") {
const slot = rawCandidateWorkerSlots[index];
if (!slot) return rawCandidateWorkerTerminations[index] || Promise.resolve();
rawCandidateWorkerSlots[index] = null;
const active = slot.active;
slot.active = null;
if (active) {
const error = new Error(reason);
error.code = "raw-candidate-worker-terminated";
active.reject(error);
}
let termination;
try {
termination = normalizeWorkerTermination(slot.worker?.terminate?.());
} catch {
termination = Promise.resolve();
}
const trackedTermination = termination.finally(() => {
if (rawCandidateWorkerTerminations[index] === trackedTermination) rawCandidateWorkerTerminations[index] = null;
});
rawCandidateWorkerTerminations[index] = trackedTermination;
return trackedTermination;
}
async function ensureRawCandidateWorkerSlot(index) {
if (rawCandidateWorkerTerminations[index]) await rawCandidateWorkerTerminations[index];
const existing = rawCandidateWorkerSlots[index];
if (existing?.worker) return existing;
if (typeof Worker !== "function") {
const error = new Error("Nested module workers are not available in this environment.");
error.code = "raw-candidate-worker-unavailable";
throw error;
}
const worker = new Worker(new URL("./patchCandidateWorker.js", import.meta.url), { type: "module" });
const slot = { worker, active: null, index };
worker.onmessage = (event) => {
const message = event.data || {};
const active = slot.active;
if (!active || Number(message.id) !== active.id) return;
if (message.type === active.progressType) {
active.onProgress?.(active.request, message.progress || {});
return;
}
if (message.type !== active.resultType) return;
slot.active = null;
if (!message.ok) {
const error = new Error(message.error || "Raw patch candidate generation failed.");
error.code = message.code || "raw-patch-candidate-error";
error.stack = message.stack || error.stack;
active.reject(error);
return;
}
active.resolve(message.candidate);
};
worker.onerror = (event) => {
const active = slot.active;
slot.active = null;
const error = new Error(event?.message || "Raw patch candidate worker failed.");
error.code = "raw-candidate-worker-error";
if (active) active.reject(error);
// Do not reuse a worker that raised an uncaught error. The next task in
// this lane waits for termination before constructing a replacement.
destroyRawCandidateWorkerSlot(index, error.message);
};
rawCandidateWorkerSlots[index] = slot;
return slot;
}
async function runRawHelperTask(slotIndex, request, onProgress, kind = "candidate") {
const slot = await ensureRawCandidateWorkerSlot(slotIndex);
if (slot.active) {
const error = new Error(`Raw candidate worker slot ${slotIndex} is unexpectedly busy.`);
error.code = "raw-candidate-worker-busy";
throw error;
}
const id = ++rawCandidateTaskSerial;
const terrainScoutOnly = kind === "terrain-scout";
const draftOnly = kind === "draft";
const resultType = terrainScoutOnly ? "raw-patch-terrain-scout-result" : draftOnly ? "raw-patch-draft-result" : "raw-patch-candidate-result";
const progressType = terrainScoutOnly ? "raw-patch-terrain-scout-progress" : draftOnly ? "raw-patch-draft-progress" : "raw-patch-candidate-progress";
return new Promise((resolve, reject) => {
slot.active = { id, request, onProgress, resolve, reject, resultType, progressType };
try {
slot.worker.postMessage({
type: terrainScoutOnly ? "generate-raw-patch-terrain-scout" : draftOnly ? "generate-raw-patch-draft" : "generate-raw-patch-candidate",
id,
taskId: request.taskId || `${terrainScoutOnly ? "raw-terrain-scout" : draftOnly ? "raw-draft" : "raw-candidate"}-${id}`,
seed: request.seed >>> 0,
mapOptions: request.mapOptions || {},
});
} catch (error) {
slot.active = null;
reject(error);
}
});
}
async function runRawCandidateTask(slotIndex, request, onProgress) {
return runRawHelperTask(slotIndex, request, onProgress, "candidate");
}
async function runRawDraftTask(slotIndex, request, onProgress) {
return runRawHelperTask(slotIndex, request, onProgress, "draft");
}
async function runRawTerrainScoutTask(slotIndex, request, onProgress) {
return runRawHelperTask(slotIndex, request, onProgress, "terrain-scout");
}
async function precomputeRawCandidateBatch(requests, onProgress) {
if (!Array.isArray(requests) || !requests.length) return [];
if (requests.length > 2) throw new Error(`Raw candidate batch exceeds the two-worker limit (${requests.length}).`);
try {
return await Promise.all(requests.map((request, index) => runRawCandidateTask(index, request, onProgress)));
} catch (error) {
// A failed child may have left its module worker in an unknown state. Reset
// the bounded pool before the coordinator falls back to serial generation.
await Promise.all(rawCandidateWorkerSlots.map((slot, index) => slot?.active ? destroyRawCandidateWorkerSlot(index) : null));
throw error;
}
}
async function precomputeRawDraftBatch(requests, onProgress) {
if (!Array.isArray(requests) || !requests.length) return [];
if (requests.length > 2) throw new Error(`Raw draft batch exceeds the two-worker limit (${requests.length}).`);
try {
return await Promise.all(requests.map((request, index) => runRawDraftTask(index, request, onProgress)));
} catch (error) {
await Promise.all(rawCandidateWorkerSlots.map((slot, index) => slot?.active ? destroyRawCandidateWorkerSlot(index) : null));
throw error;
}
}
async function precomputeRawTerrainScoutBatch(requests, onProgress) {
if (!Array.isArray(requests) || !requests.length) return [];
if (requests.length > 2) throw new Error(`Raw terrain-scout batch exceeds the two-worker limit (${requests.length}).`);
try {
return await Promise.all(requests.map((request, index) => runRawTerrainScoutTask(index, request, onProgress)));
} catch (error) {
await Promise.all(rawCandidateWorkerSlots.map((slot, index) => slot?.active ? destroyRawCandidateWorkerSlot(index) : null));
throw error;
}
}
// Continuously feed at most two production helpers instead of waiting for
// fixed pairs to finish. Merge order remains strictly deterministic in
// mapPatch.js. Callers choose a bounded sliding window; production uses one
// resident result per lane so transferred candidate graphs cannot accumulate.
export function scheduleRawCandidateSequence(requests, onProgress, options = {}) {
const list = Array.isArray(requests) ? requests : [];
const count = list.length;
const laneCount = Math.max(1, Math.min(2, Math.floor(options.parallelism || 2), Math.max(1, count)));
const windowSize = Math.max(laneCount, Math.min(count || laneCount, Math.floor(options.windowSize || (laneCount + 1))));
const recycleWorkers = options.recycleWorkers === true;
// Keep each helper for a small bounded run. Reusing it forever lets
// generateMap's module-local/cache state accumulate; recycling after every
// tile creates excessive isolate churn on max-range selections. Three
// complete candidates per lane is the bounded middle ground.
const recycleEvery = recycleWorkers
? Math.max(1, Math.min(4, Math.floor(options.recycleEvery || 3)))
: Infinity;
const controls = list.map(() => {
let resolve;
let reject;
const promise = new Promise((res, rej) => { resolve = res; reject = rej; });
// The coordinator can stop after an earlier failure. Register a rejection
// observer now so later cancelled items cannot become unhandled rejections.
promise.catch(() => undefined);
return { promise, resolve, reject, settled: false };
});
const released = new Uint8Array(count);
let releasedPrefix = 0;
let nextToSchedule = 0;
let cancelled = false;
let cancelError = null;
const gateWaiters = new Set();
const wake = () => {
for (const resolve of gateWaiters) resolve();
gateWaiters.clear();
};
const waitForGate = () => new Promise((resolve) => gateWaiters.add(resolve));
const allowedEnd = () => Math.min(count, releasedPrefix + windowSize);
const takeNext = () => {
if (cancelled || nextToSchedule >= count) return -1;
if (nextToSchedule >= allowedEnd()) return -2;
return nextToSchedule++;
};
const failAll = (error) => {
if (cancelled) return;
cancelled = true;
cancelError = error instanceof Error ? error : new Error(String(error || "Raw candidate sequence cancelled."));
for (const control of controls) {
if (!control?.settled) {
control.settled = true;
const reject = control.reject;
// Promise capability functions keep their Promise reachable. Clear
// both callbacks as soon as the public Promise has settled so a
// transferred raw candidate cannot remain retained through scheduler
// bookkeeping after the coordinator drops publicPromises[index].
control.resolve = null;
control.reject = null;
reject?.(cancelError);
}
}
for (let index = 0; index < laneCount; index++) {
if (rawCandidateWorkerSlots[index]?.active) destroyRawCandidateWorkerSlot(index, cancelError.message);
}
wake();
};
const lane = async (slotIndex) => {
let tasksSinceRecycle = 0;
while (!cancelled) {
const index = takeNext();
if (index === -1) return;
if (index === -2) {
await waitForGate();
continue;
}
try {
let candidate = await runRawCandidateTask(slotIndex, list[index], onProgress);
if (cancelled) return;
const control = controls[index];
if (!control.settled) {
control.settled = true;
const resolve = control.resolve;
control.resolve = null;
control.reject = null;
resolve?.(candidate);
}
// The Promise result owns the transferred graph now. Do not keep an
// additional lane-local reference while waiting for the next window.
candidate = null;
// Reclaim helper-local generator state before it can grow without
// paying module-worker startup/teardown cost on every single tile.
tasksSinceRecycle++;
if (recycleWorkers && tasksSinceRecycle >= recycleEvery) {
await destroyRawCandidateWorkerSlot(slotIndex, `Raw candidate helper recycled after ${tasksSinceRecycle} completed tiles.`);
tasksSinceRecycle = 0;
}
} catch (error) {
failAll(error);
return;
}
}
};
// Keep the fulfilled Promise graph only in the public array. Once the
// coordinator nulls an entry after merge, scheduler bookkeeping must not keep
// the transferred candidate reachable for the rest of the sequence.
const publicPromises = controls.map((control) => control.promise);
for (const control of controls) control.promise = null;
const lanes = count ? Array.from({ length: laneCount }, (_, index) => lane(index)) : [];
const done = Promise.allSettled(lanes).then(() => undefined);
return {
promises: publicPromises,
release(index) {
const i = Math.floor(Number(index));
if (i < 0 || i >= count || released[i]) return;
released[i] = 1;
while (releasedPrefix < count && released[releasedPrefix]) releasedPrefix++;
wake();
},
cancel(reason = "Raw candidate sequence cancelled.") {
const error = reason instanceof Error ? reason : new Error(String(reason));
if (!error.code) error.code = "raw-candidate-sequence-cancelled";
failAll(error);
return done;
},
done,
async dispose(reason = "Raw candidate sequence disposed.") {
await done;
await Promise.allSettled(Array.from({ length: laneCount }, (_, index) =>
rawCandidateWorkerSlots[index] ? destroyRawCandidateWorkerSlot(index, reason) : rawCandidateWorkerTerminations[index]
).filter(Boolean));
},
get cancelled() { return cancelled; },
get error() { return cancelError; },
laneCount,
windowSize,
};
}
export async function shutdownRawCandidateWorkers() {
const pending = [];
for (let index = 0; index < rawCandidateWorkerSlots.length; index++) {
if (rawCandidateWorkerSlots[index]) pending.push(destroyRawCandidateWorkerSlot(index, "Raw candidate operation completed."));
else if (rawCandidateWorkerTerminations[index]) pending.push(rawCandidateWorkerTerminations[index]);
}
if (pending.length) await Promise.allSettled(pending);
}
function isMirrorSyncMessage(type) {
return typeof type === "string" && type.startsWith("patch-mirror-sync-");
}
function safeMirrorKey(key, label = "key") {
const normalized = String(key ?? "");
if (!normalized || normalized === "__proto__" || normalized === "prototype" || normalized === "constructor") {
throw new Error(`Invalid mirror ${label}: ${normalized || "<empty>"}.`);
}
return normalized;
}
function defineMirrorEntry(target, key, value) {
Object.defineProperty(target, key, {
value,
enumerable: true,
configurable: true,
writable: true,
});
}
function sameMirrorKeys(actual, expected) {
const actualKeys = Object.keys(actual || {});
if (!Array.isArray(expected) || actualKeys.length !== expected.length) return false;
const actualSet = new Set(actualKeys);
return expected.every((key) => actualSet.has(key));
}
function validateCompletedMirrorBootstrap(bootstrap) {
if (!bootstrap?.world || !bootstrap?.manifest) throw new Error("Mirror bootstrap is incomplete.");
const { world, manifest } = bootstrap;
if (!sameMirrorKeys(world.fields, manifest.fieldKeys)) throw new Error("Mirror field manifest is incomplete.");
if (!sameMirrorKeys(world.sourceMap, manifest.sourceKeys)) throw new Error("Mirror sourceMap manifest is incomplete.");
const rootActual = Object.keys(world).filter((key) => key !== "fields" && key !== "sourceMap" && key !== "generatedMask");
const rootExpected = Array.isArray(manifest.rootKeys) ? manifest.rootKeys : [];
if (rootActual.length !== rootExpected.length || !rootExpected.every((key) => rootActual.includes(key))) {
throw new Error("Mirror root manifest is incomplete.");
}
if (!!manifest.hasGeneratedMask !== !!world.generatedMask) throw new Error("Mirror generatedMask manifest is incomplete.");
const width = Number(world.width);
const height = Number(world.height);
const area = width * height;
if (!Number.isInteger(width) || !Number.isInteger(height) || width <= 0 || height <= 0 || !Number.isSafeInteger(area) || area <= 0) {
throw new Error("Mirror dimensions are invalid.");
}
for (const key of manifest.fieldKeys || []) {
const field = world.fields[key];
if (!ArrayBuffer.isView(field) || field.length !== area) {
throw new Error(`Mirror field ${key} has invalid storage (${field?.length ?? "missing"} != ${area}).`);
}
}
if (manifest.hasGeneratedMask && (!ArrayBuffer.isView(world.generatedMask) || world.generatedMask.length !== area)) {
throw new Error(`Mirror generatedMask has invalid storage (${world.generatedMask?.length ?? "missing"} != ${area}).`);
}
for (const [key, childKeys] of Object.entries(manifest.expandedSourceObjects || {})) {
if (!world.sourceMap[key] || !sameMirrorKeys(world.sourceMap[key], childKeys)) {
throw new Error(`Mirror sourceMap.${key} manifest is incomplete.`);
}
}
}
function handleMirrorSyncMessage(incoming) {
if (!isMirrorSyncMessage(incoming?.type)) return false;
const type = incoming.type;
const syncId = String(incoming.syncId || "");
const sequence = Number(incoming.sequence || 0);
const acknowledge = (ok, error = null, extra = {}) => {
self.postMessage({
id: incoming.id,
type: "patch-mirror-sync-ack",
syncId,
sequence,
stage: type,
ok,
error,
...extra,
});
};
try {
if (!syncId || !Number.isSafeInteger(sequence) || sequence <= 0) throw new Error("Invalid mirror synchronization envelope.");
if (type === "patch-mirror-sync-start") {
const manifest = incoming.manifest || {};
if (!Array.isArray(manifest.rootKeys) || !Array.isArray(manifest.fieldKeys) || !Array.isArray(manifest.sourceKeys)) {
throw new Error("Mirror synchronization manifest is invalid.");
}
pendingMirrorBootstrap = {
id: incoming.id,
syncId,
committedRevision: Number(incoming.committedRevision ?? -1),
lastSequence: sequence,
manifest,
world: { fields: {}, sourceMap: {} },
};
acknowledge(true);
return true;
}
const bootstrap = pendingMirrorBootstrap;
if (!bootstrap || bootstrap.syncId !== syncId || bootstrap.id !== incoming.id) throw new Error("Mirror synchronization session is unavailable or stale.");
if (sequence <= bootstrap.lastSequence) throw new Error(`Mirror synchronization sequence did not advance (${sequence} <= ${bootstrap.lastSequence}).`);
bootstrap.lastSequence = sequence;
if (type === "patch-mirror-sync-root") {
const key = safeMirrorKey(incoming.key, "root key");
if (!bootstrap.manifest.rootKeys.includes(key)) throw new Error(`Unexpected mirror root key ${key}.`);
defineMirrorEntry(bootstrap.world, key, incoming.value);
} else if (type === "patch-mirror-sync-field") {
const key = safeMirrorKey(incoming.key, "field key");
if (!bootstrap.manifest.fieldKeys.includes(key)) throw new Error(`Unexpected mirror field ${key}.`);
defineMirrorEntry(bootstrap.world.fields, key, incoming.value);
} else if (type === "patch-mirror-sync-generated-mask") {
if (!bootstrap.manifest.hasGeneratedMask) throw new Error("Unexpected mirror generatedMask.");
bootstrap.world.generatedMask = incoming.value;
} else if (type === "patch-mirror-sync-source") {
const key = safeMirrorKey(incoming.key, "source key");
if (!bootstrap.manifest.sourceKeys.includes(key)) throw new Error(`Unexpected mirror source key ${key}.`);
if (Object.prototype.hasOwnProperty.call(bootstrap.manifest.expandedSourceObjects || {}, key)) {
throw new Error(`Mirror source key ${key} must be synchronized by child entries.`);
}
defineMirrorEntry(bootstrap.world.sourceMap, key, incoming.value);
} else if (type === "patch-mirror-sync-source-object-start") {
const key = safeMirrorKey(incoming.key, "source object key");
if (!Object.prototype.hasOwnProperty.call(bootstrap.manifest.expandedSourceObjects || {}, key)) {
throw new Error(`Unexpected expanded mirror source key ${key}.`);
}
defineMirrorEntry(bootstrap.world.sourceMap, key, {});
} else if (type === "patch-mirror-sync-source-object-entry") {
const key = safeMirrorKey(incoming.key, "source object key");
const childKey = safeMirrorKey(incoming.childKey, "source child key");
const expectedChildren = bootstrap.manifest.expandedSourceObjects?.[key];
if (!Array.isArray(expectedChildren) || !expectedChildren.includes(childKey) || !bootstrap.world.sourceMap[key]) {
throw new Error(`Unexpected mirror source child ${key}.${childKey}.`);
}
defineMirrorEntry(bootstrap.world.sourceMap[key], childKey, incoming.value);
} else if (type === "patch-mirror-sync-finish") {
validateCompletedMirrorBootstrap(bootstrap);
persistentCommittedMirror = bootstrap.world;
persistentCommittedRevision = bootstrap.committedRevision;
pendingMirrorBootstrap = null;
pendingApplyDeltas.clear();
acknowledge(true, null, { mirrorCommittedRevision: persistentCommittedRevision });
return true;
} else if (type === "patch-mirror-sync-abort") {
pendingMirrorBootstrap = null;
acknowledge(true);
return true;
} else {
throw new Error(`Unknown mirror synchronization stage ${type}.`);
}
acknowledge(true);
} catch (error) {
if (type === "patch-mirror-sync-start" || pendingMirrorBootstrap?.syncId === syncId) pendingMirrorBootstrap = null;
acknowledge(false, error?.message || String(error));
}
return true;
}
function valuesEqual(a, b) {
return a === b || (Number.isNaN(a) && Number.isNaN(b));
}
function exactStructuredEqual(a, b) {
if (valuesEqual(a, b)) return true;
if (a == null || b == null || typeof a !== "object" || typeof b !== "object") return false;
if (ArrayBuffer.isView(a) || ArrayBuffer.isView(b)) {
if (!ArrayBuffer.isView(a) || !ArrayBuffer.isView(b)
|| a.constructor !== b.constructor || a.length !== b.length) return false;
for (let index = 0; index < a.length; index++) if (!valuesEqual(a[index], b[index])) return false;
return true;
}
if (Array.isArray(a) || Array.isArray(b)) {
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;
for (let index = 0; index < a.length; index++) if (!exactStructuredEqual(a[index], b[index])) return false;
// Generated paths use one enumerable array annotation. Compare it directly
// instead of allocating Object.keys arrays for every coordinate tuple.
return a.patchGenerated === b.patchGenerated;
}
if (a instanceof Date || b instanceof Date) return a instanceof Date && b instanceof Date && a.getTime() === b.getTime();
if (a instanceof Map || b instanceof Map) {
if (!(a instanceof Map) || !(b instanceof Map) || a.size !== b.size) return false;
for (const [key, value] of a) if (!b.has(key) || !exactStructuredEqual(value, b.get(key))) return false;
return true;
}
if (a instanceof Set || b instanceof Set) {
if (!(a instanceof Set) || !(b instanceof Set) || a.size !== b.size) return false;
for (const value of a) if (!b.has(value)) return false;
return true;
}
const aKeys = Object.keys(a);
const bKeys = Object.keys(b);
if (aKeys.length !== bKeys.length) return false;
for (let index = 0; index < aKeys.length; index++) {
const key = aKeys[index];
if (key !== bKeys[index] || !exactStructuredEqual(a[key], b[key])) return false;
}
return true;
}
function isDensePlainArray(value) {
if (!Array.isArray(value)) return false;
const keys = Object.keys(value);
if (keys.length !== value.length) return false;
for (let index = 0; index < keys.length; index++) if (keys[index] !== String(index)) return false;
return true;
}
function buildExactArraySplice(base, next, { cloneValues = true } = {}) {
if (!isDensePlainArray(base) || !isDensePlainArray(next)) return null;
const commonLimit = Math.min(base.length, next.length);
let start = 0;
while (start < commonLimit && exactStructuredEqual(base[start], next[start])) start++;
if (start === base.length && start === next.length) return { unchanged: true };
let suffix = 0;
while (suffix < commonLimit - start
&& exactStructuredEqual(base[base.length - 1 - suffix], next[next.length - 1 - suffix])) suffix++;
const items = next.slice(start, next.length - suffix);
return {
start,
deleteCount: base.length - start - suffix,
items: cloneValues ? structuredClone(items) : items,
};
}
function buildExactObjectDelta(base = {}, next = {}, { cloneValues = true } = {}) {
const set = {};
const arraySplices = {};
for (const [key, value] of Object.entries(next || {})) {
if (!Object.prototype.hasOwnProperty.call(base || {}, key)) {
set[key] = cloneValues ? structuredClone(value) : value;
continue;
}
if (isDensePlainArray(base[key]) && isDensePlainArray(value)) {
const splice = buildExactArraySplice(base[key], value, { cloneValues });
if (splice && !splice.unchanged) arraySplices[key] = splice;
continue;
}
if (!exactStructuredEqual(base[key], value)) set[key] = cloneValues ? structuredClone(value) : value;
}
const removed = Object.keys(base || {}).filter((key) => !Object.prototype.hasOwnProperty.call(next || {}, key));
return { set, arraySplices, removed };
}
function buildTypedRowDelta(base, next, width) {
if (!ArrayBuffer.isView(next)) return null;
if (!ArrayBuffer.isView(base) || base.constructor?.name !== next.constructor?.name || base.length !== next.length) {
return { constructorName: next.constructor.name, length: next.length, replace: new next.constructor(next) };
}
const rows = [];
const rowWidth = Math.max(1, Number(width || next.length));
for (let rowStart = 0; rowStart < next.length; rowStart += rowWidth) {
const rowEnd = Math.min(next.length, rowStart + rowWidth);
let first = -1;
let last = -1;
for (let index = rowStart; index < rowEnd; index++) {
if (valuesEqual(base[index], next[index])) continue;
if (first < 0) first = index;
last = index;
}
if (first >= 0) rows.push({ start: first, values: new next.constructor(next.subarray(first, last + 1)) });
}
return rows.length ? { constructorName: next.constructor.name, length: next.length, rows } : null;
}
export function buildCommittedMirrorDelta(baseWorld, nextWorld) {
if (!baseWorld || !nextWorld) throw new Error("Cannot build a committed mirror delta without both worlds.");
const fieldNames = new Set([...Object.keys(baseWorld.fields || {}), ...Object.keys(nextWorld.fields || {})]);
const fields = {};
for (const name of fieldNames) {
const next = nextWorld.fields?.[name];
if (!next) {
fields[name] = { remove: true };
continue;
}
const delta = buildTypedRowDelta(baseWorld.fields?.[name], next, nextWorld.width);
if (delta) fields[name] = delta;
}
const generatedMask = buildTypedRowDelta(baseWorld.generatedMask, nextWorld.generatedMask, nextWorld.width);
const baseMeta = {};
const nextMeta = {};
for (const [key, value] of Object.entries(baseWorld)) {
if (key !== "fields" && key !== "generatedMask" && key !== "sourceMap") baseMeta[key] = value;
}
for (const [key, value] of Object.entries(nextWorld)) {
if (key !== "fields" && key !== "generatedMask" && key !== "sourceMap") nextMeta[key] = value;
}
const exactDeltas = structuredClone({
sourceMapDelta: buildExactObjectDelta(baseWorld.sourceMap || {}, nextWorld.sourceMap || {}, { cloneValues: false }),
metaDelta: buildExactObjectDelta(baseMeta, nextMeta, { cloneValues: false }),
});
return {
width: nextWorld.width,
height: nextWorld.height,
fields,
generatedMask,
sourceMapDelta: exactDeltas.sourceMapDelta,
metaDelta: exactDeltas.metaDelta,
};
}
export function buildMainThreadTransferDelta(delta) {
if (!delta) return null;
// Raster row buffers are transferred to the main thread and therefore need
// a Worker-side copy so the retained Apply-ACK delta is not detached. Plain
// metadata is already cloned once by postMessage; cloning that graph here as
// well only doubled paths, points, histories and diagnostics at peak memory.
const raster = structuredClone({
fields: delta.fields || {},
generatedMask: delta.generatedMask || null,
});
return {
...delta,
fields: raster.fields,
generatedMask: raster.generatedMask,
};
}
function markPreviewChange(changeTracker, worldIndex, category = 0) {
if (!changeTracker?.mask) return;
const width = changeTracker.worldWidth;
const x = worldIndex % width;
const y = Math.floor(worldIndex / width);
const rect = changeTracker.rect;
if (x < rect.x0 || y < rect.y0 || x >= rect.x1 || y >= rect.y1) return;
const localIndex = (y - rect.y0) * changeTracker.width + (x - rect.x0);
changeTracker.mask[localIndex] |= 1 | category;
}
function markAllPreviewChanges(changeTracker, category = 0) {
if (!changeTracker?.mask) return;
const flags = 1 | category;
changeTracker.mask.fill(flags);
}
function buildTypedRowDeltaFromTransaction(snapshot, name, next, changeTracker = null) {
if (!ArrayBuffer.isView(next)) return null;
const baseRef = snapshot?.fieldRefs?.get(name);
if (!ArrayBuffer.isView(baseRef) || baseRef.constructor?.name !== next.constructor?.name || baseRef.length !== next.length) {
const category = PREVIEW_TERRAIN_FIELDS.has(name) ? 2 : PREVIEW_ADMIN_FIELDS.has(name) ? 4 : 0;
markAllPreviewChanges(changeTracker, category);
return { constructorName: next.constructor.name, length: next.length, replace: new next.constructor(next) };
}
const localEntry = snapshot?.fields?.get(name) || null;
const rect = snapshot?.fieldRect || null;
const width = Math.max(1, Number(snapshot?.width || next.length));
const rows = [];
const scanLocalRect = localEntry && rect;
const startY = scanLocalRect ? Math.max(0, rect.y0) : 0;
const endY = scanLocalRect ? Math.min(snapshot.height, rect.y1) : Math.ceil(next.length / width);
for (let y = startY; y < endY; y++) {
const rowStart = y * width;
const rowEnd = Math.min(next.length, rowStart + width);
const scanStart = scanLocalRect ? Math.max(rowStart, rowStart + rect.x0) : rowStart;
const scanEnd = scanLocalRect ? Math.min(rowEnd, rowStart + rect.x1) : rowEnd;
let first = -1;
let last = -1;
for (let index = scanStart; index < scanEnd; index++) {
const x = index - rowStart;
let oldValue = baseRef[index];
if (localEntry && rect && x >= rect.x0 && x < rect.x1 && y >= rect.y0 && y < rect.y1) {
oldValue = localEntry.data[(y - rect.y0) * snapshot.fieldWidth + (x - rect.x0)];
}
if (valuesEqual(oldValue, next[index])) continue;
const category = PREVIEW_TERRAIN_FIELDS.has(name) ? 2 : PREVIEW_ADMIN_FIELDS.has(name) ? 4 : 0;
markPreviewChange(changeTracker, index, category);
if (first < 0) first = index;
last = index;
}
if (first >= 0) rows.push({ start: first, values: new next.constructor(next.subarray(first, last + 1)) });
}
return rows.length ? { constructorName: next.constructor.name, length: next.length, rows } : null;
}
export function buildCommittedMirrorDeltaFromTransaction(snapshot, nextWorld) {
if (!snapshot || snapshot.lightweight || !nextWorld) throw new Error("A full patch transaction snapshot is required.");
const fieldNames = new Set([...(snapshot.fieldNames || []), ...Object.keys(nextWorld.fields || {})]);
const fields = {};
const snapshotRect = snapshot.fieldRect || { x0: 0, y0: 0, x1: nextWorld.width, y1: nextWorld.height };
const changeRect = {
x0: Math.max(0, Math.floor(snapshotRect.x0 || 0)),
y0: Math.max(0, Math.floor(snapshotRect.y0 || 0)),
x1: Math.min(nextWorld.width, Math.ceil(snapshotRect.x1 || 0)),
y1: Math.min(nextWorld.height, Math.ceil(snapshotRect.y1 || 0)),
};
const changeTracker = {
rect: changeRect,
width: Math.max(0, changeRect.x1 - changeRect.x0),
worldWidth: nextWorld.width,
mask: null,
};
changeTracker.mask = new Uint8Array(changeTracker.width * Math.max(0, changeRect.y1 - changeRect.y0));
for (const name of fieldNames) {
const next = nextWorld.fields?.[name];
if (!next) {
if (snapshot.fieldNames?.has(name)) {
fields[name] = { remove: true };
const category = PREVIEW_TERRAIN_FIELDS.has(name) ? 2 : PREVIEW_ADMIN_FIELDS.has(name) ? 4 : 0;
markAllPreviewChanges(changeTracker, category);
}
continue;
}
const delta = buildTypedRowDeltaFromTransaction(snapshot, name, next, changeTracker);
if (delta) fields[name] = delta;
}
const baseMeta = {};
const nextMeta = {};
for (const [key, value] of Object.entries(nextWorld)) {
if (key !== "fields" && key !== "generatedMask" && key !== "sourceMap") {
baseMeta[key] = value;
nextMeta[key] = value;
}
}
Object.assign(baseMeta, {
width: snapshot.width,
height: snapshot.height,
originX: snapshot.originX,
originY: snapshot.originY,
sourceWidth: snapshot.sourceWidth,
sourceHeight: snapshot.sourceHeight,
generatedRects: snapshot.generatedRects,
lastPatchResult: snapshot.lastPatchResult,
patchGenerationSerial: snapshot.patchGenerationSerial,
seaLevel: snapshot.seaLevel,
});
const rawSourceMapDelta = buildExactObjectDelta(snapshot.sourceMap || {}, nextWorld.sourceMap || {}, { cloneValues: false });
const rawMetaDelta = buildExactObjectDelta(baseMeta, nextMeta, { cloneValues: false });
// Transaction restore replaces world/sourceMap roots; it does not mutate the
// accepted arrays and diagnostic objects referenced by these deltas. Adopt
// that completed graph directly. Cloning it here duplicated all changed
// metadata immediately before rollback and the later postMessage clone.
const exactDeltas = { sourceMapDelta: rawSourceMapDelta, metaDelta: rawMetaDelta };
let changedCells = 0;
let terrainChangedCells = 0;
let adminChangedCells = 0;
for (const flags of changeTracker.mask) {
if (flags & 1) changedCells++;
if (flags & 2) terrainChangedCells++;
if (flags & 4) adminChangedCells++;
}
const changedSourceKeys = new Set([
...Object.keys(rawSourceMapDelta.set || {}),
...Object.keys(rawSourceMapDelta.arraySplices || {}),
...(rawSourceMapDelta.removed || []),
]);
let featureLayersChanged = 0;
for (const key of PREVIEW_FEATURE_KEYS) if (changedSourceKeys.has(key)) featureLayersChanged++;
return {
width: nextWorld.width,
height: nextWorld.height,
fields,
generatedMask: buildTypedRowDelta(
snapshot.generatedMask || snapshot.generatedMaskRef,
nextWorld.generatedMask,
nextWorld.width
),
sourceMapDelta: exactDeltas.sourceMapDelta,
metaDelta: exactDeltas.metaDelta,
previewDelta: {
changedCells,
terrainChangedCells,
adminChangedCells,
featureLayersChanged,
identical: changedCells === 0 && featureLayersChanged === 0,
},
};
}
function nowMs() {
return typeof performance !== "undefined" && performance.now ? performance.now() : Date.now();
}
function compactQuality(quality) {
if (!quality || typeof quality !== "object") return null;
return {
hardPass: quality.hardPass !== false,
score: Number(quality.score || 0),
selectedVariant: Number.isFinite(quality.selectedVariant) ? quality.selectedVariant >>> 0 : null,
terrainType: quality.terrainType || quality.terrain?.terrainType || null,
terrain: quality.terrain ? {
hardPass: quality.terrain.hardPass !== false,
landRatio: Number(quality.terrain.landRatio || 0),
developableRatio: Number(quality.terrain.developableRatio || 0),
largestComponentRatio: Number(quality.terrain.largestComponentRatio || 0),
} : null,
human: quality.human ? {
hardPass: quality.human.hardPass !== false,
settlementCount: Number(quality.human.settlementCount || 0),
labelCount: Number(quality.human.labelCount || 0),
roadPaths: Number(quality.human.roadPaths || 0),
railPaths: Number(quality.human.railPaths || 0),
} : null,
finalMerge: quality.finalMerge ? {
hardPass: quality.finalMerge.hardPass !== false,
ownedCells: Number(quality.finalMerge.ownedCells || 0),
ownedLandCells: Number(quality.finalMerge.ownedLandCells || 0),
ownedLandRatio: Number(quality.finalMerge.ownedLandRatio || 0),
landFloor: Number(quality.finalMerge.landFloor || 0),
settlementCount: Number(quality.finalMerge.settlementCount || 0),
minFinalSettlements: Number(quality.finalMerge.minFinalSettlements || 0),
preMergeSettlementCount: Number.isFinite(quality.finalMerge.preMergeSettlementCount)
? Number(quality.finalMerge.preMergeSettlementCount) : null,
candidateMinimumSettlements: Number(quality.finalMerge.candidateMinimumSettlements || 0),
labelCount: Number(quality.finalMerge.labelCount || 0),
minFinalLabels: Number(quality.finalMerge.minFinalLabels || 0),
preMergeLabelCount: Number.isFinite(quality.finalMerge.preMergeLabelCount)
? Number(quality.finalMerge.preMergeLabelCount) : null,
candidateMinimumLabels: Number(quality.finalMerge.candidateMinimumLabels || 0),
adminCenters: Number(quality.finalMerge.counts?.adminCenters || 0),
minFinalAdminCenters: Number(quality.finalMerge.minFinalAdminCenters || 0),
transportRequired: quality.finalMerge.transportRequired === true,
roadPaths: Number(quality.finalMerge.roadPaths || 0),
railPaths: Number(quality.finalMerge.railPaths || 0),
transportHierarchyPass: quality.finalMerge.transportHierarchyPass !== false,
transportTopology: quality.finalMerge.transportTopology ? structuredClone(quality.finalMerge.transportTopology) : null,
prefectureCoherence: quality.finalMerge.prefectureCoherence ? structuredClone(quality.finalMerge.prefectureCoherence) : null,
transportClasses: quality.finalMerge.transportClasses
? Object.fromEntries(Object.entries(quality.finalMerge.transportClasses).map(([key, value]) => [key, {
paths: Number(value?.paths || 0),
cells: Number(value?.cells || 0),
pathsPer1000Land: Number(value?.pathsPer1000Land || 0),
cellsPer1000Land: Number(value?.cellsPer1000Land || 0),
}]))
: null,
transportRequirements: quality.finalMerge.transportRequirements
? Object.fromEntries(Object.entries(quality.finalMerge.transportRequirements).map(([key, value]) => [key, {
// The producer field is `demand`; the old compact diagnostic read a
// nonexistent `required` property, making every required trunk class
// appear optional and allowing regression tests to silently skip it.
demand: value?.demand === true,
required: value?.demand === true,
minPaths: Number(value?.minPaths || 0),
minCells: Number(value?.minCells || 0),
expectedPaths: Number(value?.expectedPaths || 0),
expectedCells: Number(value?.expectedCells || 0),
}]))
: null,
rectangularCoastHardPass: quality.finalMerge.rectangularCoastHardPass !== false,
rectangularCoastRun: Number(quality.finalMerge.rectangularCoastCut?.maxAxisAlignedRun || 0),
rectangularCoastLongestRun: quality.finalMerge.rectangularCoastCut?.longestRun
? { ...quality.finalMerge.rectangularCoastCut.longestRun }
: null,
rectangularCoastCutScope: quality.finalMerge.rectangularCoastCutScope || null,
score: Number(quality.finalMerge.score || 0),
} : null,
};
}
function compactSeam(diagnostics) {
if (!diagnostics || typeof diagnostics !== "object") return null;
return {
hardPass: diagnostics.hardPass !== false,
status: diagnostics.status || null,
gateReasons: [...(diagnostics.gateReasons || [])],
roadPortalsBroken: Number(diagnostics.roadPortalsBroken || 0),
railPortalsBroken: Number(diagnostics.railPortalsBroken || 0),
prefectureSeamBreakEdges: Number(diagnostics.prefectureSeamBreakEdges || 0),
adminSeamBreakEdges: Number(diagnostics.adminSeamBreakEdges || 0),
landToSeaCells: Number(diagnostics.landToSeaCells || 0),
transportLandToSeaConflicts: Number(diagnostics.transportLandToSeaConflicts || 0),
duplicateBoundaryPairs: Number(diagnostics.duplicateBoundaryPairs || 0),
expansionFootprintEscapedCells: Number(diagnostics.expansionFootprintEscapedCells || 0),
maxEstablishedFrontierElevationJump: Number(diagnostics.maxEstablishedFrontierElevationJump || 0),
humanTerrainReconciliation: diagnostics.humanTerrainReconciliation ? {
checked: Number(diagnostics.humanTerrainReconciliation.checked || 0),
alreadyValid: Number(diagnostics.humanTerrainReconciliation.alreadyValid || 0),
relocated: Number(diagnostics.humanTerrainReconciliation.relocated || 0),
dropped: Number(diagnostics.humanTerrainReconciliation.dropped || 0),
stagedOutsideOwnership: Number(diagnostics.humanTerrainReconciliation.stagedOutsideOwnership || 0),
byLayer: diagnostics.humanTerrainReconciliation.byLayer
? Object.fromEntries(Object.entries(diagnostics.humanTerrainReconciliation.byLayer).map(([key, value]) => [key, {
checked: Number(value?.checked || 0),
alreadyValid: Number(value?.alreadyValid || 0),
relocated: Number(value?.relocated || 0),
dropped: Number(value?.dropped || 0),
stagedOutsideOwnership: Number(value?.stagedOutsideOwnership || 0),
}]))
: {},
} : null,
};
}
function isInvariantFailure(result) {
if (result?.tileResult && isInvariantFailure(result.tileResult)) return true;
const code = String(result?.code || "");
const reasons = result?.seamDiagnostics?.gateReasons || [];
return code === "patch-candidate-coverage-incomplete"
|| code === "patch-generated-footprint-write-escape"
|| code === "patch-invariant-breach"
|| reasons.includes("generated-footprint-write-escape")
|| Number(result?.candidateUnmappedActiveCells || 0) > 0;
}
function isContentRejection(result) {
const code = String(result?.code || "");
if (isInvariantFailure(result)) return false;
if ((code === "patch-large-tile-failed" || code === "patch-large-regeneration-tile-failed") && result?.tileResult) {
return isContentRejection(result.tileResult);
}
return code === "patch-quality-gate-failed"
|| code === "patch-seam-gate-failed"
|| code === "patch-large-final-seam-failed";
}
function normalizeCandidateResult(result) {
if (!result?.ok || result?.seamDiagnostics?.hardPass !== false) return result;
return {
...result,
ok: false,
code: "patch-seam-gate-failed",
reason: `Candidate failed final seam continuity (${(result.seamDiagnostics.gateReasons || []).join(", ") || "unknown seam failure"}).`,
rolledBack: true,
};
}
function summarizeAttempt(result, candidate, candidateOrdinal, wallMs, status, executionAttempt = 1) {
return {
candidateId: candidate.candidateId || `${candidate.variant >>> 0}:${candidate.seed >>> 0}`,
candidateOrdinal,
executionAttempt: Math.max(1, Number(executionAttempt || 1)),
variant: candidate.variant >>> 0,
seed: candidate.seed >>> 0,
status,
ok: result?.ok === true,
code: result?.code || null,
reason: result?.reason || null,
patchMode: result?.patchMode || null,
tileCount: Number(result?.tileCount || 0),
wallMs: Math.round(wallMs * 10) / 10,
candidateQuality: compactQuality(result?.candidateQuality),
seamDiagnostics: compactSeam(result?.seamDiagnostics),
patchTimings: (result?.patchTimings || []).map((entry) => ({
key: entry.key || null,
label: entry.label || entry.key || "Stage",
ms: Number(entry.ms || 0),
})),
};
}
function candidateQualityScore(result) {
const quality = result?.candidateQuality || null;
// Ordinary production candidates already expose the combined ranking score
// in candidateQuality.score. Tiled candidates explicitly promote the final
// whole-selection merge audit to the authoritative score instead.
const candidates = quality?.qualityAuthority === "whole-selection-post-merge"
? [quality?.finalMerge?.score, quality?.score, quality?.final?.score]
: [quality?.score, quality?.final?.score, quality?.finalMerge?.score];
for (const value of candidates) {
const score = Number(value);
if (Number.isFinite(score)) return score;
}
return 0;
}
function retainProductionTerrainDraft(draft) {
if (!draft?.terrain) return null;
return {
terrain: draft.terrain,
generationTimings: (draft.generationTimings || []).filter((row) => row?.key === "terrain").map((row) => ({ ...row })),
generationTotalMs: Number((draft.generationTimings || []).find((row) => row?.key === "terrain")?.ms || 0),
baseSeed: draft.baseSeed >>> 0,
effectiveSeed: draft.effectiveSeed >>> 0,
generationContext: { ...(draft.generationContext || {}) },
terrainDraftOnly: true,
residentDraftSource: true,
};
}
function draftCandidateScore(result) {
const score = Number(result?.score ?? result?.candidateQuality?.score);
return Number.isFinite(score) ? score : -Infinity;
}
function draftCandidateUpperBound(result) {
const value = Number(result?.qualityUpperBound ?? result?.candidateQuality?.qualityUpperBound);
if (Number.isFinite(value)) return Math.max(0, Math.min(1, value));
return 1;
}
function draftAdmissibleHardReject(result) {
return result?.admissibleHardReject === true || result?.candidateQuality?.admissibleHardReject === true;
}
function compactDraftQuality(result) {
const quality = result?.candidateQuality || null;
if (!quality) return null;
return {
score: draftCandidateScore(result),
qualityUpperBound: draftCandidateUpperBound(result),
hardPass: quality.hardPass !== false,
admissibleHardReject: draftAdmissibleHardReject(result),
earlyRejectStage: result?.earlyRejectStage || null,
draftProxy: true,
terrain: quality.terrain ? {
terrainType: quality.terrain.terrainType || null,
score: Number(quality.terrain.score || 0),
landRatio: Number(quality.terrain.landRatio || 0),
developableRatio: Number(quality.terrain.developableRatio || 0),
largestComponentRatio: Number(quality.terrain.largestComponentRatio || 0),
frontierLandRate: Number(quality.terrain.frontierLandRate || 0),
} : null,
human: quality.human ? {
score: Number(quality.human.score || 0),
settlementCount: Number(quality.human.settlementCount || 0),
labelCount: Number(quality.human.labelCount || 0),
roadPaths: Number(quality.human.roadPaths || 0),
railPaths: Number(quality.human.railPaths || 0),
} : null,
};
}
function rankedDraftCandidates(rows = []) {
return [...rows].sort((a, b) => {
const scoreDelta = draftCandidateScore(b.draftResult) - draftCandidateScore(a.draftResult);
if (Math.abs(scoreDelta) > 1e-12) return scoreDelta;
const hardDelta = Number(b.draftResult?.candidateQuality?.hardPass !== false) - Number(a.draftResult?.candidateQuality?.hardPass !== false);
if (hardDelta) return hardDelta;
return a.candidateOrdinal - b.candidateOrdinal;
});
}
function candidateSeamIssueCount(result) {
const seam = result?.seamDiagnostics || null;
if (!seam) return 0;
return (seam.gateReasons || []).length
+ Number(seam.roadPortalsBroken || 0)
+ Number(seam.railPortalsBroken || 0)
+ Number(seam.prefectureSeamBreakEdges || 0)
+ Number(seam.transportLandToSeaConflicts || 0);
}
function isBetterCandidate(result, candidateOrdinal, best) {
if (!best) return true;
const score = candidateQualityScore(result);
const bestScore = candidateQualityScore(best.result);
if (Math.abs(score - bestScore) > 1e-12) return score > bestScore;
const seamPass = result?.seamDiagnostics?.hardPass !== false;
const bestSeamPass = best.result?.seamDiagnostics?.hardPass !== false;
if (seamPass !== bestSeamPass) return seamPass;
const issues = candidateSeamIssueCount(result);
const bestIssues = candidateSeamIssueCount(best.result);
if (issues !== bestIssues) return issues < bestIssues;
const jump = Number(result?.seamDiagnostics?.maxEstablishedFrontierElevationJump || 0);
const bestJump = Number(best.result?.seamDiagnostics?.maxEstablishedFrontierElevationJump || 0);
if (Math.abs(jump - bestJump) > 1e-12) return jump < bestJump;
return candidateOrdinal < best.candidateOrdinal;
}
function finalizeBestCandidate(best, attempts, candidatePlan, candidateCount) {
if (!best) return null;
const selectedId = best.candidate.candidateId || `${best.candidate.variant >>> 0}:${best.candidate.seed >>> 0}`;
for (const attempt of attempts) {
const attemptId = attempt.candidateId || `${attempt.variant >>> 0}:${attempt.seed >>> 0}`;
attempt.selected = attemptId === selectedId;
if (attempt.selected) attempt.status = "success";
}
const last = candidatePlan[candidatePlan.length - 1] || best.candidate;
return {
...best.result,
ok: true,
searchAttempts: attempts,
searchStatus: "succeeded",
candidateOrdinal: best.candidateOrdinal,
candidateCount,
actualVariant: best.candidate.variant >>> 0,
actualSeed: best.candidate.seed >>> 0,
nextVariant: (((last?.variant || 0) >>> 0) + 1) >>> 0,
bestOfCandidates: true,
evaluatedCandidateCount: attempts.filter((attempt) => attempt.status === "evaluated" || attempt.status === "success").length,
selectionScore: candidateQualityScore(best.result),
};
}
const PREVIEW_TERRAIN_FIELDS = new Set(["elevation", "slope", "sea", "landMask", "plain", "landuse", "populationDensity"]);
const PREVIEW_ADMIN_FIELDS = new Set(["adminId", "municipalityId", "prefectureRegionId", "prefectureMask", "humanRegionMask"]);
const PREVIEW_FEATURE_KEYS = [
"villages", "markets", "castles", "ports", "modernCities", "satelliteCities", "stations",
"interchanges", "industrialZones", "logisticsParks", "newTowns", "adminCenters", "externalGateways",
"prefectureRegions", "premodernRoads", "minorRoads", "nationalRoads", "ringRoads", "externalRoads",
"railways", "branchRailways", "ringRailways", "externalRailways", "expressways", "externalExpressways",
"mainRivers", "tributaryRivers", "smallStreams", "prefectureBorder", "regionalPrefectureBorders", "adminBorders",
];
function computePreviewDelta(baseWorld, previewWorld, rectLike, onProgress = () => {}) {
const rect = rectLike?.transportReachRect || rectLike?.repairRect || rectLike?.writeRect || rectLike || null;
if (!baseWorld || !previewWorld || !rect) return null;
const x0 = Math.max(0, Math.floor(rect.x0 || 0));
const y0 = Math.max(0, Math.floor(rect.y0 || 0));
const x1 = Math.min(Math.max(baseWorld.width || 0, previewWorld.width || 0), Math.ceil(rect.x1 || 0));
const y1 = Math.min(Math.max(baseWorld.height || 0, previewWorld.height || 0), Math.ceil(rect.y1 || 0));
const fieldNames = new Set([...Object.keys(baseWorld.fields || {}), ...Object.keys(previewWorld.fields || {})]);
let changedCells = 0;
let terrainChangedCells = 0;
let adminChangedCells = 0;
const totalRows = Math.max(0, y1 - y0) + PREVIEW_FEATURE_KEYS.length;
for (let y = y0; y < y1; y++) {
for (let x = x0; x < x1; x++) {
const bi = x >= 0 && y >= 0 && x < baseWorld.width && y < baseWorld.height ? y * baseWorld.width + x : -1;
const pi = x >= 0 && y >= 0 && x < previewWorld.width && y < previewWorld.height ? y * previewWorld.width + x : -1;
if (bi < 0 || pi < 0) continue;
let terrainChanged = false;
let adminChanged = false;
let cellChanged = false;
for (const name of fieldNames) {
const a = baseWorld.fields?.[name]?.[bi];
const b = previewWorld.fields?.[name]?.[pi];
if (a === b || (Number.isNaN(a) && Number.isNaN(b))) continue;
cellChanged = true;
if (PREVIEW_TERRAIN_FIELDS.has(name)) terrainChanged = true;
if (PREVIEW_ADMIN_FIELDS.has(name)) adminChanged = true;
}
if (cellChanged) changedCells++;
if (terrainChanged) terrainChangedCells++;
if (adminChanged) adminChangedCells++;
}
if ((y - y0) % 16 === 15 || y + 1 === y1) onProgress(y - y0 + 1, totalRows, "raster");
}
let featureLayersChanged = 0;
for (let index = 0; index < PREVIEW_FEATURE_KEYS.length; index++) {
const key = PREVIEW_FEATURE_KEYS[index];
if (!exactStructuredEqual(baseWorld.sourceMap?.[key] || [], previewWorld.sourceMap?.[key] || [])) featureLayersChanged++;
onProgress(Math.max(0, y1 - y0) + index + 1, totalRows, "features");
}
return {
changedCells,
terrainChangedCells,
adminChangedCells,
featureLayersChanged,
identical: changedCells === 0 && featureLayersChanged === 0,
};
}
export function runPatchCandidateSearch(message, dependencies = {}) {
const { id, world, rect, options, search } = message || {};
const cloneWorld = dependencies.cloneWorld || ((value) => structuredClone(value));
const generateCandidate = dependencies.generateCandidate || generatePatch;
const clock = dependencies.now || nowMs;
const publishProgress = dependencies.onProgress || (() => {});
const transactional = dependencies.transactional === true;
const selectBestCandidate = search?.selectBestCandidate === true;
const candidatePlan = Array.isArray(search?.candidatePlan) && search.candidatePlan.length
? search.candidatePlan
: [{ variant: options?.variant || 0, seed: options?.seed || world?.seed || 0 }];
const candidateCount = Math.max(candidatePlan.length, Number(search?.totalCandidateCount || candidatePlan.length));
const searchId = search?.searchId || `patch-${id}`;
const workerEpoch = Number(search?.workerEpoch || 0);
const executionAttempt = Math.max(1, Number(search?.executionAttempt || 1));
let eventSeq = 0;
let phaseOrdinal = 0;
let currentPhase = null;
const workUnits = new Map();
const emitProgress = (progress = {}, candidateOrdinal = 0) => {
const phase = String(progress.phase || progress.key || "patch");
if (phase !== currentPhase) {
currentPhase = phase;
phaseOrdinal++;
}
const hasCompleted = progress.completed != null;
const hasTotal = progress.total != null;
const completed = Number(progress.completed);
const total = Number(progress.total);
const boundedWork = hasCompleted || hasTotal;
const explicitWorkUnitId = progress.workUnitId != null && String(progress.workUnitId).length > 0;
const workUnitId = String(explicitWorkUnitId ? progress.workUnitId : (progress.key || phase));
if (boundedWork) {
if (!hasCompleted || !hasTotal || !Number.isFinite(completed) || !Number.isFinite(total)) {
const error = new Error(`Incomplete bounded progress for ${phase}/${workUnitId}: ${String(progress.completed)}/${String(progress.total)}`);
error.code = "worker-progress-invariant";
throw error;
}
if (!explicitWorkUnitId) {
const error = new Error(`Bounded progress is missing an explicit workUnitId for ${phase}/${workUnitId}.`);
error.code = "worker-progress-invariant";
throw error;
}
if (completed < 0 || total < 0 || completed > total) {
const error = new Error(`Invalid progress bounds for ${phase}/${workUnitId}: ${completed}/${total}`);
error.code = "worker-progress-invariant";
throw error;
}
// workUnitId is globally unique within one candidate-search operation.
// Do not reset its monotonicity merely because a display phase changed in
// between heartbeats; that would hide real restarts/runaway producers.
const unitKey = workUnitId;
const previous = workUnits.get(unitKey);
if (previous && (total !== previous.total || completed < previous.completed)) {
const error = new Error(`Non-monotonic progress for ${phase}/${workUnitId}: ${completed}/${total} after ${previous.completed}/${previous.total}`);
error.code = "worker-progress-invariant";
throw error;
}
const workerNow = nowMs();
const startedAtWorker = previous?.startedAtWorker ?? workerNow;
const lastAdvancedAtWorker = !previous || completed > previous.completed
? workerNow
: (previous.lastAdvancedAtWorker ?? startedAtWorker);
workUnits.set(unitKey, { completed, total, phase, startedAtWorker, lastAdvancedAtWorker });
}
eventSeq++;
publishProgress({
id,
type: "progress",
progress: {
...progress,
searchId,
operationId: search?.operationId || searchId,
candidateOrdinal,
candidateCount,
executionAttempt,
workerEpoch,
committedRevision: Number(search?.committedRevision || 0),
eventSeq,
counter: eventSeq,
phase,
phaseOrdinal,
workUnitId,
boundedWork,
startedAtWorker: boundedWork ? workUnits.get(workUnitId)?.startedAtWorker : undefined,
lastAdvancedAtWorker: boundedWork ? workUnits.get(workUnitId)?.lastAdvancedAtWorker : undefined,
cooperative: progress.nonCooperative !== true,
},
});
};
try {
const attempts = [];
let terminalResult = null;
let successWorld = null;
let successDelta = null;
let successTargetHash = null;
let bestCandidate = null;
emitProgress({ status: "start", key: "search", phase: "search", workUnitId: "candidate-search", label: selectBestCandidate
? `Evaluating ${candidateCount} complete candidates and selecting the highest-quality result`
: `Searching ${candidateCount} complete candidate${candidateCount === 1 ? "" : "s"}`, completed: 0, total: candidateCount });
for (let index = 0; index < candidatePlan.length; index++) {
const candidate = candidatePlan[index];
const candidateOrdinal = Math.max(1, Number(candidate.candidateOrdinal || index + 1));
emitProgress({
status: "start",
key: transactional ? "candidate-transaction" : "candidate-clone",
phase: transactional ? "candidate-transaction" : "candidate-clone",
label: transactional
? `Candidate ${candidateOrdinal}/${candidateCount}: capturing exact rollback state`
: `Candidate ${candidateOrdinal}/${candidateCount}: preparing immutable baseline`,
variant: candidate.variant >>> 0,
workUnitId: "candidate-search",
// candidateOrdinal is global across the full search, whereas `index` is
// local to this Worker execution. Recovery can restart with candidates
// 2..N after candidate 1 was already rejected, so using `index` here
// made the shared search work unit move backward (2/3 -> 1/3).
completed: Math.max(0, candidateOrdinal - 1),
total: candidateCount,
nonCooperative: true,
}, candidateOrdinal);
let candidateWorld;
let transaction = null;
try {
if (transactional) {
transaction = capturePatchTransactionSnapshot(world, {
lightweight: false,
isolateSourceMap: true,
copyGeneratedMask: String(search?.resolvedPatchMode || "").toLowerCase() !== "regeneration",
});
candidateWorld = world;
} else {
candidateWorld = cloneWorld(world);
}
} catch (error) {
const failed = {
ok: false,
code: transactional ? "candidate-transaction-failed" : "candidate-clone-failed",
reason: error?.message || String(error),
};
attempts.push(summarizeAttempt(failed, candidate, candidateOrdinal, 0, "infrastructure-error", executionAttempt));
terminalResult = {
...failed,
searchAttempts: attempts,
searchStatus: "infrastructure-error",
nextVariant: candidate.variant >>> 0,
};
break;
}
const startedAt = clock();
let result;
try {
result = generateCandidate(candidateWorld, rect, {
...(options || {}),
seed: candidate.seed >>> 0,
variant: candidate.variant >>> 0,
maxQualityRetries: 0,
// The production Worker mutates its committed mirror transactionally
// and restores it after extracting the accepted delta. Direct callers
// retain the immutable-clone reference path for independent tests.
_workerOwnedPreview: !transactional,
_externalTransactionSnapshot: transaction,
onProgress: (progress) => {
// Producer workUnitIds are invocation-local. The same complete
// pipeline is executed again when a content-rejected candidate
// advances to the next Variant, so namespace every explicit inner
// unit by candidate ordinal before the search-wide monotonicity
// validator sees it. Do not invent an ID for a bounded producer
// that omitted one; emitProgress must still reject that protocol
// violation instead of masking it.
const rawWorkUnitId = progress?.workUnitId != null && String(progress.workUnitId).length > 0
? String(progress.workUnitId)
: null;
emitProgress({
...progress,
workUnitId: rawWorkUnitId ? `candidate-${candidateOrdinal}/${rawWorkUnitId}` : progress?.workUnitId,
variant: candidate.variant >>> 0,
seed: candidate.seed >>> 0,
}, candidateOrdinal);
},
});
if (!selectBestCandidate) result = normalizeCandidateResult(result);
} catch (error) {
if (transaction) restorePatchTransactionSnapshot(world, transaction);
if (error?.code === "worker-progress-invariant") throw error;
const wallMs = clock() - startedAt;
const failed = {
ok: false,
code: "candidate-execution-error",
reason: error?.message || String(error),
stack: error?.stack || "",
};
attempts.push(summarizeAttempt(failed, candidate, candidateOrdinal, wallMs, "execution-error", executionAttempt));
terminalResult = { ...failed, searchAttempts: attempts, searchStatus: "execution-error", nextVariant: candidate.variant >>> 0 };
break;
}
const wallMs = clock() - startedAt;
if (result?.ok) {
let candidateDelta = null;
let candidateTargetHash = null;
if (transaction) {
try {
candidateDelta = buildCommittedMirrorDeltaFromTransaction(transaction, candidateWorld);
candidateTargetHash = hashCommittedWorld(candidateWorld);
} catch (error) {
restorePatchTransactionSnapshot(world, transaction);
const failed = {
ok: false,
code: "candidate-delta-build-failed",
reason: error?.message || String(error),
};
attempts.push(summarizeAttempt(failed, candidate, candidateOrdinal, wallMs, "infrastructure-error", executionAttempt));
terminalResult = { ...failed, searchAttempts: attempts, searchStatus: "infrastructure-error", nextVariant: candidate.variant >>> 0 };
break;
}
restorePatchTransactionSnapshot(world, transaction);
}
if (!selectBestCandidate) {
successDelta = candidateDelta;
successTargetHash = candidateTargetHash;
attempts.push(summarizeAttempt(result, candidate, candidateOrdinal, wallMs, "success", executionAttempt));
result.searchAttempts = attempts;
result.searchStatus = "succeeded";
result.candidateOrdinal = candidateOrdinal;
result.candidateCount = candidateCount;
result.actualVariant = candidate.variant >>> 0;
result.actualSeed = candidate.seed >>> 0;
result.nextVariant = ((candidate.variant >>> 0) + 1) >>> 0;
if (successDelta?.previewDelta) result.previewDelta = { ...successDelta.previewDelta };
terminalResult = result;
successWorld = transactional ? null : candidateWorld;
emitProgress({ status: "done", key: "search", phase: "search", workUnitId: "candidate-search", label: `Candidate ${candidateOrdinal}/${candidateCount} accepted`, variant: candidate.variant >>> 0, completed: candidateOrdinal, total: candidateCount }, candidateOrdinal);
break;
}
if (candidateDelta?.previewDelta) result.previewDelta = { ...candidateDelta.previewDelta };
const attemptSummary = summarizeAttempt(result, candidate, candidateOrdinal, wallMs, "evaluated", executionAttempt);
attemptSummary.selectionScore = candidateQualityScore(result);
attempts.push(attemptSummary);
if (isBetterCandidate(result, candidateOrdinal, bestCandidate)) {
bestCandidate = {
result, candidate, candidateOrdinal,
world: transactional ? null : candidateWorld,
delta: candidateDelta,
targetHash: candidateTargetHash,
};
}
emitProgress({
status: "evaluated",
key: "candidate-evaluated",
phase: "candidate-result",
workUnitId: "candidate-search",
label: `Candidate ${candidateOrdinal}/${candidateCount} evaluated (quality ${candidateQualityScore(result).toFixed(3)}); continuing best-of-${candidateCount} selection`,
variant: candidate.variant >>> 0,
completed: candidateOrdinal,
total: candidateCount,
attemptSummary,
}, candidateOrdinal);
candidateWorld = null;
transaction = null;
result = null;
continue;
}
const invariant = isInvariantFailure(result);
const contentRejected = isContentRejection(result);
const status = invariant ? "invariant-breach" : contentRejected ? "rejected" : "failed";
const attemptSummary = summarizeAttempt(result, candidate, candidateOrdinal, wallMs, status, executionAttempt);
attempts.push(attemptSummary);
if (transaction) restorePatchTransactionSnapshot(world, transaction);
emitProgress({
status: contentRejected ? "rejected" : "error",
key: contentRejected ? "candidate-rejected" : "candidate-failed",
phase: "candidate-result",
label: contentRejected
? `Candidate ${candidateOrdinal}/${candidateCount} rejected; searching the next complete candidate`
: `Candidate ${candidateOrdinal}/${candidateCount} stopped: ${result?.reason || result?.code || "failure"}`,
variant: candidate.variant >>> 0,
workUnitId: "candidate-search",
completed: candidateOrdinal,
total: candidateCount,
code: result?.code || null,
attemptSummary,
}, candidateOrdinal);
if (!contentRejected) {
terminalResult = {
...(result || { ok: false }),
searchAttempts: attempts,
searchStatus: invariant ? "invariant-breach" : "failed",
nextVariant: candidate.variant >>> 0,
};
break;
}
// The rejected full world is no longer observable. Drop the last strong
// references before cloning the next Variant so the browser may reclaim
// its field buffers instead of retaining multiple complete candidates.
candidateWorld = null;
transaction = null;
result = null;
}
if (!terminalResult && selectBestCandidate && bestCandidate) {
terminalResult = finalizeBestCandidate(bestCandidate, attempts, candidatePlan, candidateCount);
successWorld = bestCandidate.world;
successDelta = bestCandidate.delta;
successTargetHash = bestCandidate.targetHash;
if (successDelta?.previewDelta) terminalResult.previewDelta = { ...successDelta.previewDelta };
emitProgress({
status: "done", key: "search", phase: "search", workUnitId: "candidate-search",
label: `Selected candidate ${bestCandidate.candidateOrdinal}/${candidateCount} with highest quality ${candidateQualityScore(bestCandidate.result).toFixed(3)}`,
variant: bestCandidate.candidate.variant >>> 0, completed: candidateCount, total: candidateCount,
}, bestCandidate.candidateOrdinal);
}
if (!terminalResult) {
const last = candidatePlan[candidatePlan.length - 1];
terminalResult = {
ok: false,
code: "patch-search-exhausted",
reason: `All ${candidateCount} complete production candidates were rejected.`,
searchStatus: "exhausted",
searchAttempts: attempts,
nextVariant: (((last?.variant || 0) >>> 0) + 1) >>> 0,
candidateCount,
};
emitProgress({ status: "done", key: "search-exhausted", phase: "search", workUnitId: "candidate-search", label: terminalResult.reason, completed: candidateCount, total: candidateCount });
}
if (successWorld && terminalResult?.ok) {
emitProgress({
status: "start",
key: "preview-delta",
phase: "preview-delta",
label: "Auditing preview changes",
}, terminalResult.candidateOrdinal || 0);
terminalResult.previewDelta = computePreviewDelta(world, successWorld, terminalResult.rects || rect, (completed, total, part) => {
emitProgress({
status: "step",
key: `preview-delta:${part}`,
phase: "preview-delta",
label: part === "raster" ? "Auditing preview raster changes" : "Auditing preview feature changes",
workUnitId: "preview-delta-audit",
completed,
total,
}, terminalResult.candidateOrdinal || 0);
});
emitProgress({
status: "done",
key: "preview-delta",
phase: "preview-delta",
label: "Preview change audit complete",
}, terminalResult.candidateOrdinal || 0);
}
// Return only the accepted candidate world. Rejected candidate clones and
// the immutable worker baseline remain worker-local and become collectible.
return {
id,
ok: true,
world: successWorld,
transactionDelta: successDelta,
targetHash: successTargetHash,
result: terminalResult,
searchId,
workerEpoch,
eventSeq,
};
} catch (error) {
return { id, ok: false, code: error?.code || "candidate-search-error", error: error?.message || String(error), stack: error?.stack || "", searchId, workerEpoch, eventSeq };
}
}
export async function runPatchCandidateSearchAsync(message, dependencies = {}) {
const { id, world, rect, options, search } = message || {};
const cloneWorld = dependencies.cloneWorld || ((value) => structuredClone(value));
const generateCandidate = dependencies.generateCandidate || generatePatchAsync;
const clock = dependencies.now || nowMs;
const publishProgress = dependencies.onProgress || (() => {});
const transactional = dependencies.transactional === true;
const selectBestCandidate = search?.selectBestCandidate === true;
const candidatePlan = Array.isArray(search?.candidatePlan) && search.candidatePlan.length
? search.candidatePlan
: [{ variant: options?.variant || 0, seed: options?.seed || world?.seed || 0 }];
const candidateCount = Math.max(candidatePlan.length, Number(search?.totalCandidateCount || candidatePlan.length));
const searchId = search?.searchId || `patch-${id}`;
const workerEpoch = Number(search?.workerEpoch || 0);
const executionAttempt = Math.max(1, Number(search?.executionAttempt || 1));
let eventSeq = 0;
let phaseOrdinal = 0;
let currentPhase = null;
const workUnits = new Map();
const emitProgress = (progress = {}, candidateOrdinal = 0) => {
const phase = String(progress.phase || progress.key || "patch");
if (phase !== currentPhase) {
currentPhase = phase;
phaseOrdinal++;
}
const hasCompleted = progress.completed != null;
const hasTotal = progress.total != null;
const completed = Number(progress.completed);
const total = Number(progress.total);
const boundedWork = hasCompleted || hasTotal;
const explicitWorkUnitId = progress.workUnitId != null && String(progress.workUnitId).length > 0;
const workUnitId = String(explicitWorkUnitId ? progress.workUnitId : (progress.key || phase));
if (boundedWork) {
if (!hasCompleted || !hasTotal || !Number.isFinite(completed) || !Number.isFinite(total)) {
const error = new Error(`Incomplete bounded progress for ${phase}/${workUnitId}: ${String(progress.completed)}/${String(progress.total)}`);
error.code = "worker-progress-invariant";
throw error;
}
if (!explicitWorkUnitId) {
const error = new Error(`Bounded progress is missing an explicit workUnitId for ${phase}/${workUnitId}.`);
error.code = "worker-progress-invariant";
throw error;
}
if (completed < 0 || total < 0 || completed > total) {
const error = new Error(`Invalid progress bounds for ${phase}/${workUnitId}: ${completed}/${total}`);
error.code = "worker-progress-invariant";
throw error;
}
// workUnitId is globally unique within one candidate-search operation.
// Do not reset its monotonicity merely because a display phase changed in
// between heartbeats; that would hide real restarts/runaway producers.
const unitKey = workUnitId;
const previous = workUnits.get(unitKey);
if (previous && (total !== previous.total || completed < previous.completed)) {
const error = new Error(`Non-monotonic progress for ${phase}/${workUnitId}: ${completed}/${total} after ${previous.completed}/${previous.total}`);
error.code = "worker-progress-invariant";
throw error;
}
const workerNow = nowMs();
const startedAtWorker = previous?.startedAtWorker ?? workerNow;
const lastAdvancedAtWorker = !previous || completed > previous.completed
? workerNow
: (previous.lastAdvancedAtWorker ?? startedAtWorker);
workUnits.set(unitKey, { completed, total, phase, startedAtWorker, lastAdvancedAtWorker });
}
eventSeq++;
publishProgress({
id,
type: "progress",
progress: {
...progress,
searchId,
operationId: search?.operationId || searchId,
candidateOrdinal,
candidateCount,
executionAttempt,
workerEpoch,
committedRevision: Number(search?.committedRevision || 0),
eventSeq,
counter: eventSeq,
phase,
phaseOrdinal,
workUnitId,
boundedWork,
startedAtWorker: boundedWork ? workUnits.get(workUnitId)?.startedAtWorker : undefined,
lastAdvancedAtWorker: boundedWork ? workUnits.get(workUnitId)?.lastAdvancedAtWorker : undefined,
cooperative: progress.nonCooperative !== true,
},
});
};
try {
if (selectBestCandidate && search?.draftSelection === true) {
const attempts = [];
const draftRows = [];
const evaluateDraft = dependencies.evaluateDraftCandidate || evaluatePatchDraftCandidate;
const prepareContext = dependencies.prepareOperationContext || preparePatchOperationContext;
let operationContext;
try {
operationContext = prepareContext(world, rect, options || {});
if (!operationContext?.ok) {
return {
id, ok: true, world: null, transactionDelta: null, targetHash: null,
result: {
ok: false,
code: operationContext?.code || "patch-draft-context-failed",
reason: operationContext?.reason || "Could not prepare patch operation context.",
searchStatus: "failed",
searchAttempts: attempts,
candidateCount,
},
searchId, workerEpoch, eventSeq,
};
}
} catch (error) {
return {
id, ok: true, world: null, transactionDelta: null, targetHash: null,
result: {
ok: false, code: "patch-draft-context-failed", reason: error?.message || String(error),
searchStatus: "infrastructure-error", searchAttempts: attempts, candidateCount,
},
searchId, workerEpoch, eventSeq,
};
}
const draftBatchTotal = candidatePlan.length;
const draftBatchFirstOrdinal = Math.max(1, Number(candidatePlan[0]?.candidateOrdinal || 1));
const draftBatchLastOrdinal = Math.max(draftBatchFirstOrdinal, Number(candidatePlan[candidatePlan.length - 1]?.candidateOrdinal || draftBatchFirstOrdinal));
const draftRankingWorkUnitId = `draft-ranking-${draftBatchFirstOrdinal}-${draftBatchLastOrdinal}`;
emitProgress({
status: "start", key: "draft-ranking", phase: "draft-ranking", workUnitId: draftRankingWorkUnitId,
label: `Scouting terrain batch ${draftBatchFirstOrdinal}-${draftBatchLastOrdinal} with admissible pruning; only complete production finalists can publish`,
completed: 0, total: draftBatchTotal,
});
// r10: generate regular-size drafts on two resident nested-worker lanes.
// Typed-array ownership is transferred back to this coordinator, so the
// helpers remain resident without retaining duplicate candidate heaps.
const parallelDrafts = new Map();
let parallelDraftRequests = null;
let parallelDraftGeneration = false;
let parallelDraftFallbackReason = null;
if (typeof dependencies.precomputeRawTerrainScoutBatch === "function"
&& search?.parallelDrafts !== false
&& candidatePlan.length > 1) {
try {
const requests = candidatePlan.map((candidate, index) => buildRawPatchTerrainScoutRequest(world, rect, {
...(options || {}),
seed: candidate.seed >>> 0,
variant: candidate.variant >>> 0,
maxQualityRetries: 0,
includeSeamVisualization: false,
_preparedPatchContext: operationContext,
_draftProxy: true,
taskId: `candidate-draft-${candidate.candidateOrdinal || index + 1}`,
}));
if (requests.every((request) => request?.ok && request.reusableForFull === true)) {
parallelDraftGeneration = true;
parallelDraftRequests = requests;
// Prime only the first two resident lanes. Later candidates are fed
// after earlier transferred drafts have been evaluated/released, so
// the coordinator never retains three complete draft graphs at once.
const requestBatch = requests.slice(0, 2);
const candidateBatch = candidatePlan.slice(0, requestBatch.length);
const drafts = await dependencies.precomputeRawTerrainScoutBatch(requestBatch, (request, progress) => {
const localIndex = requestBatch.indexOf(request);
const candidate = candidateBatch[Math.max(0, localIndex)] || candidateBatch[0];
const ordinal = Math.max(1, Number(candidate?.candidateOrdinal || localIndex + 1));
emitProgress({
...progress,
phase: `draft-lane-${String(progress?.phase || progress?.key || "generation")}`,
workUnitId: progress?.workUnitId ? `draft-lane-${ordinal}/${progress.workUnitId}` : undefined,
variant: candidate?.variant >>> 0,
seed: candidate?.seed >>> 0,
draftOnly: true,
parallelDraftLane: true,
}, ordinal);
});
for (let index = 0; index < drafts.length; index++) {
const candidate = candidateBatch[index];
const candidateId = candidate?.candidateId || `${candidate?.variant >>> 0}:${candidate?.seed >>> 0}`;
parallelDrafts.set(candidateId, drafts[index]);
}
} else {
parallelDraftFallbackReason = "selection-not-regular-production-size";
}
} catch (error) {
parallelDrafts.clear();
parallelDraftGeneration = false;
parallelDraftFallbackReason = error?.message || error?.code || "parallel-draft-failed";
emitProgress({
status: "warning", key: "draft-lane-fallback", phase: "draft-ranking", workUnitId: draftRankingWorkUnitId,
label: "Parallel terrain-scout lanes were unavailable; continuing with deterministic serial terrain scouting",
completed: 0, total: draftBatchTotal,
code: error?.code || "parallel-draft-fallback",
});
}
}
for (let index = 0; index < candidatePlan.length; index++) {
const candidate = candidatePlan[index];
const candidateOrdinal = Math.max(1, Number(candidate.candidateOrdinal || index + 1));
const candidateId = candidate.candidateId || `${candidate.variant >>> 0}:${candidate.seed >>> 0}`;
const startedAt = clock();
let draftResult;
if (parallelDraftGeneration && !parallelDrafts.has(candidateId) && parallelDraftRequests?.[index]) {
try {
const [draft] = await dependencies.precomputeRawTerrainScoutBatch([parallelDraftRequests[index]], (request, progress) => {
emitProgress({
...progress,
phase: `draft-lane-${String(progress?.phase || progress?.key || "generation")}`,
workUnitId: progress?.workUnitId ? `draft-lane-${candidateOrdinal}/${progress.workUnitId}` : undefined,
variant: candidate.variant >>> 0,
seed: candidate.seed >>> 0,
draftOnly: true,
parallelDraftLane: true,
}, candidateOrdinal);
});
if (draft) parallelDrafts.set(candidateId, draft);
} catch (error) {
parallelDraftFallbackReason = error?.message || error?.code || "parallel-draft-feed-failed";
}
}
try {
draftResult = await evaluateDraft(world, rect, {
...(options || {}),
seed: candidate.seed >>> 0,
variant: candidate.variant >>> 0,
maxQualityRetries: 0,
includeSeamVisualization: false,
_preparedPatchContext: operationContext,
_terrainScoutOnly: true,
_precomputedTerrainDraftCandidate: parallelDrafts.get(candidateId) || null,
onProgress: (progress) => {
const rawWorkUnitId = progress?.workUnitId != null && String(progress.workUnitId).length > 0
? String(progress.workUnitId)
: null;
emitProgress({
...progress,
phase: `draft-${String(progress?.phase || progress?.key || "generation")}`,
workUnitId: rawWorkUnitId ? `draft-${candidateOrdinal}/${rawWorkUnitId}` : progress?.workUnitId,
variant: candidate.variant >>> 0,
seed: candidate.seed >>> 0,
draftOnly: true,
}, candidateOrdinal);
},
});
} catch (error) {
const wallMs = clock() - startedAt;
const failed = { ok: false, code: "candidate-draft-error", reason: error?.message || String(error) };
const summary = summarizeAttempt(failed, candidate, candidateOrdinal, wallMs, "draft-failed", executionAttempt);
summary.draftOnly = true;
attempts.push(summary);
emitProgress({
status: "error", key: "draft-candidate-failed", phase: "draft-ranking", workUnitId: draftRankingWorkUnitId,
label: `Draft ${candidateOrdinal}/${candidateCount} failed; continuing with remaining drafts`,
completed: index + 1, total: draftBatchTotal, variant: candidate.variant >>> 0, code: failed.code,
}, candidateOrdinal);
continue;
} finally {
parallelDrafts.delete(candidateId);
}
const wallMs = clock() - startedAt;
if (!draftResult?.ok || !Number.isFinite(draftCandidateScore(draftResult))) {
const failed = draftResult?.ok === false
? draftResult
: { ok: false, code: "candidate-draft-score-invalid", reason: "Draft ranking did not produce a finite score." };
const summary = summarizeAttempt(failed, candidate, candidateOrdinal, wallMs, "draft-failed", executionAttempt);
summary.draftOnly = true;
attempts.push(summary);
emitProgress({
status: "error", key: "draft-candidate-failed", phase: "draft-ranking", workUnitId: draftRankingWorkUnitId,
label: `Draft ${candidateOrdinal}/${candidateCount} could not be ranked`,
completed: index + 1, total: draftBatchTotal, variant: candidate.variant >>> 0, code: failed.code || null,
}, candidateOrdinal);
continue;
}
const score = draftCandidateScore(draftResult);
const qualityUpperBound = draftCandidateUpperBound(draftResult);
const hardPruned = draftAdmissibleHardReject(draftResult);
const summary = summarizeAttempt(draftResult, candidate, candidateOrdinal, wallMs, hardPruned ? "pruned" : "evaluated", executionAttempt);
summary.draftOnly = true;
summary.draftQuality = compactDraftQuality(draftResult);
summary.selectionScore = score;
summary.qualityUpperBound = qualityUpperBound;
summary.admissibleHardReject = hardPruned;
summary.earlyRejectStage = draftResult.earlyRejectStage || null;
summary.fullFinalized = false;
summary.fullGenerationPasses = 0;
attempts.push(summary);
const row = {
candidate, candidateOrdinal, candidateId,
draftResult: {
ok: true,
score,
qualityUpperBound,
admissibleHardReject: hardPruned,
earlyRejectStage: draftResult.earlyRejectStage || null,
candidateQuality: draftResult.candidateQuality || null,
reusableForFull: draftResult.reusableForFull === true,
},
precomputedDraft: draftResult.reusableForFull === true ? retainProductionTerrainDraft(draftResult.precomputedDraft) : null,
};
draftRows.push(row);
draftResult.precomputedDraft = null;
// Before feeding the next resident-lane result, retain only the strongest
// already-scored draft. A dropped candidate remains fully reproducible
// from its deterministic seed/variant if Branch-and-Bound later needs it.
if (index < candidatePlan.length - 1) {
const seenWithDraft = draftRows.filter((entry) => entry.precomputedDraft);
if (seenWithDraft.length > 1) {
seenWithDraft.sort((a, b) => {
const scoreDelta = draftCandidateScore(b.draftResult) - draftCandidateScore(a.draftResult);
if (Math.abs(scoreDelta) > 1e-12) return scoreDelta;
const boundDelta = draftCandidateUpperBound(b.draftResult) - draftCandidateUpperBound(a.draftResult);
if (Math.abs(boundDelta) > 1e-12) return boundDelta;
return a.candidateOrdinal - b.candidateOrdinal;
});
for (const discard of seenWithDraft.slice(1)) discard.precomputedDraft = null;
}
}
emitProgress({
status: hardPruned ? "pruned" : "evaluated",
key: hardPruned ? "draft-candidate-pruned" : "draft-candidate-evaluated",
phase: "draft-ranking", workUnitId: draftRankingWorkUnitId,
label: hardPruned
? `Terrain scout ${candidateOrdinal}/${candidateCount} rejected at ${row.draftResult.earlyRejectStage || "immutable terrain safety"}`
: `Terrain scout ${candidateOrdinal}/${candidateCount} ranked at ${score.toFixed(3)} (final upper ${qualityUpperBound.toFixed(3)})`,
completed: index + 1, total: draftBatchTotal, variant: candidate.variant >>> 0,
attemptSummary: summary, draftOnly: true,
}, candidateOrdinal);
draftResult = null;
}
const rankedAll = rankedDraftCandidates(draftRows);
const ranked = rankedAll.filter((row) => !draftAdmissibleHardReject(row.draftResult));
if (!ranked.length) {
const last = candidatePlan[candidatePlan.length - 1];
const result = {
ok: false,
code: "patch-draft-search-exhausted",
reason: `All ${candidatePlan.length} candidates in this quality batch were proven unable to satisfy the full production contract before finalization.`,
searchStatus: "exhausted",
searchAttempts: attempts,
nextVariant: (((last?.variant || 0) >>> 0) + 1) >>> 0,
candidateCount,
draftSelection: true,
};
emitProgress({
status: "done", key: "draft-ranking-exhausted", phase: "draft-ranking", workUnitId: draftRankingWorkUnitId,
label: result.reason, completed: draftBatchTotal, total: draftBatchTotal,
});
return { id, ok: true, world: null, transactionDelta: null, targetHash: null, result, searchId, workerEpoch, eventSeq };
}
// Bound peak retained draft memory at two candidates: the rank-1 proxy and
// the strongest remaining admissible upper bound. Any later contender can
// deterministically regenerate its draft if Branch-and-Bound proves it is
// still capable of winning after the first full evaluation.
const retainedDrafts = new Map();
const keepRows = [ranked[0]];
const upperBoundRunner = ranked.slice(1).sort((a, b) => {
const boundDelta = draftCandidateUpperBound(b.draftResult) - draftCandidateUpperBound(a.draftResult);
if (Math.abs(boundDelta) > 1e-12) return boundDelta;
return draftCandidateScore(b.draftResult) - draftCandidateScore(a.draftResult);
})[0];
if (upperBoundRunner) keepRows.push(upperBoundRunner);
const keepIds = new Set(keepRows.map((row) => row.candidateId));
for (const row of draftRows) {
if (keepIds.has(row.candidateId) && row.precomputedDraft) retainedDrafts.set(row.candidateId, { draft: row.precomputedDraft });
row.precomputedDraft = null;
}
emitProgress({
status: "done", key: "draft-ranking", phase: "draft-ranking", workUnitId: draftRankingWorkUnitId,
label: `Terrain scouting complete; admissible Branch-and-Bound starts from candidate ${ranked[0].candidateOrdinal}/${candidateCount}`,
completed: draftBatchTotal, total: draftBatchTotal,
}, ranked[0].candidateOrdinal);
let fullGenerationPassCount = 0;
const fullFinalizedCandidateIds = new Set();
const fullComparedCandidateOrdinals = [];
let branchBoundPrunedCount = rankedAll.length - ranked.length;
const branchBoundPrunedCandidateOrdinals = rankedAll
.filter((row) => draftAdmissibleHardReject(row.draftResult))
.map((row) => row.candidateOrdinal);
const recordFullAttempt = (row, result, wallMs, status) => {
const prior = attempts.find((entry) => entry.candidateId === row.candidateId);
const previousPasses = Number(prior?.fullGenerationPasses || 0);
const previousFullWallMs = Number(prior?.fullWallMs || 0);
const draftQuality = prior?.draftQuality || compactDraftQuality(row.draftResult);
const summary = summarizeAttempt(result, row.candidate, row.candidateOrdinal, wallMs, status, executionAttempt);
if (prior) {
Object.assign(prior, summary, {
draftQuality,
draftOnly: false,
fullFinalized: true,
draftSelectionScore: row.draftResult.score,
qualityUpperBound: draftCandidateUpperBound(row.draftResult),
selected: false,
});
prior.fullGenerationPasses = previousPasses + 1;
prior.fullWallMs = Math.round((previousFullWallMs + wallMs) * 10) / 10;
prior.wallMs = prior.fullWallMs;
}
fullFinalizedCandidateIds.add(row.candidateId);
if (!fullComparedCandidateOrdinals.includes(row.candidateOrdinal)) fullComparedCandidateOrdinals.push(row.candidateOrdinal);
return prior;
};
const executeFullCandidate = async (row, { preserveSuccess = false, label = null, materializationPass = false } = {}) => {
const { candidate, candidateOrdinal, candidateId } = row;
fullGenerationPassCount++;
const passOrdinal = fullGenerationPassCount;
const finalistWorkUnitId = `finalist-${candidateOrdinal}-pass-${passOrdinal}-generation`;
emitProgress({
status: "start", key: "finalist-generation", phase: "finalist-generation", workUnitId: finalistWorkUnitId,
label: label || `Finalizing draft ${candidateOrdinal}/${candidateCount}`,
completed: 0, total: 1, variant: candidate.variant >>> 0,
materializationPass,
}, candidateOrdinal);
let candidateWorld;
let transaction = null;
try {
if (transactional) {
transaction = capturePatchTransactionSnapshot(world, {
lightweight: false,
isolateSourceMap: true,
copyGeneratedMask: String(search?.resolvedPatchMode || "").toLowerCase() !== "regeneration",
});
candidateWorld = world;
} else {
candidateWorld = cloneWorld(world);
}
} catch (error) {
const failed = { ok: false, code: transactional ? "candidate-transaction-failed" : "candidate-clone-failed", reason: error?.message || String(error) };
return {
terminal: { ...failed, searchAttempts: attempts, searchStatus: "infrastructure-error", candidateCount, draftSelection: true },
};
}
const startedAt = clock();
let result;
try {
result = await generateCandidate(candidateWorld, rect, {
...(options || {}),
seed: candidate.seed >>> 0,
variant: candidate.variant >>> 0,
maxQualityRetries: 0,
_workerOwnedPreview: !transactional,
_externalTransactionSnapshot: transaction,
_preparedPatchContext: operationContext,
// Draft features are ranking-only and are never publishable. Reuse
// only the exact terrain field; geography, settlements, admin, and
// transport rerun with full production parity.
_precomputedDraftCandidate: null,
_precomputedTerrainDraftCandidate: retainedDrafts.get(candidateId)?.draft || null,
_precomputeRawCandidateBatch: dependencies.precomputeRawCandidateBatch,
_precomputeRawCandidateSequence: dependencies.precomputeRawCandidateSequence,
_rawCandidateParallelism: Math.max(1, Math.min(2, Number(dependencies.rawCandidateParallelism || 2))),
onProgress: (progress) => {
const rawWorkUnitId = progress?.workUnitId != null && String(progress.workUnitId).length > 0
? String(progress.workUnitId)
: null;
emitProgress({
...progress,
workUnitId: rawWorkUnitId ? `finalist-${candidateOrdinal}-pass-${passOrdinal}/${rawWorkUnitId}` : progress?.workUnitId,
variant: candidate.variant >>> 0,
seed: candidate.seed >>> 0,
finalist: true,
materializationPass,
}, candidateOrdinal);
},
});
} catch (error) {
if (transaction) restorePatchTransactionSnapshot(world, transaction);
if (error?.code === "worker-progress-invariant") throw error;
const wallMs = clock() - startedAt;
const failed = { ok: false, code: "candidate-execution-error", reason: error?.message || String(error), stack: error?.stack || "" };
recordFullAttempt(row, failed, wallMs, "execution-error");
return {
terminal: { ...failed, searchAttempts: attempts, searchStatus: "execution-error", nextVariant: candidate.variant >>> 0, candidateCount, draftSelection: true },
};
}
const wallMs = clock() - startedAt;
if (!result?.ok) {
if (transaction) restorePatchTransactionSnapshot(world, transaction);
const invariant = isInvariantFailure(result);
const contentRejected = isContentRejection(result);
recordFullAttempt(row, result, wallMs, invariant ? "invariant-breach" : contentRejected ? "rejected" : "failed");
emitProgress({
status: contentRejected ? "rejected" : "error",
key: contentRejected ? "finalist-content-rejected" : "finalist-generation-failed",
phase: "finalist-generation", workUnitId: finalistWorkUnitId,
label: contentRejected
? `Finalist ${candidateOrdinal}/${candidateCount} was content-rejected`
: `Finalist ${candidateOrdinal}/${candidateCount} failed`,
completed: 1, total: 1, variant: candidate.variant >>> 0, code: result?.code || null,
}, candidateOrdinal);
if (!contentRejected || invariant) {
return {
terminal: {
...(result || { ok: false }),
searchAttempts: attempts,
searchStatus: invariant ? "invariant-breach" : "failed",
nextVariant: candidate.variant >>> 0,
candidateCount,
draftSelection: true,
},
};
}
return { row, result, contentRejected: true, wallMs, restored: true };
}
recordFullAttempt(row, result, wallMs, "evaluated");
emitProgress({
status: "done", key: "finalist-generation", phase: "finalist-generation", workUnitId: finalistWorkUnitId,
label: materializationPass
? `Materialized selected candidate ${candidateOrdinal}/${candidateCount}`
: `Full evaluation complete for candidate ${candidateOrdinal}/${candidateCount}`,
completed: 1, total: 1, variant: candidate.variant >>> 0,
materializationPass,
}, candidateOrdinal);
if (transaction && !preserveSuccess) {
restorePatchTransactionSnapshot(world, transaction);
return { row, result, candidateWorld: null, transaction: null, restored: true, wallMs };
}
return { row, result, candidateWorld, transaction, restored: false, wallMs };
};
const captureWinnerArtifact = (row, execution) => {
if (!execution?.result?.ok) return { ok: false, code: "candidate-artifact-result-missing" };
if (!transactional) {
// Non-transactional test/in-process callers already generated into an
// isolated clone. Retain that exact full-production world instead of
// regenerating the winner after comparing later challengers.
return { ok: true, world: execution.candidateWorld || null, delta: null, targetHash: null };
}
if (!execution?.transaction || execution.restored) {
return { ok: false, code: "candidate-materialization-state-missing", reason: "Candidate is not materialized on the transactional mirror." };
}
try {
// Keep a bounded replay state for a provisional winner, not the final
// committed Apply artifact. This avoids an expensive winner
// rematerialization if a later challenger loses, while the official
// committed delta/hash are still built exactly once for the final
// selected candidate at publication time.
return {
ok: true,
provisionalDelta: buildCommittedMirrorDeltaFromTransaction(execution.transaction, execution.candidateWorld),
world: null,
};
} catch (error) {
return { ok: false, code: "candidate-provisional-state-build-failed", reason: error?.message || String(error) };
}
};
const publishSuccessfulCandidate = (row, execution, selectionReason) => {
const { candidate, candidateOrdinal, candidateId } = row;
let successDelta = null;
let successTargetHash = null;
let successWorldArtifact = execution?.winnerArtifact?.world || null;
if (transactional) {
const buildWinnerDelta = dependencies.buildCommittedDeltaFromTransaction || buildCommittedMirrorDeltaFromTransaction;
const hashWinnerWorld = dependencies.hashCommittedWorld || hashCommittedWorld;
let publishTransaction = execution?.transaction || null;
let materializedFromCache = false;
try {
if (execution?.winnerArtifact?.provisionalDelta && (!publishTransaction || execution.restored)) {
publishTransaction = capturePatchTransactionSnapshot(world, {
lightweight: false,
isolateSourceMap: true,
copyGeneratedMask: String(search?.resolvedPatchMode || "").toLowerCase() !== "regeneration",
});
applyCommittedWorldDelta(world, execution.winnerArtifact.provisionalDelta);
materializedFromCache = true;
}
if (!publishTransaction || (execution.restored && !materializedFromCache)) {
throw new Error("Selected candidate is not materialized on the transactional mirror.");
}
// r11.6: only the final selected candidate constructs the public
// committed delta and whole-world hash. Provisional winners retain
// a replay state only, so multi-finalist comparison no longer forces
// a full winner regeneration and still preserves the r6 delta/hash
// single-build contract.
successDelta = buildWinnerDelta(publishTransaction, world);
successTargetHash = hashWinnerWorld(world);
} catch (error) {
if (publishTransaction) restorePatchTransactionSnapshot(world, publishTransaction);
const failed = { ok: false, code: "candidate-delta-build-failed", reason: error?.message || String(error) };
return {
terminal: { ...failed, searchAttempts: attempts, searchStatus: "infrastructure-error", nextVariant: candidate.variant >>> 0, candidateCount, draftSelection: true },
};
}
if (publishTransaction) restorePatchTransactionSnapshot(world, publishTransaction);
if (execution?.transaction === publishTransaction) execution.restored = true;
}
const result = execution.result;
const prior = attempts.find((entry) => entry.candidateId === candidateId);
const draftQuality = prior?.draftQuality || compactDraftQuality(row.draftResult);
if (prior) {
prior.status = "success";
prior.ok = true;
prior.selected = true;
prior.draftQuality = draftQuality;
prior.draftOnly = false;
prior.fullFinalized = true;
prior.draftSelectionScore = row.draftResult.score;
}
for (const attempt of attempts) if (attempt !== prior) attempt.selected = false;
const last = candidatePlan[candidatePlan.length - 1] || candidate;
result.searchAttempts = attempts;
result.searchStatus = "succeeded";
result.candidateOrdinal = candidateOrdinal;
result.candidateCount = candidateCount;
result.actualVariant = candidate.variant >>> 0;
result.actualSeed = candidate.seed >>> 0;
result.nextVariant = (((last?.variant || 0) >>> 0) + 1) >>> 0;
result.bestOfCandidates = true;
result.evaluatedCandidateCount = draftRows.length;
result.selectionScore = candidateQualityScore(result);
result.draftSelectionScore = row.draftResult.score;
result.draftSelection = {
enabled: true,
policy: "admissible-terrain-scout-branch-and-bound-two-lane-v2",
finalistCandidateOrdinal: candidateOrdinal,
finalistVariant: candidate.variant >>> 0,
draftCount: draftRows.length,
fullCandidateCount: fullFinalizedCandidateIds.size,
fullGenerationPassCount,
reusedWinningDraft: false,
reusedTerrainDraft: !!retainedDrafts.get(candidateId)?.draft,
fullProductionFromTerrainOnly: true,
parallelDraftGeneration, // legacy metadata name retained for UI compatibility
parallelDraftLaneCount: parallelDraftGeneration ? 2 : 0,
parallelTerrainScoutGeneration: parallelDraftGeneration,
terrainScoutLaneCount: parallelDraftGeneration ? 2 : 0,
parallelDraftFallbackReason,
branchBoundPrunedCount,
branchBoundPrunedCandidateOrdinals: branchBoundPrunedCandidateOrdinals.slice(),
selectionReason,
fullComparedCandidateOrdinals: fullComparedCandidateOrdinals.slice(),
ranking: rankedAll.map((entry, rank) => ({
rank: rank + 1,
candidateOrdinal: entry.candidateOrdinal,
variant: entry.candidate.variant >>> 0,
seed: entry.candidate.seed >>> 0,
score: entry.draftResult.score,
qualityUpperBound: draftCandidateUpperBound(entry.draftResult),
admissibleHardReject: draftAdmissibleHardReject(entry.draftResult),
})),
};
if (successDelta?.previewDelta) result.previewDelta = { ...successDelta.previewDelta };
return {
payload: {
id, ok: true,
world: transactional ? null : (successWorldArtifact || execution.candidateWorld),
transactionDelta: successDelta,
targetHash: successTargetHash,
result, searchId, workerEpoch, eventSeq,
},
};
};
let provisionalBest = null;
const remaining = ranked.slice();
while (remaining.length) {
const row = remaining.shift();
const currentBestScore = provisionalBest ? candidateQualityScore(provisionalBest.result) : -Infinity;
const upperBound = draftCandidateUpperBound(row.draftResult);
// Strict '<' preserves the existing deterministic seam/tie-break rules:
// an equal-score candidate can still win on seam quality, so equality is
// never pruned.
if (provisionalBest && upperBound < currentBestScore - 1e-12) {
branchBoundPrunedCount++;
branchBoundPrunedCandidateOrdinals.push(row.candidateOrdinal);
const prior = attempts.find((entry) => entry.candidateId === row.candidateId);
if (prior) {
prior.status = "bound-pruned";
prior.branchBoundBestScore = currentBestScore;
prior.qualityUpperBound = upperBound;
}
emitProgress({
status: "pruned", key: "branch-bound-pruned", phase: "finalist-generation",
workUnitId: `branch-bound-${row.candidateOrdinal}`,
label: `Candidate ${row.candidateOrdinal}/${candidateCount} cannot beat ${currentBestScore.toFixed(3)} (upper ${upperBound.toFixed(3)})`,
variant: row.candidate.variant >>> 0,
nonCooperative: true,
}, row.candidateOrdinal);
continue;
}
const execution = await executeFullCandidate(row, {
preserveSuccess: true,
label: `Fully evaluating candidate ${row.candidateOrdinal}/${candidateCount} (upper ${upperBound.toFixed(3)})`,
});
if (execution.terminal) {
return { id, ok: true, world: null, transactionDelta: null, targetHash: null, result: execution.terminal, searchId, workerEpoch, eventSeq };
}
if (execution.contentRejected || !execution.result?.ok) continue;
if (!provisionalBest || isBetterCandidate(execution.result, row.candidateOrdinal, {
result: provisionalBest.result,
candidateOrdinal: provisionalBest.row.candidateOrdinal,
})) {
// Capture the exact full-production state while it is live. If a later
// challenger does not beat it, r11.5 used to rerun the entire large
// candidate solely to reconstruct the winner. A bounded delta/hash
// (or isolated clone for non-transactional tests) removes that extra
// full generation pass without changing candidate comparison.
const winnerArtifact = captureWinnerArtifact(row, execution);
if (!winnerArtifact.ok) {
if (execution.transaction && !execution.restored) {
restorePatchTransactionSnapshot(world, execution.transaction);
execution.restored = true;
}
return { id, ok: true, world: null, transactionDelta: null, targetHash: null, result: {
ok: false,
code: winnerArtifact.code || "candidate-delta-build-failed",
reason: winnerArtifact.reason || "Could not retain provisional winner state.",
searchAttempts: attempts,
searchStatus: "infrastructure-error",
candidateCount,
draftSelection: true,
}, searchId, workerEpoch, eventSeq };
}
execution.winnerArtifact = winnerArtifact;
provisionalBest = { row, result: execution.result, winnerArtifact };
}
const bestScore = candidateQualityScore(provisionalBest.result);
const hasPotentialChallenger = remaining.some((future) => draftCandidateUpperBound(future.draftResult) >= bestScore - 1e-12);
const currentIsBest = provisionalBest.row.candidateId === row.candidateId;
if (currentIsBest && !hasPotentialChallenger) {
// Prune all remaining candidates now for diagnostics, then publish the
// live transaction without an avoidable rematerialization pass.
for (const future of remaining) {
branchBoundPrunedCount++;
branchBoundPrunedCandidateOrdinals.push(future.candidateOrdinal);
const prior = attempts.find((entry) => entry.candidateId === future.candidateId);
if (prior) {
prior.status = "bound-pruned";
prior.branchBoundBestScore = bestScore;
prior.qualityUpperBound = draftCandidateUpperBound(future.draftResult);
}
}
remaining.length = 0;
const published = publishSuccessfulCandidate(row, execution, "admissible-bound-winner-live");
if (published.terminal) return { id, ok: true, world: null, transactionDelta: null, targetHash: null, result: published.terminal, searchId, workerEpoch, eventSeq };
return published.payload;
}
// Another candidate can still win, or this candidate did not beat the
// previous best. Roll back the live mirror before the next challenger.
if (execution.transaction && !execution.restored) {
restorePatchTransactionSnapshot(world, execution.transaction);
execution.restored = true;
}
}
if (provisionalBest) {
const published = publishSuccessfulCandidate(provisionalBest.row, {
result: provisionalBest.result,
winnerArtifact: provisionalBest.winnerArtifact,
candidateWorld: provisionalBest.winnerArtifact?.world || null,
transaction: null,
restored: true,
}, "admissible-bound-cached-winner");
if (published.terminal) return { id, ok: true, world: null, transactionDelta: null, targetHash: null, result: published.terminal, searchId, workerEpoch, eventSeq };
return published.payload;
}
const last = candidatePlan[candidatePlan.length - 1];
const terminal = {
ok: false, code: "patch-search-exhausted",
reason: `All ${candidatePlan.length} candidates in this quality batch failed or were proven unable to satisfy the full production quality gate.`,
searchStatus: "exhausted", searchAttempts: attempts, candidateCount, draftSelection: true,
nextVariant: (((last?.variant || 0) >>> 0) + 1) >>> 0,
};
return { id, ok: true, world: null, transactionDelta: null, targetHash: null, result: terminal, searchId, workerEpoch, eventSeq };
}
const attempts = [];
let terminalResult = null;
let successWorld = null;
let successDelta = null;
let successTargetHash = null;
let bestCandidate = null;
emitProgress({ status: "start", key: "search", phase: "search", workUnitId: "candidate-search", label: selectBestCandidate
? `Evaluating ${candidateCount} complete candidates and selecting the highest-quality result`
: `Searching ${candidateCount} complete candidate${candidateCount === 1 ? "" : "s"}`, completed: 0, total: candidateCount });
for (let index = 0; index < candidatePlan.length; index++) {
const candidate = candidatePlan[index];
const candidateOrdinal = Math.max(1, Number(candidate.candidateOrdinal || index + 1));
emitProgress({
status: "start",
key: transactional ? "candidate-transaction" : "candidate-clone",
phase: transactional ? "candidate-transaction" : "candidate-clone",
label: transactional
? `Candidate ${candidateOrdinal}/${candidateCount}: capturing exact rollback state`
: `Candidate ${candidateOrdinal}/${candidateCount}: preparing immutable baseline`,
variant: candidate.variant >>> 0,
workUnitId: "candidate-search",
// candidateOrdinal is global across the full search, whereas `index` is
// local to this Worker execution. Recovery can restart with candidates
// 2..N after candidate 1 was already rejected, so using `index` here
// made the shared search work unit move backward (2/3 -> 1/3).
completed: Math.max(0, candidateOrdinal - 1),
total: candidateCount,
nonCooperative: true,
}, candidateOrdinal);
let candidateWorld;
let transaction = null;
try {
if (transactional) {
transaction = capturePatchTransactionSnapshot(world, {
lightweight: false,
isolateSourceMap: true,
copyGeneratedMask: String(search?.resolvedPatchMode || "").toLowerCase() !== "regeneration",
});
candidateWorld = world;
} else {
candidateWorld = cloneWorld(world);
}
} catch (error) {
const failed = {
ok: false,
code: transactional ? "candidate-transaction-failed" : "candidate-clone-failed",
reason: error?.message || String(error),
};
attempts.push(summarizeAttempt(failed, candidate, candidateOrdinal, 0, "infrastructure-error", executionAttempt));
terminalResult = {
...failed,
searchAttempts: attempts,
searchStatus: "infrastructure-error",
nextVariant: candidate.variant >>> 0,
};
break;
}
const startedAt = clock();
let result;
try {
result = await generateCandidate(candidateWorld, rect, {
...(options || {}),
seed: candidate.seed >>> 0,
variant: candidate.variant >>> 0,
maxQualityRetries: 0,
// The production Worker mutates its committed mirror transactionally
// and restores it after extracting the accepted delta. Direct callers
// retain the immutable-clone reference path for independent tests.
_workerOwnedPreview: !transactional,
_externalTransactionSnapshot: transaction,
_precomputeRawCandidateBatch: dependencies.precomputeRawCandidateBatch,
_precomputeRawCandidateSequence: dependencies.precomputeRawCandidateSequence,
_rawCandidateParallelism: Math.max(1, Math.min(2, Number(dependencies.rawCandidateParallelism || 2))),
onProgress: (progress) => {
// Producer workUnitIds are invocation-local. The same complete
// pipeline is executed again when a content-rejected candidate
// advances to the next Variant, so namespace every explicit inner
// unit by candidate ordinal before the search-wide monotonicity
// validator sees it. Do not invent an ID for a bounded producer
// that omitted one; emitProgress must still reject that protocol
// violation instead of masking it.
const rawWorkUnitId = progress?.workUnitId != null && String(progress.workUnitId).length > 0
? String(progress.workUnitId)
: null;
emitProgress({
...progress,
workUnitId: rawWorkUnitId ? `candidate-${candidateOrdinal}/${rawWorkUnitId}` : progress?.workUnitId,
variant: candidate.variant >>> 0,
seed: candidate.seed >>> 0,
}, candidateOrdinal);
},
});
if (!selectBestCandidate) result = normalizeCandidateResult(result);
} catch (error) {
if (transaction) restorePatchTransactionSnapshot(world, transaction);
if (error?.code === "worker-progress-invariant") throw error;
const wallMs = clock() - startedAt;
const failed = {
ok: false,
code: "candidate-execution-error",
reason: error?.message || String(error),
stack: error?.stack || "",
};
attempts.push(summarizeAttempt(failed, candidate, candidateOrdinal, wallMs, "execution-error", executionAttempt));
terminalResult = { ...failed, searchAttempts: attempts, searchStatus: "execution-error", nextVariant: candidate.variant >>> 0 };
break;
}
const wallMs = clock() - startedAt;
if (result?.ok) {
let candidateDelta = null;
let candidateTargetHash = null;
if (transaction) {
try {
candidateDelta = buildCommittedMirrorDeltaFromTransaction(transaction, candidateWorld);
candidateTargetHash = hashCommittedWorld(candidateWorld);
} catch (error) {
restorePatchTransactionSnapshot(world, transaction);
const failed = {
ok: false,
code: "candidate-delta-build-failed",
reason: error?.message || String(error),
};
attempts.push(summarizeAttempt(failed, candidate, candidateOrdinal, wallMs, "infrastructure-error", executionAttempt));
terminalResult = { ...failed, searchAttempts: attempts, searchStatus: "infrastructure-error", nextVariant: candidate.variant >>> 0 };
break;
}
restorePatchTransactionSnapshot(world, transaction);
}
if (!selectBestCandidate) {
successDelta = candidateDelta;
successTargetHash = candidateTargetHash;
attempts.push(summarizeAttempt(result, candidate, candidateOrdinal, wallMs, "success", executionAttempt));
result.searchAttempts = attempts;
result.searchStatus = "succeeded";
result.candidateOrdinal = candidateOrdinal;
result.candidateCount = candidateCount;
result.actualVariant = candidate.variant >>> 0;
result.actualSeed = candidate.seed >>> 0;
result.nextVariant = ((candidate.variant >>> 0) + 1) >>> 0;
if (successDelta?.previewDelta) result.previewDelta = { ...successDelta.previewDelta };
terminalResult = result;
successWorld = transactional ? null : candidateWorld;
emitProgress({ status: "done", key: "search", phase: "search", workUnitId: "candidate-search", label: `Candidate ${candidateOrdinal}/${candidateCount} accepted`, variant: candidate.variant >>> 0, completed: candidateOrdinal, total: candidateCount }, candidateOrdinal);
break;
}
if (candidateDelta?.previewDelta) result.previewDelta = { ...candidateDelta.previewDelta };
const attemptSummary = summarizeAttempt(result, candidate, candidateOrdinal, wallMs, "evaluated", executionAttempt);
attemptSummary.selectionScore = candidateQualityScore(result);
attempts.push(attemptSummary);
if (isBetterCandidate(result, candidateOrdinal, bestCandidate)) {
bestCandidate = {
result, candidate, candidateOrdinal,
world: transactional ? null : candidateWorld,
delta: candidateDelta,
targetHash: candidateTargetHash,
};
}
emitProgress({
status: "evaluated",
key: "candidate-evaluated",
phase: "candidate-result",
workUnitId: "candidate-search",
label: `Candidate ${candidateOrdinal}/${candidateCount} evaluated (quality ${candidateQualityScore(result).toFixed(3)}); continuing best-of-${candidateCount} selection`,
variant: candidate.variant >>> 0,
completed: candidateOrdinal,
total: candidateCount,
attemptSummary,
}, candidateOrdinal);
candidateWorld = null;
transaction = null;
result = null;
continue;
}
const invariant = isInvariantFailure(result);
const contentRejected = isContentRejection(result);
const status = invariant ? "invariant-breach" : contentRejected ? "rejected" : "failed";
const attemptSummary = summarizeAttempt(result, candidate, candidateOrdinal, wallMs, status, executionAttempt);
attempts.push(attemptSummary);
if (transaction) restorePatchTransactionSnapshot(world, transaction);
emitProgress({
status: contentRejected ? "rejected" : "error",
key: contentRejected ? "candidate-rejected" : "candidate-failed",
phase: "candidate-result",
label: contentRejected
? `Candidate ${candidateOrdinal}/${candidateCount} rejected; searching the next complete candidate`
: `Candidate ${candidateOrdinal}/${candidateCount} stopped: ${result?.reason || result?.code || "failure"}`,
variant: candidate.variant >>> 0,
workUnitId: "candidate-search",
completed: candidateOrdinal,
total: candidateCount,
code: result?.code || null,
attemptSummary,
}, candidateOrdinal);
if (!contentRejected) {
terminalResult = {
...(result || { ok: false }),
searchAttempts: attempts,
searchStatus: invariant ? "invariant-breach" : "failed",
nextVariant: candidate.variant >>> 0,
};
break;
}
// The rejected full world is no longer observable. Drop the last strong
// references before cloning the next Variant so the browser may reclaim
// its field buffers instead of retaining multiple complete candidates.
candidateWorld = null;
transaction = null;
result = null;
}
if (!terminalResult && selectBestCandidate && bestCandidate) {
terminalResult = finalizeBestCandidate(bestCandidate, attempts, candidatePlan, candidateCount);
successWorld = bestCandidate.world;
successDelta = bestCandidate.delta;
successTargetHash = bestCandidate.targetHash;
if (successDelta?.previewDelta) terminalResult.previewDelta = { ...successDelta.previewDelta };
emitProgress({
status: "done", key: "search", phase: "search", workUnitId: "candidate-search",
label: `Selected candidate ${bestCandidate.candidateOrdinal}/${candidateCount} with highest quality ${candidateQualityScore(bestCandidate.result).toFixed(3)}`,
variant: bestCandidate.candidate.variant >>> 0, completed: candidateCount, total: candidateCount,
}, bestCandidate.candidateOrdinal);
}
if (!terminalResult) {
const last = candidatePlan[candidatePlan.length - 1];
terminalResult = {
ok: false,
code: "patch-search-exhausted",
reason: `All ${candidateCount} complete production candidates were rejected.`,
searchStatus: "exhausted",
searchAttempts: attempts,
nextVariant: (((last?.variant || 0) >>> 0) + 1) >>> 0,
candidateCount,
};
emitProgress({ status: "done", key: "search-exhausted", phase: "search", workUnitId: "candidate-search", label: terminalResult.reason, completed: candidateCount, total: candidateCount });
}
if (successWorld && terminalResult?.ok) {
emitProgress({
status: "start",
key: "preview-delta",
phase: "preview-delta",
label: "Auditing preview changes",
}, terminalResult.candidateOrdinal || 0);
terminalResult.previewDelta = computePreviewDelta(world, successWorld, terminalResult.rects || rect, (completed, total, part) => {
emitProgress({
status: "step",
key: `preview-delta:${part}`,
phase: "preview-delta",
label: part === "raster" ? "Auditing preview raster changes" : "Auditing preview feature changes",
workUnitId: "preview-delta-audit",
completed,
total,
}, terminalResult.candidateOrdinal || 0);
});
emitProgress({
status: "done",
key: "preview-delta",
phase: "preview-delta",
label: "Preview change audit complete",
}, terminalResult.candidateOrdinal || 0);
}
// Return only the accepted candidate world. Rejected candidate clones and
// the immutable worker baseline remain worker-local and become collectible.
return {
id,
ok: true,
world: successWorld,
transactionDelta: successDelta,
targetHash: successTargetHash,
result: terminalResult,
searchId,
workerEpoch,
eventSeq,
};
} catch (error) {
return { id, ok: false, code: error?.code || "candidate-search-error", error: error?.message || String(error), stack: error?.stack || "", searchId, workerEpoch, eventSeq };
}
}
if (typeof self !== "undefined") {
self.onmessage = async (event) => {
const incoming = event.data || {};
if (handleMirrorSyncMessage(incoming)) return;
if (incoming.type === "patch-apply-discard") {
if (incoming.applyToken) pendingApplyDeltas.delete(incoming.applyToken);
return;
}
if (incoming.type === "patch-apply-ack") {
const pending = pendingApplyDeltas.get(incoming.applyToken);
let ok = false;
let error = null;
try {
if (!pending) throw new Error("Pending patch delta is unavailable.");
if (persistentCommittedRevision !== Number(incoming.baseCommittedRevision)) {
throw new Error(`Committed mirror revision conflict (${persistentCommittedRevision} != ${incoming.baseCommittedRevision}).`);
}
applyCommittedWorldDelta(persistentCommittedMirror, pending.delta, { consumeMetadata: true });
const mirrorHash = hashCommittedWorld(persistentCommittedMirror);
if (mirrorHash !== pending.targetHash) {
throw new Error(`Committed mirror hash mismatch (${mirrorHash} != ${pending.targetHash}).`);
}
persistentCommittedRevision = Number(incoming.committedRevision);
pendingApplyDeltas.delete(incoming.applyToken);
ok = true;
} catch (applyError) {
error = applyError?.message || String(applyError);
persistentCommittedMirror = null;
persistentCommittedRevision = -1;
pendingApplyDeltas.clear();
}
self.postMessage({
type: "patch-apply-ack-result",
ackId: incoming.ackId,
applyToken: incoming.applyToken,
ok,
error,
mirrorHash: ok ? pending?.targetHash || null : null,
mirrorCommittedRevision: persistentCommittedRevision,
});
return;
}
const requestedRevision = Number(incoming.search?.committedRevision ?? -1);
if (incoming.world) {
persistentCommittedMirror = incoming.world;
persistentCommittedRevision = requestedRevision;
pendingMirrorBootstrap = null;
pendingApplyDeltas.clear();
} else if (!incoming.search?.reuseCommittedMirror || !persistentCommittedMirror || persistentCommittedRevision !== requestedRevision) {
self.postMessage({
id: incoming.id,
ok: false,
error: "Committed worker mirror is unavailable or stale.",
code: "worker-mirror-stale",
searchId: incoming.search?.searchId || null,
workerEpoch: Number(incoming.search?.workerEpoch || 0),
});
return;
}
const payload = await runPatchCandidateSearchAsync({ ...incoming, world: persistentCommittedMirror }, {
onProgress: (message) => self.postMessage(message),
transactional: true,
precomputeRawCandidateBatch,
precomputeRawDraftBatch,
precomputeRawTerrainScoutBatch,
precomputeRawCandidateSequence: scheduleRawCandidateSequence,
rawCandidateParallelism: 2,
});
// Helper workers are scoped to one candidate-search operation. Releasing
// them here prevents a completed/rejected large search from retaining two
// full generator heaps while the coordinator waits for Apply/Alternative.
await shutdownRawCandidateWorkers();
payload.mirrorCommittedRevision = persistentCommittedRevision;
if (payload.ok && payload.result?.ok && (payload.transactionDelta || payload.world)) {
payload.eventSeq = Number(payload.eventSeq || 0) + 1;
self.postMessage({
id: incoming.id,
type: "progress",
progress: {
searchId: payload.searchId,
operationId: incoming.search?.operationId || payload.searchId,
candidateOrdinal: Number(payload.result?.candidateOrdinal || 0),
candidateCount: Number(payload.result?.candidateCount || incoming.search?.totalCandidateCount || 0),
executionAttempt: Math.max(1, Number(incoming.search?.executionAttempt || 1)),
workerEpoch: payload.workerEpoch,
committedRevision: requestedRevision,
eventSeq: payload.eventSeq,
counter: payload.eventSeq,
phase: "mirror-delta-build",
phaseOrdinal: Number.MAX_SAFE_INTEGER - 1,
workUnitId: "mirror-delta-build",
boundedWork: false,
cooperative: false,
nonCooperative: true,
status: "start",
key: "mirror-delta-build",
label: "Building transactional Apply delta",
},
});
const applyToken = `${payload.searchId}:${payload.result.candidateOrdinal || 0}:${payload.result.actualVariant ?? payload.result.variant ?? 0}:${requestedRevision}`;
try {
const delta = payload.transactionDelta || buildCommittedMirrorDelta(persistentCommittedMirror, payload.world);
const targetHash = payload.targetHash || hashCommittedWorld(payload.world);
const mainThreadDelta = buildMainThreadTransferDelta(delta);
pendingApplyDeltas.clear();
pendingApplyDeltas.set(applyToken, { delta, baseCommittedRevision: requestedRevision, targetHash });
// The main thread needs one transferable copy to materialize the
// preview. Keep the original delta Worker-local for the later Apply ACK.
payload.worldDelta = mainThreadDelta;
payload.transactionDelta = null;
payload.targetHash = null;
payload.world = null;
payload.result.applyToken = applyToken;
payload.result.acceptedWorldHash = targetHash;
} catch (deltaError) {
pendingApplyDeltas.delete(applyToken);
payload.transactionDelta = null;
payload.targetHash = null;
payload.world = null;
payload.result = {
...payload.result,
ok: false,
code: "candidate-delta-build-failed",
reason: deltaError?.message || String(deltaError),
searchStatus: "infrastructure-error",
applyToken: null,
applyDeltaError: deltaError?.message || String(deltaError),
};
}
}
if (payload.ok) {
payload.eventSeq = Number(payload.eventSeq || 0) + 1;
self.postMessage({
id: incoming.id,
type: "progress",
progress: {
searchId: payload.searchId,
operationId: incoming.search?.operationId || payload.searchId,
candidateOrdinal: Number(payload.result?.candidateOrdinal || 0),
candidateCount: Number(payload.result?.candidateCount || incoming.search?.totalCandidateCount || 0),
executionAttempt: Math.max(1, Number(incoming.search?.executionAttempt || 1)),
workerEpoch: payload.workerEpoch,
committedRevision: requestedRevision,
eventSeq: payload.eventSeq,
counter: payload.eventSeq,
phase: "result-serialization",
phaseOrdinal: Number.MAX_SAFE_INTEGER,
workUnitId: "result-serialization",
boundedWork: false,
cooperative: false,
nonCooperative: true,
status: "start",
key: "result-serialization",
label: "Serializing accepted patch result",
},
});
}
// Accepted transactional results keep all large typed payloads under the
// world delta. Traversing the complete diagnostic/result graph here caused
// a long no-progress pause at the final stage without finding additional
// buffers. Legacy full-world payloads still transfer their world buffers.
// Only the copied raster delta buffers are transferable. Metadata in
// worldDelta deliberately shares the Worker-retained ACK graph until
// postMessage clones it; transferring a nested typed metadata buffer would
// detach the retained delta and make Apply fail.
const transferRoot = payload.worldDelta
? { fields: payload.worldDelta.fields, generatedMask: payload.worldDelta.generatedMask }
: (payload.world || null);
const transfer = payload.ok && transferRoot ? Array.from(collectTransferableBuffers(transferRoot)) : [];
self.postMessage(payload, transfer);
};
}