@livestore/webmesh 0.3.0-dev.23 → 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 +10 -9
- 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 +59 -42
- 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
|
@@ -4,15 +4,15 @@ import {
|
|
|
4
4
|
Effect,
|
|
5
5
|
Either,
|
|
6
6
|
Exit,
|
|
7
|
+
Layer,
|
|
7
8
|
Queue,
|
|
8
9
|
Schedule,
|
|
9
10
|
Schema,
|
|
10
11
|
Scope,
|
|
12
|
+
Socket,
|
|
11
13
|
Stream,
|
|
12
14
|
WebChannel,
|
|
13
|
-
WebSocket,
|
|
14
15
|
} from '@livestore/utils/effect'
|
|
15
|
-
import type * as NodeWebSocket from 'ws'
|
|
16
16
|
|
|
17
17
|
import * as WebmeshSchema from './mesh-schema.js'
|
|
18
18
|
import type { MeshNode } from './node.js'
|
|
@@ -42,30 +42,40 @@ export type SocketType =
|
|
|
42
42
|
export const connectViaWebSocket = ({
|
|
43
43
|
node,
|
|
44
44
|
url,
|
|
45
|
-
reconnect = Schedule.exponential(100),
|
|
46
45
|
}: {
|
|
47
46
|
node: MeshNode
|
|
48
47
|
url: string
|
|
49
|
-
reconnect?: Schedule.Schedule<unknown> | false
|
|
50
48
|
}): Effect.Effect<void, never, Scope.Scope | HttpClient.HttpClient> =>
|
|
51
49
|
Effect.gen(function* () {
|
|
52
50
|
const disconnected = yield* Deferred.make<void>()
|
|
53
51
|
|
|
54
|
-
const socket = yield*
|
|
52
|
+
const socket = yield* Socket.makeWebSocket(url, { openTimeout: 50 })
|
|
55
53
|
|
|
56
|
-
|
|
54
|
+
const edgeChannel = yield* makeWebSocketEdge({
|
|
55
|
+
socket,
|
|
56
|
+
socketType: { _tag: 'leaf', from: node.nodeName },
|
|
57
|
+
})
|
|
57
58
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
yield* node
|
|
60
|
+
.addEdge({ target: 'ws', edgeChannel: edgeChannel.webChannel, replaceIfExists: true })
|
|
61
|
+
.pipe(Effect.acquireRelease(() => node.removeEdge('ws').pipe(Effect.orDie)))
|
|
61
62
|
|
|
62
63
|
yield* disconnected
|
|
63
|
-
}).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
|
+
})
|
|
64
71
|
|
|
65
|
-
export const makeWebSocketEdge = (
|
|
66
|
-
socket
|
|
67
|
-
socketType
|
|
68
|
-
|
|
72
|
+
export const makeWebSocketEdge = ({
|
|
73
|
+
socket,
|
|
74
|
+
socketType,
|
|
75
|
+
}: {
|
|
76
|
+
socket: Socket.Socket
|
|
77
|
+
socketType: SocketType
|
|
78
|
+
}): Effect.Effect<
|
|
69
79
|
{
|
|
70
80
|
webChannel: WebChannel.WebChannel<typeof WebmeshSchema.Packet.Type, typeof WebmeshSchema.Packet.Type>
|
|
71
81
|
from: string
|
|
@@ -75,8 +85,6 @@ export const makeWebSocketEdge = (
|
|
|
75
85
|
> =>
|
|
76
86
|
Effect.scopeWithCloseable((scope) =>
|
|
77
87
|
Effect.gen(function* () {
|
|
78
|
-
socket.binaryType = 'arraybuffer'
|
|
79
|
-
|
|
80
88
|
const fromDeferred = yield* Deferred.make<string>()
|
|
81
89
|
|
|
82
90
|
const listenQueue = yield* Queue.unbounded<typeof WebmeshSchema.Packet.Type>().pipe(
|
|
@@ -85,11 +93,32 @@ export const makeWebSocketEdge = (
|
|
|
85
93
|
|
|
86
94
|
const schema = WebChannel.mapSchema(WebmeshSchema.Packet)
|
|
87
95
|
|
|
88
|
-
yield*
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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))
|
|
93
122
|
if (msg._tag === 'WSEdgeInit') {
|
|
94
123
|
yield* Deferred.succeed(fromDeferred, msg.from)
|
|
95
124
|
} else {
|
|
@@ -100,45 +129,33 @@ export const makeWebSocketEdge = (
|
|
|
100
129
|
),
|
|
101
130
|
Stream.runDrain,
|
|
102
131
|
Effect.interruptible,
|
|
132
|
+
Effect.withSpan('makeWebSocketEdge:listen'),
|
|
103
133
|
Effect.tapCauseLogPretty,
|
|
104
134
|
Effect.forkScoped,
|
|
105
135
|
)
|
|
106
136
|
|
|
137
|
+
const sendToSocket = yield* socket.writer
|
|
138
|
+
|
|
107
139
|
const initHandshake = (from: string) =>
|
|
108
|
-
|
|
140
|
+
sendToSocket(Schema.encodeSync(MessageMsgPack)({ _tag: 'WSEdgeInit', from }))
|
|
109
141
|
|
|
110
142
|
if (socketType._tag === 'leaf') {
|
|
111
|
-
initHandshake(socketType.from)
|
|
143
|
+
yield* initHandshake(socketType.from)
|
|
112
144
|
}
|
|
113
145
|
|
|
114
146
|
const deferredResult = yield* fromDeferred
|
|
115
147
|
const from = socketType._tag === 'leaf' ? socketType.from : deferredResult
|
|
116
148
|
|
|
117
149
|
if (socketType._tag === 'relay') {
|
|
118
|
-
initHandshake(from)
|
|
150
|
+
yield* initHandshake(from)
|
|
119
151
|
}
|
|
120
152
|
|
|
121
|
-
const isConnectedLatch = yield* Effect.makeLatch(true)
|
|
122
|
-
|
|
123
|
-
const closedDeferred = yield* Deferred.make<void>().pipe(Effect.acquireRelease(Deferred.done(Exit.void)))
|
|
124
|
-
|
|
125
|
-
yield* Effect.eventListener<any>(
|
|
126
|
-
socket,
|
|
127
|
-
'close',
|
|
128
|
-
() =>
|
|
129
|
-
Effect.gen(function* () {
|
|
130
|
-
yield* isConnectedLatch.close
|
|
131
|
-
yield* Deferred.succeed(closedDeferred, undefined)
|
|
132
|
-
}),
|
|
133
|
-
{ once: true },
|
|
134
|
-
)
|
|
135
|
-
|
|
136
153
|
const send = (message: typeof WebmeshSchema.Packet.Type) =>
|
|
137
154
|
Effect.gen(function* () {
|
|
138
155
|
yield* isConnectedLatch.await
|
|
139
156
|
const payload = yield* Schema.encode(schema.send)(message)
|
|
140
|
-
|
|
141
|
-
})
|
|
157
|
+
yield* sendToSocket(Schema.encodeSync(MessageMsgPack)({ _tag: 'WSEdgePayload', payload, from }))
|
|
158
|
+
}).pipe(Effect.orDie)
|
|
142
159
|
|
|
143
160
|
const listen = Stream.fromQueue(listenQueue).pipe(
|
|
144
161
|
Stream.map(Either.right),
|
|
@@ -156,5 +173,5 @@ export const makeWebSocketEdge = (
|
|
|
156
173
|
} satisfies WebChannel.WebChannel<typeof WebmeshSchema.Packet.Type, typeof WebmeshSchema.Packet.Type>
|
|
157
174
|
|
|
158
175
|
return { webChannel, from }
|
|
159
|
-
}).pipe(Effect.withSpanScoped('makeWebSocketEdge')),
|
|
176
|
+
}).pipe(Effect.withSpanScoped('makeWebSocketEdge'), Effect.orDie),
|
|
160
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 { HttpClient, 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 | HttpClient.HttpClient>;
|
|
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,UAAU,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAChE,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,GAAG,UAAU,CAAC,UAAU,CA4CnF,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 { HttpClient, 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 | HttpClient.HttpClient> =>
|
|
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<HttpClient.HttpClient>()
|
|
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
|
-
})
|