Thank you for being patient! We're working hard on resolving the issue
Compact reference for the Lona SDK.
import { LonaSdk } from "@tento-lona";
const client = new LonaSdk.Client(config: ClientConfig);
| Member | Returns | Description |
|---|---|---|
client.open(key) | Promise<SheetHandle> | Open a sheet by key |
client.open({ ephemeral }) | Promise<SheetHandle> | Create local sheet |
client.setCurrentUser(userId) | void | Bind the active user for user-scoped row and sheet lookups |
client.sheets.list() | Promise<UserSheet[]> | List all sheets |
client.sheets.get(key) | Promise<UserSheetWithRows> | Get sheet with rows |
client.sheets.create(attrs) | Promise<UserSheetWithRows> | Create a sheet |
client.sheets.update(key, attrs) | void | Update sheet metadata (debounced) |
client.sheets.reorder(key, body) | Promise | Reorder sheet position |
client.sheets.delete(key) | Promise<void> | Delete a sheet |
client.sheets.getAcl(key) | Promise<AccessEntry[]> | List access control |
client.sheets.grantAccess(key, acl) | Promise<void> | Grant access |
client.sheets.revokeAccess(key, userId) | Promise<void> | Revoke access |
client.rows.open(key) | Promise<Row | null> | Open a row by key (supports cross-user) |
client.events | EventsStore | Reactive event index and mutations |
client.calendars | CalendarClient | Connected calendar management |
client.tasks | TasksClient | Task CRUD operations |
client.user | UserClient | User profile operations |
client.preferences | PreferencesClient | User preferences |
client.themes | ThemeStore | Theme management |
| Field | Type | Required | Description |
|---|---|---|---|
storage | PreferencesStorage | yes | Persistence backend (localStorage or in-memory) |
platform | SheetPlatform | yes | Layout queries and infrastructure (SheetPlatform.TEST for headless) |
feedback | FeedbackDelegate | no | UI feedback callbacks (defaults to FeedbackDelegate.NOOP) |
invalidation | InvalidationSink | no | Change event sink (defaults to InvalidationSink.NOOP) |
baseUrl | string | no | API base URL (defaults to https://lona.so) |
accessToken | string | no | Personal access token |
Returned by client.open().
| Member | Returns | Description |
|---|---|---|
sheet.id | string | Sheet ID |
sheet.title | string | null | Sheet title |
sheet.numFrozenRows | number | Number of frozen rows |
sheet.rows | RowsAccessor | Fluent row operations |
sheet.row(query) | Row | null | Find row by query |
sheet.row(query, variant) | Row<V> | null | Find row with type-safe variant narrowing |
sheet.tree() | RowNode.Tree | Resolved row tree |
sheet.cells | CellAccessor | Cell data access and subscriptions |
sheet.cells.fetch(range) | Promise<void> | Fetch cells for all rows in NaiveDate.Range |
sheet.cells.getRange(rowId) | CellEntry[] | Read cached cells (populated by fetch) |
sheet.cells.onChange(cb) | () => void | Subscribe to cell changes; returns unsubscribe |
sheet.promote() | Promise<void> | Persist an ephemeral sheet |
sheet.serialize() | UserSheetWithRows | Serialize to wire format |
Used by sheet.row(query) and sheet.rows.get(query):
| Form | Example | Description |
|---|---|---|
string | "r_a1b2..." | Match by row ID |
{ id } | { id: "r_a1b2..." } | Match by row ID |
{ label } | { label: "Weight" } | Match by label |
{ type } | { type: "number" } | Match by type |
{ lookupKey } | { lookupKey: ":~calendar" } | Match by lookup key |
Accessed via sheet.rows.
| Member | Returns | Description |
|---|---|---|
rows.list | Row[] | All rows in sheet |
rows.get(query) | Row | null | Find row by query |
rows.add(attrs) | Promise<Row> | Add a row |
rows.delete(rowId) | Promise<void> | Delete a row (with undo) |
rows.move(rowId, opts) | Promise<void> | Move/reparent a row |
rows.add)| Field | Type | Required | Description |
|---|---|---|---|
type | string | yes | Row type |
label | string | no | Display label |
formula | string | no | Lisp formula |
timeScale | string | no | Time scale |
attributes | object | no | Type-specific attributes |
Accessed via client.rows. Provides standalone row access without sheet
context, including cross-user rows.
| Method | Returns | Description |
|---|---|---|
client.rows.open(key) | Promise<Row | null> | Open a row by key |
client.rows.linkRow(sheetId, lookupKey, position?) | Promise<void> | Link a reserved or persisted lookup-key row to a sheet |
client.rows.listLinkable() | Promise<LinkableRow[]> | List linkable reserved rows and user-owned lookup-key rows |
client.rows.update(rowKey, patch) | Promise<PatchRowResponse> | Update a row's properties |
client.rows.updateDebounced(rowKey, patch) | void | Update with debouncing (fire-and-forget) |
client.rows.checkLookupKeyExists(rowKey, excludeRowId?) | Promise<LookupKeyExistsResponse> | Check if a lookup key is in use |
Row key formats:
| Format | Example | Description |
|---|---|---|
:lookupKey | :~weather | Reserved/provider row (current user) |
[user@email]:lookupKey | [alice@x.com]:~weather | Cross-user row (requires ACL) |
r_<hex> | r_a1b2c3d4... | Row by UUID |
Represents a row in sheet.rows.list or returned by client.rows.open().
| Property | Type | Description |
|---|---|---|
id | string | Row ID |
type | string | Row type identifier |
label | string | null | Display label |
lookupKey | string | null | Lookup key |
formula | string | null | Lisp formula |
timeScale | TimeScaleCustom | Time scale |
attributes | UntypedJson | null | Type-specific attributes |
isReadOnly | boolean | Whether cells can be set |
icon | string | null | Row icon |
heightPx | number | null | Row height in pixels |
| Method | Returns | Description |
|---|---|---|
row.is(type) | boolean | Check if row is of a specific type |
row.update(patch, actor?) | Promise<void> | Update row. Emits typed invalidation events per field |
row.cells(range) | Promise<CellEntry[]> | Fetch cells for date range |
row.cell(date) | CellHandle | Progressive cell handle for NaiveDate.Partial (awaitable) |
row.setCell(date, data) | Promise<void> | Create or overwrite a cell |
row.variant | SheetRow.Variant | Lazy-cached, type-specific derived data. See Row variants |
| Property | Type | Description |
|---|---|---|
date | string | Cell date ("YYYY-MM-DD") |
endDate | string | undefined | End date for range cells |
data | unknown | Cell value |
Returned by row.cell(date). Implements PromiseLike so it can be awaited
directly, and provides progressive callbacks for sync-aware loading.
| Method | Returns | Description |
|---|---|---|
cell.onLoading(cb) | this | Called when no data is cached and fetch is pending |
cell.onData(cb) | this | Called when data arrives (may re-fire on sync updates) |
cell.onDataFull(cb) | this | Called only when sync is fully complete |
cell.dispose() | void | Cancel all subscriptions |
await cell | CellEntry | null | Resolves on first onDataFull |
Callbacks are chainable and re-fire on every data/sync change.
| Property | Type | Description |
|---|---|---|
status | string | "pending", "running", "complete", or "failed" |
keys | Map<string, SyncKeyStatus> | Per-provider sync status |
Injected via ClientConfig.platform. Provides layout queries and infrastructure.
| Callback | Required | Description |
|---|---|---|
installDebounce(baseUrl, accessCode) | yes | Install TypedApi debounce backend |
getMaxHeight() | yes | Viewport height for layout |
getMaxWidth() | no | Sidebar width calculation |
onFrozenRowOverflow(tried, max, maxHeight) | no | Frozen rows exceed viewport |
onFrozenRowFit() | no | Frozen rows fit again |
themeBackend | no | Theme CSS application |
Injected via ClientConfig.feedback. UI feedback for row operations.
| Callback | Returns | Description |
|---|---|---|
confirmDelete(message) | Promise<boolean> | Confirm destructive action |
warn(message, description?) | void | Show a warning |
showUndo(message, undo) | void | Show undo notification with restore callback |
Injected via ClientConfig.invalidation. Change event bus.
| Method | Returns | Description |
|---|---|---|
emit(event) | void | Emit an invalidation event |
subscribe(cb) | () => void | Subscribe to all events; returns unsubscribe |
See Invalidation for event types and patterns.
header, text, number, group, formula, checkmark, graph,
calendar, calendar-list, timeline, calendar-month, weather,
timezone, block, logs, timeline, sticker, task, journal,
data, data-canvas, data-series, data-renderer, ai-report
Fractional positions used for ordering sheets and rows.
| Method | Returns | Description |
|---|---|---|
Rational.midpoint(upper?, lower?) | Rational | Position between two bounds |
Rational.nth(n) | Rational | Initial position for index n |
rational.n | number | Numerator |
rational.d | number | Denominator |
midpoint computes the mediant: (a.n + b.n) / (a.d + b.d). With one
bound, it positions just before/after. With no bounds, returns 1/1.
Stable row reference. Use when you need a durable or serializable identifier.
| Method | Returns | Description |
|---|---|---|
RowKey.parse(raw) | RowKey | Parse any format |
RowKey.user(hex) | RowKey.User | User row |
RowKey.lookup(key) | RowKey.Lookup | Lookup key |
RowKey.reserved(key) | RowKey.Reserved | Builtin or reserved key |
RowKey.virtual(hex, preset) | RowKey.Virtual | Virtual child |
RowKey.system(name, param?) | RowKey.System | System row |
RowKey.pending(uuid?) | RowKey.Pending | Local pending row |
key.resolve() | RowLocalId | Resolve through the global registry |
| Method | Narrows to |
|---|---|
key.isUser() | RowKey.User |
key.isLookup() | RowKey.Lookup |
key.isReserved() | RowKey.Reserved |
key.isVirtual() | RowKey.Virtual |
key.isSystem() | RowKey.System |
key.isPending() | RowKey.Pending |
| Method | Returns | Description |
|---|---|---|
key.toHex() | Option<string> | Hex string (user rows) |
key.toUuid() | Option<string> | UUID string (user rows) |
key.asLookup() | Option<string> | Lookup key string |
key.asVirtual() | Option<VirtualInfo> | { parentHex, preset } |
key.asSystem() | Option<SystemInfo> | { name } |
Interned row identity. Created through RowLocalId.Registry.
| Method | Returns | Description |
|---|---|---|
RowLocalId.Registry.instance | Registry | Global session registry |
registry.resolve(key) | RowLocalId | Resolve or create |
registry.alias(from, to) | void | Register alias |
registry.get(key) | Option<RowLocalId> | Look up without creating |
registry.setCurrentUser(userId) | void | Set the active user scope |
registry.currentUser | Option<string> | Current user scope |
registry.promoteAnonymous(userId) | void | Rebind anonymous keys to a logged-in user |