From f84f93d429dc7beff85097c50c6ae335ebf7cffc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 1 Sep 2026 05:21:59 +0000 Subject: [PATCH] chore: release packages --- .changeset/array-mutator-frozen-invariant.md | 5 --- .changeset/batch-error-hardening.md | 5 --- .changeset/batch-flush-error-priority.md | 5 --- .changeset/bind-defer-fallback.md | 5 --- .changeset/bind-services-destroy.md | 7 ---- .changeset/cleanup-all-memos-notify.md | 5 --- .changeset/cleanup-all-prototype-chain.md | 5 --- .changeset/debounce-throttle-detached.md | 5 --- .changeset/debounce-throttle-per-instance.md | 5 --- .changeset/domain-context-ref-sync.md | 5 --- .changeset/domain-readme-dead-api.md | 5 --- .changeset/inject-per-instance-cache.md | 5 --- .changeset/map-value-iteration-notify.md | 5 --- .changeset/memo-batch-stale-read.md | 5 --- .changeset/memo-throw-observer-recover.md | 5 --- .changeset/model-loading-last-write.md | 5 --- .changeset/notify-key-unwrap.md | 5 --- .changeset/observe-reuse-unobserved.md | 5 --- .changeset/reaction-error-deps.md | 5 --- .../use-as-observable-source-frozen-props.md | 5 --- .changeset/use-reaction-lazy-effect.md | 5 --- .changeset/use-reaction-untracked-effect.md | 5 --- .changeset/view-class-commit-tracking.md | 5 --- examples/reactive-state/CHANGELOG.md | 14 ++++++++ examples/reactive-state/package.json | 2 +- packages/devtools/CHANGELOG.md | 15 ++++++++ packages/devtools/package.json | 2 +- packages/observer/CHANGELOG.md | 15 ++++++++ packages/observer/package.json | 2 +- packages/react/CHANGELOG.md | 36 +++++++++++++++++++ packages/react/package.json | 2 +- packages/rn-debug-server/CHANGELOG.md | 2 ++ packages/rn-debug-server/package.json | 2 +- packages/rn-debug/CHANGELOG.md | 15 ++++++++ packages/rn-debug/package.json | 2 +- packages/service/CHANGELOG.md | 13 +++++++ packages/service/package.json | 2 +- packages/shared/CHANGELOG.md | 2 ++ packages/shared/package.json | 2 +- packages/web-mcp/CHANGELOG.md | 15 ++++++++ packages/web-mcp/package.json | 2 +- website/CHANGELOG.md | 33 +++++++++++++++++ website/package.json | 2 +- 43 files changed, 170 insertions(+), 127 deletions(-) delete mode 100644 .changeset/array-mutator-frozen-invariant.md delete mode 100644 .changeset/batch-error-hardening.md delete mode 100644 .changeset/batch-flush-error-priority.md delete mode 100644 .changeset/bind-defer-fallback.md delete mode 100644 .changeset/bind-services-destroy.md delete mode 100644 .changeset/cleanup-all-memos-notify.md delete mode 100644 .changeset/cleanup-all-prototype-chain.md delete mode 100644 .changeset/debounce-throttle-detached.md delete mode 100644 .changeset/debounce-throttle-per-instance.md delete mode 100644 .changeset/domain-context-ref-sync.md delete mode 100644 .changeset/domain-readme-dead-api.md delete mode 100644 .changeset/inject-per-instance-cache.md delete mode 100644 .changeset/map-value-iteration-notify.md delete mode 100644 .changeset/memo-batch-stale-read.md delete mode 100644 .changeset/memo-throw-observer-recover.md delete mode 100644 .changeset/model-loading-last-write.md delete mode 100644 .changeset/notify-key-unwrap.md delete mode 100644 .changeset/observe-reuse-unobserved.md delete mode 100644 .changeset/reaction-error-deps.md delete mode 100644 .changeset/use-as-observable-source-frozen-props.md delete mode 100644 .changeset/use-reaction-lazy-effect.md delete mode 100644 .changeset/use-reaction-untracked-effect.md delete mode 100644 .changeset/view-class-commit-tracking.md diff --git a/.changeset/array-mutator-frozen-invariant.md b/.changeset/array-mutator-frozen-invariant.md deleted file mode 100644 index b079b25..0000000 --- a/.changeset/array-mutator-frozen-invariant.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rabjs/observer': patch ---- - -Fix a `TypeError: 'get' on proxy` when reading a frozen (non-configurable + non-writable) own array mutator property on an observable array. The batch-wrapping introduced for array mutators (#93) ran before the Proxy get invariant check and returned a different function object; the invariant check now runs first in both base and shadow get traps (#251). diff --git a/.changeset/batch-error-hardening.md b/.changeset/batch-error-hardening.md deleted file mode 100644 index 7498c21..0000000 --- a/.changeset/batch-error-hardening.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rabjs/observer': patch ---- - -`batch()` flush-error handling hardening: attaching the flush error as `cause` is skipped when the callback and a reaction threw the identical `Error` instance (a self-referential `cause` loops naive cause-chain walkers), and the `console.warn` fallback for unattached flush errors is itself isolated so throwing console shims cannot replace the in-flight exception. Also, reviving an unobserved reaction via `observe(r)` no longer overwrites its custom `scheduler`/`debugger` with global defaults. diff --git a/.changeset/batch-flush-error-priority.md b/.changeset/batch-flush-error-priority.md deleted file mode 100644 index 2a0faf0..0000000 --- a/.changeset/batch-flush-error-priority.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rabjs/observer': patch ---- - -`batch(fn)` no longer lets a flush-time reaction error replace the callback's own in-flight exception. Previously `try { batch(mutate) } catch` caught the reaction's error while the callback's original error was silently dropped; the flush error is now attached as `cause` on the original error when possible (#212). diff --git a/.changeset/bind-defer-fallback.md b/.changeset/bind-defer-fallback.md deleted file mode 100644 index 57c4aa6..0000000 --- a/.changeset/bind-defer-fallback.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rabjs/react': patch ---- - -`bindServices` container teardown scheduling now falls back `queueMicrotask` → `Promise` → `setTimeout`, so cleanup still happens in legacy JS engines without `queueMicrotask` (old React Native JSC/Hermes). Also extracts an internal `createContainer` factory used by both creation and the hidden-tree rebuild path. diff --git a/.changeset/bind-services-destroy.md b/.changeset/bind-services-destroy.md deleted file mode 100644 index 94e2fbf..0000000 --- a/.changeset/bind-services-destroy.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@rabjs/react': patch ---- - -`bindServices` now destroys its container on unmount instead of waiting for the FinalizationRegistry/GC fallback. Service cleanup (event listeners, debounce/throttle timers) previously stayed pending for an unbounded window. Destroy is scheduled on a microtask so React StrictMode's fake unmount/remount does not tear down a live container; the GC fallback is kept for concurrent renders that never commit (#218). - -**Behavior change**: the container is private to the bound subtree by design. Service instances held outside the subtree (stored in refs, injected into parent/global containers, kept in external caches) become destroyed objects after unmount — do not let subtree services escape; if an instance's lifetime must outlive the component, register it in a parent container instead (#252). diff --git a/.changeset/cleanup-all-memos-notify.md b/.changeset/cleanup-all-memos-notify.md deleted file mode 100644 index 1ee5298..0000000 --- a/.changeset/cleanup-all-memos-notify.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rabjs/service': patch ---- - -`cleanupAllMemos` now notifies outer observers per cleaned memo key (batched into a single flush), matching `invalidateMemo` semantics — mounted `observe`/`observer` consumers no longer stay stale after a cache reset. `Service.destroy` passes `{ notify: false }` to keep its deliberate silence (#255). diff --git a/.changeset/cleanup-all-prototype-chain.md b/.changeset/cleanup-all-prototype-chain.md deleted file mode 100644 index 4edfcfb..0000000 --- a/.changeset/cleanup-all-prototype-chain.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rabjs/service': patch ---- - -`cleanupAllMemos` / `cleanupAllDebounces` / `cleanupAllThrottles` now walk the full prototype chain instead of only the direct prototype. Decorated members defined on a base class are cleaned up when a subclass instance is destroyed; previously their memo reactions kept running and debounce/throttle timers kept firing on destroyed instances (#221). diff --git a/.changeset/debounce-throttle-detached.md b/.changeset/debounce-throttle-detached.md deleted file mode 100644 index a04a8a5..0000000 --- a/.changeset/debounce-throttle-detached.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rabjs/service': patch ---- - -`@Debounce`/`@Throttle` no longer throw `TypeError: Invalid value used as weak map key` on detached calls (`this` null/undefined, e.g. `arr.map(service.save)` or destructured methods). Detached calls share one module-level sentinel state, matching the pre-WeakMap closure behavior (#250). diff --git a/.changeset/debounce-throttle-per-instance.md b/.changeset/debounce-throttle-per-instance.md deleted file mode 100644 index 8985a4b..0000000 --- a/.changeset/debounce-throttle-per-instance.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rabjs/service': patch ---- - -`@Debounce` / `@Throttle` state (timers, pending args, `this`, results) is now stored per instance instead of in the decorator closure shared by every instance of the class. Previously one instance's pending call was silently dropped when another instance invoked the same method, and destroying one instance cancelled every other instance's pending calls (#220). diff --git a/.changeset/domain-context-ref-sync.md b/.changeset/domain-context-ref-sync.md deleted file mode 100644 index 1be16e0..0000000 --- a/.changeset/domain-context-ref-sync.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rabjs/react': patch ---- - -`useDomainContext` now syncs its internal ref on every render, so consumers (`useService` / `useContainer` / `useContainerEvents`) follow `DomainContext.Provider` value changes instead of permanently resolving against the first-render container (#217). diff --git a/.changeset/domain-readme-dead-api.md b/.changeset/domain-readme-dead-api.md deleted file mode 100644 index 433ef9a..0000000 --- a/.changeset/domain-readme-dead-api.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rabjs/react': patch ---- - -The domain README now documents the real API (`bindServices` with tuple-style service registrations, `RSRoot`/`RSStrict`) instead of the non-existent `createDomain`/`Provider`/`createNestedDomain` functions and the object-form `{ identifier, factory }` registrations that throw at runtime. The dead `ProviderOptions`/`ProviderResult`/`DomainComponent` types and the broken `types/window.d.ts` are removed (#223). diff --git a/.changeset/inject-per-instance-cache.md b/.changeset/inject-per-instance-cache.md deleted file mode 100644 index e4daf31..0000000 --- a/.changeset/inject-per-instance-cache.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rabjs/service': patch ---- - -`@Inject` caches are now per-instance instead of shared across every instance of the class. Previously the first instance's resolved dependency (from whatever container it belonged to) leaked into all other instances, including cross-container and re-bound scenarios, and a manual `set` on one instance overwrote every other instance's injection (#219). diff --git a/.changeset/map-value-iteration-notify.md b/.changeset/map-value-iteration-notify.md deleted file mode 100644 index 7134d50..0000000 --- a/.changeset/map-value-iteration-notify.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rabjs/observer': minor ---- - -Map value overwrites (`map.set(k, v)` for an existing key) now notify value-side iteration dependencies (`forEach` / `values` / `entries` / `for...of` / `size`), which previously never re-ran and kept reading stale data. `Map.keys()` iterations moved to a separate key-side bucket (Vue's `MAP_KEY_ITERATE_KEY` design) so they are still only triggered by add/delete/clear, not by value overwrites (#211). Forged `[object Map]` plain objects still use the object set path and do not re-run `ownKeys` observers. diff --git a/.changeset/memo-batch-stale-read.md b/.changeset/memo-batch-stale-read.md deleted file mode 100644 index aaef846..0000000 --- a/.changeset/memo-batch-stale-read.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rabjs/service': patch ---- - -Fix `@Memo` getters returning stale cached values when read inside `batch()` (including the implicit batch around array mutators). Cache invalidation bookkeeping (`computed = false`) now happens synchronously on the trigger path via the reaction's `debugger` hook (filtered to write operations); only the outer `notify` stays deferred to flush. The memo's inner reaction is also reused across recomputations instead of being recreated, so a notify queued mid-batch can no longer be dropped (#248). diff --git a/.changeset/memo-throw-observer-recover.md b/.changeset/memo-throw-observer-recover.md deleted file mode 100644 index 8db43ac..0000000 --- a/.changeset/memo-throw-observer-recover.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rabjs/service': patch ---- - -Fix outer `observe`/`observer` consumers of a `@Memo` getter going permanently silent after the getter throws once. The proxy get trap registers the dependency only after the getter returns, so a throwing getter left the outer reaction with zero dependencies and no later change could wake it. The memo accessor now pre-registers the `(instance, key)` dependency through the `has` trap before computing, so recovery works once the underlying data is fixed (#247). diff --git a/.changeset/model-loading-last-write.md b/.changeset/model-loading-last-write.md deleted file mode 100644 index a1b834f..0000000 --- a/.changeset/model-loading-last-write.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rabjs/service': patch ---- - -Document that `$model.method.loading` is a boolean last-write flag (not a pending count) and `$model.method.error` cannot be attributed under overlapping same-method calls. diff --git a/.changeset/notify-key-unwrap.md b/.changeset/notify-key-unwrap.md deleted file mode 100644 index 801d462..0000000 --- a/.changeset/notify-key-unwrap.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rabjs/observer': patch ---- - -`notify(target, key)` now unwraps a proxy-form key the same way collection traps do. Passing an observable object as a Map/Set key to `notify` previously looked up a fresh WeakRef that never matched the registered (raw-identity) dependencies, silently notifying no one (#214). diff --git a/.changeset/observe-reuse-unobserved.md b/.changeset/observe-reuse-unobserved.md deleted file mode 100644 index 245d71c..0000000 --- a/.changeset/observe-reuse-unobserved.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rabjs/observer': patch ---- - -`observe(r)` on a previously unobserved reaction now resets the `unobserved` flag, restoring it as a live reaction that collects dependencies and reacts to changes. Previously the reuse path returned a reaction that executed once (appearing revived) but never tracked dependencies again, silently ignoring all subsequent changes (#215). diff --git a/.changeset/reaction-error-deps.md b/.changeset/reaction-error-deps.md deleted file mode 100644 index ce2e1c3..0000000 --- a/.changeset/reaction-error-deps.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rabjs/observer': patch ---- - -Failed reaction re-runs restore the last successful dependency set. Previously `runAsReaction` released all connections up front and a throw left only keys read before the throw point, so later keys went silent until the next successful run (#213). diff --git a/.changeset/use-as-observable-source-frozen-props.md b/.changeset/use-as-observable-source-frozen-props.md deleted file mode 100644 index 63e286d..0000000 --- a/.changeset/use-as-observable-source-frozen-props.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rabjs/react': patch ---- - -`useAsObservableSource` now wraps a shallow copy of the input instead of the original object, so passing React component props no longer throws `TypeError: 'set' on proxy: trap returned falsish` in dev mode (React freezes props) (#216). The caller's original object is never mutated. diff --git a/.changeset/use-reaction-lazy-effect.md b/.changeset/use-reaction-lazy-effect.md deleted file mode 100644 index 032e865..0000000 --- a/.changeset/use-reaction-lazy-effect.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rabjs/react': minor ---- - -`useReaction` gains a two-function (MobX `reaction`-style) overload `useReaction(dataFn, effect, { fireImmediately })`: the data function collects dependencies on mount without running the effect, and the effect runs with `(current, previous)` only after dependencies change. This provides the "don't run on mount" semantics that the single-function form's `immediate: false` cannot express, since the effect and dependency collection share one function there (#200). The single-function form's `immediate` JSDoc now documents this honestly. diff --git a/.changeset/use-reaction-untracked-effect.md b/.changeset/use-reaction-untracked-effect.md deleted file mode 100644 index 3717716..0000000 --- a/.changeset/use-reaction-untracked-effect.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rabjs/react': patch ---- - -`useReaction(dataFn, effectFn)`: reads inside the effect are no longer collected as dependencies — the effect now runs untracked (MobX `reaction` semantics), so mutating observables only touched by the effect no longer spuriously re-fires it (#249). Also, passing the ignored `lazy` option to the single-function form now emits a development-mode warning instead of being silently dropped (#253). diff --git a/.changeset/view-class-commit-tracking.md b/.changeset/view-class-commit-tracking.md deleted file mode 100644 index 0f7db5c..0000000 --- a/.changeset/view-class-commit-tracking.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@rabjs/react': patch ---- - -Class components wrapped by `view()` now start dependency tracking only after the first commit (`componentDidMount` creates the reaction and forces one re-render to collect deps; pre-commit renders run raw). A discarded render pass can no longer leak a live reaction that keeps calling `forceUpdate` on a dead instance — class components cannot use the `useObserver` FinalizationRegistry backstop because the leaked subgraph is self-sustaining. This also moves the static-rendering check from constructor-time to render-time, matching the function-component path (#254). Additionally, lifecycle methods declared as arrow-function class fields (`componentDidMount = () => {...}`) no longer shadow the wrapper's revival/cleanup logic: they are rebound in the constructor to run both the user's field and the wrapper logic. diff --git a/examples/reactive-state/CHANGELOG.md b/examples/reactive-state/CHANGELOG.md index 56f7f28..051779a 100644 --- a/examples/reactive-state/CHANGELOG.md +++ b/examples/reactive-state/CHANGELOG.md @@ -1,5 +1,19 @@ # reactive-state +## 0.0.6 + +### Patch Changes + +- Updated dependencies [946f148] +- Updated dependencies [cd8ec15] +- Updated dependencies [3c2fee7] +- Updated dependencies [a150846] +- Updated dependencies [8bd3a16] +- Updated dependencies [641b090] +- Updated dependencies [946f148] +- Updated dependencies [946f148] + - @rabjs/react@9.4.0 + ## 0.0.5 ### Patch Changes diff --git a/examples/reactive-state/package.json b/examples/reactive-state/package.json index 59b3d82..bfe3f8e 100644 --- a/examples/reactive-state/package.json +++ b/examples/reactive-state/package.json @@ -1,7 +1,7 @@ { "name": "reactive-state", "private": true, - "version": "0.0.5", + "version": "0.0.6", "type": "module", "scripts": { "dev": "vite", diff --git a/packages/devtools/CHANGELOG.md b/packages/devtools/CHANGELOG.md index a1d4e1f..c92e6de 100644 --- a/packages/devtools/CHANGELOG.md +++ b/packages/devtools/CHANGELOG.md @@ -1,5 +1,20 @@ # @rabjs/devtools +## 9.4.0 + +### Patch Changes + +- Updated dependencies [946f148] +- Updated dependencies [cf93d8d] +- Updated dependencies [946f148] +- Updated dependencies [358f357] +- Updated dependencies [5095f54] +- Updated dependencies [946f148] +- Updated dependencies [946f148] +- Updated dependencies [cf0c308] + - @rabjs/service@9.4.0 + - @rabjs/shared@9.4.0 + ## 9.3.5 ### Patch Changes diff --git a/packages/devtools/package.json b/packages/devtools/package.json index dc4702f..fdaf805 100644 --- a/packages/devtools/package.json +++ b/packages/devtools/package.json @@ -1,6 +1,6 @@ { "name": "@rabjs/devtools", - "version": "9.3.5", + "version": "9.4.0", "description": "RABjs 开发调试工具,通过 CDP 协议暴露容器树状态", "main": "lib/main.cjs", "module": "lib/main.js", diff --git a/packages/observer/CHANGELOG.md b/packages/observer/CHANGELOG.md index f655d3a..bb87c3c 100644 --- a/packages/observer/CHANGELOG.md +++ b/packages/observer/CHANGELOG.md @@ -1,5 +1,20 @@ # @rabjs/observer +## 9.4.0 + +### Minor Changes + +- 46f2e01: Map value overwrites (`map.set(k, v)` for an existing key) now notify value-side iteration dependencies (`forEach` / `values` / `entries` / `for...of` / `size`), which previously never re-ran and kept reading stale data. `Map.keys()` iterations moved to a separate key-side bucket (Vue's `MAP_KEY_ITERATE_KEY` design) so they are still only triggered by add/delete/clear, not by value overwrites (#211). Forged `[object Map]` plain objects still use the object set path and do not re-run `ownKeys` observers. + +### Patch Changes + +- 946f148: Fix a `TypeError: 'get' on proxy` when reading a frozen (non-configurable + non-writable) own array mutator property on an observable array. The batch-wrapping introduced for array mutators (#93) ran before the Proxy get invariant check and returned a different function object; the invariant check now runs first in both base and shadow get traps (#251). +- 946f148: `batch()` flush-error handling hardening: attaching the flush error as `cause` is skipped when the callback and a reaction threw the identical `Error` instance (a self-referential `cause` loops naive cause-chain walkers), and the `console.warn` fallback for unattached flush errors is itself isolated so throwing console shims cannot replace the in-flight exception. Also, reviving an unobserved reaction via `observe(r)` no longer overwrites its custom `scheduler`/`debugger` with global defaults. +- 6c0aa33: `batch(fn)` no longer lets a flush-time reaction error replace the callback's own in-flight exception. Previously `try { batch(mutate) } catch` caught the reaction's error while the callback's original error was silently dropped; the flush error is now attached as `cause` on the original error when possible (#212). +- dd17bbd: `notify(target, key)` now unwraps a proxy-form key the same way collection traps do. Passing an observable object as a Map/Set key to `notify` previously looked up a fresh WeakRef that never matched the registered (raw-identity) dependencies, silently notifying no one (#214). +- 1978dba: `observe(r)` on a previously unobserved reaction now resets the `unobserved` flag, restoring it as a live reaction that collects dependencies and reacts to changes. Previously the reuse path returned a reaction that executed once (appearing revived) but never tracked dependencies again, silently ignoring all subsequent changes (#215). +- 05d2d2a: Failed reaction re-runs restore the last successful dependency set. Previously `runAsReaction` released all connections up front and a throw left only keys read before the throw point, so later keys went silent until the next successful run (#213). + ## 9.3.5 ## 9.3.4 diff --git a/packages/observer/package.json b/packages/observer/package.json index 9480bc9..0eaca01 100644 --- a/packages/observer/package.json +++ b/packages/observer/package.json @@ -1,6 +1,6 @@ { "name": "@rabjs/observer", - "version": "9.3.5", + "version": "9.4.0", "description": "Fine-grained reactivity — observable state, computed values, and reactions for the rab state architecture", "main": "lib/main.cjs", "module": "lib/main.js", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 5887c2c..23ec7d3 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,41 @@ # @rabjs/react +## 9.4.0 + +### Minor Changes + +- 641b090: `useReaction` gains a two-function (MobX `reaction`-style) overload `useReaction(dataFn, effect, { fireImmediately })`: the data function collects dependencies on mount without running the effect, and the effect runs with `(current, previous)` only after dependencies change. This provides the "don't run on mount" semantics that the single-function form's `immediate: false` cannot express, since the effect and dependency collection share one function there (#200). The single-function form's `immediate` JSDoc now documents this honestly. + +### Patch Changes + +- 946f148: `bindServices` container teardown scheduling now falls back `queueMicrotask` → `Promise` → `setTimeout`, so cleanup still happens in legacy JS engines without `queueMicrotask` (old React Native JSC/Hermes). Also extracts an internal `createContainer` factory used by both creation and the hidden-tree rebuild path. +- cd8ec15: `bindServices` now destroys its container on unmount instead of waiting for the FinalizationRegistry/GC fallback. Service cleanup (event listeners, debounce/throttle timers) previously stayed pending for an unbounded window. Destroy is scheduled on a microtask so React StrictMode's fake unmount/remount does not tear down a live container; the GC fallback is kept for concurrent renders that never commit (#218). + + **Behavior change**: the container is private to the bound subtree by design. Service instances held outside the subtree (stored in refs, injected into parent/global containers, kept in external caches) become destroyed objects after unmount — do not let subtree services escape; if an instance's lifetime must outlive the component, register it in a parent container instead (#252). + +- 3c2fee7: `useDomainContext` now syncs its internal ref on every render, so consumers (`useService` / `useContainer` / `useContainerEvents`) follow `DomainContext.Provider` value changes instead of permanently resolving against the first-render container (#217). +- a150846: The domain README now documents the real API (`bindServices` with tuple-style service registrations, `RSRoot`/`RSStrict`) instead of the non-existent `createDomain`/`Provider`/`createNestedDomain` functions and the object-form `{ identifier, factory }` registrations that throw at runtime. The dead `ProviderOptions`/`ProviderResult`/`DomainComponent` types and the broken `types/window.d.ts` are removed (#223). +- 8bd3a16: `useAsObservableSource` now wraps a shallow copy of the input instead of the original object, so passing React component props no longer throws `TypeError: 'set' on proxy: trap returned falsish` in dev mode (React freezes props) (#216). The caller's original object is never mutated. +- 946f148: `useReaction(dataFn, effectFn)`: reads inside the effect are no longer collected as dependencies — the effect now runs untracked (MobX `reaction` semantics), so mutating observables only touched by the effect no longer spuriously re-fires it (#249). Also, passing the ignored `lazy` option to the single-function form now emits a development-mode warning instead of being silently dropped (#253). +- 946f148: Class components wrapped by `view()` now start dependency tracking only after the first commit (`componentDidMount` creates the reaction and forces one re-render to collect deps; pre-commit renders run raw). A discarded render pass can no longer leak a live reaction that keeps calling `forceUpdate` on a dead instance — class components cannot use the `useObserver` FinalizationRegistry backstop because the leaked subgraph is self-sustaining. This also moves the static-rendering check from constructor-time to render-time, matching the function-component path (#254). Additionally, lifecycle methods declared as arrow-function class fields (`componentDidMount = () => {...}`) no longer shadow the wrapper's revival/cleanup logic: they are rebound in the constructor to run both the user's field and the wrapper logic. +- Updated dependencies [946f148] +- Updated dependencies [946f148] +- Updated dependencies [6c0aa33] +- Updated dependencies [946f148] +- Updated dependencies [cf93d8d] +- Updated dependencies [946f148] +- Updated dependencies [358f357] +- Updated dependencies [5095f54] +- Updated dependencies [46f2e01] +- Updated dependencies [946f148] +- Updated dependencies [946f148] +- Updated dependencies [cf0c308] +- Updated dependencies [dd17bbd] +- Updated dependencies [1978dba] +- Updated dependencies [05d2d2a] + - @rabjs/observer@9.4.0 + - @rabjs/service@9.4.0 + ## 9.3.5 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index 8f56de8..99cabf3 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@rabjs/react", - "version": "9.3.5", + "version": "9.4.0", "description": "AI-first reactive state for React — observable Service instances shared by UI, tests, DevTools, and AI agents (Web MCP)", "main": "lib/cjs/main.js", "module": "lib/esm/main.js", diff --git a/packages/rn-debug-server/CHANGELOG.md b/packages/rn-debug-server/CHANGELOG.md index 2db42dd..d48d1be 100644 --- a/packages/rn-debug-server/CHANGELOG.md +++ b/packages/rn-debug-server/CHANGELOG.md @@ -1,5 +1,7 @@ # @rabjs/rn-debug-server +## 9.4.0 + ## 9.3.5 ## 9.3.4 diff --git a/packages/rn-debug-server/package.json b/packages/rn-debug-server/package.json index 2a19b82..91b7372 100644 --- a/packages/rn-debug-server/package.json +++ b/packages/rn-debug-server/package.json @@ -1,6 +1,6 @@ { "name": "@rabjs/rn-debug-server", - "version": "9.3.5", + "version": "9.4.0", "description": "RABjs RN 调试服务 - Agent 通过 HTTP 指令调试 React Native 设备", "type": "module", "main": "lib/main.cjs", diff --git a/packages/rn-debug/CHANGELOG.md b/packages/rn-debug/CHANGELOG.md index e622b26..e40cd58 100644 --- a/packages/rn-debug/CHANGELOG.md +++ b/packages/rn-debug/CHANGELOG.md @@ -1,5 +1,20 @@ # @rabjs/rn-debug +## 9.4.0 + +### Patch Changes + +- Updated dependencies [946f148] +- Updated dependencies [cf93d8d] +- Updated dependencies [946f148] +- Updated dependencies [358f357] +- Updated dependencies [5095f54] +- Updated dependencies [946f148] +- Updated dependencies [946f148] +- Updated dependencies [cf0c308] + - @rabjs/service@9.4.0 + - @rabjs/shared@9.4.0 + ## 9.3.5 ### Patch Changes diff --git a/packages/rn-debug/package.json b/packages/rn-debug/package.json index 57941c2..8bc4253 100644 --- a/packages/rn-debug/package.json +++ b/packages/rn-debug/package.json @@ -1,6 +1,6 @@ { "name": "@rabjs/rn-debug", - "version": "9.3.5", + "version": "9.4.0", "description": "RABjs React Native 调试 SDK - 长连接接收指令并顺序执行", "type": "module", "main": "lib/main.cjs", diff --git a/packages/service/CHANGELOG.md b/packages/service/CHANGELOG.md index bf26b6b..beea9d6 100644 --- a/packages/service/CHANGELOG.md +++ b/packages/service/CHANGELOG.md @@ -1,5 +1,18 @@ # @rabjs/service +## 9.4.0 + +### Patch Changes + +- 946f148: `cleanupAllMemos` now notifies outer observers per cleaned memo key (batched into a single flush), matching `invalidateMemo` semantics — mounted `observe`/`observer` consumers no longer stay stale after a cache reset. `Service.destroy` passes `{ notify: false }` to keep its deliberate silence (#255). +- cf93d8d: `cleanupAllMemos` / `cleanupAllDebounces` / `cleanupAllThrottles` now walk the full prototype chain instead of only the direct prototype. Decorated members defined on a base class are cleaned up when a subclass instance is destroyed; previously their memo reactions kept running and debounce/throttle timers kept firing on destroyed instances (#221). +- 946f148: `@Debounce`/`@Throttle` no longer throw `TypeError: Invalid value used as weak map key` on detached calls (`this` null/undefined, e.g. `arr.map(service.save)` or destructured methods). Detached calls share one module-level sentinel state, matching the pre-WeakMap closure behavior (#250). +- 358f357: `@Debounce` / `@Throttle` state (timers, pending args, `this`, results) is now stored per instance instead of in the decorator closure shared by every instance of the class. Previously one instance's pending call was silently dropped when another instance invoked the same method, and destroying one instance cancelled every other instance's pending calls (#220). +- 5095f54: `@Inject` caches are now per-instance instead of shared across every instance of the class. Previously the first instance's resolved dependency (from whatever container it belonged to) leaked into all other instances, including cross-container and re-bound scenarios, and a manual `set` on one instance overwrote every other instance's injection (#219). +- 946f148: Fix `@Memo` getters returning stale cached values when read inside `batch()` (including the implicit batch around array mutators). Cache invalidation bookkeeping (`computed = false`) now happens synchronously on the trigger path via the reaction's `debugger` hook (filtered to write operations); only the outer `notify` stays deferred to flush. The memo's inner reaction is also reused across recomputations instead of being recreated, so a notify queued mid-batch can no longer be dropped (#248). +- 946f148: Fix outer `observe`/`observer` consumers of a `@Memo` getter going permanently silent after the getter throws once. The proxy get trap registers the dependency only after the getter returns, so a throwing getter left the outer reaction with zero dependencies and no later change could wake it. The memo accessor now pre-registers the `(instance, key)` dependency through the `has` trap before computing, so recovery works once the underlying data is fixed (#247). +- cf0c308: Document that `$model.method.loading` is a boolean last-write flag (not a pending count) and `$model.method.error` cannot be attributed under overlapping same-method calls. + ## 9.3.5 ### Patch Changes diff --git a/packages/service/package.json b/packages/service/package.json index 7f322dd..ef31328 100644 --- a/packages/service/package.json +++ b/packages/service/package.json @@ -1,6 +1,6 @@ { "name": "@rabjs/service", - "version": "9.3.5", + "version": "9.4.0", "description": "Observable Service containers, lifecycle, and method models (loading/error) for the rab AI-first state architecture", "main": "lib/main.cjs", "module": "lib/main.js", diff --git a/packages/shared/CHANGELOG.md b/packages/shared/CHANGELOG.md index 0bd9989..a989ad7 100644 --- a/packages/shared/CHANGELOG.md +++ b/packages/shared/CHANGELOG.md @@ -1,5 +1,7 @@ # @rabjs/shared +## 9.4.0 + ## 9.3.5 ## 9.3.4 diff --git a/packages/shared/package.json b/packages/shared/package.json index ed5d497..7b3eac8 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,6 +1,6 @@ { "name": "@rabjs/shared", - "version": "9.3.5", + "version": "9.4.0", "description": "RABjs 共享工具库(断言、路径解析等)", "main": "lib/main.cjs", "module": "lib/main.js", diff --git a/packages/web-mcp/CHANGELOG.md b/packages/web-mcp/CHANGELOG.md index d3f8378..b49bb0c 100644 --- a/packages/web-mcp/CHANGELOG.md +++ b/packages/web-mcp/CHANGELOG.md @@ -1,5 +1,20 @@ # @rabjs/web-mcp +## 9.4.0 + +### Patch Changes + +- Updated dependencies [946f148] +- Updated dependencies [cf93d8d] +- Updated dependencies [946f148] +- Updated dependencies [358f357] +- Updated dependencies [5095f54] +- Updated dependencies [946f148] +- Updated dependencies [946f148] +- Updated dependencies [cf0c308] + - @rabjs/service@9.4.0 + - @rabjs/shared@9.4.0 + ## 9.3.5 ### Patch Changes diff --git a/packages/web-mcp/package.json b/packages/web-mcp/package.json index e13de07..6113672 100644 --- a/packages/web-mcp/package.json +++ b/packages/web-mcp/package.json @@ -1,6 +1,6 @@ { "name": "@rabjs/web-mcp", - "version": "9.3.5", + "version": "9.4.0", "description": "Web MCP 集成 - 将 @rabjs/service 的 Service 系统与 WebMCP 协议桥接", "main": "lib/main.cjs", "module": "lib/main.js", diff --git a/website/CHANGELOG.md b/website/CHANGELOG.md index a2bd715..2173ce9 100644 --- a/website/CHANGELOG.md +++ b/website/CHANGELOG.md @@ -1,5 +1,38 @@ # @rabjs/website +## 9.0.6 + +### Patch Changes + +- Updated dependencies [946f148] +- Updated dependencies [946f148] +- Updated dependencies [6c0aa33] +- Updated dependencies [946f148] +- Updated dependencies [cd8ec15] +- Updated dependencies [946f148] +- Updated dependencies [cf93d8d] +- Updated dependencies [946f148] +- Updated dependencies [358f357] +- Updated dependencies [3c2fee7] +- Updated dependencies [a150846] +- Updated dependencies [5095f54] +- Updated dependencies [46f2e01] +- Updated dependencies [946f148] +- Updated dependencies [946f148] +- Updated dependencies [cf0c308] +- Updated dependencies [dd17bbd] +- Updated dependencies [1978dba] +- Updated dependencies [05d2d2a] +- Updated dependencies [8bd3a16] +- Updated dependencies [641b090] +- Updated dependencies [946f148] +- Updated dependencies [946f148] + - @rabjs/observer@9.4.0 + - @rabjs/react@9.4.0 + - @rabjs/service@9.4.0 + - @rabjs/devtools@9.4.0 + - @rabjs/web-mcp@9.4.0 + ## 9.0.5 ### Patch Changes diff --git a/website/package.json b/website/package.json index 6cad5a0..c8c99d8 100644 --- a/website/package.json +++ b/website/package.json @@ -1,6 +1,6 @@ { "name": "@rabjs/website", - "version": "9.0.5", + "version": "9.0.6", "private": true, "type": "module", "scripts": {