Commit Database

The versioned persistence tier. CommitDatabase keeps the history of mutations in a DAG of commits; two stateless namespaces operate over it, each taking a CommitDatabase as their first argument:

  • CommitStateBuilder — reconstruct a CommitState from a chosen commit: CommitStateBuilder.state(db, id), CommitStateBuilder.initialState(db).

  • CommitDatabaseHelper — reduce heads and navigate (reduceHeads, forward / fastForward).

CommitDatabase itself answers topology queries (headCommitIds(), lastCommitId(), isAncestor) and holds no “current” state. A CommitStore wraps the persistence layer and both namespaces behind a stateful facade (undo/redo, the dispatch surface) for interactive apps. A reconstructed state is a blind replay of the linearized trace — see the peer Python narrative, Commit.

This bucket also holds the additive merge machinery (CommitMergeAnalyzer and friends): see Merge reconciliation below.

When to use

Reach for this page’s classes when you persist DSM documents with history — every write is a commit, and earlier states stay reconstructible. If you only need flat CRUD without versioning, use Database instead. The Python counterpart is Commit Database.

Quick Start

const {
    CommitDatabase, CommitStateBuilder, CommitMutableState,
} = require('@digitalsubstrate/dsviper');

// Create an in-memory commit database and grow its schema from definitions.
const db = CommitDatabase.createInMemory();
db.extendDefinitions(defs.const());

// Stage writes on a mutable state built from the empty initial snapshot.
const state = new CommitMutableState(CommitStateBuilder.initialState(db));
const mutating = state.attachmentMutating();
mutating.set(attachment, key, document); // a Document_Set opcode is recorded

// Seal the staged mutations into a new commit.
db.commitMutations('Add document', state);

// Read back from a reconstructed snapshot at the latest commit.
const getting = CommitStateBuilder.state(db, db.lastCommitId()).attachmentGetting();
const value = getting.get(attachment, key); // a ValueOptional

db.close();

Note

INT64 documents unwrap to a JS bigint (getting.get(att, key).unwrap() is 42n, not 42). Compare keys and values with .equals, never ==. Operations on a closed CommitDatabase throw a ViperError (a JS Error whose .name === 'ViperError').

Choosing the right class

Use case

Class

Example

Create an in-memory commit database

CommitDatabase

CommitDatabase.createInMemory()

Read state at a specific commit

CommitStateBuilder

CommitStateBuilder.state(db, id)

Prepare mutations

CommitMutableState

new CommitMutableState(CommitStateBuilder.initialState(db))

Write documents (set, update, unionInSet, …)

attachmentMutating()

state.attachmentMutating().set(att, key, doc)

Read documents (get, keys, has)

attachmentGetting()

CommitStateBuilder.state(db, id).attachmentGetting()

Inspect commit metadata

CommitHeader

db.commitHeader(id)

Redux-style store (dispatch, undo/redo)

CommitStore

store.use(db); store.dispatch(label, fn)

Reconcile a merge

CommitMergeAnalyzer

see below

Serve a database over a socket

CommitDatabaseServer

see Serving a database below

Merge reconciliation

CommitMergeAnalyzer is an additive, application-level supervisor over the public CommitDatabase API. The engine reduces concurrent streams mechanically and signals no conflict; this layer reconstructs a notion of conflict over a merge — already persisted, or computed from the two heads — and lets a caller make a chosen value survive. It adds no engine, storage-format, or runtime change.

const { CommitMergeAnalyzer, CommitMergeResolution } = require('@digitalsubstrate/dsviper');

const merge = db.mergeCommit('merge', ours, theirs);
const analysis = CommitMergeAnalyzer.analyzeMerge(db, merge);

// The supervisor decides per conflict; here, keep ours at every locus.
const resolutions = analysis.conflicts().map(
    (c) => new CommitMergeResolution(c, c.oursValue().unwrap()),
);
const survivor = CommitMergeAnalyzer.reconcile(db, merge, resolutions, 'reconcile');

Accepting the merge for every conflict (resolving each with mergedValue()) makes reconcile return the merge commit unchanged. When the two heads share no unambiguous base, analyzeMerge degrades to a base-free 2-way scan (analysis.twoWay() is true, analysis.base() is undefined) rather than erroring. For the model behind identify / surface / reconcile, see Commit.

Generated from the @digitalsubstrate/dsviper TypeScript declarations (index.d.ts) by TypeDoc.

Serving a database

A Node host can serve a commit database, not only consume one: CommitDatabaseServer opens the database behind a passive socket and serves each client on its own C++ thread. The client side is unchanged — CommitDatabaseRemote (connectLocal / connect).

The loop belongs to the host. step(timeoutInSec) is a bounded wait, so the server must yield to the event loop between calls; a loop that never yields starves timers, I/O and signal delivery.

const { CommitDatabase, CommitDatabaseServer, Cancelation, Socket, LoggerNull } =
    require('@digitalsubstrate/dsviper');

CommitDatabase.create(databasePath).close();

const cancelation = new Cancelation();
const socket = Socket.createPassiveLocal(socketPath);
const server = new CommitDatabaseServer(databasePath, socket,
                                        new LoggerNull().logging(), cancelation);

process.on('SIGINT', () => cancelation.cancel());   // honoured within one timeout

const tick = () => {
    if (!server.step(1) || cancelation.requested()) { server.finishBefore(5); return; }
    setImmediate(tick);
};
server.start(); tick();

finishBefore(timeoutInSec) bounds the teardown and returns the number of client threads it could not join — zero means every client ended, non-zero means the process is not idle yet. finish() waits without a bound.

Socket exposes only the passive factories a server needs (createPassiveLocal, createPassiveInet): a host consumes a service through the *Remote classes, it does not drive a socket by hand. A passive local socket is a file on disk, and V8 releases nothing on a schedule a host can rely on — release it explicitly with socket.close(), or through [Symbol.dispose]: using socket = Socket.createPassiveLocal(socketPath).

Note

On macOS and Linux a unix-domain socket path is limited to ~104 bytes; a longer path fails bind with a misleading “Address already in use”.

Available from the Node binding 1.2.9 (runtime 1.2.24) — see Release notes.

Core Classes

Class

Description

Commit

One commit as it is stored

CommitDatabase

A Commit database keeps the history of mutations in a DAG of commits

CommitDatabaseSQLite

A low-level class used to represent the database based on SQLite3 through the CommitDatabasing interface

CommitDatabaseRemote

A low-level class used to represent a remote Commit database through the CommitDatabasing interface

CommitDatabaseServer

Serve a CommitDatabase over a socket, one C++ thread per client

CommitDatabasing

Abstracts the persistence layer behind a Commit database

State Access

Class

Description

CommitState

The data reconstructed at one commit, by replaying the mutations down to it

CommitMutableState

Registers the mutations of a value executed through the AttachmentMutating interface

CommitStateBuilder

Reconstructs a CommitState from a chosen commit

History & DAG

Class

Description

CommitNode

One commit in the DAG, linked to the commits that follow it

CommitNodeGrid

One commit’s place in the DAG once it is laid out on a grid

CommitNodeGridBuilder

Builds the grid layout of the commit DAG

CommitHeader

What identifies a commit, without its content

CommitData

One commit’s encoded opcodes, with the header that places it

CommitEvalAction

A class used by the evaluator to reconstruct a value by executing mutation opcodes

CommitDatabaseHelper

Navigates the commit DAG

Synchronization

Class

Description

CommitStore

A high-level application class used to implement the store, dispatch, undo/redo and notification concepts inspired by the redux approach

CommitStoreNotifying

An interface used to represent the notification emitted by a store

CommitSynchronizer

Synchronizes two concrete databases through the CommitDatabasing interface (low-level driver interface)

CommitSynchronizerInfo

What a synchronization found

CommitSynchronizerInfoTransmit

What one synchronization actually transferred

CommitSyncData

The commits one database hands another when they synchronize

