@verdant-web/server 2.1.3 → 3.0.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 (198) hide show
  1. package/dist/esm/ClientConnection.d.ts +1 -0
  2. package/dist/esm/ClientConnection.js.map +1 -1
  3. package/dist/esm/Presence.js.map +1 -1
  4. package/dist/esm/Profiles.js.map +1 -1
  5. package/dist/esm/ReplicaKeepaliveTimers.js.map +1 -1
  6. package/dist/esm/Server.d.ts +15 -11
  7. package/dist/esm/Server.js +29 -30
  8. package/dist/esm/Server.js.map +1 -1
  9. package/dist/esm/ServerLibrary.d.ts +10 -17
  10. package/dist/esm/ServerLibrary.js +151 -127
  11. package/dist/esm/ServerLibrary.js.map +1 -1
  12. package/dist/esm/ServerLibrary.test.js +369 -0
  13. package/dist/esm/ServerLibrary.test.js.map +1 -0
  14. package/dist/esm/TokenVerifier.js.map +1 -1
  15. package/dist/esm/files/FileStorage.js.map +1 -1
  16. package/dist/esm/storage/Storage.d.ts +67 -0
  17. package/dist/esm/storage/Storage.js +2 -0
  18. package/dist/esm/storage/Storage.js.map +1 -0
  19. package/dist/esm/storage/index.d.ts +2 -0
  20. package/dist/esm/storage/index.js +3 -0
  21. package/dist/esm/storage/index.js.map +1 -0
  22. package/dist/esm/storage/sql/SqlBaselines.d.ts +22 -0
  23. package/dist/esm/storage/sql/SqlBaselines.js +101 -0
  24. package/dist/esm/storage/sql/SqlBaselines.js.map +1 -0
  25. package/dist/esm/storage/sql/SqlFileMetadata.d.ts +18 -0
  26. package/dist/esm/storage/sql/SqlFileMetadata.js +69 -0
  27. package/dist/esm/storage/sql/SqlFileMetadata.js.map +1 -0
  28. package/dist/esm/storage/sql/SqlOperations.d.ts +19 -0
  29. package/dist/esm/storage/sql/SqlOperations.js +104 -0
  30. package/dist/esm/storage/sql/SqlOperations.js.map +1 -0
  31. package/dist/esm/storage/sql/SqlReplicas.d.ts +32 -0
  32. package/dist/esm/storage/sql/SqlReplicas.js +163 -0
  33. package/dist/esm/storage/sql/SqlReplicas.js.map +1 -0
  34. package/dist/esm/storage/sql/migrations/v1.d.ts +3 -0
  35. package/dist/esm/storage/sql/migrations/v1.js +59 -0
  36. package/dist/esm/storage/sql/migrations/v1.js.map +1 -0
  37. package/dist/esm/storage/sql/migrations.d.ts +5 -0
  38. package/dist/esm/storage/sql/migrations.js +3 -0
  39. package/dist/esm/storage/sql/migrations.js.map +1 -0
  40. package/dist/esm/storage/sql/sqlStorage.d.ts +5 -0
  41. package/dist/esm/storage/sql/sqlStorage.js +43 -0
  42. package/dist/esm/storage/sql/sqlStorage.js.map +1 -0
  43. package/dist/esm/storage/sql/tables.d.ts +40 -0
  44. package/dist/esm/storage/sql/tables.js +2 -0
  45. package/dist/esm/storage/sql/tables.js.map +1 -0
  46. package/dist/esm/types.d.ts +14 -5
  47. package/package.json +20 -14
  48. package/src/Server.ts +37 -43
  49. package/src/ServerLibrary.test.ts +447 -0
  50. package/src/ServerLibrary.ts +239 -163
  51. package/src/storage/Storage.ts +118 -0
  52. package/src/storage/index.ts +2 -0
  53. package/src/storage/sql/SqlBaselines.ts +141 -0
  54. package/src/storage/sql/SqlFileMetadata.ts +94 -0
  55. package/src/storage/sql/SqlOperations.ts +149 -0
  56. package/src/storage/sql/SqlReplicas.ts +234 -0
  57. package/src/storage/sql/migrations/v1.ts +64 -0
  58. package/src/storage/sql/migrations.ts +3 -0
  59. package/src/storage/sql/sqlStorage.ts +59 -0
  60. package/src/storage/sql/tables.ts +45 -0
  61. package/src/types.ts +15 -4
  62. package/bin/server.mjs +0 -115
  63. package/dist/cjs/Baselines.d.ts +0 -16
  64. package/dist/cjs/Baselines.js +0 -128
  65. package/dist/cjs/Baselines.js.map +0 -1
  66. package/dist/cjs/ClientConnection.d.ts +0 -20
  67. package/dist/cjs/ClientConnection.js +0 -139
  68. package/dist/cjs/ClientConnection.js.map +0 -1
  69. package/dist/cjs/MessageSender.d.ts +0 -5
  70. package/dist/cjs/MessageSender.js +0 -3
  71. package/dist/cjs/MessageSender.js.map +0 -1
  72. package/dist/cjs/OperationHistory.d.ts +0 -36
  73. package/dist/cjs/OperationHistory.js +0 -165
  74. package/dist/cjs/OperationHistory.js.map +0 -1
  75. package/dist/cjs/Presence.d.ts +0 -15
  76. package/dist/cjs/Presence.js +0 -60
  77. package/dist/cjs/Presence.js.map +0 -1
  78. package/dist/cjs/Profiles.d.ts +0 -10
  79. package/dist/cjs/Profiles.js +0 -20
  80. package/dist/cjs/Profiles.js.map +0 -1
  81. package/dist/cjs/ReplicaKeepaliveTimers.d.ts +0 -17
  82. package/dist/cjs/ReplicaKeepaliveTimers.js +0 -31
  83. package/dist/cjs/ReplicaKeepaliveTimers.js.map +0 -1
  84. package/dist/cjs/Replicas.d.ts +0 -25
  85. package/dist/cjs/Replicas.js +0 -196
  86. package/dist/cjs/Replicas.js.map +0 -1
  87. package/dist/cjs/Server.d.ts +0 -167
  88. package/dist/cjs/Server.js +0 -552
  89. package/dist/cjs/Server.js.map +0 -1
  90. package/dist/cjs/ServerLibrary.d.ts +0 -65
  91. package/dist/cjs/ServerLibrary.js +0 -505
  92. package/dist/cjs/ServerLibrary.js.map +0 -1
  93. package/dist/cjs/TokenProvider.d.ts +0 -19
  94. package/dist/cjs/TokenProvider.js +0 -27
  95. package/dist/cjs/TokenProvider.js.map +0 -1
  96. package/dist/cjs/TokenVerifier.d.ts +0 -16
  97. package/dist/cjs/TokenVerifier.js +0 -40
  98. package/dist/cjs/TokenVerifier.js.map +0 -1
  99. package/dist/cjs/files/FileMetadata.d.ts +0 -28
  100. package/dist/cjs/files/FileMetadata.js +0 -69
  101. package/dist/cjs/files/FileMetadata.js.map +0 -1
  102. package/dist/cjs/files/FileStorage.d.ts +0 -35
  103. package/dist/cjs/files/FileStorage.js +0 -72
  104. package/dist/cjs/files/FileStorage.js.map +0 -1
  105. package/dist/cjs/index.d.ts +0 -10
  106. package/dist/cjs/index.js +0 -12
  107. package/dist/cjs/index.js.map +0 -1
  108. package/dist/cjs/migrations/v0.d.ts +0 -1
  109. package/dist/cjs/migrations/v0.js +0 -30
  110. package/dist/cjs/migrations/v0.js.map +0 -1
  111. package/dist/cjs/migrations/v1.d.ts +0 -1
  112. package/dist/cjs/migrations/v1.js +0 -32
  113. package/dist/cjs/migrations/v1.js.map +0 -1
  114. package/dist/cjs/migrations/v2.d.ts +0 -1
  115. package/dist/cjs/migrations/v2.js +0 -29
  116. package/dist/cjs/migrations/v2.js.map +0 -1
  117. package/dist/cjs/migrations/v3.d.ts +0 -1
  118. package/dist/cjs/migrations/v3.js +0 -15
  119. package/dist/cjs/migrations/v3.js.map +0 -1
  120. package/dist/cjs/migrations/v4.d.ts +0 -1
  121. package/dist/cjs/migrations/v4.js +0 -9
  122. package/dist/cjs/migrations/v4.js.map +0 -1
  123. package/dist/cjs/migrations/v5.d.ts +0 -2
  124. package/dist/cjs/migrations/v5.js +0 -37
  125. package/dist/cjs/migrations/v5.js.map +0 -1
  126. package/dist/cjs/migrations/v6.d.ts +0 -1
  127. package/dist/cjs/migrations/v6.js +0 -8
  128. package/dist/cjs/migrations/v6.js.map +0 -1
  129. package/dist/cjs/migrations/v7.d.ts +0 -1
  130. package/dist/cjs/migrations/v7.js +0 -10
  131. package/dist/cjs/migrations/v7.js.map +0 -1
  132. package/dist/cjs/migrations.d.ts +0 -6
  133. package/dist/cjs/migrations.js +0 -72
  134. package/dist/cjs/migrations.js.map +0 -1
  135. package/dist/cjs/migrations.test.js +0 -121
  136. package/dist/cjs/migrations.test.js.map +0 -1
  137. package/dist/cjs/types.d.ts +0 -38
  138. package/dist/cjs/types.js +0 -3
  139. package/dist/cjs/types.js.map +0 -1
  140. package/dist/esm/Baselines.d.ts +0 -16
  141. package/dist/esm/Baselines.js +0 -124
  142. package/dist/esm/Baselines.js.map +0 -1
  143. package/dist/esm/OperationHistory.d.ts +0 -36
  144. package/dist/esm/OperationHistory.js +0 -161
  145. package/dist/esm/OperationHistory.js.map +0 -1
  146. package/dist/esm/Replicas.d.ts +0 -25
  147. package/dist/esm/Replicas.js +0 -192
  148. package/dist/esm/Replicas.js.map +0 -1
  149. package/dist/esm/files/FileMetadata.d.ts +0 -28
  150. package/dist/esm/files/FileMetadata.js +0 -65
  151. package/dist/esm/files/FileMetadata.js.map +0 -1
  152. package/dist/esm/migrations/v0.d.ts +0 -1
  153. package/dist/esm/migrations/v0.js +0 -27
  154. package/dist/esm/migrations/v0.js.map +0 -1
  155. package/dist/esm/migrations/v1.d.ts +0 -1
  156. package/dist/esm/migrations/v1.js +0 -29
  157. package/dist/esm/migrations/v1.js.map +0 -1
  158. package/dist/esm/migrations/v2.d.ts +0 -1
  159. package/dist/esm/migrations/v2.js +0 -26
  160. package/dist/esm/migrations/v2.js.map +0 -1
  161. package/dist/esm/migrations/v3.d.ts +0 -1
  162. package/dist/esm/migrations/v3.js +0 -12
  163. package/dist/esm/migrations/v3.js.map +0 -1
  164. package/dist/esm/migrations/v4.d.ts +0 -1
  165. package/dist/esm/migrations/v4.js +0 -6
  166. package/dist/esm/migrations/v4.js.map +0 -1
  167. package/dist/esm/migrations/v5.d.ts +0 -2
  168. package/dist/esm/migrations/v5.js +0 -33
  169. package/dist/esm/migrations/v5.js.map +0 -1
  170. package/dist/esm/migrations/v6.d.ts +0 -1
  171. package/dist/esm/migrations/v6.js +0 -5
  172. package/dist/esm/migrations/v6.js.map +0 -1
  173. package/dist/esm/migrations/v7.d.ts +0 -1
  174. package/dist/esm/migrations/v7.js +0 -7
  175. package/dist/esm/migrations/v7.js.map +0 -1
  176. package/dist/esm/migrations.d.ts +0 -6
  177. package/dist/esm/migrations.js +0 -45
  178. package/dist/esm/migrations.js.map +0 -1
  179. package/dist/esm/migrations.test.d.ts +0 -1
  180. package/dist/esm/migrations.test.js +0 -116
  181. package/dist/esm/migrations.test.js.map +0 -1
  182. package/dist/tsconfig-cjs.tsbuildinfo +0 -1
  183. package/dist/tsconfig.tsbuildinfo +0 -1
  184. package/src/Baselines.ts +0 -198
  185. package/src/OperationHistory.ts +0 -232
  186. package/src/Replicas.ts +0 -274
  187. package/src/files/FileMetadata.ts +0 -112
  188. package/src/migrations/v0.ts +0 -26
  189. package/src/migrations/v1.ts +0 -28
  190. package/src/migrations/v2.ts +0 -26
  191. package/src/migrations/v3.ts +0 -12
  192. package/src/migrations/v4.ts +0 -6
  193. package/src/migrations/v5.ts +0 -49
  194. package/src/migrations/v6.ts +0 -4
  195. package/src/migrations/v7.ts +0 -6
  196. package/src/migrations.test.ts +0 -133
  197. package/src/migrations.ts +0 -61
  198. /package/dist/{cjs/migrations.test.d.ts → esm/ServerLibrary.test.d.ts} +0 -0
