Thank you for being patient! We're working hard on resolving the issue
The Backend interface is the read/write seam between
@tento-lona/sheets and a concrete network/storage layer.
interface Backend {
fetchSheet(sheetId: string): Promise<RawSheet>;
fetchRowByKey(key: RowKey): Promise<RawRow | null>;
fetchCells(rowId: RowId, range: DateRange): Promise<RawCell[]>;
setCell(rowId: RowId, date: NaiveDate, entry: CellEntry): Promise<void>;
subscribeRow(rowId: RowId, cb: (change: RowChange) => void): Unsubscribe;
subscribeCell(rowId: RowId, date: NaiveDate, cb: (change: CellChange) => void): Unsubscribe;
}
TestBackendIn-memory backend for fixtures + unit tests. Hydrate from a
RawSheet then mutate freely; nothing leaves the process.
import { TestBackend, Sheet } from "@tento-lona/sheets";
const backend = new TestBackend();
backend.seed(rawSheet);
const sheet = await Sheet.from(rawSheet, { backend });
await sheet.setCell(rowLocalId, date, { value: 42 });
// → backend in-memory state updated, invalidation event fired
HttpBackendTalks to the Lona REST API. Used by the SDK client.
import { HttpBackend } from "@tento-lona/sheets";
const backend = new HttpBackend({
baseUrl: "https://api.lona.so",
accessToken: process.env.LONA_ACCESS_TOKEN,
});
NormalizingBackendWraps another backend and runs the encoding registry on every
read so consumers see canonical values instead of wire JSON. Most
SDK code wraps HttpBackend in NormalizingBackend.
import { HttpBackend, NormalizingBackend, EncodingRegistry } from "@tento-lona/sheets";
const transport = new HttpBackend({ /* ... */ });
const encoding = new EncodingRegistry();
registerBuiltinEncodings(encoding);
const backend = new NormalizingBackend({ transport, encoding });
CanonicalBackendDedup layer over a normalizing backend that shares
provider-keyed (:~) cell reads across multiple Sheet
instances in one client. App code rarely instantiates this
directly — SheetsAccessor (in @tento-lona) sets it up.
Implement the interface and you have a new transport. Common custom backends:
subscribeRow callbacks.commit().The Backend contract has no DOM dependency, so a custom backend
runs unchanged under Node, Deno, or the browser.
NormalizingBackend does on readSheet.from(raw, { backend })