Tracing

Class

Description

CommitStateTracing

Asks a state for the trace of one document

CommitStateTrace

The replay of one document

CommitStateTraceProgram

One commit’s contribution to a document

Reference

class Commit()

One commit as it is stored.

Its header, and the program of opcodes it contributes to the state.

Note: Not directly instantiable.

exported from index.d

Commit.header()

Return the CommitHeader - the label, type, parent and timestamp.

Returns:

CommitHeader

Commit.program()

Return the program or undefined

Returns:

ValueProgram | undefined

class CommitDatabase()

A Commit database keeps the history of mutations in a DAG of commits.

Use the static factory method createInMemory(), create(…), open(…), connect(…) or connectLocal(…).

Writes here need NO transaction, unlike a Database, where every write requires one already open. A blob stored here survives without any commit; a commit records mutations of documents, not of blobs.

One file may be open in several processes; SQLite locks it. A commit writes in one short statement, while extendDefinitions, reduceHeads and the transfers hold the file exclusively as they run. A call from another process meanwhile waits for up to 10 seconds, then throws ViperError: the database is busy.

exported from index.d

CommitDatabase.[Symbol․dispose]()

Release the resource at scope exit via using (TC39 disposable); delegates to close(). Idempotent.

CommitDatabase.blob(blobId)

Return the bytes of the blob blobId names, or undefined if it is not held here.

Throws past 2 GB, where the bytes cannot be handed over in one piece. Ask blobInfo(blobId).chunked() first, and read such a blob with readBlob.

A blob commitDatabasing().createZeroBlob reserved throws until commitDatabasing().freezeBlob seals it; blobInfo answers undefined for it meanwhile.

Arguments:
  • blobId (ValueBlobId)

Returns:

ValueBlob | undefined

CommitDatabase.blobGetting()

Return the BlobGetting interface.

Returns:

BlobGetting

CommitDatabase.blobIds()
Return the distinct blobId of every sealed blob, as a ValueSet: contains() finds

an id by value, and the set algebra applies.

A blob commitDatabasing().createZeroBlob reserved joins it once commitDatabasing().freezeBlob seals it.

Returns:

ValueSet<ValueBlobId>

CommitDatabase.blobInfo(blobId)

Return the BlobInfo for blobId, or undefined if there is no such blob.

It gives the layout, the size, whether the blob is chunked, and the rowid that reaches it. A blob commitDatabasing().createZeroBlob reserved answers undefined until commitDatabasing().freezeBlob seals it.

Arguments:
  • blobId (ValueBlobId)

Returns:

BlobInfo | undefined

CommitDatabase.blobInfos(blobIds)

Return one BlobInfo per blobId of blobIds the database holds.

An unknown blobId is left out, so the list may be shorter than blobIds.

Arguments:
  • blobIds (ValueSet<ValueBlobId> | ValueBlobId[])

Returns:

BlobInfo[]

CommitDatabase.blobStatistics()

Return the statistics for blobs.

Returns:

BlobStatistics

CommitDatabase.blobStreamAppend(blobStream, blob)

Append blob to blobStream, after the bytes already written.

A failure here closes the stream and discards what it collected, so nothing partial is left behind and there is nothing to clean up.

Arguments:
  • blobStream (BlobStream)

  • blob (ValueBlob)

CommitDatabase.blobStreamClose(blobStream)

Close blobStream and return its blobId.

The blobId is computed from everything written into it.

A failure here closes the stream and discards what it collected, so nothing partial is left behind and there is nothing to clean up.

Arguments:
  • blobStream (BlobStream)

Returns:

ValueBlobId

CommitDatabase.blobStreamCreate(blobLayout, size)

Return a BlobStream to fill a blob of size bytes laid out by blobLayout.

Arguments:
  • blobLayout (BlobLayout)

  • size (number)

Returns:

BlobStream

CommitDatabase.childrenCommitIds(commitId)

Return the distinct commitId for the children of the commit.

Arguments:
  • commitId (ValueCommitId)

Returns:

ValueSet<ValueCommitId>

CommitDatabase.close()

Close the database.

CommitDatabase.codecName()

Return the name of the codec.

Returns:

string

CommitDatabase.commit(commitId)

Return the commit commitId names, header and opcodes.

Arguments:
  • commitId (ValueCommitId)

Returns:

Commit

CommitDatabase.commitDatabasing()

Return the CommitDatabasing interface.

Returns:

CommitDatabasing

CommitDatabase.commitExists(commitId)

Return true if the database holds the commit commitId names.

Arguments:
  • commitId (ValueCommitId)

Returns:

boolean

CommitDatabase.commitHeader(commitId)
Return the CommitHeader of the commit commitId names - its label, its type, its

parent and its timestamp.

Arguments:
  • commitId (ValueCommitId)

Returns:

CommitHeader

CommitDatabase.commitIds()

Return the distinct commitId for all available commits.

A ValueSet: these are the commits, without duplicates, iterating in the order of the ids, so a listing is reproducible. contains() finds one by value, and the set algebra applies.

The history’s order is a different thing and no sort gives it: walk CommitNode.build. CommitHeader.timestamp does not, for the reason written there.

Returns:

ValueSet<ValueCommitId>

CommitDatabase.commitMutations(label, commitMutableState)

Append what commitMutableState recorded as a new commit under label.

It returns the new commitId. The commit’s PARENT is the state commitMutableState was built from, so the returned commitId is what the next mutation starts from: pass it to CommitStateBuilder.state to carry on in one line. Building the next mutation from initialState instead diverges from the root, and the database then has two heads.

Arguments:
  • label (string)

  • commitMutableState (CommitMutableState)

Returns:

ValueCommitId

CommitDatabase.createBlob(blobLayout, blob)
Store blob under blobLayout, and return the blobId computed from its content and

that layout.

Arguments:
  • blobLayout (BlobLayout)

  • blob (ValueBlob)

Returns:

ValueBlobId

CommitDatabase.createBlobFromBuffer(buffer)
Store the bytes of a Node Buffer, a typed array, an ArrayBuffer or a ValueBlob, and

return the blobId computed from them.

Arguments:
  • buffer (ValueBlob | BlobTypedArray | ArrayBuffer | Buffer<ArrayBufferLike>)

Returns:

ValueBlobId

CommitDatabase.definitions()

Return the Definitions every value in the database is typed by.

It is a SNAPSHOT: extending the database afterwards does not show through the handle you hold, so ask again. A view obtained from Definitions.const() is live instead - same class, opposite liveness.

Returns:

DefinitionsConst

CommitDatabase.definitionsHexdigest()

Return the SHA1 of the definitions, as a hex string.

Returns:

string

CommitDatabase.deleteCommit(commitId)

Delete the commit commitId names.

Breaks the append-only invariant every other reader relies on, and only makes sense on a head: deleting any other commit orphans its descendants. Kept for rewinding an interactive demonstration, not for storage management.

Arguments:
  • commitId (ValueCommitId)

CommitDatabase.disableCommit(label, parentCommitId, disabledCommitId)

Append a commit under label that hides disabledCommitId.

It sits on top of parentCommitId, and its commitId is returned.

Nothing is removed: the evaluator skips the hidden commit from here on.

Arguments:
  • label (string)

  • parentCommitId (ValueCommitId)

  • disabledCommitId (ValueCommitId)

Returns:

ValueCommitId

CommitDatabase.documentation()
Return the free text stored with the database at create(). One made without any

answers ‘not documented.’, one made in memory answers ‘In Memory’ - both are placeholders written in at create(), not substituted on read.

Returns:

string

CommitDatabase.enableCommit(label, parentCommitId, enabledCommitId)
Append a commit under label that unhides enabledCommitId, on top of parentCommitId,

and return its commitId.

Arguments:
  • label (string)

  • parentCommitId (ValueCommitId)

  • enabledCommitId (ValueCommitId)

Returns:

