@livestore/webmesh 0.3.0-dev.22 → 0.3.0-dev.24
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/.tsbuildinfo +1 -1
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +5 -8
- package/dist/node.js.map +1 -1
- package/dist/utils.d.ts +4 -4
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +7 -1
- package/dist/utils.js.map +1 -1
- package/dist/websocket-edge.d.ts +9 -7
- package/dist/websocket-edge.d.ts.map +1 -1
- package/dist/websocket-edge.js +38 -22
- package/dist/websocket-edge.js.map +1 -1
- package/package.json +3 -5
- package/src/node.ts +5 -5
- package/src/utils.ts +13 -2
- package/src/websocket-edge.ts +62 -44
- package/tmp/pack.tgz +0 -0
- package/dist/websocket-connection.d.ts +0 -50
- package/dist/websocket-connection.d.ts.map +0 -1
- package/dist/websocket-connection.js +0 -69
- package/dist/websocket-connection.js.map +0 -1
- package/dist/websocket-server.d.ts +0 -7
- package/dist/websocket-server.d.ts.map +0 -1
- package/dist/websocket-server.js +0 -38
- package/dist/websocket-server.js.map +0 -1
- package/src/websocket-server.ts +0 -57
package/src/websocket-edge.ts
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
|
+
import type { HttpClient } from '@livestore/utils/effect'
|
|
1
2
|
import {
|
|
2
3
|
Deferred,
|
|
3
4
|
Effect,
|
|
4
5
|
Either,
|
|
5
6
|
Exit,
|
|
7
|
+
Layer,
|
|
6
8
|
Queue,
|
|
7
9
|
Schedule,
|
|
8
10
|
Schema,
|
|
9
11
|
Scope,
|
|
12
|
+
Socket,
|
|
10
13
|
Stream,
|
|
11
14
|
WebChannel,
|
|
12
|
-
WebSocket,
|
|
13
15
|
} from '@livestore/utils/effect'
|
|
14
|
-
import type * as NodeWebSocket from 'ws'
|
|
15
16
|
|
|
16
17
|
import * as WebmeshSchema from './mesh-schema.js'
|
|
17
18
|
import type { MeshNode } from './node.js'
|
|
@@ -41,41 +42,49 @@ export type SocketType =
|
|
|
41
42
|
export const connectViaWebSocket = ({
|
|
42
43
|
node,
|
|
43
44
|
url,
|
|
44
|
-
reconnect = Schedule.exponential(100),
|
|
45
45
|
}: {
|
|
46
46
|
node: MeshNode
|
|
47
47
|
url: string
|
|
48
|
-
|
|
49
|
-
}): Effect.Effect<void, never, Scope.Scope> =>
|
|
48
|
+
}): Effect.Effect<void, never, Scope.Scope | HttpClient.HttpClient> =>
|
|
50
49
|
Effect.gen(function* () {
|
|
51
50
|
const disconnected = yield* Deferred.make<void>()
|
|
52
51
|
|
|
53
|
-
const socket = yield*
|
|
52
|
+
const socket = yield* Socket.makeWebSocket(url, { openTimeout: 50 })
|
|
54
53
|
|
|
55
|
-
|
|
54
|
+
const edgeChannel = yield* makeWebSocketEdge({
|
|
55
|
+
socket,
|
|
56
|
+
socketType: { _tag: 'leaf', from: node.nodeName },
|
|
57
|
+
})
|
|
56
58
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
59
|
+
yield* node
|
|
60
|
+
.addEdge({ target: 'ws', edgeChannel: edgeChannel.webChannel, replaceIfExists: true })
|
|
61
|
+
.pipe(Effect.acquireRelease(() => node.removeEdge('ws').pipe(Effect.orDie)))
|
|
60
62
|
|
|
61
63
|
yield* disconnected
|
|
62
|
-
}).pipe(Effect.scoped, Effect.forever, Effect.
|
|
64
|
+
}).pipe(Effect.scoped, Effect.forever, Effect.interruptible, Effect.provide(binaryWebSocketConstructorLayer))
|
|
65
|
+
|
|
66
|
+
const binaryWebSocketConstructorLayer = Layer.succeed(Socket.WebSocketConstructor, (url, protocols) => {
|
|
67
|
+
const socket = new globalThis.WebSocket(url, protocols)
|
|
68
|
+
socket.binaryType = 'arraybuffer'
|
|
69
|
+
return socket
|
|
70
|
+
})
|
|
63
71
|
|
|
64
|
-
export const makeWebSocketEdge = (
|
|
65
|
-
socket
|
|
66
|
-
socketType
|
|
67
|
-
|
|
72
|
+
export const makeWebSocketEdge = ({
|
|
73
|
+
socket,
|
|
74
|
+
socketType,
|
|
75
|
+
}: {
|
|
76
|
+
socket: Socket.Socket
|
|
77
|
+
socketType: SocketType
|
|
78
|
+
}): Effect.Effect<
|
|
68
79
|
{
|
|
69
80
|
webChannel: WebChannel.WebChannel<typeof WebmeshSchema.Packet.Type, typeof WebmeshSchema.Packet.Type>
|
|
70
81
|
from: string
|
|
71
82
|
},
|
|
72
83
|
never,
|
|
73
|
-
Scope.Scope
|
|
84
|
+
Scope.Scope | HttpClient.HttpClient
|
|
74
85
|
> =>
|
|
75
86
|
Effect.scopeWithCloseable((scope) =>
|
|
76
87
|
Effect.gen(function* () {
|
|
77
|
-
socket.binaryType = 'arraybuffer'
|
|
78
|
-
|
|
79
88
|
const fromDeferred = yield* Deferred.make<string>()
|
|
80
89
|
|
|
81
90
|
const listenQueue = yield* Queue.unbounded<typeof WebmeshSchema.Packet.Type>().pipe(
|
|
@@ -84,11 +93,32 @@ export const makeWebSocketEdge = (
|
|
|
84
93
|
|
|
85
94
|
const schema = WebChannel.mapSchema(WebmeshSchema.Packet)
|
|
86
95
|
|
|
87
|
-
yield*
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
96
|
+
const isConnectedLatch = yield* Effect.makeLatch(true)
|
|
97
|
+
|
|
98
|
+
const closedDeferred = yield* Deferred.make<void>().pipe(Effect.acquireRelease(Deferred.done(Exit.void)))
|
|
99
|
+
|
|
100
|
+
const retryOpenTimeoutSchedule = Schedule.exponential(100).pipe(
|
|
101
|
+
Schedule.whileInput((_: Socket.SocketError) => _.reason === 'OpenTimeout'),
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
yield* Stream.never.pipe(
|
|
105
|
+
Stream.pipeThroughChannel(Socket.toChannel(socket)),
|
|
106
|
+
Stream.catchTag(
|
|
107
|
+
'SocketError',
|
|
108
|
+
Effect.fn(function* (error) {
|
|
109
|
+
if (error.reason === 'Close') {
|
|
110
|
+
yield* isConnectedLatch.close
|
|
111
|
+
yield* Deferred.succeed(closedDeferred, undefined)
|
|
112
|
+
return yield* Effect.interrupt
|
|
113
|
+
} else {
|
|
114
|
+
return yield* Effect.fail(error)
|
|
115
|
+
}
|
|
116
|
+
}),
|
|
117
|
+
),
|
|
118
|
+
Stream.retry(retryOpenTimeoutSchedule),
|
|
119
|
+
Stream.tap(
|
|
120
|
+
Effect.fn(function* (bytes) {
|
|
121
|
+
const msg = yield* Schema.decode(MessageMsgPack)(new Uint8Array(bytes))
|
|
92
122
|
if (msg._tag === 'WSEdgeInit') {
|
|
93
123
|
yield* Deferred.succeed(fromDeferred, msg.from)
|
|
94
124
|
} else {
|
|
@@ -99,45 +129,33 @@ export const makeWebSocketEdge = (
|
|
|
99
129
|
),
|
|
100
130
|
Stream.runDrain,
|
|
101
131
|
Effect.interruptible,
|
|
132
|
+
Effect.withSpan('makeWebSocketEdge:listen'),
|
|
102
133
|
Effect.tapCauseLogPretty,
|
|
103
134
|
Effect.forkScoped,
|
|
104
135
|
)
|
|
105
136
|
|
|
137
|
+
const sendToSocket = yield* socket.writer
|
|
138
|
+
|
|
106
139
|
const initHandshake = (from: string) =>
|
|
107
|
-
|
|
140
|
+
sendToSocket(Schema.encodeSync(MessageMsgPack)({ _tag: 'WSEdgeInit', from }))
|
|
108
141
|
|
|
109
142
|
if (socketType._tag === 'leaf') {
|
|
110
|
-
initHandshake(socketType.from)
|
|
143
|
+
yield* initHandshake(socketType.from)
|
|
111
144
|
}
|
|
112
145
|
|
|
113
146
|
const deferredResult = yield* fromDeferred
|
|
114
147
|
const from = socketType._tag === 'leaf' ? socketType.from : deferredResult
|
|
115
148
|
|
|
116
149
|
if (socketType._tag === 'relay') {
|
|
117
|
-
initHandshake(from)
|
|
150
|
+
yield* initHandshake(from)
|
|
118
151
|
}
|
|
119
152
|
|
|
120
|
-
const isConnectedLatch = yield* Effect.makeLatch(true)
|
|
121
|
-
|
|
122
|
-
const closedDeferred = yield* Deferred.make<void>().pipe(Effect.acquireRelease(Deferred.done(Exit.void)))
|
|
123
|
-
|
|
124
|
-
yield* Effect.eventListener<any>(
|
|
125
|
-
socket,
|
|
126
|
-
'close',
|
|
127
|
-
() =>
|
|
128
|
-
Effect.gen(function* () {
|
|
129
|
-
yield* isConnectedLatch.close
|
|
130
|
-
yield* Deferred.succeed(closedDeferred, undefined)
|
|
131
|
-
}),
|
|
132
|
-
{ once: true },
|
|
133
|
-
)
|
|
134
|
-
|
|
135
153
|
const send = (message: typeof WebmeshSchema.Packet.Type) =>
|
|
136
154
|
Effect.gen(function* () {
|
|
137
155
|
yield* isConnectedLatch.await
|
|
138
156
|
const payload = yield* Schema.encode(schema.send)(message)
|
|
139
|
-
|
|
140
|
-
})
|
|
157
|
+
yield* sendToSocket(Schema.encodeSync(MessageMsgPack)({ _tag: 'WSEdgePayload', payload, from }))
|
|
158
|
+
}).pipe(Effect.orDie)
|
|
141
159
|
|
|
142
160
|
const listen = Stream.fromQueue(listenQueue).pipe(
|
|
143
161
|
Stream.map(Either.right),
|
|
@@ -155,5 +173,5 @@ export const makeWebSocketEdge = (
|
|
|
155
173
|
} satisfies WebChannel.WebChannel<typeof WebmeshSchema.Packet.Type, typeof WebmeshSchema.Packet.Type>
|
|
156
174
|
|
|
157
175
|
return { webChannel, from }
|
|
158
|
-
}).pipe(Effect.withSpanScoped('makeWebSocketEdge')),
|
|
176
|
+
}).pipe(Effect.withSpanScoped('makeWebSocketEdge'), Effect.orDie),
|
|
159
177
|
)
|
package/tmp/pack.tgz
CHANGED
|
Binary file
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { Effect, Schedule, Schema, Scope, WebChannel } from '@livestore/utils/effect';
|
|
2
|
-
import type * as NodeWebSocket from 'ws';
|
|
3
|
-
import * as WebmeshSchema from './mesh-schema.js';
|
|
4
|
-
import type { MeshNode } from './node.js';
|
|
5
|
-
declare const WSConnectionInit_base: Schema.TaggedStruct<"WSConnectionInit", {
|
|
6
|
-
from: typeof Schema.String;
|
|
7
|
-
}>;
|
|
8
|
-
export declare class WSConnectionInit extends WSConnectionInit_base {
|
|
9
|
-
}
|
|
10
|
-
declare const WSConnectionPayload_base: Schema.TaggedStruct<"WSConnectionPayload", {
|
|
11
|
-
from: typeof Schema.String;
|
|
12
|
-
payload: typeof Schema.Any;
|
|
13
|
-
}>;
|
|
14
|
-
export declare class WSConnectionPayload extends WSConnectionPayload_base {
|
|
15
|
-
}
|
|
16
|
-
declare const WSConnectionMessage_base: Schema.Union<[typeof WSConnectionInit, typeof WSConnectionPayload]>;
|
|
17
|
-
export declare class WSConnectionMessage extends WSConnectionMessage_base {
|
|
18
|
-
}
|
|
19
|
-
export declare const MessageMsgPack: Schema.transform<typeof Schema.Uint8ArrayFromSelf, Schema.Schema<{
|
|
20
|
-
readonly _tag: "WSConnectionInit";
|
|
21
|
-
readonly from: string;
|
|
22
|
-
} | {
|
|
23
|
-
readonly _tag: "WSConnectionPayload";
|
|
24
|
-
readonly payload: any;
|
|
25
|
-
readonly from: string;
|
|
26
|
-
}, {
|
|
27
|
-
readonly _tag: "WSConnectionInit";
|
|
28
|
-
readonly from: string;
|
|
29
|
-
} | {
|
|
30
|
-
readonly _tag: "WSConnectionPayload";
|
|
31
|
-
readonly payload: any;
|
|
32
|
-
readonly from: string;
|
|
33
|
-
}, never>>;
|
|
34
|
-
export type SocketType = {
|
|
35
|
-
_tag: 'leaf';
|
|
36
|
-
from: string;
|
|
37
|
-
} | {
|
|
38
|
-
_tag: 'relay';
|
|
39
|
-
};
|
|
40
|
-
export declare const connectViaWebSocket: ({ node, url, reconnect, }: {
|
|
41
|
-
node: MeshNode;
|
|
42
|
-
url: string;
|
|
43
|
-
reconnect?: Schedule.Schedule<unknown> | false;
|
|
44
|
-
}) => Effect.Effect<void, never, Scope.Scope>;
|
|
45
|
-
export declare const makeWebSocketEdge: (socket: globalThis.WebSocket | NodeWebSocket.WebSocket, socketType: SocketType) => Effect.Effect<{
|
|
46
|
-
webChannel: WebChannel.WebChannel<typeof WebmeshSchema.Packet.Type, typeof WebmeshSchema.Packet.Type>;
|
|
47
|
-
from: string;
|
|
48
|
-
}, never, Scope.Scope>;
|
|
49
|
-
export {};
|
|
50
|
-
//# sourceMappingURL=websocket-connection.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"websocket-connection.d.ts","sourceRoot":"","sources":["../src/websocket-connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,MAAM,EAIN,QAAQ,EACR,MAAM,EACN,KAAK,EAEL,UAAU,EAEX,MAAM,yBAAyB,CAAA;AAChC,OAAO,KAAK,KAAK,aAAa,MAAM,IAAI,CAAA;AAExC,OAAO,KAAK,aAAa,MAAM,kBAAkB,CAAA;AACjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;;;;AAEzC,qBAAa,gBAAiB,SAAQ,qBAEpC;CAAG;;;;;AAEL,qBAAa,mBAAoB,SAAQ,wBAGvC;CAAG;;AAEL,qBAAa,mBAAoB,SAAQ,wBAAmD;CAAG;AAE/F,eAAO,MAAM,cAAc;;;;;;;;;;;;;;UAAsC,CAAA;AAEjE,MAAM,MAAM,UAAU,GAClB;IACE,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb,GACD;IACE,IAAI,EAAE,OAAO,CAAA;CACd,CAAA;AAEL,eAAO,MAAM,mBAAmB,GAAI,2BAIjC;IACD,IAAI,EAAE,QAAQ,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,CAAC,EAAE,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,KAAK,CAAA;CAC/C,KAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAa+C,CAAA;AAEzF,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,UAAU,CAAC,SAAS,GAAG,aAAa,CAAC,SAAS,EACtD,YAAY,UAAU,KACrB,MAAM,CAAC,MAAM,CACd;IACE,UAAU,EAAE,UAAU,CAAC,UAAU,CAAC,OAAO,aAAa,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;IACrG,IAAI,EAAE,MAAM,CAAA;CACb,EACD,KAAK,EACL,KAAK,CAAC,KAAK,CAsFV,CAAA"}
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { Deferred, Effect, Either, Exit, Queue, Schedule, Schema, Scope, Stream, WebChannel, WebSocket, } from '@livestore/utils/effect';
|
|
2
|
-
import * as WebmeshSchema from './mesh-schema.js';
|
|
3
|
-
export class WSConnectionInit extends Schema.TaggedStruct('WSConnectionInit', {
|
|
4
|
-
from: Schema.String,
|
|
5
|
-
}) {
|
|
6
|
-
}
|
|
7
|
-
export class WSConnectionPayload extends Schema.TaggedStruct('WSConnectionPayload', {
|
|
8
|
-
from: Schema.String,
|
|
9
|
-
payload: Schema.Any,
|
|
10
|
-
}) {
|
|
11
|
-
}
|
|
12
|
-
export class WSConnectionMessage extends Schema.Union(WSConnectionInit, WSConnectionPayload) {
|
|
13
|
-
}
|
|
14
|
-
export const MessageMsgPack = Schema.MsgPack(WSConnectionMessage);
|
|
15
|
-
export const connectViaWebSocket = ({ node, url, reconnect = Schedule.exponential(100), }) => Effect.gen(function* () {
|
|
16
|
-
const disconnected = yield* Deferred.make();
|
|
17
|
-
const socket = yield* WebSocket.makeWebSocket({ url, reconnect });
|
|
18
|
-
socket.addEventListener('close', () => Deferred.unsafeDone(disconnected, Exit.void));
|
|
19
|
-
const edgeChannel = yield* makeWebSocketEdge(socket, { _tag: 'leaf', from: node.nodeName });
|
|
20
|
-
yield* node.addEdge({ target: 'ws', edgeChannel: edgeChannel.webChannel, replaceIfExists: true });
|
|
21
|
-
yield* disconnected;
|
|
22
|
-
}).pipe(Effect.scoped, Effect.forever, Effect.catchTag('WebSocketError', Effect.orDie));
|
|
23
|
-
export const makeWebSocketEdge = (socket, socketType) => Effect.scopeWithCloseable((scope) => Effect.gen(function* () {
|
|
24
|
-
socket.binaryType = 'arraybuffer';
|
|
25
|
-
const fromDeferred = yield* Deferred.make();
|
|
26
|
-
const listenQueue = yield* Queue.unbounded().pipe(Effect.acquireRelease(Queue.shutdown));
|
|
27
|
-
const schema = WebChannel.mapSchema(WebmeshSchema.Packet);
|
|
28
|
-
yield* Stream.fromEventListener(socket, 'message').pipe(Stream.map((msg) => Schema.decodeUnknownEither(MessageMsgPack)(new Uint8Array(msg.data))), Stream.flatten(), Stream.tap((msg) => Effect.gen(function* () {
|
|
29
|
-
if (msg._tag === 'WSConnectionInit') {
|
|
30
|
-
yield* Deferred.succeed(fromDeferred, msg.from);
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
const decodedPayload = yield* Schema.decode(schema.listen)(msg.payload);
|
|
34
|
-
yield* Queue.offer(listenQueue, decodedPayload);
|
|
35
|
-
}
|
|
36
|
-
})), Stream.runDrain, Effect.interruptible, Effect.tapCauseLogPretty, Effect.forkScoped);
|
|
37
|
-
const initHandshake = (from) => socket.send(Schema.encodeSync(MessageMsgPack)({ _tag: 'WSConnectionInit', from }));
|
|
38
|
-
if (socketType._tag === 'leaf') {
|
|
39
|
-
initHandshake(socketType.from);
|
|
40
|
-
}
|
|
41
|
-
const deferredResult = yield* fromDeferred;
|
|
42
|
-
const from = socketType._tag === 'leaf' ? socketType.from : deferredResult;
|
|
43
|
-
if (socketType._tag === 'relay') {
|
|
44
|
-
initHandshake(from);
|
|
45
|
-
}
|
|
46
|
-
const isConnectedLatch = yield* Effect.makeLatch(true);
|
|
47
|
-
const closedDeferred = yield* Deferred.make().pipe(Effect.acquireRelease(Deferred.done(Exit.void)));
|
|
48
|
-
yield* Effect.eventListener(socket, 'close', () => Effect.gen(function* () {
|
|
49
|
-
yield* isConnectedLatch.close;
|
|
50
|
-
yield* Deferred.succeed(closedDeferred, undefined);
|
|
51
|
-
}), { once: true });
|
|
52
|
-
const send = (message) => Effect.gen(function* () {
|
|
53
|
-
yield* isConnectedLatch.await;
|
|
54
|
-
const payload = yield* Schema.encode(schema.send)(message);
|
|
55
|
-
socket.send(Schema.encodeSync(MessageMsgPack)({ _tag: 'WSConnectionPayload', payload, from }));
|
|
56
|
-
});
|
|
57
|
-
const listen = Stream.fromQueue(listenQueue).pipe(Stream.map(Either.right), WebChannel.listenToDebugPing('websocket-edge'));
|
|
58
|
-
const webChannel = {
|
|
59
|
-
[WebChannel.WebChannelSymbol]: WebChannel.WebChannelSymbol,
|
|
60
|
-
send,
|
|
61
|
-
listen,
|
|
62
|
-
closedDeferred,
|
|
63
|
-
schema,
|
|
64
|
-
supportsTransferables: false,
|
|
65
|
-
shutdown: Scope.close(scope, Exit.void),
|
|
66
|
-
};
|
|
67
|
-
return { webChannel, from };
|
|
68
|
-
}).pipe(Effect.withSpanScoped('makeWebSocketEdge')));
|
|
69
|
-
//# sourceMappingURL=websocket-connection.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"websocket-connection.js","sourceRoot":"","sources":["../src/websocket-connection.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { Scope } from '@livestore/utils/effect';
|
|
2
|
-
import { Effect } from '@livestore/utils/effect';
|
|
3
|
-
import * as WebSocket from 'ws';
|
|
4
|
-
export declare const makeWebSocketServer: ({ relayNodeName, }: {
|
|
5
|
-
relayNodeName: string;
|
|
6
|
-
}) => Effect.Effect<WebSocket.WebSocketServer, never, Scope.Scope>;
|
|
7
|
-
//# sourceMappingURL=websocket-server.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"websocket-server.d.ts","sourceRoot":"","sources":["../src/websocket-server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AACpD,OAAO,EAAE,MAAM,EAAY,MAAM,yBAAyB,CAAA;AAC1D,OAAO,KAAK,SAAS,MAAM,IAAI,CAAA;AAK/B,eAAO,MAAM,mBAAmB,GAAI,oBAEjC;IACD,aAAa,EAAE,MAAM,CAAA;CACtB,KAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,eAAe,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CA4C3D,CAAA"}
|
package/dist/websocket-server.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { UnexpectedError } from '@livestore/common';
|
|
2
|
-
import { Effect, FiberSet } from '@livestore/utils/effect';
|
|
3
|
-
import * as WebSocket from 'ws';
|
|
4
|
-
import { makeMeshNode } from './node.js';
|
|
5
|
-
import { makeWebSocketEdge } from './websocket-edge.js';
|
|
6
|
-
export const makeWebSocketServer = ({ relayNodeName, }) => Effect.gen(function* () {
|
|
7
|
-
const server = new WebSocket.WebSocketServer({ noServer: true });
|
|
8
|
-
yield* Effect.addFinalizer(() => Effect.async((cb) => {
|
|
9
|
-
server.close((cause) => {
|
|
10
|
-
if (cause) {
|
|
11
|
-
cb(Effect.fail(UnexpectedError.make({ cause })));
|
|
12
|
-
}
|
|
13
|
-
else {
|
|
14
|
-
server.removeAllListeners();
|
|
15
|
-
server.clients.forEach((client) => client.terminate());
|
|
16
|
-
cb(Effect.succeed(undefined));
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
}).pipe(Effect.orDie));
|
|
20
|
-
const node = yield* makeMeshNode(relayNodeName);
|
|
21
|
-
const runtime = yield* Effect.runtime();
|
|
22
|
-
const fiberSet = yield* FiberSet.make();
|
|
23
|
-
// TODO handle node disconnects (i.e. remove respective connection)
|
|
24
|
-
server.on('connection', (socket) => {
|
|
25
|
-
Effect.gen(function* () {
|
|
26
|
-
const { webChannel, from } = yield* makeWebSocketEdge(socket, { _tag: 'relay' });
|
|
27
|
-
yield* node.addEdge({ target: from, edgeChannel: webChannel, replaceIfExists: true });
|
|
28
|
-
yield* Effect.log(`WS Relay ${relayNodeName}: added edge from '${from}'`);
|
|
29
|
-
socket.addEventListener('close', () => Effect.gen(function* () {
|
|
30
|
-
yield* node.removeEdge(from);
|
|
31
|
-
yield* Effect.log(`WS Relay ${relayNodeName}: removed edge from '${from}'`);
|
|
32
|
-
}).pipe(Effect.provide(runtime), Effect.tapCauseLogPretty, Effect.runFork));
|
|
33
|
-
yield* Effect.never;
|
|
34
|
-
}).pipe(Effect.scoped, Effect.tapCauseLogPretty, Effect.provide(runtime), FiberSet.run(fiberSet), Effect.runFork);
|
|
35
|
-
});
|
|
36
|
-
return server;
|
|
37
|
-
});
|
|
38
|
-
//# sourceMappingURL=websocket-server.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"websocket-server.js","sourceRoot":"","sources":["../src/websocket-server.ts"],"names":[],"mappings":"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"}
|
package/src/websocket-server.ts
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { UnexpectedError } from '@livestore/common'
|
|
2
|
-
import type { Scope } from '@livestore/utils/effect'
|
|
3
|
-
import { Effect, FiberSet } from '@livestore/utils/effect'
|
|
4
|
-
import * as WebSocket from 'ws'
|
|
5
|
-
|
|
6
|
-
import { makeMeshNode } from './node.js'
|
|
7
|
-
import { makeWebSocketEdge } from './websocket-edge.js'
|
|
8
|
-
|
|
9
|
-
export const makeWebSocketServer = ({
|
|
10
|
-
relayNodeName,
|
|
11
|
-
}: {
|
|
12
|
-
relayNodeName: string
|
|
13
|
-
}): Effect.Effect<WebSocket.WebSocketServer, never, Scope.Scope> =>
|
|
14
|
-
Effect.gen(function* () {
|
|
15
|
-
const server = new WebSocket.WebSocketServer({ noServer: true })
|
|
16
|
-
|
|
17
|
-
yield* Effect.addFinalizer(() =>
|
|
18
|
-
Effect.async<void, UnexpectedError>((cb) => {
|
|
19
|
-
server.close((cause) => {
|
|
20
|
-
if (cause) {
|
|
21
|
-
cb(Effect.fail(UnexpectedError.make({ cause })))
|
|
22
|
-
} else {
|
|
23
|
-
server.removeAllListeners()
|
|
24
|
-
server.clients.forEach((client) => client.terminate())
|
|
25
|
-
cb(Effect.succeed(undefined))
|
|
26
|
-
}
|
|
27
|
-
})
|
|
28
|
-
}).pipe(Effect.orDie),
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
const node = yield* makeMeshNode(relayNodeName)
|
|
32
|
-
|
|
33
|
-
const runtime = yield* Effect.runtime<never>()
|
|
34
|
-
|
|
35
|
-
const fiberSet = yield* FiberSet.make()
|
|
36
|
-
|
|
37
|
-
// TODO handle node disconnects (i.e. remove respective connection)
|
|
38
|
-
server.on('connection', (socket) => {
|
|
39
|
-
Effect.gen(function* () {
|
|
40
|
-
const { webChannel, from } = yield* makeWebSocketEdge(socket, { _tag: 'relay' })
|
|
41
|
-
|
|
42
|
-
yield* node.addEdge({ target: from, edgeChannel: webChannel, replaceIfExists: true })
|
|
43
|
-
yield* Effect.log(`WS Relay ${relayNodeName}: added edge from '${from}'`)
|
|
44
|
-
|
|
45
|
-
socket.addEventListener('close', () =>
|
|
46
|
-
Effect.gen(function* () {
|
|
47
|
-
yield* node.removeEdge(from)
|
|
48
|
-
yield* Effect.log(`WS Relay ${relayNodeName}: removed edge from '${from}'`)
|
|
49
|
-
}).pipe(Effect.provide(runtime), Effect.tapCauseLogPretty, Effect.runFork),
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
yield* Effect.never
|
|
53
|
-
}).pipe(Effect.scoped, Effect.tapCauseLogPretty, Effect.provide(runtime), FiberSet.run(fiberSet), Effect.runFork)
|
|
54
|
-
})
|
|
55
|
-
|
|
56
|
-
return server
|
|
57
|
-
})
|