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
+21 -9
View File
@@ -42,17 +42,19 @@ The items below are still open.
renders them as a warning banner. A bad declaration no longer aborts the rest
of a cascade.
### 2. `var del` does not reach the engine — medium
### 2. `var del` does not reach the engine — ✅ fixed (dropped)
- **Where:** reducer in `types/var.tsx` supports `action: "del"`; the parser
(`command-parser.ts`) has no `/del`; `var-reactivity.ts` never clears
`baseValues` and `rebuildReactivityFromStore` never removes stale keys.
- **Symptom:** a deleted variable still resolves locally via `getCombined`,
because it reads `baseValues` first.
- **Fix:** either wire a `/del` command and clear engine state (base + mods) on
delete, or drop `del` from the schema/reducer if it is intentionally unused.
- **Fixed:** `/del` was never reachable (no parser emits it, and replay does not
validate), so the `del` action was removed from the `var` schema, render, and
reducer. The wire type is now `action: "set"` only; a legacy `del` message in
an old stream is a no-op on replay rather than resurrecting a deleted key.
### 3. Reactivity is initialized once, at import — medium
### 3. Reactivity is initialized once, at import — ✅ fixed
- **Where:** `bootstrapReactivity` in `completions.ts` runs `initReactivity`
once; nothing re-runs it when declare blocks change or a session/document is
@@ -62,8 +64,16 @@ The items below are still open.
per-dispatch init that was never wired up.
- **Symptom:** editing `role=declare` content requires a full reload; stale
graph/expressions persist.
- **Fix:** expose a re-init entry point keyed to content/session changes, and
either use or remove the unused context fields.
- **Fixed:** `bootstrapReactivity` is now `applyReactivity` behind an idempotent
`ensureReactivity()` that reads the live completions signal, compares a
signature, and re-initializes only when the declaration set changes.
`dispatchCommand` calls it before every dispatch, so a content rescan takes
effect on the next command without a reload. The unused
`DispatchContext.declarations` / `tagModifiers` fields were removed (they were
mount-time snapshots and could not be trusted). Session switches were already
covered by the hydration rebuild, which now also passes
`journalStreamState.variableBases` so bases are restored exactly instead of
falling back to combined values.
### 4. `lookup` contract disagrees with its docs — low
@@ -102,12 +112,14 @@ The items below are still open.
that did not change. Mostly harmless, but noisy.
- **Fix:** only visit/topologically order keys in `affected`.
### 8. Failed `initReactivity` leaves partial state — low
### 8. Failed `initReactivity` leaves partial state — ✅ fixed
- **Where:** `initReactivity` populates `depGraph` / `declExprs` / `tagModMap`
before `checkCircular()` throws; `inFlight` is never cleared on re-init.
- **Fix:** build into locals and commit on success, or roll back on failure.
Clear `inFlight` in `initReactivity`.
- **Fixed:** `initReactivity` now builds the declaration map, dependency graph,
and tag-modifier map into locals and commits them only after `checkCircular`
passes, so a failed (re-)init leaves the previous engine intact. Runtime state
(`baseValues`, mods, `sourceActivations`) and `inFlight` are reset on commit.
### 9. Residual base / tagmap-target edges — low