ValueCommitId

CommitDatabase.extendDefinitions(other)

Add every type and attachment of other that the database does not already hold.

Arguments:
  • other (DefinitionsConst)

Returns:

DefinitionsExtendInfo

CommitDatabase.firstCommitId()

Return the commitId of the first commit or undefined.

First in creation order, which is the root of the DAG CommitNode.build walks.

Returns:

ValueCommitId | undefined

CommitDatabase.headCommitIds()
Return the distinct commitId for the available heads, as a ValueSet: contains()

finds an id by value, and size() says how many heads there are.

Returns:

ValueSet<ValueCommitId>

CommitDatabase.inMemory()

Return true if the database is in memory.

Returns:

boolean

CommitDatabase.isAncestor(commitId, descendantId)

Return true if commitId is an ancestor of descendantId.

A commit is its own ancestor. A merge commit is reached through both its parent and its target.

Arguments:
  • commitId (ValueCommitId)

  • descendantId (ValueCommitId)

Returns:

boolean

CommitDatabase.isClosed()

Return true if the database is closed.

Returns:

boolean

CommitDatabase.isMergeable(parentCommitId, mergedCommitId)
Return true if parentCommitId and mergedCommitId have diverged - neither is an

ancestor of the other.

Arguments:
  • parentCommitId (ValueCommitId)

  • mergedCommitId (ValueCommitId)

Returns:

boolean

CommitDatabase.lastCommitId()

Return the commitId of the last commit or undefined.

Last in creation order: the one a new commit follows, and the one CommitStore.use resumes from.

Returns:

ValueCommitId | undefined

CommitDatabase.mergeCommit(label, parentCommitId, mergedCommitId)

Append a commit under label joining two heads, and return its commitId.

The commit records the pair (parentCommitId, mergedCommitId); nothing is composed here. At reconstruction mergedCommitId’s mutations land last, which makes the join deterministic but not commutative: swapping the two gives a different commit.

On a path both heads wrote, mergedCommitId wins and the other is dropped; nothing is signalled. CommitMergeAnalyzer reconstructs, after the fact, what a merge did not keep.

Arguments:
  • label (string)

  • parentCommitId (ValueCommitId)

  • mergedCommitId (ValueCommitId)

Returns:

ValueCommitId

CommitDatabase.nephewCommitIds(commitId)

Return the distinct commitId for the nephew of the commit.

Arguments:
  • commitId (ValueCommitId)

Returns:

ValueSet<ValueCommitId>

CommitDatabase.path()

Return the file path the database was opened from.

A database made in memory answers ‘InMemory’ rather than a path, and that exact string is how the runtime recognises one, so no file may take it: creating or opening a file of that path throws. Over a socket the answer is whatever the server answers for its own database.

Returns:

string

CommitDatabase.readBlob(blobId, size, offset)

Return size bytes of the blob blobId names, starting at offset.

The read side of blobStreamCreate, blobStreamAppend and blobStreamClose, and the only way to read a blob past 2 GB, which blob() refuses.

Arguments:
  • blobId (ValueBlobId)

  • size (number)

  • offset (number)

Returns:

ValueBlob

CommitDatabase.resetCommits()

Remove all commits except the first one.

Breaks the append-only invariant every other reader relies on. Kept for replaying an interactive demonstration from a known baseline, not for storage management.

CommitDatabase.streamCodecInstancing()
Return the StreamCodecInstancing interface used to encode the binary

data.

Returns:

StreamCodecInstancing

CommitDatabase.uuid()

Return the uuid identifying this database, generated at create().

Returns:

ValueUUId

static CommitDatabase.connect(host, service)

Return a CommitDatabase served by host on service, over TCP.

Arguments:
  • host (string)

  • service (string | null)

Returns:

CommitDatabase

static CommitDatabase.connectLocal(socketPath)

Connect to a socket located at socketPath.

Arguments:
  • socketPath (string)

Returns:

CommitDatabase

static CommitDatabase.create(filePath, documentation)

Create a database at filePath and return it.

documentation is stored in the file and read back by documentation().

Requires that nothing exist at filePath, and throws without creating anything when something does.

Arguments:
  • filePath (string)

  • documentation (string | null)

Returns:

CommitDatabase

static CommitDatabase.createInMemory()

Create a database in memory.

Returns:

CommitDatabase

static CommitDatabase.isCompatible(filePath)

Return true if the file at filePath carries the expected SQL schema.

Arguments:
  • filePath (string)

Returns:

boolean

static CommitDatabase.open(filePath, readonly)

Open the database at filePath and return it.

readonly opens it without allowing a commit.

Requires a file at filePath, and throws when there is none.

Arguments:
  • filePath (string)

  • readonly (boolean | null)

Returns:

CommitDatabase

class CommitDatabaseSQLite()
A low-level class used to represent the database based on SQLite3 through the

CommitDatabasing interface. Use the high-level static factory method CommitDatabase.create(…) or CommitDatabase.open(…).

Note: Not directly instantiable.

exported from index.d

CommitDatabaseSQLite.[Symbol․dispose]()

Release the resource at scope exit via using (TC39 disposable); delegates to close(). Idempotent.

CommitDatabaseSQLite.beginTransaction()

Create a transaction to boost the creation of many blobs.

Transactions do not nest: calling this while inTransaction() is true throws, and the transaction already open is untouched.

CommitDatabaseSQLite.close()

Close the database.

CommitDatabaseSQLite.commit()

Commit the transaction, so what it wrote stays.

Throws when no transaction is open.

CommitDatabaseSQLite.commitDatabasing()

Return the CommitDatabasing interface.

Returns:

CommitDatabasing

CommitDatabaseSQLite.inTransaction()

Return true if a transaction is running.

Returns:

boolean

CommitDatabaseSQLite.isClosed()

Return true if the database is closed.

Returns:

boolean

CommitDatabaseSQLite.rollback()

Roll back the transaction, so what it wrote is dropped.

Throws when no transaction is open.

CommitDatabaseSQLite.sqlite()
Return the SQLite connection underneath, for the settings and the statistics it

exposes.

Returns:

SQLite

static CommitDatabaseSQLite.create(filePath, documentation)

Create a database at filePath and return it.

documentation is stored in the file and read back by documentation().

Requires that nothing exist at filePath, and throws without creating anything when something does.

Arguments:
  • filePath (string)

  • documentation (string | null)

Returns:

CommitDatabaseSQLite

static CommitDatabaseSQLite.createInMemory()

Create a database in memory.

Returns:

CommitDatabaseSQLite

static CommitDatabaseSQLite.isCompatible(filePath)

Return true if the file at filePath carries the expected SQL schema.

Arguments:
  • filePath (string)

Returns:

boolean

static CommitDatabaseSQLite.open(filePath, readonly)

Open the database at filePath and return it.

readonly opens it without allowing a commit.

Requires a file at filePath, and throws when there is none.

Arguments:
  • filePath (string)

  • readonly (boolean | null)

Returns:

CommitDatabaseSQLite

class CommitDatabaseRemote()
A low-level class used to represent a remote Commit database through the

CommitDatabasing interface. Use the high-level static factory method CommitDatabase.connect(…) or CommitDatabase.connectLocal(…).

Note: Not directly instantiable.

exported from index.d

CommitDatabaseRemote.[Symbol․dispose]()

Release the resource at scope exit via using (TC39 disposable); delegates to close(). Idempotent.

CommitDatabaseRemote.close()

Close the connection.

CommitDatabaseRemote.commitDatabasing()

Return the CommitDatabasing interface.

Returns:

CommitDatabasing

CommitDatabaseRemote.downloadSpeed(size)

Return the download speed in MBps (megabytes per second).

Measured by receiving size megabytes. size is brought into [1, 1000]: a smaller one counts as 1, a larger one as 1000.

Arguments:
  • size (number | null)

Returns:

number

CommitDatabaseRemote.isClosed()

