@verdant-web/server 2.1.2 → 3.0.0-next.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 (199) hide show
  1. package/dist/esm/ClientConnection.js.map +1 -1
  2. package/dist/esm/Presence.js.map +1 -1
  3. package/dist/esm/Profiles.js.map +1 -1
  4. package/dist/esm/ReplicaKeepaliveTimers.js.map +1 -1
  5. package/dist/esm/Server.js +29 -30
  6. package/dist/esm/Server.js.map +1 -1
  7. package/dist/esm/ServerLibrary.js +161 -129
  8. package/dist/esm/ServerLibrary.js.map +1 -1
  9. package/dist/esm/ServerLibrary.test.js +369 -0
  10. package/dist/esm/ServerLibrary.test.js.map +1 -0
  11. package/dist/esm/TokenProvider.js.map +1 -1
  12. package/dist/esm/TokenVerifier.js.map +1 -1
  13. package/dist/esm/files/FileStorage.js.map +1 -1
  14. package/dist/esm/storage/Storage.js +2 -0
  15. package/dist/esm/storage/Storage.js.map +1 -0
  16. package/dist/esm/storage/index.js +3 -0
  17. package/dist/esm/storage/index.js.map +1 -0
  18. package/dist/esm/storage/sql/SqlBaselines.js +101 -0
  19. package/dist/esm/storage/sql/SqlBaselines.js.map +1 -0
  20. package/dist/esm/storage/sql/SqlFileMetadata.js +69 -0
  21. package/dist/esm/storage/sql/SqlFileMetadata.js.map +1 -0
  22. package/dist/esm/storage/sql/SqlOperations.js +104 -0
  23. package/dist/esm/storage/sql/SqlOperations.js.map +1 -0
  24. package/dist/esm/storage/sql/SqlReplicas.js +163 -0
  25. package/dist/esm/storage/sql/SqlReplicas.js.map +1 -0
  26. package/dist/esm/storage/sql/migrations/v1.js +59 -0
  27. package/dist/esm/storage/sql/migrations/v1.js.map +1 -0
  28. package/dist/esm/storage/sql/migrations.js +3 -0
  29. package/dist/esm/storage/sql/migrations.js.map +1 -0
  30. package/dist/esm/storage/sql/sqlStorage.js +43 -0
  31. package/dist/esm/storage/sql/sqlStorage.js.map +1 -0
  32. package/dist/esm/storage/sql/tables.js +2 -0
  33. package/dist/esm/storage/sql/tables.js.map +1 -0
  34. package/package.json +20 -14
  35. package/src/Server.ts +37 -43
  36. package/src/ServerLibrary.test.ts +447 -0
  37. package/src/ServerLibrary.ts +253 -166
  38. package/src/TokenProvider.ts +3 -0
  39. package/src/index.ts +1 -0
  40. package/src/storage/Storage.ts +118 -0
  41. package/src/storage/index.ts +2 -0
  42. package/src/storage/sql/SqlBaselines.ts +141 -0
  43. package/src/storage/sql/SqlFileMetadata.ts +94 -0
  44. package/src/storage/sql/SqlOperations.ts +149 -0
  45. package/src/storage/sql/SqlReplicas.ts +234 -0
  46. package/src/storage/sql/migrations/v1.ts +64 -0
  47. package/src/storage/sql/migrations.ts +3 -0
  48. package/src/storage/sql/sqlStorage.ts +59 -0
  49. package/src/storage/sql/tables.ts +45 -0
  50. package/src/types.ts +31 -4
  51. package/bin/server.mjs +0 -115
  52. package/dist/cjs/Baselines.d.ts +0 -16
  53. package/dist/cjs/Baselines.js +0 -128
  54. package/dist/cjs/Baselines.js.map +0 -1
  55. package/dist/cjs/ClientConnection.d.ts +0 -20
  56. package/dist/cjs/ClientConnection.js +0 -139
  57. package/dist/cjs/ClientConnection.js.map +0 -1
  58. package/dist/cjs/MessageSender.d.ts +0 -5
  59. package/dist/cjs/MessageSender.js +0 -3
  60. package/dist/cjs/MessageSender.js.map +0 -1
  61. package/dist/cjs/OperationHistory.d.ts +0 -36
  62. package/dist/cjs/OperationHistory.js +0 -165
  63. package/dist/cjs/OperationHistory.js.map +0 -1
  64. package/dist/cjs/Presence.d.ts +0 -15
  65. package/dist/cjs/Presence.js +0 -60
  66. package/dist/cjs/Presence.js.map +0 -1
  67. package/dist/cjs/Profiles.d.ts +0 -10
  68. package/dist/cjs/Profiles.js +0 -20
  69. package/dist/cjs/Profiles.js.map +0 -1
  70. package/dist/cjs/ReplicaKeepaliveTimers.d.ts +0 -17
  71. package/dist/cjs/ReplicaKeepaliveTimers.js +0 -31
  72. package/dist/cjs/ReplicaKeepaliveTimers.js.map +0 -1
  73. package/dist/cjs/Replicas.d.ts +0 -25
  74. package/dist/cjs/Replicas.js +0 -196
  75. package/dist/cjs/Replicas.js.map +0 -1
  76. package/dist/cjs/Server.d.ts +0 -180
  77. package/dist/cjs/Server.js +0 -552
  78. package/dist/cjs/Server.js.map +0 -1
  79. package/dist/cjs/ServerLibrary.d.ts +0 -77
  80. package/dist/cjs/ServerLibrary.js +0 -497
  81. package/dist/cjs/ServerLibrary.js.map +0 -1
  82. package/dist/cjs/TokenProvider.d.ts +0 -16
  83. package/dist/cjs/TokenProvider.js +0 -27
  84. package/dist/cjs/TokenProvider.js.map +0 -1
  85. package/dist/cjs/TokenVerifier.d.ts +0 -16
  86. package/dist/cjs/TokenVerifier.js +0 -40
  87. package/dist/cjs/TokenVerifier.js.map +0 -1
  88. package/dist/cjs/files/FileMetadata.d.ts +0 -28
  89. package/dist/cjs/files/FileMetadata.js +0 -69
  90. package/dist/cjs/files/FileMetadata.js.map +0 -1
  91. package/dist/cjs/files/FileStorage.d.ts +0 -35
  92. package/dist/cjs/files/FileStorage.js +0 -72
  93. package/dist/cjs/files/FileStorage.js.map +0 -1
  94. package/dist/cjs/index.d.ts +0 -9
  95. package/dist/cjs/index.js +0 -12
  96. package/dist/cjs/index.js.map +0 -1
  97. package/dist/cjs/migrations/v0.d.ts +0 -1
  98. package/dist/cjs/migrations/v0.js +0 -30
  99. package/dist/cjs/migrations/v0.js.map +0 -1
  100. package/dist/cjs/migrations/v1.d.ts +0 -1
  101. package/dist/cjs/migrations/v1.js +0 -32
  102. package/dist/cjs/migrations/v1.js.map +0 -1
  103. package/dist/cjs/migrations/v2.d.ts +0 -1
  104. package/dist/cjs/migrations/v2.js +0 -29
  105. package/dist/cjs/migrations/v2.js.map +0 -1
  106. package/dist/cjs/migrations/v3.d.ts +0 -1
  107. package/dist/cjs/migrations/v3.js +0 -15
  108. package/dist/cjs/migrations/v3.js.map +0 -1
  109. package/dist/cjs/migrations/v4.d.ts +0 -1
  110. package/dist/cjs/migrations/v4.js +0 -9
  111. package/dist/cjs/migrations/v4.js.map +0 -1
  112. package/dist/cjs/migrations/v5.d.ts +0 -2
  113. package/dist/cjs/migrations/v5.js +0 -37
  114. package/dist/cjs/migrations/v5.js.map +0 -1
  115. package/dist/cjs/migrations/v6.d.ts +0 -1
  116. package/dist/cjs/migrations/v6.js +0 -8
  117. package/dist/cjs/migrations/v6.js.map +0 -1
  118. package/dist/cjs/migrations/v7.d.ts +0 -1
  119. package/dist/cjs/migrations/v7.js +0 -10
  120. package/dist/cjs/migrations/v7.js.map +0 -1
  121. package/dist/cjs/migrations.d.ts +0 -6
  122. package/dist/cjs/migrations.js +0 -72
  123. package/dist/cjs/migrations.js.map +0 -1
  124. package/dist/cjs/migrations.test.d.ts +0 -1
  125. package/dist/cjs/migrations.test.js +0 -121
  126. package/dist/cjs/migrations.test.js.map +0 -1
  127. package/dist/cjs/types.d.ts +0 -23
  128. package/dist/cjs/types.js +0 -3
  129. package/dist/cjs/types.js.map +0 -1
  130. package/dist/esm/Baselines.d.ts +0 -16
  131. package/dist/esm/Baselines.js +0 -124
  132. package/dist/esm/Baselines.js.map +0 -1
  133. package/dist/esm/ClientConnection.d.ts +0 -20
  134. package/dist/esm/MessageSender.d.ts +0 -5
  135. package/dist/esm/OperationHistory.d.ts +0 -36
  136. package/dist/esm/OperationHistory.js +0 -161
  137. package/dist/esm/OperationHistory.js.map +0 -1
  138. package/dist/esm/Presence.d.ts +0 -15
  139. package/dist/esm/Profiles.d.ts +0 -10
  140. package/dist/esm/ReplicaKeepaliveTimers.d.ts +0 -17
  141. package/dist/esm/Replicas.d.ts +0 -25
  142. package/dist/esm/Replicas.js +0 -192
  143. package/dist/esm/Replicas.js.map +0 -1
  144. package/dist/esm/Server.d.ts +0 -180
  145. package/dist/esm/ServerLibrary.d.ts +0 -77
  146. package/dist/esm/TokenProvider.d.ts +0 -16
  147. package/dist/esm/TokenVerifier.d.ts +0 -16
  148. package/dist/esm/files/FileMetadata.d.ts +0 -28
  149. package/dist/esm/files/FileMetadata.js +0 -65
  150. package/dist/esm/files/FileMetadata.js.map +0 -1
  151. package/dist/esm/files/FileStorage.d.ts +0 -35
  152. package/dist/esm/index.d.ts +0 -9
  153. package/dist/esm/migrations/v0.d.ts +0 -1
  154. package/dist/esm/migrations/v0.js +0 -27
  155. package/dist/esm/migrations/v0.js.map +0 -1
  156. package/dist/esm/migrations/v1.d.ts +0 -1
  157. package/dist/esm/migrations/v1.js +0 -29
  158. package/dist/esm/migrations/v1.js.map +0 -1
  159. package/dist/esm/migrations/v2.d.ts +0 -1
  160. package/dist/esm/migrations/v2.js +0 -26
  161. package/dist/esm/migrations/v2.js.map +0 -1
  162. package/dist/esm/migrations/v3.d.ts +0 -1
  163. package/dist/esm/migrations/v3.js +0 -12
  164. package/dist/esm/migrations/v3.js.map +0 -1
  165. package/dist/esm/migrations/v4.d.ts +0 -1
  166. package/dist/esm/migrations/v4.js +0 -6
  167. package/dist/esm/migrations/v4.js.map +0 -1
  168. package/dist/esm/migrations/v5.d.ts +0 -2
  169. package/dist/esm/migrations/v5.js +0 -33
  170. package/dist/esm/migrations/v5.js.map +0 -1
  171. package/dist/esm/migrations/v6.d.ts +0 -1
  172. package/dist/esm/migrations/v6.js +0 -5
  173. package/dist/esm/migrations/v6.js.map +0 -1
  174. package/dist/esm/migrations/v7.d.ts +0 -1
  175. package/dist/esm/migrations/v7.js +0 -7
  176. package/dist/esm/migrations/v7.js.map +0 -1
  177. package/dist/esm/migrations.d.ts +0 -6
  178. package/dist/esm/migrations.js +0 -45
  179. package/dist/esm/migrations.js.map +0 -1
  180. package/dist/esm/migrations.test.d.ts +0 -1
  181. package/dist/esm/migrations.test.js +0 -116
  182. package/dist/esm/migrations.test.js.map +0 -1
  183. package/dist/esm/types.d.ts +0 -23
  184. package/dist/tsconfig-cjs.tsbuildinfo +0 -1
  185. package/dist/tsconfig.tsbuildinfo +0 -1
  186. package/src/Baselines.ts +0 -198
  187. package/src/OperationHistory.ts +0 -232
  188. package/src/Replicas.ts +0 -274
  189. package/src/files/FileMetadata.ts +0 -112
  190. package/src/migrations/v0.ts +0 -26
  191. package/src/migrations/v1.ts +0 -28
  192. package/src/migrations/v2.ts +0 -26
  193. package/src/migrations/v3.ts +0 -12
  194. package/src/migrations/v4.ts +0 -6
  195. package/src/migrations/v5.ts +0 -49
  196. package/src/migrations/v6.ts +0 -4
  197. package/src/migrations/v7.ts +0 -6
  198. package/src/migrations.test.ts +0 -133
  199. package/src/migrations.ts +0 -61
