@dabble/patches 0.2.19 → 0.2.21
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/client/InMemoryStore.d.ts +1 -3
- package/dist/client/InMemoryStore.js +2 -6
- package/dist/client/IndexedDBStore.d.ts +1 -3
- package/dist/client/IndexedDBStore.js +2 -6
- package/dist/client/Patches.js +2 -5
- package/dist/client/PatchesHistoryClient.d.ts +3 -3
- package/dist/client/PatchesHistoryClient.js +4 -4
- package/dist/client/PatchesStore.d.ts +1 -1
- package/dist/net/protocol/types.d.ts +4 -4
- package/dist/net/websocket/PatchesWebSocket.d.ts +29 -3
- package/dist/net/websocket/PatchesWebSocket.js +39 -4
- package/dist/net/websocket/WebSocketServer.d.ts +9 -9
- package/dist/net/websocket/WebSocketServer.js +36 -11
- package/package.json +1 -1
|
@@ -7,13 +7,11 @@ import type { PatchesStore, TrackedDoc } from './PatchesStore.js';
|
|
|
7
7
|
*/
|
|
8
8
|
export declare class InMemoryStore implements PatchesStore {
|
|
9
9
|
private docs;
|
|
10
|
-
/** Signal emitted when pending changes are added (mirrors IndexedDBStore API) */
|
|
11
|
-
readonly onPendingChanges: import("../event-signal.js").Signal<(docId: string, changes: Change[]) => void>;
|
|
12
10
|
getDoc(docId: string): Promise<PatchesSnapshot | undefined>;
|
|
13
11
|
getPendingChanges(docId: string): Promise<Change[]>;
|
|
14
12
|
getLastRevs(docId: string): Promise<[number, number]>;
|
|
15
13
|
listDocs(includeDeleted?: boolean): Promise<TrackedDoc[]>;
|
|
16
|
-
|
|
14
|
+
savePendingChange(docId: string, change: Change): Promise<void>;
|
|
17
15
|
saveCommittedChanges(docId: string, changes: Change[], sentPendingRange?: [number, number]): Promise<void>;
|
|
18
16
|
trackDocs(docIds: string[]): Promise<void>;
|
|
19
17
|
untrackDocs(docIds: string[]): Promise<void>;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { signal } from '../event-signal.js';
|
|
2
1
|
import { transformPatch } from '../json-patch/transformPatch.js';
|
|
3
2
|
import { applyChanges } from '../utils.js';
|
|
4
3
|
/**
|
|
@@ -9,8 +8,6 @@ import { applyChanges } from '../utils.js';
|
|
|
9
8
|
export class InMemoryStore {
|
|
10
9
|
constructor() {
|
|
11
10
|
this.docs = new Map();
|
|
12
|
-
/** Signal emitted when pending changes are added (mirrors IndexedDBStore API) */
|
|
13
|
-
this.onPendingChanges = signal();
|
|
14
11
|
}
|
|
15
12
|
// ─── Reconstruction ────────────────────────────────────────────────────
|
|
16
13
|
async getDoc(docId) {
|
|
@@ -55,12 +52,11 @@ export class InMemoryStore {
|
|
|
55
52
|
}));
|
|
56
53
|
}
|
|
57
54
|
// ─── Writes ────────────────────────────────────────────────────────────
|
|
58
|
-
async
|
|
55
|
+
async savePendingChange(docId, change) {
|
|
59
56
|
const buf = this.docs.get(docId) ?? { committed: [], pending: [] };
|
|
60
57
|
if (!this.docs.has(docId))
|
|
61
58
|
this.docs.set(docId, buf);
|
|
62
|
-
buf.pending.push(
|
|
63
|
-
this.onPendingChanges.emit(docId, changes);
|
|
59
|
+
buf.pending.push(change);
|
|
64
60
|
}
|
|
65
61
|
async saveCommittedChanges(docId, changes, sentPendingRange) {
|
|
66
62
|
const buf = this.docs.get(docId) ?? { committed: [], pending: [] };
|
|
@@ -16,8 +16,6 @@ export declare class IndexedDBStore implements PatchesStore {
|
|
|
16
16
|
private db;
|
|
17
17
|
private dbName?;
|
|
18
18
|
private dbPromise;
|
|
19
|
-
/** Subscribe to be notified after local state changes are saved to the database. */
|
|
20
|
-
readonly onPendingChanges: import("../event-signal.js").Signal<(docId: string, changes: Change[]) => void>;
|
|
21
19
|
constructor(dbName?: string);
|
|
22
20
|
private initDB;
|
|
23
21
|
private getDB;
|
|
@@ -54,7 +52,7 @@ export declare class IndexedDBStore implements PatchesStore {
|
|
|
54
52
|
* Append an array of local changes to the pending queue.
|
|
55
53
|
* Called *before* you attempt to send them to the server.
|
|
56
54
|
*/
|
|
57
|
-
|
|
55
|
+
savePendingChange(docId: string, change: Change): Promise<void>;
|
|
58
56
|
/** Read back all pending changes for this docId (in order). */
|
|
59
57
|
getPendingChanges(docId: string): Promise<Change[]>;
|
|
60
58
|
/**
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { signal } from '../event-signal.js';
|
|
2
1
|
import { transformPatch } from '../json-patch/transformPatch.js';
|
|
3
2
|
import { applyChanges, deferred } from '../utils.js';
|
|
4
3
|
const DB_VERSION = 1;
|
|
@@ -18,8 +17,6 @@ const SNAPSHOT_INTERVAL = 200;
|
|
|
18
17
|
export class IndexedDBStore {
|
|
19
18
|
constructor(dbName) {
|
|
20
19
|
this.db = null;
|
|
21
|
-
/** Subscribe to be notified after local state changes are saved to the database. */
|
|
22
|
-
this.onPendingChanges = signal();
|
|
23
20
|
this.dbName = dbName;
|
|
24
21
|
this.dbPromise = deferred();
|
|
25
22
|
if (this.dbName) {
|
|
@@ -169,7 +166,7 @@ export class IndexedDBStore {
|
|
|
169
166
|
* Append an array of local changes to the pending queue.
|
|
170
167
|
* Called *before* you attempt to send them to the server.
|
|
171
168
|
*/
|
|
172
|
-
async
|
|
169
|
+
async savePendingChange(docId, change) {
|
|
173
170
|
const [tx, pendingChanges, docsStore] = await this.transaction(['pendingChanges', 'docs'], 'readwrite');
|
|
174
171
|
let docMeta = await docsStore.get(docId);
|
|
175
172
|
if (!docMeta) {
|
|
@@ -181,8 +178,7 @@ export class IndexedDBStore {
|
|
|
181
178
|
await docsStore.put(docMeta);
|
|
182
179
|
console.warn(`Revived document ${docId} by saving pending changes.`);
|
|
183
180
|
}
|
|
184
|
-
await
|
|
185
|
-
this.onPendingChanges.emit(docId, changes);
|
|
181
|
+
await pendingChanges.put({ ...change, docId });
|
|
186
182
|
await tx.complete();
|
|
187
183
|
}
|
|
188
184
|
/** Read back all pending changes for this docId (in order). */
|
package/dist/client/Patches.js
CHANGED
|
@@ -207,12 +207,9 @@ export class Patches {
|
|
|
207
207
|
* @returns An Unsubscriber function to remove the listener.
|
|
208
208
|
*/
|
|
209
209
|
_setupLocalDocListener(docId, doc) {
|
|
210
|
-
return doc.onChange(async () => {
|
|
211
|
-
const changes = doc.getUpdatesForServer();
|
|
212
|
-
if (!changes.length)
|
|
213
|
-
return;
|
|
210
|
+
return doc.onChange(async (change) => {
|
|
214
211
|
try {
|
|
215
|
-
await this.store.
|
|
212
|
+
await this.store.savePendingChange(docId, change);
|
|
216
213
|
// Note: When used with PatchesSync, it will handle flushing the changes
|
|
217
214
|
}
|
|
218
215
|
catch (err) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PatchesAPI } from '../net/protocol/types.js';
|
|
2
|
-
import type { Change, ListVersionsOptions, VersionMetadata } from '../types.js';
|
|
2
|
+
import type { Change, EditableVersionMetadata, ListVersionsOptions, VersionMetadata } from '../types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Client-side history/scrubbing interface for a document.
|
|
5
5
|
* Read-only: allows listing versions, loading states/changes, and scrubbing.
|
|
@@ -23,9 +23,9 @@ export declare class PatchesHistoryClient<T = any> {
|
|
|
23
23
|
/** List version metadata for this document (with options) */
|
|
24
24
|
listVersions(options?: ListVersionsOptions): Promise<VersionMetadata[]>;
|
|
25
25
|
/** Create a new named version snapshot of the document's current state. */
|
|
26
|
-
createVersion(
|
|
26
|
+
createVersion(metadata: EditableVersionMetadata): Promise<string>;
|
|
27
27
|
/** Update the name of a specific version. */
|
|
28
|
-
updateVersion(versionId: string,
|
|
28
|
+
updateVersion(versionId: string, metadata: EditableVersionMetadata): Promise<void>;
|
|
29
29
|
/** Load the state for a specific version */
|
|
30
30
|
getStateAtVersion(versionId: string): Promise<any>;
|
|
31
31
|
/** Load the changes for a specific version */
|
|
@@ -62,14 +62,14 @@ export class PatchesHistoryClient {
|
|
|
62
62
|
return this._versions;
|
|
63
63
|
}
|
|
64
64
|
/** Create a new named version snapshot of the document's current state. */
|
|
65
|
-
async createVersion(
|
|
66
|
-
const versionId = await this.api.createVersion(this.id,
|
|
65
|
+
async createVersion(metadata) {
|
|
66
|
+
const versionId = await this.api.createVersion(this.id, metadata);
|
|
67
67
|
await this.listVersions(); // Refresh the list of versions
|
|
68
68
|
return versionId;
|
|
69
69
|
}
|
|
70
70
|
/** Update the name of a specific version. */
|
|
71
|
-
async updateVersion(versionId,
|
|
72
|
-
await this.api.updateVersion(this.id, versionId,
|
|
71
|
+
async updateVersion(versionId, metadata) {
|
|
72
|
+
await this.api.updateVersion(this.id, versionId, metadata);
|
|
73
73
|
await this.listVersions(); // Refresh the list of versions
|
|
74
74
|
}
|
|
75
75
|
/** Load the state for a specific version */
|
|
@@ -27,7 +27,7 @@ export interface PatchesStore {
|
|
|
27
27
|
getDoc(docId: string): Promise<PatchesSnapshot | undefined>;
|
|
28
28
|
getPendingChanges(docId: string): Promise<Change[]>;
|
|
29
29
|
getLastRevs(docId: string): Promise<[committedRev: number, pendingRev: number]>;
|
|
30
|
-
|
|
30
|
+
savePendingChange(docId: string, change: Change): Promise<void>;
|
|
31
31
|
saveCommittedChanges(docId: string, changes: Change[], sentPendingRange?: [number, number]): Promise<void>;
|
|
32
32
|
/** Permanently delete document (writes tombstone so server delete happens later). */
|
|
33
33
|
deleteDoc(docId: string): Promise<void>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Unsubscriber } from '../../event-signal.js';
|
|
2
|
-
import type { Change, ListVersionsOptions, PatchesSnapshot, PatchesState, VersionMetadata } from '../../types';
|
|
2
|
+
import type { Change, EditableVersionMetadata, ListVersionsOptions, PatchesSnapshot, PatchesState, VersionMetadata } from '../../types';
|
|
3
3
|
/**
|
|
4
4
|
* Represents the possible states of a network transport connection.
|
|
5
5
|
* - 'connecting': Connection is being established
|
|
@@ -117,15 +117,15 @@ export interface PatchesAPI {
|
|
|
117
117
|
/** Delete a document. */
|
|
118
118
|
deleteDoc(docId: string): Promise<void>;
|
|
119
119
|
/** Create a new named version snapshot of a document's current state. */
|
|
120
|
-
createVersion(docId: string,
|
|
120
|
+
createVersion(docId: string, metadata: EditableVersionMetadata): Promise<string>;
|
|
121
121
|
/** List metadata for saved versions of a document. */
|
|
122
122
|
listVersions(docId: string, options?: ListVersionsOptions): Promise<VersionMetadata[]>;
|
|
123
123
|
/** Get the state snapshot for a specific version ID. */
|
|
124
124
|
getVersionState(docId: string, versionId: string): Promise<PatchesState>;
|
|
125
125
|
/** Get the original Change objects associated with a specific version ID. */
|
|
126
126
|
getVersionChanges(docId: string, versionId: string): Promise<Change[]>;
|
|
127
|
-
/** Update the name of a specific version. */
|
|
128
|
-
updateVersion(docId: string, versionId: string,
|
|
127
|
+
/** Update the name and other metadata of a specific version. */
|
|
128
|
+
updateVersion(docId: string, versionId: string, metadata: EditableVersionMetadata): Promise<void>;
|
|
129
129
|
}
|
|
130
130
|
export interface PatchesNotificationParams {
|
|
131
131
|
docId: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Signal } from '../../event-signal.js';
|
|
2
|
-
import type { Change, ListVersionsOptions, PatchesSnapshot, VersionMetadata } from '../../types.js';
|
|
2
|
+
import type { Change, EditableVersionMetadata, ListVersionsOptions, PatchesSnapshot, VersionMetadata } from '../../types.js';
|
|
3
3
|
import type { ConnectionState, PatchesAPI, PatchesNotificationParams } from '../protocol/types.js';
|
|
4
4
|
import { type WebSocketOptions } from './WebSocketTransport.js';
|
|
5
5
|
/**
|
|
@@ -74,7 +74,7 @@ export declare class PatchesWebSocket implements PatchesAPI {
|
|
|
74
74
|
* @param name - A descriptive name for the version.
|
|
75
75
|
* @returns A promise resolving with the unique ID of the newly created version.
|
|
76
76
|
*/
|
|
77
|
-
createVersion(docId: string,
|
|
77
|
+
createVersion(docId: string, metadata: EditableVersionMetadata): Promise<string>;
|
|
78
78
|
/**
|
|
79
79
|
* Lists metadata for saved versions of a document.
|
|
80
80
|
* @param docId - The ID of the document.
|
|
@@ -103,5 +103,31 @@ export declare class PatchesWebSocket implements PatchesAPI {
|
|
|
103
103
|
* @param name - The new name for the version.
|
|
104
104
|
* @returns A promise resolving when the update is confirmed.
|
|
105
105
|
*/
|
|
106
|
-
updateVersion(docId: string, versionId: string,
|
|
106
|
+
updateVersion(docId: string, versionId: string, metadata: EditableVersionMetadata): Promise<void>;
|
|
107
|
+
/**
|
|
108
|
+
* Lists all branches for a document.
|
|
109
|
+
* @param docId - The ID of the document.
|
|
110
|
+
* @returns A promise resolving with an array of branch metadata objects.
|
|
111
|
+
*/
|
|
112
|
+
listBranches(docId: string): Promise<VersionMetadata[]>;
|
|
113
|
+
/**
|
|
114
|
+
* Creates a new branch for a document.
|
|
115
|
+
* @param docId - The ID of the document.
|
|
116
|
+
* @param rev - The revision number to base the new branch on.
|
|
117
|
+
* @param metadata - Optional metadata for the new branch.
|
|
118
|
+
* @returns A promise resolving with the unique ID of the newly created branch.
|
|
119
|
+
*/
|
|
120
|
+
createBranch(docId: string, rev: number, metadata?: EditableVersionMetadata): Promise<string>;
|
|
121
|
+
/**
|
|
122
|
+
* Closes a branch on the server.
|
|
123
|
+
* @param branchId - The ID of the branch to close.
|
|
124
|
+
* @returns A promise resolving when the branch is closed.
|
|
125
|
+
*/
|
|
126
|
+
closeBranch(branchId: string): Promise<void>;
|
|
127
|
+
/**
|
|
128
|
+
* Merges a branch on the server.
|
|
129
|
+
* @param branchId - The ID of the branch to merge.
|
|
130
|
+
* @returns A promise resolving when the merge is confirmed.
|
|
131
|
+
*/
|
|
132
|
+
mergeBranch(branchId: string): Promise<void>;
|
|
107
133
|
}
|
|
@@ -101,8 +101,8 @@ export class PatchesWebSocket {
|
|
|
101
101
|
* @param name - A descriptive name for the version.
|
|
102
102
|
* @returns A promise resolving with the unique ID of the newly created version.
|
|
103
103
|
*/
|
|
104
|
-
async createVersion(docId,
|
|
105
|
-
return this.rpc.request('createVersion', { docId,
|
|
104
|
+
async createVersion(docId, metadata) {
|
|
105
|
+
return this.rpc.request('createVersion', { docId, metadata });
|
|
106
106
|
}
|
|
107
107
|
/**
|
|
108
108
|
* Lists metadata for saved versions of a document.
|
|
@@ -138,7 +138,42 @@ export class PatchesWebSocket {
|
|
|
138
138
|
* @param name - The new name for the version.
|
|
139
139
|
* @returns A promise resolving when the update is confirmed.
|
|
140
140
|
*/
|
|
141
|
-
async updateVersion(docId, versionId,
|
|
142
|
-
return this.rpc.request('updateVersion', { docId, versionId,
|
|
141
|
+
async updateVersion(docId, versionId, metadata) {
|
|
142
|
+
return this.rpc.request('updateVersion', { docId, versionId, metadata });
|
|
143
|
+
}
|
|
144
|
+
// === Branch Operations ===
|
|
145
|
+
/**
|
|
146
|
+
* Lists all branches for a document.
|
|
147
|
+
* @param docId - The ID of the document.
|
|
148
|
+
* @returns A promise resolving with an array of branch metadata objects.
|
|
149
|
+
*/
|
|
150
|
+
async listBranches(docId) {
|
|
151
|
+
return this.rpc.request('listBranches', { docId });
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Creates a new branch for a document.
|
|
155
|
+
* @param docId - The ID of the document.
|
|
156
|
+
* @param rev - The revision number to base the new branch on.
|
|
157
|
+
* @param metadata - Optional metadata for the new branch.
|
|
158
|
+
* @returns A promise resolving with the unique ID of the newly created branch.
|
|
159
|
+
*/
|
|
160
|
+
async createBranch(docId, rev, metadata) {
|
|
161
|
+
return this.rpc.request('createBranch', { docId, rev, metadata });
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Closes a branch on the server.
|
|
165
|
+
* @param branchId - The ID of the branch to close.
|
|
166
|
+
* @returns A promise resolving when the branch is closed.
|
|
167
|
+
*/
|
|
168
|
+
async closeBranch(branchId) {
|
|
169
|
+
return this.rpc.request('closeBranch', { branchId });
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Merges a branch on the server.
|
|
173
|
+
* @param branchId - The ID of the branch to merge.
|
|
174
|
+
* @returns A promise resolving when the merge is confirmed.
|
|
175
|
+
*/
|
|
176
|
+
async mergeBranch(branchId) {
|
|
177
|
+
return this.rpc.request('mergeBranch', { branchId });
|
|
143
178
|
}
|
|
144
179
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { PatchesBranchManager } from '../../server/PatchesBranchManager.js';
|
|
2
2
|
import type { PatchesHistoryManager } from '../../server/PatchesHistoryManager.js';
|
|
3
3
|
import type { PatchesServer } from '../../server/PatchesServer.js';
|
|
4
|
-
import type { Change,
|
|
4
|
+
import type { Change, EditableVersionMetadata, ListVersionsOptions } from '../../types.js';
|
|
5
5
|
import { JSONRPCServer } from '../protocol/JSONRPCServer.js';
|
|
6
6
|
import type { ServerTransport } from '../protocol/types.js';
|
|
7
7
|
import type { AuthorizationProvider } from './AuthorizationProvider.js';
|
|
@@ -35,6 +35,8 @@ export declare class WebSocketServer {
|
|
|
35
35
|
protected assertAccess(connectionId: string, docId: string, kind: 'read' | 'write', method: string, params?: Record<string, any>): Promise<void>;
|
|
36
36
|
protected assertRead(connectionId: string, docId: string, method: string, params?: Record<string, any>): Promise<void>;
|
|
37
37
|
protected assertWrite(connectionId: string, docId: string, method: string, params?: Record<string, any>): Promise<void>;
|
|
38
|
+
protected assertHistoryEnabled(): void;
|
|
39
|
+
protected assertBranchingEnabled(): void;
|
|
38
40
|
/**
|
|
39
41
|
* Subscribes the client to one or more documents to receive real-time updates.
|
|
40
42
|
* @param connectionId - The ID of the connection making the request
|
|
@@ -88,25 +90,25 @@ export declare class WebSocketServer {
|
|
|
88
90
|
}): Promise<Change[]>;
|
|
89
91
|
/**
|
|
90
92
|
* Deletes a document on the server.
|
|
91
|
-
* @param
|
|
93
|
+
* @param connectionId - The ID of the connection making the request
|
|
92
94
|
* @param params - The deletion parameters
|
|
93
95
|
* @param params.docId - The ID of the document to delete
|
|
94
96
|
*/
|
|
95
|
-
deleteDoc(
|
|
97
|
+
deleteDoc(connectionId: string, params: {
|
|
96
98
|
docId: string;
|
|
97
99
|
}): Promise<void>;
|
|
98
100
|
listVersions(connectionId: string, params: {
|
|
99
101
|
docId: string;
|
|
100
102
|
options?: ListVersionsOptions;
|
|
101
|
-
}): Promise<VersionMetadata[]>;
|
|
103
|
+
}): Promise<import("../../types.js").VersionMetadata[]>;
|
|
102
104
|
createVersion(connectionId: string, params: {
|
|
103
105
|
docId: string;
|
|
104
|
-
|
|
106
|
+
metadata: EditableVersionMetadata;
|
|
105
107
|
}): Promise<string>;
|
|
106
108
|
updateVersion(connectionId: string, params: {
|
|
107
109
|
docId: string;
|
|
108
110
|
versionId: string;
|
|
109
|
-
|
|
111
|
+
metadata: EditableVersionMetadata;
|
|
110
112
|
}): Promise<void>;
|
|
111
113
|
getStateAtVersion(connectionId: string, params: {
|
|
112
114
|
docId: string;
|
|
@@ -131,12 +133,10 @@ export declare class WebSocketServer {
|
|
|
131
133
|
createBranch(connectionId: string, params: {
|
|
132
134
|
docId: string;
|
|
133
135
|
rev: number;
|
|
134
|
-
|
|
135
|
-
metadata?: Record<string, any>;
|
|
136
|
+
metadata?: EditableVersionMetadata;
|
|
136
137
|
}): Promise<string>;
|
|
137
138
|
closeBranch(connectionId: string, params: {
|
|
138
139
|
branchId: string;
|
|
139
|
-
status?: 'merged' | 'closed';
|
|
140
140
|
}): Promise<void>;
|
|
141
141
|
mergeBranch(connectionId: string, params: {
|
|
142
142
|
branchId: string;
|
|
@@ -54,6 +54,16 @@ export class WebSocketServer {
|
|
|
54
54
|
assertWrite(connectionId, docId, method, params) {
|
|
55
55
|
return this.assertAccess(connectionId, docId, 'write', method, params);
|
|
56
56
|
}
|
|
57
|
+
assertHistoryEnabled() {
|
|
58
|
+
if (!this.history) {
|
|
59
|
+
throw new Error('History is not enabled');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
assertBranchingEnabled() {
|
|
63
|
+
if (!this.branches) {
|
|
64
|
+
throw new Error('Branching is not enabled');
|
|
65
|
+
}
|
|
66
|
+
}
|
|
57
67
|
// --- Patches API Methods ---
|
|
58
68
|
// === Subscription Operations ===
|
|
59
69
|
/**
|
|
@@ -141,44 +151,55 @@ export class WebSocketServer {
|
|
|
141
151
|
}
|
|
142
152
|
/**
|
|
143
153
|
* Deletes a document on the server.
|
|
144
|
-
* @param
|
|
154
|
+
* @param connectionId - The ID of the connection making the request
|
|
145
155
|
* @param params - The deletion parameters
|
|
146
156
|
* @param params.docId - The ID of the document to delete
|
|
147
157
|
*/
|
|
148
|
-
async deleteDoc(
|
|
158
|
+
async deleteDoc(connectionId, params) {
|
|
149
159
|
const { docId } = params;
|
|
150
|
-
await this.assertWrite(
|
|
151
|
-
|
|
160
|
+
await this.assertWrite(connectionId, docId, 'deleteDoc', params);
|
|
161
|
+
await this.patches.deleteDoc(docId);
|
|
162
|
+
// Notify other clients that the document has been deleted
|
|
163
|
+
const connectionIds = this.transport.getConnectionIds().filter(id => id !== connectionId);
|
|
164
|
+
if (connectionIds.length > 0) {
|
|
165
|
+
this.rpc.notify(connectionIds, 'docDeleted', { docId });
|
|
166
|
+
}
|
|
152
167
|
}
|
|
153
168
|
// ---------------------------------------------------------------------------
|
|
154
169
|
// History Manager wrappers
|
|
155
170
|
// ---------------------------------------------------------------------------
|
|
156
171
|
async listVersions(connectionId, params) {
|
|
172
|
+
this.assertHistoryEnabled();
|
|
157
173
|
const { docId, options } = params;
|
|
158
174
|
await this.assertRead(connectionId, docId, 'listVersions', params);
|
|
159
175
|
return this.history.listVersions(docId, options ?? {});
|
|
160
176
|
}
|
|
161
177
|
async createVersion(connectionId, params) {
|
|
162
|
-
|
|
178
|
+
this.assertHistoryEnabled();
|
|
179
|
+
const { docId, metadata } = params;
|
|
163
180
|
await this.assertWrite(connectionId, docId, 'createVersion', params);
|
|
164
|
-
return this.history.createVersion(docId,
|
|
181
|
+
return this.history.createVersion(docId, metadata);
|
|
165
182
|
}
|
|
166
183
|
async updateVersion(connectionId, params) {
|
|
167
|
-
|
|
184
|
+
this.assertHistoryEnabled();
|
|
185
|
+
const { docId, versionId, metadata } = params;
|
|
168
186
|
await this.assertWrite(connectionId, docId, 'updateVersion', params);
|
|
169
|
-
return this.history.updateVersion(docId, versionId,
|
|
187
|
+
return this.history.updateVersion(docId, versionId, metadata);
|
|
170
188
|
}
|
|
171
189
|
async getStateAtVersion(connectionId, params) {
|
|
190
|
+
this.assertHistoryEnabled();
|
|
172
191
|
const { docId, versionId } = params;
|
|
173
192
|
await this.assertRead(connectionId, docId, 'getStateAtVersion', params);
|
|
174
193
|
return this.history.getStateAtVersion(docId, versionId);
|
|
175
194
|
}
|
|
176
195
|
async getChangesForVersion(connectionId, params) {
|
|
196
|
+
this.assertHistoryEnabled();
|
|
177
197
|
const { docId, versionId } = params;
|
|
178
198
|
await this.assertRead(connectionId, docId, 'getChangesForVersion', params);
|
|
179
199
|
return this.history.getChangesForVersion(docId, versionId);
|
|
180
200
|
}
|
|
181
201
|
async listServerChanges(connectionId, params) {
|
|
202
|
+
this.assertHistoryEnabled();
|
|
182
203
|
const { docId, options } = params;
|
|
183
204
|
await this.assertRead(connectionId, docId, 'listServerChanges', params);
|
|
184
205
|
return this.history.listServerChanges(docId, options ?? {});
|
|
@@ -187,21 +208,25 @@ export class WebSocketServer {
|
|
|
187
208
|
// Branch Manager wrappers
|
|
188
209
|
// ---------------------------------------------------------------------------
|
|
189
210
|
async listBranches(connectionId, params) {
|
|
211
|
+
this.assertBranchingEnabled();
|
|
190
212
|
const { docId } = params;
|
|
191
213
|
await this.assertRead(connectionId, docId, 'listBranches', params);
|
|
192
214
|
return this.branches.listBranches(docId);
|
|
193
215
|
}
|
|
194
216
|
async createBranch(connectionId, params) {
|
|
195
|
-
|
|
217
|
+
this.assertBranchingEnabled();
|
|
218
|
+
const { docId, rev, metadata } = params;
|
|
196
219
|
await this.assertWrite(connectionId, docId, 'createBranch', params);
|
|
197
|
-
return this.branches.createBranch(docId,
|
|
220
|
+
return this.branches.createBranch(docId, rev, metadata);
|
|
198
221
|
}
|
|
199
222
|
async closeBranch(connectionId, params) {
|
|
223
|
+
this.assertBranchingEnabled();
|
|
200
224
|
const { branchId } = params;
|
|
201
225
|
await this.assertWrite(connectionId, branchId, 'closeBranch', params);
|
|
202
|
-
return this.branches.closeBranch(branchId,
|
|
226
|
+
return this.branches.closeBranch(branchId, 'closed');
|
|
203
227
|
}
|
|
204
228
|
async mergeBranch(connectionId, params) {
|
|
229
|
+
this.assertBranchingEnabled();
|
|
205
230
|
const { branchId } = params;
|
|
206
231
|
await this.assertWrite(connectionId, branchId, 'mergeBranch', params);
|
|
207
232
|
return this.branches.mergeBranch(branchId);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dabble/patches",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.21",
|
|
4
4
|
"description": "Immutable JSON Patch implementation based on RFC 6902 supporting operational transformation and last-writer-wins",
|
|
5
5
|
"author": "Jacob Wright <jacwright@gmail.com>",
|
|
6
6
|
"bugs": {
|