Return true if this connection to the server is closed.

Returns:

boolean

CommitDatabaseRemote.ping()
Ping (latency is the technically more correct term) means the time it

takes for a small data set to be transmitted from your device to a server and back to your device again. The ping time is measured in milliseconds (ms).

Returns:

number

CommitDatabaseRemote.uploadSpeed(size)

Return the upload speed in MBps (megabytes per second).

Measured by sending size megabytes. size is brought into [1, 1000]: a smaller one counts as 1, a larger one as 1000.

Arguments:
  • size (number | null)

Returns:

number

static CommitDatabaseRemote.connect(host, service)

Return a CommitDatabaseRemote served by host on service, over TCP.

Arguments:
  • host (string)

  • service (string | null)

Returns:

CommitDatabaseRemote

static CommitDatabaseRemote.connectLocal(socketPath)

Connect to the socket located at socketPath.

Arguments:
  • socketPath (string)

Returns:

CommitDatabaseRemote

class CommitDatabaseServer(database, socket, logging, cancelation)

Serve a CommitDatabase over a socket, one C++ thread per client.

Clients are served on C++ threads that never enter JS. This binding exposes no re-entrant logger - LoggerConsole, LoggerNull and LoggerReport are pure C++ - so any Logging is safe here. A logger able to call back into JS would have to be refused by this constructor, the way the Python binding refuses one.

step() is a bounded wait, so the loop must yield to the event loop between calls - otherwise timers, I/O and signal handlers never run:

const tick = () => {
    if (!server.step(1) || cancelation.requested()) { server.finishBefore(5); return; }
    setImmediate(tick);
};
server.start(); tick();

exported from index.d

Arguments:
  • database (string)

  • socket (Socket)

  • logging (Logging)

  • cancelation (Cancelation)

CommitDatabaseServer.finish()

Block until every client thread has answered the cancelation request.

CommitDatabaseServer.finishBefore(timeoutInSec)
Stop, waiting at most timeoutInSec. Returns the number of client threads

still running - zero means it stopped cleanly.

Arguments:
  • timeoutInSec (number)

Returns:

number

CommitDatabaseServer.start()

Listen on the server socket, without blocking.

step() then accepts the clients one round at a time.

CommitDatabaseServer.step(timeoutInSec)

Accept the connections waiting, for at most timeoutInSec.

Returns false once the server has stopped, so a loop can end on it.

Arguments:
  • timeoutInSec (number | null)

Returns:

boolean

class CommitDatabasing()

Abstracts the persistence layer behind a Commit database.

Writes here need NO transaction, unlike Databasing, where every write requires one already open. beginTransaction is available for batching and is never a precondition.

Note: Not directly instantiable.

exported from index.d

CommitDatabasing.[Symbol․dispose]()

Release the resource at scope exit via using (TC39 disposable); delegates to close(). Idempotent.

CommitDatabasing.beginTransaction(mode)

Begin a transaction in mode ‘Deferred’ (the default), ‘Immediate’ or ‘Exclusive’.

Another spelling throws.

Transactions do not nest: calling this while inTransaction() is true throws, and the transaction already open is untouched.

Arguments:
  • mode (string | null)

CommitDatabasing.blob(blobId)

Return the bytes of the blob blobId names, or undefined if it is not held here.

Throws past 2 GB, where the bytes cannot be handed over in one piece. Ask blobInfo(blobId).chunked() first, and read such a blob with readBlob.

A blob reserved by createZeroBlob throws until freezeBlob seals it; blobInfo answers undefined for it meanwhile.

Arguments:
  • blobId (ValueBlobId)

Returns:

ValueBlob | undefined

CommitDatabasing.blobDatas(blobIds)
Return one BlobData per blobId of blobIds this source holds - the bytes together

with their layout.

Arguments:
  • blobIds (ValueSet<ValueBlobId> | ValueBlobId[])

Returns:

BlobData[]

CommitDatabasing.blobIds()

Return the distinct blobId of every sealed blob.

A blob createZeroBlob reserved joins it once freezeBlob seals it.

Returns:

ValueSet<ValueBlobId>

CommitDatabasing.blobInfo(blobId)

Return the BlobInfo for blobId, or undefined if there is no such blob.

It gives the layout, the size, whether the blob is chunked, and the rowid that reaches it. A blob createZeroBlob reserved answers undefined until freezeBlob seals it.

Arguments:
  • blobId (ValueBlobId)

Returns:

BlobInfo | undefined

CommitDatabasing.blobInfos(blobIds)

Return one BlobInfo per blobId of blobIds this source holds.

An unknown blobId is left out, so the array may be shorter than blobIds.

Arguments:
  • blobIds (ValueSet<ValueBlobId> | ValueBlobId[])

Returns:

BlobInfo[]

CommitDatabasing.blobStatistics()

Return the statistics for blobs.

Returns:

BlobStatistics

CommitDatabasing.blobStreamClose(streamId, blobId)

Close the stream streamId names, storing what it collected under blobId.

Arguments:
  • streamId (ValueUUId)

  • blobId (ValueBlobId)

CommitDatabasing.blobStreamCreate(blobLayout, size)
Open a stream for a blob of size bytes laid out by blobLayout, and return the uuid

naming it.

Arguments:
  • blobLayout (BlobLayout)

  • size (number)

Returns:

ValueUUId

CommitDatabasing.blobStreamDelete(streamId)

Drop the stream streamId names, discarding what it collected.

Arguments:
  • streamId (ValueUUId)

CommitDatabasing.blobStreamWrite(streamId, blob, offset)

Write blob into the stream streamId names, at offset.

Arguments:
  • streamId (ValueUUId)

  • blob (ValueBlob)

  • offset (number)

CommitDatabasing.childrenCommitIds(commitId)

Return the distinct commitId for the children of the commit.

Arguments:
  • commitId (ValueCommitId)

Returns:

ValueSet<ValueCommitId>

CommitDatabasing.close()

Close the connection.

CommitDatabasing.codecName()

Return the name of the codec.

Returns:

string

CommitDatabasing.commit()

Commit the transaction, so what it wrote stays.

Throws when no transaction is open.

CommitDatabasing.commitData(commitId)
Return the CommitData commitId names - its header and its encoded opcodes - or undefined

if this source does not hold it.

Arguments:
  • commitId (ValueCommitId)

Returns:

CommitData | undefined

CommitDatabasing.commitDatas(commitIds)
Return one CommitData per commitId of commitIds, or all of them when commitIds is

undefined.

Arguments:
  • commitIds (ValueSet<ValueCommitId> | ValueCommitId[] | null)

Returns:

CommitData[]

CommitDatabasing.commitExists(commitId)

Return true if this source holds the commit commitId names.

Arguments:
  • commitId (ValueCommitId)

Returns:

boolean

CommitDatabasing.commitHeader(commitId)

Return the header of the commit associated with the commitId.

Arguments:
  • commitId (ValueCommitId)

Returns:

CommitHeader

CommitDatabasing.commitIds()

Return the distinct commitIds.

Returns:

ValueSet<ValueCommitId>

CommitDatabasing.createBlob(blobId, blobLayout, blob)

Store blob under blobId and blobLayout.

Arguments:
  • blobId (ValueBlobId)

  • blobLayout (BlobLayout)

  • blob (ValueBlob)

Returns:

boolean

CommitDatabasing.createBlobs(blobDatas)

Store every BlobData of blobDatas, and return the blobIds it added.

One the store already holds is left as it is and stays out of the answer, so an empty answer means every one of them was there already.

Arguments:
  • blobDatas (BlobData[])

Returns:

ValueSet<ValueBlobId>

CommitDatabasing.createCommitData(commitData)

Store commitData, and return true if it was not already there.

Arguments:
  • commitData (CommitData)

Returns:

boolean

CommitDatabasing.createZeroBlob(blobId, blobLayout, size)

Reserve size zeroed bytes under blobId and blobLayout.

