@verdant-web/server 1.8.13 → 1.8.14-next.1

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 (150) hide show
  1. package/dist/cjs/Baselines.d.ts +15 -15
  2. package/dist/cjs/Baselines.js +83 -83
  3. package/dist/cjs/ClientConnection.d.ts +18 -18
  4. package/dist/cjs/ClientConnection.js +105 -105
  5. package/dist/cjs/MessageSender.d.ts +5 -5
  6. package/dist/cjs/MessageSender.js +2 -2
  7. package/dist/cjs/OperationHistory.d.ts +36 -36
  8. package/dist/cjs/OperationHistory.js +120 -120
  9. package/dist/cjs/Presence.d.ts +15 -15
  10. package/dist/cjs/Presence.js +59 -59
  11. package/dist/cjs/Profiles.d.ts +10 -10
  12. package/dist/cjs/Profiles.js +19 -19
  13. package/dist/cjs/ReplicaKeepaliveTimers.d.ts +17 -17
  14. package/dist/cjs/ReplicaKeepaliveTimers.js +30 -30
  15. package/dist/cjs/Replicas.d.ts +24 -24
  16. package/dist/cjs/Replicas.js +137 -137
  17. package/dist/cjs/Server.d.ts +143 -143
  18. package/dist/cjs/Server.js +396 -396
  19. package/dist/cjs/ServerLibrary.d.ts +77 -77
  20. package/dist/cjs/ServerLibrary.js +487 -487
  21. package/dist/cjs/ServerStorage.d.ts +35 -0
  22. package/dist/cjs/ServerStorage.js +60 -0
  23. package/dist/cjs/ServerStorage.js.map +1 -0
  24. package/dist/cjs/TokenProvider.d.ts +16 -16
  25. package/dist/cjs/TokenProvider.js +26 -26
  26. package/dist/cjs/TokenVerifier.d.ts +16 -16
  27. package/dist/cjs/TokenVerifier.js +28 -28
  28. package/dist/cjs/files/FileMetadata.d.ts +28 -28
  29. package/dist/cjs/files/FileMetadata.js +46 -46
  30. package/dist/cjs/files/FileStorage.d.ts +35 -35
  31. package/dist/cjs/files/FileStorage.js +71 -71
  32. package/dist/cjs/index.d.ts +9 -9
  33. package/dist/cjs/index.js +11 -11
  34. package/dist/cjs/migrations/v0.d.ts +1 -0
  35. package/dist/cjs/migrations/v0.js +30 -0
  36. package/dist/cjs/migrations/v0.js.map +1 -0
  37. package/dist/cjs/migrations/v0.sql.d.ts +2 -2
  38. package/dist/cjs/migrations/v0.sql.js +3 -3
  39. package/dist/cjs/migrations/v1.d.ts +1 -0
  40. package/dist/cjs/migrations/v1.js +32 -0
  41. package/dist/cjs/migrations/v1.js.map +1 -0
  42. package/dist/cjs/migrations/v1.sql.d.ts +2 -2
  43. package/dist/cjs/migrations/v1.sql.js +3 -3
  44. package/dist/cjs/migrations/v2.d.ts +1 -0
  45. package/dist/cjs/migrations/v2.js +29 -0
  46. package/dist/cjs/migrations/v2.js.map +1 -0
  47. package/dist/cjs/migrations/v2.sql.d.ts +2 -2
  48. package/dist/cjs/migrations/v2.sql.js +4 -4
  49. package/dist/cjs/migrations/v3.d.ts +1 -0
  50. package/dist/cjs/migrations/v3.js +15 -0
  51. package/dist/cjs/migrations/v3.js.map +1 -0
  52. package/dist/cjs/migrations/v3.sql.d.ts +2 -2
  53. package/dist/cjs/migrations/v3.sql.js +4 -4
  54. package/dist/cjs/migrations/v4.d.ts +1 -0
  55. package/dist/cjs/migrations/v4.js +9 -0
  56. package/dist/cjs/migrations/v4.js.map +1 -0
  57. package/dist/cjs/migrations/v4.sql.d.ts +2 -2
  58. package/dist/cjs/migrations/v4.sql.js +4 -4
  59. package/dist/cjs/migrations/v5.d.ts +2 -0
  60. package/dist/cjs/migrations/v5.js +37 -0
  61. package/dist/cjs/migrations/v5.js.map +1 -0
  62. package/dist/cjs/migrations.d.ts +6 -2
  63. package/dist/cjs/migrations.js +62 -32
  64. package/dist/cjs/migrations.js.map +1 -1
  65. package/dist/cjs/migrations.test.d.ts +1 -0
  66. package/dist/cjs/migrations.test.js +121 -0
  67. package/dist/cjs/migrations.test.js.map +1 -0
  68. package/dist/cjs/types.d.ts +22 -22
  69. package/dist/cjs/types.js +2 -2
  70. package/dist/esm/Baselines.d.ts +15 -15
  71. package/dist/esm/Baselines.js +79 -79
  72. package/dist/esm/ClientConnection.d.ts +18 -18
  73. package/dist/esm/ClientConnection.js +101 -101
  74. package/dist/esm/MessageSender.d.ts +5 -5
  75. package/dist/esm/MessageSender.js +1 -1
  76. package/dist/esm/OperationHistory.d.ts +36 -36
  77. package/dist/esm/OperationHistory.js +116 -116
  78. package/dist/esm/Presence.d.ts +15 -15
  79. package/dist/esm/Presence.js +52 -52
  80. package/dist/esm/Profiles.d.ts +10 -10
  81. package/dist/esm/Profiles.js +15 -15
  82. package/dist/esm/ReplicaKeepaliveTimers.d.ts +17 -17
  83. package/dist/esm/ReplicaKeepaliveTimers.js +26 -26
  84. package/dist/esm/Replicas.d.ts +24 -24
  85. package/dist/esm/Replicas.js +133 -133
  86. package/dist/esm/Server.d.ts +143 -143
  87. package/dist/esm/Server.js +389 -389
  88. package/dist/esm/ServerLibrary.d.ts +77 -77
  89. package/dist/esm/ServerLibrary.js +483 -483
  90. package/dist/esm/ServerStorage.d.ts +44 -0
  91. package/dist/esm/ServerStorage.js +58 -0
  92. package/dist/esm/ServerStorage.js.map +1 -0
  93. package/dist/esm/TokenProvider.d.ts +16 -16
  94. package/dist/esm/TokenProvider.js +19 -19
  95. package/dist/esm/TokenVerifier.d.ts +16 -16
  96. package/dist/esm/TokenVerifier.js +21 -21
  97. package/dist/esm/files/FileMetadata.d.ts +28 -28
  98. package/dist/esm/files/FileMetadata.js +42 -42
  99. package/dist/esm/files/FileStorage.d.ts +35 -35
  100. package/dist/esm/files/FileStorage.js +44 -44
  101. package/dist/esm/index.d.ts +9 -9
  102. package/dist/esm/index.js +4 -4
  103. package/dist/esm/migrations/v0.d.ts +1 -0
  104. package/dist/esm/migrations/v0.js +27 -0
  105. package/dist/esm/migrations/v0.js.map +1 -0
  106. package/dist/esm/migrations/v0.sql.d.ts +2 -2
  107. package/dist/esm/migrations/v0.sql.js +1 -1
  108. package/dist/esm/migrations/v1.d.ts +1 -0
  109. package/dist/esm/migrations/v1.js +29 -0
  110. package/dist/esm/migrations/v1.js.map +1 -0
  111. package/dist/esm/migrations/v1.sql.d.ts +2 -2
  112. package/dist/esm/migrations/v1.sql.js +1 -1
  113. package/dist/esm/migrations/v2.d.ts +1 -0
  114. package/dist/esm/migrations/v2.js +26 -0
  115. package/dist/esm/migrations/v2.js.map +1 -0
  116. package/dist/esm/migrations/v2.sql.d.ts +2 -2
  117. package/dist/esm/migrations/v2.sql.js +2 -2
  118. package/dist/esm/migrations/v3.d.ts +1 -0
  119. package/dist/esm/migrations/v3.js +12 -0
  120. package/dist/esm/migrations/v3.js.map +1 -0
  121. package/dist/esm/migrations/v3.sql.d.ts +2 -2
  122. package/dist/esm/migrations/v3.sql.js +2 -2
  123. package/dist/esm/migrations/v4.d.ts +1 -0
  124. package/dist/esm/migrations/v4.js +6 -0
  125. package/dist/esm/migrations/v4.js.map +1 -0
  126. package/dist/esm/migrations/v4.sql.d.ts +2 -2
  127. package/dist/esm/migrations/v4.sql.js +2 -2
  128. package/dist/esm/migrations/v5.d.ts +2 -0
  129. package/dist/esm/migrations/v5.js +33 -0
  130. package/dist/esm/migrations/v5.js.map +1 -0
  131. package/dist/esm/migrations.d.ts +6 -2
  132. package/dist/esm/migrations.js +35 -25
  133. package/dist/esm/migrations.js.map +1 -1
  134. package/dist/esm/migrations.test.d.ts +1 -0
  135. package/dist/esm/migrations.test.js +116 -0
  136. package/dist/esm/migrations.test.js.map +1 -0
  137. package/dist/esm/types.d.ts +22 -22
  138. package/dist/esm/types.js +1 -1
  139. package/dist/tsconfig-cjs.tsbuildinfo +1 -1
  140. package/dist/tsconfig.tsbuildinfo +1 -1
  141. package/package.json +6 -4
  142. package/src/__snapshots__/migrations.test.ts.snap +55 -0
  143. package/src/migrations/{v0.sql.ts → v0.ts} +1 -1
  144. package/src/migrations/{v1.sql.ts → v1.ts} +1 -1
  145. package/src/migrations/{v2.sql.ts → v2.ts} +1 -1
  146. package/src/migrations/{v3.sql.ts → v3.ts} +1 -1
  147. package/src/migrations/{v4.sql.ts → v4.ts} +1 -1
  148. package/src/migrations/v5.ts +49 -0
  149. package/src/migrations.test.ts +133 -0
  150. package/src/migrations.ts +28 -19