@@ -1,192 +0,0 @@
1
- export class ReplicaInfos {
2
- constructor(db, replicaTruancyMinutes) {
3
- this.db = db;
4
- this.replicaTruancyMinutes = replicaTruancyMinutes;
5
- this.get = (libraryId, replicaId) => {
6
- const row = this.db
7
- .prepare(`
8
- SELECT * FROM ReplicaInfo
9
- WHERE id = ? AND libraryId = ?
10
- `)
11
- .get(replicaId, libraryId);
12
- if (!row) {
13
- return null;
14
- }
15
- return {
16
- id: row.id,
17
- libraryId: row.libraryId,
18
- clientId: row.clientId,
19
- lastSeenWallClockTime: row.lastSeenWallClockTime,
20
- ackedLogicalTime: row.ackedLogicalTime,
21
- type: row.type,
22
- ackedServerOrder: row.ackedServerOrder,
23
- };
24
- };
25
- this.getOrCreate = (libraryId, replicaId, info) => {
26
- const replicaInfo = this.db
27
- .prepare(`
28
- SELECT * FROM ReplicaInfo
29
- WHERE id = ? AND libraryId = ?
30
- `)
31
- .get(replicaId, libraryId);
32
- if (!replicaInfo) {
33
- this.db
34
- .prepare(`
35
- INSERT INTO ReplicaInfo (id, clientId, libraryId, type)
36
- VALUES (?, ?, ?, ?)
37
- `)
38
- .run(replicaId, info.userId, libraryId, info.type);
39
- return {
40
- status: 'new',
41
- replicaInfo: {
42
- id: replicaId,
43
- clientId: info.userId,
44
- ackedLogicalTime: null,
45
- lastSeenWallClockTime: null,
46
- libraryId: libraryId,
47
- type: info.type,
48
- ackedServerOrder: 0,
49
- },
50
- };
51
- }
52
- if (replicaInfo.type !== info.type) {
53
- // type should be updated if a new token changes it
54
- this.db
55
- .prepare(`
56
- UPDATE ReplicaInfo
57
- SET type = ?
58
- WHERE id = ? AND libraryId = ?
59
- `)
60
- .run(info.type, replicaId, libraryId);
61
- }
62
- if (replicaInfo.clientId !== info.userId) {
63
- throw new Error(`Replica ${replicaId} already exists with a different user ID`);
64
- }
65
- if (replicaInfo.lastSeenWallClockTime &&
66
- replicaInfo.lastSeenWallClockTime < this.truantCutoff) {
67
- return {
68
- status: 'truant',
69
- replicaInfo,
70
- };
71
- }
72
- return {
73
- status: 'existing',
74
- replicaInfo,
75
- };
76
- };
77
- this.getAllNonTruant = (libraryId) => {
78
- return this.db
79
- .prepare(`
80
- SELECT * FROM ReplicaInfo
81
- WHERE libraryId = ? AND lastSeenWallClockTime > ?
82
- `)
83
- .all(libraryId, this.truantCutoff);
84
- };
85
- this.getAll = (libraryId) => {
86
- return this.db
87
- .prepare(`
88
- SELECT * FROM ReplicaInfo
89
- WHERE libraryId = ?
90
- `)
91
- .all(libraryId);
92
- };
93
- this.updateLastSeen = (libraryId, replicaId) => {
94
- const clockTime = new Date().getTime();
95
- return this.db
96
- .prepare(`
97
- UPDATE ReplicaInfo
98
- SET lastSeenWallClockTime = ?
99
- WHERE id = ? AND libraryId = ?
100
- `)
101
- .run(clockTime, replicaId, libraryId);
102
- };
103
- this.updateAcknowledged = (libraryId, replicaId, timestamp) => {
104
- this.db
105
- .prepare(`
106
- UPDATE ReplicaInfo
107
- SET ackedLogicalTime = ?
108
- WHERE id = ? AND libraryId = ?
109
- `)
110
- .run(timestamp, replicaId, libraryId);
111
- };
112
- this.updateServerOrder = (libraryId, replicaId, serverOrder) => {
113
- // only increment the server order, never set it to lower than before
114
- this.db
115
- .prepare(`
116
- UPDATE ReplicaInfo
117
- SET ackedServerOrder = MAX(ackedServerOrder, ?)
118
- WHERE id = ? AND libraryId = ?
119
- `)
120
- .run(serverOrder, replicaId, libraryId);
121
- };
122
- this.getEarliestAckedServerOrder = (libraryId) => {
123
- // get the earliest acked server order of all non-truant replicas
124
- const allAcks = this.db
125
- .prepare(`
126
- SELECT ackedServerOrder FROM ReplicaInfo
127
- WHERE libraryId = ?
128
- AND lastSeenWallClockTime > ?
129
- `)
130
- .all(libraryId, this.truantCutoff).map((row) => row.ackedServerOrder);
131
- if (allAcks.some((ack) => ack === null)) {
132
- return null;
133
- }
134
- return Math.min(...allAcks);
135
- };
136
- this.acknowledgeOperation = (libraryId, replicaId, timestamp) => {
137
- if (!timestamp)
138
- return;
139
- // get the server order from the operation with the timestamp and update the replica's server order
140
- // to the max of the current server order and the server order of the operation
141
- this.db
142
- .prepare(`
143
- UPDATE ReplicaInfo
144
- SET ackedLogicalTime = ?, ackedServerOrder = MAX(ackedServerOrder, COALESCE((
145
- SELECT serverOrder FROM OperationHistory
146
- WHERE libraryId = ? AND timestamp = ?
147
- ), 0))
148
- WHERE id = ? AND libraryId = ?
149
- `)
150
- .run(timestamp, libraryId, timestamp, replicaId, libraryId);
151
- };
152
- this.getGlobalAck = (libraryId, onlineReplicaIds) => {
153
- const nonTruant = this.getAllNonTruant(libraryId);
154
- const globalAckEligible = nonTruant.filter((replica) => replica.type < 2 || (onlineReplicaIds === null || onlineReplicaIds === void 0 ? void 0 : onlineReplicaIds.includes(replica.id)));
155
- // get the earliest acked time
156
- return globalAckEligible.reduce((acc, replica) => {
157
- if (!replica.ackedLogicalTime) {
158
- return acc;
159
- }
160
- if (acc === undefined) {
161
- return replica.ackedLogicalTime;
162
- }
163
- return acc < replica.ackedLogicalTime ? acc : replica.ackedLogicalTime;
164
- }, undefined);
165
- };
166
- this.delete = (libraryId, replicaId) => {
167
- return this.db
168
- .prepare(`
169
- DELETE FROM ReplicaInfo
170
- WHERE id = ? AND libraryId = ?
171
- `)
172
- .run(replicaId, libraryId);
173
- };
174
- this.deleteAll = (libraryId) => {
175
- return this.db
176
- .prepare(`
177
- DELETE FROM ReplicaInfo
178
- WHERE libraryId = ?
179
- `)
180
- .run(libraryId);
181
- };
182
- this.deleteAllForUser = (libraryId, userId) => {
183
- return this.db
184
- .prepare(`DELETE FROM ReplicaInfo WHERE libraryId = ? AND clientId = ?`)
185
- .run(libraryId, userId);
186
- };
187
- }
188
- get truantCutoff() {
189
- return Date.now() - this.replicaTruancyMinutes * 60 * 1000;
190
- }
191
- }
192
- //# sourceMappingURL=Replicas.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Replicas.js","sourceRoot":"","sources":["../../src/Replicas.ts"],"names":[],"mappings":"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"}
@@ -1,180 +0,0 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
- /// <reference types="node" resolution-mode="require"/>
3
- /// <reference types="node" resolution-mode="require"/>
4
- /// <reference types="node" resolution-mode="require"/>
5
- import { DocumentBaseline, Operation, ServerMessage } from '@verdant-web/common';
6
- import EventEmitter from 'events';
7
- import { IncomingMessage, Server as HttpServer, ServerResponse } from 'http';
8
- import { UserProfiles } from './Profiles.js';
9
- import { MessageSender } from './MessageSender.js';
10
- import { TokenInfo } from './TokenVerifier.js';
11
- import { FileStorage } from './files/FileStorage.js';
12
- import internal from 'stream';
13
- import { FileMetadataConfig } from './files/FileMetadata.js';
14
- export interface ServerOptions {
15
- /**
16
- * Attach to a pre-existing HTTP server. Provide this if you have another server,
17
- * like an Express server, that you want to add lofi to. If provided, you don't
18
- * need to call .listen()
19
- */
20
- httpServer?: HttpServer;
21
- /**
22
- * The secret value used to generate tokens from your authentication endpoint.
23
- * Used to verify and decode user identity and library access on connection.
24
- */
25
- tokenSecret: string;
26
- /**
27
- * The path to your SQLite database.
28
- */
29
- databaseFile: string;
30
- /**
31
- * Optionally provide an implementation of the UserProfiles interface to look up
32
- * static user profile data to use in persistence. This data is considered trusted
33
- * and can be used to identify users with information like name or profile image.
34
- */
35
- profiles?: UserProfiles<any>;
36
- /**
37
- * How many minutes of inactivity before a replica is considered truant and
38
- * removed from the library. Defaults to 30 days.
39
- */
40
- replicaTruancyMinutes?: number;
41
- /**
42
- * Supply a logging function to log debug messages.
43
- */
44
- log?: (...args: any[]) => void;
45
- /**
46
- * Disable history compaction. Storage usage will grow indefinitely. Not recommended.
47
- */
48
- disableRebasing?: boolean;
49
- /**
50
- * Provide a FileStorage backend to accept file uploads. Without a file backend,
51
- * users will not be able to synchronize files, and all files added on peer replicas
52
- * will be forever unavailable.
53
- *
54
- * A default, filesystem-backed FileStorage implementation is provided as an export
55
- * of this library.
56
- */
57
- fileStorage?: FileStorage;
58
- fileConfig?: FileMetadataConfig;
59
- }
60
- export interface ServerEvents {
61
- error: (err: any) => void;
62
- warning: (msg: string, ...args: any[]) => void;
63
- changes: (info: Omit<TokenInfo, 'token'>, operations: Operation[], baselines: DocumentBaseline[]) => void;
64
- request: (info: TokenInfo) => void;
65
- 'socket-close': (info: TokenInfo) => void;
66
- 'socket-connection': (info: TokenInfo) => void;
67
- }
68
- export declare interface Server {
69
- on<Event extends keyof ServerEvents>(ev: Event, cb: ServerEvents[Event]): this;
70
- off<Event extends keyof ServerEvents>(ev: Event, cb: ServerEvents[Event]): this;
71
- emit<Event extends keyof ServerEvents>(ev: Event, ...args: Parameters<ServerEvents[Event]>): boolean;
72
- }
73
- export declare class Server extends EventEmitter implements MessageSender {
74
- private httpServer;
75
- private wss;
76
- private fileStorage?;
77
- private fileMetadata;
78
- private library;
79
- private clientConnections;
80
- private keepalives;
81
- private tokenVerifier;
82
- private connectionToReplicaIdMap;
83
- private log;
84
- private __testMode;
85
- constructor(options: ServerOptions);
86
- /**
87
- * Attaches the Verdant server to an HttpServer instance, which
88
- * allows it to handle requests and websockets required for the
89
- * Verdant protocol.
90
- *
91
- * You can pass httpPath = false if you want to handle HTTP requests
92
- * yourself, and this will only attach the websocket handling.
93
- */
94
- attach: (server: HttpServer, options?: {
95
- httpPath?: string | false;
96
- }) => void;
97
- /**
98
- * Handles an HTTP upgrade request to a websocket connection.
99
- */
100
- handleUpgrade: (req: IncomingMessage, socket: internal.Duplex, head: Buffer) => Promise<void>;
101
- private authorizeRequest;
102
- private getRequestToken;
103
- private createInternalRequestHandler;
104
- /**
105
- * Handles an HTTP request from a verdant client.
106
- */
107
- handleRequest: (req: IncomingMessage, res: ServerResponse) => Promise<void>;
108
- /**
109
- * Handles a "fetch" style request. Complement to handleRequest, for servers
110
- * that use Request/Response style handlers.
111
- */
112
- handleFetch: (req: Request) => Promise<Response>;
113
- private handleRequestBody;
114
- private writeErrorResponse;
115
- private getErrorResponse;
116
- /**
117
- * Handles a multipart upload of a file from a verdant client. The upload
118
- * will include parameters for the file's ID, name, and type. The request
119
- * must be authenticated with a token to tie it to a library.
120
- */
121
- handleFileRequest: (req: IncomingMessage, res: ServerResponse) => Promise<void>;
122
- /**
123
- * Handles a "fetch" style file request. Complement to handleFileRequest,
124
- * for servers that use Request/Response style handlers.
125
- */
126
- handleFileFetch: (req: Request) => Promise<Response>;
127
- private getFileStorageOrThrow;
128
- private streamIncomingFile;
129
- private getFileData;
130
- broadcast: (libraryId: string, message: ServerMessage, omitKeys?: string[]) => void;
131
- send: (libraryId: string, key: string, message: ServerMessage) => void;
132
- private handleMessage;
133
- private handleConnection;
134
- listen: (handle: any, listeningListener?: (() => void) | undefined) => void;
135
- close: () => Promise<void>;
136
- /**
137
- * Completely remove a library from the server.
138
- * This will remove all data associated with the library.
139
- * Use it very carefully! Data will still be stored on user
140
- * devices, so this is not as scary as it sounds - the next time
141
- * any replica connects, it will repopulate the library. But
142
- * you should still be careful.
143
- */
144
- evictLibrary: (libraryId: string) => void;
145
- /**
146
- * Returns currently connected replica info for a library
147
- */
148
- getLibraryPresence: (libraryId: string) => Record<string, import("@verdant-web/common").UserInfo<any, any>>;
149
- /**
150
- * Returns helpful information about a library.
151
- * This is currently only the known replicas and some
152
- * more low-level metadata.
153
- */
154
- getLibraryInfo: (libraryId: string) => Promise<{
155
- replicas: {
156
- id: string;
157
- ackedLogicalTime: string | null;
158
- ackedServerOrder: number;
159
- type: import("@verdant-web/common").ReplicaType;
160
- truant: boolean | 0 | null;
161
- profile: any;
162
- }[];
163
- latestServerOrder: number;
164
- operationsCount: number;
165
- baselinesCount: number;
166
- globalAck: string | undefined;
167
- }>;
168
- /**
169
- * Removes all replicas associated with a User ID from
170
- * the server. Consistency algorithms will no longer wait on these
171
- * replicas before confirming and squashing changes.
172
- */
173
- evictUser: (libraryId: string, userId: string) => void;
174
- /**
175
- * Retrieves a snapshot of the full document contents at this time.
176
- * Useful for capturing the shape of data for static usage outside
177
- * of the live system.
178
- */
179
- getDocumentSnapshot: (libraryId: string, collection: string, documentId: string) => any;
180
- }
@@ -1,77 +0,0 @@
1
- import { ClientMessage, DocumentBaseline, Operation, ReplicaType, EventSubscriber } from '@verdant-web/common';
2
- import { Database } from 'better-sqlite3';
3
- import { MessageSender } from './MessageSender.js';
4
- import { UserProfileLoader } from './Profiles.js';
5
- import { TokenInfo } from './TokenVerifier.js';
6
- import { FileMetadata } from './files/FileMetadata.js';
7
- import { FileStorage } from './files/FileStorage.js';
8
- export declare type ServerLibraryEvents = {
9
- changes: (info: TokenInfo, operations: Operation[], baselines: DocumentBaseline[]) => void;
10
- };
11
- export declare class ServerLibrary extends EventSubscriber<ServerLibraryEvents> {
12
- private db;
13
- private sender;
14
- private profiles;
15
- private replicas;
16
- private operations;
17
- private baselines;
18
- private presences;
19
- private disableRebasing;
20
- private files;
21
- private fileStorage;
22
- private log;
23
- constructor({ db, sender, profiles, replicaTruancyMinutes, log, disableRebasing, fileMetadata, fileStorage, }: {
24
- db: Database;
25
- sender: MessageSender;
26
- profiles: UserProfileLoader<any>;
27
- replicaTruancyMinutes: number;
28
- log?: (...args: any[]) => void;
29
- disableRebasing?: boolean;
30
- fileMetadata: FileMetadata;
31
- fileStorage?: FileStorage;
32
- });
33
- /**
34
- * Validates a user's access to a replica. If the replica does not
35
- * exist, a user may create it. But if it does exist, its user (clientId)
36
- * must match the user making the request.
37
- */
38
- private validateReplicaAccess;
39
- private hasWriteAccess;
40
- receive: (message: ClientMessage, clientKey: string, info: TokenInfo) => Promise<void>;
41
- remove: (libraryId: string, replicaId: string) => void;
42
- private handleOperation;
43
- private removeExtraOperationData;
44
- private rebroadcastOperations;
45
- private handleSync;
46
- private createAckNonce;
47
- private handleAck;
48
- private updateHighwater;
49
- private pendingRebaseTimeout;
50
- private enqueueRebase;
51
- private rebase;
52
- private handleHeartbeat;
53
- private handlePresenceUpdate;
54
- private onPresenceLost;
55
- destroy: (libraryId: string) => Promise<void>;
56
- getPresence: (libraryId: string) => Record<string, import("@verdant-web/common").UserInfo<any, any>>;
57
- getInfo: (libraryId: string) => Promise<{
58
- replicas: {
59
- id: string;
60
- ackedLogicalTime: string | null;
61
- ackedServerOrder: number;
62
- type: ReplicaType;
63
- truant: boolean | 0 | null;
64
- profile: any;
65
- }[];
66
- latestServerOrder: number;
67
- operationsCount: number;
68
- baselinesCount: number;
69
- globalAck: string | undefined;
70
- }>;
71
- evictUser: (libraryId: string, userId: string) => void;
72
- getDocumentSnapshot: (libraryId: string, oid: string) => any;
73
- private getObjectSnapshot;
74
- private hydrateObject;
75
- private hydrateFile;
76
- close: () => void;
77
- }
@@ -1,16 +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
- expiresIn?: string | number | undefined;
15
- }) => string;
16
- }
@@ -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,28 +0,0 @@
1
- import { Database } from 'better-sqlite3';
2
- import { FileInfo } from './FileStorage.js';
3
- export interface FileMetadataConfig {
4
- deleteExpirationDays?: number;
5
- }
6
- export declare class FileMetadata {
7
- private db;
8
- private deleteExpirationDays;
9
- constructor(db: Database, { deleteExpirationDays }?: FileMetadataConfig);
10
- get: (libraryId: string, fileId: string) => {
11
- libraryId: string;
12
- fileId: string;
13
- name: string;
14
- type: string;
15
- };
16
- getAll: (libraryId: string) => any[];
17
- deleteAll: (libraryId: string) => import("better-sqlite3").RunResult;
18
- put: (libraryId: string, fileInfo: FileInfo) => import("better-sqlite3").RunResult;
19
- markPendingDelete: (libraryId: string, fileId: string) => import("better-sqlite3").RunResult;
20
- delete: (libraryId: string, fileId: string) => import("better-sqlite3").RunResult;
21
- getPendingDeletes: (libraryId: string) => {
22
- libraryId: string;
23
- fileId: string;
24
- name: string;
25
- type: string;
26
- pendingDeleteAt: number;
27
- }[];
28
- }
@@ -1,65 +0,0 @@
1
- export class FileMetadata {
2
- constructor(db, { deleteExpirationDays = 1 } = {}) {
3
- this.db = db;
4
- this.deleteExpirationDays = 1;
5
- this.get = (libraryId, fileId) => {
6
- return this.db
7
- .prepare(`
8
- SELECT * FROM FileMetadata
9
- WHERE libraryId = ? AND fileId = ?
10
- `)
11
- .get(libraryId, fileId);
12
- };
13
- this.getAll = (libraryId) => {
14
- return this.db
15
- .prepare(`
16
- SELECT * FROM FileMetadata
17
- WHERE libraryId = ?
18
- `)
19
- .all(libraryId);
20
- };
21
- this.deleteAll = (libraryId) => {
22
- return this.db
23
- .prepare(`
24
- DELETE FROM FileMetadata
25
- WHERE libraryId = ?
26
- `)
27
- .run(libraryId);
28
- };
29
- this.put = (libraryId, fileInfo) => {
30
- return this.db
31
- .prepare(`
32
- INSERT OR REPLACE INTO FileMetadata (libraryId, fileId, name, type)
33
- VALUES (?, ?, ?, ?)
34
- `)
35
- .run(libraryId, fileInfo.id, fileInfo.fileName, fileInfo.type);
36
- };
37
- this.markPendingDelete = (libraryId, fileId) => {
38
- return this.db
39
- .prepare(`
40
- UPDATE FileMetadata
41
- SET pendingDeleteAt = ?
42
- WHERE libraryId = ? AND fileId = ?
43
- `)
44
- .run(Date.now(), libraryId, fileId);
45
- };
46
- this.delete = (libraryId, fileId) => {
47
- return this.db
48
- .prepare(`
49
- DELETE FROM FileMetadata
50
- WHERE libraryId = ? AND fileId = ?
51
- `)
52
- .run(libraryId, fileId);
53
- };
54
- this.getPendingDeletes = (libraryId) => {
55
- return this.db
56
- .prepare(`
57
- SELECT * FROM FileMetadata
58
- WHERE libraryId = ? AND pendingDeleteAt < ?
59
- `)
60
- .all(libraryId, Date.now() - 1000 * 60 * 60 * 24 * this.deleteExpirationDays);
61
- };
62
- this.deleteExpirationDays = deleteExpirationDays;
63
- }
64
- }
65
- //# sourceMappingURL=FileMetadata.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"FileMetadata.js","sourceRoot":"","sources":["../../../src/files/FileMetadata.ts"],"names":[],"mappings":"AAOA,MAAM,OAAO,YAAY;IAGxB,YACS,EAAY,EACpB,EAAE,oBAAoB,GAAG,CAAC,KAAyB,EAAE;QAD7C,OAAE,GAAF,EAAE,CAAU;QAHb,yBAAoB,GAAG,CAAC,CAAC;QASjC,QAAG,GAAG,CACL,SAAiB,EACjB,MAAc,EAMb,EAAE;YACH,OAAO,IAAI,CAAC,EAAE;iBACZ,OAAO,CACP;;;KAGC,CACD;iBACA,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAC1B,CAAC,CAAC;QAEF,WAAM,GAAG,CAAC,SAAiB,EAAE,EAAE;YAC9B,OAAO,IAAI,CAAC,EAAE;iBACZ,OAAO,CACP;;;GAGD,CACC;iBACA,GAAG,CAAC,SAAS,CAAC,CAAC;QAClB,CAAC,CAAC;QAEF,cAAS,GAAG,CAAC,SAAiB,EAAE,EAAE;YACjC,OAAO,IAAI,CAAC,EAAE;iBACZ,OAAO,CACP;;;GAGD,CACC;iBACA,GAAG,CAAC,SAAS,CAAC,CAAC;QAClB,CAAC,CAAC;QAEF,QAAG,GAAG,CAAC,SAAiB,EAAE,QAAkB,EAAE,EAAE;YAC/C,OAAO,IAAI,CAAC,EAAE;iBACZ,OAAO,CACP;;;KAGC,CACD;iBACA,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;QACjE,CAAC,CAAC;QAEF,sBAAiB,GAAG,CAAC,SAAiB,EAAE,MAAc,EAAE,EAAE;YACzD,OAAO,IAAI,CAAC,EAAE;iBACZ,OAAO,CACP;;;;KAIC,CACD;iBACA,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;QACtC,CAAC,CAAC;QAEF,WAAM,GAAG,CAAC,SAAiB,EAAE,MAAc,EAAE,EAAE;YAC9C,OAAO,IAAI,CAAC,EAAE;iBACZ,OAAO,CACP;;;KAGC,CACD;iBACA,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAC1B,CAAC,CAAC;QAEF,sBAAiB,GAAG,CAAC,SAAiB,EAAE,EAAE;YACzC,OAAO,IAAI,CAAC,EAAE;iBACZ,OAAO,CACP;;;KAGC,CACD;iBACA,GAAG,CACH,SAAS,EACT,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,oBAAoB,CAO3D,CAAC;QACL,CAAC,CAAC;QAhGD,IAAI,CAAC,oBAAoB,GAAG,oBAAoB,CAAC;IAClD,CAAC;CAgGD"}
@@ -1,35 +0,0 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
- import { Readable } from 'stream';
3
- export interface FileInfo {
4
- fileName: string;
5
- id: string;
6
- libraryId: string;
7
- type: string;
8
- }
9
- /**
10
- * The interface for implementing a file storage backend.
11
- * verdant will supply file Blobs and metadata, and the storage backend
12
- * must store them somewhere.
13
- *
14
- * The storage backend must also provide a way to get a URL for the file,
15
- * even if the file is not yet uploaded, based on its metadata.
16
- */
17
- export interface FileStorage {
18
- put(fileStream: Readable, data: FileInfo): Promise<void>;
19
- getUrl(data: FileInfo): string | Promise<string>;
20
- delete(data: FileInfo): Promise<void>;
21
- }
22
- export declare class LocalFileStorage implements FileStorage {
23
- private readonly host;
24
- private readonly rootDirectory;
25
- constructor({ rootDirectory, host, }: {
26
- rootDirectory: string;
27
- host: string;
28
- });
29
- private prepareHost;
30
- put(fileStream: Readable, data: FileInfo): Promise<void>;
31
- getUrl(data: FileInfo): string;
32
- delete(data: FileInfo): Promise<void>;
33
- private getPath;
34
- private getStorageLocation;
35
- }
@@ -1,9 +0,0 @@
1
- export type { MessageSender } from './MessageSender.js';
2
- export type { UserProfiles } from './Profiles.js';
3
- export type { ClientMessage, ServerMessage } from '@verdant-web/common';
4
- export { ReplicaType } from '@verdant-web/common';
5
- export { Server } from './Server.js';
6
- export { TokenProvider } from './TokenProvider.js';
7
- export { LocalFileStorage } from './files/FileStorage.js';
8
- export type { FileStorage, FileInfo } from './files/FileStorage.js';
9
- export type { TokenInfo } from './TokenVerifier.js';
@@ -1 +0,0 @@
1
- export declare const sql = "\nCREATE TABLE IF NOT EXISTS ReplicaInfo (\n id TEXT PRIMARY KEY NOT NULL,\n libraryId TEXT NOT NULL,\n clientId TEXT NOT NULL,\n lastSeenWallClockTime INTEGER,\n ackedLogicalTime TEXT,\n type INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE IF NOT EXISTS OperationHistory (\n libraryId TEXT NOT NULL,\n replicaId TEXT NOT NULL,\n oid TEXT NOT NULL,\n data TEXT NOT NULL,\n timestamp INTEGER NOT NULL,\n PRIMARY KEY (libraryId, replicaId, oid, timestamp)\n);\n\nCREATE TABLE IF NOT EXISTS DocumentBaseline (\n oid TEXT PRIMARY KEY NOT NULL,\n snapshot TEXT,\n timestamp TEXT NOT NULL,\n libraryId TEXT NOT NULL\n);\n";
@@ -1,27 +0,0 @@
1
- export const sql = `
2
- CREATE TABLE IF NOT EXISTS ReplicaInfo (
3
- id TEXT PRIMARY KEY NOT NULL,
4
- libraryId TEXT NOT NULL,
5
- clientId TEXT NOT NULL,
6
- lastSeenWallClockTime INTEGER,
7
- ackedLogicalTime TEXT,
8
- type INTEGER NOT NULL DEFAULT 0
9
- );
10
-
11
- CREATE TABLE IF NOT EXISTS OperationHistory (
12
- libraryId TEXT NOT NULL,
13
- replicaId TEXT NOT NULL,
14
- oid TEXT NOT NULL,
15
- data TEXT NOT NULL,
16
- timestamp INTEGER NOT NULL,
17
- PRIMARY KEY (libraryId, replicaId, oid, timestamp)
18
- );
19
-
20
- CREATE TABLE IF NOT EXISTS DocumentBaseline (
21
- oid TEXT PRIMARY KEY NOT NULL,
22
- snapshot TEXT,
23
- timestamp TEXT NOT NULL,
24
- libraryId TEXT NOT NULL
25
- );
26
- `;
27
- //# sourceMappingURL=v0.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"v0.js","sourceRoot":"","sources":["../../../src/migrations/v0.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,GAAG,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;CAyBlB,CAAC"}