The blob is filled later. Returns true if it was created.

Until freezeBlob seals it, blobIds leaves it out, blobInfo answers undefined, and blob and readBlob throw.

Arguments:
  • blobId (ValueBlobId)

  • blobLayout (BlobLayout)

  • size (number)

Returns:

boolean

CommitDatabasing.dataVersion()

Return the counter another connection’s commit bumps.

An unchanged value means nothing was committed elsewhere since the last read.

Returns:

number

CommitDatabasing.definitions()

Return the Definitions every value in this source is typed by.

It is a SNAPSHOT: extending the source afterwards does not show through the handle you hold, so ask again. A view obtained from Definitions.const() is live instead - same class, opposite liveness.

Returns:

DefinitionsConst

CommitDatabasing.definitionsHexdigest()

Return the SHA1 of the definitions, as a hex string.

Returns:

string

CommitDatabasing.deleteCommit(commitId)

Delete the commit commitId names.

Breaks the append-only invariant every other reader relies on, and only makes sense on a head: deleting any other commit orphans its descendants. Kept for rewinding an interactive demonstration, not for storage management.

Arguments:
  • commitId (ValueCommitId)

CommitDatabasing.documentation()
Return the free text stored with the database at create(). One made without any

answers ‘not documented.’, one made in memory answers ‘In Memory’ - both are placeholders written in at create(), not substituted on read.

Returns:

string

CommitDatabasing.extendDefinitions(other)

Add every type and attachment of other that this source does not already hold.

Arguments:
  • other (DefinitionsConst)

Returns:

DefinitionsExtendInfo

CommitDatabasing.firstCommitId()

Return the commitId of the first commit or undefined.

First in creation order, which is the root of the DAG CommitNode.build walks.

Returns:

ValueCommitId | undefined

CommitDatabasing.freezeBlob(blobId)
Seal the blob blobId names against further writes, and return true if it was still

open.

Arguments:
  • blobId (ValueBlobId)

Returns:

boolean

CommitDatabasing.headCommitIds()

Return the distinct commitId for the heads.

Returns:

ValueSet<ValueCommitId>

CommitDatabasing.inTransaction()

Return true if a transaction is running.

Returns:

boolean

CommitDatabasing.isClosed()

Return true if the connection to the database is closed.

Returns:

boolean

CommitDatabasing.lastCommitId()

Return the commitId of the last commit or undefined.

Last in creation order: the one a new commit follows, and the one CommitStore.use resumes from.

Returns:

ValueCommitId | undefined

CommitDatabasing.nephewCommitIds(commitId)

Return the distinct commitId for the nephew of the commit.

Arguments:
  • commitId (ValueCommitId)

Returns:

ValueSet<ValueCommitId>

CommitDatabasing.path()

Return the file path behind this source.

A database made in memory answers ‘InMemory’ rather than a path, and that exact string is how the runtime recognises one, so no file may take it: creating or opening a file of that path throws. Over a socket the answer is whatever the server answers for its own database.

Returns:

string

CommitDatabasing.readBlob(blobId, size, offset)

Return size bytes of the blob blobId names, starting at offset.

The read side of blobStreamCreate, blobStreamWrite and blobStreamClose, and the only way to read a blob past 2 GB, which blob() refuses.

Arguments:
  • blobId (ValueBlobId)

  • size (number)

  • offset (number)

Returns:

ValueBlob

CommitDatabasing.resetCommits()

Remove all commits except the first one.

Breaks the append-only invariant every other reader relies on. Kept for replaying an interactive demonstration from a known baseline, not for storage management.

CommitDatabasing.rollback()

Roll back the transaction, so what it wrote is dropped.

Throws when no transaction is open.

CommitDatabasing.syncData(commitIds)

Return what a synchronizer needs to carry the commits of commitIds.

The commits, the codec their opcodes were encoded with, and the digest of the definitions. The blobs they reference are not included: they travel apart, through blobDatas.

Arguments:
  • commitIds (ValueSet<ValueCommitId> | ValueCommitId[])

Returns:

CommitSyncData

CommitDatabasing.unknownBlobIds(blobIds)

Return the distinct blobId for all unknown blobId found in blobIds.

Arguments:
  • blobIds (ValueSet<ValueBlobId> | ValueBlobId[])

Returns:

ValueSet<ValueBlobId>

CommitDatabasing.uuid()

Return the uuid identifying the database behind this source.

Returns:

ValueUUId

CommitDatabasing.writeBlob(blobId, blob, offset)

Write the bytes of blob into the stored blob blobId names, at offset.

Arguments:
  • blobId (ValueBlobId)

  • blob (ValueBlob)

  • offset (number)

class CommitState(definitions)

The data reconstructed at one commit, by replaying the mutations down to it.

Read it through the AttachmentGetting interface. Built by CommitStateBuilder in normal use; the constructor makes an empty one over definitions.

exported from index.d

Arguments:
  • definitions (DefinitionsConst)

CommitState.attachmentGetting()

Return the AttachmentGetting interface.

Returns:

AttachmentGetting

CommitState.cacheHitRate()

Return the share of reads answered from the cache, between 0 and 1.

Returns:

number

CommitState.cacheHits()

Return the count of value return from the cache.

Returns:

number

CommitState.cachePreload()

Read every attachment’s documents into the cache, and return the seconds taken.

Every read is a first read, so the time includes one isolated copy per document, which this call then discards.

Returns:

number

CommitState.cacheRequests()

Return the count of value requested.

Returns:

number

CommitState.commitId()

Return the identifier of the commit.

Returns:

ValueCommitId

CommitState.commitStateTracing()
Return the CommitStateTracing interface, which answers a read with the commits that

produced the value.

Returns:

CommitStateTracing

CommitState.definitions()

Return the Definitions every value in this state is typed by.

Returns:

DefinitionsConst

CommitState.evalActions()

Return a list of CommitEvalAction.

Returns:

CommitEvalAction[]

CommitState.tracedOpcodes()

Return the list of opcodes from the commit trace.

Returns:

ValueOpcode[]

class CommitMutableState(state)

Registers the mutations of a value executed through the AttachmentMutating interface.

exported from index.d

Arguments:
  • state (CommitState)

CommitMutableState.attachmentGetting()

Return the AttachmentGetting interface.

Returns:

AttachmentGetting

CommitMutableState.attachmentMutating()

Return the AttachmentMutating interface.

Returns:

AttachmentMutating

CommitMutableState.commitState()

Return the CommitState.

Returns:

CommitState

CommitMutableState.commitStateTracing()

Return the CommitStateTracing interface.

Returns:

CommitStateTracing

CommitMutableState.mutations()

Return the program for the current mutations.

Returns:

ValueProgram

class CommitStateBuilder()

Reconstructs a CommitState from a chosen commit.

state(commitDatabase, commitId), initialState(commitDatabase), mergeState(commitDatabase, ours, theirs). Stateless: every method takes the database as its first argument.

Note: Not directly instantiable.

exported from index.d

static CommitStateBuilder.enabledByCommitId(commitDatabase, commitId)
Return which commits of commitDatabase are enabled at the commit commitId names, as

[commitId, enabled] pairs.

Arguments:
  • commitDatabase (CommitDatabase)

  • commitId (ValueCommitId)

Returns:

[ValueCommitId, boolean][]

static CommitStateBuilder.initialState(commitDatabase)

Return the state of commitDatabase before its first commit.

Every attachment is empty, typed by its definitions. This is where a sequence STARTS, and only there. Coming back to it on a database that already holds commits builds the next one from the root again, which diverges into a second head: use state() with the commitId the last commitMutations returned to carry on instead.

Arguments:
  • commitDatabase (CommitDatabase)

Returns:

CommitState

static CommitStateBuilder.mergeEnabledByCommitId(commitDatabase, ours, theirs)
Return which commits would be enabled by reducing ours and theirs in commitDatabase,

