@assistant-ui/tap#
0.9.14#
Patch Changes#
- #6171
f2b3ef8- fix: flush state updates dispatched from subscriber notifications during flushTapSync (@Kinfe123)
0.9.13#
Patch Changes#
-
#5884
99c5302- fix: deduplicate changelog records during StrictMode replay (@rupic-app) -
#5833
5c092ef- feat: reconcile effects at commit time so mount, update, and Activity reveal share one mechanism (@Yonom) -
#5885
2f3c638- fix: rewind reducer cells through committed history so React replays from any mid-chain base reduce from the oracle state (@okisdev) -
#5857
8e77515- refactor: add a shared scheduleTask for one-off deferred work instead of allocating single-purpose UpdateScheduler instances (@Yonom) -
#5856
d9c355d- test: wait deterministically for scheduler flushes instead of racing setTimeout against MessageChannel (@Yonom) -
#5897
74dca03- feat: useTapRoot falls through React for Suspense/ErrorBoundary support (@Yonom)
feat: useSyncExternalStore now forces a rerender if the getSnapshot throws an error -
#5850
a14b347- feat: hold the committed value when a scheduler-driven update suspends in useTapRoot; createTapRoot now reports initial-render suspension with a clear error (@Yonom) -
#5873
e999f5d- fix: keep the compiler memo cache across uncommitted render replays so a StrictMode double invoke observes one memoized instance (@okisdev) -
#5881
44d98d7- fix: roll back compiler memo caches with resource versions (@rupic-app) -
#5858
4320fc6- docs: repitch the README around the hook-dispatch engine and its two use cases (@Yonom) -
#5867
d4b8845- fix: preserve reducer state when React replays a chain from a record's committed dispatch floor (@rupic-app) -
#5897
74dca03- feat: useReducer overloads for action-less reducers (@Yonom) -
#5847
a279301- fix: discard the work-in-progress render when a resource render throws (@Yonom) -
#5886
d7322c0- fix: restore application snapshots when a rewound replay is discarded, stop dispatch-before-mount from stranding replay history retention, and throw in development and test environments when a below-committed replay finds no committed history to rewind (@okisdev) -
#5876
8b0a836- test: wait deterministically for the scheduleTask flush instead of racing setTimeout against MessageChannel (@okisdev) -
#5943
20efa42- fix: export the full react surface the package dists import from both shims explicitly (@okisdev) -
#5940
833fbe8- feat: the standalone shim gainsjsx-runtimeandjsx-dev-runtimeentries plus module-scopeforwardRefandmemo, so react-coupled module graphs stay loadable under the react-less alias; rendering their JSX without real React still throws. (@okisdev) -
#5848
94a39ad- feat: use(promise) suspends resource renders (@Yonom) -
#5897
74dca03- fix: useSyncExternalStore re-checks the snapshot after commits where the value or getSnapshot changed (@Yonom) -
#5897
74dca03- fix: useSyncExternalStore reads getServerSnapshot for every pre-mount render pass (@Yonom)
0.9.12#
Patch Changes#
0.9.11#
Patch Changes#
0.9.10#
Patch Changes#
- #5655
71cf74e- feat: add a react-free standalone shim entry and make the react peer optional (@okisdev)
0.9.9#
Patch Changes#
- #5399
b8daa96- re-add the deprecated useMemoCache export for older @assistant-ui/store versions (@Yonom)
0.9.8#
Patch Changes#
-
#5368
60d049e- refactor(store): local useShallowStable helper replaces tap useMemoCache; drop useMemoCache from tap's public entrypoint (@Yonom) -
#5375
feef8fd- The update-depth error now throws from the markDirty that schedules the run past the limit, so the stack points at the offending setState. (@Yonom) -
#5370
c02680a- fix: count update depth per scheduler in UpdateScheduler and drop only the offending scheduler from a flush, so one looping root no longer starves or wedges unrelated roots (@Yonom) -
#5357
e6045bb- createTapRoot: reuse a single per-root UpdateScheduler across dispatches and assert without applying first (@Yonom) -
#5358
04c070e- Deduplicate the rethrow-or-AggregateError error handling into a shared internal helper (@Yonom) -
#5331
d7afb3d- fix: accept reducer replays below the committed version instead of throwing (@okisdev)
0.9.7#
Patch Changes#
- #5285
d72c2b6- fix: useSyncExternalStore retains the last committed value when the snapshot getter throws; exportuseMemoCachefrom the package root (@Yonom)
0.9.6#
Patch Changes#
-
#5208
a0ddc86- AdopterasableSyntaxOnly; public enums are nowas constobjects. (@Yonom) -
#5235
8c97501- feat: dropconfigurableResource()— useresource()with an options argument instead (@Yonom) -
#5207
7e871ef- Stop shipping react-shim declaration files the exports map disclaims — the shim subpaths are now genuinely untyped in every resolution mode instead of accidentally typed via TypeScript's fallback resolution. (@Yonom)
0.9.5#
Patch Changes#
-
#5194
ecd2280- feat:configurableResource()— curries an options-first hook into(options) => Resource<V, A>, replacing.bind(null, options)boilerplate (@Yonom) -
#5182
83d7b42- fix: implement useMemoCache on tap's dispatcher so compiled components work under duplicated tap copies (@Yonom) -
#5181
5c54141- fix: create the scheduler MessageChannel lazily so importing tap does not hold the Node event loop open (@Yonom) -
#5190
5412099- refactor:ResourceElement<Result>drops its args type parameter — elements are opaque descriptors;Resource<Result, Args>keeps the callable typing andContravariantResourceis removed (@Yonom) -
#5186
99da4af- feat:withKeyaccepts a Resource —withKey(key, resourceFn)returns a resource whose produced elements carry the key (@Yonom)
0.9.4#
Patch Changes#
-
#4920
e02b21b- fix: preserve React-hosted tap resource roots and keyed fiber registries for the component lifetime (@samdickson22) -
#4919
7e28a72- fix: keep tap root scheduler, fiber, queue, and subscribers in React state for the full component lifetime (@samdickson22)
0.9.3#
Patch Changes#
0.9.2#
Patch Changes#
0.9.1#
Patch Changes#
-
#4392
4cc7eaa- fix: preserve tap context across nested tap root rerenders and mark tap context as supported (@Yonom)
0.8.1#
Patch Changes#
-
#4385
ae59baf- feat: precompile packages with React Compiler (@Yonom)- aui-build runs React Compiler over packages that depend on tap and remaps
react/compiler-runtimeto the tap shim subpath, so compiled hooks and components work both in React components and inside tap resource renders @assistant-ui/tap/react-shimexportsuseMemoCache(tap inside a resource render,React.__COMPILER_RUNTIME.cotherwise, with a React 18 polyfill); new@assistant-ui/tap/react-shim/compiler-runtimesubpath mirrorsreact/compiler-runtime'scexport- tap implements
useSyncExternalStoreand a no-opuseDebugValue;useSubscribablenow builds onuseSyncExternalStoreso its store reads stay visible to the compiler AssistantProviderBaseopts out via"use no memo"because the runtime receives options through an effect inside a re-rendered child element
- aui-build runs React Compiler over packages that depend on tap and remaps
-
#4389
9f13fdb- perf: optimize tap memo hook hot paths (@Yonom)
0.8.0#
Minor Changes#
- feat: drop the experimental deps array from
useResource/useResourcesand makeuseResourcestake an array of elements directly instead of agetElementscallback. The React Compiler memoizes element inputs, so the manual dependency arrays were redundant; re-renders are now controlled by element identity. (@Yonom)
0.7.1#
Patch Changes#
-
#4360
12b016b- fix: match React semantics: support render-phase updates (setState during render re-renders before committing, capped at 25 passes, instead of throwing; discarded render attempts drop their render-phase dispatches like React; updating a resource other than the one currently rendering throws), apply dispatches exactly once across React-discarded and replayed renders of tap sub-roots, run all effect cleanups before any setups within a commit, and compare only the common prefix of deps arrays that change length (with a dev warning) (@Yonom) -
#4366
3e58253- feat: add useTapHost, a React host that commits the resource in the passive phase without blocking paint; the returned per-render effects callback lets descendant consumers mount the commit ahead of their own effects via useEffect(effects). The React bridge hosts (useResource, useResources, useTapRoot) now also commit in useEffect instead of useLayoutEffect. (@Yonom)
0.6.2#
Patch Changes#
-
#4318
1b6a0d6- fix: React parity for useReducer and StrictMode. User reducers now compute during render instead of eagerly at dispatch (matching React, which reserves eager computation for useState), so dev-mode reducer invocation counts and kept results match React; a same-state dispatch now renders once like React instead of bailing out at dispatch. The React bridge keeps one host fiber across both StrictMode render passes (hosted identities match across passes like React's own hook state) and lets React's strict replay drive the effect cycle (mount, unmount, mount). (@Yonom) -
#4318
1b6a0d6- feat(tap): resources carry all hook arguments; elements are{ hook, args }(@Yonom)A
ResourceElementis now{ hook, args }(was{ type, props }): the underlying hook plus the full tuple of arguments to call it with. This lets a resource take multiple positional arguments, exactly like a hook, and makes hosting justhook(...args):const usePair = (a: number, b: string) => ({ a, b }); const Pair = resource(usePair); const element = Pair(1, "hi"); // { hook: usePair, args: [1, "hi"] }The single-object case is unchanged ergonomically (
Counter({ initialValue: 0 })still works; itsargsis just[{ initialValue: 0 }]), so existing resources and call sites are unaffected.resource()'s overloads collapse into one variadic signature, and thefnSymbol/callResourceFnindirection is gone (the element holds the hook directly;renderResourceFibercallsfiber.hook(...args)).Breaking (internal/advanced):
- The second type parameter of
Resource/ResourceElement/ContravariantResourcenow means the argument tupleA extends readonly unknown[]rather than a single payloadP. Explicit two-arg annotations must wrap the payload in a tuple (e.g.ResourceElement<R, [Props]>). - A resource's identity is now its hook. Reading
element.propsbecomeselement.args[0]; readingelement.typebecomeselement.hook.attachTransformScopesis now keyed by (and called with) the hook rather than the factory. useResource(element, deps)'s second arg is unchanged in behavior (renamedargsDeps).
- The second type parameter of
-
#4318
1b6a0d6- refactor: adopt the extracted-hook convention for resources (@Yonom)A resource body is a hook, so resources are now authored as a
use-prefixed hook
wrapped withresource():const useCounter = () => { ... }; const Counter = resource(useCounter);resource()turns a hook into a Resource;useResource(Counter(props))turns it
back into a hook call. Extracting the body to ause-prefixed hook lets React's
stock rules-of-hooks and exhaustive-deps lint resource bodies directly. No
public API or runtime behavior changes. -
#4318
1b6a0d6- refactor: rename the root APIs touseTapRoot/createTapRootand make them callback-based (@Yonom)useResourceRoot(element)is nowuseTapRoot(fn)andcreateResourceRoot().render(element)is nowcreateTapRoot(fn). Both take a render callback instead of a pre-built resource element, so you no longer have to wrap a hook inresource()just to host it as a root. The callback must be a named function expression (so React's rules-of-hooks lints the body):// before const root = createResourceRoot(); const handle = root.render(Counter()); handle.getValue(); // after const root = createTapRoot(function CounterRoot() { return useResource(Counter()); }); root.getValue();createTapRootreturns{ getValue, subscribe, unmount }directly (no separate.renderstep).flushResourcesSyncis also renamed toflushTapSync, to match thetapnaming of the root APIs (and to stay distinct from react-dom'sflushSync).
0.6.1#
Patch Changes#
0.6.0#
Minor Changes#
-
#4282
01cf957- feat: React integration (@Yonom)@assistant-ui/tapnow requiresreactas a peer dependency and ships a React integration:- Resource API at the package root:
useResource(host a resource element),useResources(keyed lists), anduseResourceRoot(a subscribable{ getValue, subscribe }boundary). Each is isomorphic: it works inside a resource render and inside a React component. - Author resource state and effects with plain React hooks. A React dispatcher installed around every resource render makes
import { useState } from "react"(anduseReducer/useRef/useMemo/useCallback/useEffect/useEffectEvent/use) route to tap inside a resource, with no build step. It also backsreact/compiler-runtime'suseMemoCache, so React Compiler output runs in a resource without a"use no memo"opt-out. Hooks tap has no equivalent for throw when called inside a resource. @assistant-ui/tap/react-shim: a runtime drop-in for"react"that assistant-ui's own packages are built against (theirreactimports are pre-routed to it), so they route to tap inside a resource render and to React otherwise without depending on the consumer's bundler. It ships no type declarations; keep importing from"react"so React's own types apply.- Also exports
resource,withKey,createResourceRoot,flushResourcesSync, thecreateResourceContext/withContextProvidercontext API, and theResource/ContravariantResource/ResourceElementtypes.
- Resource API at the package root:
Patch Changes#
0.5.14#
Patch Changes#
- #4151
299d448- chore: drop stalebiome-ignorepragmas now that the repo lints with oxlint (@okisdev)
0.5.13#
Patch Changes#
0.5.12#
Patch Changes#
-
#4097
1e21076- build(x-buildutils): migrateaui-buildfromts.createProgramtotsdownwithunbundle: true(@Yonom)Tsdown drives both JS and
.d.tsemission. Reference-directive restoration is preserved (tsdown/oxc drop/// <reference>lines, so we re-inject them in abuild:donehook).deps.skipNodeModulesBundle: truekeeps the old "never bundle anything fromnode_modules" behavior — devDependencies stay external instead of getting inlined intodist.Side fixes the new strict dts pipeline surfaced:
@assistant-ui/tap: dropped thefnSymbolbrand from the publicResourceElementtype. It referenced an@internalsymbol thatstripInternalremoved from emit, leaving the published.d.tswith a dangling reference.@assistant-ui/store: un-markedClientSchemaas@internal. It was already re-exported from the public package index; treating the re-export as authoritative.
0.5.11#
Patch Changes#
0.5.10#
Patch Changes#
0.5.9#
Patch Changes#
-
#3832
055dda5- fix: tapEffectEvent returned a frozen callback in production, breaking consumers that stored the reference externally (e.g. trigger popover plugin registry). Both dev and prod now use the same wrapper that reads the latest callback from the ref at call time — matching the documented "stable reference that always calls the most recent version" contract. (@okisdev) -
#3831
d53ff4f- chore: remove decorative separator comments across packages (@okisdev)
0.5.8#
Patch Changes#
- c988db8: chore: update dependencies
0.5.7#
Patch Changes#
- 376bb00: chore: update dependencies
0.5.6#
Patch Changes#
- bdce66f: chore: update dependencies
- 209ae81: chore: remove aui-source export condition from package.json exports
0.5.5#
Patch Changes#
- 52403c3: chore: update dependencies
0.5.4#
Patch Changes#
- 736344c: chore: update dependencies
- c71cb58: chore: update dependencies
0.5.3#
Patch Changes#
- 349f3c7: chore: update deps
0.5.2#
Patch Changes#
- a845911: chore: update dependencies
0.5.1#
Patch Changes#
- 36ef3a2: chore: update dependencies
0.5.0#
Minor Changes#
- b65428e: feat: tap scheduler now uses macro tasks
- b65428e: feat: createResourceRoot and tapResourceRoot APIs
Patch Changes#
- b65428e: feat: tapReducer API
- 6bd6419: fix(tap): prevent rollback crash when tapResourceRoot version falls below committedVersion
- b65428e: feat: Offscreen API support
- b65428e: feat: tapReducerWithDerivedState API
- b65428e: feat: tapMemo concurrent safe mode
0.4.6#
Patch Changes#
- afaaf3b: fix: use bracket notation for process.env
0.4.5#
Patch Changes#
- a088518: chore: update dependencies
0.4.4#
Patch Changes#
- 77af8c3: fix: runtime not responsive if loaded under React StrictMode (critial bug)
0.4.3#
Patch Changes#
- d45b893: chore: update dependencies
- fe71bfc: feat: tapSubscribableResource hook
0.4.2#
Patch Changes#
- 5ab3690: fix: allow optional props in resources
0.4.1#
Patch Changes#
- 8cbf686: fix: tap should run effects after remount
- a8be364: feat: log individual errors when throwing AggregateError
- 605d825: chore: update dependencies
- fe15232: fix: tap strict mode should double invoke tapMemo calls
0.4.0#
Minor Changes#
- feat: add StrictMode support
- feat: add tapConst
- feat: rewrite tapResources for better performance
- feat: withKey API
- feat: flushResourcesSync API
- fix: correctly unmount effects
0.3.6#
Patch Changes#
- 3719567: chore: update deps
0.3.5#
Patch Changes#
- 57bd207: chore: update dependencies
- cce009d: chore: use tsc for building packages
0.3.4#
Patch Changes#
- fix: crash on StrictMode
0.3.3#
Patch Changes#
- bae3aa2: feat: new scheduler
- bae3aa2: feat: global flushSync
- bae3aa2: feat: align createResource API with react-dom's createRoot
- bae3aa2: feat: new tapResources API
- bae3aa2: fix: correctly unmount resources when the element passed to useResource changes
- bae3aa2: feat: better inference of unions passed to tapResource, tapResources and useResource
- e8ea57b: chore: update deps
- bae3aa2: feat: update Resource and ResourceElement types for better type inference
0.3.2#
Patch Changes#
- 01c31fe: chore: update dependencies
0.3.1#
Patch Changes#
- ec662cd: chore: update dependencies
0.3.0#
Minor Changes#
- feat: added
ContravariantResourcetype - refactor: removed
Unsubscribetype - refactor: moved multiple types to
tapXhook namespace
0.2.2#
Patch Changes#
- 2c33091: chore: update deps
0.2.1#
Patch Changes#
- 0a4bdc1: feat: renamed
ResourceElementConstructortoResource, changedResourceElement.typeto beResourceinstead ofResourceFn
0.1.5#
Patch Changes#
- dbc4ec7: fix: tapRef should not support callback fns
- 2fc7e99: chore: update deps
0.1.4#
Patch Changes#
- 953db24: chore: update deps
0.1.3#
Patch Changes#
- chore: update deps
0.1.2#
Patch Changes#
- e6a46e4: chore: update deps
0.1.1#
Patch Changes#
- 0534bc5: feat: Context API
0.1.0#
Minor Changes#
- 5437dbe: feat: runtime rearchitecture (unified state API)