openmixer — generated API reference
    Preparing search index...

    Class SessionStore

    Persists whole-console sessions as JSON files and drives save/load over a ConsoleStateProvider.

    Hierarchy

    Index
    dir: string
    ext: ".session.json" = '.session.json'

    File suffix for this library's entries (.scene.json, …).

    idGen: () => string
    label: "session" = 'session'

    What this library's entries are CALLED, in refusals the operator reads: no such ${label}, corrupt ${label} file, ${label} name must not be empty.

    now: () => Date
    • Boot-time restore (operator #51): resolve the best available "last session" and apply it to the live console, or leave the caller's freshly-built default console untouched when there is nothing to restore. Preference order — the live autosave (the most current picture of what was actually on air), else the most-recently-saved NAMED session (a fresh deployment that never had a live autosave written yet), else nothing. The reserved autosave ids are excluded from the named-session fallback — they are restore points, not shows an operator named and chose.

      Never throws: a missing store, a corrupt file, or a saved shape that does not fit the live console (e.g. a session captured on a differently-sized console) is caught and logged, and this resolves undefined — the caller's default console stands, exactly the fresh-boot path behaves today.

      Parameters

      • log: (m: string) => void = ...

      Returns Promise<SessionSummary | undefined>

    • Snapshot the live console as the "live" autosave (a single, overwritten entry under LIVE_AUTOSAVE_ID). Called debounced on every state change and once more on graceful shutdown, so this always reflects the last live show — the source autoload restores from when the operator never explicitly saved. Best-effort by convention (callers treat a throw as non-fatal — a failed autosave must never interrupt live operation or block shutdown).

      Returns Promise<{ id: string }>

    • Snapshot the live console as the pre-load restore point (a single, overwritten entry under PRELOAD_AUTOSAVE_ID). Backup-before-mutation: a session.load applies over the live show, so this captures an undo point first. Returns the reserved id. Failures here must not block the load the operator asked for, so the caller treats a throw as best-effort.

      Returns Promise<{ id: string }>

    • Create a BRAND-NEW show — the operator's "start brand new" (an internal spec).

      The document is core's blankConsoleSnapshot over a FRESH capture of the console the operator is standing at: the show drops, the topology stays (§3). Reduced from a capture rather than built from nothing because only the console knows where MAIN and the monitors are wired, how the control room listens and what shape the desk is; a hand-built blank would be a second declaration of that rule.

      WRITES, AND DOES NOT APPLY. Switching the console to it is the caller's job, through the ONE load path every other session load takes (loadWithRestorePoint) — a second restore here would be a second answer to "what does loading a session do".

      No patch block: the console snapshot already says sources: [] for every input strip, which is what unpatches them, and the outputs carry their own routes.

      Parameters

      Returns Promise<{ id: string }>

    • Delete the stored entry id (throws if it does not exist).

      Parameters

      • id: string

      Returns Promise<void>

    • Read a full stored entry by id (for embedders / the domain verbs).

      Parameters

      • id: string

      Returns Promise<SavedSession>

    • Narrow a parsed file to a stored entry. A GUARD, never a cast — see listStoredSync.

      Parameters

      • value: unknown

      Returns value is SavedSession

    • The sync twin of list: the resource layer's read/patch/project pipeline is synchronous end to end (see the southbound-actuator-contract), so a row's GET cannot call the async list(). Same files, same headers, read fresh every call.

      Returns SessionSummary[]

    • Load the stored session id and apply it to the live console atomically. The provider broadcasts the resulting state; this resolves once applied.

      The boot restore's door (autoload). An operator's load goes through loadWithRestorePoint, which is this plus the undo point, in the one order that order can be taken.

      Parameters

      • id: string

      Returns Promise<void>

    • What loading session id RIGHT NOW would KEEP rather than restore — the console-level collections the session snapshot does not govern (twin of SceneStore.recallKeeps). Synchronous so a resource GET can read it; undefined for an unknown id. Mutates nothing.

      Parameters

      • id: string

      Returns RecallKeeps | undefined

    • THE OPERATOR'S LOAD: the undo point, then the show — and the document is READ BEFORE the undo point is written, because the id being loaded may BE the undo point.

      Backup-before-mutation captures the live console under the reserved PRELOAD_AUTOSAVE_ID. Composed as "autosave, then read and apply", loading that reserved id snapshotted the live console STRAIGHT OVER the document it was about to read and then applied the copy it had just made: a guaranteed no-op that answers ok, moves nothing, warns nothing, and destroys the one restore point in the same breath. On the rig (2026-09-07) that is a show of 49 link pairs — a whole stagebox patch — answering ok and leaving the desk exactly as it was, with GET /patch/input/input/9 still empty.

      And the undo-redo design (an internal spec) is explicit that the pre-load autosave "restores by re-issuing session.load autosave-preload", so the ONE document this mechanism exists to make loadable was the one document it could not load.

      Reading first fixes it without weakening the backup: the restore point still ends up holding the console as it was a moment ago, which after an undo is exactly the redo point.

      The autosave stays best-effort — an undo convenience is never a precondition for the load the operator asked for. Answers the session it APPLIED, so a caller reporting on the load (the missing-hardware summary) reads what landed rather than re-reading a path the restore-point write may have just replaced.

      Parameters

      • id: string

      Returns Promise<SavedSession>

    • The named refusal the save-into row narrows on — see SessionNotFoundError.

      Parameters

      • id: string

      Returns Error

    • Observe every persisted mutation — a write (save, autosave, overwrite) or a delete — fired AFTER the file settles, with the touched id. Wired once by the server to re-publish the library's list + item rows, so an internal writer (the debounced live autosave, the pre-load restore point) announces exactly like the POST door: task #72's rule — the write that changed the books is the write that tells every surface — applied to the /sessions standing discovery in the convergence e2e.

      Parameters

      • observe: (id: string) => void

      Returns void

    • The file an id lives in — through the id guard, so a hostile id never escapes dir.

      Parameters

      • id: string

      Returns string

    • Read one entry by id. A missing file is notFound; a malformed one is an explicit "corrupt" — unlike a list read, which skips it. Fetched by id, the caller asked for THAT entry, and a corrupted file would otherwise surface as a confusing downstream error.

      Parameters

      • id: string

      Returns Promise<SavedSession>

    • The sync twin of get: ONE full entry by id, read fresh from its file the same way listSync reads the headers — so a synchronous resource GET can compute a fact that needs the whole stored snapshot (e.g. what a recall would keep). undefined for an id that names nothing or a file that will not parse, matching the item row's honest absence.

      Parameters

      • id: string

      Returns SavedSession | undefined

    • A trimmed non-empty name, or the refusal a blank one earns.

      Parameters

      • name: string

      Returns string

    • Snapshot the live console under name and persist it; returns the new id.

      Parameters

      • name: string

      Returns Promise<{ id: string }>

    • Re-capture the live console INTO an already-stored session id, keeping that item's own NAME (operator, 2026-09-10). Names are not identity here — two sessions can share a name today (saveByName mints a fresh id on every save), so overwrite always targets the id, never a name lookup that could land on the wrong one of two.

      Throws SessionReservedIdError for the reserved autosave ids (those restore points are the engine's, not the operator's library) and SessionNotFoundError (via notFound) for an id nothing names — both narrowed by the REST row into a coded refusal, never a raw throw reaching the wire.

      Parameters

      • id: string

      Returns Promise<{ id: string }>

    • Install the SHIPPED sessions into an empty store, and answer whether anything was written.

      A console with no history has nothing to autoload, so it used to come up as the bare allocation — every strip unnamed, no bus routed (task #33's "we need a working desk"). This seeds session-templates.ts's shipped shows so the first boot restores a real, minimal, UNPATCHED desk the operator can read and change.

      ONLY into an empty store. A store with anything in it — a live autosave, one named show, or templates seeded on a previous boot and since deleted — is the operator's, and re-installing over it would resurrect shows they threw away. So this is a first-boot act, never a reconciliation.

      Never throws: a store that cannot be written is a desk that still boots, on the default console, with the failure logged.

      Parameters

      • templates: readonly SavedSession[]
      • log: (m: string) => void = ...

      Returns Promise<boolean>

    • Persist one entry under its own id: temp + rename, so no reader ever sees a half file.

      Parameters

      Returns Promise<void>