@verdant-web/server 1.8.13 → 1.8.14-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.
- package/dist/cjs/Baselines.d.ts +15 -15
- package/dist/cjs/Baselines.js +83 -83
- package/dist/cjs/ClientConnection.d.ts +18 -18
- package/dist/cjs/ClientConnection.js +105 -105
- package/dist/cjs/MessageSender.d.ts +5 -5
- package/dist/cjs/MessageSender.js +2 -2
- package/dist/cjs/OperationHistory.d.ts +36 -36
- package/dist/cjs/OperationHistory.js +120 -120
- package/dist/cjs/Presence.d.ts +15 -15
- package/dist/cjs/Presence.js +59 -59
- package/dist/cjs/Profiles.d.ts +10 -10
- package/dist/cjs/Profiles.js +19 -19
- package/dist/cjs/ReplicaKeepaliveTimers.d.ts +17 -17
- package/dist/cjs/ReplicaKeepaliveTimers.js +30 -30
- package/dist/cjs/Replicas.d.ts +24 -24
- package/dist/cjs/Replicas.js +137 -137
- package/dist/cjs/Server.d.ts +143 -143
- package/dist/cjs/Server.js +396 -396
- package/dist/cjs/ServerLibrary.d.ts +77 -77
- package/dist/cjs/ServerLibrary.js +487 -487
- package/dist/cjs/ServerStorage.d.ts +35 -0
- package/dist/cjs/ServerStorage.js +60 -0
- package/dist/cjs/ServerStorage.js.map +1 -0
- package/dist/cjs/TokenProvider.d.ts +16 -16
- package/dist/cjs/TokenProvider.js +26 -26
- package/dist/cjs/TokenVerifier.d.ts +16 -16
- package/dist/cjs/TokenVerifier.js +28 -28
- package/dist/cjs/files/FileMetadata.d.ts +28 -28
- package/dist/cjs/files/FileMetadata.js +46 -46
- package/dist/cjs/files/FileStorage.d.ts +35 -35
- package/dist/cjs/files/FileStorage.js +71 -71
- package/dist/cjs/index.d.ts +9 -9
- package/dist/cjs/index.js +11 -11
- package/dist/cjs/migrations/v0.d.ts +1 -0
- package/dist/cjs/migrations/v0.js +30 -0
- package/dist/cjs/migrations/v0.js.map +1 -0
- package/dist/cjs/migrations/v0.sql.d.ts +2 -2
- package/dist/cjs/migrations/v0.sql.js +3 -3
- package/dist/cjs/migrations/v1.d.ts +1 -0
- package/dist/cjs/migrations/v1.js +32 -0
- package/dist/cjs/migrations/v1.js.map +1 -0
- package/dist/cjs/migrations/v1.sql.d.ts +2 -2
- package/dist/cjs/migrations/v1.sql.js +3 -3
- package/dist/cjs/migrations/v2.d.ts +1 -0
- package/dist/cjs/migrations/v2.js +29 -0
- package/dist/cjs/migrations/v2.js.map +1 -0
- package/dist/cjs/migrations/v2.sql.d.ts +2 -2
- package/dist/cjs/migrations/v2.sql.js +4 -4
- package/dist/cjs/migrations/v3.d.ts +1 -0
- package/dist/cjs/migrations/v3.js +15 -0
- package/dist/cjs/migrations/v3.js.map +1 -0
- package/dist/cjs/migrations/v3.sql.d.ts +2 -2
- package/dist/cjs/migrations/v3.sql.js +4 -4
- package/dist/cjs/migrations/v4.d.ts +1 -0
- package/dist/cjs/migrations/v4.js +9 -0
- package/dist/cjs/migrations/v4.js.map +1 -0
- package/dist/cjs/migrations/v4.sql.d.ts +2 -2
- package/dist/cjs/migrations/v4.sql.js +4 -4
- package/dist/cjs/migrations/v5.d.ts +2 -0
- package/dist/cjs/migrations/v5.js +35 -0
- package/dist/cjs/migrations/v5.js.map +1 -0
- package/dist/cjs/migrations.d.ts +6 -2
- package/dist/cjs/migrations.js +62 -32
- package/dist/cjs/migrations.js.map +1 -1
- package/dist/cjs/migrations.test.d.ts +1 -0
- package/dist/cjs/migrations.test.js +121 -0
- package/dist/cjs/migrations.test.js.map +1 -0
- package/dist/cjs/types.d.ts +22 -22
- package/dist/cjs/types.js +2 -2
- package/dist/esm/Baselines.d.ts +15 -15
- package/dist/esm/Baselines.js +79 -79
- package/dist/esm/ClientConnection.d.ts +18 -18
- package/dist/esm/ClientConnection.js +101 -101
- package/dist/esm/MessageSender.d.ts +5 -5
- package/dist/esm/MessageSender.js +1 -1
- package/dist/esm/OperationHistory.d.ts +36 -36
- package/dist/esm/OperationHistory.js +116 -116
- package/dist/esm/Presence.d.ts +15 -15
- package/dist/esm/Presence.js +52 -52
- package/dist/esm/Profiles.d.ts +10 -10
- package/dist/esm/Profiles.js +15 -15
- package/dist/esm/ReplicaKeepaliveTimers.d.ts +17 -17
- package/dist/esm/ReplicaKeepaliveTimers.js +26 -26
- package/dist/esm/Replicas.d.ts +24 -24
- package/dist/esm/Replicas.js +133 -133
- package/dist/esm/Server.d.ts +143 -143
- package/dist/esm/Server.js +389 -389
- package/dist/esm/ServerLibrary.d.ts +77 -77
- package/dist/esm/ServerLibrary.js +483 -483
- package/dist/esm/ServerStorage.d.ts +44 -0
- package/dist/esm/ServerStorage.js +58 -0
- package/dist/esm/ServerStorage.js.map +1 -0
- package/dist/esm/TokenProvider.d.ts +16 -16
- package/dist/esm/TokenProvider.js +19 -19
- package/dist/esm/TokenVerifier.d.ts +16 -16
- package/dist/esm/TokenVerifier.js +21 -21
- package/dist/esm/files/FileMetadata.d.ts +28 -28
- package/dist/esm/files/FileMetadata.js +42 -42
- package/dist/esm/files/FileStorage.d.ts +35 -35
- package/dist/esm/files/FileStorage.js +44 -44
- package/dist/esm/index.d.ts +9 -9
- package/dist/esm/index.js +4 -4
- package/dist/esm/migrations/v0.d.ts +1 -0
- package/dist/esm/migrations/v0.js +27 -0
- package/dist/esm/migrations/v0.js.map +1 -0
- package/dist/esm/migrations/v0.sql.d.ts +2 -2
- package/dist/esm/migrations/v0.sql.js +1 -1
- package/dist/esm/migrations/v1.d.ts +1 -0
- package/dist/esm/migrations/v1.js +29 -0
- package/dist/esm/migrations/v1.js.map +1 -0
- package/dist/esm/migrations/v1.sql.d.ts +2 -2
- package/dist/esm/migrations/v1.sql.js +1 -1
- package/dist/esm/migrations/v2.d.ts +1 -0
- package/dist/esm/migrations/v2.js +26 -0
- package/dist/esm/migrations/v2.js.map +1 -0
- package/dist/esm/migrations/v2.sql.d.ts +2 -2
- package/dist/esm/migrations/v2.sql.js +2 -2
- package/dist/esm/migrations/v3.d.ts +1 -0
- package/dist/esm/migrations/v3.js +12 -0
- package/dist/esm/migrations/v3.js.map +1 -0
- package/dist/esm/migrations/v3.sql.d.ts +2 -2
- package/dist/esm/migrations/v3.sql.js +2 -2
- package/dist/esm/migrations/v4.d.ts +1 -0
- package/dist/esm/migrations/v4.js +6 -0
- package/dist/esm/migrations/v4.js.map +1 -0
- package/dist/esm/migrations/v4.sql.d.ts +2 -2
- package/dist/esm/migrations/v4.sql.js +2 -2
- package/dist/esm/migrations/v5.d.ts +2 -0
- package/dist/esm/migrations/v5.js +31 -0
- package/dist/esm/migrations/v5.js.map +1 -0
- package/dist/esm/migrations.d.ts +6 -2
- package/dist/esm/migrations.js +35 -25
- package/dist/esm/migrations.js.map +1 -1
- package/dist/esm/migrations.test.d.ts +1 -0
- package/dist/esm/migrations.test.js +116 -0
- package/dist/esm/migrations.test.js.map +1 -0
- package/dist/esm/types.d.ts +22 -22
- package/dist/esm/types.js +1 -1
- package/dist/tsconfig-cjs.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -4
- package/src/__snapshots__/migrations.test.ts.snap +55 -0
- package/src/migrations/{v0.sql.ts → v0.ts} +1 -1
- package/src/migrations/{v1.sql.ts → v1.ts} +1 -1
- package/src/migrations/{v2.sql.ts → v2.ts} +1 -1
- package/src/migrations/{v3.sql.ts → v3.ts} +1 -1
- package/src/migrations/{v4.sql.ts → v4.ts} +1 -1
- package/src/migrations/v5.ts +47 -0
- package/src/migrations.test.ts +133 -0
- package/src/migrations.ts +28 -19
package/dist/cjs/Baselines.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { DocumentBaseline, Operation, Ref } from '@verdant-web/common';
|
|
2
|
-
import { Database } from 'better-sqlite3';
|
|
3
|
-
export declare class Baselines {
|
|
4
|
-
private db;
|
|
5
|
-
constructor(db: Database);
|
|
6
|
-
get: (libraryId: string, oid: string) => DocumentBaseline<any> | null;
|
|
7
|
-
getAllWithSubObjects: (libraryId: string, oid: string) => DocumentBaseline<any>[];
|
|
8
|
-
set: (libraryId: string, baseline: DocumentBaseline) => import("better-sqlite3").RunResult;
|
|
9
|
-
insertAll: (libraryId: string, baselines: DocumentBaseline[]) => void;
|
|
10
|
-
private hydrateSnapshot;
|
|
11
|
-
getAllAfter: (libraryId: string, timestamp: string | null) => DocumentBaseline<any>[];
|
|
12
|
-
applyOperations: (libraryId: string, oid: string, operations: Operation[], deletedRefs?: Ref[]) => never[] | undefined;
|
|
13
|
-
deleteAll: (libraryId: string) => void;
|
|
14
|
-
getCount: (libraryId: string) => number;
|
|
15
|
-
}
|
|
1
|
+
import { DocumentBaseline, Operation, Ref } from '@verdant-web/common';
|
|
2
|
+
import { Database } from 'better-sqlite3';
|
|
3
|
+
export declare class Baselines {
|
|
4
|
+
private db;
|
|
5
|
+
constructor(db: Database);
|
|
6
|
+
get: (libraryId: string, oid: string) => DocumentBaseline<any> | null;
|
|
7
|
+
getAllWithSubObjects: (libraryId: string, oid: string) => DocumentBaseline<any>[];
|
|
8
|
+
set: (libraryId: string, baseline: DocumentBaseline) => import("better-sqlite3").RunResult;
|
|
9
|
+
insertAll: (libraryId: string, baselines: DocumentBaseline[]) => void;
|
|
10
|
+
private hydrateSnapshot;
|
|
11
|
+
getAllAfter: (libraryId: string, timestamp: string | null) => DocumentBaseline<any>[];
|
|
12
|
+
applyOperations: (libraryId: string, oid: string, operations: Operation[], deletedRefs?: Ref[]) => never[] | undefined;
|
|
13
|
+
deleteAll: (libraryId: string) => void;
|
|
14
|
+
getCount: (libraryId: string) => number;
|
|
15
|
+
}
|
package/dist/cjs/Baselines.js
CHANGED
|
@@ -1,110 +1,110 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Baselines = void 0;
|
|
4
|
-
const common_1 = require("@verdant-web/common");
|
|
5
|
-
class Baselines {
|
|
6
|
-
constructor(db) {
|
|
7
|
-
this.db = db;
|
|
8
|
-
this.get = (libraryId, oid) => {
|
|
9
|
-
const row = this.db
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Baselines = void 0;
|
|
4
|
+
const common_1 = require("@verdant-web/common");
|
|
5
|
+
class Baselines {
|
|
6
|
+
constructor(db) {
|
|
7
|
+
this.db = db;
|
|
8
|
+
this.get = (libraryId, oid) => {
|
|
9
|
+
const row = this.db
|
|
10
10
|
.prepare(`
|
|
11
11
|
SELECT * FROM DocumentBaseline
|
|
12
12
|
WHERE libraryId = ? AND oid = ?
|
|
13
|
-
`)
|
|
14
|
-
.get(libraryId, oid);
|
|
15
|
-
if (!row) {
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
18
|
-
return this.hydrateSnapshot(row);
|
|
19
|
-
};
|
|
20
|
-
this.getAllWithSubObjects = (libraryId, oid) => {
|
|
21
|
-
const rows = this.db
|
|
13
|
+
`)
|
|
14
|
+
.get(libraryId, oid);
|
|
15
|
+
if (!row) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
return this.hydrateSnapshot(row);
|
|
19
|
+
};
|
|
20
|
+
this.getAllWithSubObjects = (libraryId, oid) => {
|
|
21
|
+
const rows = this.db
|
|
22
22
|
.prepare(`
|
|
23
23
|
SELECT * FROM DocumentBaseline
|
|
24
24
|
WHERE libraryId = ? AND oid LIKE ?
|
|
25
|
-
`)
|
|
26
|
-
.all(libraryId, `${oid}%`);
|
|
27
|
-
return rows.map(this.hydrateSnapshot);
|
|
28
|
-
};
|
|
29
|
-
this.set = (libraryId, baseline) => {
|
|
30
|
-
return this.db
|
|
25
|
+
`)
|
|
26
|
+
.all(libraryId, `${oid}%`);
|
|
27
|
+
return rows.map(this.hydrateSnapshot);
|
|
28
|
+
};
|
|
29
|
+
this.set = (libraryId, baseline) => {
|
|
30
|
+
return this.db
|
|
31
31
|
.prepare(`
|
|
32
32
|
INSERT OR REPLACE INTO DocumentBaseline (libraryId, oid, snapshot, timestamp)
|
|
33
33
|
VALUES (?, ?, ?, ?)
|
|
34
|
-
`)
|
|
35
|
-
.run(libraryId, baseline.oid, JSON.stringify(baseline.snapshot), baseline.timestamp);
|
|
36
|
-
};
|
|
37
|
-
this.insertAll = (libraryId, baselines) => {
|
|
38
|
-
const tx = this.db.transaction(() => {
|
|
39
|
-
for (const baseline of baselines) {
|
|
40
|
-
this.db
|
|
34
|
+
`)
|
|
35
|
+
.run(libraryId, baseline.oid, JSON.stringify(baseline.snapshot), baseline.timestamp);
|
|
36
|
+
};
|
|
37
|
+
this.insertAll = (libraryId, baselines) => {
|
|
38
|
+
const tx = this.db.transaction(() => {
|
|
39
|
+
for (const baseline of baselines) {
|
|
40
|
+
this.db
|
|
41
41
|
.prepare(`
|
|
42
42
|
INSERT OR REPLACE INTO DocumentBaseline (libraryId, oid, snapshot, timestamp)
|
|
43
43
|
VALUES (?, ?, ?, ?)
|
|
44
|
-
`)
|
|
45
|
-
.run(libraryId, baseline.oid, JSON.stringify(baseline.snapshot), baseline.timestamp);
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
tx();
|
|
49
|
-
};
|
|
50
|
-
this.hydrateSnapshot = (snapshot) => {
|
|
51
|
-
return Object.assign(Object.assign({}, snapshot), { snapshot: JSON.parse(snapshot.snapshot) });
|
|
52
|
-
};
|
|
53
|
-
this.getAllAfter = (libraryId, timestamp) => {
|
|
54
|
-
if (!timestamp) {
|
|
55
|
-
return this.db
|
|
44
|
+
`)
|
|
45
|
+
.run(libraryId, baseline.oid, JSON.stringify(baseline.snapshot), baseline.timestamp);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
tx();
|
|
49
|
+
};
|
|
50
|
+
this.hydrateSnapshot = (snapshot) => {
|
|
51
|
+
return Object.assign(Object.assign({}, snapshot), { snapshot: JSON.parse(snapshot.snapshot) });
|
|
52
|
+
};
|
|
53
|
+
this.getAllAfter = (libraryId, timestamp) => {
|
|
54
|
+
if (!timestamp) {
|
|
55
|
+
return this.db
|
|
56
56
|
.prepare(`
|
|
57
57
|
SELECT * FROM DocumentBaseline
|
|
58
58
|
WHERE libraryId = ?
|
|
59
59
|
ORDER BY timestamp ASC
|
|
60
|
-
`)
|
|
61
|
-
.all(libraryId)
|
|
62
|
-
.map(this.hydrateSnapshot);
|
|
63
|
-
}
|
|
64
|
-
return this.db
|
|
60
|
+
`)
|
|
61
|
+
.all(libraryId)
|
|
62
|
+
.map(this.hydrateSnapshot);
|
|
63
|
+
}
|
|
64
|
+
return this.db
|
|
65
65
|
.prepare(`
|
|
66
66
|
SELECT * FROM DocumentBaseline
|
|
67
67
|
WHERE libraryId = ? AND timestamp > ?
|
|
68
68
|
ORDER BY timestamp ASC
|
|
69
|
-
`)
|
|
70
|
-
.all(libraryId, timestamp)
|
|
71
|
-
.map(this.hydrateSnapshot);
|
|
72
|
-
};
|
|
73
|
-
this.applyOperations = (libraryId, oid, operations, deletedRefs) => {
|
|
74
|
-
if (operations.length === 0)
|
|
75
|
-
return [];
|
|
76
|
-
let baseline = this.get(libraryId, oid);
|
|
77
|
-
if (!baseline) {
|
|
78
|
-
baseline = {
|
|
79
|
-
oid,
|
|
80
|
-
snapshot: {},
|
|
81
|
-
timestamp: operations[0].timestamp,
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
for (const operation of operations) {
|
|
85
|
-
baseline.snapshot = (0, common_1.applyPatch)(baseline.snapshot, operation.data, deletedRefs);
|
|
86
|
-
}
|
|
87
|
-
baseline.timestamp = operations[operations.length - 1].timestamp;
|
|
88
|
-
this.set(libraryId, baseline);
|
|
89
|
-
};
|
|
90
|
-
this.deleteAll = (libraryId) => {
|
|
91
|
-
this.db
|
|
69
|
+
`)
|
|
70
|
+
.all(libraryId, timestamp)
|
|
71
|
+
.map(this.hydrateSnapshot);
|
|
72
|
+
};
|
|
73
|
+
this.applyOperations = (libraryId, oid, operations, deletedRefs) => {
|
|
74
|
+
if (operations.length === 0)
|
|
75
|
+
return [];
|
|
76
|
+
let baseline = this.get(libraryId, oid);
|
|
77
|
+
if (!baseline) {
|
|
78
|
+
baseline = {
|
|
79
|
+
oid,
|
|
80
|
+
snapshot: {},
|
|
81
|
+
timestamp: operations[0].timestamp,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
for (const operation of operations) {
|
|
85
|
+
baseline.snapshot = (0, common_1.applyPatch)(baseline.snapshot, operation.data, deletedRefs);
|
|
86
|
+
}
|
|
87
|
+
baseline.timestamp = operations[operations.length - 1].timestamp;
|
|
88
|
+
this.set(libraryId, baseline);
|
|
89
|
+
};
|
|
90
|
+
this.deleteAll = (libraryId) => {
|
|
91
|
+
this.db
|
|
92
92
|
.prepare(`
|
|
93
93
|
DELETE FROM DocumentBaseline
|
|
94
94
|
WHERE libraryId = ?
|
|
95
|
-
`)
|
|
96
|
-
.run(libraryId);
|
|
97
|
-
};
|
|
98
|
-
this.getCount = (libraryId) => {
|
|
99
|
-
var _a, _b;
|
|
100
|
-
return ((_b = (_a = this.db
|
|
95
|
+
`)
|
|
96
|
+
.run(libraryId);
|
|
97
|
+
};
|
|
98
|
+
this.getCount = (libraryId) => {
|
|
99
|
+
var _a, _b;
|
|
100
|
+
return ((_b = (_a = this.db
|
|
101
101
|
.prepare(`
|
|
102
102
|
SELECT COUNT(*) AS count FROM DocumentBaseline
|
|
103
103
|
WHERE libraryId = ?
|
|
104
|
-
`)
|
|
105
|
-
.get(libraryId)) === null || _a === void 0 ? void 0 : _a.count) !== null && _b !== void 0 ? _b : 0);
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
exports.Baselines = Baselines;
|
|
104
|
+
`)
|
|
105
|
+
.get(libraryId)) === null || _a === void 0 ? void 0 : _a.count) !== null && _b !== void 0 ? _b : 0);
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
exports.Baselines = Baselines;
|
|
110
110
|
//# sourceMappingURL=Baselines.js.map
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { ServerMessage } from '@verdant-web/common';
|
|
2
|
-
import { IncomingMessage, ServerResponse } from 'http';
|
|
3
|
-
import { WebSocket } from 'ws';
|
|
4
|
-
import { TokenInfo } from './TokenVerifier.js';
|
|
5
|
-
export declare class ClientConnectionManager {
|
|
6
|
-
private readonly connections;
|
|
7
|
-
private getLibraryConnections;
|
|
8
|
-
addSocket: (libraryId: string, key: string, socket: WebSocket, info: TokenInfo) => void;
|
|
9
|
-
addRequest: (libraryId: string, key: string, request: IncomingMessage, response: ServerResponse, info: TokenInfo) => () => void;
|
|
10
|
-
remove: (libraryId: string, key: string) => void;
|
|
11
|
-
respond: (libraryId: string, key: string, message: ServerMessage) => void;
|
|
12
|
-
/**
|
|
13
|
-
* Broadcasts a message to all live-connected clients in a library.
|
|
14
|
-
* This does not reach push/pull clients.
|
|
15
|
-
*/
|
|
16
|
-
broadcast: (libraryId: string, message: ServerMessage, omitKeys?: string[]) => void;
|
|
17
|
-
disconnectAll: (libraryId: string) => void;
|
|
18
|
-
}
|
|
1
|
+
import { ServerMessage } from '@verdant-web/common';
|
|
2
|
+
import { IncomingMessage, ServerResponse } from 'http';
|
|
3
|
+
import { WebSocket } from 'ws';
|
|
4
|
+
import { TokenInfo } from './TokenVerifier.js';
|
|
5
|
+
export declare class ClientConnectionManager {
|
|
6
|
+
private readonly connections;
|
|
7
|
+
private getLibraryConnections;
|
|
8
|
+
addSocket: (libraryId: string, key: string, socket: WebSocket, info: TokenInfo) => void;
|
|
9
|
+
addRequest: (libraryId: string, key: string, request: IncomingMessage, response: ServerResponse, info: TokenInfo) => () => void;
|
|
10
|
+
remove: (libraryId: string, key: string) => void;
|
|
11
|
+
respond: (libraryId: string, key: string, message: ServerMessage) => void;
|
|
12
|
+
/**
|
|
13
|
+
* Broadcasts a message to all live-connected clients in a library.
|
|
14
|
+
* This does not reach push/pull clients.
|
|
15
|
+
*/
|
|
16
|
+
broadcast: (libraryId: string, message: ServerMessage, omitKeys?: string[]) => void;
|
|
17
|
+
disconnectAll: (libraryId: string) => void;
|
|
18
|
+
}
|
|
@@ -1,106 +1,106 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ClientConnectionManager = void 0;
|
|
4
|
-
class ClientConnection {
|
|
5
|
-
constructor(key) {
|
|
6
|
-
this.key = key;
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
class RequestClientConnection extends ClientConnection {
|
|
10
|
-
constructor(key, req, res, info) {
|
|
11
|
-
super(key);
|
|
12
|
-
this.req = req;
|
|
13
|
-
this.res = res;
|
|
14
|
-
this.info = info;
|
|
15
|
-
this.type = 'request';
|
|
16
|
-
this.responses = [];
|
|
17
|
-
this.respond = (message) => {
|
|
18
|
-
this.responses.push(message);
|
|
19
|
-
};
|
|
20
|
-
this.end = () => {
|
|
21
|
-
this.res.writeHead(200, {
|
|
22
|
-
'Content-Type': 'application/json',
|
|
23
|
-
});
|
|
24
|
-
this.res.write(JSON.stringify({
|
|
25
|
-
messages: this.responses,
|
|
26
|
-
}));
|
|
27
|
-
this.res.end();
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
class WebSocketClientConnection extends ClientConnection {
|
|
32
|
-
constructor(key, ws, info) {
|
|
33
|
-
super(key);
|
|
34
|
-
this.ws = ws;
|
|
35
|
-
this.info = info;
|
|
36
|
-
this.type = 'websocket';
|
|
37
|
-
this.respond = (message) => {
|
|
38
|
-
this.ws.send(JSON.stringify(message));
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
class ClientConnectionManager {
|
|
43
|
-
constructor() {
|
|
44
|
-
this.connections = {};
|
|
45
|
-
this.getLibraryConnections = (libraryId) => {
|
|
46
|
-
if (!this.connections[libraryId]) {
|
|
47
|
-
this.connections[libraryId] = new Map();
|
|
48
|
-
}
|
|
49
|
-
return this.connections[libraryId];
|
|
50
|
-
};
|
|
51
|
-
this.addSocket = (libraryId, key, socket, info) => {
|
|
52
|
-
const lib = this.getLibraryConnections(libraryId);
|
|
53
|
-
const connection = new WebSocketClientConnection(key, socket, info);
|
|
54
|
-
lib.set(key, connection);
|
|
55
|
-
socket.on('close', () => {
|
|
56
|
-
lib.delete(key);
|
|
57
|
-
});
|
|
58
|
-
};
|
|
59
|
-
this.addRequest = (libraryId, key, request, response, info) => {
|
|
60
|
-
const lib = this.getLibraryConnections(libraryId);
|
|
61
|
-
const connection = new RequestClientConnection(key, request, response, info);
|
|
62
|
-
lib.set(key, connection);
|
|
63
|
-
return () => {
|
|
64
|
-
connection.end();
|
|
65
|
-
lib.delete(key);
|
|
66
|
-
};
|
|
67
|
-
};
|
|
68
|
-
this.remove = (libraryId, key) => {
|
|
69
|
-
const lib = this.getLibraryConnections(libraryId);
|
|
70
|
-
lib.delete(key);
|
|
71
|
-
};
|
|
72
|
-
this.respond = (libraryId, key, message) => {
|
|
73
|
-
const lib = this.getLibraryConnections(libraryId);
|
|
74
|
-
const connection = lib.get(key);
|
|
75
|
-
if (connection) {
|
|
76
|
-
connection.respond(message);
|
|
77
|
-
}
|
|
78
|
-
else {
|
|
79
|
-
throw new Error(`No connection found for library ${libraryId}, key ${key}`);
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
/**
|
|
83
|
-
* Broadcasts a message to all live-connected clients in a library.
|
|
84
|
-
* This does not reach push/pull clients.
|
|
85
|
-
*/
|
|
86
|
-
this.broadcast = (libraryId, message, omitKeys = []) => {
|
|
87
|
-
const lib = this.getLibraryConnections(libraryId);
|
|
88
|
-
for (const [key, connection] of lib) {
|
|
89
|
-
if (!omitKeys.includes(key)) {
|
|
90
|
-
connection.respond(message);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
this.disconnectAll = (libraryId) => {
|
|
95
|
-
const lib = this.getLibraryConnections(libraryId);
|
|
96
|
-
for (const connection of lib.values()) {
|
|
97
|
-
if (connection instanceof WebSocketClientConnection) {
|
|
98
|
-
connection.ws.close();
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
lib.clear();
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
exports.ClientConnectionManager = ClientConnectionManager;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ClientConnectionManager = void 0;
|
|
4
|
+
class ClientConnection {
|
|
5
|
+
constructor(key) {
|
|
6
|
+
this.key = key;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
class RequestClientConnection extends ClientConnection {
|
|
10
|
+
constructor(key, req, res, info) {
|
|
11
|
+
super(key);
|
|
12
|
+
this.req = req;
|
|
13
|
+
this.res = res;
|
|
14
|
+
this.info = info;
|
|
15
|
+
this.type = 'request';
|
|
16
|
+
this.responses = [];
|
|
17
|
+
this.respond = (message) => {
|
|
18
|
+
this.responses.push(message);
|
|
19
|
+
};
|
|
20
|
+
this.end = () => {
|
|
21
|
+
this.res.writeHead(200, {
|
|
22
|
+
'Content-Type': 'application/json',
|
|
23
|
+
});
|
|
24
|
+
this.res.write(JSON.stringify({
|
|
25
|
+
messages: this.responses,
|
|
26
|
+
}));
|
|
27
|
+
this.res.end();
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
class WebSocketClientConnection extends ClientConnection {
|
|
32
|
+
constructor(key, ws, info) {
|
|
33
|
+
super(key);
|
|
34
|
+
this.ws = ws;
|
|
35
|
+
this.info = info;
|
|
36
|
+
this.type = 'websocket';
|
|
37
|
+
this.respond = (message) => {
|
|
38
|
+
this.ws.send(JSON.stringify(message));
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
class ClientConnectionManager {
|
|
43
|
+
constructor() {
|
|
44
|
+
this.connections = {};
|
|
45
|
+
this.getLibraryConnections = (libraryId) => {
|
|
46
|
+
if (!this.connections[libraryId]) {
|
|
47
|
+
this.connections[libraryId] = new Map();
|
|
48
|
+
}
|
|
49
|
+
return this.connections[libraryId];
|
|
50
|
+
};
|
|
51
|
+
this.addSocket = (libraryId, key, socket, info) => {
|
|
52
|
+
const lib = this.getLibraryConnections(libraryId);
|
|
53
|
+
const connection = new WebSocketClientConnection(key, socket, info);
|
|
54
|
+
lib.set(key, connection);
|
|
55
|
+
socket.on('close', () => {
|
|
56
|
+
lib.delete(key);
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
this.addRequest = (libraryId, key, request, response, info) => {
|
|
60
|
+
const lib = this.getLibraryConnections(libraryId);
|
|
61
|
+
const connection = new RequestClientConnection(key, request, response, info);
|
|
62
|
+
lib.set(key, connection);
|
|
63
|
+
return () => {
|
|
64
|
+
connection.end();
|
|
65
|
+
lib.delete(key);
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
this.remove = (libraryId, key) => {
|
|
69
|
+
const lib = this.getLibraryConnections(libraryId);
|
|
70
|
+
lib.delete(key);
|
|
71
|
+
};
|
|
72
|
+
this.respond = (libraryId, key, message) => {
|
|
73
|
+
const lib = this.getLibraryConnections(libraryId);
|
|
74
|
+
const connection = lib.get(key);
|
|
75
|
+
if (connection) {
|
|
76
|
+
connection.respond(message);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
throw new Error(`No connection found for library ${libraryId}, key ${key}`);
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Broadcasts a message to all live-connected clients in a library.
|
|
84
|
+
* This does not reach push/pull clients.
|
|
85
|
+
*/
|
|
86
|
+
this.broadcast = (libraryId, message, omitKeys = []) => {
|
|
87
|
+
const lib = this.getLibraryConnections(libraryId);
|
|
88
|
+
for (const [key, connection] of lib) {
|
|
89
|
+
if (!omitKeys.includes(key)) {
|
|
90
|
+
connection.respond(message);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
this.disconnectAll = (libraryId) => {
|
|
95
|
+
const lib = this.getLibraryConnections(libraryId);
|
|
96
|
+
for (const connection of lib.values()) {
|
|
97
|
+
if (connection instanceof WebSocketClientConnection) {
|
|
98
|
+
connection.ws.close();
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
lib.clear();
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
exports.ClientConnectionManager = ClientConnectionManager;
|
|
106
106
|
//# sourceMappingURL=ClientConnection.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ServerMessage } from '@verdant-web/common';
|
|
2
|
-
export interface MessageSender {
|
|
3
|
-
broadcast(libraryId: string, message: ServerMessage, omitKeys?: string[]): void;
|
|
4
|
-
send(libraryId: string, clientKey: string, message: ServerMessage): void;
|
|
5
|
-
}
|
|
1
|
+
import { ServerMessage } from '@verdant-web/common';
|
|
2
|
+
export interface MessageSender {
|
|
3
|
+
broadcast(libraryId: string, message: ServerMessage, omitKeys?: string[]): void;
|
|
4
|
+
send(libraryId: string, clientKey: string, message: ServerMessage): void;
|
|
5
|
+
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
//# sourceMappingURL=MessageSender.js.map
|
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
import { Operation } from '@verdant-web/common';
|
|
2
|
-
import { Database } from 'better-sqlite3';
|
|
3
|
-
import { OperationSpec } from './types.js';
|
|
4
|
-
export declare class OperationHistory {
|
|
5
|
-
private db;
|
|
6
|
-
constructor(db: Database);
|
|
7
|
-
private hydratePatch;
|
|
8
|
-
getAllFor: (libraryId: string, oid: string) => OperationSpec[];
|
|
9
|
-
getEarliest: (libraryId: string, count: number) => OperationSpec[];
|
|
10
|
-
getAfter: (libraryId: string, timestamp?: string | null) => OperationSpec[];
|
|
11
|
-
/**
|
|
12
|
-
* Returns all operations before the given timestamp
|
|
13
|
-
* in ascending chronological order
|
|
14
|
-
*/
|
|
15
|
-
getBefore: (libraryId: string, before: string) => OperationSpec[];
|
|
16
|
-
/**
|
|
17
|
-
* Returns all operations after a given server order. Useful
|
|
18
|
-
* for retrieving operations that were created after a client
|
|
19
|
-
* last synced.
|
|
20
|
-
*/
|
|
21
|
-
getFromServerOrder: (libraryId: string, serverOrder: number) => OperationSpec[];
|
|
22
|
-
getLatestServerOrder: (libraryId: string) => number;
|
|
23
|
-
getCount: (libraryId: string) => number;
|
|
24
|
-
/**
|
|
25
|
-
* Adds a new operation or replaces an existing one.
|
|
26
|
-
* The server order will be set to the current max + 1
|
|
27
|
-
*/
|
|
28
|
-
insert: (libraryId: string, replicaId: string, item: Operation) => import("better-sqlite3").RunResult;
|
|
29
|
-
/**
|
|
30
|
-
* Inserts all operations and updates the server
|
|
31
|
-
* order for this library
|
|
32
|
-
*/
|
|
33
|
-
insertAll: (libraryId: string, replicaId: string, items: Operation[]) => Promise<void>;
|
|
34
|
-
dropAll: (libraryId: string, items: Pick<OperationSpec, 'replicaId' | 'oid' | 'timestamp'>[]) => Promise<void>;
|
|
35
|
-
deleteAll: (libraryId: string) => void;
|
|
36
|
-
}
|
|
1
|
+
import { Operation } from '@verdant-web/common';
|
|
2
|
+
import { Database } from 'better-sqlite3';
|
|
3
|
+
import { OperationSpec } from './types.js';
|
|
4
|
+
export declare class OperationHistory {
|
|
5
|
+
private db;
|
|
6
|
+
constructor(db: Database);
|
|
7
|
+
private hydratePatch;
|
|
8
|
+
getAllFor: (libraryId: string, oid: string) => OperationSpec[];
|
|
9
|
+
getEarliest: (libraryId: string, count: number) => OperationSpec[];
|
|
10
|
+
getAfter: (libraryId: string, timestamp?: string | null) => OperationSpec[];
|
|
11
|
+
/**
|
|
12
|
+
* Returns all operations before the given timestamp
|
|
13
|
+
* in ascending chronological order
|
|
14
|
+
*/
|
|
15
|
+
getBefore: (libraryId: string, before: string) => OperationSpec[];
|
|
16
|
+
/**
|
|
17
|
+
* Returns all operations after a given server order. Useful
|
|
18
|
+
* for retrieving operations that were created after a client
|
|
19
|
+
* last synced.
|
|
20
|
+
*/
|
|
21
|
+
getFromServerOrder: (libraryId: string, serverOrder: number) => OperationSpec[];
|
|
22
|
+
getLatestServerOrder: (libraryId: string) => number;
|
|
23
|
+
getCount: (libraryId: string) => number;
|
|
24
|
+
/**
|
|
25
|
+
* Adds a new operation or replaces an existing one.
|
|
26
|
+
* The server order will be set to the current max + 1
|
|
27
|
+
*/
|
|
28
|
+
insert: (libraryId: string, replicaId: string, item: Operation) => import("better-sqlite3").RunResult;
|
|
29
|
+
/**
|
|
30
|
+
* Inserts all operations and updates the server
|
|
31
|
+
* order for this library
|
|
32
|
+
*/
|
|
33
|
+
insertAll: (libraryId: string, replicaId: string, items: Operation[]) => Promise<void>;
|
|
34
|
+
dropAll: (libraryId: string, items: Pick<OperationSpec, 'replicaId' | 'oid' | 'timestamp'>[]) => Promise<void>;
|
|
35
|
+
deleteAll: (libraryId: string) => void;
|
|
36
|
+
}
|