@dabble/patches 0.5.22 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/README.md +221 -208
  2. package/dist/BaseDoc-DkP3tUhT.d.ts +206 -0
  3. package/dist/algorithms/client/applyCommittedChanges.d.ts +7 -0
  4. package/dist/algorithms/client/applyCommittedChanges.js +6 -3
  5. package/dist/algorithms/lww/consolidateOps.d.ts +40 -0
  6. package/dist/algorithms/lww/consolidateOps.js +103 -0
  7. package/dist/algorithms/lww/index.d.ts +2 -0
  8. package/dist/algorithms/lww/index.js +1 -0
  9. package/dist/algorithms/lww/mergeServerWithLocal.d.ts +22 -0
  10. package/dist/algorithms/lww/mergeServerWithLocal.js +32 -0
  11. package/dist/algorithms/server/commitChanges.d.ts +32 -8
  12. package/dist/algorithms/server/commitChanges.js +24 -10
  13. package/dist/algorithms/server/createVersion.d.ts +1 -1
  14. package/dist/algorithms/server/createVersion.js +2 -4
  15. package/dist/algorithms/server/getSnapshotAtRevision.d.ts +1 -1
  16. package/dist/algorithms/server/getStateAtRevision.d.ts +1 -1
  17. package/dist/algorithms/server/handleOfflineSessionsAndBatches.d.ts +1 -1
  18. package/dist/algorithms/server/handleOfflineSessionsAndBatches.js +5 -7
  19. package/dist/client/BaseDoc.d.ts +6 -0
  20. package/dist/client/BaseDoc.js +70 -0
  21. package/dist/client/ClientAlgorithm.d.ts +101 -0
  22. package/dist/client/ClientAlgorithm.js +0 -0
  23. package/dist/client/InMemoryStore.d.ts +5 -7
  24. package/dist/client/InMemoryStore.js +6 -35
  25. package/dist/client/IndexedDBStore.d.ts +39 -73
  26. package/dist/client/IndexedDBStore.js +17 -220
  27. package/dist/client/LWWAlgorithm.d.ts +43 -0
  28. package/dist/client/LWWAlgorithm.js +87 -0
  29. package/dist/client/LWWClientStore.d.ts +73 -0
  30. package/dist/client/LWWClientStore.js +0 -0
  31. package/dist/client/LWWDoc.d.ts +56 -0
  32. package/dist/client/LWWDoc.js +84 -0
  33. package/dist/client/LWWInMemoryStore.d.ts +88 -0
  34. package/dist/client/LWWInMemoryStore.js +208 -0
  35. package/dist/client/LWWIndexedDBStore.d.ts +91 -0
  36. package/dist/client/LWWIndexedDBStore.js +275 -0
  37. package/dist/client/OTAlgorithm.d.ts +42 -0
  38. package/dist/client/OTAlgorithm.js +113 -0
  39. package/dist/client/OTClientStore.d.ts +50 -0
  40. package/dist/client/OTClientStore.js +0 -0
  41. package/dist/client/OTDoc.d.ts +6 -0
  42. package/dist/client/OTDoc.js +97 -0
  43. package/dist/client/OTIndexedDBStore.d.ts +84 -0
  44. package/dist/client/OTIndexedDBStore.js +163 -0
  45. package/dist/client/Patches.d.ts +36 -16
  46. package/dist/client/Patches.js +60 -27
  47. package/dist/client/PatchesDoc.d.ts +4 -113
  48. package/dist/client/PatchesDoc.js +3 -153
  49. package/dist/client/PatchesStore.d.ts +8 -105
  50. package/dist/client/factories.d.ts +72 -0
  51. package/dist/client/factories.js +80 -0
  52. package/dist/client/index.d.ts +14 -5
  53. package/dist/client/index.js +9 -0
  54. package/dist/compression/index.d.ts +1 -1
  55. package/dist/data/change.js +4 -3
  56. package/dist/fractionalIndex.d.ts +67 -0
  57. package/dist/fractionalIndex.js +241 -0
  58. package/dist/index.d.ts +13 -4
  59. package/dist/index.js +1 -1
  60. package/dist/json-patch/types.d.ts +2 -0
  61. package/dist/net/PatchesClient.js +15 -15
  62. package/dist/net/PatchesSync.d.ts +24 -12
  63. package/dist/net/PatchesSync.js +56 -64
  64. package/dist/net/index.d.ts +6 -10
  65. package/dist/net/index.js +6 -1
  66. package/dist/net/protocol/JSONRPCClient.d.ts +4 -4
  67. package/dist/net/protocol/JSONRPCClient.js +6 -4
  68. package/dist/net/protocol/JSONRPCServer.d.ts +45 -9
  69. package/dist/net/protocol/JSONRPCServer.js +63 -8
  70. package/dist/net/serverContext.d.ts +38 -0
  71. package/dist/net/serverContext.js +20 -0
  72. package/dist/net/webrtc/WebRTCTransport.js +1 -1
  73. package/dist/net/websocket/AuthorizationProvider.d.ts +3 -3
  74. package/dist/net/websocket/WebSocketServer.d.ts +29 -20
  75. package/dist/net/websocket/WebSocketServer.js +23 -12
  76. package/dist/server/BranchManager.d.ts +50 -0
  77. package/dist/server/BranchManager.js +0 -0
  78. package/dist/server/CompressedStoreBackend.d.ts +8 -6
  79. package/dist/server/CompressedStoreBackend.js +3 -9
  80. package/dist/server/LWWBranchManager.d.ts +82 -0
  81. package/dist/server/LWWBranchManager.js +99 -0
  82. package/dist/server/LWWMemoryStoreBackend.d.ts +78 -0
  83. package/dist/server/LWWMemoryStoreBackend.js +191 -0
  84. package/dist/server/LWWServer.d.ts +130 -0
  85. package/dist/server/LWWServer.js +207 -0
  86. package/dist/server/{PatchesBranchManager.d.ts → OTBranchManager.d.ts} +32 -12
  87. package/dist/server/{PatchesBranchManager.js → OTBranchManager.js} +26 -42
  88. package/dist/server/OTServer.d.ts +108 -0
  89. package/dist/server/OTServer.js +141 -0
  90. package/dist/server/PatchesHistoryManager.d.ts +20 -7
  91. package/dist/server/PatchesHistoryManager.js +26 -3
  92. package/dist/server/PatchesServer.d.ts +70 -81
  93. package/dist/server/PatchesServer.js +0 -176
  94. package/dist/server/branchUtils.d.ts +82 -0
  95. package/dist/server/branchUtils.js +66 -0
  96. package/dist/server/index.d.ts +17 -6
  97. package/dist/server/index.js +33 -4
  98. package/dist/server/tombstone.d.ts +29 -0
  99. package/dist/server/tombstone.js +32 -0
  100. package/dist/server/types.d.ts +129 -27
  101. package/dist/server/utils.d.ts +12 -0
  102. package/dist/server/utils.js +23 -0
  103. package/dist/solid/context.d.ts +5 -4
  104. package/dist/solid/doc-manager.d.ts +3 -3
  105. package/dist/solid/index.d.ts +5 -4
  106. package/dist/solid/primitives.d.ts +2 -3
  107. package/dist/types.d.ts +16 -14
  108. package/dist/vue/composables.d.ts +2 -3
  109. package/dist/vue/doc-manager.d.ts +3 -3
  110. package/dist/vue/index.d.ts +5 -4
  111. package/dist/vue/provider.d.ts +5 -4
  112. package/package.json +1 -1
  113. package/dist/algorithms/client/collapsePendingChanges.d.ts +0 -30
  114. package/dist/algorithms/client/collapsePendingChanges.js +0 -78
  115. package/dist/net/websocket/RPCServer.d.ts +0 -141
  116. package/dist/net/websocket/RPCServer.js +0 -204
  117. package/dist/utils/dates.d.ts +0 -43
  118. package/dist/utils/dates.js +0 -47
