Repository navigation
feat(sockets): listener delivery strategies for throttling and batching - #147
Merged
Merged
Conversation
…hing Add a `delivery` option to listeners so high-frequency streams can be sampled (`latest`), batched (`batch`) or shaped by a custom strategy before reaching `listen` callbacks. Wrapping happens in `Listener.listen`, so every adapter, `useListener` and the SDK pick it up without changes. No `delivery` means the callback is registered as-is with zero overhead. - New `delivery/` module: types, `latest`/`batch` presets, `createDeliveryStrategy`, `createDeliveryController`, `getDeliveryKey` - Fifth `Delivered` generic on `Listener` (defaults to `Response`), inferred from the `delivery` option; `batch` delivers `Response[]` - `setDelivery()` clone method; `delivery` carried through setParams/setOptions/clone - `ExtractListenerDeliveredType`; `delivered` slot on ListenerInstance, ListenerModel and ExtendListener - SDK: `delivery` in `SocketSdkDefaults`, `InjectSocket` preserves the delivered type - Fix: `listener.params` was declared but never assigned Closes discussion #141. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Type `data` and `onEvent` by the listener's delivered type (arrays for `batch`), and re-subscribe on `topic`, `options` and the delivery key instead of the never-assigned `listener.params`. Presets compare by value, custom strategies by identity. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- useSubmit queue: the mock resolved (default 20ms delay) before the second hook mounted, so "loading" was already gone; give the request an explicit delay - useFetch revalidate: replace a fixed 50ms sleep with waitFor on the callback Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- New guides: sockets "Throttling & Batching" and React counterpart - Listener reference: Delivery Strategies feature section, Delivered Type - useListener reference: Throttling & Batching section - SDK reference: `delivery` default and `delivered` model field - Fix stale `endpoint` keys in socket docs (listeners and emitters use `topic`) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
🎉 This PR is included in version 9.1.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Resolves discussion #141: per-listener throttling for high-frequency WebSocket streams, configured on
createListenersolisten(),useListenerand the SDK keep working unchanged.Design
Listener.listen, the one point every adapter (WS, SSE, Firebase) passes through. Zero overhead whendeliveryis omitted. Thesocket.eventsraw broadcast stays unthrottled for devtools.latest= leading + trailing sampling;batch= window from first message,maxSizeearly flush;extra= last message's extra; unsubscribe disposes timers and drops pending (nothing fires afterunlisten()); everylisten()call owns its own controller.Deliveredgeneric onListener(defaults toResponse), inferred fromdelivery.ExtractListenerResponseTypekeeps meaning the wire type; newExtractListenerDeliveredType. Covariance ofResponseis preserved (type-tested), soListenerInstance<{ response: ... }>constraints keep working.useListenerdata/onEventtyped by the delivered type; deps keyed ontopic+ options + delivery key (replaces the never-assignedlistener.params).deliveryin defaults,deliveredfield onListenerModel,InjectSocketpreserves it.Also in this PR
listener.paramswas declared but never assigned.fix-flaky-testswith a repeat-run script.endpoint→topicfixes.Tests
useListenerdelivery tests incl. StrictMode, unmount, re-subscribe, render counts)🤖 Generated with Claude Code