Morphos & Kosmesis are here.Explore
PraxisJS

@praxisjs/store

Changelog for @praxisjs/store — global state management with @Storable and @Store.

@praxisjs/store

2.0.6

Depends on the other @praxisjs/* packages through caret ranges (^2.3.0) instead of exact versions, so npm no longer installs a second copy of a package when two releases disagree, and upgrades no longer end in peer conflicts.

2.0.5

The published package no longer contains the package's tests (compiled tests in dist/__tests__, test sources in src/__tests__).

The package is marked "sideEffects": false, so bundlers leave out the modules of it that an app does not use.

@Store throw a TypeError when the class is defined if they decorate an accessor instead of a plain field, naming the member to fix (see assertFieldContext).

Fixes for @Storable stores with plugins, which the 2.0.4 notes described but which only reached the old functional store:

  • An action read from the store is the same function on every read, instead of a new wrapper per access. It stays bound to the store, so onClick={cart.clear} still works.
  • Writing a field inside an effect no longer subscribes that effect to the field. The previous value passed to onMutation (and anything the plugins read) is read untracked; an effect assigning store.value = source() used to re-run on every external write to value, overwriting it.
  • Extension functions from extend() are bound once instead of on every read, and an extension no longer shadows inherited members such as constructor.
  • constructor and inherited Object.prototype methods (toString, hasOwnProperty...) are no longer wrapped and reported to plugins as actions.

store() does a single registry lookup, and @Store(Class) keeps the singleton after its first read, sharing one accessor across instances.

Removed the internal createStore() module: it was no longer exported, so nothing outside the package could use it, and the plugin tests that went through it now run against @Storable classes.

2.0.4

store.action now returns the same wrapper function on every read instead of allocating a new one per access. $patch() and $reset() run inside one batch, so dependents re-run once for the whole operation rather than once per key. Writing a key inside an effect no longer subscribes that effect to the key (the previous value is read untracked).

2.0.0

Breaking: ReactiveStore no longer exposes _stateDirty.

ReactiveStore now uses a type-only reactive-host marker for @State and @DeepState compatibility. Store instances no longer create the _stateDirty field at runtime.

1.3.0

Plugin system — useStorePlugin, clearPlugins, and the StorePlugin interface. Plugins hook into store lifecycle via onInit, onMutation, onAction, and onActionDone. Works with both createStore (functional) and class-based @Storable stores. See the Plugins section for usage and built-in plugin recipes.

1.2.0

API rename — @Store() (class decorator) → @Storable(), @UseStore(Class) (field decorator) → @Store(Class), useStore() → store().

BeforeAfter
@Store() on a class@Storable()
@UseStore(CartStore) on a field@Store(CartStore)
useStore(CartStore) imperativelystore(CartStore)
import { Storable, Store, store, ReactiveStore } from '@praxisjs/store'

@Storable()
class CartStore extends ReactiveStore { /* ... */ }

// in a component:
@Store(CartStore) cart!: CartStore

// imperatively:
const cart = store(CartStore)

1.1.0

Add store() — functional alternative to @Store for use outside component context (route guards, plain functions). Resolves from the same global registry as @Store and always returns the same singleton instance.

1.0.12

Updated dependencies — @praxisjs/[email protected], @praxisjs/[email protected].

1.0.11

Updated dependencies — @praxisjs/[email protected].

1.0.10

ReactiveStore base class introduced. Store classes must now extend ReactiveStore to satisfy the ReactiveHost constraint required by @State and @DeepState. A TypeScript error is produced at the call site if omitted — no more silent runtime failures.

1.0.0

Breaking — createStore() removed

createStore() is removed. Use @Storable and @Store:

// before
const store = createStore({ count: 0 })

// after
@Storable()
class CounterStore extends ReactiveStore {
  @State() count = 0
}

// in a component:
@Store(CounterStore) counter!: CounterStore

0.2.2

Bug fix: store Proxy set trap no longer throws TypeError when JavaScript internals write symbol keys (e.g. Symbol.toPrimitive).

0.2.0

Migrated to TC39 decorator context API.

0.1.0

Initial beta release.

On this page