as [commitId, enabled] pairs, for the virtual merge of ours and theirs, without persisting a merge commit.

Arguments:
  • commitDatabase (CommitDatabase)

  • ours (ValueCommitId)

  • theirs (ValueCommitId)

Returns:

[ValueCommitId, boolean][]

static CommitStateBuilder.mergeState(commitDatabase, ours, theirs)

Return the state reducing ours and theirs would produce.

Computed over commitDatabase, without persisting a merge commit.

Value-identical to state(mergeCommit(ours, theirs)).

Arguments:
  • commitDatabase (CommitDatabase)

  • ours (ValueCommitId)

  • theirs (ValueCommitId)

Returns:

CommitState

static CommitStateBuilder.state(commitDatabase, commitId)

Return the state commitDatabase reaches at the commit commitId names.

It evaluates every commit down to it. This is how a sequence CARRIES ON: hand it the commitId that commitMutations returned and the next mutation continues the same line, where initialState would start a second one. CommitStore keeps that thread for you, if you would rather not hold it yourself.

ValueCommitId.INVALID is the one id naming no commit that this accepts, and it answers what initialState does. It names the root CommitNode.build() shows, which stands for the state before the first commit; commitHeader throws on that same id, having no header to return.

Arguments:
  • commitDatabase (CommitDatabase)

  • commitId (ValueCommitId)

Returns:

CommitState

class CommitNode()

One commit in the DAG, linked to the commits that follow it.

build() returns the whole DAG for a commit database; header() carries the label, type, parent and timestamp.

The node build() roots that DAG at is the one exception: it carries a label and a type like any other, and no commit backs it.

Note: Not directly instantiable.

exported from index.d

CommitNode.children()

Return the list of childs.

Returns:

CommitNode[]

CommitNode.header()

Return the CommitHeader of this node - its label, type, parent and timestamp.

Returns:

CommitHeader

static CommitNode.build(commitDatabase)

Return the DAG of commitDatabase, as linked CommitNode.

It is rooted at one node that no commit backs, and that root is what the walk starts from - so a database holding two commits answers three nodes. It stands for the state before anything was written: its commitId is ValueCommitId.INVALID, commitExists says false for it, and commitHeader throws, a node without a commit having no header. CommitStateBuilder.state accepts that id and answers the initial state.

Arguments:
  • commitDatabase (CommitDatabase)

Returns:

CommitNode

class CommitNodeGrid()

One commit’s place in the DAG once it is laid out on a grid.

row() and column() are the position; parent() and children() walk the layout, and header() reaches the commit itself.

Note: Not directly instantiable.

exported from index.d

CommitNodeGrid.childCount()

Return the number of children.

Returns:

number

CommitNodeGrid.children()

Return the nodes whose parent is this one.

Returns:

CommitNodeGrid[]

CommitNodeGrid.column()

Return the column the node sits in, once the DAG is laid out.

Returns:

number

CommitNodeGrid.commitId()

Return the commitId of the commit this node stands for.

Returns:

ValueCommitId

CommitNodeGrid.hasChildren()

Return true if the node has children.

Returns:

boolean

CommitNodeGrid.header()

Return the CommitHeader of the commit this node stands for.

Returns:

CommitHeader

CommitNodeGrid.parent()

Return the parent or undefined.

Returns:

CommitNodeGrid | undefined

CommitNodeGrid.row()

Return the row the node sits in, once the DAG is laid out.

Returns:

number

class CommitNodeGridBuilder()

Builds the grid layout of the commit DAG.

Note: Not directly instantiable.

exported from index.d

CommitNodeGridBuilder.columnMax()

Return the max index for a column.

Returns:

number

CommitNodeGridBuilder.nodes()

Return the laid-out nodes, keyed by commit.

The key is the ValueCommitId of the commit a node stands for. The root the layout starts from is in here too, under ValueCommitId.INVALID, so a database holding one commit answers two entries.

Returns:

[ValueCommitId, CommitNodeGrid][]

CommitNodeGridBuilder.root()

Return the root node or undefined.

Returns:

CommitNodeGrid | undefined

CommitNodeGridBuilder.rowMax()

Return the max index for row.

Returns:

number

static CommitNodeGridBuilder.build(commitNode)
Return a builder that lays the DAG rooted at commitNode onto a grid of rows and

columns.

Arguments:
  • commitNode (CommitNode)

Returns:

CommitNodeGridBuilder

class CommitHeader()

What identifies a commit, without its content.

Its id and parent, timestamp, label, type, and - for a merge - the commit it targets.

Note: Not directly instantiable.

exported from index.d

CommitHeader.commitId()

Return the commitId of the commit.

Returns:

ValueCommitId

CommitHeader.commitType()

Return the type (‘Mutations’, ‘Disable’, ‘Enable’ or ‘Merge’).

Returns:

string

CommitHeader.label()

Return the label the commit was created under.

Returns:

string

CommitHeader.parentCommitId()

Return the commitId of the parent commit.

Returns:

ValueCommitId

CommitHeader.targetCommitId()

Return the commitId of the target commit.

Returns:

ValueCommitId

CommitHeader.timestamp()

Return when the commit was created, in seconds since the epoch.

It does not order commits. It is written to the millisecond, and a burst (a dispatch and the undo that follows it) shares one value, so sorting on it leaves the order to whatever the sort falls back on. Walk CommitNode.build for the order, or take firstCommitId and lastCommitId for the ends.

Returns:

number

class CommitData()

One commit’s encoded opcodes, with the header that places it.

What one database hands another when they synchronize. opcodes() decodes them against definitions; sort() puts a list of them in topological order.

Note: Not directly instantiable.

exported from index.d

CommitData.blobIds(streamCodecInstancing, definitions)
Return the blobId set the opcodes reference, decoding them with

streamCodecInstancing against definitions.

Arguments:
  • streamCodecInstancing (StreamCodecInstancing)

  • definitions (DefinitionsConst)

Returns:

ValueSet<ValueBlobId>

CommitData.data()

Return the blob of the encoded opcodes.

Returns:

ValueBlob

CommitData.header()

Return the CommitHeader - the label, type, parent and timestamp.

Returns:

CommitHeader

CommitData.opcodes(streamCodecInstancing, definitions)

Return the opcodes, decoded with streamCodecInstancing against definitions.

Arguments:
  • streamCodecInstancing (StreamCodecInstancing)

  • definitions (DefinitionsConst)

Returns:

ValueOpcode[]

static CommitData.sort(commitDatas)

Return the list of CommitData, topologically sorted.

Arguments:
  • commitDatas (CommitData[])

Returns:

CommitData[]

class CommitEvalAction()
A class used by the evaluator to reconstruct a value by executing mutation

opcodes.

Note: Not directly instantiable.

exported from index.d

CommitEvalAction.enabled()

Return true if the commit is enabled.

Returns:

boolean

CommitEvalAction.header()

Return the header of the commit.

Returns:

CommitHeader

CommitEvalAction.program()

Return the ValueProgram this action applied - the opcodes of one commit.

Returns:

ValueProgram

class CommitDatabaseHelper()

Navigates the commit DAG.

reduceHeads(commitDatabase [, commitId]) reduces multiple heads into one, the head commitId names or the last commit by default; forward and fastForward move along the DAG. Stateless, like CommitStateBuilder.

Note: Not directly instantiable.

exported from index.d

static CommitDatabaseHelper.fastForward(commitDatabase, commitId)
Return the head commitDatabase reaches from commitId by following its single child

at each step.

Arguments:
  • commitDatabase (CommitDatabase)

  • commitId (ValueCommitId)

Returns:

ValueCommitId

static CommitDatabaseHelper.forward(commitDatabase, commitId)
Return the head of commitDatabase when there is only one, and otherwise what

fastForward(commitId) reaches.

Arguments:
  • commitDatabase (CommitDatabase)

  • commitId (ValueCommitId)

Returns:

ValueCommitId

