Skip to content

Fix on-disk storage robustness and other pre-release review findings - #78

Merged
PierreRaybaut merged 5 commits into
developfrom
fix/pre-release-review
Oct 30, 2026
Merged

PierreRaybaut merged 5 commits into
developfrom
fix/pre-release-review

Conversation

@PierreRaybaut

Copy link
Copy Markdown
Contributor

Fixes from the pre-release review of v0.10.0..HEAD (findings re-checked against the code; several were present in v0.10.0 already).

On-disk storage

  • Enabling the mode atomically (setStorageMode): the OPFS store is kept only once init() succeeded (a failed init can be retried), and a switch whose spill fails pages the spilled objects back in and stays in RAM mode. The toggle follows the mode the runtime actually ended in. Before, a failed attempt left the runtime in disk mode with an uninitialised store while the toggle showed RAM, later operations failed although applied, and a further click reported the mode as enabled.
  • A successful call is no longer failed by storage errors (diskGuardAfter): each reconciliation step (settle, store clear after a replaced model, sweep, GC) is attempted, objects that cannot be written stay in memory with their data, and the error is reported once per episode through a new onStorageError listener, bridged from the kernel worker (storage-error event) and shown as a warning. Before, the call was reported as failed (applied twice if retried) and the next steps were skipped.
  • OpfsSyncObjectStore.get() of an absent object now throws instead of creating an empty file and returning no bytes.

Other fixes

  • HDF5 browser: children are registered at their path in the browsed file instead of child_dset.name (path in the external file). Low impact on the web (files are copied alone, so external links are broken), aligns with Keep the paths of HDF5 objects reached through external links SigimaX#38.
  • AI Assistant: macros saved from a reply with several Python code blocks get numbered titles (Request (2)).
  • Remote bridge: events are structured-cloned instead of transferring their buffers (a transferred buffer is detached, so the second peer got empty buffers); responses still transfer.

Validation

  • tsc -b, eslint, Prettier, i18n:check: OK
  • Vitest: 114 files / 979 tests passed; new tests fail without the fixes
  • pytest tests/python: 532 passed
  • Playwright (chromium): disk_mode_data.spec.ts (main + worker) and worker_mode.spec.ts: 9 passed

Not in this PR: the release blocker (Sigima / DataLab-Capsule development snapshots in sigima-dependency.json and datalab-capsule-dependency.json), to be handled when they are published.

OpfsSyncObjectStore.get() opened the file with create: true, like put():
reading an absent object created an empty file and returned no bytes,
which were then taken for the object data. It now throws, like the
asynchronous store.

Assisted-by: Claude Opus 5.5
…lures

Enabling the on-disk storage mode kept the OPFS store before it was
initialised and switched the mode before spilling the objects: after a
failure (storage refused, write error), the runtime stayed in disk mode
with an unusable store while the toggle showed memory storage, later
operations failed although applied, and a further attempt reported the
mode as enabled. The store is now kept once initialised only, and a
failed switch pages the spilled objects back in and stays in RAM mode
(the toggle follows the mode the runtime actually ended in).

After a successful call, a storage failure (settling paged-in objects,
clearing a replaced store, sweeping) made the call fail, so that running
it again applied it twice, and skipped the next reconciliation steps.
These steps are now best effort: each one is attempted, objects that
cannot be written stay in memory, and the error is reported once
through the new onStorageError listener (bridged from the kernel
worker), which the app shows as a warning.

Assisted-by: Claude Opus 5.5
Every "Save to Macros" button under the Python code blocks of a reply
used the title derived from the request, so that saving several blocks
created homonymous macros. With several blocks, each title now ends
with the number of its block, as the button label does.

Assisted-by: Claude Opus 5.5
Events are posted to every peer window, and post() transferred the
buffers of each message: a transferred buffer is detached, so the
second peer would have received empty buffers, and the caller of
emit() lost its own. Events are now structured-cloned; responses, sent
to a single peer, still transfer their buffers.

Assisted-by: Claude Opus 5.5
…inks

The tree registered each child at child_dset.name, which is the path of
an object reached through an external link in its own file: that path
may be missing from the browsed file, or designate another dataset of
it, whose data was then previewed and imported. Children are now
registered at their path in the browsed file.

Browsed files are copied alone, so their external links are broken and
skipped today: this mainly aligns the browser with SigimaX.

Assisted-by: Claude Opus 5.5
@PierreRaybaut
PierreRaybaut merged commit baef512 into develop Oct 30, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant