@book.dev/sdk 3.7.0 → 3.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai.d.ts +12 -2
- package/dist/ai.js.map +1 -1
- package/dist/blockCatalogue.d.ts +560 -0
- package/dist/blockCatalogue.js +336 -0
- package/dist/blockCatalogue.js.map +1 -0
- package/dist/bookFolder.d.ts +9 -1
- package/dist/bookFolder.js +64 -2
- package/dist/bookFolder.js.map +1 -1
- package/dist/client.d.ts +22 -2
- package/dist/client.js +6 -2
- package/dist/client.js.map +1 -1
- package/dist/content.d.ts +40 -1
- package/dist/content.js +29 -7
- package/dist/content.js.map +1 -1
- package/dist/forwarding/forwardingClient.d.ts +68 -2
- package/dist/forwarding/forwardingClient.js +126 -12
- package/dist/forwarding/forwardingClient.js.map +1 -1
- package/dist/forwarding/index.d.ts +2 -1
- package/dist/forwarding/index.js +2 -1
- package/dist/forwarding/index.js.map +1 -1
- package/dist/forwarding/namespacedKeyStore.d.ts +52 -0
- package/dist/forwarding/namespacedKeyStore.js +99 -0
- package/dist/forwarding/namespacedKeyStore.js.map +1 -0
- package/dist/index.d.ts +10 -5
- package/dist/index.js +10 -5
- package/dist/index.js.map +1 -1
- package/dist/ledger.d.ts +29 -0
- package/dist/ledger.js +43 -0
- package/dist/ledger.js.map +1 -1
- package/dist/ledgerExportSection.d.ts +160 -0
- package/dist/ledgerExportSection.js +594 -0
- package/dist/ledgerExportSection.js.map +1 -0
- package/dist/orderKeys.d.ts +36 -0
- package/dist/orderKeys.js +88 -0
- package/dist/orderKeys.js.map +1 -0
- package/dist/plugins.d.ts +76 -4
- package/dist/plugins.js +95 -12
- package/dist/plugins.js.map +1 -1
- package/dist/provenance.d.ts +13 -0
- package/dist/registryClient.d.ts +227 -0
- package/dist/registryClient.js +397 -0
- package/dist/registryClient.js.map +1 -0
- package/dist/routes.d.ts +9 -0
- package/dist/routes.js +9 -0
- package/dist/routes.js.map +1 -1
- package/dist/suggestions.d.ts +12 -2
- package/dist/tableSnapshot.d.ts +233 -0
- package/dist/tableSnapshot.js +680 -0
- package/dist/tableSnapshot.js.map +1 -0
- package/dist/templates.d.ts +8 -0
- package/dist/templates.js +7 -2
- package/dist/templates.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Table STRUCTURE ops over a stored page snapshot (API-3).
|
|
3
|
+
*
|
|
4
|
+
* The editor owns the live-document versions of these ops (`packages/ui/src/
|
|
5
|
+
* blockeditor/model.ts` — `tableInsertRow`, `tableMoveColumn`, …), which mutate a
|
|
6
|
+
* Y.Doc inside one transaction. This module is their SERVER-SIDE twin: the same
|
|
7
|
+
* seven structural ops (plus cell text and row/column tints) applied to the
|
|
8
|
+
* `blockdoc` JSON projection, for the paths that have no live editor — the MCP
|
|
9
|
+
* write tools, and the agent bridge's stored-page fallback.
|
|
10
|
+
*
|
|
11
|
+
* ── THE `col:` / `ord` DECISION ──────────────────────────────────────────────
|
|
12
|
+
* A keyed table carries FRACTIONAL ORDER KEYS: `table.props['col:<colId>']` per
|
|
13
|
+
* column and `row.props.ord` per row (see the model's table contract). Render
|
|
14
|
+
* order is those keys sorted — never array order. A table built by
|
|
15
|
+
* `append_blocks` has NO keys (an MCP client can't invent them), so it is a
|
|
16
|
+
* "legacy" table that renders in array order until something migrates it.
|
|
17
|
+
*
|
|
18
|
+
* These ops MIGRATE EAGERLY: every op runs {@link ensureSnapshotTableOrder}
|
|
19
|
+
* first — a line-for-line mirror of the editor's `ensureTableOrderInTx`, using
|
|
20
|
+
* the SAME shared key algebra (`./orderKeys`, which the editor now imports from
|
|
21
|
+
* here) and the SAME deterministic column ids (`c0…cN-1`) and
|
|
22
|
+
* `keysBetween(null, null, n)` spread. So a table migrated by an MCP op and the
|
|
23
|
+
* same table migrated by the editor end up with IDENTICAL keys.
|
|
24
|
+
*
|
|
25
|
+
* We do NOT take the alternative — "stay positional and let
|
|
26
|
+
* `ensureTableOrderInTx` migrate later" — because three of the ops
|
|
27
|
+
* (`move_row`, `move_column`, and every insert) are DEFINED as order-key edits.
|
|
28
|
+
* A positional-only snapshot op would have to reorder the arrays instead, which
|
|
29
|
+
* (a) gives a different result than the editor for an already-keyed table, and
|
|
30
|
+
* (b) rewrites nodes a concurrent peer is editing, losing the ops' convergence
|
|
31
|
+
* property. Migrating first costs one deterministic pass and makes the editor,
|
|
32
|
+
* agent-proposal and snapshot paths produce the same grid — which is exactly
|
|
33
|
+
* what the cross-path invariant test asserts.
|
|
34
|
+
*
|
|
35
|
+
* Ops here mutate a DEEP COPY of the snapshot's blocks and drop the stale CRDT
|
|
36
|
+
* `update` (like every other snapshot writer), so the next reader rebuilds from
|
|
37
|
+
* the projection.
|
|
38
|
+
*/
|
|
39
|
+
import type { PageSnapshot } from './types';
|
|
40
|
+
/** Prefix of the column-registry entries in a table block's props. */
|
|
41
|
+
export declare const TABLE_COL_PREFIX = "col:";
|
|
42
|
+
/** Prefix of the per-column colour entries (`colbg:<colId>` → palette token). */
|
|
43
|
+
export declare const TABLE_COLBG_PREFIX = "colbg:";
|
|
44
|
+
/**
|
|
45
|
+
* The table order-contract PRIVATE keys (TBL-1): `row.props.ord`,
|
|
46
|
+
* `cell.props.col`, the `col:<id>` column registry, and the `colbg:<id>`
|
|
47
|
+
* column tints. They encode a table's cell order/identity — writing them
|
|
48
|
+
* through a generic props tool corrupts or hides cells, so EVERY
|
|
49
|
+
* update_block_props surface (MCP server AND the in-app agent) refuses them
|
|
50
|
+
* with {@link tableOrderContractRefusal} and points at the sanctioned table
|
|
51
|
+
* structure tools. Returns the offending key, or null when `props` touches
|
|
52
|
+
* none.
|
|
53
|
+
*/
|
|
54
|
+
export declare function tableOrderContractKey(props: Record<string, unknown>): string | null;
|
|
55
|
+
/** The shared refusal message for a {@link tableOrderContractKey} hit — the
|
|
56
|
+
* SAME wording on both write surfaces, naming the table tools that own the
|
|
57
|
+
* keys. */
|
|
58
|
+
export declare const tableOrderContractRefusal: (key: string) => string;
|
|
59
|
+
/** One block of the `blockdoc` JSON projection, as these ops mutate it. */
|
|
60
|
+
export interface SnapshotBlock {
|
|
61
|
+
id?: string;
|
|
62
|
+
type?: string;
|
|
63
|
+
text?: Array<{
|
|
64
|
+
t: string;
|
|
65
|
+
a?: Record<string, unknown>;
|
|
66
|
+
}>;
|
|
67
|
+
props?: Record<string, unknown>;
|
|
68
|
+
children?: SnapshotBlock[];
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* The structural table ops, named exactly as the agent proposal kinds and the
|
|
72
|
+
* MCP tool names — one vocabulary across the editor bridge, the agent, and MCP.
|
|
73
|
+
*/
|
|
74
|
+
export type TableOpKind = 'table_insert_row' | 'table_delete_row' | 'table_duplicate_row' | 'table_insert_column' | 'table_delete_column' | 'table_move_row' | 'table_move_column' | 'table_set_cell' | 'table_set_row_color' | 'table_set_column_color';
|
|
75
|
+
/** Every {@link TableOpKind}, for schema/description generation. */
|
|
76
|
+
export declare const TABLE_OP_KINDS: readonly TableOpKind[];
|
|
77
|
+
/**
|
|
78
|
+
* A table op with its coordinates already RESOLVED to SORTED (render-order)
|
|
79
|
+
* indices — the same coordinate space as the editor's `cellPosition`. Id-based
|
|
80
|
+
* addressing (a cell id, a row id, a column id) is resolved to these indices by
|
|
81
|
+
* {@link resolveTableOp} before validation, so bounds errors read the same
|
|
82
|
+
* whichever way the caller addressed the table.
|
|
83
|
+
*/
|
|
84
|
+
export interface TableOpRequest {
|
|
85
|
+
kind: TableOpKind;
|
|
86
|
+
/** Sorted row index (row-axis ops, and `table_set_cell`). */
|
|
87
|
+
rowIndex?: number;
|
|
88
|
+
/** Sorted column index (column-axis ops, and `table_set_cell`). */
|
|
89
|
+
colIndex?: number;
|
|
90
|
+
/** Move target, a sorted index counted with the moved row/column REMOVED. */
|
|
91
|
+
toIndex?: number;
|
|
92
|
+
/** New plain text (`table_set_cell`). */
|
|
93
|
+
text?: string;
|
|
94
|
+
/** Palette token, or null to clear (`table_set_row_color` / `..._column_color`). */
|
|
95
|
+
color?: string | null;
|
|
96
|
+
}
|
|
97
|
+
/** The dimensions an op is validated against (from the SORTED grid). */
|
|
98
|
+
export interface TableShape {
|
|
99
|
+
rows: number;
|
|
100
|
+
cols: number;
|
|
101
|
+
/** The table's `header` prop — sorted row 0 renders as the header row. */
|
|
102
|
+
header: boolean;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Validate a resolved op against the table's shape — the ONE definition of the
|
|
106
|
+
* table ops' server-side invariants, shared by the agent bridge and the MCP
|
|
107
|
+
* tools so both refuse exactly the same requests with exactly the same words.
|
|
108
|
+
* Returns an actionable message, or null when the op is legal.
|
|
109
|
+
*
|
|
110
|
+
* Mirrors the editor's context-menu guards (`BlockEditor.tsx`,
|
|
111
|
+
* `TableCellMenuContent`):
|
|
112
|
+
* · insert-row-above is HIDDEN on the header row, because rendering is
|
|
113
|
+
* positional — the blank new row would become the header and silently demote
|
|
114
|
+
* the real one. Here that is a refusal, not a silent clamp.
|
|
115
|
+
* · move up/down and move left/right are DISABLED at the extremes, which is the
|
|
116
|
+
* same thing as a target index outside `0…n-1`.
|
|
117
|
+
* · row 0 is otherwise an ordinary row: it can be deleted, duplicated, tinted,
|
|
118
|
+
* and another row may be MOVED into position 0 (that promotes it to header —
|
|
119
|
+
* the documented behaviour of contract note 5).
|
|
120
|
+
* Unlike the editor's ops (which CLAMP indices and no-op on a miss), these
|
|
121
|
+
* refuse: a remote caller that mis-addresses a table should hear about it rather
|
|
122
|
+
* than have the edit land somewhere else.
|
|
123
|
+
*/
|
|
124
|
+
export declare function tableOpError(shape: TableShape, op: TableOpRequest): string | null;
|
|
125
|
+
/** True for the two ops whose "last one" case removes the whole table block. */
|
|
126
|
+
export declare function tableOpRemovesTable(shape: TableShape, op: TableOpRequest): boolean;
|
|
127
|
+
/** The table's column registry, sorted into render order (key, then id). */
|
|
128
|
+
export declare function snapshotTableColumns(table: SnapshotBlock): Array<{
|
|
129
|
+
id: string;
|
|
130
|
+
key: string;
|
|
131
|
+
}>;
|
|
132
|
+
/** The sorted grid view of a snapshot table — mirrors the model's `TableGrid`. */
|
|
133
|
+
export interface SnapshotTableGrid {
|
|
134
|
+
keyed: boolean;
|
|
135
|
+
rows: SnapshotBlock[];
|
|
136
|
+
colIds: string[];
|
|
137
|
+
/** `cells[r][c]`, null for a merge gap (exactly like the model's grid). */
|
|
138
|
+
cells: (SnapshotBlock | null)[][];
|
|
139
|
+
width: number;
|
|
140
|
+
}
|
|
141
|
+
export declare function snapshotTableGrid(table: SnapshotBlock): SnapshotTableGrid;
|
|
142
|
+
/**
|
|
143
|
+
* Lazy migration + backfill of a snapshot table's order keys — the mirror of the
|
|
144
|
+
* editor's `ensureTableOrderInTx`, deterministic in exactly the same way so a
|
|
145
|
+
* migration performed here and one performed in the editor converge. Idempotent.
|
|
146
|
+
*/
|
|
147
|
+
export declare function ensureSnapshotTableOrder(table: SnapshotBlock): void;
|
|
148
|
+
/** A read-only projection of a table for inspection + op resolution. */
|
|
149
|
+
export interface SnapshotTableView {
|
|
150
|
+
tableId: string;
|
|
151
|
+
header: boolean;
|
|
152
|
+
rows: number;
|
|
153
|
+
cols: number;
|
|
154
|
+
/** Row block ids in SORTED order. */
|
|
155
|
+
rowIds: string[];
|
|
156
|
+
/** Column ids in SORTED order (empty for a not-yet-migrated legacy table). */
|
|
157
|
+
colIds: string[];
|
|
158
|
+
/** Cell block ids in SORTED order; null for a merge gap. */
|
|
159
|
+
cellIds: (string | null)[][];
|
|
160
|
+
/** Cell plain text in SORTED order; '' for a merge gap. */
|
|
161
|
+
cells: string[][];
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Read a table by id from a page snapshot, in SORTED render order. Read-only —
|
|
165
|
+
* it never migrates (like the model's `cellPosition`), so `colIds` is empty for
|
|
166
|
+
* a legacy table even though `cols` already reports its rendered width. Returns
|
|
167
|
+
* null when `tableId` isn't a `table` block on the page.
|
|
168
|
+
*/
|
|
169
|
+
export declare function snapshotTableView(data: PageSnapshot | null | undefined, tableId: string): SnapshotTableView | null;
|
|
170
|
+
/** Grid coordinates of a cell id — the snapshot mirror of `cellPosition`. */
|
|
171
|
+
export declare function snapshotCellPosition(data: PageSnapshot | null | undefined, cellId: string): {
|
|
172
|
+
tableId: string;
|
|
173
|
+
row: number;
|
|
174
|
+
col: number;
|
|
175
|
+
rows: number;
|
|
176
|
+
cols: number;
|
|
177
|
+
} | null;
|
|
178
|
+
/** The id of the table that contains `blockId` (a table, row, or cell id). */
|
|
179
|
+
export declare function snapshotTableIdFor(data: PageSnapshot | null | undefined, blockId: string): string | null;
|
|
180
|
+
/** How a caller addressed a table op: sorted indices and/or block ids. */
|
|
181
|
+
export interface TableOpAddress {
|
|
182
|
+
rowIndex?: number;
|
|
183
|
+
colIndex?: number;
|
|
184
|
+
toIndex?: number;
|
|
185
|
+
/** A cell id — resolves BOTH `rowIndex` and `colIndex`. */
|
|
186
|
+
cellId?: string;
|
|
187
|
+
/** A row block id — resolves `rowIndex`. */
|
|
188
|
+
rowId?: string;
|
|
189
|
+
/** A column id (from `col:<id>` / a cell's `col` prop) — resolves `colIndex`. */
|
|
190
|
+
colId?: string;
|
|
191
|
+
text?: string;
|
|
192
|
+
color?: string | null;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Resolve id-based addressing to SORTED indices against a table view. An id that
|
|
196
|
+
* isn't in this table is an error, never a silent fallback.
|
|
197
|
+
*
|
|
198
|
+
* Precedence: for ops that TARGET AN EXISTING NODE, an id wins over the matching
|
|
199
|
+
* index — the id is that node's identity, so a caller who sent both meant the
|
|
200
|
+
* node. For the two INSERT ops the index is a POSITION, not a node, so an id
|
|
201
|
+
* there only serves to name the table and never overrides the position (a
|
|
202
|
+
* `cellId` on `table_insert_row` means "the table this cell is in", not "insert
|
|
203
|
+
* at this cell's row").
|
|
204
|
+
*/
|
|
205
|
+
export declare function resolveTableOp(view: SnapshotTableView, kind: TableOpKind, address: TableOpAddress): {
|
|
206
|
+
op: TableOpRequest;
|
|
207
|
+
} | {
|
|
208
|
+
error: string;
|
|
209
|
+
};
|
|
210
|
+
/** The shape an op is validated against, from a read view. */
|
|
211
|
+
export declare const tableShapeOf: (view: SnapshotTableView) => TableShape;
|
|
212
|
+
/**
|
|
213
|
+
* Apply ONE resolved table op to a page snapshot, returning the new snapshot.
|
|
214
|
+
* Coordinates are SORTED indices ({@link resolveTableOp} turns ids into them);
|
|
215
|
+
* validate with {@link tableOpError} first — this function assumes a legal op
|
|
216
|
+
* and clamps like the editor rather than reporting.
|
|
217
|
+
*
|
|
218
|
+
* Returns null when `tableId` isn't a table on the page. `removedTable` is true
|
|
219
|
+
* when the op deleted the LAST row or column, which removes the whole table
|
|
220
|
+
* block — the editor's behaviour (`tableDeleteRow` / `tableDeleteColumn`), kept
|
|
221
|
+
* identical here so the three paths can't diverge.
|
|
222
|
+
*/
|
|
223
|
+
export declare function applyTableOpToSnapshot(data: PageSnapshot, tableId: string, op: TableOpRequest): {
|
|
224
|
+
data: PageSnapshot;
|
|
225
|
+
removedTable: boolean;
|
|
226
|
+
} | null;
|
|
227
|
+
/** Every `table` block on a page, in document order (for `list_tables`). */
|
|
228
|
+
export declare function snapshotTables(data: PageSnapshot | null | undefined): Array<{
|
|
229
|
+
id: string;
|
|
230
|
+
rows: number;
|
|
231
|
+
cols: number;
|
|
232
|
+
header: boolean;
|
|
233
|
+
}>;
|