@livestore/webmesh 0.0.0-snapshot-1d99fea7d2ce2c7a5d9ed0a3752f8a7bda6bc3db

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.
Files changed (54) hide show
  1. package/README.md +5 -0
  2. package/dist/.tsbuildinfo +1 -0
  3. package/dist/channel/message-channel.d.ts +20 -0
  4. package/dist/channel/message-channel.d.ts.map +1 -0
  5. package/dist/channel/message-channel.js +183 -0
  6. package/dist/channel/message-channel.js.map +1 -0
  7. package/dist/channel/proxy-channel.d.ts +19 -0
  8. package/dist/channel/proxy-channel.d.ts.map +1 -0
  9. package/dist/channel/proxy-channel.js +179 -0
  10. package/dist/channel/proxy-channel.js.map +1 -0
  11. package/dist/common.d.ts +83 -0
  12. package/dist/common.d.ts.map +1 -0
  13. package/dist/common.js +13 -0
  14. package/dist/common.js.map +1 -0
  15. package/dist/mesh-schema.d.ts +104 -0
  16. package/dist/mesh-schema.d.ts.map +1 -0
  17. package/dist/mesh-schema.js +77 -0
  18. package/dist/mesh-schema.js.map +1 -0
  19. package/dist/mod.d.ts +5 -0
  20. package/dist/mod.d.ts.map +1 -0
  21. package/dist/mod.js +5 -0
  22. package/dist/mod.js.map +1 -0
  23. package/dist/node.d.ts +65 -0
  24. package/dist/node.d.ts.map +1 -0
  25. package/dist/node.js +216 -0
  26. package/dist/node.js.map +1 -0
  27. package/dist/node.test.d.ts +2 -0
  28. package/dist/node.test.d.ts.map +1 -0
  29. package/dist/node.test.js +351 -0
  30. package/dist/node.test.js.map +1 -0
  31. package/dist/utils.d.ts +19 -0
  32. package/dist/utils.d.ts.map +1 -0
  33. package/dist/utils.js +41 -0
  34. package/dist/utils.js.map +1 -0
  35. package/dist/websocket-connection.d.ts +51 -0
  36. package/dist/websocket-connection.d.ts.map +1 -0
  37. package/dist/websocket-connection.js +74 -0
  38. package/dist/websocket-connection.js.map +1 -0
  39. package/dist/websocket-server.d.ts +7 -0
  40. package/dist/websocket-server.d.ts.map +1 -0
  41. package/dist/websocket-server.js +24 -0
  42. package/dist/websocket-server.js.map +1 -0
  43. package/package.json +32 -0
  44. package/src/channel/message-channel.ts +354 -0
  45. package/src/channel/proxy-channel.ts +332 -0
  46. package/src/common.ts +36 -0
  47. package/src/mesh-schema.ts +94 -0
  48. package/src/mod.ts +4 -0
  49. package/src/node.test.ts +533 -0
  50. package/src/node.ts +408 -0
  51. package/src/utils.ts +47 -0
  52. package/src/websocket-connection.ts +158 -0
  53. package/src/websocket-server.ts +40 -0
  54. package/tsconfig.json +11 -0
