@livestore/webmesh 0.3.0-dev.37 → 0.3.0-dev.38

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 (44) hide show
  1. package/README.md +19 -3
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/channel/{message-channel-internal.d.ts → direct-channel-internal.d.ts} +7 -7
  4. package/dist/channel/direct-channel-internal.d.ts.map +1 -0
  5. package/dist/channel/{message-channel-internal.js → direct-channel-internal.js} +22 -22
  6. package/dist/channel/direct-channel-internal.js.map +1 -0
  7. package/dist/channel/{message-channel.d.ts → direct-channel.d.ts} +3 -3
  8. package/dist/channel/direct-channel.d.ts.map +1 -0
  9. package/dist/channel/{message-channel.js → direct-channel.js} +17 -17
  10. package/dist/channel/direct-channel.js.map +1 -0
  11. package/dist/channel/proxy-channel.d.ts.map +1 -1
  12. package/dist/channel/proxy-channel.js +84 -21
  13. package/dist/channel/proxy-channel.js.map +1 -1
  14. package/dist/common.d.ts +11 -5
  15. package/dist/common.d.ts.map +1 -1
  16. package/dist/common.js +6 -1
  17. package/dist/common.js.map +1 -1
  18. package/dist/mesh-schema.d.ts +15 -15
  19. package/dist/mesh-schema.d.ts.map +1 -1
  20. package/dist/mesh-schema.js +9 -9
  21. package/dist/mesh-schema.js.map +1 -1
  22. package/dist/node.d.ts +10 -5
  23. package/dist/node.d.ts.map +1 -1
  24. package/dist/node.js +68 -30
  25. package/dist/node.js.map +1 -1
  26. package/dist/node.test.js +114 -17
  27. package/dist/node.test.js.map +1 -1
  28. package/dist/websocket-edge.d.ts +2 -1
  29. package/dist/websocket-edge.d.ts.map +1 -1
  30. package/dist/websocket-edge.js +6 -2
  31. package/dist/websocket-edge.js.map +1 -1
  32. package/package.json +3 -4
  33. package/src/channel/{message-channel-internal.ts → direct-channel-internal.ts} +29 -29
  34. package/src/channel/{message-channel.ts → direct-channel.ts} +20 -20
  35. package/src/channel/proxy-channel.ts +107 -25
  36. package/src/common.ts +12 -4
  37. package/src/mesh-schema.ts +16 -19
  38. package/src/node.test.ts +185 -17
  39. package/src/node.ts +97 -35
  40. package/src/websocket-edge.ts +7 -1
  41. package/dist/channel/message-channel-internal.d.ts.map +0 -1
  42. package/dist/channel/message-channel-internal.js.map +0 -1
  43. package/dist/channel/message-channel.d.ts.map +0 -1
  44. package/dist/channel/message-channel.js.map +0 -1
package/dist/common.d.ts CHANGED
@@ -1,12 +1,12 @@
1
1
  import { type Effect, Schema } from '@livestore/utils/effect';
2
- import type { MessageChannelPacket, Packet, ProxyChannelPacket } from './mesh-schema.js';
2
+ import type { DirectChannelPacket, Packet, ProxyChannelPacket } from './mesh-schema.js';
3
3
  export type ProxyQueueItem = {
4
4
  packet: typeof ProxyChannelPacket.Type;
5
5
  respondToSender: (msg: typeof ProxyChannelPacket.Type) => Effect.Effect<void>;
6
6
  };
7
7
  export type MessageQueueItem = {
8
- packet: typeof MessageChannelPacket.Type;
9
- respondToSender: (msg: typeof MessageChannelPacket.Type) => Effect.Effect<void>;
8
+ packet: typeof DirectChannelPacket.Type;
9
+ respondToSender: (msg: typeof DirectChannelPacket.Type) => Effect.Effect<void>;
10
10
  };
11
11
  export type MeshNodeName = string;
12
12
  export type ChannelName = string;
