Primitives / foldkit-primitives/net

websocket

function · packages/primitives/src/net/websocket.ts:141

function websocket<const Name extends string>(config: {
  readonly name: Name
  readonly createSocket?: ((url: string) => SocketHandle) | undefined
}): Bundle.Bundle<
  Name,
  { readonly url: string; readonly connectTimeoutMs?: number | undefined },
  {
    readonly url: string
    readonly status: 'open' | 'closed' | 'connecting'
    readonly lastError: string | null
    readonly opened: boolean
  },
  | { readonly _tag: 'Opened' }
  | { readonly _tag: 'Closed' }
  | { readonly _tag: 'Connecting' }
  | { readonly _tag: 'Failed'; readonly message: string }
  | { readonly _tag: 'Received'; readonly data: string }
  | { readonly _tag: 'SendFailed'; readonly message: string }
  | { readonly _tag: 'Sent'; readonly data: string }
  | { readonly _tag: 'TimedOut' },
  never,
  ManagedResource.ManagedResourceService<'websocket'>,
  ManagedResource.ManagedResourceService<'websocket'>,
  void,
  Readonly<{
    socket: ManagedResource.Entry<
      WebSocketModel,
      WebSocketMessage,
      Option.Option<string>,
      Acquired,
      SocketService,
      () => WebSocketMessage
    >
  }>,
  Readonly<{
    send: (
      model: WebSocketModel,
      data: string,
    ) => Update.ReturnWithOutMessage<
      WebSocketModel,
      WebSocketMessage,
      never,
      SocketService
    >
  }>
>

A WebSocket as a bundle: connection lifecycle in the Model, full duplex through one Managed Resource. The resource owns the socket; a send helper writes through its tag service (lifted to the parent like every helper); a subscription stream reads incoming messages through the same tag. No hidden hub: everything the bundle touches is the Model, the resource registry, or a Message.