cojson-transport-ws 0.7.14

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/.eslintrc.cjs ADDED
@@ -0,0 +1,24 @@
1
+ module.exports = {
2
+ extends: [
3
+ "eslint:recommended",
4
+ "plugin:@typescript-eslint/recommended",
5
+ "plugin:require-extensions/recommended",
6
+ "prettier"
7
+ ],
8
+ parser: "@typescript-eslint/parser",
9
+ plugins: ["@typescript-eslint", "require-extensions"],
10
+ parserOptions: {
11
+ project: "./tsconfig.json",
12
+ tsconfigRootDir: __dirname,
13
+ },
14
+ ignorePatterns: [".eslint.cjs"],
15
+ root: true,
16
+ rules: {
17
+ "no-unused-vars": "off",
18
+ "@typescript-eslint/no-unused-vars": [
19
+ "error",
20
+ { argsIgnorePattern: "^_", varsIgnorePattern: "^_" },
21
+ ],
22
+ "@typescript-eslint/no-floating-promises": "error",
23
+ },
24
+ }
package/.prettierrc.js ADDED
@@ -0,0 +1,9 @@
1
+ /** @type {import("prettier").Config} */
2
+ const config = {
3
+ trailingComma: "all",
4
+ tabWidth: 4,
5
+ semi: true,
6
+ singleQuote: false,
7
+ };
8
+
9
+ export default config;
@@ -0,0 +1,8 @@
1
+
2
+ > cojson-transport-ws@0.7.14 build /Users/anselm/jazz/jazz/packages/cojson-transport-ws
3
+ > npm run lint && rm -rf ./dist && tsc --sourceMap --outDir dist
4
+
5
+
6
+ > cojson-transport-ws@0.7.14 lint
7
+ > eslint . --ext ts,tsx
8
+
package/CHANGELOG.md ADDED
@@ -0,0 +1,189 @@
1
+ # cojson-transport-nodejs-ws
2
+
3
+ ## 0.7.14
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+ - cojson@0.7.14
9
+
10
+ ## 0.7.11
11
+
12
+ ### Patch Changes
13
+
14
+ - Updated dependencies
15
+ - cojson@0.7.11
16
+
17
+ ## 0.7.10
18
+
19
+ ### Patch Changes
20
+
21
+ - Updated dependencies
22
+ - cojson@0.7.10
23
+
24
+ ## 0.7.9
25
+
26
+ ### Patch Changes
27
+
28
+ - Updated dependencies
29
+ - cojson@0.7.9
30
+
31
+ ## 0.7.0
32
+
33
+ ### Patch Changes
34
+
35
+ - c4151fc: Support stricter TS lint rules
36
+ - 21771c4: Reintroduce changes from main
37
+ - f0f6f1b: Clean up API more & re-add jazz-nodejs
38
+ - 627d895: Get rid of Co namespace
39
+ - a423eee: ignore error on ws close, fixing "Invalid state: Controller is already closed"
40
+ - Updated dependencies [1a35307]
41
+ - Updated dependencies [96c494f]
42
+ - Updated dependencies [19f52b7]
43
+ - Updated dependencies [d8fe2b1]
44
+ - Updated dependencies [1200aae]
45
+ - Updated dependencies [52675c9]
46
+ - Updated dependencies [1a35307]
47
+ - Updated dependencies [e299c3e]
48
+ - Updated dependencies [bf0f8ec]
49
+ - Updated dependencies [c4151fc]
50
+ - Updated dependencies [8636319]
51
+ - Updated dependencies [952982e]
52
+ - Updated dependencies [21771c4]
53
+ - Updated dependencies [69ac514]
54
+ - Updated dependencies [f0f6f1b]
55
+ - Updated dependencies [1a44f87]
56
+ - Updated dependencies [63374cc]
57
+ - cojson@0.7.0
58
+
59
+ ## 0.7.0-alpha.42
60
+
61
+ ### Patch Changes
62
+
63
+ - Updated dependencies
64
+ - cojson@0.7.0-alpha.42
65
+
66
+ ## 0.7.0-alpha.41
67
+
68
+ ### Patch Changes
69
+
70
+ - ignore error on ws close, fixing "Invalid state: Controller is already closed"
71
+
72
+ ## 0.7.0-alpha.39
73
+
74
+ ### Patch Changes
75
+
76
+ - Updated dependencies
77
+ - cojson@0.7.0-alpha.39
78
+
79
+ ## 0.7.0-alpha.38
80
+
81
+ ### Patch Changes
82
+
83
+ - Updated dependencies
84
+ - cojson@0.7.0-alpha.38
85
+
86
+ ## 0.7.0-alpha.37
87
+
88
+ ### Patch Changes
89
+
90
+ - Updated dependencies
91
+ - cojson@0.7.0-alpha.37
92
+
93
+ ## 0.7.0-alpha.36
94
+
95
+ ### Patch Changes
96
+
97
+ - Updated dependencies [1a35307]
98
+ - Updated dependencies [1a35307]
99
+ - cojson@0.7.0-alpha.36
100
+
101
+ ## 0.7.0-alpha.35
102
+
103
+ ### Patch Changes
104
+
105
+ - Updated dependencies
106
+ - cojson@0.7.0-alpha.35
107
+
108
+ ## 0.7.0-alpha.29
109
+
110
+ ### Patch Changes
111
+
112
+ - Reintroduce changes from main
113
+ - Updated dependencies
114
+ - cojson@0.7.0-alpha.29
115
+
116
+ ## 0.7.0-alpha.28
117
+
118
+ ### Patch Changes
119
+
120
+ - Updated dependencies
121
+ - cojson@0.7.0-alpha.28
122
+
123
+ ## 0.7.0-alpha.27
124
+
125
+ ### Patch Changes
126
+
127
+ - Updated dependencies
128
+ - cojson@0.7.0-alpha.27
129
+
130
+ ## 0.7.0-alpha.24
131
+
132
+ ### Patch Changes
133
+
134
+ - Updated dependencies
135
+ - cojson@0.7.0-alpha.24
136
+
137
+ ## 0.7.0-alpha.11
138
+
139
+ ### Patch Changes
140
+
141
+ - Support stricter TS lint rules
142
+ - Updated dependencies
143
+ - cojson@0.7.0-alpha.11
144
+
145
+ ## 0.7.0-alpha.10
146
+
147
+ ### Patch Changes
148
+
149
+ - Clean up API more & re-add jazz-nodejs
150
+ - Updated dependencies
151
+ - cojson@0.7.0-alpha.10
152
+
153
+ ## 0.5.2-alpha.2
154
+
155
+ ### Patch Changes
156
+
157
+ - Get rid of Co namespace
158
+
159
+ ## 0.5.2-alpha.1
160
+
161
+ ### Patch Changes
162
+
163
+ - Updated dependencies
164
+ - cojson@0.7.0-alpha.1
165
+
166
+ ## 0.5.2-alpha.0
167
+
168
+ ### Patch Changes
169
+
170
+ - Updated dependencies
171
+ - cojson@0.7.0-alpha.0
172
+
173
+ ## 0.5.1
174
+
175
+ ### Patch Changes
176
+
177
+ - Updated dependencies
178
+ - cojson@0.6.0
179
+
180
+ ## 0.5.0
181
+
182
+ ### Minor Changes
183
+
184
+ - Adding a lot of performance improvements to cojson, add a stresstest for the twit example and make that run smoother in a lot of ways.
185
+
186
+ ### Patch Changes
187
+
188
+ - Updated dependencies
189
+ - cojson@0.5.0
package/LICENSE.txt ADDED
@@ -0,0 +1,19 @@
1
+ Copyright 2024, Garden Computing, Inc.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # CoJSON Transport NodeJS/Websockets
2
+
3
+ This implements sync protocol transport for CoJSON / Jazz (see [jazz.tools](https://jazz.tools)) using WebSockets.
package/dist/index.js ADDED
@@ -0,0 +1,59 @@
1
+ import { DisconnectedError, PingTimeoutError } from "cojson";
2
+ import { Either, Stream, Queue, Effect, Exit } from "effect";
3
+ export function createWebSocketPeer(options) {
4
+ return Effect.gen(function* () {
5
+ const ws = options.websocket;
6
+ const incoming = yield* Queue.unbounded();
7
+ const outgoing = yield* Queue.unbounded();
8
+ ws.addEventListener("close", (event) => {
9
+ void Effect.runPromiseExit(Queue.offer(incoming, Either.left(new DisconnectedError(`${event.code}: ${event.reason}`)))).then((e) => {
10
+ if (Exit.isFailure(e) && !Exit.isInterrupted(e)) {
11
+ console.warn("Failed closing ws", e);
12
+ }
13
+ });
14
+ });
15
+ let pingTimeout;
16
+ ws.addEventListener("message", (event) => {
17
+ const msg = JSON.parse(event.data);
18
+ if (pingTimeout) {
19
+ clearTimeout(pingTimeout);
20
+ }
21
+ pingTimeout = setTimeout(() => {
22
+ console.debug("Ping timeout");
23
+ void Effect.runPromise(Queue.offer(incoming, Either.left(new PingTimeoutError())));
24
+ try {
25
+ ws.close();
26
+ }
27
+ catch (e) {
28
+ console.error("Error while trying to close ws on ping timeout", e);
29
+ }
30
+ }, 2500);
31
+ if (msg.type === "ping") {
32
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
33
+ globalThis.jazzPings =
34
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
35
+ globalThis.jazzPings || [];
36
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
37
+ globalThis.jazzPings.push({
38
+ received: Date.now(),
39
+ sent: msg.time,
40
+ dc: msg.dc,
41
+ });
42
+ return;
43
+ }
44
+ else {
45
+ void Effect.runPromise(Queue.offer(incoming, Either.right(msg)));
46
+ }
47
+ });
48
+ ws.addEventListener("open", () => {
49
+ void Stream.fromQueue(outgoing).pipe(Stream.runForEach((msg) => Effect.sync(() => ws.send(JSON.stringify(msg)))), Effect.runPromise);
50
+ });
51
+ return {
52
+ id: options.id,
53
+ incoming: Stream.fromQueue(incoming, { shutdown: true }).pipe(Stream.mapEffect((either) => either)),
54
+ outgoing,
55
+ role: options.role,
56
+ };
57
+ });
58
+ }
59
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "cojson-transport-ws",
3
+ "type": "module",
4
+ "version": "0.7.14",
5
+ "main": "dist/index.js",
6
+ "types": "src/index.ts",
7
+ "license": "MIT",
8
+ "dependencies": {
9
+ "effect": "^3.1.5",
10
+ "typescript": "^5.1.6",
11
+ "cojson": "0.7.14"
12
+ },
13
+ "devDependencies": {
14
+ "@types/ws": "^8.5.5"
15
+ },
16
+ "lint-staged": {
17
+ "*.{ts,tsx}": "eslint --fix",
18
+ "*.{js,jsx,mdx,json}": "prettier --write"
19
+ },
20
+ "scripts": {
21
+ "dev": "tsc --watch --sourceMap --outDir dist",
22
+ "lint": "eslint . --ext ts,tsx",
23
+ "format": "prettier --write './src/**/*.{ts,tsx}'",
24
+ "build": "npm run lint && rm -rf ./dist && tsc --sourceMap --outDir dist"
25
+ }
26
+ }
package/src/index.ts ADDED
@@ -0,0 +1,108 @@
1
+ import { DisconnectedError, Peer, PingTimeoutError, SyncMessage } from "cojson";
2
+ import { Either, Stream, Queue, Effect, Exit } from "effect";
3
+
4
+ interface AnyWebSocket {
5
+ addEventListener(
6
+ type: "close",
7
+ listener: (event: { code: number; reason: string }) => void,
8
+ ): void;
9
+ addEventListener(
10
+ type: "message",
11
+ listener: (event: { data: string | unknown }) => void,
12
+ ): void;
13
+ addEventListener(type: "open", listener: () => void): void;
14
+ close(): void;
15
+ send(data: string): void;
16
+ }
17
+
18
+ export function createWebSocketPeer(options: {
19
+ id: string;
20
+ websocket: AnyWebSocket;
21
+ role: Peer["role"];
22
+ }): Effect.Effect<Peer> {
23
+ return Effect.gen(function* () {
24
+ const ws = options.websocket;
25
+
26
+ const incoming =
27
+ yield* Queue.unbounded<
28
+ Either.Either<SyncMessage, DisconnectedError | PingTimeoutError>
29
+ >();
30
+ const outgoing = yield* Queue.unbounded<SyncMessage>();
31
+
32
+ ws.addEventListener("close", (event) => {
33
+ void Effect.runPromiseExit(
34
+ Queue.offer(
35
+ incoming,
36
+ Either.left(
37
+ new DisconnectedError(`${event.code}: ${event.reason}`),
38
+ ),
39
+ ),
40
+ ).then((e) => {
41
+ if (Exit.isFailure(e) && !Exit.isInterrupted(e)) {
42
+ console.warn("Failed closing ws", e);
43
+ }
44
+ });
45
+ });
46
+
47
+ let pingTimeout: ReturnType<typeof setTimeout> | undefined;
48
+
49
+ ws.addEventListener("message", (event) => {
50
+ const msg = JSON.parse(event.data as string);
51
+
52
+ if (pingTimeout) {
53
+ clearTimeout(pingTimeout);
54
+ }
55
+
56
+ pingTimeout = setTimeout(() => {
57
+ console.debug("Ping timeout");
58
+ void Effect.runPromise(
59
+ Queue.offer(incoming, Either.left(new PingTimeoutError())),
60
+ );
61
+ try {
62
+ ws.close();
63
+ } catch (e) {
64
+ console.error(
65
+ "Error while trying to close ws on ping timeout",
66
+ e,
67
+ );
68
+ }
69
+ }, 2500);
70
+
71
+ if (msg.type === "ping") {
72
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
73
+ (globalThis as any).jazzPings =
74
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
75
+ (globalThis as any).jazzPings || [];
76
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
77
+ (globalThis as any).jazzPings.push({
78
+ received: Date.now(),
79
+ sent: msg.time,
80
+ dc: msg.dc,
81
+ });
82
+ return;
83
+ } else {
84
+ void Effect.runPromise(
85
+ Queue.offer(incoming, Either.right(msg)),
86
+ );
87
+ }
88
+ });
89
+
90
+ ws.addEventListener("open", () => {
91
+ void Stream.fromQueue(outgoing).pipe(
92
+ Stream.runForEach((msg) =>
93
+ Effect.sync(() => ws.send(JSON.stringify(msg))),
94
+ ),
95
+ Effect.runPromise,
96
+ );
97
+ });
98
+
99
+ return {
100
+ id: options.id,
101
+ incoming: Stream.fromQueue(incoming, { shutdown: true }).pipe(
102
+ Stream.mapEffect((either) => either),
103
+ ),
104
+ outgoing,
105
+ role: options.role,
106
+ };
107
+ });
108
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "compilerOptions": {
3
+ "lib": ["ESNext"],
4
+ "module": "esnext",
5
+ "target": "ES2020",
6
+ "moduleResolution": "bundler",
7
+ "moduleDetection": "force",
8
+ "strict": true,
9
+ "skipLibCheck": true,
10
+ "forceConsistentCasingInFileNames": true,
11
+ "noUncheckedIndexedAccess": true,
12
+ "esModuleInterop": true,
13
+ },
14
+ "include": ["./src/**/*"],
15
+ }