@@ -1,204 +0,0 @@
1
- import "../../chunk-IZ2YBCUP.js";
2
- import { StatusError } from "../error.js";
3
- import { JSONRPCServer } from "../protocol/JSONRPCServer.js";
4
- import { denyAll } from "./AuthorizationProvider.js";
5
- class RPCServer {
6
- rpc;
7
- auth;
8
- patches;
9
- history;
10
- branches;
11
- /**
12
- * Creates a new Patches WebSocket client instance.
13
- * @param patches - The patches server instance to handle document operations
14
- * @param history - (Optional) History manager instance to handle versioning operations
15
- * @param branches - (Optional) Branch manager instance to handle branching operations
16
- * @param auth - (Optional) Authorization provider implementation. Defaults to deny-all for security.
17
- */
18
- constructor({ patches, history, branches, auth = denyAll }) {
19
- this.rpc = new JSONRPCServer();
20
- this.patches = patches;
21
- this.history = history;
22
- this.branches = branches;
23
- this.auth = auth;
24
- this.rpc.registerMethod("getDoc", this.getDoc.bind(this));
25
- this.rpc.registerMethod("getChangesSince", this.getChangesSince.bind(this));
26
- this.rpc.registerMethod("commitChanges", this.commitChanges.bind(this));
27
- this.rpc.registerMethod("deleteDoc", this.deleteDoc.bind(this));
28
- this.rpc.registerMethod("undeleteDoc", this.undeleteDoc.bind(this));
29
- if (this.history) {
30
- this.rpc.registerMethod("listVersions", this.listVersions.bind(this));
31
- this.rpc.registerMethod("createVersion", this.createVersion.bind(this));
32
- this.rpc.registerMethod("updateVersion", this.updateVersion.bind(this));
33
- this.rpc.registerMethod("getVersionState", this.getVersionState.bind(this));
34
- this.rpc.registerMethod("getVersionChanges", this.getVersionChanges.bind(this));
35
- this.rpc.registerMethod("listServerChanges", this.listServerChanges.bind(this));
36
- }
37
- if (this.branches) {
38
- this.rpc.registerMethod("listBranches", this.listBranches.bind(this));
39
- this.rpc.registerMethod("createBranch", this.createBranch.bind(this));
40
- this.rpc.registerMethod("closeBranch", this.closeBranch.bind(this));
41
- this.rpc.registerMethod("mergeBranch", this.mergeBranch.bind(this));
42
- }
43
- this.patches.onChangesCommitted((docId, changes, originClientId) => {
44
- this.rpc.notify("changesCommitted", { docId, changes }, originClientId);
45
- });
46
- this.patches.onDocDeleted((docId, options, originClientId) => {
47
- this.rpc.notify("docDeleted", { docId }, originClientId);
48
- });
49
- }
50
- /**
51
- * Gets the latest state (content and revision) of a document.
52
- * @param connectionId - The ID of the connection making the request
53
- * @param params - The document parameters
54
- * @param params.docId - The ID of the document
55
- * @param params.atRev - Optional revision number to get document state at
56
- */
57
- async getDoc(params, ctx) {
58
- const { docId, atRev } = params;
59
- await this.assertRead(ctx, docId, "getDoc", params);
60
- return this.patches.getDoc(docId, atRev);
61
- }
62
- /**
63
- * Gets changes that occurred for a document after a specific revision number.
64
- * @param connectionId - The ID of the connection making the request
65
- * @param params - The change request parameters
66
- * @param params.docId - The ID of the document
67
- * @param params.rev - The revision number after which to fetch changes
68
- */
69
- async getChangesSince(params, ctx) {
70
- const { docId, rev } = params;
71
- await this.assertRead(ctx, docId, "getChangesSince", params);
72
- return this.patches.getChangesSince(docId, rev);
73
- }
74
- /**
75
- * Applies a set of client-generated changes to a document on the server.
76
- * @param connectionId - The ID of the connection making the request
77
- * @param params - The change parameters
78
- * @param params.docId - The ID of the document
79
- * @param params.changes - An array of changes to apply
80
- * @param params.options - Optional commit settings (e.g., forceCommit for migrations)
81
- */
82
- async commitChanges(params, ctx) {
83
- const { docId, changes, options } = params;
84
- await this.assertWrite(ctx, docId, "commitChanges", params);
85
- const [priorChanges, newChanges] = await this.patches.commitChanges(docId, changes, options, ctx?.clientId);
86
- return [...priorChanges, ...newChanges];
87
- }
88
- /**
89
- * Deletes a document on the server.
90
- * @param connectionId - The ID of the connection making the request
91
- * @param params - The deletion parameters
92
- * @param params.docId - The ID of the document to delete
93
- * @param params.options - Optional deletion settings (e.g., skipTombstone)
94
- */
95
- async deleteDoc(params, ctx) {
96
- const { docId, options } = params;
97
- await this.assertWrite(ctx, docId, "deleteDoc", params);
98
- await this.patches.deleteDoc(docId, options, ctx?.clientId);
99
- }
100
- /**
101
- * Removes the tombstone for a deleted document, allowing it to be recreated.
102
- * @param params - The undelete parameters
103
- * @param params.docId - The ID of the document to undelete
104
- */
105
- async undeleteDoc(params, ctx) {
106
- const { docId } = params;
107
- await this.assertWrite(ctx, docId, "undeleteDoc", params);
108
- return this.patches.undeleteDoc(docId);
109
- }
110
- // ---------------------------------------------------------------------------
111
- // History Manager wrappers
112
- // ---------------------------------------------------------------------------
113
- async listVersions(params, ctx) {
114
- this.assertHistoryEnabled();
115
- const { docId, options } = params;
116
- await this.assertRead(ctx, docId, "listVersions", params);
117
- return this.history.listVersions(docId, options ?? {});
118
- }
119
- async createVersion(params, ctx) {
120
- this.assertHistoryEnabled();
121
- const { docId, metadata } = params;
122
- await this.assertWrite(ctx, docId, "createVersion", params);
123
- return this.history.createVersion(docId, metadata);
124
- }
125
- async updateVersion(params, ctx) {
126
- this.assertHistoryEnabled();
127
- const { docId, versionId, metadata } = params;
128
- await this.assertWrite(ctx, docId, "updateVersion", params);
129
- return this.history.updateVersion(docId, versionId, metadata);
130
- }
131
- async getVersionState(params, ctx) {
132
- this.assertHistoryEnabled();
133
- const { docId, versionId } = params;
134
- await this.assertRead(ctx, docId, "getStateAtVersion", params);
135
- return this.history.getStateAtVersion(docId, versionId);
136
- }
137
- async getVersionChanges(params, ctx) {
138
- this.assertHistoryEnabled();
139
- const { docId, versionId } = params;
140
- await this.assertRead(ctx, docId, "getChangesForVersion", params);
141
- return this.history.getChangesForVersion(docId, versionId);
142
- }
143
- async listServerChanges(params, ctx) {
144
- this.assertHistoryEnabled();
145
- const { docId, options } = params;
146
- await this.assertRead(ctx, docId, "listServerChanges", params);
147
- return this.history.listServerChanges(docId, options ?? {});
148
- }
149
- // ---------------------------------------------------------------------------
150
- // Branch Manager wrappers
151
- // ---------------------------------------------------------------------------
152
- async listBranches(params, ctx) {
153
- this.assertBranchingEnabled();
154
- const { docId } = params;
155
- await this.assertRead(ctx, docId, "listBranches", params);
156
- return this.branches.listBranches(docId);
157
- }
158
- async createBranch(params, ctx) {
159
- this.assertBranchingEnabled();
160
- const { docId, rev, metadata } = params;
161
- await this.assertWrite(ctx, docId, "createBranch", params);
162
- return this.branches.createBranch(docId, rev, metadata);
163
- }
164
- async closeBranch(params, ctx) {
165
- this.assertBranchingEnabled();
166
- const { branchId } = params;
167
- await this.assertWrite(ctx, branchId, "closeBranch", params);
168
- return this.branches.closeBranch(branchId, "closed");
169
- }
170
- async mergeBranch(params, ctx) {
171
- this.assertBranchingEnabled();
172
- const { branchId } = params;
173
- await this.assertWrite(ctx, branchId, "mergeBranch", params);
174
- return this.branches.mergeBranch(branchId);
175
- }
176
- // ---------------------------------------------------------------------------
177
- // Authorization helpers
178
- // ---------------------------------------------------------------------------
179
- async assertAccess(ctx, docId, kind, method, params) {
180
- const ok = await this.auth.canAccess(ctx, docId, kind, method, params);
181
- if (!ok) {
182
- throw new StatusError(401, `${kind.toUpperCase()}_FORBIDDEN:${docId}`);
183
- }
184
- }
185
- assertRead(ctx, docId, method, params) {
186
- return this.assertAccess(ctx, docId, "read", method, params);
187
- }
188
- assertWrite(ctx, docId, method, params) {
189
- return this.assertAccess(ctx, docId, "write", method, params);
190
- }
191
- assertHistoryEnabled() {
192
- if (!this.history) {
193
- throw new StatusError(404, "History is not enabled");
194
- }
195
- }
196
- assertBranchingEnabled() {
197
- if (!this.branches) {
198
- throw new StatusError(404, "Branching is not enabled");
199
- }
200
- }
201
- }
202
- export {
203
- RPCServer
204
- };
@@ -1,43 +0,0 @@
1
- /**
2
- * Date utility functions for creating and manipulating ISO 8601 timestamps.
3
- *
4
- * Client-side timestamps use local timezone offsets (e.g., +04:00).
5
- * Server-side timestamps use UTC with Z suffix.
6
- */
7
- /**
8
- * Converts a Date or ISO string to UTC format without milliseconds.
9
- * Example: "2025-12-26T10:00:00Z"
10
- */
11
- declare function getISO(date?: Date | string): string;
12
- /**
13
- * Formats a Date with a specific timezone offset string.
14
- * The date is adjusted to display the correct local time for that offset.
15
- */
16
- declare function getLocalISO(date?: Date | string, offset?: string): string;
17
- /**
18
- * Calculates milliseconds between two ISO timestamps.
19
- * Returns (a - b) in milliseconds.
20
- */
21
- declare function timestampDiff(a: string, b: string): number;
22
- /**
23
- * Clamps a timestamp to not exceed a limit, preserving the original timezone offset.
24
- * Returns the original if it's <= limit, otherwise returns limit in original's timezone.
25
- *
26
- * Example:
27
- * timestamp: "2025-12-26T18:00:00+04:00" (future)
28
- * limit: "2025-12-26T10:00:00Z" (server time)
29
- * result: "2025-12-26T14:00:00+04:00" (clamped, same instant as limit)
30
- */
31
- declare function clampTimestamp(timestamp: string, limit: string): string;
32
- /**
33
- * Extracts the timezone offset string from an ISO timestamp.
34
- * Returns "+04:00", "-05:00", or "Z".
35
- */
36
- declare function extractTimezoneOffset(iso: string): string;
37
- /**
38
- * Gets the local timezone offset string for the current environment.
39
- * Returns "+04:00", "-05:00", or "Z" for UTC.
40
- */
41
- declare function getLocalTimezoneOffset(): string;
42
-
43
- export { clampTimestamp, extractTimezoneOffset, getISO, getLocalISO, getLocalTimezoneOffset, timestampDiff };
@@ -1,47 +0,0 @@
1
- import "../chunk-IZ2YBCUP.js";
2
- function getISO(date = /* @__PURE__ */ new Date()) {
3
- const d = typeof date === "string" ? new Date(date) : date;
4
- return d.toISOString().replace(/\.\d{3}/, "");
5
- }
6
- function getLocalISO(date = /* @__PURE__ */ new Date(), offset = getLocalTimezoneOffset()) {
7
- const match = offset.match(/([+-])(\d{2}):(\d{2})/);
8
- if (offset === "Z" || !match) return getISO(date);
9
- const sign = match[1] === "+" ? 1 : -1;
10
- const offsetMinutes = sign * (parseInt(match[2]) * 60 + parseInt(match[3]));
11
- const localDate = new Date((typeof date === "string" ? new Date(date) : date).getTime() + offsetMinutes * 60 * 1e3);
12
- return getISO(localDate).slice(0, -1) + offset;
13
- }
14
- function timestampDiff(a, b) {
15
- return new Date(a).getTime() - new Date(b).getTime();
16
- }
17
- function clampTimestamp(timestamp, limit) {
18
- if (!timestamp || !limit) throw new Error("Timestamp and limit are required");
19
- const timestampDate = new Date(timestamp);
20
- const limitDate = new Date(limit);
21
- if (timestampDate <= limitDate) {
22
- return timestamp;
23
- }
24
- const offset = extractTimezoneOffset(timestamp);
25
- return getLocalISO(limitDate, offset);
26
- }
27
- function extractTimezoneOffset(iso) {
28
- if (!iso) return "Z";
29
- const match = iso.match(/([+-]\d{2}:\d{2}|Z)$/);
30
- return match ? match[1] : "Z";
31
- }
32
- function getLocalTimezoneOffset() {
33
- const offset = -(/* @__PURE__ */ new Date()).getTimezoneOffset();
34
- if (offset === 0) return "Z";
35
- const hours = Math.floor(Math.abs(offset) / 60);
36
- const mins = Math.abs(offset) % 60;
37
- const sign = offset >= 0 ? "+" : "-";
38
- return `${sign}${String(hours).padStart(2, "0")}:${String(mins).padStart(2, "0")}`;
39
- }
40
- export {
41
- clampTimestamp,
42
- extractTimezoneOffset,
43
- getISO,
44
- getLocalISO,
45
- getLocalTimezoneOffset,
46
- timestampDiff
47
- };