- Add message queue to subscription controller to prevent data loss during rapid events
- Add
refetchmethod to infinite controller for soft invalidation
- Add
generateUUIDutility with fallback for non-secure contexts (HTTP)
- Add
matchTagandmatchTagsutilities for wildcard pattern matching
- Fix queue concurrent request decrement not working properly
- Breaking: Rename plugin
exportstointernalandinstanceApitoapi - Fix cache
selfTaggeneration not using dynamic params in path
- Add
subscriptioncontroller for managing real-time transports.
- Add
createSpooshPluginhelper for automatic plugin options type inference
- Breaking: Rename
infiniteReadoperation type topages - Add reactive state change event to infinite read controller
- Remove infinite tracker and use state derivation directly
- Add
onDataChangeevent to state manager to allow plugins to react to data changes in controllers.
- Add
queuecontroller support for queuing multiple requests to the same endpoint.
- Fix global
Content-Typeheader overrideform,urlencoded, andjsonbody helpers.
- Fix fetch transport return empty object when response is not JSON
- Pending promise now wraps the entire middleware chain to ensure proper handling of async operations in middlewares
- Add trigger options to plugin architecture to allow passing custom trigger values
- Add devtool tracing support for plugins
- Add
priorityoption in plugin interface to control execution order of plugins. - Remove retries logic from core.
- Renamed
PluginContext.hookIdtoPluginContext.instanceIdfor framework-agnostic terminology.
- Rename
metadatatotempin internal plugin communication.
- Removed legacy middleware system:
createMiddleware,applyMiddlewares, andcomposeMiddlewaresfunctions have been removed. Use the plugin-based middleware system instead. - Removed
middlewaresoption fromcreateClientconfig. Migrate to plugin-based middleware. - Changed
createClientAPI signature fromcreateClient(config)tocreateClient(baseUrl, defaultOptions?)to match theSpooshclass style. - Changed
PluginContext.pathfromstring[]tostringfor simpler plugin API. - Renamed
PluginContext.requestOptionstoPluginContext.requestfor cleaner API. - Changed
CreateOperationOptions.pathandCreateInfiniteReadOptions.pathfromstring[]tostringfor consistency. - Changed
StateManager.createQueryKeyto acceptpath: stringinstead ofpath: string[].
- Expose
getSubscribersCountmethod in listen controllers to get current number of subscribers. - Remove unnecessary plugin options from plugin context.
- Fix invalidation not working properly when using initial data.
- Set SpooshSchema
dataas optional field to allow endpoints with no response body - Introduce
xhrtransport option for custom XMLHttpRequest handling - Update documentation URLs to new
/docs/{framework}format
- Add
refetchAllevent to reset all listen controllers
- Remove
stripTagPrefixlogics and user must useStripPrefixutility type to remove prefix from api schema paths
- Create
StripPrefixutility type to remove prefix from api schema paths - Auto merge duplicate prefix paths when fetching data
- Add
stripTagPrefixoption to prevent unintended tag generation with prefixed paths
- Insteads of relying on header or body to determine body type. Now use
form() / json() / urlencoded()helpers to explicitly set body type.
- Fix response override
setMetadata in first request
- Fixed
staleflag not being set tofalsein controller after successful fetch
- Renamed
onResponsetoafterResponsein plugin interface afterResponsenow supports return values for response transformation- Plugins can return new response objects to chain transformations, or return void for side effects only
- Fixed cache timing bug in
createOperationControllerwhere cache was updated beforeafterResponsehandlers ran - Fixed identical cache timing bug in
createInfiniteReadController - Cache now correctly stores transformed data instead of original wrapped responses
Unified Tags API
The tags API now follows the same pattern as the invalidation plugin's unified invalidate option. This simplifies the API by merging tags and additionalTags into a single tags option that supports modes ('all', 'self', 'none') and arrays.
- Removed
additionalTagsoption tagsnow accepts'all' | 'self' | 'none' | string[](unified pattern matching invalidation API)
- New Flat Schema API: Replaced nested schema structure with flat path-based schema
- Old:
api.posts._.$get()with_wildcard for path params - New:
api("posts/:id").GET()with path string keys
- Old:
- HTTP methods changed from
$get,$posttoGET,POSTformat
Before (nested schema):
type ApiSchema = {
posts: {
$get: { data: Post[] };
_: {
$get: { data: Post };
};
};
};
const { data } = await api.posts._.$get({ params: { id: 1 } });After (flat schema):
type ApiSchema = {
posts: { GET: { data: Post[] } };
"posts/:id": { GET: { data: Post } };
};
const { data } = await api("posts/:id").GET({ params: { id: 1 } });- Cleaner path syntax with explicit path parameters in key
- Better TypeScript autocomplete for path strings
- Prevent type deep recursion issues in large schemas
- Rename
pluginResulttometato have consistent naming.
- Strict request options types to allow optional value as well.
- Fix homepage URL to point to correct documentation path
- Added internal _pathTransformer to allow params paths modification
- Fixed createSelectorProxy to convert numeric segments to strings
- Remove bracket syntax for dynamic paths
-
- Strict typescript allowing
_syntax for dynamic path segments
- Strict typescript allowing
- Auto convert body to FormData when body contains File or Blob objects
- Catch errors in onResponse from plugins
- Removed
createSpoosh()function in favor ofSpooshclass
Before:
import { createSpoosh } from "@spoosh/core";
const plugins = [cachePlugin()] as const;
const client = createSpoosh<Schema, Error, typeof plugins>({
baseUrl: "/api",
plugins,
});After:
import { Spoosh } from "@spoosh/core";
const spoosh = new Spoosh<Schema, Error>("/api").use([cachePlugin()]);- No more
as constassertion needed for plugins - No more
typeof pluginsgeneric parameter - Cleaner, more intuitive class-based API
- Full type inference preserved
- Initial beta release
- Type-safe API client with proxy-based endpoint access
- Plugin middleware system with lifecycle hooks
- State management for request/response tracking
- Event emitter for request lifecycle events
- Support for all HTTP methods (
$get,$post,$put,$patch,$delete) - Dynamic path segments with bracket notation
- Request body serialization (JSON, FormData, URLEncoded)
- Query string handling
- Header management and merging