jazz-run 0.8.15 → 0.8.17
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/CHANGELOG.md +401 -378
- package/dist/createWorkerAccount.js +22 -40
- package/dist/createWorkerAccount.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/startSyncServer.js +4 -4
- package/dist/startSyncServer.js.map +1 -1
- package/dist/test/createWorkerAccount.test.js +17 -7
- package/dist/test/createWorkerAccount.test.js.map +1 -1
- package/package.json +9 -12
- package/src/createWorkerAccount.ts +78 -103
- package/src/index.ts +42 -46
- package/src/startSyncServer.ts +75 -77
- package/src/test/createWorkerAccount.test.ts +30 -20
- package/tsconfig.json +1 -1
- package/.eslintrc.cjs +0 -24
- package/.prettierrc.js +0 -9
@@ -1,7 +1,7 @@
|
|
1
1
|
import { createWebSocketPeer } from "cojson-transport-ws";
|
2
|
-
import { WebSocket } from "ws";
|
3
2
|
import { Account, WasmCrypto, createJazzContext, isControlledAccount, } from "jazz-tools";
|
4
3
|
import { fixedCredentialsAuth, randomSessionProvider } from "jazz-tools";
|
4
|
+
import { WebSocket } from "ws";
|
5
5
|
export const createWorkerAccount = async ({ name, peer: peerAddr, }) => {
|
6
6
|
const crypto = await WasmCrypto.create();
|
7
7
|
const peer = createWebSocketPeer({
|
@@ -24,57 +24,39 @@ export const createWorkerAccount = async ({ name, peer: peerAddr, }) => {
|
|
24
24
|
syncManager.syncCoValue(accountCoValue),
|
25
25
|
syncManager.syncCoValue(accountProfileCoValue),
|
26
26
|
]);
|
27
|
-
await Promise.
|
28
|
-
|
29
|
-
|
27
|
+
await Promise.race([
|
28
|
+
Promise.all([
|
29
|
+
syncManager.waitForUploadIntoPeer(peer.id, accountCoValue.id),
|
30
|
+
syncManager.waitForUploadIntoPeer(peer.id, accountProfileCoValue.id),
|
31
|
+
]),
|
32
|
+
failAfter(4000, "Timeout: Didn't manage to upload the account and profile"),
|
30
33
|
]);
|
31
34
|
// Spawn a second peer to double check that the account is fully synced
|
32
35
|
const peer2 = createWebSocketPeer({
|
33
|
-
id: "
|
36
|
+
id: "verifyingPeer",
|
34
37
|
websocket: new WebSocket(peerAddr),
|
35
38
|
role: "server",
|
36
39
|
});
|
37
|
-
await
|
38
|
-
|
39
|
-
|
40
|
-
|
40
|
+
await Promise.race([
|
41
|
+
createJazzContext({
|
42
|
+
auth: fixedCredentialsAuth({
|
43
|
+
accountID: account.id,
|
44
|
+
secret: account._raw.agentSecret,
|
45
|
+
}),
|
46
|
+
sessionProvider: randomSessionProvider,
|
47
|
+
peersToLoadFrom: [peer2],
|
48
|
+
crypto,
|
41
49
|
}),
|
42
|
-
|
43
|
-
|
44
|
-
crypto,
|
45
|
-
});
|
50
|
+
failAfter(10000, "Timeout: Account loading check failed"),
|
51
|
+
]);
|
46
52
|
return {
|
47
53
|
accountId: account.id,
|
48
54
|
agentSecret: account._raw.agentSecret,
|
49
55
|
};
|
50
56
|
};
|
51
|
-
function
|
52
|
-
|
53
|
-
|
54
|
-
return new Promise((resolve) => {
|
55
|
-
const unsubscribe = peerState?.optimisticKnownStates.subscribe((id, peerKnownState) => {
|
56
|
-
if (id !== coValue.id)
|
57
|
-
return;
|
58
|
-
const knownState = coValue.knownState();
|
59
|
-
const synced = isEqualSession(knownState.sessions, peerKnownState.sessions);
|
60
|
-
if (synced) {
|
61
|
-
resolve(true);
|
62
|
-
unsubscribe?.();
|
63
|
-
}
|
64
|
-
});
|
57
|
+
function failAfter(ms, errorMessage) {
|
58
|
+
return new Promise((_, reject) => {
|
59
|
+
setTimeout(() => reject(new Error(errorMessage)), ms);
|
65
60
|
});
|
66
61
|
}
|
67
|
-
function isEqualSession(a, b) {
|
68
|
-
const keysA = Object.keys(a);
|
69
|
-
const keysB = Object.keys(b);
|
70
|
-
if (keysA.length !== keysB.length) {
|
71
|
-
return false;
|
72
|
-
}
|
73
|
-
for (const sessionId of keysA) {
|
74
|
-
if (a[sessionId] !== b[sessionId]) {
|
75
|
-
return false;
|
76
|
-
}
|
77
|
-
}
|
78
|
-
return true;
|
79
|
-
}
|
80
62
|
//# sourceMappingURL=createWorkerAccount.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"createWorkerAccount.js","sourceRoot":"","sources":["../src/createWorkerAccount.ts"],"names":[],"mappings":"
|
1
|
+
{"version":3,"file":"createWorkerAccount.js","sourceRoot":"","sources":["../src/createWorkerAccount.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,uCAAuC;AACvC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;AAE7C,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;AACrE,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/startSyncServer.js
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
+
import { createServer } from "http";
|
1
2
|
import { ControlledAgent, LocalNode, WasmCrypto } from "cojson";
|
2
3
|
import { WebSocketServer } from "ws";
|
3
|
-
import { createServer } from "http";
|
4
|
-
import { createWebSocketPeer } from "cojson-transport-ws";
|
5
|
-
import { SQLiteStorage } from "cojson-storage-sqlite";
|
6
|
-
import { dirname } from "node:path";
|
7
4
|
import { mkdir } from "node:fs/promises";
|
5
|
+
import { dirname } from "node:path";
|
6
|
+
import { SQLiteStorage } from "cojson-storage-sqlite";
|
7
|
+
import { createWebSocketPeer } from "cojson-transport-ws";
|
8
8
|
export const startSyncServer = async ({ port, inMemory, db, }) => {
|
9
9
|
const crypto = await WasmCrypto.create();
|
10
10
|
const server = createServer((req, res) => {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"startSyncServer.js","sourceRoot":"","sources":["../src/startSyncServer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;
|
1
|
+
{"version":3,"file":"startSyncServer.js","sourceRoot":"","sources":["../src/startSyncServer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAErC,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAAE,EACpC,IAAI,EACJ,QAAQ,EACR,EAAE,GAKH,EAAE,EAAE;IACH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,CAAC;IAEzC,MAAM,MAAM,GAAG,YAAY,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACvC,IAAI,GAAG,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;YAC1B,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;YACnB,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC;IACH,CAAC,CAAC,CAAC;IACH,MAAM,GAAG,GAAG,IAAI,eAAe,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAEpD,MAAM,WAAW,GAAG,MAAM,CAAC,oBAAoB,EAAE,CAAC;IAClD,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;IAE/C,MAAM,SAAS,GAAG,IAAI,SAAS,CAC7B,IAAI,eAAe,CAAC,WAAW,EAAE,MAAM,CAAC,EACxC,MAAM,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAClC,MAAM,CACP,CAAC;IAEF,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE9C,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;QAE7D,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACzC,CAAC;IAED,GAAG,CAAC,EAAE,CAAC,YAAY,EAAE,SAAS,UAAU,CAAC,EAAE,EAAE,GAAG;QAC9C,wCAAwC;QACxC,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE;YAC/B,EAAE,CAAC,IAAI,CACL,IAAI,CAAC,SAAS,CAAC;gBACb,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE;gBAChB,EAAE,EAAE,SAAS;aACd,CAAC,CACH,CAAC;QACJ,CAAC,EAAE,IAAI,CAAC,CAAC;QAET,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YAClB,aAAa,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;QAEH,MAAM,aAAa,GAChB,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAwB;YACpD,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACf,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC;QAEzC,MAAM,QAAQ,GAAG,aAAa,GAAG,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAEhE,SAAS,CAAC,WAAW,CAAC,OAAO,CAC3B,mBAAmB,CAAC;YAClB,EAAE,EAAE,QAAQ;YACZ,IAAI,EAAE,QAAQ;YACd,SAAS,EAAE,EAAE;YACb,WAAW,EAAE,KAAK;YAClB,iBAAiB,EAAE,KAAK;SACzB,CAAC,CACH,CAAC;QAEF,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,uBAAuB,QAAQ,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI;QACrD,IAAI,GAAG,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;YAC1B,GAAG,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,IAAI,CAAC,EAAE;gBACnD,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;YAClC,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAEjD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC"}
|
@@ -1,23 +1,33 @@
|
|
1
|
-
import { describe,
|
2
|
-
import { startSyncServer } from "../startSyncServer.js";
|
1
|
+
import { describe, expect, it, onTestFinished } from "vitest";
|
3
2
|
import { createWorkerAccount } from "../createWorkerAccount.js";
|
3
|
+
import { startSyncServer } from "../startSyncServer.js";
|
4
4
|
describe("createWorkerAccount - integration tests", () => {
|
5
5
|
it("should create a worker account using the local sync server", async () => {
|
6
6
|
// Pass port: undefined to let the server choose a random port
|
7
|
-
const server = await startSyncServer({
|
7
|
+
const server = await startSyncServer({
|
8
|
+
port: undefined,
|
9
|
+
inMemory: true,
|
10
|
+
db: "",
|
11
|
+
});
|
8
12
|
onTestFinished(() => {
|
9
13
|
server.close();
|
10
14
|
});
|
11
15
|
const address = server.address();
|
12
|
-
if (typeof address !==
|
13
|
-
throw new Error(
|
16
|
+
if (typeof address !== "object" || address === null) {
|
17
|
+
throw new Error("Server address is not an object");
|
14
18
|
}
|
15
|
-
const { accountId, agentSecret } = await createWorkerAccount({
|
19
|
+
const { accountId, agentSecret } = await createWorkerAccount({
|
20
|
+
name: "test",
|
21
|
+
peer: `ws://localhost:${address.port}`,
|
22
|
+
});
|
16
23
|
expect(accountId).toBeDefined();
|
17
24
|
expect(agentSecret).toBeDefined();
|
18
25
|
});
|
19
26
|
it("should create a worker account using the Jazz cloud", async () => {
|
20
|
-
const { accountId, agentSecret } = await createWorkerAccount({
|
27
|
+
const { accountId, agentSecret } = await createWorkerAccount({
|
28
|
+
name: "test",
|
29
|
+
peer: `wss://cloud.jazz.tools`,
|
30
|
+
});
|
21
31
|
expect(accountId).toBeDefined();
|
22
32
|
expect(agentSecret).toBeDefined();
|
23
33
|
});
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"createWorkerAccount.test.js","sourceRoot":"","sources":["../../src/test/createWorkerAccount.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,
|
1
|
+
{"version":3,"file":"createWorkerAccount.test.js","sourceRoot":"","sources":["../../src/test/createWorkerAccount.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,QAAQ,CAAC,yCAAyC,EAAE,GAAG,EAAE;IACvD,EAAE,CAAC,4DAA4D,EAAE,KAAK,IAAI,EAAE;QAC1E,8DAA8D;QAC9D,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC;YACnC,IAAI,EAAE,SAAS;YACf,QAAQ,EAAE,IAAI;YACd,EAAE,EAAE,EAAE;SACP,CAAC,CAAC;QAEH,cAAc,CAAC,GAAG,EAAE;YAClB,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,CAAC,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;QAEjC,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACpD,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACrD,CAAC;QAED,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,MAAM,mBAAmB,CAAC;YAC3D,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,kBAAkB,OAAO,CAAC,IAAI,EAAE;SACvC,CAAC,CAAC;QAEH,MAAM,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;QAChC,MAAM,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;QACnE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,MAAM,mBAAmB,CAAC;YAC3D,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,wBAAwB;SAC/B,CAAC,CAAC;QAEH,MAAM,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;QAChC,MAAM,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
"bin": "./dist/index.js",
|
4
4
|
"type": "module",
|
5
5
|
"license": "MIT",
|
6
|
-
"version": "0.8.
|
6
|
+
"version": "0.8.17",
|
7
7
|
"dependencies": {
|
8
8
|
"@effect/cli": "^0.41.2",
|
9
9
|
"@effect/platform-node": "^0.57.2",
|
@@ -11,24 +11,21 @@
|
|
11
11
|
"@effect/printer-ansi": "^0.34.5",
|
12
12
|
"@effect/schema": "^0.71.1",
|
13
13
|
"@effect/typeclass": "^0.25.5",
|
14
|
-
"cojson": "0.8.
|
15
|
-
"cojson-storage-sqlite": "0.8.
|
16
|
-
"cojson-transport-ws": "0.8.
|
14
|
+
"cojson": "0.8.17",
|
15
|
+
"cojson-storage-sqlite": "0.8.17",
|
16
|
+
"cojson-transport-ws": "0.8.17",
|
17
17
|
"effect": "^3.6.5",
|
18
|
-
"jazz-tools": "0.8.
|
18
|
+
"jazz-tools": "0.8.17",
|
19
19
|
"ws": "^8.14.2"
|
20
20
|
},
|
21
21
|
"devDependencies": {
|
22
22
|
"@types/ws": "^8.5.5",
|
23
23
|
"typescript": "^5.3.3"
|
24
24
|
},
|
25
|
-
"lint-staged": {
|
26
|
-
"*.{ts,tsx}": "eslint --fix",
|
27
|
-
"*.{js,jsx,mdx,json}": "prettier --write"
|
28
|
-
},
|
29
25
|
"scripts": {
|
30
|
-
"lint": "
|
31
|
-
"format": "
|
32
|
-
"build": "
|
26
|
+
"format-and-lint": "biome check .",
|
27
|
+
"format-and-lint:fix": "biome check . --write",
|
28
|
+
"build": "rm -rf ./dist && tsc --sourceMap --outDir dist",
|
29
|
+
"build-and-run": "pnpm turbo build && chmod +x ./dist/index.js && ./dist/index.js sync --in-memory"
|
33
30
|
}
|
34
31
|
}
|
@@ -1,114 +1,89 @@
|
|
1
|
+
import { CoValueCore, Profile } from "cojson";
|
1
2
|
import { createWebSocketPeer } from "cojson-transport-ws";
|
2
|
-
import { WebSocket } from "ws";
|
3
3
|
import {
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
Account,
|
5
|
+
CoMap,
|
6
|
+
Peer,
|
7
|
+
WasmCrypto,
|
8
|
+
createJazzContext,
|
9
|
+
isControlledAccount,
|
9
10
|
} from "jazz-tools";
|
10
11
|
import { fixedCredentialsAuth, randomSessionProvider } from "jazz-tools";
|
11
|
-
import {
|
12
|
+
import { WebSocket } from "ws";
|
12
13
|
|
13
14
|
export const createWorkerAccount = async ({
|
14
|
-
|
15
|
-
|
15
|
+
name,
|
16
|
+
peer: peerAddr,
|
16
17
|
}: {
|
17
|
-
|
18
|
-
|
18
|
+
name: string;
|
19
|
+
peer: string;
|
19
20
|
}) => {
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
21
|
+
const crypto = await WasmCrypto.create();
|
22
|
+
|
23
|
+
const peer = createWebSocketPeer({
|
24
|
+
id: "upstream",
|
25
|
+
websocket: new WebSocket(peerAddr),
|
26
|
+
role: "server",
|
27
|
+
});
|
28
|
+
|
29
|
+
const account = await Account.create({
|
30
|
+
creationProps: { name },
|
31
|
+
peersToLoadFrom: [peer],
|
32
|
+
crypto,
|
33
|
+
});
|
34
|
+
|
35
|
+
if (!isControlledAccount(account)) {
|
36
|
+
throw new Error("account is not a controlled account");
|
37
|
+
}
|
38
|
+
|
39
|
+
const accountCoValue = account._raw.core;
|
40
|
+
const accountProfileCoValue = account.profile!._raw.core;
|
41
|
+
const syncManager = account._raw.core.node.syncManager;
|
42
|
+
|
43
|
+
await Promise.all([
|
44
|
+
syncManager.syncCoValue(accountCoValue),
|
45
|
+
syncManager.syncCoValue(accountProfileCoValue),
|
46
|
+
]);
|
47
|
+
|
48
|
+
await Promise.race([
|
49
|
+
Promise.all([
|
50
|
+
syncManager.waitForUploadIntoPeer(peer.id, accountCoValue.id),
|
51
|
+
syncManager.waitForUploadIntoPeer(peer.id, accountProfileCoValue.id),
|
52
|
+
]),
|
53
|
+
failAfter(
|
54
|
+
4_000,
|
55
|
+
"Timeout: Didn't manage to upload the account and profile",
|
56
|
+
),
|
57
|
+
]);
|
58
|
+
|
59
|
+
// Spawn a second peer to double check that the account is fully synced
|
60
|
+
const peer2 = createWebSocketPeer({
|
61
|
+
id: "verifyingPeer",
|
62
|
+
websocket: new WebSocket(peerAddr),
|
63
|
+
role: "server",
|
64
|
+
});
|
65
|
+
|
66
|
+
await Promise.race([
|
67
|
+
createJazzContext({
|
68
|
+
auth: fixedCredentialsAuth({
|
69
|
+
accountID: account.id,
|
70
|
+
secret: account._raw.agentSecret,
|
71
|
+
}),
|
72
|
+
sessionProvider: randomSessionProvider,
|
73
|
+
peersToLoadFrom: [peer2],
|
74
|
+
crypto,
|
75
|
+
}),
|
76
|
+
failAfter(10_000, "Timeout: Account loading check failed"),
|
77
|
+
]);
|
78
|
+
|
79
|
+
return {
|
80
|
+
accountId: account.id,
|
81
|
+
agentSecret: account._raw.agentSecret,
|
82
|
+
};
|
73
83
|
};
|
74
84
|
|
75
|
-
function
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
return new Promise((resolve) => {
|
80
|
-
const unsubscribe = peerState?.optimisticKnownStates.subscribe(
|
81
|
-
(id, peerKnownState) => {
|
82
|
-
if (id !== coValue.id) return;
|
83
|
-
|
84
|
-
const knownState = coValue.knownState();
|
85
|
-
|
86
|
-
const synced = isEqualSession(
|
87
|
-
knownState.sessions,
|
88
|
-
peerKnownState.sessions,
|
89
|
-
);
|
90
|
-
if (synced) {
|
91
|
-
resolve(true);
|
92
|
-
unsubscribe?.();
|
93
|
-
}
|
94
|
-
},
|
95
|
-
);
|
96
|
-
});
|
97
|
-
}
|
98
|
-
|
99
|
-
function isEqualSession(a: Record<string, number>, b: Record<string, number>) {
|
100
|
-
const keysA = Object.keys(a);
|
101
|
-
const keysB = Object.keys(b);
|
102
|
-
|
103
|
-
if (keysA.length !== keysB.length) {
|
104
|
-
return false;
|
105
|
-
}
|
106
|
-
|
107
|
-
for (const sessionId of keysA) {
|
108
|
-
if (a[sessionId] !== b[sessionId]) {
|
109
|
-
return false;
|
110
|
-
}
|
111
|
-
}
|
112
|
-
|
113
|
-
return true;
|
85
|
+
function failAfter(ms: number, errorMessage: string) {
|
86
|
+
return new Promise((_, reject) => {
|
87
|
+
setTimeout(() => reject(new Error(errorMessage)), ms);
|
88
|
+
});
|
114
89
|
}
|
package/src/index.ts
CHANGED
@@ -10,80 +10,76 @@ const jazzTools = Command.make("jazz-tools");
|
|
10
10
|
|
11
11
|
const nameOption = Options.text("name").pipe(Options.withAlias("n"));
|
12
12
|
const peerOption = Options.text("peer")
|
13
|
-
|
14
|
-
|
13
|
+
.pipe(Options.withAlias("p"))
|
14
|
+
.pipe(Options.withDefault("wss://cloud.jazz.tools"));
|
15
15
|
|
16
16
|
const createAccountCommand = Command.make(
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
17
|
+
"create",
|
18
|
+
{ name: nameOption, peer: peerOption },
|
19
|
+
({ name, peer }) => {
|
20
|
+
return Effect.gen(function* () {
|
21
|
+
const { accountId, agentSecret } = yield* Effect.promise(() =>
|
22
|
+
createWorkerAccount({ name, peer }),
|
23
|
+
);
|
24
24
|
|
25
|
-
|
25
|
+
yield* Console.log(`# Credentials for Jazz account "${name}":
|
26
26
|
JAZZ_WORKER_ACCOUNT=${accountId}
|
27
27
|
JAZZ_WORKER_SECRET=${agentSecret}
|
28
28
|
`);
|
29
|
-
|
30
|
-
|
29
|
+
});
|
30
|
+
},
|
31
31
|
);
|
32
32
|
|
33
33
|
const accountCommand = Command.make("account").pipe(
|
34
|
-
|
34
|
+
Command.withSubcommands([createAccountCommand]),
|
35
35
|
);
|
36
36
|
|
37
37
|
const portOption = Options.text("port")
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
38
|
+
.pipe(Options.withAlias("p"))
|
39
|
+
.pipe(
|
40
|
+
Options.withDescription(
|
41
|
+
"Select a different port for the WebSocket server. Default is 4200",
|
42
|
+
),
|
43
|
+
)
|
44
|
+
.pipe(Options.withDefault("4200"));
|
45
45
|
|
46
46
|
const inMemoryOption = Options.boolean("in-memory").pipe(
|
47
|
-
|
47
|
+
Options.withDescription("Use an in-memory storage instead of file-based"),
|
48
48
|
);
|
49
49
|
|
50
50
|
const dbOption = Options.file("db")
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
51
|
+
.pipe(
|
52
|
+
Options.withDescription(
|
53
|
+
"The path to the file where to store the data. Default is 'sync-db/storage.db'",
|
54
|
+
),
|
55
|
+
)
|
56
|
+
.pipe(Options.withDefault("sync-db/storage.db"));
|
57
57
|
|
58
58
|
export const startSyncServerCommand = Command.make(
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
startSyncServer({ port, inMemory, db }),
|
65
|
-
);
|
59
|
+
"sync",
|
60
|
+
{ port: portOption, inMemory: inMemoryOption, db: dbOption },
|
61
|
+
({ port, inMemory, db }) => {
|
62
|
+
return Effect.gen(function* () {
|
63
|
+
yield* Effect.promise(() => startSyncServer({ port, inMemory, db }));
|
66
64
|
|
67
|
-
|
68
|
-
`COJSON sync server listening on ws://127.0.0.1:${port}`,
|
69
|
-
);
|
65
|
+
Console.log(`COJSON sync server listening on ws://127.0.0.1:${port}`);
|
70
66
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
67
|
+
// Keep the server up
|
68
|
+
yield* Effect.never;
|
69
|
+
});
|
70
|
+
},
|
75
71
|
);
|
76
72
|
|
77
73
|
const command = jazzTools.pipe(
|
78
|
-
|
74
|
+
Command.withSubcommands([accountCommand, startSyncServerCommand]),
|
79
75
|
);
|
80
76
|
|
81
77
|
const cli = Command.run(command, {
|
82
|
-
|
83
|
-
|
78
|
+
name: "Jazz CLI Tools",
|
79
|
+
version: "v0.8.11",
|
84
80
|
});
|
85
81
|
|
86
82
|
Effect.suspend(() => cli(process.argv)).pipe(
|
87
|
-
|
88
|
-
|
83
|
+
Effect.provide(NodeContext.layer),
|
84
|
+
NodeRuntime.runMain,
|
89
85
|
);
|