static CommitDatabaseHelper.reduceHeads(commitDatabase, commitId)

Reduce commitDatabase to a single head, and return the new commitId.

The other heads are reduced one at a time into the anchor commitId, which must itself be a head and defaults to lastCommitId. Returns undefined when there was nothing to reduce.

On a path both heads wrote, the later in linearisation order wins and the other is dropped; nothing is signalled. CommitMergeAnalyzer reconstructs, after the fact, what a merge did not keep.

Arguments:
  • commitDatabase (CommitDatabase)

  • commitId (ValueCommitId | null)

Returns:

ValueCommitId | undefined

class CommitStore()
A high-level application class used to implement the store, dispatch,

undo/redo and notification concepts inspired by the redux approach.

The implementation uses a Commit database for the persistence layer.

A dispatch throws before it runs: without a database, or on an argument that does not convert to the type it is written as. What fails once it runs - the callable, a write, the commit - does not throw: nothing is committed, the error goes to the notifier’s notifyDispatchError, and it is lost when no notifier is set.

exported from index.d

CommitStore.[Symbol․dispose]()

Release the resource at scope exit via using (TC39 disposable); delegates to close(). Idempotent.

CommitStore.attachmentGetting()

Return the AttachmentGetting interface of the current state or throw.

Like state(), it reads the state current when it was asked for.

Returns:

AttachmentGetting

CommitStore.canRedo()

Return true if the store can redo.

Returns:

boolean

CommitStore.canUndo()

Return true if the store can undo.

Returns:

boolean

CommitStore.clearUndoRedo()

Empty the undo and redo stacks, anchored on nothing.

Unlike resetUndoRedo, it needs no state and never throws.

CommitStore.close()

Let go of the database and the state this store holds.

Whether the database then closes depends on who else holds it. The store drops its reference, and the database closes when that was the last one - which it is when you handed use() a database you kept no name for. Keep your own reference to decide yourself.

After this, hasDatabase() and hasState() are false, and a dispatch throws.

CommitStore.commitMutations(label, commitMutableState)
Append the opcodes commitMutableState recorded as a new commit under label, move

onto it and notify.

Arguments:
  • label (string)

  • commitMutableState (CommitMutableState)

CommitStore.database()

Return the database or throw.

Returns:

CommitDatabase

CommitStore.definitions()

Return the Definitions every value in the database is typed by.

It is a SNAPSHOT: extending the database afterwards does not show through the handle you hold, so ask again. A view obtained from Definitions.const() is live instead - same class, opposite liveness.

Returns:

DefinitionsConst

CommitStore.deleteCommit(commitId)

Delete the commit commitId names.

Breaks the append-only invariant every other reader relies on, and only makes sense on a head: deleting any other commit orphans its descendants. Kept for rewinding an interactive demonstration, not for storage management. The store moves onto the parent of commitId and clears its undo and redo stacks.

Arguments:
  • commitId (ValueCommitId)

CommitStore.disableCommit(commitId)

Append a commit hiding commitId and move onto it.

It sits on top of the current commit.

Nothing is removed: the evaluator skips the hidden commit from here on. The undo stack is left alone; dispatchEnableCommit is the undoable form.

Arguments:
  • commitId (ValueCommitId)

CommitStore.dispatch<T>(label, callable, ...args)

Run callable against a fresh mutable state and commit what it wrote.

The commit carries label.

args are passed on to callable after the AttachmentMutating interface. Returns what callable returns, or undefined when it throws: nothing is committed, and the error reaches the notifier instead.

Type parameters:

T –

Arguments:
  • label (string)

  • callable ((mutating: AttachmentMutating, args: any[]) => T)

  • args (any[])

Returns:

T | undefined

CommitStore.dispatchDiff(label, attachment, key, value, recursive)

Commit under label a diff against what attachment holds at key.

Only what differs from value is written, and an absent document is written whole. A set or map field is diffed entry by entry; a structure field is written whole, or walked field by field when recursive is true.

Arguments:
  • label (string)

  • attachment (Attachment)

  • key (ValueKey)

  • value (InputValue)

  • recursive (boolean | null)

CommitStore.dispatchEnableCommit(commitId, enabled)
Commit the hiding of commitId, or its unhiding when enabled is true, and move onto

the new commit.

Arguments:
  • commitId (ValueCommitId)

  • enabled (boolean)

CommitStore.dispatchSet(label, attachment, key, value)

Commit under label the writing of value at key in attachment.

Arguments:
  • label (string)

  • attachment (Attachment)

  • key (ValueKey)

  • value (InputValue)

CommitStore.dispatchUpdate(label, attachment, key, path, value)
Commit under label the writing of value at path, inside the document attachment

holds at key.

Arguments:
  • label (string)

  • attachment (Attachment)

  • key (ValueKey)

  • path (PathConst)

  • value (InputValue)

CommitStore.enableCommit(commitId)

Append a commit unhiding commitId and move onto it.

It sits on top of the current commit. The undo stack is left alone; dispatchEnableCommit is the undoable form.

Arguments:
  • commitId (ValueCommitId)

CommitStore.extendDefinitions(definitions)
Add every type and attachment of definitions the database does not already hold,

then notify.

Arguments:
  • definitions (DefinitionsConst)

Returns:

DefinitionsExtendInfo

CommitStore.forward()
Move onto the head reached from the current commit by following its single child at

each step.

CommitStore.hasDatabase()

Return true if a database is in use.

Returns:

boolean

CommitStore.hasState()

Return true if a state has been built.

Returns:

boolean

CommitStore.mergeCommit(commitId)

Append a commit joining the current head and commitId, and move onto it.

The commit records the pair; nothing is composed here. At reconstruction commitId’s mutations land last, so on a path both wrote its value wins and the other is dropped; nothing is signalled. The undo stack is left alone. CommitMergeAnalyzer reconstructs, after the fact, what a merge did not keep.

Arguments:
  • commitId (ValueCommitId)

CommitStore.mutableState()

Return a new mutable state for the current state.

Returns:

CommitMutableState

CommitStore.notifier()

Return the notifier or undefined.

Returns:

CommitStoreNotifying | undefined

CommitStore.notifyDatabaseDidClose()

Send a notification to inform that the database was closed.

CommitStore.notifyDatabaseDidOpen()

Send a notification to inform that the database was opened.

CommitStore.notifyDatabaseDidReset()

Send a notification to inform that the database did reset.

CommitStore.notifyDatabaseWillReset()

Send a notification to inform that the database will reset.

CommitStore.notifyDefinitionsDidChange()

Send a notification to inform that the definitions has changed.

CommitStore.notifyDispatchError(error)

Send a notification to inform that an error occurred during a dispatch.

Arguments:
  • error (Error)

CommitStore.notifyResetDatabase()

Send a notification to reset the database.

CommitStore.notifyStateDidChange()

Send a notification to inform that the current state has changed.

CommitStore.notifyStopLive()

Send a notification to stop the live mode.

CommitStore.redo()

Redo the last undone dispatch.

A commit is appended that hides the hiding one.

The new commit is labelled Redo [<label of the target>].

CommitStore.reduceHeads()

Reduce the database to a single head, starting from lastCommitId.

The other heads are reduced one at a time, and the store moves onto the result.

On a path both heads wrote, the later in linearisation order wins and the other is dropped; nothing is signalled. CommitMergeAnalyzer reconstructs, after the fact, what a merge did not keep.

CommitStore.reset()

Remove all commits except the first one.

Breaks the append-only invariant every other reader relies on. Kept for replaying an interactive demonstration from a known baseline, not for storage management.

CommitStore.resetUndoRedo()

Empty the undo and redo stacks and anchor them on the current commit.

Throws when the store has no state, where clearUndoRedo does not.

CommitStore.setDatabase(commitDatabase)
Take commitDatabase as the store’s database, without building a state or notifying -

use() does both.

