jazz-run 0.7.35-unique.2 → 0.7.35
Sign up to get free protection for your applications and to get access to all the features.
- package/.turbo/turbo-build.log +2 -2
- package/CHANGELOG.md +12 -12
- package/dist/index.js +9 -10
- package/dist/index.js.map +1 -1
- package/dist/startSync.js +60 -0
- package/dist/startSync.js.map +1 -0
- package/package.json +7 -6
- package/src/index.ts +12 -10
- package/src/startSync.ts +114 -0
package/.turbo/turbo-build.log
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
|
2
|
-
> jazz-run@0.7.
|
2
|
+
> jazz-run@0.7.34 build /Users/anselm/jazz/jazz/packages/jazz-run
|
3
3
|
> npm run lint && rm -rf ./dist && tsc --sourceMap --outDir dist
|
4
4
|
|
5
5
|
|
6
|
-
> jazz-run@0.7.
|
6
|
+
> jazz-run@0.7.34 lint
|
7
7
|
> eslint . --ext ts,tsx
|
8
8
|
|
package/CHANGELOG.md
CHANGED
@@ -1,20 +1,20 @@
|
|
1
1
|
# jazz-autosub
|
2
2
|
|
3
|
-
## 0.7.35
|
3
|
+
## 0.7.35
|
4
4
|
|
5
5
|
### Patch Changes
|
6
6
|
|
7
|
-
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
-
|
17
|
-
-
|
7
|
+
- 403b430: Added sync command to start a local sync server
|
8
|
+
- f350e90: Added a priority system for the sync messages
|
9
|
+
- Updated dependencies [49a8b54]
|
10
|
+
- Updated dependencies [35bbcd9]
|
11
|
+
- Updated dependencies [6f80282]
|
12
|
+
- Updated dependencies [35bbcd9]
|
13
|
+
- Updated dependencies [f350e90]
|
14
|
+
- jazz-tools@0.7.35
|
15
|
+
- cojson@0.7.35
|
16
|
+
- cojson-storage-sqlite@0.7.35
|
17
|
+
- cojson-transport-ws@0.7.35
|
18
18
|
|
19
19
|
## 0.7.34
|
20
20
|
|
package/dist/index.js
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
|
+
/* istanbul ignore file -- @preserve */
|
2
3
|
import { Command, Options } from "@effect/cli";
|
3
4
|
import { NodeContext, NodeRuntime } from "@effect/platform-node";
|
4
5
|
import { Console, Effect } from "effect";
|
5
6
|
import { createWebSocketPeer } from "cojson-transport-ws";
|
6
7
|
import { WebSocket } from "ws";
|
7
|
-
import { Account, WasmCrypto,
|
8
|
-
import {
|
8
|
+
import { Account, WasmCrypto, cojsonInternals, isControlledAccount, } from "jazz-tools";
|
9
|
+
import { startSync } from "./startSync.js";
|
9
10
|
const jazzTools = Command.make("jazz-tools");
|
10
11
|
const name = Options.text("name").pipe(Options.withAlias("n"));
|
11
12
|
const peer = Options.text("peer")
|
@@ -36,14 +37,12 @@ const accountCreate = Command.make("create", { name, peer }, ({ name, peer: peer
|
|
36
37
|
websocket: new WebSocket(peerAddr),
|
37
38
|
role: "server",
|
38
39
|
});
|
39
|
-
yield* Effect.promise(async () =>
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
}),
|
44
|
-
sessionProvider: randomSessionProvider,
|
40
|
+
yield* Effect.promise(async () => Account.become({
|
41
|
+
accountID: account.id,
|
42
|
+
accountSecret: account._raw.agentSecret,
|
43
|
+
sessionID: cojsonInternals.newRandomSessionID(account.id),
|
45
44
|
peersToLoadFrom: [peer2],
|
46
|
-
crypto
|
45
|
+
crypto,
|
47
46
|
}));
|
48
47
|
yield* Console.log(`# Credentials for Jazz account "${name}":
|
49
48
|
JAZZ_WORKER_ACCOUNT=${account.id}
|
@@ -53,7 +52,7 @@ JAZZ_WORKER_SECRET=${account._raw.agentSecret}
|
|
53
52
|
});
|
54
53
|
const accountBase = Command.make("account");
|
55
54
|
const account = accountBase.pipe(Command.withSubcommands([accountCreate]));
|
56
|
-
const command = jazzTools.pipe(Command.withSubcommands([account]));
|
55
|
+
const command = jazzTools.pipe(Command.withSubcommands([account, startSync]));
|
57
56
|
const cli = Command.run(command, {
|
58
57
|
name: "Jazz CLI Tools",
|
59
58
|
version: "v0.7.0",
|
package/dist/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,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,qBAAqB,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,EACH,OAAO,EACP,UAAU,EACV,
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
@@ -0,0 +1,60 @@
|
|
1
|
+
/* istanbul ignore file -- @preserve */
|
2
|
+
import { Command, Options } from "@effect/cli";
|
3
|
+
import { ControlledAgent, LocalNode, WasmCrypto, cojsonInternals, } from "cojson";
|
4
|
+
import { WebSocketServer } from "ws";
|
5
|
+
import { createWebSocketPeer } from "cojson-transport-ws";
|
6
|
+
import { Effect } from "effect";
|
7
|
+
import { SQLiteStorage } from "cojson-storage-sqlite";
|
8
|
+
import { dirname } from "node:path";
|
9
|
+
import { mkdir } from "node:fs/promises";
|
10
|
+
const port = Options.text("port")
|
11
|
+
.pipe(Options.withAlias("p"))
|
12
|
+
.pipe(Options.withDescription("Select a different port for the WebSocket server. Default is 4200"))
|
13
|
+
.pipe(Options.withDefault("4200"));
|
14
|
+
const inMemory = Options.boolean("in-memory").pipe(Options.withDescription("Use an in-memory storage instead of file-based"));
|
15
|
+
const db = Options.file("db")
|
16
|
+
.pipe(Options.withDescription("The path to the file where to store the data. Default is 'sync-db/storage.db'"))
|
17
|
+
.pipe(Options.withDefault("sync-db/storage.db"));
|
18
|
+
export const startSync = Command.make("sync", { port, inMemory, db }, ({ port, inMemory, db }) => {
|
19
|
+
return Effect.gen(function* () {
|
20
|
+
const crypto = yield* Effect.promise(() => WasmCrypto.create());
|
21
|
+
const wss = new WebSocketServer({ port: parseInt(port) });
|
22
|
+
console.log("COJSON sync server listening on port " + wss.options.port);
|
23
|
+
const agentSecret = crypto.newRandomAgentSecret();
|
24
|
+
const agentID = crypto.getAgentID(agentSecret);
|
25
|
+
const localNode = new LocalNode(new ControlledAgent(agentSecret, crypto), cojsonInternals.newRandomSessionID(agentID), crypto);
|
26
|
+
if (!inMemory) {
|
27
|
+
yield* Effect.promise(() => mkdir(dirname(db), { recursive: true }));
|
28
|
+
const storage = yield* Effect.promise(() => SQLiteStorage.asPeer({ filename: db }));
|
29
|
+
localNode.syncManager.addPeer(storage);
|
30
|
+
}
|
31
|
+
wss.on("connection", function connection(ws, req) {
|
32
|
+
// ping/pong for the connection liveness
|
33
|
+
const pinging = setInterval(() => {
|
34
|
+
ws.send(JSON.stringify({
|
35
|
+
type: "ping",
|
36
|
+
time: Date.now(),
|
37
|
+
dc: "unknown",
|
38
|
+
}));
|
39
|
+
}, 1500);
|
40
|
+
ws.on("close", () => {
|
41
|
+
clearInterval(pinging);
|
42
|
+
});
|
43
|
+
const clientAddress = req.headers["x-forwarded-for"]
|
44
|
+
?.split(",")[0]
|
45
|
+
?.trim() || req.socket.remoteAddress;
|
46
|
+
const clientId = clientAddress + "@" + new Date().toISOString();
|
47
|
+
localNode.syncManager.addPeer(createWebSocketPeer({
|
48
|
+
id: clientId,
|
49
|
+
role: "client",
|
50
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
51
|
+
websocket: ws, // TODO: fix types
|
52
|
+
expectPings: false,
|
53
|
+
}));
|
54
|
+
ws.on("error", (e) => console.error(`Error on connection ${clientId}:`, e));
|
55
|
+
});
|
56
|
+
// Keep the server up
|
57
|
+
yield* Effect.never;
|
58
|
+
});
|
59
|
+
});
|
60
|
+
//# sourceMappingURL=startSync.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"startSync.js","sourceRoot":"","sources":["../src/startSync.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
@@ -3,19 +3,20 @@
|
|
3
3
|
"bin": "./dist/index.js",
|
4
4
|
"type": "module",
|
5
5
|
"license": "MIT",
|
6
|
-
"version": "0.7.35
|
6
|
+
"version": "0.7.35",
|
7
7
|
"dependencies": {
|
8
|
-
"effect": "^3.6.5",
|
9
8
|
"@effect/cli": "^0.41.2",
|
10
|
-
"@effect/schema": "^0.71.1",
|
11
9
|
"@effect/platform-node": "^0.57.2",
|
12
10
|
"@effect/printer": "^0.34.5",
|
13
11
|
"@effect/printer-ansi": "^0.34.5",
|
12
|
+
"@effect/schema": "^0.71.1",
|
14
13
|
"@effect/typeclass": "^0.25.5",
|
14
|
+
"effect": "^3.6.5",
|
15
15
|
"ws": "^8.14.2",
|
16
|
-
"cojson": "0.7.35
|
17
|
-
"
|
18
|
-
"cojson-transport-ws": "0.7.35
|
16
|
+
"cojson": "0.7.35",
|
17
|
+
"cojson-storage-sqlite": "0.7.35",
|
18
|
+
"cojson-transport-ws": "0.7.35",
|
19
|
+
"jazz-tools": "0.7.35"
|
19
20
|
},
|
20
21
|
"devDependencies": {
|
21
22
|
"@types/ws": "^8.5.5",
|
package/src/index.ts
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
|
+
/* istanbul ignore file -- @preserve */
|
2
3
|
import { Command, Options } from "@effect/cli";
|
3
4
|
import { NodeContext, NodeRuntime } from "@effect/platform-node";
|
4
5
|
import { Console, Effect } from "effect";
|
@@ -7,10 +8,11 @@ import { WebSocket } from "ws";
|
|
7
8
|
import {
|
8
9
|
Account,
|
9
10
|
WasmCrypto,
|
10
|
-
|
11
|
+
cojsonInternals,
|
11
12
|
isControlledAccount,
|
12
13
|
} from "jazz-tools";
|
13
|
-
import {
|
14
|
+
import type { AccountID } from "cojson";
|
15
|
+
import { startSync } from "./startSync.js";
|
14
16
|
|
15
17
|
const jazzTools = Command.make("jazz-tools");
|
16
18
|
|
@@ -63,14 +65,14 @@ const accountCreate = Command.make(
|
|
63
65
|
});
|
64
66
|
|
65
67
|
yield* Effect.promise(async () =>
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
68
|
+
Account.become({
|
69
|
+
accountID: account.id,
|
70
|
+
accountSecret: account._raw.agentSecret,
|
71
|
+
sessionID: cojsonInternals.newRandomSessionID(
|
72
|
+
account.id as unknown as AccountID,
|
73
|
+
),
|
72
74
|
peersToLoadFrom: [peer2],
|
73
|
-
crypto
|
75
|
+
crypto,
|
74
76
|
}),
|
75
77
|
);
|
76
78
|
|
@@ -86,7 +88,7 @@ const accountBase = Command.make("account");
|
|
86
88
|
|
87
89
|
const account = accountBase.pipe(Command.withSubcommands([accountCreate]));
|
88
90
|
|
89
|
-
const command = jazzTools.pipe(Command.withSubcommands([account]));
|
91
|
+
const command = jazzTools.pipe(Command.withSubcommands([account, startSync]));
|
90
92
|
|
91
93
|
const cli = Command.run(command, {
|
92
94
|
name: "Jazz CLI Tools",
|
package/src/startSync.ts
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
/* istanbul ignore file -- @preserve */
|
2
|
+
import { Command, Options } from "@effect/cli";
|
3
|
+
import {
|
4
|
+
ControlledAgent,
|
5
|
+
LocalNode,
|
6
|
+
WasmCrypto,
|
7
|
+
cojsonInternals,
|
8
|
+
} from "cojson";
|
9
|
+
import { WebSocketServer } from "ws";
|
10
|
+
|
11
|
+
import { createWebSocketPeer } from "cojson-transport-ws";
|
12
|
+
import { Effect } from "effect";
|
13
|
+
import { SQLiteStorage } from "cojson-storage-sqlite";
|
14
|
+
import { dirname } from "node:path";
|
15
|
+
import { mkdir } from "node:fs/promises";
|
16
|
+
|
17
|
+
const port = Options.text("port")
|
18
|
+
.pipe(Options.withAlias("p"))
|
19
|
+
.pipe(
|
20
|
+
Options.withDescription(
|
21
|
+
"Select a different port for the WebSocket server. Default is 4200",
|
22
|
+
),
|
23
|
+
)
|
24
|
+
.pipe(Options.withDefault("4200"));
|
25
|
+
|
26
|
+
const inMemory = Options.boolean("in-memory").pipe(
|
27
|
+
Options.withDescription("Use an in-memory storage instead of file-based"),
|
28
|
+
);
|
29
|
+
|
30
|
+
const db = Options.file("db")
|
31
|
+
.pipe(
|
32
|
+
Options.withDescription(
|
33
|
+
"The path to the file where to store the data. Default is 'sync-db/storage.db'",
|
34
|
+
),
|
35
|
+
)
|
36
|
+
.pipe(Options.withDefault("sync-db/storage.db"));
|
37
|
+
|
38
|
+
export const startSync = Command.make(
|
39
|
+
"sync",
|
40
|
+
{ port, inMemory, db },
|
41
|
+
({ port, inMemory, db }) => {
|
42
|
+
return Effect.gen(function* () {
|
43
|
+
const crypto = yield* Effect.promise(() => WasmCrypto.create());
|
44
|
+
|
45
|
+
const wss = new WebSocketServer({ port: parseInt(port) });
|
46
|
+
|
47
|
+
console.log(
|
48
|
+
"COJSON sync server listening on port " + wss.options.port,
|
49
|
+
);
|
50
|
+
|
51
|
+
const agentSecret = crypto.newRandomAgentSecret();
|
52
|
+
const agentID = crypto.getAgentID(agentSecret);
|
53
|
+
|
54
|
+
const localNode = new LocalNode(
|
55
|
+
new ControlledAgent(agentSecret, crypto),
|
56
|
+
cojsonInternals.newRandomSessionID(agentID),
|
57
|
+
crypto,
|
58
|
+
);
|
59
|
+
|
60
|
+
if (!inMemory) {
|
61
|
+
yield* Effect.promise(() =>
|
62
|
+
mkdir(dirname(db), { recursive: true }),
|
63
|
+
);
|
64
|
+
|
65
|
+
const storage = yield* Effect.promise(() =>
|
66
|
+
SQLiteStorage.asPeer({ filename: db }),
|
67
|
+
);
|
68
|
+
|
69
|
+
localNode.syncManager.addPeer(storage);
|
70
|
+
}
|
71
|
+
|
72
|
+
wss.on("connection", function connection(ws, req) {
|
73
|
+
// ping/pong for the connection liveness
|
74
|
+
const pinging = setInterval(() => {
|
75
|
+
ws.send(
|
76
|
+
JSON.stringify({
|
77
|
+
type: "ping",
|
78
|
+
time: Date.now(),
|
79
|
+
dc: "unknown",
|
80
|
+
}),
|
81
|
+
);
|
82
|
+
}, 1500);
|
83
|
+
|
84
|
+
ws.on("close", () => {
|
85
|
+
clearInterval(pinging);
|
86
|
+
});
|
87
|
+
|
88
|
+
const clientAddress =
|
89
|
+
(req.headers["x-forwarded-for"] as string | undefined)
|
90
|
+
?.split(",")[0]
|
91
|
+
?.trim() || req.socket.remoteAddress;
|
92
|
+
|
93
|
+
const clientId = clientAddress + "@" + new Date().toISOString();
|
94
|
+
|
95
|
+
localNode.syncManager.addPeer(
|
96
|
+
createWebSocketPeer({
|
97
|
+
id: clientId,
|
98
|
+
role: "client",
|
99
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
100
|
+
websocket: ws as any, // TODO: fix types
|
101
|
+
expectPings: false,
|
102
|
+
}),
|
103
|
+
);
|
104
|
+
|
105
|
+
ws.on("error", (e) =>
|
106
|
+
console.error(`Error on connection ${clientId}:`, e),
|
107
|
+
);
|
108
|
+
});
|
109
|
+
|
110
|
+
// Keep the server up
|
111
|
+
yield* Effect.never;
|
112
|
+
});
|
113
|
+
},
|
114
|
+
);
|