@@ -1,505 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ServerLibrary = void 0;
4
- const common_1 = require("@verdant-web/common");
5
- const Replicas_js_1 = require("./Replicas.js");
6
- const OperationHistory_js_1 = require("./OperationHistory.js");
7
- const Baselines_js_1 = require("./Baselines.js");
8
- const Presence_js_1 = require("./Presence.js");
9
- class ServerLibrary extends common_1.EventSubscriber {
10
- constructor({ db, sender, profiles, replicaTruancyMinutes, log = () => { }, disableRebasing, fileMetadata, fileStorage, }) {
11
- super();
12
- this.presences = new Presence_js_1.Presence();
13
- /**
14
- * Validates a user's access to a replica. If the replica does not
15
- * exist, a user may create it. But if it does exist, its user (clientId)
16
- * must match the user making the request.
17
- */
18
- this.validateReplicaAccess = (replicaId, info) => {
19
- const replica = this.replicas.get(info.libraryId, replicaId);
20
- if (replica && replica.clientId !== info.userId) {
21
- throw new Error(`Replica ${replicaId} does not belong to client ${info.userId}`);
22
- }
23
- };
24
- this.hasWriteAccess = (info) => {
25
- return (info.type !== common_1.ReplicaType.ReadOnlyPull &&
26
- info.type !== common_1.ReplicaType.ReadOnlyRealtime);
27
- };
28
- this.receive = async (message, clientKey, info) => {
29
- this.validateReplicaAccess(message.replicaId, info);
30
- switch (message.type) {
31
- case 'op':
32
- this.handleOperation(message, clientKey, info);
33
- break;
34
- case 'sync':
35
- this.handleSync(message, clientKey, info);
36
- break;
37
- case 'ack':
38
- this.handleAck(message, clientKey, info);
39
- break;
40
- case 'heartbeat':
41
- this.handleHeartbeat(message, clientKey, info);
42
- break;
43
- case 'presence-update':
44
- await this.handlePresenceUpdate(message, clientKey, info);
45
- break;
46
- default:
47
- this.log('Unknown message type', message.type);
48
- break;
49
- }
50
- this.replicas.updateLastSeen(info.libraryId, message.replicaId);
51
- };
52
- this.remove = (libraryId, replicaId) => {
53
- this.presences.removeReplica(libraryId, replicaId);
54
- };
55
- this.handleOperation = (message, clientKey, info) => {
56
- if (!message.operations.length)
57
- return;
58
- if (!this.hasWriteAccess(info)) {
59
- this.sender.send(info.libraryId, clientKey, {
60
- type: 'forbidden',
61
- });
62
- return;
63
- }
64
- const run = this.db.transaction(() => {
65
- // insert patches into history
66
- this.operations.insertAll(info.libraryId, message.replicaId, message.operations);
67
- });
68
- run();
69
- this.enqueueRebase(info.libraryId);
70
- // rebroadcast to whole library except the sender
71
- this.rebroadcastOperations(info.libraryId, clientKey, message.replicaId, message.operations, []);
72
- // tell sender we got and processed their operation
73
- this.sender.send(info.libraryId, clientKey, {
74
- type: 'server-ack',
75
- timestamp: message.timestamp,
76
- });
77
- this.updateHighwater(message.replicaId, message.operations[message.operations.length - 1].timestamp, info);
78
- this.emit(`changes`, info, message.operations, []);
79
- };
80
- this.removeExtraOperationData = (operation) => {
81
- return (0, common_1.omit)(operation, ['replicaId', 'serverOrder']);
82
- };
83
- this.rebroadcastOperations = (libraryId, clientKey, replicaId, ops, baselines) => {
84
- if (ops.length === 0 && baselines.length === 0)
85
- return;
86
- this.log('info', 'Rebroadcasting', ops.length, 'operations and', baselines.length, 'baselines');
87
- this.sender.broadcast(libraryId, {
88
- type: 'op-re',
89
- operations: ops,
90
- baselines,
91
- replicaId,
92
- globalAckTimestamp: this.replicas.getGlobalAck(libraryId),
93
- }, [clientKey]);
94
- };
95
- this.handleSync = (message, clientKey, info) => {
96
- const replicaId = message.replicaId;
97
- // TODO: is this right? shouldn't read-only replicas still be able to sync,
98
- // just not send ops?
99
- if (!this.hasWriteAccess(info)) {
100
- this.sender.send(info.libraryId, clientKey, {
101
- type: 'forbidden',
102
- });
103
- this.log('warning', 'sync from read-only replica', replicaId);
104
- return;
105
- }
106
- if (message.resyncAll) {
107
- // forget our local understanding of the replica and reset it
108
- this.replicas.delete(info.libraryId, replicaId);
109
- }
110
- const { status, replicaInfo: clientReplicaInfo } = this.replicas.getOrCreate(info.libraryId, replicaId, info);
111
- const changesSince = status === 'existing' ? clientReplicaInfo.ackedLogicalTime : null;
112
- this.log(`Sync from ${replicaId} (user: ${info.userId}) [ackedLogicalTime: ${changesSince}, ackedServerOrder: ${clientReplicaInfo.ackedServerOrder}, status: ${status}}]`);
113
- // lookup operations after the last ack the client gave us
114
- const ops = this.operations.getFromServerOrder(info.libraryId, clientReplicaInfo.ackedServerOrder);
115
- // new, unseen replicas should reset their existing storage
116
- // to that of the server when joining a library.
117
- // truant replicas should also reset their storage.
118
- const replicaShouldReset = !!message.resyncAll || status !== 'existing';
119
- // TODO: assumption: only new replicas need baselines
120
- // const baselines = replicaShouldReset
121
- // ? []
122
- // : this.baselines.getAllAfter(info.libraryId, changesSince);
123
- const baselines = this.baselines.getAllAfter(info.libraryId, changesSince);
124
- // const baselines = this.baselines.getFromServerOrder(
125
- // info.libraryId,
126
- // clientReplicaInfo.ackedServerOrder
127
- // );
128
- // We detect that a library is new by checking if it has any history.
129
- // If there are no existing operations or baselines (and the requested
130
- // history timerange was "everything", i.e. "from null"), then this is
131
- // a fresh library which should receive the first client's history as its
132
- // own. Otherwise, if the client requested a reset, we should send them
133
- // the full history of the library.
134
- // the definition of this field could be improved to be more explicit
135
- // and not rely on seemingly unrelated data.
136
- const isEmptyLibrary = changesSince === null && ops.length === 0 && baselines.length === 0;
137
- let overwriteLocalData = replicaShouldReset && !isEmptyLibrary;
138
- // if the local library is empty and the replica is new to us,
139
- // but the replica is providing a "since" timestamp, this
140
- // suggests the local data is incomplete or gone. we request
141
- // this replica should respond with a full history.
142
- if (isEmptyLibrary && status === 'new' && message.since !== null) {
143
- this.log('Detected local data is incomplete, requesting full history from replica', replicaId);
144
- this.sender.send(info.libraryId, clientKey, {
145
- type: 'need-since',
146
- since: null,
147
- });
148
- return;
149
- }
150
- else if (!isEmptyLibrary && message.since === null) {
151
- // this would mean the replica is providing a full history
152
- // but the library already has data. the replica should
153
- // reset to the server version
154
- this.log('Detected replica', replicaId, 'is providing a full history but the library already has data. Requesting replica reset.');
155
- overwriteLocalData = true;
156
- }
157
- if (overwriteLocalData) {
158
- this.log('Overwriting local data for replica', replicaId, 'with', baselines.length, 'baselines and', ops.length, 'operations');
159
- }
160
- // only write incoming replica data to storage if
161
- // we are not overwriting the replica's data
162
- if (!overwriteLocalData) {
163
- // store all incoming operations and baselines
164
- this.baselines.insertAll(info.libraryId, message.baselines);
165
- this.log('Storing', message.baselines.length, 'baselines and', message.operations.length, 'operations');
166
- this.operations.insertAll(info.libraryId, replicaId, message.operations);
167
- this.replicas.updateAcknowledged(info.libraryId, replicaId, message.timestamp);
168
- // will include the new global ack
169
- this.rebroadcastOperations(info.libraryId, clientKey, message.replicaId, message.operations, message.baselines);
170
- if (message.operations.length || message.baselines.length) {
171
- this.emit(`changes`, info, message.operations, message.baselines);
172
- }
173
- }
174
- if (status === 'truant') {
175
- this.log('A truant replica has reconnected', replicaId);
176
- }
177
- // create the nonce by encoding the server order of the last operation
178
- const ackThisNonce = this.createAckNonce(ops);
179
- // respond to client
180
- this.log('Sending sync response with', ops.length, 'operations and', baselines.length, 'baselines');
181
- this.sender.send(info.libraryId, clientKey, {
182
- type: 'sync-resp',
183
- operations: ops.map(this.removeExtraOperationData),
184
- baselines: baselines.map((baseline) => ({
185
- oid: baseline.oid,
186
- snapshot: baseline.snapshot,
187
- timestamp: baseline.timestamp,
188
- })),
189
- globalAckTimestamp: this.replicas.getGlobalAck(info.libraryId),
190
- peerPresence: this.presences.all(info.libraryId),
191
- // only request the client to overwrite local data if a reset is requested
192
- // and there is data to overwrite it. otherwise the client may still
193
- // send its own history to us.
194
- overwriteLocalData,
195
- ackedTimestamp: message.timestamp,
196
- ackThisNonce,
197
- });
198
- };
199
- this.createAckNonce = (ops) => {
200
- return ops.length
201
- ? Buffer.from(JSON.stringify(ops[ops.length - 1].serverOrder)).toString('base64')
202
- : undefined;
203
- };
204
- this.handleAck = (message, clientKey, info) => {
205
- if (message.nonce) {
206
- const decodedNonce = JSON.parse(Buffer.from(message.nonce, 'base64').toString('utf8'));
207
- this.log('Ack from', message.replicaId, '(user', info.userId, ')', 'with order', decodedNonce);
208
- if (typeof decodedNonce !== 'number') {
209
- this.log('error', 'Invalid nonce', message.nonce);
210
- return;
211
- }
212
- const replicaId = message.replicaId;
213
- this.replicas.updateServerOrder(info.libraryId, replicaId, decodedNonce);
214
- }
215
- else if (message.timestamp) {
216
- this.replicas.acknowledgeOperation(info.libraryId, message.replicaId, message.timestamp);
217
- const globalAck = this.replicas.getGlobalAck(info.libraryId);
218
- if (globalAck) {
219
- this.sender.broadcast(info.libraryId, {
220
- type: 'global-ack',
221
- timestamp: globalAck,
222
- });
223
- }
224
- }
225
- };
226
- this.updateHighwater = (replicaId, timestamp, info, ignoreClientKeys = []) => {
227
- this.replicas.updateAcknowledged(info.libraryId, replicaId, timestamp);
228
- const newGlobalAck = this.replicas.getGlobalAck(info.libraryId);
229
- if (newGlobalAck) {
230
- this.sender.broadcast(info.libraryId, {
231
- type: 'global-ack',
232
- timestamp: newGlobalAck,
233
- }, ignoreClientKeys);
234
- }
235
- };
236
- this.pendingRebaseTimeout = null;
237
- this.enqueueRebase = (libraryId) => {
238
- if (this.disableRebasing)
239
- return;
240
- if (!this.pendingRebaseTimeout) {
241
- setTimeout(() => this.rebase(libraryId), 0);
242
- }
243
- };
244
- this.rebase = (libraryId) => {
245
- if (this.disableRebasing)
246
- return;
247
- this.log('Performing rebase check');
248
- // fundamentally a rebase occurs when some conditions are met:
249
- // 1. the replica which created an operation has dropped that operation
250
- // from their history stack, i.e. their oldest acked timestamp is after it.
251
- // 2. all other replicas have acknowledged an operation since the
252
- // operation which will be flattened to the baseline. i.e. global
253
- // ack server order > server order.
254
- //
255
- // to determine which rebases we can do, we use a heuristic.
256
- // the maximal set of operations we could potentially rebase is
257
- // up to the newest 'oldest timestamp' of any replica. so we
258
- // grab that slice of the operations history, then iterate over it
259
- // and check if any rebase conditions are met.
260
- // for global ack, to determine consensus, also allow
261
- // for all actively connected replicas to ack regardless of their
262
- // type.
263
- const activeReplicaIds = Object.values(this.presences.all(libraryId)).map((p) => p.replicaId);
264
- const globalAck = this.replicas.getGlobalAck(libraryId, activeReplicaIds);
265
- const globalServerOrder = this.replicas.getEarliestAckedServerOrder(libraryId);
266
- if (!globalAck) {
267
- this.log('No global ack, skipping rebase');
268
- return;
269
- }
270
- if (globalServerOrder === null) {
271
- this.log('No global server order, skipping rebase');
272
- return;
273
- }
274
- // these are in forward chronological order
275
- const ops = this.operations.getBeforeServerOrder(libraryId, globalServerOrder);
276
- const opsToApply = {};
277
- // if we encounter a sequential operation in history which does
278
- // not meet our conditions, we must ignore subsequent operations
279
- // applied to that document.
280
- const hardStops = {};
281
- for (const op of ops) {
282
- const isBeforeGlobalAck = globalAck > op.timestamp;
283
- if (!hardStops[op.oid] && isBeforeGlobalAck) {
284
- opsToApply[op.oid] = opsToApply[op.oid] || [];
285
- opsToApply[op.oid].push(op);
286
- }
287
- else {
288
- hardStops[op.oid] = true;
289
- }
290
- }
291
- const deletedRefs = new Array();
292
- for (const [documentId, ops] of Object.entries(opsToApply)) {
293
- this.log('Rebasing', documentId);
294
- this.baselines.applyOperations(libraryId, documentId, ops, deletedRefs),
295
- this.operations.dropAll(libraryId, ops);
296
- }
297
- // hint to clients they can rebase too
298
- this.sender.broadcast(libraryId, {
299
- type: 'global-ack',
300
- timestamp: globalAck,
301
- });
302
- // cleanup deleted files
303
- for (const ref of deletedRefs) {
304
- if ((0, common_1.isFileRef)(ref)) {
305
- this.files.markPendingDelete(libraryId, ref.id);
306
- }
307
- }
308
- };
309
- this.handleHeartbeat = (_, clientKey, info) => {
310
- this.sender.send(info.libraryId, clientKey, {
311
- type: 'heartbeat-response',
312
- });
313
- };
314
- this.handlePresenceUpdate = async (message, clientKey, info) => {
315
- this.presences.set(info.libraryId, info.userId, {
316
- presence: message.presence,
317
- replicaId: message.replicaId,
318
- profile: await this.profiles.get(info.userId),
319
- id: info.userId,
320
- });
321
- this.sender.broadcast(info.libraryId, {
322
- type: 'presence-changed',
323
- replicaId: message.replicaId,
324
- userInfo: {
325
- id: info.userId,
326
- presence: message.presence,
327
- profile: await this.profiles.get(info.userId),
328
- replicaId: message.replicaId,
329
- },
330
- },
331
- // mirror back to the replica which sent it so it has profile
332
- []);
333
- };
334
- this.onPresenceLost = async (libraryId, replicaId, userId) => {
335
- this.log('User disconnected from all replicas:', userId);
336
- this.sender.broadcast(libraryId, {
337
- type: 'presence-offline',
338
- replicaId,
339
- userId,
340
- });
341
- if (Object.keys(this.presences.all(libraryId)).length === 0) {
342
- this.log(`All users have disconnected from ${libraryId}`);
343
- // could happen - if the server is shutting down manually
344
- if (!this.db.open) {
345
- this.log('debug', 'Database not open, skipping cleanup');
346
- return;
347
- }
348
- const pendingDelete = this.files.getPendingDeletes(libraryId);
349
- if (pendingDelete.length > 0) {
350
- if (!this.fileStorage) {
351
- throw new Error('File storage not configured, cannot delete files');
352
- }
353
- this.log('Deleting files:', pendingDelete.map((f) => f.fileId).join(', '));
354
- await Promise.all(pendingDelete.map(async (fileInfo) => {
355
- var _a;
356
- try {
357
- await ((_a = this.fileStorage) === null || _a === void 0 ? void 0 : _a.delete({
358
- libraryId: fileInfo.libraryId,
359
- fileName: fileInfo.name,
360
- id: fileInfo.fileId,
361
- type: fileInfo.type,
362
- }));
363
- this.files.delete(libraryId, fileInfo.fileId);
364
- }
365
- catch (e) {
366
- this.log('Failed to delete file', fileInfo.fileId, ' the file will remain in a pending delete state', e);
367
- }
368
- }));
369
- }
370
- }
371
- };
372
- this.destroy = async (libraryId) => {
373
- var _a;
374
- this.presences.clear(libraryId);
375
- this.replicas.deleteAll(libraryId);
376
- this.operations.deleteAll(libraryId);
377
- this.baselines.deleteAll(libraryId);
378
- const allFiles = this.files.getAll(libraryId);
379
- if (allFiles.length > 0) {
380
- this.log(`Deleting ${allFiles.length} files for library ${libraryId}`, allFiles.map((f) => f.fileId).join(', '));
381
- for (const fileInfo of allFiles) {
382
- await ((_a = this.fileStorage) === null || _a === void 0 ? void 0 : _a.delete({
383
- libraryId,
384
- fileName: fileInfo.name,
385
- id: fileInfo.fileId,
386
- type: fileInfo.type,
387
- }));
388
- }
389
- this.files.deleteAll(libraryId);
390
- }
391
- };
392
- this.getPresence = (libraryId) => {
393
- return this.presences.all(libraryId);
394
- };
395
- this.getInfo = async (libraryId) => {
396
- var _a;
397
- const rawReplicas = this.replicas.getAll(libraryId);
398
- const profiles = await Promise.all(rawReplicas.map((r) => this.profiles.get(r.clientId)));
399
- const replicas = rawReplicas.map((r, index) => ({
400
- id: r.id,
401
- ackedLogicalTime: r.ackedLogicalTime,
402
- ackedServerOrder: r.ackedServerOrder,
403
- type: r.type,
404
- truant: !!r.lastSeenWallClockTime &&
405
- r.lastSeenWallClockTime < this.replicas.truantCutoff,
406
- profile: profiles[index],
407
- }));
408
- const data = {
409
- id: libraryId,
410
- replicas,
411
- latestServerOrder: this.operations.getLatestServerOrder(libraryId),
412
- operationsCount: this.operations.getCount(libraryId),
413
- baselinesCount: this.baselines.getCount(libraryId),
414
- globalAck: (_a = this.replicas.getGlobalAck(libraryId)) !== null && _a !== void 0 ? _a : null,
415
- };
416
- if (data.replicas.length === 0 &&
417
- data.operationsCount === 0 &&
418
- data.baselinesCount === 0) {
419
- return null;
420
- }
421
- return data;
422
- };
423
- this.evictUser = (libraryId, userId) => {
424
- this.replicas.deleteAllForUser(libraryId, userId);
425
- };
426
- this.getDocumentSnapshot = (libraryId, oid) => {
427
- return this.hydrateObject(libraryId, oid);
428
- };
429
- this.getObjectSnapshot = (libraryId, oid) => {
430
- var _a;
431
- const baseline = this.baselines.get(libraryId, oid);
432
- const ops = this.operations.getAllFor(libraryId, oid);
433
- const snapshot = (0, common_1.applyOperations)((_a = baseline === null || baseline === void 0 ? void 0 : baseline.snapshot) !== null && _a !== void 0 ? _a : undefined, ops);
434
- return snapshot;
435
- };
436
- this.hydrateObject = (libraryId, oid) => {
437
- const snapshot = this.getObjectSnapshot(libraryId, oid);
438
- if (Array.isArray(snapshot)) {
439
- return snapshot.map((item, index) => {
440
- if ((0, common_1.isObjectRef)(item)) {
441
- return this.hydrateObject(libraryId, item.id);
442
- }
443
- else if ((0, common_1.isFileRef)(item)) {
444
- return this.hydrateFile(libraryId, item.id);
445
- }
446
- else {
447
- return item;
448
- }
449
- });
450
- }
451
- else if (snapshot && typeof snapshot === 'object') {
452
- const hydrated = Object.assign({}, snapshot);
453
- for (const [key, value] of Object.entries(snapshot)) {
454
- if ((0, common_1.isObjectRef)(value)) {
455
- hydrated[key] = this.hydrateObject(libraryId, value.id);
456
- }
457
- else if ((0, common_1.isFileRef)(value)) {
458
- hydrated[key] = this.hydrateFile(libraryId, value.id);
459
- }
460
- }
461
- return hydrated;
462
- }
463
- else {
464
- return snapshot;
465
- }
466
- };
467
- this.hydrateFile = (libraryId, fileId) => {
468
- var _a, _b;
469
- const data = this.files.get(libraryId, fileId);
470
- if (data) {
471
- const url = (_b = (_a = this.fileStorage) === null || _a === void 0 ? void 0 : _a.getUrl({
472
- fileName: data.name,
473
- id: data.fileId,
474
- libraryId,
475
- type: data.type,
476
- })) !== null && _b !== void 0 ? _b : null;
477
- return {
478
- url,
479
- id: data.fileId,
480
- name: data.name,
481
- type: data.type,
482
- };
483
- }
484
- else {
485
- return null;
486
- }
487
- };
488
- this.close = () => {
489
- this.db.close();
490
- };
491
- this.db = db;
492
- this.log = log;
493
- this.disableRebasing = !!disableRebasing;
494
- this.sender = sender;
495
- this.profiles = profiles;
496
- this.replicas = new Replicas_js_1.ReplicaInfos(this.db, replicaTruancyMinutes);
497
- this.operations = new OperationHistory_js_1.OperationHistory(this.db);
498
- this.baselines = new Baselines_js_1.Baselines(this.db);
499
- this.files = fileMetadata;
500
- this.fileStorage = fileStorage;
501
- this.presences.on('lost', this.onPresenceLost);
502
- }
503
- }
504
- exports.ServerLibrary = ServerLibrary;
505
- //# sourceMappingURL=ServerLibrary.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ServerLibrary.js","sourceRoot":"","sources":["../../src/ServerLibrary.ts"],"names":[],"mappings":"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"}
@@ -1,19 +0,0 @@
1
- import { ReplicaType } from '@verdant-web/common';
2
- export declare class TokenProvider {
3
- private config;
4
- constructor(config: {
5
- secret: string;
6
- });
7
- getToken: ({ userId, libraryId, syncEndpoint, role, type, expiresIn, fileEndpoint, }: {
8
- userId: string;
9
- libraryId: string;
10
- syncEndpoint: string;
11
- fileEndpoint?: string | undefined;
12
- role?: string | undefined;
13
- type?: ReplicaType | undefined;
14
- /**
15
- * The time when the token will expire. A string in the format of "3d" or a number of seconds.
16
- */
17
- expiresIn?: string | number | undefined;
18
- }) => string;
19
- }
@@ -1,27 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.TokenProvider = void 0;
7
- const common_1 = require("@verdant-web/common");
8
- const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
9
- class TokenProvider {
10
- constructor(config) {
11
- this.config = config;
12
- this.getToken = ({ userId, libraryId, syncEndpoint, role, type = common_1.ReplicaType.Realtime, expiresIn = '1d', fileEndpoint, }) => {
13
- return jsonwebtoken_1.default.sign({
14
- sub: userId,
15
- lib: libraryId,
16
- url: syncEndpoint,
17
- file: fileEndpoint,
18
- role,
19
- type,
20
- }, this.config.secret, {
21
- expiresIn,
22
- });
23
- };
24
- }
25
- }
26
- exports.TokenProvider = TokenProvider;
27
- //# sourceMappingURL=TokenProvider.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"TokenProvider.js","sourceRoot":"","sources":["../../src/TokenProvider.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAkD;AAClD,gEAA+B;AAE/B,MAAa,aAAa;IACzB,YAAoB,MAA0B;QAA1B,WAAM,GAAN,MAAM,CAAoB;QAE9C,aAAQ,GAAG,CAAC,EACX,MAAM,EACN,SAAS,EACT,YAAY,EACZ,IAAI,EACJ,IAAI,GAAG,oBAAW,CAAC,QAAQ,EAC3B,SAAS,GAAG,IAAI,EAChB,YAAY,GAYZ,EAAE,EAAE;YACJ,OAAO,sBAAG,CAAC,IAAI,CACd;gBACC,GAAG,EAAE,MAAM;gBACX,GAAG,EAAE,SAAS;gBACd,GAAG,EAAE,YAAY;gBACjB,IAAI,EAAE,YAAY;gBAClB,IAAI;gBACJ,IAAI;aACJ,EACD,IAAI,CAAC,MAAM,CAAC,MAAM,EAClB;gBACC,SAAS;aACT,CACD,CAAC;QACH,CAAC,CAAC;IApC+C,CAAC;CAqClD;AAtCD,sCAsCC"}
@@ -1,16 +0,0 @@
1
- import { ReplicaType } from '@verdant-web/common';
2
- export declare class TokenVerifier {
3
- private config;
4
- constructor(config: {
5
- secret: string;
6
- });
7
- verifyToken: (token: string) => TokenInfo;
8
- }
9
- export interface TokenInfo {
10
- userId: string;
11
- libraryId: string;
12
- syncEndpoint: string;
13
- role?: string;
14
- type: ReplicaType;
15
- token: string;
16
- }
@@ -1,40 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.TokenVerifier = void 0;
7
- const common_1 = require("@verdant-web/common");
8
- const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
9
- class TokenVerifier {
10
- constructor(config) {
11
- this.config = config;
12
- this.verifyToken = (token) => {
13
- try {
14
- const decoded = jsonwebtoken_1.default.verify(token, this.config.secret, {
15
- complete: false,
16
- });
17
- (0, common_1.assert)(decoded.sub);
18
- return {
19
- userId: decoded.sub,
20
- libraryId: decoded.lib,
21
- syncEndpoint: decoded.url,
22
- role: decoded.role,
23
- type: decoded.type,
24
- token,
25
- };
26
- }
27
- catch (e) {
28
- if (e instanceof jsonwebtoken_1.default.TokenExpiredError) {
29
- throw new common_1.VerdantError(common_1.VerdantError.Code.TokenExpired);
30
- }
31
- if (e instanceof Error) {
32
- throw new common_1.VerdantError(common_1.VerdantError.Code.Unexpected, e);
33
- }
34
- throw new common_1.VerdantError(common_1.VerdantError.Code.Unexpected, undefined, JSON.stringify(e));
35
- }
36
- };
37
- }
38
- }
39
- exports.TokenVerifier = TokenVerifier;
40
- //# sourceMappingURL=TokenVerifier.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"TokenVerifier.js","sourceRoot":"","sources":["../../src/TokenVerifier.ts"],"names":[],"mappings":";;;;;;AAAA,gDAAwE;AACxE,gEAA+C;AAE/C,MAAa,aAAa;IACzB,YAAoB,MAA0B;QAA1B,WAAM,GAAN,MAAM,CAAoB;QAE9C,gBAAW,GAAG,CAAC,KAAa,EAAa,EAAE;YAC1C,IAAI;gBACH,MAAM,OAAO,GAAG,sBAAG,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;oBACrD,QAAQ,EAAE,KAAK;iBACf,CAAe,CAAC;gBACjB,IAAA,eAAM,EAAC,OAAO,CAAC,GAAG,CAAC,CAAC;gBACpB,OAAO;oBACN,MAAM,EAAE,OAAO,CAAC,GAAG;oBACnB,SAAS,EAAE,OAAO,CAAC,GAAG;oBACtB,YAAY,EAAE,OAAO,CAAC,GAAG;oBACzB,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,KAAK;iBACL,CAAC;aACF;YAAC,OAAO,CAAC,EAAE;gBACX,IAAI,CAAC,YAAY,sBAAG,CAAC,iBAAiB,EAAE;oBACvC,MAAM,IAAI,qBAAY,CAAC,qBAAY,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;iBACvD;gBACD,IAAI,CAAC,YAAY,KAAK,EAAE;oBACvB,MAAM,IAAI,qBAAY,CAAC,qBAAY,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;iBACxD;gBACD,MAAM,IAAI,qBAAY,CACrB,qBAAY,CAAC,IAAI,CAAC,UAAU,EAC5B,SAAS,EACT,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CACjB,CAAC;aACF;QACF,CAAC,CAAC;IA7B+C,CAAC;CA8BlD;AA/BD,sCA+BC"}