@book.dev/sdk 3.10.0 → 3.14.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/types.d.ts CHANGED
@@ -47,12 +47,199 @@ export interface PageSnapshot {
47
47
  */
48
48
  authors?: Array<[string, string]>;
49
49
  }
50
+ /**
51
+ * Monotonic optimistic-concurrency token for one durable entity. Implementing
52
+ * servers return positive safe integers; see `docs/write-contract.md`.
53
+ */
54
+ export type EntityRev = number;
55
+ /** A representation that is guaranteed to carry its concurrency token. */
56
+ export type WithRev<Shape> = Shape & {
57
+ rev: EntityRev;
58
+ };
59
+ /** Additive CAS input shared by revision-aware write payloads. Omission is LWW. */
60
+ export interface ExpectedRevInput {
61
+ expectedRev?: EntityRev;
62
+ }
63
+ /** Opaque lexicographically ordered fractional key used by the CWD-12 target contract. */
64
+ export type StablePosition = string;
65
+ /** Stable page-id → position mapping; unlike `orderedIds`, identity survives insertion. */
66
+ export type PagePositionRecord = Readonly<Record<string, StablePosition>>;
67
+ /** Additive move input spanning wave 1 and the post-CWD-12 position contract. */
68
+ export interface PageMoveInput extends ExpectedRevInput {
69
+ parentId: string | null;
70
+ /** Post-CWD-12 input; exactly the route page id is normally the sole key. */
71
+ positions?: PagePositionRecord;
72
+ /** @deprecated Wave-1 LWW sibling order; use {@link positions} after CWD-12. */
73
+ orderedIds?: string[];
74
+ }
75
+ /** Target input for position-record row ordering after the CWD-12 migration. */
76
+ export interface PageOrderInput {
77
+ positions: PagePositionRecord;
78
+ }
79
+ /** UUID v4/v7 value carried in the `Idempotency-Key` request header. */
80
+ export type IdempotencyKey = string;
81
+ /** Request metadata accepted by the SDK write chokepoint (not part of JSON bodies). */
82
+ export interface WriteRequestOptions {
83
+ idempotencyKey?: IdempotencyKey;
84
+ signal?: AbortSignal;
85
+ timeoutMs?: number;
86
+ }
87
+ /** The durable entity whose guarded write conflicted. */
88
+ export type WriteEntityRef = {
89
+ kind: 'page';
90
+ id: string;
91
+ } | {
92
+ kind: 'database-row';
93
+ id: string;
94
+ databaseId: string;
95
+ } | {
96
+ kind: 'database';
97
+ id: string;
98
+ } | {
99
+ kind: 'instance-config';
100
+ id: 'instance';
101
+ };
102
+ /** Stable server codes introduced for the durable-write contract. */
103
+ export type WriteServerErrorCode = 'rev-conflict' | 'idempotency-key-reused' | 'invalid-input' | 'unauthorized' | 'forbidden' | 'not-found' | 'rate-limited' | 'server-error';
104
+ /** Minimum non-2xx JSON body returned by durable write routes. */
105
+ export interface WriteErrorEnvelope<Code extends string = WriteServerErrorCode> {
106
+ readonly error: string;
107
+ readonly code: Code;
108
+ readonly retryable: boolean;
109
+ }
110
+ /** Optional field-level detail on an {@link WriteValidationEnvelope}. */
111
+ export interface WriteValidationIssue {
112
+ readonly path?: string;
113
+ readonly code?: string;
114
+ readonly message: string;
115
+ }
116
+ /** Structured invalid-input response; `issues` is omitted for request-wide errors. */
117
+ export interface WriteValidationEnvelope extends WriteErrorEnvelope<'invalid-input'> {
118
+ readonly retryable: false;
119
+ readonly issues?: WriteValidationIssue[];
120
+ }
121
+ /** A key was previously committed for a different request fingerprint. */
122
+ export interface WriteIdempotencyKeyReuseEnvelope extends WriteErrorEnvelope<'idempotency-key-reused'> {
123
+ readonly retryable: false;
124
+ }
125
+ /** Links offered by wave-1 conflict resolution. */
126
+ export interface WriteConflictLinks {
127
+ /** Permission-appropriate GET endpoint used when `current` is omitted. */
128
+ readonly self: string;
129
+ /** Page/row history endpoint; `null` for entities without version history. */
130
+ readonly versionHistory: string | null;
131
+ }
132
+ /**
133
+ * Fields shared by every HTTP 409 CAS response. `current` is specialized by the
134
+ * responding route's projection in the discriminated members below.
135
+ */
136
+ interface WriteConflictBase extends WriteErrorEnvelope<'rev-conflict'> {
137
+ readonly retryable: false;
138
+ readonly expectedRev: EntityRev;
139
+ readonly currentRev: EntityRev;
140
+ readonly links: WriteConflictLinks;
141
+ }
142
+ /** CAS response from a page route, secondarily discriminated by route projection. */
143
+ export type PageConflict = (WriteConflictBase & {
144
+ readonly entity: Extract<WriteEntityRef, {
145
+ kind: 'page';
146
+ }>;
147
+ readonly projection: 'page';
148
+ readonly current: WithRev<StoredPage> | null;
149
+ }) | (WriteConflictBase & {
150
+ readonly entity: Extract<WriteEntityRef, {
151
+ kind: 'page';
152
+ }>;
153
+ readonly projection: 'visibility';
154
+ readonly current: WithRev<PageVisibilitySettings> | null;
155
+ }) | (WriteConflictBase & {
156
+ readonly entity: Extract<WriteEntityRef, {
157
+ kind: 'page';
158
+ }>;
159
+ readonly projection: 'agent-edits';
160
+ readonly current: WithRev<AgentEditsPolicySettings> | null;
161
+ });
162
+ /** CAS response from a database-row property route. */
163
+ export interface DatabaseRowConflict extends WriteConflictBase {
164
+ readonly entity: Extract<WriteEntityRef, {
165
+ kind: 'database-row';
166
+ }>;
167
+ readonly current: WithRev<import('./database').DatabaseRow> | null;
168
+ }
169
+ /** CAS response from a database route. */
170
+ export interface DatabaseConflict extends WriteConflictBase {
171
+ readonly entity: Extract<WriteEntityRef, {
172
+ kind: 'database';
173
+ }>;
174
+ readonly current: WithRev<import('./database').StoredDatabase> | null;
175
+ }
176
+ /** CAS response from the instance-policy route. */
177
+ export interface InstanceConfigConflict extends WriteConflictBase {
178
+ readonly entity: Extract<WriteEntityRef, {
179
+ kind: 'instance-config';
180
+ }>;
181
+ readonly current: WithRev<import('./provenance').InstanceConfig> | null;
182
+ }
183
+ /** HTTP 409 body for an opt-in CAS miss, discriminated by `entity.kind`. */
184
+ export type WriteConflictEnvelope = PageConflict | DatabaseRowConflict | DatabaseConflict | InstanceConfigConflict;
185
+ /** Stable discriminators used by the SDK's future runtime `WriteError` classes. */
186
+ export type WriteErrorKind = 'timeout' | 'abort' | 'conflict' | 'idempotency-reuse' | 'validation' | 'authorization' | 'rate-limit' | 'transport' | 'server' | 'http';
187
+ /** Shared structural contract implemented by every SDK `WriteError` class. */
188
+ export interface WriteErrorInfo<Kind extends WriteErrorKind = WriteErrorKind, Status extends number | null = number | null, Details = unknown> {
189
+ readonly kind: Kind;
190
+ readonly status: Status;
191
+ readonly retryable: boolean;
192
+ readonly code: string;
193
+ readonly message: string;
194
+ readonly details?: Details;
195
+ }
196
+ export interface WriteTimeoutErrorInfo extends WriteErrorInfo<'timeout', null | 408 | 504> {
197
+ readonly retryable: true;
198
+ }
199
+ export interface WriteAbortErrorInfo extends WriteErrorInfo<'abort', null> {
200
+ readonly retryable: false;
201
+ }
202
+ export interface WriteConflictErrorInfo extends WriteErrorInfo<'conflict', 409, WriteConflictEnvelope> {
203
+ readonly retryable: false;
204
+ readonly code: 'rev-conflict';
205
+ }
206
+ export interface WriteIdempotencyReuseErrorInfo extends WriteErrorInfo<'idempotency-reuse', 409, WriteIdempotencyKeyReuseEnvelope> {
207
+ readonly retryable: false;
208
+ readonly code: 'idempotency-key-reused';
209
+ }
210
+ export interface WriteValidationErrorInfo extends WriteErrorInfo<'validation', 400 | 413 | 422, WriteValidationEnvelope> {
211
+ readonly retryable: false;
212
+ }
213
+ export interface WriteAuthorizationErrorInfo extends WriteErrorInfo<'authorization', 401 | 403> {
214
+ readonly retryable: false;
215
+ }
216
+ export interface WriteRateLimitErrorInfo extends WriteErrorInfo<'rate-limit', 429> {
217
+ readonly retryable: true;
218
+ /** Milliseconds parsed from an HTTP `Retry-After` seconds value, when present. */
219
+ readonly retryAfterMs?: number;
220
+ }
221
+ export interface WriteTransportErrorInfo extends WriteErrorInfo<'transport', null> {
222
+ readonly retryable: true;
223
+ }
224
+ export interface WriteServerErrorInfo extends WriteErrorInfo<'server', 500 | 502 | 503> {
225
+ readonly retryable: true;
226
+ }
227
+ export interface WriteHttpErrorInfo extends WriteErrorInfo<'http', number> {
228
+ readonly retryable: false;
229
+ }
230
+ /** Exhaustive structural taxonomy implemented by the SDK error classes. */
231
+ export type WriteErrorContract = WriteTimeoutErrorInfo | WriteAbortErrorInfo | WriteConflictErrorInfo | WriteIdempotencyReuseErrorInfo | WriteValidationErrorInfo | WriteAuthorizationErrorInfo | WriteRateLimitErrorInfo | WriteTransportErrorInfo | WriteServerErrorInfo | WriteHttpErrorInfo;
50
232
  /** An empty snapshot, for initializing a brand-new page. */