@@ -0,0 +1,55 @@
1
+ // Vitest Snapshot v1
2
+
3
+ exports[`the v5->v6 migration > rewrites legacy oids in all ops and baselines 1`] = `
4
+ [
5
+ {
6
+ "data": "{\\"op\\":\\"set\\",\\"value\\":{\\"@@type\\":\\"ref\\",\\"id\\":\\"weirds/b:ghi\\"}}",
7
+ "libraryId": "test-1",
8
+ "oid": "weirds/b",
9
+ "replicaId": "foo",
10
+ "serverOrder": 1,
11
+ "timestamp": 1,
12
+ },
13
+ {
14
+ "data": "{\\"op\\":\\"list-push\\",\\"value\\":{\\"@@type\\":\\"ref\\",\\"id\\":\\"weirds/b:abc\\"}}",
15
+ "libraryId": "test-1",
16
+ "oid": "weirds/b:ghi",
17
+ "replicaId": "foo",
18
+ "serverOrder": 2,
19
+ "timestamp": 1,
20
+ },
21
+ {
22
+ "data": "{\\"op\\":\\"list-remove\\",\\"value\\":{\\"@@type\\":\\"ref\\",\\"id\\":\\"weirds/b:abc\\"}}",
23
+ "libraryId": "test-1",
24
+ "oid": "weirds/b:ghi",
25
+ "replicaId": "foo",
26
+ "serverOrder": 3,
27
+ "timestamp": 2,
28
+ },
29
+ {
30
+ "data": "{\\"op\\":\\"set\\",\\"value\\":{\\"@@type\\":\\"ref\\",\\"id\\":\\"weirds/b:ghi\\"}}",
31
+ "libraryId": "test-2",
32
+ "oid": "weirds/b",
33
+ "replicaId": "bar",
34
+ "serverOrder": 1,
35
+ "timestamp": "1a",
36
+ },
37
+ ]
38
+ `;
39
+
40
+ exports[`the v5->v6 migration > rewrites legacy oids in all ops and baselines 2`] = `
41
+ [
42
+ {
43
+ "libraryId": "test-1",
44
+ "oid": "weirds/b:ghi",
45
+ "snapshot": "{\\"@@type\\":\\"ref\\",\\"id\\":\\"weirds/b:abc\\"}",
46
+ "timestamp": "1",
47
+ },
48
+ {
49
+ "libraryId": "test-2",
50
+ "oid": "weirds/b:ghi",
51
+ "snapshot": "{\\"@@type\\":\\"ref\\",\\"id\\":\\"weirds/b:abc\\"}",
52
+ "timestamp": "1a",
53
+ },
54
+ ]
55
+ `;
@@ -1,4 +1,4 @@
1
- export default `
1
+ export const sql = `
2
2
  CREATE TABLE IF NOT EXISTS ReplicaInfo (
3
3
  id TEXT PRIMARY KEY NOT NULL,
4
4
  libraryId TEXT NOT NULL,
@@ -1,4 +1,4 @@
1
- export default `
1
+ export const sql = `
2
2
  ALTER TABLE
3
3
  ReplicaInfo RENAME TO ReplicaInfoOld;
4
4
 
@@ -1,6 +1,6 @@
1
1
  // fixes primary key for document baselines to include libraryId
2
2
 
3
- export default `
3
+ export const sql = `
4
4
  ALTER TABLE
5
5
  DocumentBaseline RENAME TO DocumentBaselineOld;
6
6
 
@@ -1,6 +1,6 @@
1
1
  // add the FileMetadata table
2
2
 
3
- export default `
3
+ export const sql = `
4
4
  CREATE TABLE IF NOT EXISTS FileMetadata (
5
5
  libraryId TEXT NOT NULL,
6
6
  fileId TEXT NOT NULL,
@@ -1,6 +1,6 @@
1
1
  // add server order to replicas and operations
2
2
 
3
- export default `
3
+ export const sql = `
4
4
  ALTER TABLE ReplicaInfo ADD COLUMN ackedServerOrder INTEGER DEFAULT 0 NOT NULL;
5
5
  ALTER TABLE OperationHistory ADD COLUMN serverOrder INTEGER DEFAULT 0 NOT NULL;
6
6
  `;
@@ -0,0 +1,49 @@
1
+ import {
2
+ convertLegacyOid,
3
+ replaceLegacyOidsInJsonString,
4
+ } from '@verdant-web/common';
5
+ import SQL from 'better-sqlite3';
6
+
7
+ // read all operations and write them back without legacy IDs.
8
+ export const procedure = (db: SQL.Database) => {
9
+ const operations = db
10
+ .prepare(/* sql */ `SELECT * from OperationHistory;`)
11
+ .all();
12
+ for (const op of operations) {
13
+ db.prepare(
14
+ /* sql */ `
15
+ UPDATE OperationHistory
16
+ SET oid = ?,
17
+ data = ?
18
+ WHERE oid = ? AND timestamp = ? AND libraryId = ?;
19
+ `,
20
+ ).run(
21
+ convertLegacyOid(op.oid),
22
+ // data is already a string, so just leave it and do the conversion on the string
23
+ op.data ? replaceLegacyOidsInJsonString(op.data) : op.data,
24
+ op.oid,
25
+ op.timestamp,
26
+ op.libraryId,
27
+ );
28
+ }
29
+ const baselines = db
30
+ .prepare(/* sql */ `SELECT * from DocumentBaseline;`)
31
+ .all();
32
+ for (const baseline of baselines) {
33
+ db.prepare(
34
+ /* sql */ `
35
+ UPDATE DocumentBaseline
36
+ SET oid = ?,
37
+ snapshot = ?
38
+ WHERE oid = ? AND libraryId = ?;
39
+ `,
40
+ ).run(
41
+ convertLegacyOid(baseline.oid),
42
+ baseline.snapshot
43
+ ? replaceLegacyOidsInJsonString(baseline.snapshot)
44
+ : baseline.snapshot,
45
+ baseline.oid,
46
+ baseline.libraryId,
47
+ );
48
+ }
49
+ };
@@ -0,0 +1,133 @@
1
+ import { describe, it, expect, afterAll, beforeAll } from 'vitest';
2
+ import create from 'better-sqlite3';
3
+ import { migrations } from './migrations.js';
4
+ import fs from 'fs';
5
+
6
+ describe('the v5->v6 migration', () => {
7
+ let dbFile: string;
8
+ let db: create.Database;
9
+ beforeAll(() => {
10
+ dbFile = `v5-migration-test-${Math.random()}.sqlite`;
11
+ db = create(dbFile);
12
+ });
13
+ afterAll(() => {
14
+ db.close();
15
+ fs.rmSync(dbFile);
16
+ });
17
+
18
+ it('rewrites legacy oids in all ops and baselines', () => {
19
+ // manually migrate to v4 before starting and seed the database with some
20
+ // operations and baselines.
21
+ migrations(db, 5);
22
+ // manually insert some operations and baselines
23
+ db.transaction(() => {
24
+ [
25
+ {
26
+ libraryId: 'test-1',
27
+ replicaId: 'foo',
28
+ oid: 'weirds/b',
29
+ data: {
30
+ op: 'set',
31
+ value: { '@@type': 'ref', id: 'weirds/b.objectMap.one:ghi' },
32
+ },
33
+ timestamp: '1',
34
+ serverOrder: 1,
35
+ },
36
+ {
37
+ libraryId: 'test-1',
38
+ replicaId: 'foo',
39
+ oid: 'weirds/b.list:ghi',
40
+ data: {
41
+ op: 'list-push',
42
+ value: { '@@type': 'ref', id: 'weirds/b.list.#:abc' },
43
+ },
44
+ timestamp: '1',
45
+ serverOrder: 2,
46
+ },
47
+ {
48
+ libraryId: 'test-1',
49
+ replicaId: 'foo',
50
+ oid: 'weirds/b.list:ghi',
51
+ data: {
52
+ op: 'list-remove',
53
+ value: { '@@type': 'ref', id: 'weirds/b.list.#:abc' },
54
+ },
55
+ timestamp: '2',
56
+ serverOrder: 3,
57
+ },
58
+ {
59
+ libraryId: 'test-2',
60
+ replicaId: 'bar',
61
+ oid: 'weirds/b',
62
+ data: {
63
+ op: 'set',
64
+ value: { '@@type': 'ref', id: 'weirds/b.objectMap.one:ghi' },
65
+ },
66
+ timestamp: '1a',
67
+ serverOrder: 1,
68
+ },
69
+ ].forEach(
70
+ ({ libraryId, replicaId, oid, data, timestamp, serverOrder }) => {
71
+ db.prepare(
72
+ /* sql */ `
73
+ INSERT INTO OperationHistory (libraryId, replicaId, oid, data, timestamp, serverOrder)
74
+ VALUES (?, ?, ?, ?, ?, ?);
75
+ `,
76
+ ).run(
77
+ libraryId,
78
+ replicaId,
79
+ oid,
80
+ JSON.stringify(data),
81
+ timestamp,
82
+ serverOrder,
83
+ );
84
+ },
85
+ );
86
+ [
87
+ {
88
+ libraryId: 'test-1',
89
+ oid: 'weirds/b.objectMap.one:ghi',
90
+ snapshot: { '@@type': 'ref', id: 'weirds/b.list.#:abc' },
91
+ timestamp: '1',
92
+ },
93
+ {
94
+ libraryId: 'test-2',
95
+ oid: 'weirds/b.objectMap.one:ghi',
96
+ snapshot: { '@@type': 'ref', id: 'weirds/b.list.#:abc' },
97
+ timestamp: '1a',
98
+ },
99
+ ].forEach(({ libraryId, oid, snapshot, timestamp }) => {
100
+ db.prepare(
101
+ /* sql */ `
102
+ INSERT INTO DocumentBaseline (libraryId, oid, snapshot, timestamp)
103
+ VALUES (?, ?, ?, ?);
104
+ `,
105
+ ).run(libraryId, oid, JSON.stringify(snapshot), timestamp);
106
+ });
107
+ })();
108
+
109
+ migrations(db);
110
+
111
+ // check that the operations and baselines have been rewritten
112
+ db.transaction(() => {
113
+ const operations = db
114
+ .prepare(
115
+ /* sql */ `
116
+ SELECT * from OperationHistory;
117
+ `,
118
+ )
119
+ .all();
120
+ expect(operations).toMatchSnapshot();
121
+ const baselines = db
122
+ .prepare(
123
+ /* sql */ `
124
+ SELECT * from DocumentBaseline;
125
+ `,
126
+ )
127
+ .all();
128
+ expect(baselines).toMatchSnapshot();
129
+ })();
130
+
131
+ db.close();
132
+ });
133
+ });
package/src/migrations.ts CHANGED
@@ -1,13 +1,17 @@
1
1
  import type { Database } from 'better-sqlite3';
2
- import v0Sql from './migrations/v0.sql.js';
3
- import v1Sql from './migrations/v1.sql.js';
4
- import v2Sql from './migrations/v2.sql.js';
5
- import v3Sql from './migrations/v3.sql.js';
6
- import v4Sql from './migrations/v4.sql.js';
7
-
8
- const allMigrations = [v0Sql, v1Sql, v2Sql, v3Sql, v4Sql];
9
-
10
- export function migrations(db: Database) {
2
+ import * as v0 from './migrations/v0.js';
3
+ import * as v1 from './migrations/v1.js';
4
+ import * as v2 from './migrations/v2.js';
5
+ import * as v3 from './migrations/v3.js';
6
+ import * as v4 from './migrations/v4.js';
7
+ import * as v5 from './migrations/v5.js';
8
+
9
+ export const allMigrations: {
10
+ sql?: string;
11
+ procedure?: (db: Database) => void;
12
+ }[] = [v0, v1, v2, v3, v4, v5];
13
+
14
+ export function migrations(db: Database, upTo: number = allMigrations.length) {
11
15
  // create the versions table if it doesn't exist
12
16
  db.prepare(
13
17
  `
@@ -27,24 +31,29 @@ export function migrations(db: Database) {
27
31
  .get() as { version: number } | undefined;
28
32
  const version = versionResult?.version ?? 0;
29
33
 
30
- const sqlToRun = allMigrations.slice(version);
34
+ const toRun = allMigrations.slice(version, upTo);
31
35
 
32
- if (sqlToRun.length === 0) return;
36
+ if (toRun.length === 0) {
37
+ console.info('No migrations to run');
38
+ return;
39
+ }
33
40
 
34
- console.info(
35
- 'Running migrations from ',
36
- version,
37
- 'to',
38
- allMigrations.length - 1,
39
- );
41
+ console.info('Running migrations from ', version, 'to', upTo);
40
42
 
41
43
  const run = db.transaction(() => {
42
- sqlToRun.forEach((sql) => db.exec(sql));
44
+ for (const { sql, procedure } of toRun) {
45
+ if (sql) {
46
+ db.exec(sql);
47
+ }
48
+ if (procedure) {
49
+ procedure(db);
50
+ }
51
+ }
43
52
  db.prepare(
44
53
  `
45
54
  INSERT INTO versions (version) VALUES (?);
46
55
  `,
47
- ).run(allMigrations.length);
56
+ ).run(upTo);
48
57
  });
49
58
 
50
59
  run();