@@ -29,7 +29,7 @@ export declare const packetAsOtelAttributes: (packet: typeof Packet.Type) => {
29
29
  readonly source: string;
30
30
  readonly channelName: string;
31
31
  readonly hops: readonly string[];
32
- readonly _tag: "MessageChannelRequest";
32
+ readonly _tag: "DirectChannelRequest";
33
33
  } | {
34
34
  readonly remainingHops: readonly string[];
35
35
  readonly reqId: string;
@@ -38,7 +38,7 @@ export declare const packetAsOtelAttributes: (packet: typeof Packet.Type) => {
38
38
  readonly source: string;
39
39
  readonly channelName: string;
40
40
  readonly hops: readonly string[];
41
- readonly _tag: "MessageChannelResponseNoTransferables";
41
+ readonly _tag: "DirectChannelResponseNoTransferables";
42
42
  } | {
43
43
  readonly remainingHops?: undefined;
44
44
  readonly id: string;
@@ -101,5 +101,11 @@ export declare const packetAsOtelAttributes: (packet: typeof Packet.Type) => {
101
101
  packetId: string;
102
102
  'span.label': string;
103
103
  };
104
+ export declare const ListenForChannelResult: Schema.Struct<{
105
+ channelName: typeof Schema.String;
106
+ source: typeof Schema.String;
107
+ mode: Schema.Union<[Schema.Literal<["proxy"]>, Schema.Literal<["direct"]>]>;
108
+ }>;
109
+ export type ListenForChannelResult = typeof ListenForChannelResult.Type;
104
110
  export {};
105
111
  //# sourceMappingURL=common.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAa,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAExE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAExF,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,OAAO,kBAAkB,CAAC,IAAI,CAAA;IACtC,eAAe,EAAE,CAAC,GAAG,EAAE,OAAO,kBAAkB,CAAC,IAAI,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;CAC9E,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,OAAO,oBAAoB,CAAC,IAAI,CAAA;IACxC,eAAe,EAAE,CAAC,GAAG,EAAE,OAAO,oBAAoB,CAAC,IAAI,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;CAChF,CAAA;AAED,MAAM,MAAM,YAAY,GAAG,MAAM,CAAA;AAEjC,MAAM,MAAM,WAAW,GAAG,MAAM,CAAA;AAChC,MAAM,MAAM,UAAU,GAAG,UAAU,YAAY,iBAAiB,WAAW,EAAE,CAAA;;;;;;AAQ7E,qBAAa,sBAAuB,SAAQ,2BAE1C;CAAG;AAEL,eAAO,MAAM,sBAAsB,GAAI,QAAQ,OAAO,MAAM,CAAC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAK/D,CAAA"}
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAa,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAExE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAEvF,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,OAAO,kBAAkB,CAAC,IAAI,CAAA;IACtC,eAAe,EAAE,CAAC,GAAG,EAAE,OAAO,kBAAkB,CAAC,IAAI,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;CAC9E,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,OAAO,mBAAmB,CAAC,IAAI,CAAA;IACvC,eAAe,EAAE,CAAC,GAAG,EAAE,OAAO,mBAAmB,CAAC,IAAI,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;CAC/E,CAAA;AAED,MAAM,MAAM,YAAY,GAAG,MAAM,CAAA;AAEjC,MAAM,MAAM,WAAW,GAAG,MAAM,CAAA;AAChC,MAAM,MAAM,UAAU,GAAG,UAAU,YAAY,iBAAiB,WAAW,EAAE,CAAA;;;;;;AAQ7E,qBAAa,sBAAuB,SAAQ,2BAE1C;CAAG;AAEL,eAAO,MAAM,sBAAsB,GAAI,QAAQ,OAAO,MAAM,CAAC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAK/D,CAAA;AAEF,eAAO,MAAM,sBAAsB;;;;EAIjC,CAAA;AAEF,MAAM,MAAM,sBAAsB,GAAG,OAAO,sBAAsB,CAAC,IAAI,CAAA"}
package/dist/common.js CHANGED
@@ -11,6 +11,11 @@ export class EdgeAlreadyExistsError extends Schema.TaggedError()('EdgeAlreadyExi
11
11
  export const packetAsOtelAttributes = (packet) => ({
12
12
  packetId: packet.id,
13
13
  'span.label': packet.id + (Predicate.hasProperty(packet, 'reqId') && packet.reqId !== undefined ? ` for ${packet.reqId}` : ''),
14
- ...(packet._tag !== 'MessageChannelResponseSuccess' && packet._tag !== 'ProxyChannelPayload' ? { packet } : {}),
14
+ ...(packet._tag !== 'DirectChannelResponseSuccess' && packet._tag !== 'ProxyChannelPayload' ? { packet } : {}),
15
+ });
16
+ export const ListenForChannelResult = Schema.Struct({
17
+ channelName: Schema.String,
18
+ source: Schema.String,
19
+ mode: Schema.Union(Schema.Literal('proxy'), Schema.Literal('direct')),
15
20
  });
16
21
  //# sourceMappingURL=common.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"common.js","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,SAAS,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAmBxE,4DAA4D;AAC5D,8FAA8F;AAC9F,+BAA+B;AAC/B,QAAQ;AACR,OAAO;AAEP,MAAM,OAAO,sBAAuB,SAAQ,MAAM,CAAC,WAAW,EAA0B,CAAC,wBAAwB,EAAE;IACjH,MAAM,EAAE,MAAM,CAAC,MAAM;CACtB,CAAC;CAAG;AAEL,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,MAA0B,EAAE,EAAE,CAAC,CAAC;IACrE,QAAQ,EAAE,MAAM,CAAC,EAAE;IACnB,YAAY,EACV,MAAM,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAClH,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,+BAA+B,IAAI,MAAM,CAAC,IAAI,KAAK,qBAAqB,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;CAChH,CAAC,CAAA"}
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,SAAS,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAmBxE,4DAA4D;AAC5D,8FAA8F;AAC9F,+BAA+B;AAC/B,QAAQ;AACR,OAAO;AAEP,MAAM,OAAO,sBAAuB,SAAQ,MAAM,CAAC,WAAW,EAA0B,CAAC,wBAAwB,EAAE;IACjH,MAAM,EAAE,MAAM,CAAC,MAAM;CACtB,CAAC;CAAG;AAEL,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,MAA0B,EAAE,EAAE,CAAC,CAAC;IACrE,QAAQ,EAAE,MAAM,CAAC,EAAE;IACnB,YAAY,EACV,MAAM,CAAC,EAAE,GAAG,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAClH,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,8BAA8B,IAAI,MAAM,CAAC,IAAI,KAAK,qBAAqB,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;CAC/G,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,CAAC;IAClD,WAAW,EAAE,MAAM,CAAC,MAAM;IAC1B,MAAM,EAAE,MAAM,CAAC,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;CACtE,CAAC,CAAA"}
@@ -1,5 +1,5 @@
1
1
  import { Schema } from '@livestore/utils/effect';
2
- declare const MessageChannelRequest_base: Schema.TaggedStruct<"MessageChannelRequest", {
2
+ declare const DirectChannelRequest_base: Schema.TaggedStruct<"DirectChannelRequest", {
3
3
  remainingHops: Schema.optional<Schema.Array$<typeof Schema.String>>;
4
4
  channelVersion: typeof Schema.Number;
5
5
  /** Only set if the request is in response to an incoming request */
@@ -16,15 +16,15 @@ declare const MessageChannelRequest_base: Schema.TaggedStruct<"MessageChannelReq
16
16
  hops: Schema.Array$<typeof Schema.String>;
17
17
  }>;
18
18
  /**
19
- * Needs to go through already existing MessageChannel edges, times out otherwise
19
+ * Needs to go through already existing DirectChannel edges, times out otherwise
20
20
  *
21
21
  * Can't yet contain the `port` because the request might be duplicated while forwarding to multiple nodes.
22
22
  * We need a clear path back to the sender to avoid this, thus we respond with a separate
23
- * `MessageChannelResponseSuccess` which contains the `port`.
23
+ * `DirectChannelResponseSuccess` which contains the `port`.
24
24
  */
25
- export declare class MessageChannelRequest extends MessageChannelRequest_base {
25
+ export declare class DirectChannelRequest extends DirectChannelRequest_base {
26
26
  }
27
- declare const MessageChannelResponseSuccess_base: Schema.TaggedStruct<"MessageChannelResponseSuccess", {
27
+ declare const DirectChannelResponseSuccess_base: Schema.TaggedStruct<"DirectChannelResponseSuccess", {
28
28
  reqId: typeof Schema.String;
29
29
  port: Schema.Schema<MessagePort, MessagePort, never>;
30
30
  remainingHops: Schema.Array$<typeof Schema.String>;
@@ -35,9 +35,9 @@ declare const MessageChannelResponseSuccess_base: Schema.TaggedStruct<"MessageCh
35
35
  channelName: typeof Schema.String;
36
36
  hops: Schema.Array$<typeof Schema.String>;
37
37
  }>;
38
- export declare class MessageChannelResponseSuccess extends MessageChannelResponseSuccess_base {
38
+ export declare class DirectChannelResponseSuccess extends DirectChannelResponseSuccess_base {
39
39
  }
40
- declare const MessageChannelResponseNoTransferables_base: Schema.TaggedStruct<"MessageChannelResponseNoTransferables", {
40
+ declare const DirectChannelResponseNoTransferables_base: Schema.TaggedStruct<"DirectChannelResponseNoTransferables", {
41
41
  reqId: typeof Schema.String;
42
42
  remainingHops: Schema.Array$<typeof Schema.String>;
43
43
  id: Schema.PropertySignature<":", string, never, "?:", string | undefined, true, never>;
@@ -46,7 +46,7 @@ declare const MessageChannelResponseNoTransferables_base: Schema.TaggedStruct<"M
46
46
  channelName: typeof Schema.String;
47
47
  hops: Schema.Array$<typeof Schema.String>;
48
48
  }>;
49
- export declare class MessageChannelResponseNoTransferables extends MessageChannelResponseNoTransferables_base {
49
+ export declare class DirectChannelResponseNoTransferables extends DirectChannelResponseNoTransferables_base {
50
50
  }
51
51
  declare const ProxyChannelRequest_base: Schema.TaggedStruct<"ProxyChannelRequest", {
52
52
  remainingHops: Schema.optional<typeof Schema.Undefined>;
@@ -140,13 +140,13 @@ export declare const BroadcastChannelPacket: Schema.TaggedStruct<"BroadcastChann
140
140
  source: typeof Schema.String;
141
141
  target: Schema.Literal<["-"]>;
142
142
  }>;
143
- declare const MessageChannelPacket_base: Schema.Union<[typeof MessageChannelRequest, typeof MessageChannelResponseSuccess, typeof MessageChannelResponseNoTransferables]>;
144
- export declare class MessageChannelPacket extends MessageChannelPacket_base {
143
+ declare const DirectChannelPacket_base: Schema.Union<[typeof DirectChannelRequest, typeof DirectChannelResponseSuccess, typeof DirectChannelResponseNoTransferables]>;
144
+ export declare class DirectChannelPacket extends DirectChannelPacket_base {
145
145
  }
146
146
  declare const ProxyChannelPacket_base: Schema.Union<[typeof ProxyChannelRequest, typeof ProxyChannelResponseSuccess, typeof ProxyChannelPayload, typeof ProxyChannelPayloadAck]>;
147
147
  export declare class ProxyChannelPacket extends ProxyChannelPacket_base {
148
148
  }
149
- declare const Packet_base: Schema.Union<[typeof MessageChannelPacket, typeof ProxyChannelPacket, typeof NetworkEdgeAdded, typeof NetworkTopologyRequest, typeof NetworkTopologyResponse, Schema.TaggedStruct<"BroadcastChannelPacket", {
149
+ declare const Packet_base: Schema.Union<[typeof DirectChannelPacket, typeof ProxyChannelPacket, typeof NetworkEdgeAdded, typeof NetworkTopologyRequest, typeof NetworkTopologyResponse, Schema.TaggedStruct<"BroadcastChannelPacket", {
150
150
  id: Schema.PropertySignature<":", string, never, "?:", string | undefined, true, never>;
151
151
  channelName: typeof Schema.String;
152
152
  /**
@@ -160,11 +160,11 @@ declare const Packet_base: Schema.Union<[typeof MessageChannelPacket, typeof Pro
160
160
  }>]>;
161
161
  export declare class Packet extends Packet_base {
162
162
  }
163
- declare const MessageChannelPing_base: Schema.TaggedStruct<"MessageChannelPing", {}>;
164
- export declare class MessageChannelPing extends MessageChannelPing_base {
163
+ declare const DirectChannelPing_base: Schema.TaggedStruct<"DirectChannelPing", {}>;
164
+ export declare class DirectChannelPing extends DirectChannelPing_base {
165
165
  }
166
- declare const MessageChannelPong_base: Schema.TaggedStruct<"MessageChannelPong", {}>;
167
- export declare class MessageChannelPong extends MessageChannelPong_base {
166
+ declare const DirectChannelPong_base: Schema.TaggedStruct<"DirectChannelPong", {}>;
167
+ export declare class DirectChannelPong extends DirectChannelPong_base {
168
168
  }
169
169
  export {};
170
170
  //# sourceMappingURL=mesh-schema.d.ts.map
@@ -1 +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;;;;IA6B5D,oEAAoE;;IAEpE;;;OAGG;;;;;;;;AAhBL;;;;;;GAMG;AACH,qBAAa,qBAAsB,SAAQ,0BAWzC;CAAG;;;;;;;;;;;;AAEL,qBAAa,6BAA8B,SAAQ,kCAOjD;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;AACH,qBAAa,gBAAiB,SAAQ,qBAIpC;CAAG;;;;IAKH,iDAAiD;;;;AAHnD,qBAAa,sBAAuB,SAAQ,2BAM1C;CAAG;;;;;;;IAQH,iDAAiD;;;;AANnD,qBAAa,uBAAwB,SAAQ,4BAS3C;CAAG;AAEL,eAAO,MAAM,sBAAsB;;;IAGjC;;;OAGG;;;;;EAKH,CAAA;;AAEF,qBAAa,oBAAqB,SAAQ,yBAIzC;CAAG;;AAEJ,qBAAa,kBAAmB,SAAQ,uBAKvC;CAAG;;;;IArBF;;;OAGG;;;;;;AAoBL,qBAAa,MAAO,SAAQ,WAO3B;CAAG;;AAEJ,qBAAa,kBAAmB,SAAQ,uBAA6C;CAAG;;AACxF,qBAAa,kBAAmB,SAAQ,uBAA6C;CAAG"}
1
+ {"version":3,"file":"mesh-schema.d.ts","sourceRoot":"","sources":["../src/mesh-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAgB,MAAM,yBAAyB,CAAA;;;;IA6B5D,oEAAoE;;IAEpE;;;OAGG;;;;;;;;AAhBL;;;;;;GAMG;AACH,qBAAa,oBAAqB,SAAQ,yBAWxC;CAAG;;;;;;;;;;;;AAEL,qBAAa,4BAA6B,SAAQ,iCAOhD;CAAG;;;;;;;;;;AAEL,qBAAa,oCAAqC,SAAQ,yCAIxD;CAAG;;;;;;;;;;AAEL,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;AACH,qBAAa,gBAAiB,SAAQ,qBAIpC;CAAG;;;;IAKH,iDAAiD;;;;AAHnD,qBAAa,sBAAuB,SAAQ,2BAM1C;CAAG;;;;;;;IAQH,iDAAiD;;;;AANnD,qBAAa,uBAAwB,SAAQ,4BAS3C;CAAG;AAEL,eAAO,MAAM,sBAAsB;;;IAGjC;;;OAGG;;;;;EAKH,CAAA;;AAEF,qBAAa,mBAAoB,SAAQ,wBAIxC;CAAG;;AAEJ,qBAAa,kBAAmB,SAAQ,uBAKvC;CAAG;;;;IArBF;;;OAGG;;;;;;AAoBL,qBAAa,MAAO,SAAQ,WAO3B;CAAG;;AAEJ,qBAAa,iBAAkB,SAAQ,sBAA4C;CAAG;;AACtF,qBAAa,iBAAkB,SAAQ,sBAA4C;CAAG"}
@@ -10,13 +10,13 @@ const defaultPacketFields = {
10
10
  };
11
11
  const remainingHopsUndefined = Schema.Undefined.pipe(Schema.optional);
12
12
  /**
13
- * Needs to go through already existing MessageChannel edges, times out otherwise
13
+ * Needs to go through already existing DirectChannel edges, times out otherwise
14
14
  *
15
15
  * Can't yet contain the `port` because the request might be duplicated while forwarding to multiple nodes.
16
16
  * We need a clear path back to the sender to avoid this, thus we respond with a separate
17
- * `MessageChannelResponseSuccess` which contains the `port`.
17
+ * `DirectChannelResponseSuccess` which contains the `port`.
18
18
  */
19
- export class MessageChannelRequest extends Schema.TaggedStruct('MessageChannelRequest', {
19
+ export class DirectChannelRequest extends Schema.TaggedStruct('DirectChannelRequest', {
20
20
  ...defaultPacketFields,
21
21
  remainingHops: Schema.Array(Schema.String).pipe(Schema.optional),
22
22
  channelVersion: Schema.Number,
@@ -29,7 +29,7 @@ export class MessageChannelRequest extends Schema.TaggedStruct('MessageChannelRe
29
29
  sourceId: Schema.String,
30
30
  }) {
31
31
  }
32
- export class MessageChannelResponseSuccess extends Schema.TaggedStruct('MessageChannelResponseSuccess', {
32
+ export class DirectChannelResponseSuccess extends Schema.TaggedStruct('DirectChannelResponseSuccess', {
33
33
  ...defaultPacketFields,
34
34
  reqId: Schema.String,
35
35
  port: Transferable.MessagePort,
@@ -38,7 +38,7 @@ export class MessageChannelResponseSuccess extends Schema.TaggedStruct('MessageC
38
38
  channelVersion: Schema.Number,
39
39
  }) {
40
40
  }
41
- export class MessageChannelResponseNoTransferables extends Schema.TaggedStruct('MessageChannelResponseNoTransferables', {
41
+ export class DirectChannelResponseNoTransferables extends Schema.TaggedStruct('DirectChannelResponseNoTransferables', {
42
42
  ...defaultPacketFields,
43
43
  reqId: Schema.String,
44
44
  remainingHops: Schema.Array(Schema.String),
@@ -113,14 +113,14 @@ export const BroadcastChannelPacket = Schema.TaggedStruct('BroadcastChannelPacke
113
113
  source: Schema.String,
114
114
  target: Schema.Literal('-'),
115
115
  });
116
- export class MessageChannelPacket extends Schema.Union(MessageChannelRequest, MessageChannelResponseSuccess, MessageChannelResponseNoTransferables) {
116
+ export class DirectChannelPacket extends Schema.Union(DirectChannelRequest, DirectChannelResponseSuccess, DirectChannelResponseNoTransferables) {
117
117
  }
118
118
  export class ProxyChannelPacket extends Schema.Union(ProxyChannelRequest, ProxyChannelResponseSuccess, ProxyChannelPayload, ProxyChannelPayloadAck) {
119
119
  }
120
- export class Packet extends Schema.Union(MessageChannelPacket, ProxyChannelPacket, NetworkEdgeAdded, NetworkTopologyRequest, NetworkTopologyResponse, BroadcastChannelPacket) {
120
+ export class Packet extends Schema.Union(DirectChannelPacket, ProxyChannelPacket, NetworkEdgeAdded, NetworkTopologyRequest, NetworkTopologyResponse, BroadcastChannelPacket) {
121
121
  }
122
- export class MessageChannelPing extends Schema.TaggedStruct('MessageChannelPing', {}) {
122
+ export class DirectChannelPing extends Schema.TaggedStruct('DirectChannelPing', {}) {
123
123
  }
124
- export class MessageChannelPong extends Schema.TaggedStruct('MessageChannelPong', {}) {
124
+ export class DirectChannelPong extends Schema.TaggedStruct('DirectChannelPong', {}) {
125
125
  }
126
126
  //# sourceMappingURL=mesh-schema.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"mesh-schema.js","sourceRoot":"","sources":["../src/mesh-schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mesh-schema.js","sourceRoot":"","sources":["../src/mesh-schema.ts"],"names":[],"mappings":"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"}
package/dist/node.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { Cause, Duration, Effect, Schema, Scope, WebChannel } from '@livestore/utils/effect';
2
- import type { MeshNodeName } from './common.js';
1
+ import { Cause, Duration, Effect, Schema, Scope, Stream, WebChannel } from '@livestore/utils/effect';
2
+ import type { ListenForChannelResult, MeshNodeName } from './common.js';
3
3
  import { EdgeAlreadyExistsError } from './common.js';
4
4
  import * as WebmeshSchema from './mesh-schema.js';
5
5
  type EdgeChannel = WebChannel.WebChannel<typeof WebmeshSchema.Packet.Type, typeof WebmeshSchema.Packet.Type>;
@@ -37,8 +37,12 @@ export interface MeshNode<TName extends MeshNodeName = MeshNodeName> {
37
37
  }): Effect.Effect<void, EdgeAlreadyExistsError, Scope.Scope>;
38
38
  };
39
39
  removeEdge: (targetNodeName: MeshNodeName) => Effect.Effect<void, Cause.NoSuchElementException>;
40
+ hasChannel: ({ target, channelName, }: {
41
+ target: MeshNodeName;
42
+ channelName: string;
43
+ }) => Effect.Effect<boolean, never, Scope.Scope>;
40
44
  /**
41
- * Tries to broker a MessageChannel edge between the nodes, otherwise will proxy messages via hop-nodes
45
+ * Tries to broker a DirectChannel edge between the nodes, otherwise will proxy messages via hop-nodes
42
46
  *
43
47
  * For a channel to successfully open, both sides need to have a edge and call `makeChannel`.
44
48
  *
@@ -63,9 +67,9 @@ export interface MeshNode<TName extends MeshNodeName = MeshNodeName> {
63
67
  send: Schema.Schema<MsgSend, any>;
64
68
  };
65
69
  /**
66
- * If possible, prefer using a MessageChannel with transferables (i.e. transferring memory instead of copying it).
70
+ * If possible, prefer using a DirectChannel with transferables (i.e. transferring memory instead of copying it).
67
71
  */
68
- mode: 'messagechannel' | 'proxy';
72
+ mode: 'direct' | 'proxy';
69
73
  /**
70
74
  * Amount of time before we consider a channel creation failed and retry when a new edge is available
71
75
  *
@@ -73,6 +77,7 @@ export interface MeshNode<TName extends MeshNodeName = MeshNodeName> {
73
77
  */
74
78
  timeout?: Duration.DurationInput;
75
79
  }) => Effect.Effect<WebChannel.WebChannel<MsgListen, MsgSend>, never, Scope.Scope>;
80
+ listenForChannel: Stream.Stream<ListenForChannelResult>;
76
81
  /**
77
82
  * Creates a WebChannel that is broadcasted to all connected nodes.
78
83
  * Messages won't be buffered for nodes that join the network after the broadcast channel has been created.
@@ -1 +1 @@
1
- {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"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"}
package/dist/node.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { indent, LS_DEV, shouldNeverHappen } from '@livestore/utils';
2
2
  import { Cause, Deferred, Duration, Effect, Exit, Fiber, Option, PubSub, Queue, Schema, Scope, Stream, WebChannel, } from '@livestore/utils/effect';
3
- import { makeMessageChannel } from './channel/message-channel.js';
3
+ import { makeDirectChannel } from './channel/direct-channel.js';
4
4
  import { makeProxyChannel } from './channel/proxy-channel.js';
5
5
  import { EdgeAlreadyExistsError, packetAsOtelAttributes } from './common.js';
6
6
  import * as WebmeshSchema from './mesh-schema.js';
@@ -15,16 +15,17 @@ export const makeMeshNode = (nodeName) => Effect.gen(function* () {
15
15
  // Effect.acquireRelease(Queue.shutdown),
16
16
  // )
17
17
  const channelMap = new Map();
18
+ const channelRequestsQueue = yield* Queue.unbounded().pipe(Effect.acquireRelease(Queue.shutdown));
18
19
  const topologyRequestsMap = new Map();
19
20
  const broadcastChannelListenQueueMap = new Map();
20
21
  const checkTransferableEdges = (packet) => {
21
- if ((packet._tag === 'MessageChannelRequest' &&
22
+ if ((packet._tag === 'DirectChannelRequest' &&
22
23
  (edgeChannels.size === 0 ||
23
24
  // Either if direct edge does not support transferables ...
24
25
  edgeChannels.get(packet.target)?.channel.supportsTransferables === false)) ||
25
26
  // ... or if no forward-edges support transferables
26
27
  ![...edgeChannels.values()].some((c) => c.channel.supportsTransferables === true)) {
27
- return WebmeshSchema.MessageChannelResponseNoTransferables.make({
28
+ return WebmeshSchema.DirectChannelResponseNoTransferables.make({
28
29
  reqId: packet.id,
29
30
  channelName: packet.channelName,
30
31
  // NOTE for now we're "pretending" that the message is coming from the target node
@@ -113,6 +114,7 @@ export const makeMeshNode = (nodeName) => Effect.gen(function* () {
113
114
  if (edgeChannels.has(packet.target)) {
114
115
  const edgeChannel = edgeChannels.get(packet.target).channel;
115
116
  const hops = packet.source === nodeName ? [] : [...packet.hops, nodeName];
117
+ yield* Effect.annotateCurrentSpan({ hasDirectEdge: true });
116
118
  yield* edgeChannel.send({ ...packet, hops });
117
119
  }
118
120
  // In this case we have an expected route back we should follow
@@ -136,15 +138,18 @@ export const makeMeshNode = (nodeName) => Effect.gen(function* () {
136
138
  // Optimization: filter out edge where packet just came from
137
139
  const edgesToForwardTo = Array.from(edgeChannels)
138
140
  .filter(([name]) => name !== packet.source)
139
- .map(([_, con]) => con.channel);
141
+ .map(([name, con]) => ({ name, channel: con.channel }));
140
142
  // TODO if hops-depth=0, we should fail right away with no route found
141
143
  if (hops.length === 0 && edgesToForwardTo.length === 0 && LS_DEV) {
142
- console.log(nodeName, 'no route found', packet._tag, 'TODO handle better');
144
+ yield* Effect.logWarning(nodeName, 'no route found to', packet.target, packet._tag, 'TODO handle better');
143
145
  // TODO return a expected failure
144
146
  }
145
147
  const packetToSend = { ...packet, hops };
146
148
  // console.debug(nodeName, 'sendPacket:forwarding', packetToSend)
147
- yield* Effect.forEach(edgesToForwardTo, (con) => con.send(packetToSend), { concurrency: 'unbounded' });
149
+ yield* Effect.annotateCurrentSpan({ edgesToForwardTo: edgesToForwardTo.map(({ name }) => name) });
150
+ yield* Effect.forEach(edgesToForwardTo, ({ channel }) => channel.send(packetToSend), {
151
+ concurrency: 'unbounded',
152
+ });
148
153
  }
149
154
  }).pipe(Effect.withSpan(`sendPacket:${packet._tag}:${packet.source}→${packet.target}`, {
150
155
  attributes: packetAsOtelAttributes(packet),
@@ -161,7 +166,7 @@ export const makeMeshNode = (nodeName) => Effect.gen(function* () {
161
166
  // TODO use a priority queue instead to prioritize network-changes/edge-requests over payloads
162
167
  const listenFiber = yield* edgeChannel.listen.pipe(Stream.flatten(), Stream.tap((message) => Effect.gen(function* () {
163
168
  const packet = yield* Schema.decodeUnknown(WebmeshSchema.Packet)(message);
164
- // console.debug(nodeName, 'received', packet._tag, packet.source, packet.target)
169
+ // console.debug(nodeName, 'recv', packet._tag, packet.source, packet.target)
165
170
  if (handledPacketIds.has(packet.id))
166
171
  return;
167
172
  handledPacketIds.add(packet.id);
@@ -176,22 +181,29 @@ export const makeMeshNode = (nodeName) => Effect.gen(function* () {
176
181
  if (packet.target === nodeName) {
177
182
  const channelKey = `target:${packet.source}, channelName:${packet.channelName}`;
178
183
  if (!channelMap.has(channelKey)) {
179
- const queue = yield* Queue.unbounded().pipe(Effect.acquireRelease(Queue.shutdown));
180
- channelMap.set(channelKey, { queue, debugInfo: undefined });
184
+ const channelQueue = yield* Queue.unbounded().pipe(Effect.acquireRelease(Queue.shutdown));
185
+ channelMap.set(channelKey, { queue: channelQueue, debugInfo: undefined });
181
186
  }
182
- const queue = channelMap.get(channelKey).queue;
187
+ const channelQueue = channelMap.get(channelKey).queue;
183
188
  const respondToSender = (outgoingPacket) => edgeChannel
184
189
  .send(outgoingPacket)
185
190
  .pipe(Effect.withSpan(`respondToSender:${outgoingPacket._tag}:${outgoingPacket.source}→${outgoingPacket.target}`, { attributes: packetAsOtelAttributes(outgoingPacket) }), Effect.orDie);
186
191
  if (Schema.is(WebmeshSchema.ProxyChannelPacket)(packet)) {
187
- yield* Queue.offer(queue, { packet, respondToSender });
192
+ yield* Queue.offer(channelQueue, { packet, respondToSender });
188
193
  }
189
- else if (Schema.is(WebmeshSchema.MessageChannelPacket)(packet)) {
190
- yield* Queue.offer(queue, { packet, respondToSender });
194
+ else if (Schema.is(WebmeshSchema.DirectChannelPacket)(packet)) {
195
+ yield* Queue.offer(channelQueue, { packet, respondToSender });
196
+ }
197
+ if (packet._tag === 'ProxyChannelRequest' || packet._tag === 'DirectChannelRequest') {
198
+ yield* Queue.offer(channelRequestsQueue, {
199
+ channelName: packet.channelName,
200
+ source: packet.source,
201
+ mode: packet._tag === 'ProxyChannelRequest' ? 'proxy' : 'direct',
202
+ });
191
203
  }
192
204
  }
193
205
  else {
194
- if (Schema.is(WebmeshSchema.MessageChannelPacket)(packet)) {
206
+ if (Schema.is(WebmeshSchema.DirectChannelPacket)(packet)) {
195
207
  const noTransferableResponse = checkTransferableEdges(packet);
196
208
  if (noTransferableResponse !== undefined) {
197
209
  yield* Effect.spanEvent(`No transferable edges found for ${packet.source}→${packet.target}`);
@@ -211,7 +223,7 @@ export const makeMeshNode = (nodeName) => Effect.gen(function* () {
211
223
  target: targetNodeName,
212
224
  });
213
225
  yield* sendPacket(edgeAddedPacket).pipe(Effect.orDie);
214
- }).pipe(Effect.annotateLogs({ 'addEdge:target': targetNodeName }), Effect.withSpan(`addEdge:${nodeName}→${targetNodeName}`, {
226
+ }).pipe(Effect.annotateLogs({ 'addEdge:target': targetNodeName, nodeName }), Effect.withSpan(`addEdge:${nodeName}→${targetNodeName}`, {
215
227
  attributes: { supportsTransferables: edgeChannel.supportsTransferables },
216
228
  })); // any-cast needed for error/never overload
217
229
  const removeEdge = (targetNodeName) => Effect.gen(function* () {
@@ -221,10 +233,11 @@ export const makeMeshNode = (nodeName) => Effect.gen(function* () {
221
233
  yield* Fiber.interrupt(edgeChannels.get(targetNodeName).listenFiber);
222
234
  edgeChannels.delete(targetNodeName);
223
235
  });
236
+ const hasChannel = ({ target, channelName }) => Effect.sync(() => channelMap.has(`target:${target}, channelName:${channelName}`));
224
237
  // TODO add heartbeat to detect dead edges (for both e2e and proxying)
225
238
  // TODO when a channel is established in the same origin, we can use a weblock to detect disconnects
226
239
  const makeChannel = ({ target, channelName, schema: inputSchema,
227
- // TODO in the future we could have a mode that prefers messagechannels and then falls back to proxies if needed
240
+ // TODO in the future we could have a mode that prefers directs and then falls back to proxies if needed
228
241
  mode, timeout = Duration.seconds(1), }) => Effect.gen(function* () {
229
242
  const schema = WebChannel.mapSchema(inputSchema);
230
243
  const channelKey = `target:${target}, channelName:${channelName}`;
@@ -235,20 +248,20 @@ export const makeMeshNode = (nodeName) => Effect.gen(function* () {
235
248
  }
236
249
  }
237
250
  else {
238
- const queue = yield* Queue.unbounded().pipe(Effect.acquireRelease(Queue.shutdown));
239
- channelMap.set(channelKey, { queue, debugInfo: undefined });
251
+ const channelQueue = yield* Queue.unbounded().pipe(Effect.acquireRelease(Queue.shutdown));
252
+ channelMap.set(channelKey, { queue: channelQueue, debugInfo: undefined });
240
253
  }
241
- const queue = channelMap.get(channelKey).queue;
254
+ const channelQueue = channelMap.get(channelKey).queue;
242
255
  yield* Effect.addFinalizer(() => Effect.sync(() => channelMap.delete(channelKey)));
243
- if (mode === 'messagechannel') {
256
+ if (mode === 'direct') {
244
257
  const incomingPacketsQueue = yield* Queue.unbounded().pipe(Effect.acquireRelease(Queue.shutdown));
245
258
  // We're we're draining the queue into another new queue.
246
259
  // It's a bit of a mystery why this is needed, since the unit tests also work without it.
247
260
  // But for the LiveStore devtools to actually work, we need to do this.
248
261
  // We should figure out some day why this is needed and further simplify if possible.
249
- yield* Queue.takeBetween(queue, 1, 10).pipe(Effect.tap((_) => Queue.offerAll(incomingPacketsQueue, _)), Effect.forever, Effect.interruptible, Effect.tapCauseLogPretty, Effect.forkScoped);
262
+ yield* Queue.takeBetween(channelQueue, 1, 10).pipe(Effect.tap((_) => Queue.offerAll(incomingPacketsQueue, _)), Effect.forever, Effect.interruptible, Effect.tapCauseLogPretty, Effect.forkScoped);
250
263
  // NOTE already retries internally when transferables are required
251
- const { webChannel, initialEdgeDeferred } = yield* makeMessageChannel({
264
+ const { webChannel, initialEdgeDeferred } = yield* makeDirectChannel({
252
265
  nodeName,
253
266
  incomingPacketsQueue,
254
267
  newEdgeAvailablePubSub,
@@ -258,7 +271,7 @@ export const makeMeshNode = (nodeName) => Effect.gen(function* () {
258
271
  sendPacket,
259
272
  checkTransferableEdges,
260
273
  });
261
- channelMap.set(channelKey, { queue, debugInfo: { channel: webChannel, target } });
274
+ channelMap.set(channelKey, { queue: channelQueue, debugInfo: { channel: webChannel, target } });
262
275
  yield* initialEdgeDeferred;
263
276
  return webChannel;
264
277
  }
@@ -269,17 +282,36 @@ export const makeMeshNode = (nodeName) => Effect.gen(function* () {
269
282
  target,
270
283
  channelName,
271
284
  schema,
272
- queue,
285
+ queue: channelQueue,
273
286
  sendPacket,
274
287
  });
275
- channelMap.set(channelKey, { queue, debugInfo: { channel, target } });
288
+ channelMap.set(channelKey, { queue: channelQueue, debugInfo: { channel, target } });
276
289
  return channel;
277
290
  }
278
291
  }).pipe(
279
292
  // Effect.timeout(timeout),
280
293
  Effect.withSpanScoped(`makeChannel:${nodeName}→${target}(${channelName})`, {
281
294
  attributes: { target, channelName, mode, timeout },
282
- }), Effect.annotateLogs({ nodeName }));
295
+ }), Effect.annotateLogs({ nodeName, target, channelName }));
296
+ // TODO consider supporting multiple listeners
297
+ // TODO also provide a way to allow for reconnects
298
+ let listenAlreadyStarted = false;
299
+ const listenForChannel = Stream.suspend(() => {
300
+ if (listenAlreadyStarted) {
301
+ return shouldNeverHappen('listenForChannel already started');
302
+ }
303
+ listenAlreadyStarted = true;
304
+ const hash = (res) => `${res.channelName}:${res.source}:${res.mode}`;
305
+ const seen = new Set();
306
+ return Stream.fromQueue(channelRequestsQueue).pipe(Stream.filter((res) => {
307
+ const hashed = hash(res);
308
+ if (seen.has(hashed)) {
309
+ return false;
310
+ }
311
+ seen.add(hashed);
312
+ return true;
313
+ }));
314
+ });
283
315
  const makeBroadcastChannel = ({ channelName, schema }) => Effect.scopeWithCloseable((scope) => Effect.gen(function* () {
284
316
  if (broadcastChannelListenQueueMap.has(channelName)) {
285
317
  return shouldNeverHappen(`Broadcast channel ${channelName} already exists`, broadcastChannelListenQueueMap.get(channelName));
@@ -305,7 +337,7 @@ export const makeMeshNode = (nodeName) => Effect.gen(function* () {
305
337
  send,
306
338
  listen,
307
339
  closedDeferred,
308
- supportsTransferables: true,
340
+ supportsTransferables: false,
309
341
  schema: { listen: schema, send: schema },
310
342
  shutdown: Scope.close(scope, Exit.void),
311
343
  debugInfo,
@@ -337,14 +369,17 @@ export const makeMeshNode = (nodeName) => Effect.gen(function* () {
337
369
  },
338
370
  ping: (payload) => {
339
371
  Effect.gen(function* () {
340
- const msg = (via) => WebChannel.DebugPingMessage.make({ message: `ping from ${nodeName} via edge ${via}`, payload });
372
+ const msg = (via) => WebChannel.DebugPingMessage.make({ message: `ping from ${nodeName} via ${via}`, payload });
341
373
  for (const [channelName, con] of edgeChannels) {
342
374
  yield* Effect.logDebug(`sending ping via edge ${channelName}`);
343
375
  yield* con.channel.send(msg(`edge ${channelName}`));
344
376
  }
345
377
  for (const [channelKey, channel] of channelMap) {
346
- if (channel.debugInfo === undefined)
378
+ if (channel.debugInfo === undefined) {
379
+ yield* Effect.logDebug(`channel ${channelKey} has no debug info`);
347
380
  continue;
381
+ }
382
+ // if (channel.debugInfo === undefined) continue
348
383
  yield* Effect.logDebug(`sending ping via channel ${channelKey}`);
349
384
  yield* channel.debugInfo.channel.send(msg(`channel ${channelKey}`));
350
385
  }
@@ -362,8 +397,9 @@ export const makeMeshNode = (nodeName) => Effect.gen(function* () {
362
397
  yield* sendPacket(packet);
363
398
  yield* Effect.logDebug(`Waiting ${timeoutMs}ms for topology response`);
364
399
  yield* Effect.sleep(timeoutMs);
400
+ yield* Effect.logDebug(`Topology response (from ${nodeName}):`);
365
401
  for (const [key, value] of item) {
366
- yield* Effect.logDebug(`node '${key}' is connected to: ${Array.from(value.values()).join(', ')}`);
402
+ yield* Effect.logDebug(` node '${key}' has edge to: ${Array.from(value.values()).join(', ')}`);
367
403
  }
368
404
  }).pipe(Effect.provide(runtime), Effect.tapCauseLogPretty, Effect.runPromise),
369
405
  };
@@ -371,7 +407,9 @@ export const makeMeshNode = (nodeName) => Effect.gen(function* () {
371
407
  nodeName,
372
408
  addEdge,
373
409
  removeEdge,
410
+ hasChannel,
374
411
  makeChannel,
412
+ listenForChannel,
375
413
  makeBroadcastChannel,
376
414
  edgeKeys,
377
415
  debug,