@dabble/patches 0.4.4 → 0.4.6
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/algorithms/client/applyCommittedChanges.d.ts +8 -2
- package/dist/algorithms/client/applyCommittedChanges.js +30 -38
- package/dist/algorithms/client/batching.d.ts +8 -2
- package/dist/algorithms/client/batching.js +38 -37
- package/dist/algorithms/client/breakChange.d.ts +8 -2
- package/dist/algorithms/client/breakChange.js +191 -240
- package/dist/algorithms/client/createStateFromSnapshot.d.ts +8 -2
- package/dist/algorithms/client/createStateFromSnapshot.js +7 -8
- package/dist/algorithms/client/getJSONByteSize.d.ts +3 -1
- package/dist/algorithms/client/getJSONByteSize.js +12 -11
- package/dist/algorithms/client/makeChange.d.ts +8 -2
- package/dist/algorithms/client/makeChange.js +28 -36
- package/dist/algorithms/server/commitChanges.d.ts +9 -3
- package/dist/algorithms/server/commitChanges.js +69 -78
- package/dist/algorithms/server/createVersion.d.ts +9 -3
- package/dist/algorithms/server/createVersion.js +21 -27
- package/dist/algorithms/server/getSnapshotAtRevision.d.ts +9 -3
- package/dist/algorithms/server/getSnapshotAtRevision.js +27 -28
- package/dist/algorithms/server/getStateAtRevision.d.ts +9 -3
- package/dist/algorithms/server/getStateAtRevision.js +13 -17
- package/dist/algorithms/server/handleOfflineSessionsAndBatches.d.ts +9 -3
- package/dist/algorithms/server/handleOfflineSessionsAndBatches.js +60 -77
- package/dist/algorithms/server/transformIncomingChanges.d.ts +8 -2
- package/dist/algorithms/server/transformIncomingChanges.js +27 -39
- package/dist/algorithms/shared/applyChanges.d.ts +8 -2
- package/dist/algorithms/shared/applyChanges.js +11 -16
- package/dist/algorithms/shared/rebaseChanges.d.ts +8 -2
- package/dist/algorithms/shared/rebaseChanges.js +30 -49
- package/dist/chunk-IZ2YBCUP.js +56 -0
- package/dist/client/InMemoryStore.d.ts +9 -3
- package/dist/client/InMemoryStore.js +92 -101
- package/dist/client/IndexedDBStore.d.ts +9 -3
- package/dist/client/IndexedDBStore.js +378 -491
- package/dist/client/Patches.d.ts +18 -13
- package/dist/client/Patches.js +152 -207
- package/dist/client/PatchesDoc.d.ts +14 -8
- package/dist/client/PatchesDoc.js +147 -154
- package/dist/client/PatchesHistoryClient.d.ts +12 -5
- package/dist/client/PatchesHistoryClient.js +110 -117
- package/dist/client/PatchesStore.d.ts +9 -3
- package/dist/client/PatchesStore.js +0 -1
- package/dist/client/index.d.ts +12 -6
- package/dist/client/index.js +5 -5
- package/dist/data/change.d.ts +9 -3
- package/dist/data/change.js +23 -15
- package/dist/data/version.d.ts +9 -3
- package/dist/data/version.js +11 -15
- package/dist/event-signal.d.ts +7 -6
- package/dist/event-signal.js +24 -39
- package/dist/index-CvQws3AB.d.ts +36 -0
- package/dist/index.d.ts +27 -5
- package/dist/index.js +10 -4
- package/dist/json-patch/JSONPatch.d.ts +9 -5
- package/dist/json-patch/JSONPatch.js +175 -183
- package/dist/json-patch/applyPatch.d.ts +5 -2
- package/dist/json-patch/applyPatch.js +27 -35
- package/dist/json-patch/composePatch.d.ts +5 -2
- package/dist/json-patch/composePatch.js +34 -34
- package/dist/json-patch/createJSONPatch.d.ts +7 -2
- package/dist/json-patch/createJSONPatch.js +11 -38
- package/dist/json-patch/index.d.ts +14 -6
- package/dist/json-patch/index.js +20 -9
- package/dist/json-patch/invertPatch.d.ts +5 -2
- package/dist/json-patch/invertPatch.js +31 -30
- package/dist/json-patch/ops/add.d.ts +5 -2
- package/dist/json-patch/ops/add.js +53 -51
- package/dist/json-patch/ops/bitmask.d.ts +8 -5
- package/dist/json-patch/ops/bitmask.js +41 -44
- package/dist/json-patch/ops/copy.d.ts +5 -2
- package/dist/json-patch/ops/copy.js +32 -33
- package/dist/json-patch/ops/increment.d.ts +5 -2
- package/dist/json-patch/ops/increment.js +21 -20
- package/dist/json-patch/ops/index.d.ts +10 -21
- package/dist/json-patch/ops/index.js +34 -24
- package/dist/json-patch/ops/move.d.ts +5 -2
- package/dist/json-patch/ops/move.js +132 -198
- package/dist/json-patch/ops/remove.d.ts +5 -2
- package/dist/json-patch/ops/remove.js +33 -30
- package/dist/json-patch/ops/replace.d.ts +5 -2
- package/dist/json-patch/ops/replace.js +45 -43
- package/dist/json-patch/ops/test.d.ts +5 -2
- package/dist/json-patch/ops/test.js +25 -21
- package/dist/json-patch/ops/text.d.ts +5 -2
- package/dist/json-patch/ops/text.js +54 -54
- package/dist/json-patch/pathProxy.d.ts +9 -3
- package/dist/json-patch/pathProxy.js +27 -48
- package/dist/json-patch/state.d.ts +5 -2
- package/dist/json-patch/state.js +11 -7
- package/dist/json-patch/transformPatch.d.ts +6 -2
- package/dist/json-patch/transformPatch.js +21 -24
- package/dist/json-patch/types.d.ts +9 -7
- package/dist/json-patch/types.js +0 -1
- package/dist/json-patch/utils/deepEqual.d.ts +3 -1
- package/dist/json-patch/utils/deepEqual.js +32 -28
- package/dist/json-patch/utils/exit.d.ts +5 -2
- package/dist/json-patch/utils/exit.js +7 -3
- package/dist/json-patch/utils/get.d.ts +5 -2
- package/dist/json-patch/utils/get.js +8 -4
- package/dist/json-patch/utils/getOpData.d.ts +5 -2
- package/dist/json-patch/utils/getOpData.js +12 -9
- package/dist/json-patch/utils/getType.d.ts +6 -3
- package/dist/json-patch/utils/getType.js +9 -4
- package/dist/json-patch/utils/index.d.ts +15 -14
- package/dist/json-patch/utils/index.js +14 -14
- package/dist/json-patch/utils/log.d.ts +4 -2
- package/dist/json-patch/utils/log.js +8 -3
- package/dist/json-patch/utils/ops.d.ts +8 -5
- package/dist/json-patch/utils/ops.js +83 -100
- package/dist/json-patch/utils/paths.d.ts +12 -9
- package/dist/json-patch/utils/paths.js +54 -51
- package/dist/json-patch/utils/pluck.d.ts +8 -5
- package/dist/json-patch/utils/pluck.js +32 -26
- package/dist/json-patch/utils/shallowCopy.d.ts +3 -1
- package/dist/json-patch/utils/shallowCopy.js +22 -18
- package/dist/json-patch/utils/softWrites.d.ts +6 -3
- package/dist/json-patch/utils/softWrites.js +17 -16
- package/dist/json-patch/utils/toArrayIndex.d.ts +3 -1
- package/dist/json-patch/utils/toArrayIndex.js +14 -10
- package/dist/json-patch/utils/toKeys.d.ts +3 -1
- package/dist/json-patch/utils/toKeys.js +15 -11
- package/dist/json-patch/utils/updateArrayIndexes.d.ts +5 -2
- package/dist/json-patch/utils/updateArrayIndexes.js +33 -37
- package/dist/json-patch/utils/updateArrayPath.d.ts +5 -2
- package/dist/json-patch/utils/updateArrayPath.js +29 -42
- package/dist/net/PatchesClient.d.ts +128 -0
- package/dist/net/PatchesClient.js +161 -0
- package/dist/net/PatchesSync.d.ts +19 -9
- package/dist/net/PatchesSync.js +291 -386
- package/dist/net/error.d.ts +3 -1
- package/dist/net/error.js +9 -6
- package/dist/net/http/FetchTransport.d.ts +21 -0
- package/dist/net/http/FetchTransport.js +34 -0
- package/dist/net/index.d.ts +26 -12
- package/dist/net/index.js +12 -10
- package/dist/net/protocol/JSONRPCClient.d.ts +11 -4
- package/dist/net/protocol/JSONRPCClient.js +95 -103
- package/dist/net/protocol/JSONRPCServer.d.ts +15 -8
- package/dist/net/protocol/JSONRPCServer.js +101 -123
- package/dist/net/protocol/types.d.ts +21 -15
- package/dist/net/protocol/types.js +0 -1
- package/dist/net/protocol/utils.d.ts +12 -0
- package/dist/net/protocol/utils.js +15 -0
- package/dist/net/types.d.ts +4 -2
- package/dist/net/types.js +0 -1
- package/dist/net/webrtc/WebRTCAwareness.d.ts +14 -4
- package/dist/net/webrtc/WebRTCAwareness.js +111 -120
- package/dist/net/webrtc/WebRTCTransport.d.ts +16 -8
- package/dist/net/webrtc/WebRTCTransport.js +149 -157
- package/dist/net/webrtc/index.d.ts +10 -2
- package/dist/net/webrtc/index.js +2 -2
- package/dist/net/websocket/AuthorizationProvider.d.ts +7 -5
- package/dist/net/websocket/AuthorizationProvider.js +12 -17
- package/dist/net/websocket/PatchesWebSocket.d.ts +14 -109
- package/dist/net/websocket/PatchesWebSocket.js +37 -184
- package/dist/net/websocket/RPCServer.d.ts +19 -10
- package/dist/net/websocket/RPCServer.js +190 -192
- package/dist/net/websocket/SignalingService.d.ts +12 -32
- package/dist/net/websocket/SignalingService.js +126 -133
- package/dist/net/websocket/WebSocketServer.d.ts +17 -4
- package/dist/net/websocket/WebSocketServer.js +64 -72
- package/dist/net/websocket/WebSocketTransport.d.ts +13 -5
- package/dist/net/websocket/WebSocketTransport.js +178 -207
- package/dist/net/websocket/onlineState.d.ts +6 -3
- package/dist/net/websocket/onlineState.js +25 -21
- package/dist/server/PatchesBranchManager.d.ts +12 -5
- package/dist/server/PatchesBranchManager.js +132 -142
- package/dist/server/PatchesHistoryManager.d.ts +11 -3
- package/dist/server/PatchesHistoryManager.js +81 -84
- package/dist/server/PatchesServer.d.ts +16 -10
- package/dist/server/PatchesServer.js +131 -137
- package/dist/server/index.d.ts +7 -2
- package/dist/server/index.js +9 -3
- package/dist/server/types.d.ts +9 -3
- package/dist/server/types.js +0 -1
- package/dist/types.d.ts +49 -19
- package/dist/types.js +1 -1
- package/dist/utils/concurrency.d.ts +7 -5
- package/dist/utils/concurrency.js +43 -53
- package/dist/utils/deferred.d.ts +4 -2
- package/dist/utils/deferred.js +25 -21
- package/package.json +5 -7
|
@@ -1,151 +1,141 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
import "../chunk-IZ2YBCUP.js";
|
|
2
|
+
import { createId } from "crypto-id";
|
|
3
|
+
import { createChange } from "../data/change.js";
|
|
4
|
+
import { createVersionMetadata } from "../data/version.js";
|
|
5
|
+
class PatchesBranchManager {
|
|
6
|
+
constructor(store, patchesServer) {
|
|
7
|
+
this.store = store;
|
|
8
|
+
this.patchesServer = patchesServer;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Lists all open branches for a document.
|
|
12
|
+
* @param docId - The ID of the document.
|
|
13
|
+
* @returns The branches.
|
|
14
|
+
*/
|
|
15
|
+
async listBranches(docId) {
|
|
16
|
+
return await this.store.listBranches(docId);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Creates a new branch for a document.
|
|
20
|
+
* @param docId - The ID of the document to branch from.
|
|
21
|
+
* @param rev - The revision of the document to branch from.
|
|
22
|
+
* @param branchName - Optional name for the branch.
|
|
23
|
+
* @param metadata - Additional optional metadata to store with the branch.
|
|
24
|
+
* @returns The ID of the new branch document.
|
|
25
|
+
*/
|
|
26
|
+
async createBranch(docId, rev, metadata) {
|
|
27
|
+
const maybeBranch = await this.store.loadBranch(docId);
|
|
28
|
+
if (maybeBranch) {
|
|
29
|
+
throw new Error("Cannot create a branch from another branch.");
|
|
15
30
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
31
|
+
const stateAtRev = (await this.patchesServer.getStateAtRevision(docId, rev)).state;
|
|
32
|
+
const branchDocId = createId();
|
|
33
|
+
const now = Date.now();
|
|
34
|
+
const initialVersionMetadata = createVersionMetadata({
|
|
35
|
+
origin: "main",
|
|
36
|
+
// Branch doc versions are 'main' until merged
|
|
37
|
+
startDate: now,
|
|
38
|
+
endDate: now,
|
|
39
|
+
rev,
|
|
40
|
+
baseRev: rev,
|
|
41
|
+
name: metadata?.name,
|
|
42
|
+
groupId: branchDocId,
|
|
43
|
+
branchName: metadata?.name
|
|
44
|
+
});
|
|
45
|
+
await this.store.createVersion(branchDocId, initialVersionMetadata, stateAtRev, []);
|
|
46
|
+
const branch = {
|
|
47
|
+
...metadata,
|
|
48
|
+
id: branchDocId,
|
|
49
|
+
branchedFromId: docId,
|
|
50
|
+
branchedRev: rev,
|
|
51
|
+
created: now,
|
|
52
|
+
status: "open"
|
|
53
|
+
};
|
|
54
|
+
await this.store.createBranch(branch);
|
|
55
|
+
return branchDocId;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Updates a branch's metadata.
|
|
59
|
+
* @param branchId - The ID of the branch to update.
|
|
60
|
+
* @param metadata - The metadata to update.
|
|
61
|
+
*/
|
|
62
|
+
async updateBranch(branchId, metadata) {
|
|
63
|
+
assertBranchMetadata(metadata);
|
|
64
|
+
await this.store.updateBranch(branchId, metadata);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Closes a branch, marking it as merged or deleted.
|
|
68
|
+
* @param branchId - The ID of the branch to close.
|
|
69
|
+
* @param status - The status to set for the branch.
|
|
70
|
+
*/
|
|
71
|
+
async closeBranch(branchId, status = "closed") {
|
|
72
|
+
await this.store.updateBranch(branchId, { status });
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Merges changes from a branch back into its source document.
|
|
76
|
+
* @param branchId - The ID of the branch document to merge.
|
|
77
|
+
* @returns The server commit change(s) applied to the source document.
|
|
78
|
+
* @throws Error if branch not found, already closed/merged, or merge fails.
|
|
79
|
+
*/
|
|
80
|
+
async mergeBranch(branchId) {
|
|
81
|
+
const branch = await this.store.loadBranch(branchId);
|
|
82
|
+
if (!branch) {
|
|
83
|
+
throw new Error(`Branch with ID ${branchId} not found.`);
|
|
23
84
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
* @param docId - The ID of the document to branch from.
|
|
27
|
-
* @param rev - The revision of the document to branch from.
|
|
28
|
-
* @param branchName - Optional name for the branch.
|
|
29
|
-
* @param metadata - Additional optional metadata to store with the branch.
|
|
30
|
-
* @returns The ID of the new branch document.
|
|
31
|
-
*/
|
|
32
|
-
async createBranch(docId, rev, metadata) {
|
|
33
|
-
// Prevent branching off a branch
|
|
34
|
-
const maybeBranch = await this.store.loadBranch(docId);
|
|
35
|
-
if (maybeBranch) {
|
|
36
|
-
throw new Error('Cannot create a branch from another branch.');
|
|
37
|
-
}
|
|
38
|
-
// 1. Get the state at the branch point
|
|
39
|
-
const stateAtRev = (await this.patchesServer.getStateAtRevision(docId, rev)).state;
|
|
40
|
-
const branchDocId = createId();
|
|
41
|
-
const now = Date.now();
|
|
42
|
-
// Create an initial version at the branch point rev (for snapshotting/large docs)
|
|
43
|
-
const initialVersionMetadata = createVersionMetadata({
|
|
44
|
-
origin: 'main', // Branch doc versions are 'main' until merged
|
|
45
|
-
startDate: now,
|
|
46
|
-
endDate: now,
|
|
47
|
-
rev,
|
|
48
|
-
baseRev: rev,
|
|
49
|
-
name: metadata?.name,
|
|
50
|
-
groupId: branchDocId,
|
|
51
|
-
branchName: metadata?.name,
|
|
52
|
-
});
|
|
53
|
-
await this.store.createVersion(branchDocId, initialVersionMetadata, stateAtRev, []);
|
|
54
|
-
// 2. Create the branch metadata record
|
|
55
|
-
const branch = {
|
|
56
|
-
...metadata,
|
|
57
|
-
id: branchDocId,
|
|
58
|
-
branchedFromId: docId,
|
|
59
|
-
branchedRev: rev,
|
|
60
|
-
created: now,
|
|
61
|
-
status: 'open',
|
|
62
|
-
};
|
|
63
|
-
await this.store.createBranch(branch);
|
|
64
|
-
return branchDocId;
|
|
85
|
+
if (branch.status !== "open") {
|
|
86
|
+
throw new Error(`Branch ${branchId} is not open (status: ${branch.status}). Cannot merge.`);
|
|
65
87
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
await this.store.updateBranch(branchId, metadata);
|
|
88
|
+
const sourceDocId = branch.branchedFromId;
|
|
89
|
+
const branchStartRevOnSource = branch.branchedRev;
|
|
90
|
+
const branchChanges = await this.store.listChanges(branchId, {});
|
|
91
|
+
if (branchChanges.length === 0) {
|
|
92
|
+
console.log(`Branch ${branchId} has no changes to merge.`);
|
|
93
|
+
await this.closeBranch(branchId, "merged");
|
|
94
|
+
return [];
|
|
74
95
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
96
|
+
const branchVersions = await this.store.listVersions(branchId, { origin: "main" });
|
|
97
|
+
let lastVersionId;
|
|
98
|
+
for (const v of branchVersions) {
|
|
99
|
+
const newVersionMetadata = createVersionMetadata({
|
|
100
|
+
...v,
|
|
101
|
+
origin: "branch",
|
|
102
|
+
baseRev: branchStartRevOnSource,
|
|
103
|
+
groupId: branchId,
|
|
104
|
+
branchName: branch.name,
|
|
105
|
+
parentId: lastVersionId
|
|
106
|
+
});
|
|
107
|
+
const state = await this.store.loadVersionState(branchId, v.id);
|
|
108
|
+
const changes = await this.store.loadVersionChanges(branchId, v.id);
|
|
109
|
+
await this.store.createVersion(sourceDocId, newVersionMetadata, state, changes);
|
|
110
|
+
lastVersionId = newVersionMetadata.id;
|
|
82
111
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (branch.status !== 'open') {
|
|
96
|
-
throw new Error(`Branch ${branchId} is not open (status: ${branch.status}). Cannot merge.`);
|
|
97
|
-
}
|
|
98
|
-
const sourceDocId = branch.branchedFromId;
|
|
99
|
-
const branchStartRevOnSource = branch.branchedRev;
|
|
100
|
-
// 2. Get all committed server changes made on the branch document since it was created.
|
|
101
|
-
const branchChanges = await this.store.listChanges(branchId, {});
|
|
102
|
-
if (branchChanges.length === 0) {
|
|
103
|
-
console.log(`Branch ${branchId} has no changes to merge.`);
|
|
104
|
-
await this.closeBranch(branchId, 'merged');
|
|
105
|
-
return [];
|
|
106
|
-
}
|
|
107
|
-
// 3. Get all versions from the branch doc (skip offline versions)
|
|
108
|
-
const branchVersions = await this.store.listVersions(branchId, { origin: 'main' });
|
|
109
|
-
// 4. For each version, create a corresponding version in the main doc with updated fields
|
|
110
|
-
let lastVersionId;
|
|
111
|
-
for (const v of branchVersions) {
|
|
112
|
-
const newVersionMetadata = createVersionMetadata({
|
|
113
|
-
...v,
|
|
114
|
-
origin: 'branch',
|
|
115
|
-
baseRev: branchStartRevOnSource,
|
|
116
|
-
groupId: branchId,
|
|
117
|
-
branchName: branch.name,
|
|
118
|
-
parentId: lastVersionId,
|
|
119
|
-
});
|
|
120
|
-
const state = await this.store.loadVersionState(branchId, v.id);
|
|
121
|
-
const changes = await this.store.loadVersionChanges(branchId, v.id);
|
|
122
|
-
await this.store.createVersion(sourceDocId, newVersionMetadata, state, changes);
|
|
123
|
-
lastVersionId = newVersionMetadata.id;
|
|
124
|
-
}
|
|
125
|
-
// 5. Flatten all branch changes into a single change for the main doc
|
|
126
|
-
const rev = branchStartRevOnSource + branchChanges.length;
|
|
127
|
-
const flattenedChange = createChange(branchStartRevOnSource, rev, branchChanges.flatMap(c => c.ops));
|
|
128
|
-
// 6. Commit the flattened change to the main doc
|
|
129
|
-
let committedMergeChanges = [];
|
|
130
|
-
try {
|
|
131
|
-
[, committedMergeChanges] = await this.patchesServer.commitChanges(sourceDocId, [flattenedChange]);
|
|
132
|
-
}
|
|
133
|
-
catch (error) {
|
|
134
|
-
console.error(`Failed to merge branch ${branchId} into ${sourceDocId}:`, error);
|
|
135
|
-
throw new Error(`Merge failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
136
|
-
}
|
|
137
|
-
// 7. Merge succeeded. Update the branch status.
|
|
138
|
-
await this.closeBranch(branchId, 'merged');
|
|
139
|
-
return committedMergeChanges;
|
|
112
|
+
const rev = branchStartRevOnSource + branchChanges.length;
|
|
113
|
+
const flattenedChange = createChange(
|
|
114
|
+
branchStartRevOnSource,
|
|
115
|
+
rev,
|
|
116
|
+
branchChanges.flatMap((c) => c.ops)
|
|
117
|
+
);
|
|
118
|
+
let committedMergeChanges = [];
|
|
119
|
+
try {
|
|
120
|
+
[, committedMergeChanges] = await this.patchesServer.commitChanges(sourceDocId, [flattenedChange]);
|
|
121
|
+
} catch (error) {
|
|
122
|
+
console.error(`Failed to merge branch ${branchId} into ${sourceDocId}:`, error);
|
|
123
|
+
throw new Error(`Merge failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
140
124
|
}
|
|
125
|
+
await this.closeBranch(branchId, "merged");
|
|
126
|
+
return committedMergeChanges;
|
|
127
|
+
}
|
|
141
128
|
}
|
|
142
|
-
const nonModifiableMetadataFields = new Set([
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
throw new Error(`Cannot modify branch field ${key}`);
|
|
149
|
-
}
|
|
129
|
+
const nonModifiableMetadataFields = /* @__PURE__ */ new Set(["id", "branchedFromId", "branchedRev", "created", "status"]);
|
|
130
|
+
function assertBranchMetadata(metadata) {
|
|
131
|
+
if (!metadata) return;
|
|
132
|
+
for (const key in metadata) {
|
|
133
|
+
if (nonModifiableMetadataFields.has(key)) {
|
|
134
|
+
throw new Error(`Cannot modify branch field ${key}`);
|
|
150
135
|
}
|
|
136
|
+
}
|
|
151
137
|
}
|
|
138
|
+
export {
|
|
139
|
+
PatchesBranchManager,
|
|
140
|
+
assertBranchMetadata
|
|
141
|
+
};
|
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import { ListVersionsOptions, VersionMetadata, EditableVersionMetadata, Change, ListChangesOptions } from '../types.js';
|
|
2
|
+
import { PatchesServer } from './PatchesServer.js';
|
|
3
|
+
import '../json-patch/JSONPatch.js';
|
|
4
|
+
import '@dabble/delta';
|
|
5
|
+
import '../json-patch/types.js';
|
|
6
|
+
import '../event-signal.js';
|
|
7
|
+
import './types.js';
|
|
8
|
+
|
|
3
9
|
/**
|
|
4
10
|
* Helps retrieve historical information (versions, changes) for a document
|
|
5
11
|
* using the new versioning model based on IDs and metadata.
|
|
6
12
|
*/
|
|
7
|
-
|
|
13
|
+
declare class PatchesHistoryManager {
|
|
8
14
|
private readonly patches;
|
|
9
15
|
private readonly store;
|
|
10
16
|
constructor(patches: PatchesServer);
|
|
@@ -55,3 +61,5 @@ export declare class PatchesHistoryManager {
|
|
|
55
61
|
*/
|
|
56
62
|
listServerChanges(docId: string, options?: ListChangesOptions): Promise<Change[]>;
|
|
57
63
|
}
|
|
64
|
+
|
|
65
|
+
export { PatchesHistoryManager };
|
|
@@ -1,88 +1,85 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import "../chunk-IZ2YBCUP.js";
|
|
2
|
+
import { assertVersionMetadata } from "./PatchesServer.js";
|
|
3
|
+
class PatchesHistoryManager {
|
|
4
|
+
constructor(patches) {
|
|
5
|
+
this.patches = patches;
|
|
6
|
+
this.store = patches.store;
|
|
7
|
+
}
|
|
8
|
+
store;
|
|
9
|
+
/**
|
|
10
|
+
* Lists version metadata for the document, supporting various filters.
|
|
11
|
+
* @param docId - The ID of the document.
|
|
12
|
+
* @param options Filtering and sorting options (e.g., limit, reverse, origin, groupId, date range).
|
|
13
|
+
* @returns A list of version metadata objects.
|
|
14
|
+
*/
|
|
15
|
+
async listVersions(docId, options = {}) {
|
|
16
|
+
if (!options.orderBy) {
|
|
17
|
+
options.orderBy = "startDate";
|
|
12
18
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
return await this.store.listVersions(docId, options);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Create a new named version snapshot of a document's current state.
|
|
23
|
+
* @param docId The document ID.
|
|
24
|
+
* @param name The name of the version.
|
|
25
|
+
* @returns The ID of the created version.
|
|
26
|
+
*/
|
|
27
|
+
async createVersion(docId, metadata) {
|
|
28
|
+
assertVersionMetadata(metadata);
|
|
29
|
+
return await this.patches.captureCurrentVersion(docId, metadata);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Updates the name of a specific version.
|
|
33
|
+
* @param docId - The ID of the document.
|
|
34
|
+
* @param versionId - The ID of the version to update.
|
|
35
|
+
* @param name - The new name for the version.
|
|
36
|
+
*/
|
|
37
|
+
async updateVersion(docId, versionId, metadata) {
|
|
38
|
+
assertVersionMetadata(metadata);
|
|
39
|
+
return this.store.updateVersion(docId, versionId, metadata);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Loads the full document state snapshot for a specific version by its ID.
|
|
43
|
+
* @param docId - The ID of the document.
|
|
44
|
+
* @param versionId - The unique ID of the version.
|
|
45
|
+
* @returns The document state at that version.
|
|
46
|
+
* @throws Error if the version ID is not found or state loading fails.
|
|
47
|
+
*/
|
|
48
|
+
async getStateAtVersion(docId, versionId) {
|
|
49
|
+
try {
|
|
50
|
+
return await this.store.loadVersionState(docId, versionId);
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.error(`Failed to load state for version ${versionId} of doc ${docId}.`, error);
|
|
53
|
+
throw new Error(`Could not load state for version ${versionId}.`);
|
|
24
54
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
*/
|
|
41
|
-
async updateVersion(docId, versionId, metadata) {
|
|
42
|
-
assertVersionMetadata(metadata);
|
|
43
|
-
return this.store.updateVersion(docId, versionId, metadata);
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Loads the full document state snapshot for a specific version by its ID.
|
|
47
|
-
* @param docId - The ID of the document.
|
|
48
|
-
* @param versionId - The unique ID of the version.
|
|
49
|
-
* @returns The document state at that version.
|
|
50
|
-
* @throws Error if the version ID is not found or state loading fails.
|
|
51
|
-
*/
|
|
52
|
-
async getStateAtVersion(docId, versionId) {
|
|
53
|
-
try {
|
|
54
|
-
return await this.store.loadVersionState(docId, versionId);
|
|
55
|
-
}
|
|
56
|
-
catch (error) {
|
|
57
|
-
console.error(`Failed to load state for version ${versionId} of doc ${docId}.`, error);
|
|
58
|
-
throw new Error(`Could not load state for version ${versionId}.`);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Loads the list of original client changes that were included in a specific version.
|
|
63
|
-
* Useful for replaying/scrubbing through the operations within an offline or online session.
|
|
64
|
-
* @param docId - The ID of the document.
|
|
65
|
-
* @param versionId - The unique ID of the version.
|
|
66
|
-
* @returns An array of Change objects.
|
|
67
|
-
* @throws Error if the version ID is not found or change loading fails.
|
|
68
|
-
*/
|
|
69
|
-
async getChangesForVersion(docId, versionId) {
|
|
70
|
-
try {
|
|
71
|
-
return await this.store.loadVersionChanges(docId, versionId);
|
|
72
|
-
}
|
|
73
|
-
catch (error) {
|
|
74
|
-
console.error(`Failed to load changes for version ${versionId} of doc ${docId}.`, error);
|
|
75
|
-
throw new Error(`Could not load changes for version ${versionId}.`);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Lists committed server changes for the document, typically used for server-side processing
|
|
80
|
-
* or deep history analysis based on raw revisions.
|
|
81
|
-
* @param docId - The ID of the document.
|
|
82
|
-
* @param options - Options like start/end revision, limit.
|
|
83
|
-
* @returns The list of committed Change objects.
|
|
84
|
-
*/
|
|
85
|
-
async listServerChanges(docId, options = {}) {
|
|
86
|
-
return await this.store.listChanges(docId, options);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Loads the list of original client changes that were included in a specific version.
|
|
58
|
+
* Useful for replaying/scrubbing through the operations within an offline or online session.
|
|
59
|
+
* @param docId - The ID of the document.
|
|
60
|
+
* @param versionId - The unique ID of the version.
|
|
61
|
+
* @returns An array of Change objects.
|
|
62
|
+
* @throws Error if the version ID is not found or change loading fails.
|
|
63
|
+
*/
|
|
64
|
+
async getChangesForVersion(docId, versionId) {
|
|
65
|
+
try {
|
|
66
|
+
return await this.store.loadVersionChanges(docId, versionId);
|
|
67
|
+
} catch (error) {
|
|
68
|
+
console.error(`Failed to load changes for version ${versionId} of doc ${docId}.`, error);
|
|
69
|
+
throw new Error(`Could not load changes for version ${versionId}.`);
|
|
87
70
|
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Lists committed server changes for the document, typically used for server-side processing
|
|
74
|
+
* or deep history analysis based on raw revisions.
|
|
75
|
+
* @param docId - The ID of the document.
|
|
76
|
+
* @param options - Options like start/end revision, limit.
|
|
77
|
+
* @returns The list of committed Change objects.
|
|
78
|
+
*/
|
|
79
|
+
async listServerChanges(docId, options = {}) {
|
|
80
|
+
return await this.store.listChanges(docId, options);
|
|
81
|
+
}
|
|
88
82
|
}
|
|
83
|
+
export {
|
|
84
|
+
PatchesHistoryManager
|
|
85
|
+
};
|
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import { Signal } from '../event-signal.js';
|
|
2
|
+
import { Change, PatchesState, ChangeInput, ChangeMutator, EditableVersionMetadata } from '../types.js';
|
|
3
|
+
import { PatchesStoreBackend } from './types.js';
|
|
4
|
+
import '../json-patch/JSONPatch.js';
|
|
5
|
+
import '@dabble/delta';
|
|
6
|
+
import '../json-patch/types.js';
|
|
7
|
+
|
|
4
8
|
/**
|
|
5
9
|
* Configuration options for the PatchesServer.
|
|
6
10
|
*/
|
|
7
|
-
|
|
11
|
+
interface PatchesServerOptions {
|
|
8
12
|
/**
|
|
9
13
|
* The maximum time difference in minutes between consecutive changes
|
|
10
14
|
* to be considered part of the same editing session for versioning.
|
|
@@ -17,13 +21,13 @@ export interface PatchesServerOptions {
|
|
|
17
21
|
* coordinating batches of changes, managing versioning based on sessions (including offline),
|
|
18
22
|
* and persisting data using a backend store.
|
|
19
23
|
*/
|
|
20
|
-
|
|
24
|
+
declare class PatchesServer {
|
|
21
25
|
readonly store: PatchesStoreBackend;
|
|
22
26
|
private readonly sessionTimeoutMillis;
|
|
23
27
|
/** Notifies listeners whenever a batch of changes is *successfully* committed. */
|
|
24
|
-
readonly onChangesCommitted:
|
|
28
|
+
readonly onChangesCommitted: Signal<(docId: string, changes: Change[], originClientId?: string) => void>;
|
|
25
29
|
/** Notifies listeners when a document is deleted. */
|
|
26
|
-
readonly onDocDeleted:
|
|
30
|
+
readonly onDocDeleted: Signal<(docId: string, originClientId?: string) => void>;
|
|
27
31
|
constructor(store: PatchesStoreBackend, options?: PatchesServerOptions);
|
|
28
32
|
/**
|
|
29
33
|
* Get the state of a document at a specific revision (or the latest state if no revision is provided).
|
|
@@ -55,13 +59,13 @@ export declare class PatchesServer {
|
|
|
55
59
|
* - committedChanges: Changes that were already committed to the server after the client's base revision
|
|
56
60
|
* - transformedChanges: The client's changes after being transformed against concurrent changes
|
|
57
61
|
*/
|
|
58
|
-
commitChanges(docId: string, changes:
|
|
62
|
+
commitChanges(docId: string, changes: ChangeInput[], originClientId?: string): Promise<[Change[], Change[]]>;
|
|
59
63
|
/**
|
|
60
64
|
* Make a server-side change to a document.
|
|
61
65
|
* @param mutator
|
|
62
66
|
* @returns
|
|
63
67
|
*/
|
|
64
|
-
change<T = Record<string, any>>(docId: string, mutator:
|
|
68
|
+
change<T = Record<string, any>>(docId: string, mutator: ChangeMutator<T>, metadata?: Record<string, any>): Promise<Change | null>;
|
|
65
69
|
/**
|
|
66
70
|
* Deletes a document.
|
|
67
71
|
* @param docId The document ID.
|
|
@@ -76,4 +80,6 @@ export declare class PatchesServer {
|
|
|
76
80
|
*/
|
|
77
81
|
captureCurrentVersion(docId: string, metadata?: EditableVersionMetadata): Promise<string>;
|
|
78
82
|
}
|
|
79
|
-
|
|
83
|
+
declare function assertVersionMetadata(metadata?: EditableVersionMetadata): void;
|
|
84
|
+
|
|
85
|
+
export { PatchesServer, type PatchesServerOptions, assertVersionMetadata };
|