Skip to content

Feature: Tiled Websocket Hooks - #73

Merged
SeijDeLeon merged 2 commits into
stagingfrom
feat/tiled-websocket
Oct 14, 2026
Merged

SeijDeLeon merged 2 commits into
stagingfrom
feat/tiled-websocket

Conversation

@SeijDeLeon

Copy link
Copy Markdown
Collaborator

Tiled WebSocket streaming

Adds live streaming from Tiled's /api/v1/stream/single/{path} websocket. It sits alongside the existing HTTP/TanStack Query client and doesn't change it.

Core client (src/api/tiled/client/websocket/)

  • TiledWebSocketClient and TiledSubscription: framework-independent, one socket per node
  • Typed messages for every stream type (container, table, array, array-ref, ragged); narrow on type, no casts
  • buildTiledWebSocketUrl: builds ws:// / wss:// URLs from the existing tiledApiUrl; no new config option
  • Sends credentials as a first message ({"type":"auth", ...}), never in the URL
  • Reconnects with exponential backoff and jitter; does not retry on auth failures (4001/4003) or when the server ends the stream (1000)
  • Tracks sequence numbers: reconnects resume at lastSequence + 1 (Tiled's start is inclusive) and duplicates are dropped
  • If the server's sequence counter resets (e.g. a restart with an in-memory cache), it starts counting afresh instead of silently dropping every later event

React hooks

  • useTiledSubscription, plus useTiledContainerSubscription, useTiledTableSubscription and useTiledArraySubscription
  • Use the same URL, initial path and API key as the HTTP hooks (FinchConfigProvider / TiledApiProvider)
  • Callbacks are the default: no re-render per message, nothing accumulated unless asked (accumulate / maxRows, trackLatest)
  • Not part of the TanStack cache; refresh HTTP data from a callback with useTiledInvalidate()
  • Exported from @/api/tiled and the package entry

Test harness: Test → Tiled WebSocket (/test/tiled-websocket)

  • Subscribe to any node with any hook or the raw client, and see live status, sequences, an event log, child tables, rows and array frames
  • Buttons that make the server emit events (create a child, add metadata.stop, create an array, write a frame, append a row), plus a Python snippet for table appends

Tests and docs

  • Unit tests for the URL builder, parser (fixtures captured from a live server), subscription lifecycle, backoff, sequence handling, hooks and the harness
  • Opt-in live test against a real server: TILED_LIVE_URL=... npx vitest run TiledWebSocket.live
  • Streaming section in the Tiled README, plus updates to SKILLS.md and TiledHooks.md

Server and behaviour notes

  • Tiled needs a streaming_cache in its config, or every stream connection fails with a 500
  • A parent container only reports its direct children; subscribe to a table or array node directly to get its data
  • Array writes always send the full payload, so there is no includePayload option; array-ref only comes from put_data_source
  • Not included yet: MsgPack, Arrow schema decoding, array-ref auto-fetch, a Bluesky run hook

Testing

  • npm run lint, npm run test:run and npm run build pass
  • Checked in the browser against a local Tiled 0.2.15b1: live container and array events, and replay of events written while disconnected

# Conflicts:
#	src/api/tiled/README.md
#	src/api/tiled/SKILLS.md
#	src/index.ts
@github-actions

Copy link
Copy Markdown
Contributor

✅ Test Results

All tests passed!

Complete Test Suite Coverage:

  • ❓ Buttons - Button, ButtonIconOnly, ButtonWithIcon, ButtonCopyToClipboard
  • ❓ Inputs - InputCheckBox, InputNumber, InputEnumBoxRounded, InputStringBoxRounded
  • ❓ Plots - PlotlyHeatmap, PlotlyHeatmapTiled, PlotlyScatter, Histogram, ColormapPicker
  • ❓ Layout - Sidebar, SidebarItem, FinchSidebar, FinchAppLayout, FinchHeader, FinchMainContent, Header, Main, Bento, Paper, Widget
  • ❓ Tiled - TiledComponents, TiledLinePlotMaker
  • ❓ Devices - Camera, Shutter, DeviceControllerBox, DeviceControllerBoxSimple, TableDeviceController, ControllerAbsoluteMove, ControllerRelativeMove, Hexapod, BeamEnergy
  • ❓ Services - QueueServer, SignalMonitorPlots, Experiment
  • ❓ Misc - IFrame, GoogleDoc, SelectDropdown, ComponentViewer, ComponentViewerUtils

Test Environment: Node.js 20.x
Linting: ❓ ESLint status unknown
Formatting: ❓ Formatting status unknown
Type Checking: ❓ Build status unknown
Build: ❓ Production build successful
Tests: ❓ Test status unknown

@SeijDeLeon
SeijDeLeon marked this pull request as ready for review October 13, 2026 21:09
@github-actions

Copy link
Copy Markdown
Contributor

✅ Test Results

All tests passed!

Complete Test Suite Coverage:

  • ❓ Buttons - Button, ButtonIconOnly, ButtonWithIcon, ButtonCopyToClipboard
  • ❓ Inputs - InputCheckBox, InputNumber, InputEnumBoxRounded, InputStringBoxRounded
  • ❓ Plots - PlotlyHeatmap, PlotlyHeatmapTiled, PlotlyScatter, Histogram, ColormapPicker
  • ❓ Layout - Sidebar, SidebarItem, FinchSidebar, FinchAppLayout, FinchHeader, FinchMainContent, Header, Main, Bento, Paper, Widget
  • ❓ Tiled - TiledComponents, TiledLinePlotMaker
  • ❓ Devices - Camera, Shutter, DeviceControllerBox, DeviceControllerBoxSimple, TableDeviceController, ControllerAbsoluteMove, ControllerRelativeMove, Hexapod, BeamEnergy
  • ❓ Services - QueueServer, SignalMonitorPlots, Experiment
  • ❓ Misc - IFrame, GoogleDoc, SelectDropdown, ComponentViewer, ComponentViewerUtils

Test Environment: Node.js 20.x
Linting: ❓ ESLint status unknown
Formatting: ❓ Formatting status unknown
Type Checking: ❓ Build status unknown
Build: ❓ Production build successful
Tests: ❓ Test status unknown

@alisonscheng alisonscheng left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

@SeijDeLeon
SeijDeLeon merged commit 3f130db into staging Oct 14, 2026
2 checks passed
@SeijDeLeon
SeijDeLeon deleted the feat/tiled-websocket branch October 14, 2026 18:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants