@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,80 +1,63 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
await store.saveChanges(docId, sessionChanges);
|
|
50
|
-
await store.updateVersion(docId, lastVersion.id, {}); // metadata already updated above
|
|
51
|
-
offlineBaseState = mergedState;
|
|
52
|
-
parentId = lastVersion.parentId;
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
// Create a new version for this session
|
|
56
|
-
offlineBaseState = applyChanges(offlineBaseState, sessionChanges);
|
|
57
|
-
const sessionMetadata = createVersionMetadata({
|
|
58
|
-
parentId,
|
|
59
|
-
groupId,
|
|
60
|
-
origin: 'offline',
|
|
61
|
-
startDate: sessionChanges[0].created,
|
|
62
|
-
endDate: sessionChanges[sessionChanges.length - 1].created,
|
|
63
|
-
rev: sessionChanges[sessionChanges.length - 1].rev,
|
|
64
|
-
baseRev,
|
|
65
|
-
});
|
|
66
|
-
await store.createVersion(docId, sessionMetadata, offlineBaseState, sessionChanges);
|
|
67
|
-
parentId = sessionMetadata.id;
|
|
68
|
-
}
|
|
69
|
-
sessionStartIndex = i;
|
|
70
|
-
}
|
|
1
|
+
import "../../chunk-IZ2YBCUP.js";
|
|
2
|
+
import { createSortableId } from "crypto-id";
|
|
3
|
+
import { createVersionMetadata } from "../../data/version.js";
|
|
4
|
+
import { applyChanges } from "../shared/applyChanges.js";
|
|
5
|
+
import { getStateAtRevision } from "./getStateAtRevision.js";
|
|
6
|
+
async function handleOfflineSessionsAndBatches(store, sessionTimeoutMillis, docId, changes, baseRev, batchId) {
|
|
7
|
+
const groupId = batchId ?? createSortableId();
|
|
8
|
+
const [lastVersion] = await store.listVersions(docId, {
|
|
9
|
+
groupId,
|
|
10
|
+
reverse: true,
|
|
11
|
+
limit: 1
|
|
12
|
+
});
|
|
13
|
+
let offlineBaseState;
|
|
14
|
+
let parentId;
|
|
15
|
+
if (lastVersion) {
|
|
16
|
+
const vs = await store.loadVersionState(docId, lastVersion.id);
|
|
17
|
+
offlineBaseState = vs.state ?? vs;
|
|
18
|
+
parentId = lastVersion.id;
|
|
19
|
+
} else {
|
|
20
|
+
offlineBaseState = (await getStateAtRevision(store, docId, baseRev)).state;
|
|
21
|
+
}
|
|
22
|
+
let sessionStartIndex = 0;
|
|
23
|
+
for (let i = 1; i <= changes.length; i++) {
|
|
24
|
+
const isLastChange = i === changes.length;
|
|
25
|
+
const timeDiff = isLastChange ? Infinity : changes[i].created - changes[i - 1].created;
|
|
26
|
+
if (timeDiff > sessionTimeoutMillis || isLastChange) {
|
|
27
|
+
const sessionChanges = changes.slice(sessionStartIndex, i);
|
|
28
|
+
if (sessionChanges.length > 0) {
|
|
29
|
+
const isContinuation = !!lastVersion && sessionChanges[0].created - lastVersion.endDate <= sessionTimeoutMillis;
|
|
30
|
+
if (isContinuation) {
|
|
31
|
+
const mergedState = applyChanges(offlineBaseState, sessionChanges);
|
|
32
|
+
await store.saveChanges(docId, sessionChanges);
|
|
33
|
+
await store.updateVersion(docId, lastVersion.id, {});
|
|
34
|
+
offlineBaseState = mergedState;
|
|
35
|
+
parentId = lastVersion.parentId;
|
|
36
|
+
} else {
|
|
37
|
+
offlineBaseState = applyChanges(offlineBaseState, sessionChanges);
|
|
38
|
+
const sessionMetadata = createVersionMetadata({
|
|
39
|
+
parentId,
|
|
40
|
+
groupId,
|
|
41
|
+
origin: "offline",
|
|
42
|
+
startDate: sessionChanges[0].created,
|
|
43
|
+
endDate: sessionChanges[sessionChanges.length - 1].created,
|
|
44
|
+
rev: sessionChanges[sessionChanges.length - 1].rev,
|
|
45
|
+
baseRev
|
|
46
|
+
});
|
|
47
|
+
await store.createVersion(docId, sessionMetadata, offlineBaseState, sessionChanges);
|
|
48
|
+
parentId = sessionMetadata.id;
|
|
71
49
|
}
|
|
50
|
+
sessionStartIndex = i;
|
|
51
|
+
}
|
|
72
52
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
53
|
+
}
|
|
54
|
+
return [
|
|
55
|
+
changes.reduce((firstChange, nextChange) => {
|
|
56
|
+
firstChange.ops = [...firstChange.ops, ...nextChange.ops];
|
|
57
|
+
return firstChange;
|
|
58
|
+
})
|
|
59
|
+
];
|
|
80
60
|
}
|
|
61
|
+
export {
|
|
62
|
+
handleOfflineSessionsAndBatches
|
|
63
|
+
};
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Change } from '../../types.js';
|
|
2
|
+
import '../../json-patch/JSONPatch.js';
|
|
3
|
+
import '@dabble/delta';
|
|
4
|
+
import '../../json-patch/types.js';
|
|
5
|
+
|
|
2
6
|
/**
|
|
3
7
|
* Transforms incoming changes against committed changes that happened *after* the client's baseRev.
|
|
4
8
|
* The state used for transformation should be the server state *at the client's baseRev*.
|
|
@@ -8,4 +12,6 @@ import type { Change } from '../../types.js';
|
|
|
8
12
|
* @param currentRev The current/latest revision number (these changes will have their `rev` set > `currentRev`).
|
|
9
13
|
* @returns The transformed changes.
|
|
10
14
|
*/
|
|
11
|
-
|
|
15
|
+
declare function transformIncomingChanges(changes: Change[], stateAtBaseRev: any, committedChanges: Change[], currentRev: number): Change[];
|
|
16
|
+
|
|
17
|
+
export { transformIncomingChanges };
|
|
@@ -1,40 +1,28 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const previous = state;
|
|
26
|
-
state = applyPatch(state, transformedOps, { strict: true });
|
|
27
|
-
if (previous === state) {
|
|
28
|
-
// Changes were no-ops, we can skip this change
|
|
29
|
-
return null;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
catch (error) {
|
|
33
|
-
console.error(`Error applying change ${change.id} to state:`, error);
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
// Return a new change object with transformed ops and original metadata
|
|
37
|
-
return { ...change, rev: rev++, ops: transformedOps };
|
|
38
|
-
})
|
|
39
|
-
.filter(Boolean);
|
|
1
|
+
import "../../chunk-IZ2YBCUP.js";
|
|
2
|
+
import { applyPatch } from "../../json-patch/applyPatch.js";
|
|
3
|
+
import { transformPatch } from "../../json-patch/transformPatch.js";
|
|
4
|
+
function transformIncomingChanges(changes, stateAtBaseRev, committedChanges, currentRev) {
|
|
5
|
+
const committedOps = committedChanges.flatMap((c) => c.ops);
|
|
6
|
+
let state = stateAtBaseRev;
|
|
7
|
+
let rev = currentRev + 1;
|
|
8
|
+
return changes.map((change) => {
|
|
9
|
+
const transformedOps = transformPatch(stateAtBaseRev, committedOps, change.ops);
|
|
10
|
+
if (transformedOps.length === 0) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
try {
|
|
14
|
+
const previous = state;
|
|
15
|
+
state = applyPatch(state, transformedOps, { strict: true });
|
|
16
|
+
if (previous === state) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
} catch (error) {
|
|
20
|
+
console.error(`Error applying change ${change.id} to state:`, error);
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
return { ...change, rev: rev++, ops: transformedOps };
|
|
24
|
+
}).filter(Boolean);
|
|
40
25
|
}
|
|
26
|
+
export {
|
|
27
|
+
transformIncomingChanges
|
|
28
|
+
};
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Change } from '../../types.js';
|
|
2
|
+
import '../../json-patch/JSONPatch.js';
|
|
3
|
+
import '@dabble/delta';
|
|
4
|
+
import '../../json-patch/types.js';
|
|
5
|
+
|
|
2
6
|
/**
|
|
3
7
|
* Applies a sequence of changes to a state object.
|
|
4
8
|
* Each change is applied in sequence using the applyPatch function.
|
|
@@ -7,4 +11,6 @@ import type { Change } from '../../types.js';
|
|
|
7
11
|
* @param changes - Array of changes to apply
|
|
8
12
|
* @returns The state after all changes have been applied
|
|
9
13
|
*/
|
|
10
|
-
|
|
14
|
+
declare function applyChanges<T>(state: T, changes: Change[]): T;
|
|
15
|
+
|
|
16
|
+
export { applyChanges };
|
|
@@ -1,17 +1,12 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
*/
|
|
10
|
-
export function applyChanges(state, changes) {
|
|
11
|
-
if (!changes.length)
|
|
12
|
-
return state;
|
|
13
|
-
for (const change of changes) {
|
|
14
|
-
state = applyPatch(state, change.ops, { strict: true });
|
|
15
|
-
}
|
|
16
|
-
return state;
|
|
1
|
+
import "../../chunk-IZ2YBCUP.js";
|
|
2
|
+
import { applyPatch } from "../../json-patch/applyPatch.js";
|
|
3
|
+
function applyChanges(state, changes) {
|
|
4
|
+
if (!changes.length) return state;
|
|
5
|
+
for (const change of changes) {
|
|
6
|
+
state = applyPatch(state, change.ops, { strict: true });
|
|
7
|
+
}
|
|
8
|
+
return state;
|
|
17
9
|
}
|
|
10
|
+
export {
|
|
11
|
+
applyChanges
|
|
12
|
+
};
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { Change } from '../../types.js';
|
|
2
|
+
import '../../json-patch/JSONPatch.js';
|
|
3
|
+
import '@dabble/delta';
|
|
4
|
+
import '../../json-patch/types.js';
|
|
5
|
+
|
|
2
6
|
/**
|
|
3
7
|
* Rebases local changes against server changes using operational transformation.
|
|
4
8
|
* This function handles the transformation of local changes to be compatible with server changes
|
|
@@ -14,4 +18,6 @@ import type { Change } from '../../types.js';
|
|
|
14
18
|
* @param localChanges - Array of local changes that need to be rebased
|
|
15
19
|
* @returns Array of rebased local changes with updated revision numbers
|
|
16
20
|
*/
|
|
17
|
-
|
|
21
|
+
declare function rebaseChanges(serverChanges: Change[], localChanges: Change[]): Change[];
|
|
22
|
+
|
|
23
|
+
export { rebaseChanges };
|
|
@@ -1,51 +1,32 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
*/
|
|
17
|
-
export function rebaseChanges(serverChanges, localChanges) {
|
|
18
|
-
if (!serverChanges.length || !localChanges.length) {
|
|
19
|
-
return localChanges;
|
|
1
|
+
import "../../chunk-IZ2YBCUP.js";
|
|
2
|
+
import { JSONPatch } from "../../json-patch/JSONPatch.js";
|
|
3
|
+
function rebaseChanges(serverChanges, localChanges) {
|
|
4
|
+
if (!serverChanges.length || !localChanges.length) {
|
|
5
|
+
return localChanges;
|
|
6
|
+
}
|
|
7
|
+
const lastChange = serverChanges[serverChanges.length - 1];
|
|
8
|
+
const receivedIds = new Set(serverChanges.map((change) => change.id));
|
|
9
|
+
const transformAgainstIds = new Set(receivedIds);
|
|
10
|
+
const filteredLocalChanges = [];
|
|
11
|
+
for (const change of localChanges) {
|
|
12
|
+
if (receivedIds.has(change.id)) {
|
|
13
|
+
transformAgainstIds.delete(change.id);
|
|
14
|
+
} else {
|
|
15
|
+
filteredLocalChanges.push(change);
|
|
20
16
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
// Create a patch from server changes that need to be transformed against
|
|
35
|
-
const transformPatch = new JSONPatch(serverChanges
|
|
36
|
-
.filter(change => transformAgainstIds.has(change.id))
|
|
37
|
-
.map(change => change.ops)
|
|
38
|
-
.flat());
|
|
39
|
-
// Rebase local changes against server changes
|
|
40
|
-
const baseRev = lastChange.rev;
|
|
41
|
-
let rev = lastChange.rev;
|
|
42
|
-
return filteredLocalChanges
|
|
43
|
-
.map(change => {
|
|
44
|
-
rev++;
|
|
45
|
-
const ops = transformPatch.transform(change.ops).ops;
|
|
46
|
-
if (!ops.length)
|
|
47
|
-
return null;
|
|
48
|
-
return { ...change, baseRev, rev, ops };
|
|
49
|
-
})
|
|
50
|
-
.filter(Boolean);
|
|
17
|
+
}
|
|
18
|
+
const transformPatch = new JSONPatch(
|
|
19
|
+
serverChanges.filter((change) => transformAgainstIds.has(change.id)).map((change) => change.ops).flat()
|
|
20
|
+
);
|
|
21
|
+
const baseRev = lastChange.rev;
|
|
22
|
+
let rev = lastChange.rev;
|
|
23
|
+
return filteredLocalChanges.map((change) => {
|
|
24
|
+
rev++;
|
|
25
|
+
const ops = transformPatch.transform(change.ops).ops;
|
|
26
|
+
if (!ops.length) return null;
|
|
27
|
+
return { ...change, baseRev, rev, ops };
|
|
28
|
+
}).filter(Boolean);
|
|
51
29
|
}
|
|
30
|
+
export {
|
|
31
|
+
rebaseChanges
|
|
32
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name);
|
|
5
|
+
var __typeError = (msg) => {
|
|
6
|
+
throw TypeError(msg);
|
|
7
|
+
};
|
|
8
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
9
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
10
|
+
var __decoratorStart = (base) => [, , , __create(base?.[__knownSymbol("metadata")] ?? null)];
|
|
11
|
+
var __decoratorStrings = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"];
|
|
12
|
+
var __expectFn = (fn) => fn !== void 0 && typeof fn !== "function" ? __typeError("Function expected") : fn;
|
|
13
|
+
var __decoratorContext = (kind, name, done, metadata, fns) => ({ kind: __decoratorStrings[kind], name, metadata, addInitializer: (fn) => done._ ? __typeError("Already initialized") : fns.push(__expectFn(fn || null)) });
|
|
14
|
+
var __decoratorMetadata = (array, target) => __defNormalProp(target, __knownSymbol("metadata"), array[3]);
|
|
15
|
+
var __runInitializers = (array, flags, self, value) => {
|
|
16
|
+
for (var i = 0, fns = array[flags >> 1], n = fns && fns.length; i < n; i++) flags & 1 ? fns[i].call(self) : value = fns[i].call(self, value);
|
|
17
|
+
return value;
|
|
18
|
+
};
|
|
19
|
+
var __decorateElement = (array, flags, name, decorators, target, extra) => {
|
|
20
|
+
var fn, it, done, ctx, access, k = flags & 7, s = !!(flags & 8), p = !!(flags & 16);
|
|
21
|
+
var j = k > 3 ? array.length + 1 : k ? s ? 1 : 2 : 0, key = __decoratorStrings[k + 5];
|
|
22
|
+
var initializers = k > 3 && (array[j - 1] = []), extraInitializers = array[j] || (array[j] = []);
|
|
23
|
+
var desc = k && (!p && !s && (target = target.prototype), k < 5 && (k > 3 || !p) && __getOwnPropDesc(k < 4 ? target : { get [name]() {
|
|
24
|
+
return __privateGet(this, extra);
|
|
25
|
+
}, set [name](x) {
|
|
26
|
+
return __privateSet(this, extra, x);
|
|
27
|
+
} }, name));
|
|
28
|
+
k ? p && k < 4 && __name(extra, (k > 2 ? "set " : k > 1 ? "get " : "") + name) : __name(target, name);
|
|
29
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
30
|
+
ctx = __decoratorContext(k, name, done = {}, array[3], extraInitializers);
|
|
31
|
+
if (k) {
|
|
32
|
+
ctx.static = s, ctx.private = p, access = ctx.access = { has: p ? (x) => __privateIn(target, x) : (x) => name in x };
|
|
33
|
+
if (k ^ 3) access.get = p ? (x) => (k ^ 1 ? __privateGet : __privateMethod)(x, target, k ^ 4 ? extra : desc.get) : (x) => x[name];
|
|
34
|
+
if (k > 2) access.set = p ? (x, y) => __privateSet(x, target, y, k ^ 4 ? extra : desc.set) : (x, y) => x[name] = y;
|
|
35
|
+
}
|
|
36
|
+
it = (0, decorators[i])(k ? k < 4 ? p ? extra : desc[key] : k > 4 ? void 0 : { get: desc.get, set: desc.set } : target, ctx), done._ = 1;
|
|
37
|
+
if (k ^ 4 || it === void 0) __expectFn(it) && (k > 4 ? initializers.unshift(it) : k ? p ? extra = it : desc[key] = it : target = it);
|
|
38
|
+
else if (typeof it !== "object" || it === null) __typeError("Object expected");
|
|
39
|
+
else __expectFn(fn = it.get) && (desc.get = fn), __expectFn(fn = it.set) && (desc.set = fn), __expectFn(fn = it.init) && initializers.unshift(fn);
|
|
40
|
+
}
|
|
41
|
+
return k || __decoratorMetadata(array, target), desc && __defProp(target, name, desc), p ? k ^ 4 ? extra : desc : target;
|
|
42
|
+
};
|
|
43
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
44
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
45
|
+
var __privateIn = (member, obj) => Object(obj) !== obj ? __typeError('Cannot use the "in" operator on this value') : member.has(obj);
|
|
46
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
47
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
|
|
48
|
+
var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
|
|
49
|
+
|
|
50
|
+
export {
|
|
51
|
+
__decoratorStart,
|
|
52
|
+
__decoratorMetadata,
|
|
53
|
+
__runInitializers,
|
|
54
|
+
__decorateElement,
|
|
55
|
+
__publicField
|
|
56
|
+
};
|
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import { PatchesSnapshot, Change, PatchesState } from '../types.js';
|
|
2
|
+
import { PatchesStore, TrackedDoc } from './PatchesStore.js';
|
|
3
|
+
import '../json-patch/JSONPatch.js';
|
|
4
|
+
import '@dabble/delta';
|
|
5
|
+
import '../json-patch/types.js';
|
|
6
|
+
|
|
3
7
|
/**
|
|
4
8
|
* A trivial in‑memory implementation of OfflineStore (soon PatchesStore).
|
|
5
9
|
* All data lives in JS objects – nothing survives a page reload.
|
|
6
10
|
* Useful for unit tests or when you want the old 'stateless realtime' behaviour.
|
|
7
11
|
*/
|
|
8
|
-
|
|
12
|
+
declare class InMemoryStore implements PatchesStore {
|
|
9
13
|
private docs;
|
|
10
14
|
getDoc(docId: string): Promise<PatchesSnapshot | undefined>;
|
|
11
15
|
getPendingChanges(docId: string): Promise<Change[]>;
|
|
@@ -21,3 +25,5 @@ export declare class InMemoryStore implements PatchesStore {
|
|
|
21
25
|
confirmDeleteDoc(docId: string): Promise<void>;
|
|
22
26
|
close(): Promise<void>;
|
|
23
27
|
}
|
|
28
|
+
|
|
29
|
+
export { InMemoryStore };
|