@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.
Files changed (53) hide show
  1. package/dist/ai.d.ts +12 -2
  2. package/dist/ai.js.map +1 -1
  3. package/dist/blockCatalogue.d.ts +560 -0
  4. package/dist/blockCatalogue.js +336 -0
  5. package/dist/blockCatalogue.js.map +1 -0
  6. package/dist/bookFolder.d.ts +9 -1
  7. package/dist/bookFolder.js +64 -2
  8. package/dist/bookFolder.js.map +1 -1
  9. package/dist/client.d.ts +22 -2
  10. package/dist/client.js +6 -2
  11. package/dist/client.js.map +1 -1
  12. package/dist/content.d.ts +40 -1
  13. package/dist/content.js +29 -7
  14. package/dist/content.js.map +1 -1
  15. package/dist/forwarding/forwardingClient.d.ts +68 -2
  16. package/dist/forwarding/forwardingClient.js +126 -12
  17. package/dist/forwarding/forwardingClient.js.map +1 -1
  18. package/dist/forwarding/index.d.ts +2 -1
  19. package/dist/forwarding/index.js +2 -1
  20. package/dist/forwarding/index.js.map +1 -1
  21. package/dist/forwarding/namespacedKeyStore.d.ts +52 -0
  22. package/dist/forwarding/namespacedKeyStore.js +99 -0
  23. package/dist/forwarding/namespacedKeyStore.js.map +1 -0
  24. package/dist/index.d.ts +10 -5
  25. package/dist/index.js +10 -5
  26. package/dist/index.js.map +1 -1
  27. package/dist/ledger.d.ts +29 -0
  28. package/dist/ledger.js +43 -0
  29. package/dist/ledger.js.map +1 -1
  30. package/dist/ledgerExportSection.d.ts +160 -0
  31. package/dist/ledgerExportSection.js +594 -0
  32. package/dist/ledgerExportSection.js.map +1 -0
  33. package/dist/orderKeys.d.ts +36 -0
  34. package/dist/orderKeys.js +88 -0
  35. package/dist/orderKeys.js.map +1 -0
  36. package/dist/plugins.d.ts +76 -4
  37. package/dist/plugins.js +95 -12
  38. package/dist/plugins.js.map +1 -1
  39. package/dist/provenance.d.ts +13 -0
  40. package/dist/registryClient.d.ts +227 -0
  41. package/dist/registryClient.js +397 -0
  42. package/dist/registryClient.js.map +1 -0
  43. package/dist/routes.d.ts +9 -0
  44. package/dist/routes.js +9 -0
  45. package/dist/routes.js.map +1 -1
  46. package/dist/suggestions.d.ts +12 -2
  47. package/dist/tableSnapshot.d.ts +233 -0
  48. package/dist/tableSnapshot.js +680 -0
  49. package/dist/tableSnapshot.js.map +1 -0
  50. package/dist/templates.d.ts +8 -0
  51. package/dist/templates.js +7 -2
  52. package/dist/templates.js.map +1 -1
  53. 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
+ }>;