Reference (session bundles)#
Audience: power users and developers
Time: 15–40 minutes
What you’ll learn:
The
.cellucid-sessioncontainer format (high level)The manifest schema (what metadata is stored)
Chunk inventory (what chunk IDs you may see)
The
state-snapshots.jsonmanifest schema used for auto-restore
File extension#
Cellucid session bundles use:
.cellucid-session
They are downloaded from the web app via Save State and restored via Load State.
Container format (high level)#
A .cellucid-session file is a single binary container:
ASCII MAGIC bytes:
CELLUCID_SESSION\\nmanifestByteLength(u32 little-endian)manifestJSON bytes (UTF-8)repeated payload chunks:
chunkByteLength(u32 little-endian)chunkBytes(raw stored payload; may be gzip-compressed; decoded based on manifest metadata)
Dev-phase constraints:
no backward compatibility guarantees
no migration/version fields
sessions treated as untrusted input (strict bounds + size guards)
Manifest schema (practical)#
The manifest is a JSON object that includes:
createdAt: ISO timestampdataSource: a snapshot of the active data source selection (debug/provenance; not used to auto-load the dataset)datasetFingerprint: used to detect dataset mismatches on restorechunks: array of chunk metadata entries
Example shape (simplified):
{
"createdAt": "2025-12-30T02:00:14.000Z",
"dataSource": { "sourceType": "local-demo", "datasetId": "suo", "userPath": null },
"datasetFingerprint": { "sourceType": "local-demo", "datasetId": "suo", "cellCount": 12345, "varCount": 20000 },
"chunks": [
{
"id": "core/state",
"contributorId": "core-state",
"priority": "eager",
"kind": "json",
"codec": "gzip",
"label": "Core state",
"datasetDependent": true,
"storedBytes": 1234,
"uncompressedBytes": 5678
}
]
}
Important fields per chunk:
priority:eagervslazy(progressive restore)kind:jsonvsbinarycodec:nonevsgzipdatasetDependent: whether the chunk is skipped on dataset mismatchdependsOn(optional): dependency ordering hints for contributors
Dataset fingerprint (what “same dataset” means)#
The dataset fingerprint is intentionally small and fast to compute.
At minimum it includes:
sourceTypedatasetId
It may also include lightweight size guards:
cellCountvarCount
If the fingerprint does not match, dataset-dependent chunks are skipped and only dataset-agnostic layout restores.
Chunk inventory (what you may see)#
These are the chunk IDs used by the current session system:
Chunk id |
Priority |
Dataset dependent |
Contains |
|---|---|---|---|
|
eager |
yes |
rename/delete registries + user-defined field definitions (metadata only) |
|
eager |
yes |
camera + UI controls + dimension + filters + active fields + multiview descriptors |
|
eager |
no |
floating non-analysis panels geometry + open/closed |
|
eager |
yes |
open analysis windows descriptors (settings + geometry) |
|
eager |
yes |
highlight pages + group shells (no cell indices) |
|
eager/lazy |
yes |
user-defined categorical codes (binary) |
|
lazy |
yes |
highlight group membership indices (binary) |
|
lazy |
yes |
analysis caches/artifacts (binary) |
Notes:
the presence and exact contents of chunks are dev-phase and can change across builds
missing contributors are skipped (best-effort robustness)
state-snapshots.json (auto-restore manifest)#
Auto-restore reads state-snapshots.json from the dataset exports directory and finds entries whose filename ends with .cellucid-session.
Supported shapes:
{ "states": [ "file.cellucid-session", ... ] }(recommended)[ "file.cellucid-session", ... ](also accepted)
The last matching entry is auto-restored on app startup.
Implementation pointers (for developers)#
Session bundle orchestrator:
cellucid/assets/js/app/session/session-serializer.js
Container format framing:
cellucid/assets/js/app/session/bundle/format.js
What is saved/restored (developer-facing list):
cellucid/assets/js/app/state-serializer/README.md
Design plan:
cellucid/markdown/session-serializer-plan.md