import { Cause, Duration, Effect, Schema, Scope, Stream, WebChannel } from '@livestore/utils/effect'; import { type ProxyChannelSimulationParams } from './channel/proxy-channel.ts'; import type { ListenForChannelResult, MeshNodeName } from './common.ts'; import { EdgeAlreadyExistsError } from './common.ts'; import * as WebmeshSchema from './mesh-schema.ts'; type EdgeChannel = WebChannel.WebChannel; export interface MeshNode { nodeName: TName; edgeKeys: Effect.Effect>; debug: { print: () => void; /** Sends a ping message to all connected nodes and channels */ ping: (payload?: string) => void; /** * Requests the topology of the network from all connected nodes */ requestTopology: (timeoutMs?: number) => Promise; }; /** * Manually adds a edge to get connected to the network of nodes with an existing WebChannel. * * Assumptions about the WebChannel edge: * - 1:1 edge * - Queues messages internally to never drop messages * - Automatically reconnects * - Ideally supports transferables */ addEdge: { (options: { target: MeshNodeName; edgeChannel: EdgeChannel; replaceIfExists: true; }): Effect.Effect; (options: { target: MeshNodeName; edgeChannel: EdgeChannel; replaceIfExists?: boolean; }): Effect.Effect; }; removeEdge: (targetNodeName: MeshNodeName) => Effect.Effect; hasChannel: ({ target, channelName, }: { target: MeshNodeName; channelName: string; }) => Effect.Effect; /** * Tries to broker a DirectChannel edge between the nodes, otherwise will proxy messages via hop-nodes * * For a channel to successfully open, both sides need to have a edge and call `makeChannel`. * * Example: * ```ts * // Code on node A * const channel = nodeA.makeChannel({ target: 'B', channelName: 'my-channel', schema: ... }) * * // Code on node B * const channel = nodeB.makeChannel({ target: 'A', channelName: 'my-channel', schema: ... }) * ``` */ makeChannel: (args: { target: MeshNodeName; /** * A name for the channel (same from both sides). * Needs to be unique in the context of the 2 connected nodes. */ channelName: string; schema: Schema.Schema | { listen: Schema.Schema; send: Schema.Schema; }; /** * If possible, prefer using a DirectChannel with transferables (i.e. transferring memory instead of copying it). */ mode: 'direct' | 'proxy'; /** * Amount of time before we consider a channel creation failed and retry when a new edge is available * * @default 1 second */ timeout?: Duration.DurationInput; /** * If true, will close an existing channel if it exists. * * @default false */ closeExisting?: boolean; /** * Optional simulation parameters for testing timing-sensitive behavior. * Only used when mode is 'proxy'. */ simulation?: ProxyChannelSimulationParams; }) => Effect.Effect, never, Scope.Scope>; listenForChannel: Stream.Stream; /** * Creates a WebChannel that is broadcasted to all connected nodes. * Messages won't be buffered for nodes that join the network after the broadcast channel has been created. */ makeBroadcastChannel: (args: { channelName: string; schema: Schema.Schema; }) => Effect.Effect, never, Scope.Scope>; } export declare const makeMeshNode: (nodeName: TName) => Effect.Effect, never, Scope.Scope>; export {}; //# sourceMappingURL=node.d.ts.map