Cross-cutting rules every API spec under this directory inherits.
All public symbols are imported from the package root:
import {
// factories
openRepo, openStore,
// primary classes
Repository, Sheet, Transaction, PushDaemon, Template,
// error classes
GitsheetsError, ConfigError, ValidationError, TransactionError,
IndexError, RefError, PathTemplateError, NotFoundError,
// utilities
mergePatch, validateRecord,
// record annotation symbols (`record[RECORD_PATH_KEY]`, etc.)
RECORD_SHEET_KEY, RECORD_PATH_KEY,
} from 'gitsheets';Type-only exports (interfaces, type aliases) flow alongside the value exports
above. The full list: OpenRepoOptions, OpenSheetOptions, OpenSheetsOptions,
TransactionOptions, TransactionResult, TransactionHandler, Author,
SheetConfig, SheetFieldConfig, SortRule, UpsertResult, UpsertOptions,
SheetConstructorOptions,
IndexKeyFn, DefineIndexOptions,
QueryFilter, QueryOptions, DiffStatus, DiffOptions, DiffChange,
AttachmentBlobHandle, AttachmentEntry,
Format, FormatConfig,
OpenStoreOptions, Store, StoreTx, StoreTransactFn, ValidatorMap, InferRecord,
PushDaemonOptions, PushDaemonStatus, PushFailureReason, BackoffConfig,
JSONSchema, StandardSchemaV1, StandardSchemaIssue, StandardSchemaResult,
StandardSchemaFailure, StandardSchemaSuccess, StandardSchemaPathSegment,
ValidationIssue, RecordLike,
PathTemplateBlob, PathTemplateTree, PathTemplateQueryResult.
No deep imports (gitsheets/lib/Sheet) — the implementation can rearrange packages/gitsheets/src/ freely.
strict: truein shipped types.- Public functions have explicit return types — no
Promise<any>. - Generics flow from sheet configs through to consumer call sites (
Sheet<T>,Store<Schemas>).
- Read-many results:
async function*iterators. Consumersfor awaitthem. - Read-one:
Promise<T | undefined>. - Writes:
Promise<{ blob, path }>(single-record) orPromise<TransactionResult>(transaction commit).
Functions with more than two parameters take an options object:
// good
await sheet.defineIndex('byEmail', { unique: true, eager: false }, fn);
// not the convention
await sheet.defineIndex('byEmail', true, false, fn);Optional fields have documented defaults. Missing undefined is treated as "use default."
Every error thrown by gitsheets extends GitsheetsError and carries a stable code string. Consumers should switch on instanceof or on err.code — never on err.message. See api/errors.md.
Long-running iterations (Sheet.query, Sheet.queryFirst, Sheet.queryAll) honor AbortSignal when one is passed in via the options. Without a signal, they run to completion.
const controller = new AbortController();
for await (const record of sheet.query({}, { signal: controller.signal })) {
// ...
if (someCondition) controller.abort(); // optional reason arg → signal.reason
}When the signal aborts, the next iteration (or the call itself, if aborted before invocation) throws signal.reason — which is whatever value was passed to controller.abort(reason), or a DOMException with name 'AbortError' if no reason was supplied. Callers can try/catch on the iteration and switch on the thrown value's shape.
Any iterator added later in the public surface should follow the same convention (opts.signal, check before iteration, check at each yield).
The library exposes async iterators throughout. They are single-pass — re-iterating requires calling the producing method again. Internal caching may make re-iteration fast, but the iterators are not stateless.
- Methods that don't commit:
upsert,delete,patch,setAttachment— they stage tree writes. Commits happen on transaction boundary. - Methods that do commit (implicit transaction): none by name. Permissive mode commits at the end of any standalone mutation, but the method doesn't carry "commit" in its name.
- Methods that always commit explicitly:
Repository.transactandStore.transact.
The public API is the API surface speced under specs/api/. Anything not speced there is implementation detail and may change without notice. Breaking changes to speced surface require a major version bump.
When a ref isn't specified:
- Read operations default to the repository's
HEAD. - Write operations (transactions) default
parenttoHEAD. - The CLI honors
GITSHEETS_REFfor an override.
When a root isn't specified:
Repository.openSheet(name)defaultsrootto/(repo root) —.gitsheets/<name>.tomlis read from there.- The CLI honors
GITSHEETS_ROOTandGITSHEETS_PREFIXfor overrides (matching the pre-v1.0 behavior).
prefix is an optional runtime parameter — both Repository.openSheet({ prefix }) / openSheets({ prefix }) / Transaction.sheet(name, { prefix }) accept it, and the CLI exposes it as --prefix (env GITSHEETS_PREFIX). When set, records are read and written under <configRoot>/<prefix>/<rendered-path>.<ext> instead of <configRoot>/<rendered-path>.<ext>. The .gitsheets/<name>.toml config file location is unaffected by prefix — only the record data tree is scoped. Default: empty string (no prefix). Useful for multi-tenant sub-tree partitioning where one git repo holds many tenants under <root>/<tenant>/....
prefix is not threaded through openStore — for prefix-scoped typed access, open prefix-scoped sheets via repo.openSheet directly and assemble a typed wrapper manually.
- All file paths inside the data repo are POSIX-style (
/separators) regardless of host OS. - TOML reads and writes happen in the Rust
gitsheets-coreengine (the bytes-authority — see architecture.md); the Node binding surfaces datetimes asinstanceof Date. - Writes serialize to the byte-stable canonical form (deep-sorted keys) in the core, identical across every binding.