edytor 0.1.0-next.23 → 0.1.0-next.24
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/README.md +1 -1
- package/dist/cloudflare/DocumentRoom.d.ts +242 -10
- package/dist/cloudflare/DocumentRoom.js +793 -45
- package/dist/cloudflare/history.d.ts +110 -0
- package/dist/cloudflare/history.js +125 -0
- package/dist/cloudflare/index.d.ts +4 -2
- package/dist/cloudflare/index.js +4 -2
- package/dist/cloudflare/routeDocumentSocket.d.ts +17 -0
- package/dist/cloudflare/routeDocumentSocket.js +82 -17
- package/dist/crdt/edytor-doc.d.ts +20 -0
- package/dist/crdt/edytor-doc.js +52 -2
- package/dist/crdt/index.d.ts +8 -0
- package/dist/crdt/purge.d.ts +46 -0
- package/dist/crdt/purge.js +206 -0
- package/dist/crdt/restore.d.ts +63 -0
- package/dist/crdt/restore.js +217 -0
- package/dist/crdt/schema.d.ts +8 -0
- package/dist/crdt/schema.js +8 -0
- package/dist/crdt/text/deletes.d.ts +17 -0
- package/dist/crdt/text/deletes.js +125 -12
- package/dist/crdt/text/model.d.ts +1 -0
- package/dist/crdt/text/model.js +18 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
Edytor aims to be for Svelte what Slate.js is for React: a heavily customizable editor with an API to build any kind of collaborative rich text editor.
|
|
17
17
|
|
|
18
|
-
> **Work in progress.** Edytor is a pre-release (`0.1.0-next.
|
|
18
|
+
> **Work in progress.** Edytor is a pre-release (`0.1.0-next.24`, `edytor@next` on npm) and not ready for production; the API changes between releases without a compatibility layer. The untagged `edytor@0.0.11` on npm predates the current API. Issues and PRs are welcome: when you report a bug, include the document's JSON value.
|
|
19
19
|
|
|
20
20
|
## Features
|
|
21
21
|
|
|
@@ -95,6 +95,8 @@
|
|
|
95
95
|
*/
|
|
96
96
|
import { DurableObject } from 'cloudflare:workers';
|
|
97
97
|
import * as E from '../crdt/index.js';
|
|
98
|
+
import type { PurgeReport } from '../crdt/purge.js';
|
|
99
|
+
import { type HistoryEntry, type HistoryOptions, type KVLike } from './history.js';
|
|
98
100
|
import type { AwarenessEntry, DocumentSemanticsConfig, EdytorDoc, JSONBlock, JSONDoc, YDoc } from '../crdt/index.js';
|
|
99
101
|
/** Under SQLite-backed Durable Objects' 2 MB row cap, with room for the other columns. */
|
|
100
102
|
export declare const DEFAULT_MAX_ROW_BYTES: number;
|
|
@@ -135,6 +137,16 @@ export type ReplicaOwner = {
|
|
|
135
137
|
replica: number;
|
|
136
138
|
user: string;
|
|
137
139
|
};
|
|
140
|
+
/** What `restoreHistory` did (`room.history.restore`): `refused` when the room holds no such version. */
|
|
141
|
+
export type RestoreResult = {
|
|
142
|
+
status: 'applied' | 'noop' | 'refused';
|
|
143
|
+
key: string;
|
|
144
|
+
revived?: number;
|
|
145
|
+
moved?: number;
|
|
146
|
+
rewritten?: number;
|
|
147
|
+
created?: number;
|
|
148
|
+
deleted?: number;
|
|
149
|
+
};
|
|
138
150
|
/** The document as `onSave` receives it. */
|
|
139
151
|
export type SavedDocument = {
|
|
140
152
|
/** The document as JSON. */
|
|
@@ -154,6 +166,14 @@ export type LoadedDocument = JSONDoc | Uint8Array | Pick<SavedDocument, 'update'
|
|
|
154
166
|
export declare const PROBE_HEADER = "X-Edytor-Probe";
|
|
155
167
|
/** The transaction origin of the room's own edits (`transact`, `onLoad` seeds). */
|
|
156
168
|
export declare const ROOM_ORIGIN: unique symbol;
|
|
169
|
+
/** The transaction origin of a history restore (H11): the room's restore history tracks it. */
|
|
170
|
+
export declare const RESTORE_ORIGIN: unique symbol;
|
|
171
|
+
/** The transaction origin of the room's purge (H7): tracked by no history. */
|
|
172
|
+
export declare const PURGE_ORIGIN: unique symbol;
|
|
173
|
+
/** The header `routeDocumentHistory` sets on an authorized history request (H11). */
|
|
174
|
+
export declare const HISTORY_HEADER = "X-Edytor-History";
|
|
175
|
+
/** The version key of a history `read` or `restore` request. */
|
|
176
|
+
export declare const HISTORY_KEY_HEADER = "X-Edytor-History-Key";
|
|
157
177
|
/**
|
|
158
178
|
* Headers carrying the identity `routeDocumentSocket` verified — never the
|
|
159
179
|
* client's. The user id is percent-encoded (`encodeURIComponent`): a header
|
|
@@ -179,6 +199,17 @@ export type DocumentRoomEnv = {
|
|
|
179
199
|
EDYTOR_MAX_UPDATES_PER_SECOND?: string | number;
|
|
180
200
|
/** `off`: the room logs nothing (default: one JSON line per compaction, quota hit, denial, fault). */
|
|
181
201
|
EDYTOR_LOG?: string;
|
|
202
|
+
/**
|
|
203
|
+
* Days after which deleted content is purged (H7; default: the history
|
|
204
|
+
* retention, else 30); `off` never purges.
|
|
205
|
+
*/
|
|
206
|
+
EDYTOR_PURGE_AFTER_DAYS?: string | number;
|
|
207
|
+
/** A KV namespace binding: the room keeps its version history there (H11, `history()`). */
|
|
208
|
+
EDYTOR_HISTORY?: KVLike;
|
|
209
|
+
/** Days a version is kept (default 30). */
|
|
210
|
+
EDYTOR_HISTORY_RETENTION_DAYS?: string | number;
|
|
211
|
+
/** The IANA time zone of the history's half-day slots (default `UTC`). */
|
|
212
|
+
EDYTOR_HISTORY_TIME_ZONE?: string;
|
|
182
213
|
};
|
|
183
214
|
/** What a socket is bound to: its verified user, its replica (Yjs client id), its access. */
|
|
184
215
|
export type SocketIdentity = {
|
|
@@ -192,7 +223,7 @@ export type Attachment = SocketIdentity & {
|
|
|
192
223
|
clock: number | null;
|
|
193
224
|
};
|
|
194
225
|
export type Refusal = {
|
|
195
|
-
reason: 'generation' | 'schema' | 'malformed' | 'container' | 'identity' | 'replica' | 'read-only' | 'waiting' | 'storage' | 'internal' | 'quota' | 'mark' | 'denied' | 'orphan' | 'relayed';
|
|
226
|
+
reason: 'generation' | 'schema' | 'malformed' | 'container' | 'identity' | 'replica' | 'read-only' | 'waiting' | 'storage' | 'internal' | 'quota' | 'mark' | 'denied' | 'orphan' | 'relayed' | 'history';
|
|
196
227
|
detail: unknown;
|
|
197
228
|
};
|
|
198
229
|
/** A duration series: how many, their total and longest (ms; see {@link RoomMetrics}). */
|
|
@@ -239,6 +270,17 @@ export type RoomMetrics = {
|
|
|
239
270
|
validationDenials: number;
|
|
240
271
|
/** Every refusal, by reason (as `refusalCounts`). */
|
|
241
272
|
refusals: Partial<Record<Refusal['reason'], number>>;
|
|
273
|
+
/** Versions written to the history (H11), skipped (`history` refusals), and the last key written. */
|
|
274
|
+
history: {
|
|
275
|
+
written: number;
|
|
276
|
+
skipped: number;
|
|
277
|
+
lastKey: string | null;
|
|
278
|
+
};
|
|
279
|
+
/** Purges run (H7) and what they wrote, summed; the last horizon purged (ms since the epoch). */
|
|
280
|
+
purge: PurgeReport & {
|
|
281
|
+
runs: number;
|
|
282
|
+
horizon: number | null;
|
|
283
|
+
};
|
|
242
284
|
/** When this instance started (ms since the epoch). */
|
|
243
285
|
since: number;
|
|
244
286
|
};
|
|
@@ -250,6 +292,20 @@ export type RoomLogEntry = {
|
|
|
250
292
|
records: number;
|
|
251
293
|
rows: number;
|
|
252
294
|
} | {
|
|
295
|
+
edytor: 'history';
|
|
296
|
+
key: string;
|
|
297
|
+
bytes: number;
|
|
298
|
+
editors: number;
|
|
299
|
+
} | {
|
|
300
|
+
edytor: 'restore';
|
|
301
|
+
key: string;
|
|
302
|
+
user: string | null;
|
|
303
|
+
undo: boolean;
|
|
304
|
+
} | ({
|
|
305
|
+
edytor: 'purge';
|
|
306
|
+
horizon: number;
|
|
307
|
+
bytes: number;
|
|
308
|
+
} & PurgeReport) | {
|
|
253
309
|
edytor: 'quota';
|
|
254
310
|
user: string;
|
|
255
311
|
quota: string;
|
|
@@ -375,6 +431,22 @@ export type AttachDocumentOptions = {
|
|
|
375
431
|
* {@link E.defaultSemantics} (the bundled rich-text, code and image kinds).
|
|
376
432
|
*/
|
|
377
433
|
semantics?: DocumentSemanticsConfig;
|
|
434
|
+
/**
|
|
435
|
+
* Version history in KV (H11, `room.history.*`): the room writes its
|
|
436
|
+
* state twice a day — the morning's at local noon, the evening's at
|
|
437
|
+
* midnight, in `timeZone` — when it changed, for `retentionDays`; read
|
|
438
|
+
* and restore them with `listHistory`, `readHistory`, `restoreHistory`
|
|
439
|
+
* and `undoRestore` (or `routeDocumentHistory`). Without it, no history.
|
|
440
|
+
*/
|
|
441
|
+
history?: HistoryOptions;
|
|
442
|
+
/**
|
|
443
|
+
* Days after which deleted content is purged from the room and every
|
|
444
|
+
* replica (H7, `room.purge.*`): default the history's `retentionDays`,
|
|
445
|
+
* else 30; `false` never purges.
|
|
446
|
+
*/
|
|
447
|
+
purgeAfterDays?: number | false;
|
|
448
|
+
/** The room's clock, ms since the epoch (default `Date.now`): its slots, epochs and alarm read it. */
|
|
449
|
+
now?: () => number;
|
|
378
450
|
};
|
|
379
451
|
/** The tag of the document's sockets: other sockets of the object are left to you. */
|
|
380
452
|
export declare const SOCKET_TAG = "edytor";
|
|
@@ -442,14 +514,33 @@ export declare class AttachedDocument {
|
|
|
442
514
|
private retryable;
|
|
443
515
|
private readonly sql;
|
|
444
516
|
private _facade;
|
|
445
|
-
private saveScheduled;
|
|
446
517
|
/** Alarms in a row that found the rows unreadable: each re-arms later. */
|
|
447
518
|
private saveRetries;
|
|
519
|
+
/** Each alarm task's due time (`room.alarm.tasks`), mirrored in the meta table (`due.<task>`). */
|
|
520
|
+
private dues;
|
|
521
|
+
/** The alarm this instance set, or found set at its start (`null`: none). */
|
|
522
|
+
private armed;
|
|
523
|
+
/** The room's clock (`now`). */
|
|
524
|
+
private readonly clock;
|
|
525
|
+
/** The verified users the open slot recorded (memory: a wake records them again, `OR IGNORE`). */
|
|
526
|
+
private readonly slotEditors;
|
|
527
|
+
/** Who the room writes for while a restore or its undo runs (the slot's editor). */
|
|
528
|
+
private writer;
|
|
529
|
+
/** The last restore's step (`room.history.undo`), read from the `restore` table at load. */
|
|
530
|
+
private restoreStep;
|
|
531
|
+
/** The history recording restores (`RESTORE_ORIGIN`), on the live facade. */
|
|
532
|
+
private restoreManager;
|
|
533
|
+
/** The version writes in flight (`historyWritten()`). */
|
|
534
|
+
private writing;
|
|
448
535
|
private readonly options;
|
|
449
536
|
private readonly rowsTable;
|
|
450
537
|
private readonly replicasTable;
|
|
451
538
|
private readonly metaTable;
|
|
539
|
+
private readonly epochsTable;
|
|
540
|
+
private readonly editorsTable;
|
|
541
|
+
private readonly restoreTable;
|
|
452
542
|
private _lookups;
|
|
543
|
+
private _history;
|
|
453
544
|
constructor(ctx: DurableObjectState, options?: AttachDocumentOptions);
|
|
454
545
|
/**
|
|
455
546
|
* Restore from storage, or seed from `onLoad`. Never throws: a throw
|
|
@@ -508,15 +599,33 @@ export declare class AttachedDocument {
|
|
|
508
599
|
/** The document as JSON. */
|
|
509
600
|
read(): JSONDoc;
|
|
510
601
|
/**
|
|
511
|
-
*
|
|
512
|
-
*
|
|
513
|
-
*
|
|
514
|
-
* alarm is set
|
|
515
|
-
*
|
|
602
|
+
* The room's one alarm (`room.alarm.tasks`): every task due at its time
|
|
603
|
+
* runs — the history slot (`room.history.slots`), `onSave`, the purge
|
|
604
|
+
* (`room.purge.timing`) — each re-arming itself or clearing its due
|
|
605
|
+
* row; then the alarm is set to the earliest due time left. While the
|
|
606
|
+
* rows cannot be read (a retryable failure), it starts the room again;
|
|
607
|
+
* if that fails too, the save stays due, later at each failure (up to 5
|
|
608
|
+
* minutes), so the mirror never silently lags what the room stored. A
|
|
609
|
+
* throw from `onSave` keeps it due and is rethrown (the platform retries).
|
|
516
610
|
*/
|
|
517
611
|
alarm(): Promise<void>;
|
|
518
|
-
/** The
|
|
612
|
+
/** The `save` task: `onSave` with the document, or the save kept due while the rows cannot be read. */
|
|
613
|
+
private save;
|
|
614
|
+
/** The first unsaved change arms the save alarm; a save already due keeps its time. */
|
|
519
615
|
private scheduleSave;
|
|
616
|
+
/**
|
|
617
|
+
* Arm `task` at `at` (`room.alarm.tasks`): a task already due keeps its
|
|
618
|
+
* time (a wake or an edit never moves a pending save), unless `earlier`
|
|
619
|
+
* (an earlier time wins: the purge tick) or `replace`. The due time is
|
|
620
|
+
* stored (meta `due.<task>`) and the alarm set to the earliest one.
|
|
621
|
+
*/
|
|
622
|
+
private schedule;
|
|
623
|
+
/** Clear `task`'s due time. */
|
|
624
|
+
private unschedule;
|
|
625
|
+
/** Set the alarm to the earliest due time (none due: the alarm set is left, and finds nothing). */
|
|
626
|
+
private arm;
|
|
627
|
+
/** The due times stored (`due.<task>`); an alarm armed by 0.1.0-next.23 (none stored) is a due save. */
|
|
628
|
+
private readDues;
|
|
520
629
|
/**
|
|
521
630
|
* Generation cutover: drop the stored document (both tables) of a room
|
|
522
631
|
* whose storage belongs to another edytor generation, and start again
|
|
@@ -600,6 +709,93 @@ export declare class AttachedDocument {
|
|
|
600
709
|
* (`GET <room>?lastUpdated`), also over RPC.
|
|
601
710
|
*/
|
|
602
711
|
lastUpdated(): number | null;
|
|
712
|
+
/** The room's id: its name (`getByName`), else the object's id. */
|
|
713
|
+
private get roomId();
|
|
714
|
+
/** The history settings, resolved at first use (`null`: none; an unknown time zone is noted `history`). */
|
|
715
|
+
private get historyConfig();
|
|
716
|
+
/** Days after which deleted content is purged (`null`: never), `room.purge.timing`. */
|
|
717
|
+
private get purgeDays();
|
|
718
|
+
/** The last restore's deleted content, kept for its undo (`prepareRoomDoc`). */
|
|
719
|
+
private get restoreKeep();
|
|
720
|
+
/** The verified user a stored change is written for (a socket's, or the restorer's), or `null`. */
|
|
721
|
+
private editorOf;
|
|
722
|
+
/**
|
|
723
|
+
* A change was stored: arm the purge tick (`room.purge.timing`) and open
|
|
724
|
+
* the history slot it falls in (`room.history.slots`) — a purge opens
|
|
725
|
+
* none: it changes nothing a reader sees.
|
|
726
|
+
*/
|
|
727
|
+
private noteChange;
|
|
728
|
+
/** Before a write: a slot past its end is captured as it is, and written (`room.history.slots`). */
|
|
729
|
+
private closeSlotIfPast;
|
|
730
|
+
/** Close the open slot: capture it now, write it (the alarm, a start past its end). */
|
|
731
|
+
private closeSlot;
|
|
732
|
+
/**
|
|
733
|
+
* The open slot's version, read now (synchronous: nothing writes
|
|
734
|
+
* between the read and the slot's close), and the slot closed.
|
|
735
|
+
*/
|
|
736
|
+
private captureSlot;
|
|
737
|
+
/** Write a captured version (`room.history.value`); a failure is noted `history` and the slot skipped. */
|
|
738
|
+
private putSlot;
|
|
739
|
+
private skipVersion;
|
|
740
|
+
/** The history settings, or a throw: the room keeps no history. */
|
|
741
|
+
private requireHistory;
|
|
742
|
+
/**
|
|
743
|
+
* Resolves once the versions the room is writing are stored (a slot a
|
|
744
|
+
* write closed is written in the background).
|
|
745
|
+
*/
|
|
746
|
+
historyWritten(): Promise<void>;
|
|
747
|
+
/**
|
|
748
|
+
* The room's versions, newest first (H11): one per half-day slot that
|
|
749
|
+
* changed, for the retention (`room.history.slots`). Throws when the
|
|
750
|
+
* room keeps no history.
|
|
751
|
+
*/
|
|
752
|
+
listHistory(): Promise<HistoryEntry[]>;
|
|
753
|
+
/** Version `key` as JSON (a preview), or `null` when this room holds no such version. */
|
|
754
|
+
readHistory(key: string): Promise<JSONDoc | null>;
|
|
755
|
+
/**
|
|
756
|
+
* Restore version `key` as a forward edit (`room.history.restore`): one
|
|
757
|
+
* room transaction makes the visible document equal the version, keeping
|
|
758
|
+
* every id the registry holds and writing only what differs; stored,
|
|
759
|
+
* relayed to every socket, one step `undoRestore` undoes. `user` (the
|
|
760
|
+
* restorer) is recorded as the slot's editor and in the log. `refused`:
|
|
761
|
+
* this room holds no such version (expired, another room's key).
|
|
762
|
+
*/
|
|
763
|
+
restoreHistory(key: string, options?: {
|
|
764
|
+
user?: string;
|
|
765
|
+
}): Promise<RestoreResult>;
|
|
766
|
+
/**
|
|
767
|
+
* Undo the last restore (`room.history.undo`): the history undo of
|
|
768
|
+
* exactly its transaction, edits made since kept. One level: `noop` when
|
|
769
|
+
* no restore stands (none, undone already, or past the purge horizon).
|
|
770
|
+
*/
|
|
771
|
+
undoRestore(options?: {
|
|
772
|
+
user?: string;
|
|
773
|
+
}): Promise<{
|
|
774
|
+
status: 'applied' | 'noop';
|
|
775
|
+
}>;
|
|
776
|
+
/** The history recording restores, on the live facade (`RESTORE_ORIGIN` only, one step each). */
|
|
777
|
+
private restoreHistoryOf;
|
|
778
|
+
/** The last restore's step, from its table (`null`: none). */
|
|
779
|
+
private readRestore;
|
|
780
|
+
/**
|
|
781
|
+
* Forget the last restore's step: its table row goes, then what it kept
|
|
782
|
+
* is released and collected (the next compaction stores it collected).
|
|
783
|
+
*/
|
|
784
|
+
private dropRestore;
|
|
785
|
+
/**
|
|
786
|
+
* The purge task, also over RPC (`room.purge.timing`): record an epoch
|
|
787
|
+
* (the state vector, now) when the document changed since the last one,
|
|
788
|
+
* purge what was deleted before the horizon — the newest epoch at least
|
|
789
|
+
* `purgeAfterDays` old — when it is newer than the last purged, and
|
|
790
|
+
* re-arm for the next epoch to pass it. Returns what the purge wrote, or
|
|
791
|
+
* `null` when nothing was past the horizon.
|
|
792
|
+
*/
|
|
793
|
+
purge(): (PurgeReport & {
|
|
794
|
+
horizon: number;
|
|
795
|
+
}) | null;
|
|
796
|
+
private tick;
|
|
797
|
+
/** Purge what was deleted before `horizon`, as the room's own transaction, then compact. */
|
|
798
|
+
private purgeTo;
|
|
603
799
|
/** The room's counters (H14), also over RPC — see {@link RoomMetrics}. */
|
|
604
800
|
metrics(): RoomMetrics;
|
|
605
801
|
/** What the rows take: bytes, logical records, rows. */
|
|
@@ -687,6 +883,13 @@ export declare class AttachedDocument {
|
|
|
687
883
|
*/
|
|
688
884
|
private attribute;
|
|
689
885
|
fetch(request: Request): Promise<Response>;
|
|
886
|
+
/**
|
|
887
|
+
* One history request (H11): `list`, `read` (a version as JSON), and,
|
|
888
|
+
* for a write identity, `restore` and `undo`. `404` when the room keeps
|
|
889
|
+
* no history or holds no such version, `403` for a read-only identity's
|
|
890
|
+
* write, `503` when the room cannot serve it.
|
|
891
|
+
*/
|
|
892
|
+
private historyRequest;
|
|
690
893
|
/** Is `ws` one of this document's sockets? */
|
|
691
894
|
owns(ws: WebSocket): boolean;
|
|
692
895
|
webSocketMessage(ws: WebSocket, message: string | ArrayBuffer): boolean;
|
|
@@ -806,7 +1009,8 @@ export declare class AttachedDocument {
|
|
|
806
1009
|
* `edytor_replicas`) live beside yours and its sockets carry
|
|
807
1010
|
* {@link SOCKET_TAG}. Each handler your class does not define —
|
|
808
1011
|
* `fetch`, `webSocketMessage`, `webSocketClose`, `webSocketError`, and
|
|
809
|
-
* `alarm`
|
|
1012
|
+
* `alarm` unless the document needs none (no `onSave`, no `history`,
|
|
1013
|
+
* `purgeAfterDays: false`) — is installed on the object; a class that
|
|
810
1014
|
* defines one delegates to the returned document's method (which returns
|
|
811
1015
|
* `false` for a socket that is not the document's).
|
|
812
1016
|
*/
|
|
@@ -840,12 +1044,40 @@ export declare class DocumentRoom<Env = DocumentRoomEnv> extends DurableObject<E
|
|
|
840
1044
|
* at first use (after construction: it may return a subclass field).
|
|
841
1045
|
*/
|
|
842
1046
|
protected semantics(): DocumentSemanticsConfig;
|
|
1047
|
+
/**
|
|
1048
|
+
* Version history — see {@link AttachDocumentOptions.history}. Default:
|
|
1049
|
+
* the `EDYTOR_HISTORY` KV binding, with `EDYTOR_HISTORY_RETENTION_DAYS`
|
|
1050
|
+
* and `EDYTOR_HISTORY_TIME_ZONE`; none without it. Read once, at first use.
|
|
1051
|
+
*/
|
|
1052
|
+
protected history(): HistoryOptions | undefined;
|
|
1053
|
+
/** The room's clock — see {@link AttachDocumentOptions.now}. */
|
|
1054
|
+
protected now(): number;
|
|
843
1055
|
fetch(request: Request): Promise<Response>;
|
|
844
1056
|
webSocketMessage(ws: WebSocket, message: string | ArrayBuffer): void;
|
|
845
1057
|
webSocketClose(ws: WebSocket, code: number, reason: string): void;
|
|
846
1058
|
webSocketError(ws: WebSocket): void;
|
|
847
|
-
/** Runs `onSave
|
|
1059
|
+
/** Runs the room's tasks: `onSave`, the history slots, the purge. Call `super.alarm()` if you override it. */
|
|
848
1060
|
alarm(): Promise<void>;
|
|
1061
|
+
/** The versions, newest first, also over RPC — see {@link AttachedDocument.listHistory}. */
|
|
1062
|
+
listHistory(): Promise<HistoryEntry[]>;
|
|
1063
|
+
/** A version as JSON, also over RPC — see {@link AttachedDocument.readHistory}. */
|
|
1064
|
+
readHistory(key: string): Promise<JSONDoc | null>;
|
|
1065
|
+
/** Restore a version, also over RPC — see {@link AttachedDocument.restoreHistory}. */
|
|
1066
|
+
restoreHistory(key: string, options?: {
|
|
1067
|
+
user?: string;
|
|
1068
|
+
}): Promise<RestoreResult>;
|
|
1069
|
+
/** Undo the last restore, also over RPC — see {@link AttachedDocument.undoRestore}. */
|
|
1070
|
+
undoRestore(options?: {
|
|
1071
|
+
user?: string;
|
|
1072
|
+
}): Promise<{
|
|
1073
|
+
status: 'applied' | 'noop';
|
|
1074
|
+
}>;
|
|
1075
|
+
/** The version writes in flight, also over RPC — see {@link AttachedDocument.historyWritten}. */
|
|
1076
|
+
historyWritten(): Promise<void>;
|
|
1077
|
+
/** Run the purge task now, also over RPC — see {@link AttachedDocument.purge}. */
|
|
1078
|
+
purge(): (PurgeReport & {
|
|
1079
|
+
horizon: number;
|
|
1080
|
+
}) | null;
|
|
849
1081
|
/** Compaction, also over RPC. */
|
|
850
1082
|
compact(): {
|
|
851
1083
|
rows: number;
|