请先阅读 backend port 指南,再查看权威的TypeScript 源码,了解可选能力。
SpreadsheetBackend
export interface SpreadsheetBackend {
listSheets?(): Promise<SheetListResult>
readVisibleProjection(request: VisibleProjectionRequest): Promise<VisibleProjectionResult>
readRangeProjection(request: RangeProjectionRequest): Promise<RangeProjectionResult>
exportRangeTsv?(request: RangeTsvExportRequest): Promise<RangeTsvExportResult>
/**
* Wave 8.4 — range screenshot. Optional capability; UI core hides the
* Copy-as-PNG surfaces and `encodeSelectionAsImage` returns `null`
* when this method is omitted.
*/
exportRangeAsImage?(request: RangeImageExportRequest): Promise<RangeImageExportResult>
consumeExportRangeTsvChunks?(
request: RangeTsvExportRequest,
onChunk: RangeTsvChunkConsumer,
): Promise<RangeTsvChunkExportResult>
readViewportSizeProjection?(
request: ViewportSizeProjectionRequest,
): Promise<ViewportSizeProjectionResult>
/**
* Commit one cell's raw input. Resolving a `BackendMutationResult` means
* the value really landed — a host that cannot apply the write MUST
* reject, never resolve a success-shaped ACK, or the user's keystrokes
* disappear while UI core records history and bumps the revision.
* `runEditingCommitAtom` turns the rejection into a `rejected` editing
* lifecycle carrying the Error's `message`, so the reason belongs there
* (any structured `code` / `detail` is host-private).
*/
setCellInput(request: SetCellInputRequest): Promise<BackendMutationResult>
setCellRichValue?(request: SetCellRichValueRequest): Promise<BackendMutationResult>
importCells?(request: ImportCellsRequest): Promise<BackendMutationResult>
importCellChunks?(request: ImportCellChunksRequest): Promise<BackendMutationResult>
clearRange?(request: ClearRangeRequest): Promise<BackendMutationResult>
insertRows?(request: InsertRowsRequest): Promise<BackendMutationResult>
deleteRows?(request: DeleteRowsRequest): Promise<BackendMutationResult>
insertColumns?(request: InsertColumnsRequest): Promise<BackendMutationResult>
deleteColumns?(request: DeleteColumnsRequest): Promise<BackendMutationResult>
setFormatRange?(request: SetFormatRangeRequest): Promise<BackendMutationResult>
setRowHeight?(request: SetRowHeightRequest): Promise<BackendMutationResult>
setColumnWidth?(request: SetColumnWidthRequest): Promise<BackendMutationResult>
fillRange?(request: FillRangeRequest): Promise<AutoFillMutationResult>
resolveDataEdge?(request: ResolveDataEdgeRequest): Promise<ResolveDataEdgeResult>
addSheet?(request: AddSheetRequest): Promise<SheetMutationResult>
renameSheet?(request: RenameSheetRequest): Promise<SheetMutationResult>
deleteSheet?(request: DeleteSheetRequest): Promise<SheetMutationResult>
reorderSheet?(request: ReorderSheetRequest): Promise<SheetMutationResult>
undoTransaction?(request: UndoTransactionRequest): Promise<HistoryTransactionResult>
redoTransaction?(request: RedoTransactionRequest): Promise<HistoryTransactionResult>
listNamedRanges?(request: ListNamedRangesRequest): Promise<NamedRangeListResult>
setNamedRange?(request: SetNamedRangeRequest): Promise<NamedRangeMutationResult>
deleteNamedRange?(request: DeleteNamedRangeRequest): Promise<NamedRangeMutationResult>
mergeRange?(request: MergeRangeRequest): Promise<BackendMutationResult>
unmergeRange?(request: UnmergeRangeRequest): Promise<BackendMutationResult>
readFreezeConfig?(request: ReadFreezeConfigRequest): Promise<ReadFreezeConfigResult>
setFreezeConfig?(request: SetFreezeConfigRequest): Promise<BackendMutationResult>
hideRows?(request: HideRowsRequest): Promise<BackendMutationResult>
unhideRows?(request: UnhideRowsRequest): Promise<BackendMutationResult>
// Read-back of the engine-owned hidden state (rows + filter), for hydrating
// UI-core render caches on sheet activation / restore. Optional: a backend
// whose engine does not OWN this state (the TS worker) omits the port and
// UI-core keeps its own canonical view fact instead of hydrating from a
// source that cannot answer authoritatively.
readSheetHiddenState?(request: SheetHiddenStateRequest): Promise<SheetHiddenStateResult>
hideColumns?(request: HideColumnsRequest): Promise<BackendMutationResult>
unhideColumns?(request: UnhideColumnsRequest): Promise<BackendMutationResult>
// engine hidden-row eval input (parity #23). Optional, fire-and-forget
// whole-set REPLACE (no exact ACK / undo): mirrors the UI-core canonical
// hidden-row VIEW fact into the engine so SUBTOTAL 101-111 can exclude
// manually hidden data rows. A backend whose engine models no such input
// omits the port; UI core silently skips the push and SUBTOTAL 101-111
// degrades to "does not exclude" without disturbing any other feature.
setEvalHiddenRows?(request: SetEvalHiddenRowsRequest): Promise<void> | void
fillSeries?(request: FillSeriesRequest): Promise<AutoFillMutationResult>
// comments & notes
setNote?(request: SetNoteRequest): Promise<BackendMutationResult>
clearNote?(request: ClearNoteRequest): Promise<BackendMutationResult>
postComment?(request: PostCommentRequest): Promise<BackendMutationResult>
resolveCommentThread?(request: ResolveCommentThreadRequest): Promise<BackendMutationResult>
deleteComment?(request: DeleteCommentRequest): Promise<BackendMutationResult>
// data validation
setValidationRule?(request: SetValidationRuleRequest): Promise<BackendMutationResult>
clearValidationRule?(request: ClearValidationRuleRequest): Promise<BackendMutationResult>
// conditional formatting
setConditionalFormatRule?(
request: SetConditionalFormatRuleRequest,
): Promise<BackendMutationResult>
removeConditionalFormatRule?(
request: RemoveConditionalFormatRuleRequest,
): Promise<BackendMutationResult>
listConditionalFormatRules?(
request: ListConditionalFormatRulesRequest,
): Promise<ConditionalFormatRulesResult>
// print config
readPrintConfig?(request: ReadPrintConfigRequest): Promise<ReadPrintConfigResult>
setPrintConfig?(request: SetPrintConfigRequest): Promise<SetPrintConfigResult>
// find-replace
/**
* Match offsets are UTF-16 code-unit indexes into the selected target and use half-open
* `[matchStart, matchEnd)` intervals. Every emitted span satisfies
* `0 <= matchStart < matchEnd`; zero-width regex results are omitted.
*/
searchRange?(request: SearchRangeRequest): Promise<SearchRangeResult>
/**
* Replacement spans use the same UTF-16 code-unit, half-open, non-empty contract as search
* results. Zero-width and reversed spans are rejected before any mutation.
*/
replaceMatches?(request: ReplaceMatchesRequest): Promise<ReplaceMatchesResponse>
// presence
subscribePresence?(handler: (update: PresenceUpdate) => void): SubscribePresenceUnsubscribe
publishLocalPresence?(request: PublishLocalPresenceRequest): Promise<void>
// filter-sort
// Resolves the ordinary mutation ACK PLUS the filter-hidden row set the
// rule scan produced (`SetFilterSortResult.hiddenRowIndices`). Widening the
// result is backward compatible: a host that returns a bare
// `BackendMutationResult` still satisfies this signature, and UI core reads
// the missing field as "cannot compute visibility" and hides nothing.
setFilterSort?(request: SetFilterSortRequest): Promise<SetFilterSortResult>
// engine physical sort — design-engine-sort. Optional capability: host
// adapters whose runtime cannot physically reorder workbook data omit
// this port (the TS worker declares `sortRange: false`), which hides
// the physical-sort entry through the standard degradation contract.
// Unlike `setFilterSort` (a UI-core VIEW fact / display permutation),
// this reorders engine DATA; undo is host-orchestrated (one bounded
// range-snapshot transaction). Resolves an applied report OR a
// structured not-applied result — a gated request does NOT reject the
// promise.
sortRange?(request: SortRangeRequest): Promise<SortRangeResult>
// protection — UI-core canonical (#40). These ports are an optional
// persistence hook: `setSheetProtection` / `setRangeLock` receive a
// fire-and-forget mirror of local commits and `readSheetProtection`
// seeds a one-shot hydration. Backends that omit them keep the full
// protection feature; enforcement runs in the UI-core mutation gateway.
setSheetProtection?(request: SetSheetProtectionRequest): Promise<BackendMutationResult>
setRangeLock?(request: SetRangeLockRequest): Promise<BackendMutationResult>
readSheetProtection?(request: ReadSheetProtectionRequest): Promise<ReadSheetProtectionResult>
// paste-special — Wave 7.3. Optional capability: host adapters that
// omit this method cause the menu entry + dialog to hide via
// `pasteSpecialSupportedAtom` so the surface degrades cleanly.
pasteRange?(request: PasteRangeRequest): Promise<PasteRangeResult>
// Optional fail-closed subdivision of the pasteRange capability (see
// `PasteSpecialControllerPort.pasteRangeSupportedKinds`): a backend
// that cannot apply the format leg declares only the value-leg kinds
// and Core blocks the rest pre-dispatch. Absent → full trust.
readonly pasteRangeSupportedKinds?: readonly PasteSpecialKind[]
// remove-duplicates — Wave 7.5. Optional capability; host adapters that
// omit this method cause the Data > Remove Duplicates menu entry to hide
// via `removeDuplicatesSupportedAtom` so the surface degrades cleanly.
removeRows?(request: RemoveRowsRequest): Promise<RemoveRowsResult>
// custom-formulas — Wave 8. Optional capability; host adapters that
// omit these methods make the `customFormulaRegistryAtom` inert
// (writes succeed but no worker side-effect runs). `source` is the
// body of a function whose argument is bound to `args` (Array) — the
// adapter is expected to `new Function('args', source)` it inside
// whichever runtime owns the formula engine. Errors thrown during
// evaluation surface as `#ERROR!` cells. Wave 8.2: pass
// `options.isAsync` to compile through the AsyncFunction constructor —
// the cell holds `#BUSY!` until the returned Promise settles, and the
// result is memoized per (name, args) until the next registry change.
registerCustomFormula?(
name: string,
source: string,
options?: { isAsync?: boolean },
): Promise<void>
unregisterCustomFormula?(name: string): Promise<void>
// tables — Excel Table CRUD (parity #32, design-excel-table.md §10).
// Optional capability family: host adapters whose engine has no Table
// model omit these ports (the TS worker declares `structuredTables:
// false`, the static backend implements none), which hides every Table
// entry through the standard method-presence degradation contract. The
// engine registry is canonical (CANONICAL_OWNERSHIP §3 #32) — these are
// the only path UI core reads a table's geometry; it stores no second
// copy. `createTable` resolves the engine-assigned canonical name OR a
// structured `TableMutationRejectedResult` (name conflict / range
// overlap / cap 256 / …) rather than rejecting the promise; rename and
// delete follow the same applied-or-structured-reject convention.
// Table-definition undo is NOT wired in this slice (design §11/§12
// known gap — persistence and the snapshot primitive do not carry the
// table registry).
createTable?(request: CreateTableRequest): Promise<CreateTableResult>
renameTable?(request: RenameTableRequest): Promise<TableMutationResult>
renameTableColumn?(request: RenameTableColumnRequest): Promise<TableMutationResult>
deleteTable?(request: DeleteTableRequest): Promise<TableMutationResult>
listTables?(request: ListTablesRequest): Promise<ListTablesResult>
getTable?(request: GetTableRequest): Promise<GetTableResult>
// Totals row (parity #32 T6, design-excel-table.md §7). Optional
// subdivision of the Table capability family — the same
// `structuredTables` witness gates them, so a backend whose engine has no
// Table model omits them alongside the CRUD ports and UI core hides the
// totals toggle through the standard method-presence contract. Both
// resolve the shared applied-or-structured-reject convention: a gated
// request (row-below occupied → `totals-row-blocked`, function before the
// row is enabled → `no-totals-row`, unknown aggregate id →
// `invalid-totals-function`) resolves a `TableMutationRejectedResult`
// rather than rejecting the promise. Not undoable in this slice (design
// §11/§12 known gap; the SUBTOTAL cell writes are covered by the existing
// cell snapshots, the registry geometry change is not).
setTableTotalsRow?(request: SetTableTotalsRowRequest): Promise<TableMutationResult>
setTableTotalFunction?(request: SetTableTotalFunctionRequest): Promise<TableMutationResult>
// spill (dynamic arrays) — ADR 0006 阶段 3。可选能力:引擎里没有动态数组
// 模型的宿主(静态后端)省掉这个端口,`spillRegionSupportedAtom` 转 false,
// 溢出边框与投影格标记整体不出现 —— 端口缺席是「功能不存在」,不是错误。
//
// 按需查询而不是给 `DisplayCell` 加字段:溢出边框只在选区落进数组时出现,
// 所以一次选区移动查一次就够。取舍与代价见 `src/spill/README.md`。
// `region: null` 是明确的「这一格不在任何活动溢出区里」,与端口缺席不同。
readSpillRegion?(request: SpillRegionRequest): Promise<SpillRegionResult>
// content-change push — Wave 8.2. Optional capability: backends whose
// engine can change cell content OUTSIDE a UI-initiated mutation
// (async custom-formula settles, collaborative edits) invoke the
// handler after such a change so the host refetches the visible
// projection. Coarse signal, no payload — hosts must tolerate
// spurious invocations. Backends whose content only ever changes in
// response to their own mutation methods may omit it.
subscribeContentChanges?(handler: () => void): () => void
}Atom 功能指南
生成的 API Markdown
浏览 TypeDoc API 参考。它在站点构建时从spreadsheet-ui-core 与 solid-excel 的公开入口生成。