Arguments:
  • commitDatabase (CommitDatabase)

CommitStore.setNotifier(notifier)

Set the notifier.

Arguments:
  • notifier (CommitStoreNotifying)

CommitStore.setState(commitState)

Take commitState as the store’s current state, without notifying.

Arguments:
  • commitState (CommitState)

CommitStore.state()

Return the current state, or undefined when the store holds none.

It holds none before use(commitDatabase) and after close(). It is a snapshot: a later dispatch, undo or redo builds a new state, and the one held keeps answering what it held. hasState() answers whether there is one.

Returns:

CommitState | undefined

CommitStore.undo()

Undo the last dispatch by appending a commit that hides it.

Not a rollback: nothing is removed, the history keeps growing forward, and the new commit is labelled Undo [<label of the target>].

CommitStore.undoStackIds()
Return [commitIds, current]: the commits made since the base, oldest first, and the

index in commitIds of the one the store is on, or undefined when it is back on the base with nothing to undo. The ids after current are what redo reapplies.

Returns:

[ValueCommitId[], number | undefined]

CommitStore.use(commitDatabase)
Take commitDatabase, build the state of its last commit - or the initial one if it

holds none - and notify.

Arguments:
  • commitDatabase (CommitDatabase)

CommitStore.useCommit(commitId)

Rebuild the current state from the commit commitId names.

Nothing is notified and the undo stack is left alone: an undo after it still undoes the last dispatch, and writes that undo on the commit used here - so moving back to an earlier commit, then undoing, opens a second head. resetUndoRedo() anchors the stacks on the commit used.

Arguments:
  • commitId (ValueCommitId)

class CommitStoreNotifying()

An interface used to represent the notification emitted by a store.

Note: Not directly instantiable.

exported from index.d

CommitStoreNotifying.notifyDatabaseDidClose()

Send a notification to inform that the database was closed.

CommitStoreNotifying.notifyDatabaseDidOpen()

Send a notification to inform that the database was opened.

CommitStoreNotifying.notifyDatabaseDidReset()

Send a notification to inform that the database did reset.

CommitStoreNotifying.notifyDatabaseWillReset()

Send a notification to inform that the database will be reset.

CommitStoreNotifying.notifyDefinitionsDidChange()

Send a notification to inform that the definitions have changed.

CommitStoreNotifying.notifyDispatchError(error)

Send a notification to inform that an error occurred during a dispatch.

Arguments:
  • error (Error)

CommitStoreNotifying.notifyResetDatabase()

Send a notification to reset the database.

CommitStoreNotifying.notifyStateDidChange()

Send a notification to inform that the current state has changed.

CommitStoreNotifying.notifyStopLive()

Send a notification to stop the live mode.

static CommitStoreNotifying.create(object)

Return a CommitStoreNotifying over object, or throw.

Throws TypeError when object lacks one of the notify methods. A notification is sent once the store has acted, so an exception thrown by the object is dropped and the store call completes.

Arguments:
  • object (NativeValue)

Returns:

CommitStoreNotifying

class CommitSynchronizer(source, target, mode, sizeOfPackedBlobs)
Synchronizes two concrete databases through the CommitDatabasing interface (low-level

driver interface).

exported from index.d

Arguments:
  • source (CommitDatabasing)

  • target (CommitDatabasing)

  • mode (string | null)

  • sizeOfPackedBlobs (number | bigint | null)

CommitSynchronizer.MODE_FETCH

type: readonly string

CommitSynchronizer.MODE_PUSH

type: readonly string

CommitSynchronizer.MODE_SYNC

type: readonly string

CommitSynchronizer.mode()
Return which way data moves - Fetch carries source into target, Push carries target

into source, and Sync runs both.

Returns:

string

CommitSynchronizer.sizeOfPackedBlobs()

Return the size in bytes of the blob smaller blobs are packed into.

Returns:

bigint

CommitSynchronizer.source()

Return the CommitDatabasing interface for the source.

Returns:

CommitDatabasing

CommitSynchronizer.sync(logging)

Carry the commits and blobs missing on either side, as the mode allows.

Compares nothing when neither side’s dataVersion() moved since the last call, as CommitSynchronizerInfo.needTransmit states. logging receives the progress; pass null to stay silent.

Arguments:
  • logging (Logging | null)

Returns:

CommitSynchronizerInfo

CommitSynchronizer.target()

Return the CommitDatabasing interface for the target.

Returns:

CommitDatabasing

class CommitSynchronizerInfo()

What a synchronization found.

Whether anything needs transmitting, what was fetched and pushed, and whether the definitions changed.

Note: Not directly instantiable.

exported from index.d

CommitSynchronizerInfo.fetch()

Return information for fetched resources.

Returns:

CommitSynchronizerInfoTransmit

CommitSynchronizerInfo.needTransmit()

Return true if either side’s dataVersion() moved since the last sync.

When neither did, sync() compared and carried nothing. dataVersion() counts the writes made through other connections, so a commit written through a connection the synchronizer holds waits until another connection writes: give the synchronizer connections of its own.

Returns:

boolean

CommitSynchronizerInfo.push()

Return information for pushed resources.

Returns:

CommitSynchronizerInfoTransmit

CommitSynchronizerInfo.updatedDefinitions()

Return true if the definitions has updated.

Returns:

boolean

class CommitSynchronizerInfoTransmit()

What one synchronization actually transferred.

How many commits and blobs were transferred and their byte totals, plus the DefinitionsExtendInfo for the definitions that came with them.

Note: Not directly instantiable.

exported from index.d

CommitSynchronizerInfoTransmit.blobBytes()

Return the number of bytes for blobs.

Returns:

bigint

CommitSynchronizerInfoTransmit.blobs()

Return the number of blobs.

Returns:

bigint

CommitSynchronizerInfoTransmit.commitBytes()

Return the number of commit bytes transferred.

Returns:

bigint

CommitSynchronizerInfoTransmit.commits()

Return the number of commits transferred.

Returns:

bigint

CommitSynchronizerInfoTransmit.extendInfo()

Return the information to extend.

Returns:

DefinitionsExtendInfo

class CommitSyncData()

The commits one database hands another when they synchronize.

commitDatas() is the payload. codecName() names the codec the opcodes were encoded with, and definitionsHexdigest() the digest of the definitions they were encoded against.

Note: Not directly instantiable.

exported from index.d

CommitSyncData.codecName()

Return the name of the codec.

Returns:

string

CommitSyncData.commitDatas()

Return the list of CommitData.

Returns:

CommitData[]

CommitSyncData.definitionsHexdigest()

Return the SHA1 of the definitions, as a hex string.

Returns:

string

class CommitStateTracing()

Asks a state for the trace of one document.

Given an attachment, returns how the document at each key was reconstructed.

Note: Not directly instantiable.

exported from index.d

CommitStateTracing.trace(attachment, key)
Return an CommitStateTrace associated with the key in the

attachment.

Arguments:
  • attachment (Attachment)

  • key (ValueKey)

Returns:

CommitStateTrace

class CommitStateTrace()

The replay of one document.

Its attachment, key and resulting value, with the programs that produced it.

Note: Not directly instantiable.

exported from index.d

CommitStateTrace.attachment()

Return the attachment the traced read went through.

Returns:

Attachment

CommitStateTrace.key()

Return the key the traced read asked for.

Returns:

ValueKey

CommitStateTrace.programs()

Return the list of programs.

Returns:

CommitStateTraceProgram[]

CommitStateTrace.value()

Return the value the traced read produced.

Returns:

ValueOptional

class CommitStateTraceProgram()

One commit’s contribution to a document.

Its header, and the trace of what it executed.

Note: Not directly instantiable.

exported from index.d

CommitStateTraceProgram.header()

Return the commit header or undefined.

Returns:

CommitHeader | undefined

CommitStateTraceProgram.trace()

Return the CommitStateTrace this program contributed to.

Returns:

ValueProcessorTrace