51
233
  export declare const emptyPageSnapshot: () => PageSnapshot;
52
234
  /** Lightweight page record for listings (no `data` payload). */
53
235
  export interface PageMeta {
54
236
  id: string;
237
+ /** Optimistic-concurrency token; absent only when reading from a legacy server. */
238
+ rev?: EntityRev;
55
239
  name: string | null;
240
+ /** Whether the page participates in discovery surfaces. Independent of who
241
+ * may read it; omitted by older servers. */
242
+ listed?: boolean;
56
243
  /** The page's emoji icon, or `null` when none is set — projected from
57
244
  * `page.properties` so lists (sidebar, tabs, mentions) resolve it directly,
58
245
  * without a per-page fetch. */
@@ -106,6 +293,8 @@ export interface PageGraph {
106
293
  /** A full page as returned by the store. `data` is the document snapshot. */
107
294
  export interface StoredPage {
108
295
  id: string;
296
+ /** Optimistic-concurrency token; absent only when reading from a legacy server. */
297
+ rev?: EntityRev;
109
298
  name: string | null;
110
299
  data: PageSnapshot;
111
300
  /** The database this page *hosts*, if any (mirrors {@link PageMeta.hostedDatabaseId}). */
@@ -160,10 +349,12 @@ export interface StoredPageVersion extends PageVersionMeta {
160
349
  * not set through this payload — they are managed by the database row APIs so a
161
350
  * routine content save never clobbers them.
162
351
  */
163
- export interface PageInput {
352
+ export interface PageInput extends ExpectedRevInput {
164
353
  id?: string;
165
354
  name?: string | null;
166
355
  data: PageSnapshot;
356
+ /** Initial discovery posture for a new page. Independent of visibility. */
357
+ listed?: boolean;
167
358
  /**
168
359
  * The page to nest this new page under. Applied only when the page is first
169
360
  * created; a later content save with the same id leaves the parent untouched.
@@ -199,6 +390,22 @@ export type Visibility = PageVisibility;
199
390
  /** Every {@link PageVisibility} value, in escalating-privacy order — the source of
200
391
  * truth for server-side validation and the share dialog's scope picker. */
201
392
  export declare const PAGE_VISIBILITIES: readonly PageVisibility[];
393
+ /** The state returned by the co-located page visibility/listing endpoint.
394
+ * `listed` is a discovery flag, not another rung in {@link PageVisibility}. */
395
+ export interface PageVisibilitySettings {
396
+ /** The owning page's concurrency token; absent only on a legacy server. */
397
+ rev?: EntityRev;
398
+ visibility: PageVisibility;
399
+ listed: boolean;
400
+ }
401
+ /** A non-empty update accepted by the page visibility/listing endpoint. */
402
+ export type PageVisibilityUpdate = ({
403
+ visibility: PageVisibility;
404
+ listed?: boolean;
405
+ } | {
406
+ visibility?: PageVisibility;
407
+ listed: boolean;
408
+ }) & ExpectedRevInput;
202
409
  /**
203
410
  * The two INSTANCE-level agent-edits modes (AGED-1). Governs whether an agent (an
204
411
  * MCP tool or the built-in AI) writes a page DIRECTLY or persists its change as a
@@ -213,6 +420,17 @@ export type AgentEditsMode = 'suggest' | 'direct';
213
420
  * Resolve to an effective {@link AgentEditsMode} with {@link resolveAgentEdits}.
214
421
  */
215
422
  export type AgentEditsPolicy = 'inherit' | 'suggest' | 'direct';
423
+ /** Revision-bearing response from a page's agent-edits policy endpoint. */
424
+ export interface AgentEditsPolicySettings {
425
+ /** The owning page's concurrency token; absent only on a legacy server. */
426
+ rev?: EntityRev;
427
+ agentEdits: AgentEditsPolicy;
428
+ effective: AgentEditsMode;
429
+ }
430
+ /** Revision-aware input for a page's agent-edits policy endpoint. */
431
+ export interface AgentEditsPolicyUpdate extends ExpectedRevInput {
432
+ agentEdits: AgentEditsPolicy;
433
+ }
216
434
  /** Every {@link AgentEditsMode} — the source of truth for validating an instance
217
435
  * policy write (`PUT /api/instance`). */
218
436
  export declare const AGENT_EDITS_MODES: readonly AgentEditsMode[];
@@ -363,3 +581,4 @@ export interface ServerControls {
363
581
  * Absent on the web / an old host that predates the capability. */
364
582
  setAgentLocalTcp?(enabled: boolean): Promise<ServerInfo>;
365
583
  }
584
+ export {};
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA0CH,4DAA4D;AAC5D,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAiB,EAAE,CAAC,CAAC;IACpD,QAAQ,EAAE,EAAC,MAAM,EAAE,EAAE,EAAC;IACtB,MAAM,EAAE,EAAE;IACV,KAAK,EAAE,EAAE;CACV,CAAC,CAAC;AAgKH;4EAC4E;AAC5E,MAAM,CAAC,MAAM,iBAAiB,GAA8B;IAC1D,SAAS;IACT,QAAQ;IACR,eAAe;IACf,SAAS;IACT,YAAY;CACb,CAAC;AAkBF;0CAC0C;AAC1C,MAAM,CAAC,MAAM,iBAAiB,GAA8B,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAElF;gDACgD;AAChD,MAAM,CAAC,MAAM,oBAAoB,GAAgC,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AAElG;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAAsB,EACtB,QAAoC;IAEpC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACzD,OAAO,QAAQ,IAAI,SAAS,CAAC;AAC/B,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAsRH,4DAA4D;AAC5D,MAAM,CAAC,MAAM,iBAAiB,GAAG,GAAiB,EAAE,CAAC,CAAC;IACpD,QAAQ,EAAE,EAAC,MAAM,EAAE,EAAE,EAAC;IACtB,MAAM,EAAE,EAAE;IACV,KAAK,EAAE,EAAE;CACV,CAAC,CAAC;AAyKH;4EAC4E;AAC5E,MAAM,CAAC,MAAM,iBAAiB,GAA8B;IAC1D,SAAS;IACT,QAAQ;IACR,eAAe;IACf,SAAS;IACT,YAAY;CACb,CAAC;AA8CF;0CAC0C;AAC1C,MAAM,CAAC,MAAM,iBAAiB,GAA8B,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAElF;gDACgD;AAChD,MAAM,CAAC,MAAM,oBAAoB,GAAgC,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;AAElG;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAAsB,EACtB,QAAoC;IAEpC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACzD,OAAO,QAAQ,IAAI,SAAS,CAAC;AAC/B,CAAC"}
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@book.dev/sdk",
3
- "version": "3.10.0",
3
+ "version": "3.14.0",
4
4
  "description": "Shared OpenBook types and HTTP client used by the server, desktop, and web.",
5
5
  "repository": {
6
6
  "type": "git",
7
- "url": "git+https://github.com/eliotlim/OpenBook.git",
7
+ "url": "git+https://github.com/lab255/OpenBook.git",
8
8
  "directory": "packages/sdk"
9
9
  },
10
10
  "publishConfig": {