fix: keep editor writers at optimizer fixed point

Issue: #477
User-Visible: yes
This commit is contained in:
Matysh
2026-09-06 17:52:05 +00:00
committed by claude[bot]
parent 80ff541cef
commit a979699a57
58 changed files with 1924 additions and 637 deletions
+87 -1
View File
@@ -10,6 +10,7 @@ import {
import { spacePhysicalGeometryFingerprint } from './plan-geometry-preflight';
import {
isSinglePartitionAppend, wallChainLiveCandidateSpace, wallChainLiveSeed,
type WallChainLiveSeed,
} from './draft-live-preflight';
const NORM_W = 1000;
@@ -34,7 +35,10 @@ export interface WallChainLiveCommitRuntime<
Violation,
> {
host: WallChainLiveHost<State, Geometry>;
_commitPhysicalGeometry: (name: string, before: State | null) => boolean;
_commitPhysicalGeometry: (
name: string, before: State | null,
additionalAuthoredPoints?: readonly (readonly number[])[], recordHistory?: boolean,
) => boolean;
_clearGeometryGesture: () => void;
_restoreGeometryStateInConfig: (config: ServerConfig, state: State) => boolean;
_restoreGeometryStateLocal: (state: State) => boolean;
@@ -48,6 +52,88 @@ export interface WallChainLiveCommitRuntime<
_saveConfig: () => void;
}
/**
* #477 finish transaction for a chain which has already been normalised on a
* clone. It uses the same production physical/junction proof as a terminal
* click, centred on the pre-normalisation seed. Unlike a click it records no
* extra history command: all segment commands already exist.
*/
export function commitWallChainFinishGeometry<
State extends { spaceId: string },
Geometry extends JunctionSharedGeometry,
Violation,
>(
runtime: WallChainLiveCommitRuntime<State, Geometry, Violation>,
name: string,
before: State | null,
seed: WallChainLiveSeed | null,
): boolean {
const { host } = runtime;
const liveCandidate = host._serverCfg;
const fallback = () => runtime._commitPhysicalGeometry(name, before, [], false);
if (!before || !liveCandidate || !seed
|| Number(liveCandidate.model_version || 0) !== WALL_SEGMENT_MODEL_VERSION) return fallback();
let committedCandidate: ServerConfig;
try {
committedCandidate = commitWallSegmentModel(liveCandidate).config;
} catch (error) {
runtime._clearGeometryGesture();
runtime._restoreGeometryStateLocal(before);
runtime._showWallModelMigrationBlocked(error);
return false;
}
const committedSpace = committedCandidate.spaces.find((space) => space.id === before.spaceId);
const previousConfig = JSON.parse(JSON.stringify(liveCandidate)) as ServerConfig;
if (!committedSpace || !runtime._restoreGeometryStateInConfig(previousConfig, before)) {
return fallback();
}
const previousSpace = previousConfig.spaces.find((space) => space.id === before.spaceId);
const candidateProjection = wallChainLiveCandidateSpace(committedSpace, seed);
const previousProjection = wallChainLiveCandidateSpace(previousSpace, seed);
if (!candidateProjection || !previousProjection) return fallback();
const localCandidate = {
...committedCandidate, spaces: [candidateProjection.space],
} as unknown as ServerConfig;
const localPrevious = {
...previousConfig, spaces: [previousProjection.space],
} as unknown as ServerConfig;
let geometry: Geometry | null = null;
let safe = false;
try {
const authoredPoints = host._path.length >= 2
? host._path.map((point) => [point[0] / NORM_W, point[1] / NORM_W]) : [];
safe = wallModelOffGridValueCount(committedSpace)
<= wallModelOffGridValueCount(before, authoredPoints)
&& host._checkSpacePhysicalGeometry(
localCandidate, before.spaceId, (value) => { geometry = value; },
).ok;
} catch {
safe = false;
}
if (!safe) return rejectUnsafe(runtime, before);
const introduced = runtime._junctionLimitsIntroduced(
localCandidate, localPrevious, before.spaceId, geometry, candidateProjection.roomIds,
);
if (introduced.length) {
runtime._clearGeometryGesture();
runtime._restoreGeometryStateLocal(before);
host._showToast(runtime._junctionLimitLabel(introduced[0]));
return false;
}
adoptWallSegmentModelCandidateInPlace(liveCandidate, committedCandidate);
const acceptedSpace = liveCandidate.spaces.find((space) => space.id === before.spaceId);
const pending = host._pendingPhysicalWrites.get(before.spaceId);
host._pendingPhysicalWrites.set(before.spaceId, {
before: pending?.before || before,
fingerprint: spacePhysicalGeometryFingerprint(acceptedSpace),
});
runtime._saveConfig();
return true;
}
const rejectUnsafe = <State extends { spaceId: string }, Geometry extends JunctionSharedGeometry,
Violation>(runtime: WallChainLiveCommitRuntime<State, Geometry, Violation>, before: State): false => {
runtime._clearGeometryGesture();