@@ -0,0 +1,104 @@
1
+ import { Schema } from '@livestore/utils/effect';
2
+ declare const MessageChannelRequest_base: Schema.TaggedStruct<"MessageChannelRequest", {
3
+ remainingHops: Schema.optional<typeof Schema.Undefined>;
4
+ id: Schema.PropertySignature<":", string, never, "?:", string | undefined, true, never>;
5
+ target: typeof Schema.String;
6
+ source: typeof Schema.String;
7
+ channelName: typeof Schema.String;
8
+ hops: Schema.Array$<typeof Schema.String>;
9
+ }>;
10
+ export declare class MessageChannelRequest extends MessageChannelRequest_base {
11
+ }
12
+ declare const MessageChannelResponseSuccess_base: Schema.TaggedStruct<"MessageChannelResponseSuccess", {
13
+ reqId: typeof Schema.String;
14
+ port: Schema.Schema<MessagePort, MessagePort, never>;
15
+ remainingHops: Schema.Array$<typeof Schema.String>;
16
+ id: Schema.PropertySignature<":", string, never, "?:", string | undefined, true, never>;
17
+ target: typeof Schema.String;
18
+ source: typeof Schema.String;
19
+ channelName: typeof Schema.String;
20
+ hops: Schema.Array$<typeof Schema.String>;
21
+ }>;
22
+ export declare class MessageChannelResponseSuccess extends MessageChannelResponseSuccess_base {
23
+ }
24
+ declare const MessageChannelResponseNoTransferables_base: Schema.TaggedStruct<"MessageChannelResponseNoTransferables", {
25
+ reqId: typeof Schema.String;
26
+ remainingHops: Schema.Array$<typeof Schema.String>;
27
+ id: Schema.PropertySignature<":", string, never, "?:", string | undefined, true, never>;
28
+ target: typeof Schema.String;
29
+ source: typeof Schema.String;
30
+ channelName: typeof Schema.String;
31
+ hops: Schema.Array$<typeof Schema.String>;
32
+ }>;
33
+ export declare class MessageChannelResponseNoTransferables extends MessageChannelResponseNoTransferables_base {
34
+ }
35
+ declare const ProxyChannelRequest_base: Schema.TaggedStruct<"ProxyChannelRequest", {
36
+ remainingHops: Schema.optional<typeof Schema.Undefined>;
37
+ channelIdCandidate: typeof Schema.String;
38
+ id: Schema.PropertySignature<":", string, never, "?:", string | undefined, true, never>;
39
+ target: typeof Schema.String;
40
+ source: typeof Schema.String;
41
+ channelName: typeof Schema.String;
42
+ hops: Schema.Array$<typeof Schema.String>;
43
+ }>;
44
+ export declare class ProxyChannelRequest extends ProxyChannelRequest_base {
45
+ }
46
+ declare const ProxyChannelResponseSuccess_base: Schema.TaggedStruct<"ProxyChannelResponseSuccess", {
47
+ reqId: typeof Schema.String;
48
+ remainingHops: Schema.Array$<typeof Schema.String>;
49
+ combinedChannelId: typeof Schema.String;
50
+ channelIdCandidate: typeof Schema.String;
51
+ id: Schema.PropertySignature<":", string, never, "?:", string | undefined, true, never>;
52
+ target: typeof Schema.String;
53
+ source: typeof Schema.String;
54
+ channelName: typeof Schema.String;
55
+ hops: Schema.Array$<typeof Schema.String>;
56
+ }>;
57
+ export declare class ProxyChannelResponseSuccess extends ProxyChannelResponseSuccess_base {
58
+ }
59
+ declare const ProxyChannelPayload_base: Schema.TaggedStruct<"ProxyChannelPayload", {
60
+ remainingHops: Schema.optional<typeof Schema.Undefined>;
61
+ payload: typeof Schema.Any;
62
+ combinedChannelId: typeof Schema.String;
63
+ id: Schema.PropertySignature<":", string, never, "?:", string | undefined, true, never>;
64
+ target: typeof Schema.String;
65
+ source: typeof Schema.String;
66
+ channelName: typeof Schema.String;
67
+ hops: Schema.Array$<typeof Schema.String>;
68
+ }>;
69
+ export declare class ProxyChannelPayload extends ProxyChannelPayload_base {
70
+ }
71
+ declare const ProxyChannelPayloadAck_base: Schema.TaggedStruct<"ProxyChannelPayloadAck", {
72
+ reqId: typeof Schema.String;
73
+ remainingHops: Schema.Array$<typeof Schema.String>;
74
+ combinedChannelId: typeof Schema.String;
75
+ id: Schema.PropertySignature<":", string, never, "?:", string | undefined, true, never>;
76
+ target: typeof Schema.String;
77
+ source: typeof Schema.String;
78
+ channelName: typeof Schema.String;
79
+ hops: Schema.Array$<typeof Schema.String>;
80
+ }>;
81
+ export declare class ProxyChannelPayloadAck extends ProxyChannelPayloadAck_base {
82
+ }
83
+ declare const NetworkConnectionAdded_base: Schema.TaggedStruct<"NetworkConnectionAdded", {
84
+ id: Schema.PropertySignature<":", string, never, "?:", string | undefined, true, never>;
85
+ source: typeof Schema.String;
86
+ target: typeof Schema.String;
87
+ }>;
88
+ /**
89
+ * Broadcast to all nodes when a new connection is added.
90
+ * Mostly used for auto-reconnect purposes.
91
+ */
92
+ export declare class NetworkConnectionAdded extends NetworkConnectionAdded_base {
93
+ }
94
+ declare const MessageChannelPacket_base: Schema.Union<[typeof MessageChannelRequest, typeof MessageChannelResponseSuccess, typeof MessageChannelResponseNoTransferables]>;
95
+ export declare class MessageChannelPacket extends MessageChannelPacket_base {
96
+ }
97
+ declare const ProxyChannelPacket_base: Schema.Union<[typeof ProxyChannelRequest, typeof ProxyChannelResponseSuccess, typeof ProxyChannelPayload, typeof ProxyChannelPayloadAck]>;
98
+ export declare class ProxyChannelPacket extends ProxyChannelPacket_base {
99
+ }
100
+ declare const Packet_base: Schema.Union<[typeof MessageChannelPacket, typeof ProxyChannelPacket, typeof NetworkConnectionAdded]>;
101
+ export declare class Packet extends Packet_base {
102
+ }
103
+ export {};
104
+ //# sourceMappingURL=mesh-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mesh-schema.d.ts","sourceRoot":"","sources":["../src/mesh-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAgB,MAAM,yBAAyB,CAAA;;;;;;;;;AAmB9D,qBAAa,qBAAsB,SAAQ,0BAGzC;CAAG;;;;;;;;;;;AAEL,qBAAa,6BAA8B,SAAQ,kCAMjD;CAAG;;;;;;;;;;AAEL,qBAAa,qCAAsC,SAAQ,0CAO1D;CAAG;;;;;;;;;;AAEJ,qBAAa,mBAAoB,SAAQ,wBAIvC;CAAG;;;;;;;;;;;;AAEL,qBAAa,2BAA4B,SAAQ,gCAM/C;CAAG;;;;;;;;;;;AAEL,qBAAa,mBAAoB,SAAQ,wBAKvC;CAAG;;;;;;;;;;;AAEL,qBAAa,sBAAuB,SAAQ,2BAK1C;CAAG;;;;;;AAEL;;;GAGG;AAEH,qBAAa,sBAAuB,SAAQ,2BAI1C;CAAG;;AAEL,qBAAa,oBAAqB,SAAQ,yBAIzC;CAAG;;AAEJ,qBAAa,kBAAmB,SAAQ,uBAKvC;CAAG;;AAEJ,qBAAa,MAAO,SAAQ,WAA8E;CAAG"}
@@ -0,0 +1,77 @@
1
+ import { Schema, Transferable } from '@livestore/utils/effect';
2
+ import { nanoid } from '@livestore/utils/nanoid';
3
+ const id = Schema.String.pipe(Schema.optional, Schema.withDefaults({ constructor: () => nanoid(10), decoding: () => nanoid(10) }));
4
+ const defaultPacketFields = {
5
+ id,
6
+ target: Schema.String,
7
+ source: Schema.String,
8
+ channelName: Schema.String,
9
+ hops: Schema.Array(Schema.String),
10
+ };
11
+ const remainingHopsUndefined = Schema.Undefined.pipe(Schema.optional);
12
+ // Needs to go through already existing MessageChannel connections, times out otherwise
13
+ export class MessageChannelRequest extends Schema.TaggedStruct('MessageChannelRequest', {
14
+ ...defaultPacketFields,
15
+ remainingHops: remainingHopsUndefined,
16
+ }) {
17
+ }
18
+ export class MessageChannelResponseSuccess extends Schema.TaggedStruct('MessageChannelResponseSuccess', {
19
+ ...defaultPacketFields,
20
+ reqId: Schema.String,
21
+ port: Transferable.MessagePort,
22
+ // Since we can't copy this message, we need to follow the exact route back to the sender
23
+ remainingHops: Schema.Array(Schema.String),
24
+ }) {
25
+ }
26
+ export class MessageChannelResponseNoTransferables extends Schema.TaggedStruct('MessageChannelResponseNoTransferables', {
27
+ ...defaultPacketFields,
28
+ reqId: Schema.String,
29
+ remainingHops: Schema.Array(Schema.String),
30
+ }) {
31
+ }
32
+ export class ProxyChannelRequest extends Schema.TaggedStruct('ProxyChannelRequest', {
33
+ ...defaultPacketFields,
34
+ remainingHops: remainingHopsUndefined,
35
+ channelIdCandidate: Schema.String,
36
+ }) {
37
+ }
38
+ export class ProxyChannelResponseSuccess extends Schema.TaggedStruct('ProxyChannelResponseSuccess', {
39
+ ...defaultPacketFields,
40
+ reqId: Schema.String,
41
+ remainingHops: Schema.Array(Schema.String),
42
+ combinedChannelId: Schema.String,
43
+ channelIdCandidate: Schema.String,
44
+ }) {
45
+ }
46
+ export class ProxyChannelPayload extends Schema.TaggedStruct('ProxyChannelPayload', {
47
+ ...defaultPacketFields,
48
+ remainingHops: remainingHopsUndefined,
49
+ payload: Schema.Any,
50
+ combinedChannelId: Schema.String,
51
+ }) {
52
+ }
53
+ export class ProxyChannelPayloadAck extends Schema.TaggedStruct('ProxyChannelPayloadAck', {
54
+ ...defaultPacketFields,
55
+ reqId: Schema.String,
56
+ remainingHops: Schema.Array(Schema.String),
57
+ combinedChannelId: Schema.String,
58
+ }) {
59
+ }
60
+ /**
61
+ * Broadcast to all nodes when a new connection is added.
62
+ * Mostly used for auto-reconnect purposes.
63
+ */
64
+ // TODO actually use for this use case
65
+ export class NetworkConnectionAdded extends Schema.TaggedStruct('NetworkConnectionAdded', {
66
+ id,
67
+ source: Schema.String,
68
+ target: Schema.String,
69
+ }) {
70
+ }
71
+ export class MessageChannelPacket extends Schema.Union(MessageChannelRequest, MessageChannelResponseSuccess, MessageChannelResponseNoTransferables) {
72
+ }
73
+ export class ProxyChannelPacket extends Schema.Union(ProxyChannelRequest, ProxyChannelResponseSuccess, ProxyChannelPayload, ProxyChannelPayloadAck) {
74
+ }
75
+ export class Packet extends Schema.Union(MessageChannelPacket, ProxyChannelPacket, NetworkConnectionAdded) {
76
+ }
77
+ //# sourceMappingURL=mesh-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mesh-schema.js","sourceRoot":"","sources":["../src/mesh-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAEhD,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAC3B,MAAM,CAAC,QAAQ,EACf,MAAM,CAAC,YAAY,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CACnF,CAAA;AAED,MAAM,mBAAmB,GAAG;IAC1B,EAAE;IACF,MAAM,EAAE,MAAM,CAAC,MAAM;IACrB,MAAM,EAAE,MAAM,CAAC,MAAM;IACrB,WAAW,EAAE,MAAM,CAAC,MAAM;IAC1B,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;CAClC,CAAA;AAED,MAAM,sBAAsB,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;AAErE,uFAAuF;AACvF,MAAM,OAAO,qBAAsB,SAAQ,MAAM,CAAC,YAAY,CAAC,uBAAuB,EAAE;IACtF,GAAG,mBAAmB;IACtB,aAAa,EAAE,sBAAsB;CACtC,CAAC;CAAG;AAEL,MAAM,OAAO,6BAA8B,SAAQ,MAAM,CAAC,YAAY,CAAC,+BAA+B,EAAE;IACtG,GAAG,mBAAmB;IACtB,KAAK,EAAE,MAAM,CAAC,MAAM;IACpB,IAAI,EAAE,YAAY,CAAC,WAAW;IAC9B,yFAAyF;IACzF,aAAa,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;CAC3C,CAAC;CAAG;AAEL,MAAM,OAAO,qCAAsC,SAAQ,MAAM,CAAC,YAAY,CAC5E,uCAAuC,EACvC;IACE,GAAG,mBAAmB;IACtB,KAAK,EAAE,MAAM,CAAC,MAAM;IACpB,aAAa,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;CAC3C,CACF;CAAG;AAEJ,MAAM,OAAO,mBAAoB,SAAQ,MAAM,CAAC,YAAY,CAAC,qBAAqB,EAAE;IAClF,GAAG,mBAAmB;IACtB,aAAa,EAAE,sBAAsB;IACrC,kBAAkB,EAAE,MAAM,CAAC,MAAM;CAClC,CAAC;CAAG;AAEL,MAAM,OAAO,2BAA4B,SAAQ,MAAM,CAAC,YAAY,CAAC,6BAA6B,EAAE;IAClG,GAAG,mBAAmB;IACtB,KAAK,EAAE,MAAM,CAAC,MAAM;IACpB,aAAa,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;IAC1C,iBAAiB,EAAE,MAAM,CAAC,MAAM;IAChC,kBAAkB,EAAE,MAAM,CAAC,MAAM;CAClC,CAAC;CAAG;AAEL,MAAM,OAAO,mBAAoB,SAAQ,MAAM,CAAC,YAAY,CAAC,qBAAqB,EAAE;IAClF,GAAG,mBAAmB;IACtB,aAAa,EAAE,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC,GAAG;IACnB,iBAAiB,EAAE,MAAM,CAAC,MAAM;CACjC,CAAC;CAAG;AAEL,MAAM,OAAO,sBAAuB,SAAQ,MAAM,CAAC,YAAY,CAAC,wBAAwB,EAAE;IACxF,GAAG,mBAAmB;IACtB,KAAK,EAAE,MAAM,CAAC,MAAM;IACpB,aAAa,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;IAC1C,iBAAiB,EAAE,MAAM,CAAC,MAAM;CACjC,CAAC;CAAG;AAEL;;;GAGG;AACH,sCAAsC;AACtC,MAAM,OAAO,sBAAuB,SAAQ,MAAM,CAAC,YAAY,CAAC,wBAAwB,EAAE;IACxF,EAAE;IACF,MAAM,EAAE,MAAM,CAAC,MAAM;IACrB,MAAM,EAAE,MAAM,CAAC,MAAM;CACtB,CAAC;CAAG;AAEL,MAAM,OAAO,oBAAqB,SAAQ,MAAM,CAAC,KAAK,CACpD,qBAAqB,EACrB,6BAA6B,EAC7B,qCAAqC,CACtC;CAAG;AAEJ,MAAM,OAAO,kBAAmB,SAAQ,MAAM,CAAC,KAAK,CAClD,mBAAmB,EACnB,2BAA2B,EAC3B,mBAAmB,EACnB,sBAAsB,CACvB;CAAG;AAEJ,MAAM,OAAO,MAAO,SAAQ,MAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE,kBAAkB,EAAE,sBAAsB,CAAC;CAAG"}
package/dist/mod.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ export * from './websocket-connection.js';
2
+ export * from './node.js';
3
+ export * as WebmeshSchema from './mesh-schema.js';
4
+ export { ConnectionAlreadyExistsError } from './common.js';
5
+ //# sourceMappingURL=mod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAA;AACzC,cAAc,WAAW,CAAA;AACzB,OAAO,KAAK,aAAa,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAA"}
package/dist/mod.js ADDED
@@ -0,0 +1,5 @@
1
+ export * from './websocket-connection.js';
2
+ export * from './node.js';
3
+ export * as WebmeshSchema from './mesh-schema.js';
4
+ export { ConnectionAlreadyExistsError } from './common.js';
5
+ //# sourceMappingURL=mod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mod.js","sourceRoot":"","sources":["../src/mod.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAA;AACzC,cAAc,WAAW,CAAA;AACzB,OAAO,KAAK,aAAa,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,4BAA4B,EAAE,MAAM,aAAa,CAAA"}
package/dist/node.d.ts ADDED
@@ -0,0 +1,65 @@
1
+ import type { Scope } from '@livestore/utils/effect';
2
+ import { Cause, Duration, Effect, Schema, WebChannel } from '@livestore/utils/effect';
3
+ import type { MeshNodeName } from './common.js';
4
+ import { ConnectionAlreadyExistsError } from './common.js';
5
+ import * as MeshSchema from './mesh-schema.js';
6
+ type ConnectionChannel = WebChannel.WebChannel<typeof MeshSchema.Packet.Type, typeof MeshSchema.Packet.Type>;
7
+ export interface MeshNode {
8
+ nodeName: MeshNodeName;
9
+ connectionKeys: Effect.Effect<Set<MeshNodeName>>;
10
+ debug: {
11
+ print: () => void;
12
+ };
13
+ /**
14
+ * Manually adds a connection to get connected to the network of nodes with an existing WebChannel.
15
+ *
16
+ * Assumptions about the WebChannel connection:
17
+ * - 1:1 connection
18
+ * - Queues messages internally to never drop messages
19
+ * - Automatically reconnects
20
+ * - Ideally supports transferables
21
+ */
22
+ addConnection: {
23
+ (options: {
24
+ target: MeshNodeName;
25
+ connectionChannel: ConnectionChannel;
26
+ replaceIfExists: true;
27
+ }): Effect.Effect<void, never, Scope.Scope>;
28
+ (options: {
29
+ target: MeshNodeName;
30
+ connectionChannel: ConnectionChannel;
31
+ replaceIfExists?: boolean;
32
+ }): Effect.Effect<void, ConnectionAlreadyExistsError, Scope.Scope>;
33
+ };
34
+ removeConnection: (targetNodeName: MeshNodeName) => Effect.Effect<void, Cause.NoSuchElementException>;
35
+ /**
36
+ * Tries to broker a MessageChannel connection between the nodes, otherwise will proxy messages via hop-nodes
37
+ *
38
+ * For a channel to successfully open, both sides need to have a connection and call `makeChannel`
39
+ */
40
+ makeChannel: <MsgListen, MsgSend>(args: {
41
+ target: MeshNodeName;
42
+ /**
43
+ * A name for the channel (same from both sides).
44
+ * Needs to be unique in the context of the 2 connected nodes.
45
+ */
46
+ channelName: string;
47
+ schema: Schema.Schema<MsgListen | MsgSend, any> | {
48
+ listen: Schema.Schema<MsgListen, any>;
49
+ send: Schema.Schema<MsgSend, any>;
50
+ };
51
+ /**
52
+ * If possible, prefer using a MessageChannel with transferables (i.e. transferring memory instead of copying it).
53
+ */
54
+ mode: 'messagechannel' | 'proxy';
55
+ /**
56
+ * Amount of time before we consider a channel creation failed and retry when a new connection is available
57
+ *
58
+ * @default 1 second
59
+ */
60
+ timeout?: Duration.DurationInput;
61
+ }) => Effect.Effect<WebChannel.WebChannel<MsgListen, MsgSend>, never, Scope.Scope>;
62
+ }
63
+ export declare const makeMeshNode: (nodeName: MeshNodeName) => Effect.Effect<MeshNode, never, Scope.Scope>;
64
+ export {};
65
+ //# sourceMappingURL=node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AACpD,OAAO,EACL,KAAK,EACL,QAAQ,EACR,MAAM,EAKN,MAAM,EAEN,UAAU,EACX,MAAM,yBAAyB,CAAA;AAIhC,OAAO,KAAK,EAAc,YAAY,EAAoC,MAAM,aAAa,CAAA;AAC7F,OAAO,EAAE,4BAA4B,EAA0B,MAAM,aAAa,CAAA;AAClF,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAA;AAG9C,KAAK,iBAAiB,GAAG,UAAU,CAAC,UAAU,CAAC,OAAO,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;AAE5G,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,YAAY,CAAA;IAEtB,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAA;IAEhD,KAAK,EAAE;QACL,KAAK,EAAE,MAAM,IAAI,CAAA;KAClB,CAAA;IAED;;;;;;;;OAQG;IACH,aAAa,EAAE;QACb,CAAC,OAAO,EAAE;YACR,MAAM,EAAE,YAAY,CAAA;YACpB,iBAAiB,EAAE,iBAAiB,CAAA;YACpC,eAAe,EAAE,IAAI,CAAA;SACtB,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;QAC3C,CAAC,OAAO,EAAE;YACR,MAAM,EAAE,YAAY,CAAA;YACpB,iBAAiB,EAAE,iBAAiB,CAAA;YACpC,eAAe,CAAC,EAAE,OAAO,CAAA;SAC1B,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,4BAA4B,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;KACnE,CAAA;IAED,gBAAgB,EAAE,CAAC,cAAc,EAAE,YAAY,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,sBAAsB,CAAC,CAAA;IAErG;;;;OAIG;IACH,WAAW,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE;QACtC,MAAM,EAAE,YAAY,CAAA;QACpB;;;WAGG;QACH,WAAW,EAAE,MAAM,CAAA;QACnB,MAAM,EACF,MAAM,CAAC,MAAM,CAAC,SAAS,GAAG,OAAO,EAAE,GAAG,CAAC,GACvC;YACE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,CAAA;YACrC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;SAClC,CAAA;QACL;;WAEG;QACH,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAA;QAChC;;;;WAIG;QACH,OAAO,CAAC,EAAE,QAAQ,CAAC,aAAa,CAAA;KACjC,KAAK,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAA;CACnF;AAED,eAAO,MAAM,YAAY,aAAc,YAAY,KAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,CA+T1C,CAAA"}
package/dist/node.js ADDED
@@ -0,0 +1,216 @@
1
+ import { LS_DEV, shouldNeverHappen } from '@livestore/utils';
2
+ import { Cause, Duration, Effect, Fiber, Option, PubSub, Queue, Schema, Stream, WebChannel, } from '@livestore/utils/effect';
3
+ import { makeMessageChannel } from './channel/message-channel.js';
4
+ import { makeProxyChannel } from './channel/proxy-channel.js';
5
+ import { ConnectionAlreadyExistsError, packetAsOtelAttributes } from './common.js';
6
+ import * as MeshSchema from './mesh-schema.js';
7
+ import { TimeoutSet } from './utils.js';
8
+ export const makeMeshNode = (nodeName) => Effect.gen(function* () {
9
+ const connectionChannels = new Map();
10
+ // To avoid unbounded memory growth, we automatically forget about packet ids after a while
11
+ const handledPacketIds = new TimeoutSet({ timeout: Duration.minutes(1) });
12
+ const newConnectionAvailablePubSub = yield* PubSub.unbounded().pipe(Effect.acquireRelease(PubSub.shutdown));
13
+ // const proxyPacketsToProcess = yield* Queue.unbounded<ProxyQueueItem>().pipe(Effect.acquireRelease(Queue.shutdown))
14
+ // const messagePacketsToProcess = yield* Queue.unbounded<MessageQueueItem>().pipe(
15
+ // Effect.acquireRelease(Queue.shutdown),
16
+ // )
17
+ const channelMap = new Map();
18
+ const checkTransferableConnections = (packet) => {
19
+ if ((packet._tag === 'MessageChannelRequest' &&
20
+ (connectionChannels.size === 0 ||
21
+ // Either if direct connection does not support transferables ...
22
+ connectionChannels.get(packet.target)?.channel.supportsTransferables === false)) ||
23
+ // ... or if no forward-connections support transferables
24
+ ![...connectionChannels.values()].some((c) => c.channel.supportsTransferables === true)) {
25
+ return MeshSchema.MessageChannelResponseNoTransferables.make({
26
+ reqId: packet.id,
27
+ channelName: packet.channelName,
28
+ // NOTE for now we're "pretending" that the message is coming from the target node
29
+ // even though we're already handling it here.
30
+ // TODO we should clean this up at some point
31
+ source: packet.target,
32
+ // source: nodeName,
33
+ target: packet.source,
34
+ remainingHops: packet.hops,
35
+ hops: [],
36
+ });
37
+ }
38
+ };
39
+ const sendPacket = (packet) => Effect.gen(function* () {
40
+ if (Schema.is(MeshSchema.NetworkConnectionAdded)(packet)) {
41
+ yield* Effect.spanEvent('NetworkConnectionAdded', { packet, nodeName });
42
+ yield* PubSub.publish(newConnectionAvailablePubSub, packet.target);
43
+ const connectionsToForwardTo = Array.from(connectionChannels)
44
+ .filter(([name]) => name !== packet.source)
45
+ .map(([_, con]) => con.channel);
46
+ yield* Effect.forEach(connectionsToForwardTo, (con) => con.send(packet), { concurrency: 'unbounded' });
47
+ return;
48
+ }
49
+ // We have a direct connection to the target node
50
+ if (connectionChannels.has(packet.target)) {
51
+ const connectionChannel = connectionChannels.get(packet.target).channel;
52
+ const hops = packet.source === nodeName ? [] : [...packet.hops, nodeName];
53
+ yield* connectionChannel.send({ ...packet, hops });
54
+ }
55
+ // In this case we have an expected route back we should follow
56
+ // eslint-disable-next-line unicorn/no-negated-condition
57
+ else if (packet.remainingHops !== undefined) {
58
+ const hopTarget = packet.remainingHops[0] ?? shouldNeverHappen(`${nodeName}: Expected remaining hops for packet`, packet);
59
+ const connectionChannel = connectionChannels.get(hopTarget)?.channel;
60
+ if (connectionChannel === undefined) {
61
+ yield* Effect.logWarning(`${nodeName}: Expected to find hop target ${hopTarget} in connections. Dropping packet.`, packet);
62
+ return;
63
+ }
64
+ yield* connectionChannel.send({
65
+ ...packet,
66
+ remainingHops: packet.remainingHops.slice(1),
67
+ hops: [...packet.hops, nodeName],
68
+ });
69
+ }
70
+ // No route found, forward to all connections
71
+ else {
72
+ const hops = packet.source === nodeName ? [] : [...packet.hops, nodeName];
73
+ // Optimization: filter out connection where packet just came from
74
+ const connectionsToForwardTo = Array.from(connectionChannels)
75
+ .filter(([name]) => name !== packet.source)
76
+ .map(([_, con]) => con.channel);
77
+ // TODO if hops-depth=0, we should fail right away with no route found
78
+ if (hops.length === 0 && connectionsToForwardTo.length === 0 && LS_DEV) {
79
+ console.log(nodeName, 'no route found', packet._tag, 'TODO handle better');
80
+ // TODO return a expected failure
81
+ }
82
+ const packetToSend = { ...packet, hops };
83
+ // console.debug(nodeName, 'sendPacket:forwarding', packetToSend)
84
+ yield* Effect.forEach(connectionsToForwardTo, (con) => con.send(packetToSend), { concurrency: 'unbounded' });
85
+ }
86
+ }).pipe(Effect.withSpan(`sendPacket:${packet._tag}:${packet.source}→${packet.target}`, {
87
+ attributes: packetAsOtelAttributes(packet),
88
+ }), Effect.orDie);
89
+ const addConnection = ({ target: targetNodeName, connectionChannel, replaceIfExists = false, }) => Effect.gen(function* () {
90
+ if (connectionChannels.has(targetNodeName)) {
91
+ if (replaceIfExists) {
92
+ yield* removeConnection(targetNodeName).pipe(Effect.orDie);
93
+ // console.log('interrupting', targetNodeName)
94
+ // yield* Fiber.interrupt(connectionChannels.get(targetNodeName)!.listenFiber)
95
+ }
96
+ else {
97
+ return yield* new ConnectionAlreadyExistsError({ target: targetNodeName });
98
+ }
99
+ }
100
+ // TODO use a priority queue instead to prioritize network-changes/connection-requests over payloads
101
+ const listenFiber = yield* connectionChannel.listen.pipe(Stream.flatten(), Stream.tap((message) => Effect.gen(function* () {
102
+ const packet = yield* Schema.decodeUnknown(MeshSchema.Packet)(message);
103
+ // console.debug(nodeName, 'received', packet._tag, packet.source, packet.target)
104
+ if (handledPacketIds.has(packet.id))
105
+ return;
106
+ handledPacketIds.add(packet.id);
107
+ if (packet._tag === 'NetworkConnectionAdded') {
108
+ yield* sendPacket(packet);
109
+ }
110
+ else if (packet.target === nodeName) {
111
+ const channelKey = `${packet.source}-${packet.channelName}`;
112
+ if (!channelMap.has(channelKey)) {
113
+ const queue = yield* Queue.unbounded().pipe(Effect.acquireRelease(Queue.shutdown));
114
+ channelMap.set(channelKey, { queue, debugInfo: undefined });
115
+ }
116
+ const queue = channelMap.get(channelKey).queue;
117
+ const respondToSender = (outgoingPacket) => connectionChannel
118
+ .send(outgoingPacket)
119
+ .pipe(Effect.withSpan(`respondToSender:${outgoingPacket._tag}:${outgoingPacket.source}→${outgoingPacket.target}`, { attributes: packetAsOtelAttributes(outgoingPacket) }), Effect.orDie);
120
+ if (Schema.is(MeshSchema.ProxyChannelPacket)(packet)) {
121
+ yield* Queue.offer(queue, { packet, respondToSender });
122
+ }
123
+ else if (Schema.is(MeshSchema.MessageChannelPacket)(packet)) {
124
+ yield* Queue.offer(queue, { packet, respondToSender });
125
+ }
126
+ }
127
+ else {
128
+ if (Schema.is(MeshSchema.MessageChannelPacket)(packet)) {
129
+ const noTransferableResponse = checkTransferableConnections(packet);
130
+ if (noTransferableResponse !== undefined) {
131
+ yield* Effect.spanEvent(`No transferable connections found for ${packet.source}→${packet.target}`);
132
+ return yield* connectionChannel.send(noTransferableResponse).pipe(Effect.withSpan(`sendNoTransferableResponse:${packet.source}→${packet.target}`, {
133
+ attributes: packetAsOtelAttributes(noTransferableResponse),
134
+ }));
135
+ }
136
+ }
137
+ yield* sendPacket(packet);
138
+ }
139
+ })), Stream.runDrain, Effect.orDie, Effect.tapCauseLogPretty, Effect.forkScoped);
140
+ connectionChannels.set(targetNodeName, { channel: connectionChannel, listenFiber });
141
+ const connectionAddedPacket = MeshSchema.NetworkConnectionAdded.make({
142
+ source: nodeName,
143
+ target: targetNodeName,
144
+ });
145
+ yield* sendPacket(connectionAddedPacket).pipe(Effect.ignoreLogged);
146
+ }).pipe(Effect.withSpan(`addConnection:${nodeName}→${targetNodeName}`, {
147
+ attributes: { supportsTransferables: connectionChannel.supportsTransferables },
148
+ })); // any-cast needed for error/never overload
149
+ const removeConnection = (targetNodeName) => Effect.gen(function* () {
150
+ if (!connectionChannels.has(targetNodeName)) {
151
+ yield* new Cause.NoSuchElementException(`No connection found for ${targetNodeName}`);
152
+ }
153
+ yield* Fiber.interrupt(connectionChannels.get(targetNodeName).listenFiber);
154
+ connectionChannels.delete(targetNodeName);
155
+ });
156
+ // TODO add heartbeat to detect dead connections (for both e2e and proxying)
157
+ // TODO when a channel is established in the same origin, we can use a weblock to detect disconnects
158
+ const makeChannel = ({ target, channelName, schema: inputSchema,
159
+ // TODO in the future we could have a mode that prefers messagechannels and then falls back to proxies if needed
160
+ mode, timeout = Duration.seconds(1), }) => Effect.gen(function* () {
161
+ const schema = WebChannel.mapSchema(inputSchema);
162
+ const channelKey = `${target}-${channelName}`;
163
+ if (!channelMap.has(channelKey)) {
164
+ const queue = yield* Queue.unbounded().pipe(Effect.acquireRelease(Queue.shutdown));
165
+ channelMap.set(channelKey, { queue, debugInfo: undefined });
166
+ }
167
+ const queue = channelMap.get(channelKey).queue;
168
+ yield* Effect.addFinalizer(() => Effect.sync(() => channelMap.delete(channelKey)));
169
+ if (mode === 'messagechannel') {
170
+ // console.debug(nodeName, 'message mode', modeRef.current)
171
+ // NOTE already retries internally when transferables are required
172
+ const channel = yield* makeMessageChannel({
173
+ nodeName,
174
+ queue,
175
+ newConnectionAvailablePubSub,
176
+ target,
177
+ channelName,
178
+ schema,
179
+ sendPacket,
180
+ checkTransferableConnections,
181
+ });
182
+ channelMap.set(channelKey, { queue, debugInfo: { channel, target } });
183
+ return channel;
184
+ }
185
+ else {
186
+ const channel = yield* makeProxyChannel({
187
+ nodeName,
188
+ newConnectionAvailablePubSub,
189
+ target,
190
+ channelName,
191
+ schema,
192
+ queue,
193
+ sendPacket,
194
+ });
195
+ channelMap.set(channelKey, { queue, debugInfo: { channel, target } });
196
+ return channel;
197
+ }
198
+ }).pipe(Effect.withSpanScoped(`makeChannel:${nodeName}→${target}(${channelName})`, {
199
+ attributes: { target, channelName, mode, timeout },
200
+ }), Effect.annotateLogs({ nodeName }));
201
+ const connectionKeys = Effect.sync(() => new Set(connectionChannels.keys()));
202
+ const debug = {
203
+ print: () => {
204
+ console.log('Connections:', connectionChannels.size);
205
+ for (const [key, value] of connectionChannels) {
206
+ console.log(` ${key}: supportsTransferables=${value.channel.supportsTransferables}`);
207
+ }
208
+ console.log('Channels:', channelMap.size);
209
+ for (const [key, value] of channelMap) {
210
+ console.log(` ${key}: \n`, ` Queue: ${value.queue.unsafeSize().pipe(Option.getOrUndefined)}`, value.queue, '\n', ` Channel: target=${value.debugInfo?.target} supportsTransferables=${value.debugInfo?.channel.supportsTransferables}`, value.debugInfo?.channel);
211
+ }
212
+ },
213
+ };
214
+ return { nodeName, addConnection, removeConnection, makeChannel, connectionKeys, debug };
215
+ }).pipe(Effect.withSpan(`makeMeshNode:${nodeName}`));
216
+ //# sourceMappingURL=node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=node.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.test.d.ts","sourceRoot":"","sources":["../src/node.test.ts"],"names":[],"mappings":""}