fix(journal): re-init reactivity and drop var del

Make the reactivity engine re-initialize when the loaded declarations
change instead of only at import. ensureReactivity() reads the live
completions signal, compares a signature, and rebuilds from the store
(with exact bases) only when needed; dispatchCommand calls it before each
dispatch. Remove the unused DispatchContext.declarations/tagModifiers
fields, which were mount-time snapshots and could not be trusted.

Build initReactivity's maps into locals and commit only after the
circular check passes, so a failed re-init leaves the previous engine
intact; clear inFlight on commit.

Drop the unreachable var "del" action from the schema, render, and
reducer.
This commit is contained in:
hyper
2026-09-12 22:29:25 +08:00
parent 9f372fa2b0
commit 02442a1100
9 changed files with 131 additions and 70 deletions
+5 -5
View File
@@ -12,7 +12,7 @@ import { resolveRollPayload } from "./types/roll";
import { resolveSparkPayload } from "./types/spark";
import { evaluateExpression, exprValueToString } from "./variable-expression";
import { computeCascade, getCombined, setBase } from "./var-reactivity";
import type { VarDeclaration, TagModifier } from "./declare-parser";
import { ensureReactivity } from "./completions";
// Tagmap pattern: "#warrior:1;#druid:2". Also accepts bare "#tag" as shorthand.
const BARE_TAG_PATTERN = /^#[a-zA-Z_][a-zA-Z0-9_]*$/;
@@ -58,10 +58,6 @@ export interface DispatchContext {
}[];
/** Current runtime variable values */
variables: Record<string, string>;
/** Variable declarations (from role=declare blocks) */
declarations: VarDeclaration[];
/** Tag modifiers (from role=declare blocks) */
tagModifiers: TagModifier[];
}
/**
@@ -74,6 +70,10 @@ export async function dispatchCommand(
const raw = ctx.command.trim();
if (!raw) return { ok: false, error: "Empty command" };
// Make sure the engine reflects the currently loaded declarations; this
// re-initializes only when they changed since the last dispatch.
ensureReactivity();
// Observers can only send chat
if (ctx.role === "observer") {
const result = sendMessage("chat", { text: raw });