chrono-state-z 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,18 +6,15 @@
6
6
 
7
7
  ---
8
8
 
9
- **chrono-state-z** is a **reactive, intent-first state runtime** designed to keep **business logic outside React**.
9
+ **chrono-state-z** is a reactive state runtime that keeps business logic outside React.
10
+ It provides **atoms, computed values, async state, effects, scheduling**, with a **headless core** and **thin React bindings**.
10
11
 
11
- It provides **atoms, computed values, async state, effects, scheduling**, with a **headless core** and **thin React bindings**.
12
-
13
- > **React renders state. Logic lives elsewhere.**
12
+ > **React renders. Logic lives elsewhere.**
14
13
 
15
14
  ---
16
15
 
17
16
  ## ✨ Why chrono-state-z?
18
17
 
19
- Use chrono-state-z when you need:
20
-
21
18
  - Predictable state & side-effects
22
19
  - Complex async flows (fetch → invalidate → retry)
23
20
  - Logic reusable outside React (tests, workers, backend)
@@ -41,10 +38,48 @@ Use chrono-state-z when you need:
41
38
  ## 📦 Installation
42
39
 
43
40
  ```bash
44
- # npm install react ## for react
45
- npm install intentx-core-z chrono-state-z
41
+ npm install chrono-state-z
42
+ # If using React:
43
+ npm install react
44
+ ```
45
+
46
+ ---
47
+
48
+ ## ⚡ Quick Start
49
+
50
+ ```ts
51
+ import { atom, computed, asyncAtom } from "chrono-state-z";
52
+
53
+ const count = atom(0);
54
+ const double = computed(() => count() * 2);
55
+
56
+ const user = asyncAtom(async () =>
57
+ fetch("https://jsonplaceholder.typicode.com/todos/1")
58
+ .then(r => r.json())
59
+ );
60
+ ```
61
+
62
+ ```ts
63
+ import { useAtom, useComputed } from "chrono-state-z";
64
+
65
+ function App() {
66
+ const value = useAtom(count);
67
+ const doubled = useComputed(double);
68
+ const username = useComputed(() => user()?.title);
69
+
70
+ return (
71
+ <button onClick={() => count.set(c => c + 1)}>
72
+ {value}
73
+ </button>
74
+ );
75
+ }
76
+
46
77
  ```
47
78
 
79
+ ✨ Fine-grained updates.
80
+ ✨ Suspense-ready async.
81
+ ✨ No reducers. No boilerplate.
82
+
48
83
  ---
49
84
 
50
85
  ## 🔹 Core Usage
@@ -269,6 +304,8 @@ function SavingBadge({ store }) {
269
304
  ```ts
270
305
  import { useWatch } from 'chrono-state-z'
271
306
 
307
+ const user = atom<{ role?: string } | null>(null)
308
+
272
309
  function AuthGuard() {
273
310
  useWatch(
274
311
  () => user(),
@@ -317,7 +354,7 @@ export function createUserLogic() {
317
354
  ```tsx
318
355
  function UserView({ logic }) {
319
356
  const user = useAtom(logic.user)
320
- const name = useComputed(() => logic.name())
357
+ const name = useComputed(logic.name)
321
358
 
322
359
  return (
323
360
  <>
@@ -331,16 +368,74 @@ function UserView({ logic }) {
331
368
 
332
369
  ---
333
370
 
334
- ## 📊 Comparison with Other Libraries
371
+ ## 🔍 Comparison
372
+
373
+ <b>This is not about “better” — it's about architectural.</b>
374
+
375
+ | Feature | chrono-state-z | Redux Toolkit | Zustand | Jotai | MobX |
376
+ | --------------------------- | -------------- | ------------- | -------- | ----- | ---- |
377
+ | Fine-grained reactivity | ✅ | ❌ | ⚠️ | ✅ | ✅ |
378
+ | Built-in async primitives | ✅ | ⚠️ | ❌ | ⚠️ | ❌ |
379
+ | Scheduler / priority system | ✅ | ❌ | ❌ | ❌ | ❌ |
380
+ | Headless (non-React) core | ✅ | ✅ | ⚠️ | ⚠️ | ✅ |
381
+ | Boilerplate level | ✅ | ❌ | ✅ | ✅ | ⚠️ |
382
+ | Devtools maturity | ⚠️ | ✅ | ✅ | ⚠️ | ✅ |
383
+ | Learning curve | ⚠️ | ⚠️ | ✅ | ✅ | ⚠️ |
384
+
385
+
386
+ <br />
387
+
388
+ <b>📝 Notes</b>
389
+
390
+ ⚠️ Fine-grained in Zustand: achieved via selectors, but not dependency-tracked graph-level.
391
+
392
+ ⚠️ Async in Redux / Jotai / Recoil: supported via patterns (thunks, query libs, async selectors), not core-first primitives.
393
+
394
+ ⚠️ Headless in Zustand/Jotai: possible, but primarily designed for React usage.
395
+
396
+ ⚠️ Devtools: Redux and MobX have mature ecosystems; newer libs are still evolving.
397
+
398
+ ---
399
+
400
+ ## ⚖️ Strengths Compared to Others
401
+
402
+ <b>vs Redux Toolkit</b>
403
+
404
+ - More fine-grained updates
405
+ - Less reducer boilerplate
406
+ - Built-in reactive primitives
407
+ - Redux has stronger ecosystem & devtools
408
+
409
+ <b>vs Zustand</b>
410
+
411
+ - More structured async handling
412
+ - Explicit intent layer
413
+ - Built-in scheduler support
414
+ - Zustand is simpler & lighter for small apps
415
+
416
+ <b>vs Jotai</b>
417
+
418
+ - More explicit effect + scheduler control
419
+ - Async-first primitives
420
+ - Jotai is more minimal and React-native
421
+
422
+ <b>vs MobX</b>
423
+
424
+ - More explicit dependency graph (no proxy magic)
425
+ - Better control over update priority
426
+ - MobX is more ergonomic for mutable patterns
427
+
428
+ <b>vs Recoil</b>
429
+
430
+ - Headless core (not React-bound)
431
+ - Explicit effect system
432
+ - Recoil has better React DevTools integration
433
+
434
+ <b>vs Solid signals</b>
335
435
 
336
- | Feature | chrono-state-z | Redux | Zustand | Jotai |
337
- |---------------------------|---------------- |-------|--------- |------- |
338
- | Fine-grained reactivity | ✅ | ❌ | ⚠️ | ✅ |
339
- | Async primitives | ✅ | ⚠️ | ❌ | ⚠️ |
340
- | Intent / effect layer | ✅ | ⚠️ | ❌ | ❌ |
341
- | Scheduler / priority | ✅ | ❌ | ❌ | ❌ |
342
- | Headless (non-React) core | ✅ | ❌ | ⚠️ | ❌ |
343
- | Testability | ✅ | ⚠️ | ⚠️ | ❌ |
436
+ - Similar fine-grained reactive model
437
+ - Designed for React ecosystem
438
+ - Solid is framework-native and extremely optimized
344
439
 
345
440
  ---
346
441
 
@@ -1,9 +1,10 @@
1
- import { Priority } from "intentx-core-z";
1
+ import { CommonResource } from "./asyncResource";
2
2
  export type AsyncAtom<T> = {
3
- (): T;
4
- set(v: T, p?: Priority): void;
5
- load(): Promise<T>;
6
- cancel(): void;
7
- invalidate(p?: Priority): void;
8
- };
9
- export declare function asyncAtom<T>(fetcher: (signal?: AbortSignal) => Promise<T>): AsyncAtom<T>;
3
+ (): T | undefined;
4
+ } & CommonResource<T>;
5
+ export declare function asyncAtom<T>(fetcher: (signal?: AbortSignal) => Promise<T>, options?: {
6
+ suspense?: boolean;
7
+ }): AsyncAtom<T>;
8
+ export declare function asyncAtomFamily<K, T>(factory: (key: K) => (signal?: AbortSignal) => Promise<T>, options?: {
9
+ suspense?: boolean;
10
+ }): (key: K) => AsyncAtom<T>;
@@ -1,6 +1,8 @@
1
1
  import type { Priority } from "intentx-core-z";
2
2
  export type AsyncComputed<T> = {
3
- (): T;
4
- invalidate(p?: Priority): void;
3
+ (): T | undefined;
4
+ invalidate(priority?: Priority): void;
5
+ status(): string;
6
+ error(): any;
5
7
  };
6
8
  export declare function asyncComputed<T>(getter: (signal?: AbortSignal) => Promise<T>, priority?: Priority): AsyncComputed<T>;
@@ -0,0 +1,28 @@
1
+ import { Priority } from "intentx-core-z";
2
+ export type CommonResource<T> = {
3
+ load(): Promise<T>;
4
+ cancel(): void;
5
+ invalidate(priority?: Priority): void;
6
+ status(): AsyncState<T>["status"];
7
+ error(): any;
8
+ setSuccess(value: T, priority?: Priority): void;
9
+ };
10
+ export type AsyncState<T> = {
11
+ status: "idle";
12
+ } | {
13
+ status: "loading";
14
+ promise: Promise<T>;
15
+ } | {
16
+ status: "success";
17
+ data: T;
18
+ } | {
19
+ status: "error";
20
+ error: any;
21
+ };
22
+ export type AsyncResource<T> = {
23
+ read(): T | undefined;
24
+ } & CommonResource<T>;
25
+ export declare function createAsyncResource<T>(fetcher: (signal?: AbortSignal) => Promise<T>, options?: {
26
+ suspense?: boolean;
27
+ priority?: Priority;
28
+ }): AsyncResource<T>;
@@ -1,6 +1,6 @@
1
- import { Priority } from "intentx-core-z";
2
- export type Atom<T> = (() => T) & {
3
- set(v: T, p?: Priority): void;
4
- subscribe(fn: () => void): () => void;
5
- };
6
- export declare function atom<T>(initial: T): Atom<T>;
1
+ export type ReadonlyAtom<T> = () => T;
2
+ export declare const atom: <T>(initial: T, options?: import("./createAtomFactory").AtomOptions<T>) => import("./createBaseAtom").Atom<T>;
3
+ export declare const atomMiddleware: <T>(initial: T, middleware?: import("./createAtomFactory").AtomMiddleware<T>) => import("./createBaseAtom").Atom<T>;
4
+ export declare function readonlyAtom<T>(atom: {
5
+ (): T;
6
+ }): ReadonlyAtom<T>;
@@ -0,0 +1,7 @@
1
+ import type { Signal } from "intentx-core-z";
2
+ export type AtomOptions<T> = {
3
+ equals?: (a: T, b: T) => boolean;
4
+ };
5
+ export type AtomMiddleware<T> = (next: T, prev: T) => T;
6
+ export declare function createAtomFactory(signal: <T>(v: T) => Signal<T>): <T>(initial: T, options?: AtomOptions<T>) => import("./createBaseAtom").Atom<T>;
7
+ export declare function createAtomWithMiddlewareFactory(signal: <T>(v: T) => Signal<T>): <T>(initial: T, middleware?: AtomMiddleware<T>) => import("./createBaseAtom").Atom<T>;
@@ -0,0 +1,6 @@
1
+ import type { Priority, Signal } from "intentx-core-z";
2
+ export type Atom<T> = Signal<T> & {
3
+ update(fn: (prev: T) => T, priority?: Priority): void;
4
+ };
5
+ export type AtomTransform<T> = (next: T, prev: T) => T;
6
+ export declare function createBaseAtomFactory(signal: <T>(v: T) => Signal<T>): <T>(initial: T, transform?: AtomTransform<T>) => Atom<T>;
@@ -1,3 +1,3 @@
1
1
  import type { Scope } from "intentx-core-z";
2
- import { Store } from "./store";
2
+ import { Store } from "./types";
3
3
  export declare function createStore<S extends object>(initial: S, scope?: Scope): Store<S>;
@@ -1 +1,7 @@
1
- export declare function factoryAtom<K, A>(factory: (key: K) => A): (key: K) => A;
1
+ export declare function factoryAtom<K, A>(factory: (key: K) => A, options?: {
2
+ weak?: boolean;
3
+ }): {
4
+ (key: K): A;
5
+ delete(key: K): void;
6
+ clear(): void;
7
+ };
@@ -1,10 +1,12 @@
1
- export { atom } from "./atom";
2
- export { computed } from "./computed";
1
+ export * from "./atom";
2
+ export * from "./asyncComputed";
3
+ export * from "./createAtomFactory";
3
4
  export { asyncAtom } from "./asyncAtom";
4
- export { asyncComputed } from "./asyncComputed";
5
- export { effect } from "./effect";
6
- export { watch } from "./watch";
5
+ export { computed } from "intentx-core-z";
6
+ export { effect } from "intentx-core-z";
7
+ export * from "./watch";
7
8
  export { createStore } from "./createStore";
8
- export { selectAtom, createSelector } from "./selector";
9
- export type { Store, Subscriber } from "./store";
9
+ export * from "./selector";
10
+ export type { Store, Subscriber } from "./types";
10
11
  export { factoryAtom } from "./factoryAtom";
12
+ export { transaction } from "./transaction";
@@ -1,2 +1,7 @@
1
1
  import type { Priority } from "intentx-core-z";
2
- export declare function watch<T>(getter: () => T, fn: (value: T) => void, priority?: Priority): () => void;
2
+ export type WatchOptions<T> = {
3
+ immediate?: boolean;
4
+ equals?: (a: T, b: T) => boolean;
5
+ priority?: Priority;
6
+ };
7
+ export declare function watch<T>(getter: () => T, fn: (value: T, prev: T | undefined, onCleanup: (callback: () => void) => void) => void, options?: WatchOptions<T>): () => void;
@@ -1 +1 @@
1
- "use strict";var t=require("intentx-core-z"),e=require("react");function n(t){var e=Object.create(null);return t&&Object.keys(t).forEach(function(n){if("default"!==n){var r=Object.getOwnPropertyDescriptor(t,n);Object.defineProperty(e,n,r.get?r:{enumerable:!0,get:function(){return t[n]}})}}),e.default=t,Object.freeze(e)}var r=n(e);const o={activeEffect:null};function c(e){let n=e;const r=new Set,c=new Set,u=()=>(o.activeEffect&&c.add(o.activeEffect),n);return u.set=(e,o="normal")=>{Object.is(e,n)||(n=e,c.forEach(e=>t.schedule(e,o)),r.forEach(e=>t.schedule(e,o)))},u.subscribe=t=>(r.add(t),()=>r.delete(t)),u}function u(e){let n,r=!0;const c=new Set,u=()=>{r||(r=!0,c.forEach(e=>t.schedule(e)))};return()=>{if(o.activeEffect&&c.add(o.activeEffect),r){const t=o.activeEffect;o.activeEffect=u,n=e(),r=!1,o.activeEffect=t}return n}}function l(e,n="normal"){let r=null,c=!1;const u=()=>{if(!c){null==r||r();try{o.activeEffect=u;const t=e();"function"==typeof t&&(r=t)}finally{o.activeEffect=null}}};return t.schedule(u,n),()=>{c=!0,null==r||r(),r=null}}function s(t,e,n="normal"){return l(()=>{e(t())},n)}function a(t,e=Object.is){let n,r=!1;return o=>{const c=t(o);return r&&e(n,c)?n:(r=!0,n=c,c)}}const i=t.createScope("default");function f(t){return r.useSyncExternalStore(e=>{let n=t();return l(()=>{const r=t();Object.is(n,r)||(n=r,e())})},t,t)}Object.defineProperty(exports,"createScope",{enumerable:!0,get:function(){return t.createScope}}),exports.asyncAtom=function(e){const n=c(null);let r=null,o=null;const u=()=>(r||(o=new AbortController,r=e(o.signal).then(t=>((null==o?void 0:o.signal.aborted)||n.set(t),t)).finally(()=>{r=null})),r),l=()=>{null==o||o.abort(),o=null,r=null},s=()=>{const t=n();if(null===t)throw u();return t};return s.set=n.set,s.load=u,s.cancel=l,s.invalidate=(e="normal")=>{l(),t.schedule(()=>{try{u()}catch{}},e)},s},exports.asyncComputed=function(e,n="normal"){const r=c(void 0);let o=null,u=null,l=null;const s=()=>(o||(u=new AbortController,l=null,o=e(u.signal).then(t=>((null==u?void 0:u.signal.aborted)||r.set(t,n),t)).catch(t=>{throw(null==u?void 0:u.signal.aborted)||(l=t),t}).finally(()=>{o=null})),o),a=()=>{const t=r();if(l)throw l;if(void 0===t)throw s();return t};return a.invalidate=(e=n)=>{null==u||u.abort(),u=null,o=null,t.schedule(()=>{try{s()}catch{}},e)},a},exports.atom=c,exports.computed=u,exports.createSelector=a,exports.createStore=function(e,n=i){let r=e;const o=new Set,c=t.createIntentBus((t,e)=>{const n=new AbortController;return{payload:t,scope:e,state:r,signal:n.signal,setState(t){t(r),o.forEach(t=>t())},emit:(t,n)=>c.emit(t,n,e)}});return{scope:n,state:()=>r,setState(t){t(r),o.forEach(t=>t())},subscribe:t=>(o.add(t),()=>o.delete(t)),emit:(t,e)=>c.emit(t,e,n),on:(t,e)=>c.on(t,e,n),watch:(t,e,n)=>function(t,e,n,r,o=Object.is){const c=a(n,o);let u=!1;const l=()=>{u||r(c(t()))};l();const s=e(l);return()=>{u=!0,s()}}(()=>r,t=>(o.add(t),()=>o.delete(t)),t,e,n)}},exports.effect=l,exports.factoryAtom=function(t){const e=new Map;return n=>{let r=e.get(n);return r||(r=t(n),e.set(n,r)),r}},exports.scheduleReactJob=function(t,n="normal"){"low"===n?e.startTransition(t):t()},exports.selectAtom=function(t,e,n,r){var o;const c=null!==(o=null==r?void 0:r.isEqual)&&void 0!==o?o:Object.is;let u;return l(()=>{const o=e(t());void 0!==u&&c(u,o)||(u=o,((null==r?void 0:r.immediate)||void 0!==u)&&n(o))})},exports.useAtom=f,exports.useAtomSelector=function(t,e,n=Object.is){const o=r.useRef(null),c=()=>{const r=e(t()),c=o.current;return null!==c&&n(c,r)?c:(o.current=r,r)};return r.useSyncExternalStore(e=>l(()=>{t(),e()}),c,c)},exports.useBatch=function(){return t.batch},exports.useComputed=function(t){return f(r.useMemo(()=>u(t),[t]))},exports.useEffectReact=function(t,e="normal"){r.useEffect(()=>{const n=l(t,e);return()=>n()},[t,e])},exports.useFactoryAtom=function(t,e){return f(t(e))},exports.useStore=function(t){return e.useSyncExternalStore(t.subscribe,t.state,t.state)},exports.useStoreSelector=function(t,e,n=Object.is){const o=r.useMemo(()=>a(e,n),[e,n]),c=r.useCallback(()=>o(t.state()),[t,o]);return r.useSyncExternalStore(t.subscribe,c,c)},exports.useWatch=function(t,e){r.useEffect(()=>{const n=s(t,e);return()=>null==n?void 0:n()},[t,e])},exports.watch=s;
1
+ "use strict";var e=require("intentx-core-z"),t=require("react");function r(e){var t=Object.create(null);return e&&Object.keys(e).forEach(function(r){if("default"!==r){var n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:function(){return e[r]}})}}),t.default=e,Object.freeze(t)}var n=r(t);function o(e){return function(t,r){const n=e(t),o=n.set;return n.set=(e,t="normal")=>{const s=n(),c=r?r(e,s):e;o(c,t)},n.update=(e,t="normal")=>{n.set(e(n()),t)},n}}function s(e){const t=o(e);return function(e,r){var n;const o=null!==(n=null==r?void 0:r.equals)&&void 0!==n?n:Object.is;return t(e,(e,t)=>o(e,t)?t:e)}}function c(e){const t=o(e);return function(e,r){return t(e,r)}}const u=s(e.signal),a=c(e.signal);function i(t,r){var n,o;const s=null!==(n=null==r?void 0:r.suspense)&&void 0!==n&&n,c=null!==(o=null==r?void 0:r.priority)&&void 0!==o?o:"normal",a=u({status:"idle"});let i=null;const l=()=>{const e=a();if("loading"===e.status)return e.promise;null==i||i.abort(),i=new AbortController;const r=t(i.signal).then(e=>(a.set({status:"success",data:e},c),e)).catch(e=>{if("AbortError"===(null==e?void 0:e.name))return Promise.resolve(void 0);throw a.set({status:"error",error:e}),e});return a.set({status:"loading",promise:r},c),r},f=()=>{null==i||i.abort()};return{read:()=>{const e=a();switch(e.status){case"success":return e.data;case"error":if(s)throw e.error;return;case"loading":if(s)throw e.promise;return;case"idle":const t=l();if(s)throw t;return}},load:l,cancel:f,invalidate:(t=c)=>{f(),a.set({status:"idle"},t),e.schedule(l,t)},status:()=>a().status,error:()=>"error"===a().status?a().error:void 0,setSuccess:(e,t=c)=>{a.set({status:"success",data:e},t)}}}function l(t,r,n){const{immediate:o=!1,equals:s=Object.is,priority:c="normal"}=null!=n?n:{};let u,a,i=!1;const l=e.effect(()=>{const e=t();if(!i)return i=!0,o&&f(e,u),void(u=e);s(e,u)||(f(e,u),u=e)},c);function f(e,t){const n=a;a=void 0,null==n||n(),r(e,t,e=>{a=e})}return()=>{null==a||a(),l()}}function f(e,t=Object.is){let r,n=!1;return o=>{const s=e(o);return n&&t(r,s)?r:(n=!0,r=s,s)}}function d(e,t,r,n,o=Object.is){const s=f(r,o);let c=!1;const u=()=>{c||n(s(e()))};u();const a=t(u);return()=>{c=!0,a()}}const p=e.createScope("default");function m(t){return n.useSyncExternalStore(r=>e.effect(()=>{t(),r()}),t,t)}Object.defineProperty(exports,"computed",{enumerable:!0,get:function(){return e.computed}}),Object.defineProperty(exports,"createScope",{enumerable:!0,get:function(){return e.createScope}}),Object.defineProperty(exports,"effect",{enumerable:!0,get:function(){return e.effect}}),Object.defineProperty(exports,"transaction",{enumerable:!0,get:function(){return e.batch}}),exports.asyncAtom=function(e,t){const r=i(e,t),n=()=>r.read();return n.load=r.load,n.cancel=r.cancel,n.invalidate=r.invalidate,n.status=r.status,n.error=r.error,n.setSuccess=e=>r.setSuccess(e),n},exports.asyncComputed=function(e,t="normal"){const r=i(e,{suspense:!0,priority:t}),n=()=>r.read();return n.invalidate=r.invalidate,n.status=r.status,n.error=r.error,n},exports.atom=u,exports.atomMiddleware=a,exports.createAtomFactory=s,exports.createAtomWithMiddlewareFactory=c,exports.createSelector=f,exports.createStore=function(t,r=p){let n=t;const o=new Set,s=e.createIntentBus((e,t)=>{const r=new AbortController;return{payload:e,scope:t,state:n,signal:r.signal,setState(e){e(n),o.forEach(e=>e())},emit:(e,r)=>s.emit(e,r,t)}});return{scope:r,state:()=>n,setState(e){e(n),o.forEach(e=>e())},subscribe:e=>(o.add(e),()=>o.delete(e)),emit:(e,t)=>s.emit(e,t,r),on:(e,t)=>s.on(e,t,r),watch:(e,t,r)=>d(()=>n,e=>(o.add(e),()=>o.delete(e)),e,t,r)}},exports.factoryAtom=function(e,t){var r;const n=null!==(r=null==t?void 0:t.weak)&&void 0!==r&&r,o=n?new WeakMap:new Map,s=t=>{const r=o.get(t);if(void 0!==r)return r;const n=e(t);return o.set(t,n),n};return s.delete=e=>{n||o.delete(e)},s.clear=()=>{n||o.clear()},s},exports.readonlyAtom=function(e){return()=>e()},exports.scheduleReactJob=function(e,r="normal"){"low"===r?t.startTransition(e):e()},exports.selectAtom=function(t,r,n,o){var s;const c=null!==(s=null==o?void 0:o.isEqual)&&void 0!==s?s:Object.is;let u;return e.effect(()=>{const e=r(t());void 0!==u&&c(u,e)||(u=e,((null==o?void 0:o.immediate)||void 0!==u)&&n(e))})},exports.useAtom=m,exports.useAtomSelector=function(r,n,o=Object.is){const s=t.useRef(f(n,o)),c=()=>s.current(r());return t.useSyncExternalStore(t=>e.effect(()=>{r(),t()}),c,c)},exports.useBatch=function(){return e.batch},exports.useComputed=function(t,r=[]){return m(n.useMemo(()=>e.computed(t),r))},exports.useEffectReact=function(t,r="normal"){const o=n.useRef(t);o.current=t,n.useEffect(()=>{const t=e.effect(()=>{o.current()},r);return()=>t()},[r])},exports.useFactoryAtom=function(e,t){const r=n.useRef(e);r.current=e;const o=n.useRef(null),s=n.useRef(null);return null!==o.current&&s.current===t||(o.current=r.current(t),s.current=t),m(o.current)},exports.useStore=function(e){return t.useSyncExternalStore(e.subscribe,e.state,e.state)},exports.useStoreSelector=function(e,t,r=Object.is){const o=n.useRef(t);o.current=t;const s=n.useRef(f(e=>o.current(e),r)),c=n.useCallback(()=>s.current(e.state()),[e]);return n.useSyncExternalStore(e.subscribe,c,c)},exports.useWatch=function(e,t,r){const o=n.useRef(t);o.current=t;const s=n.useRef(r);s.current=r,n.useEffect(()=>{const t=l(e,e=>{o.current(e)},s.current);return()=>null==t?void 0:t()},[e])},exports.watch=l,exports.watchSelector=d;
package/build/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
- export { createScope, Scope } from "intentx-core-z";
1
+ export { createScope } from "intentx-core-z";
2
+ export type { Scope } from "intentx-core-z";
2
3
  export * from './core';
3
4
  export * from './react';
@@ -1 +1 @@
1
- import{schedule as t,createScope as n,createIntentBus as e,batch as r}from"intentx-core-z";export{createScope}from"intentx-core-z";import*as o from"react";import l,{startTransition as c}from"react";const u={activeEffect:null};function i(n){let e=n;const r=new Set,o=new Set,l=()=>(u.activeEffect&&o.add(u.activeEffect),e);return l.set=(n,l="normal")=>{Object.is(n,e)||(e=n,o.forEach(n=>t(n,l)),r.forEach(n=>t(n,l)))},l.subscribe=t=>(r.add(t),()=>r.delete(t)),l}function s(n){let e,r=!0;const o=new Set,l=()=>{r||(r=!0,o.forEach(n=>t(n)))};return()=>{if(u.activeEffect&&o.add(u.activeEffect),r){const t=u.activeEffect;u.activeEffect=l,e=n(),r=!1,u.activeEffect=t}return e}}function a(n){const e=i(null);let r=null,o=null;const l=()=>(r||(o=new AbortController,r=n(o.signal).then(t=>((null==o?void 0:o.signal.aborted)||e.set(t),t)).finally(()=>{r=null})),r),c=()=>{null==o||o.abort(),o=null,r=null},u=()=>{const t=e();if(null===t)throw l();return t};return u.set=e.set,u.load=l,u.cancel=c,u.invalidate=(n="normal")=>{c(),t(()=>{try{l()}catch{}},n)},u}function f(n,e="normal"){const r=i(void 0);let o=null,l=null,c=null;const u=()=>(o||(l=new AbortController,c=null,o=n(l.signal).then(t=>((null==l?void 0:l.signal.aborted)||r.set(t,e),t)).catch(t=>{throw(null==l?void 0:l.signal.aborted)||(c=t),t}).finally(()=>{o=null})),o),s=()=>{const t=r();if(c)throw c;if(void 0===t)throw u();return t};return s.invalidate=(n=e)=>{null==l||l.abort(),l=null,o=null,t(()=>{try{u()}catch{}},n)},s}function d(n,e="normal"){let r=null,o=!1;const l=()=>{if(!o){null==r||r();try{u.activeEffect=l;const t=n();"function"==typeof t&&(r=t)}finally{u.activeEffect=null}}};return t(l,e),()=>{o=!0,null==r||r(),r=null}}function b(t,n,e="normal"){return d(()=>{n(t())},e)}function v(t,n=Object.is){let e,r=!1;return o=>{const l=t(o);return r&&n(e,l)?e:(r=!0,e=l,l)}}function m(t,n,e,r){var o;const l=null!==(o=null==r?void 0:r.isEqual)&&void 0!==o?o:Object.is;let c;return d(()=>{const o=n(t());void 0!==c&&l(c,o)||(c=o,((null==r?void 0:r.immediate)||void 0!==c)&&e(o))})}const E=n("default");function h(t,n=E){let r=t;const o=new Set,l=e((t,n)=>{const e=new AbortController;return{payload:t,scope:n,state:r,signal:e.signal,setState(t){t(r),o.forEach(t=>t())},emit:(t,e)=>l.emit(t,e,n)}});return{scope:n,state:()=>r,setState(t){t(r),o.forEach(t=>t())},subscribe:t=>(o.add(t),()=>o.delete(t)),emit:(t,e)=>l.emit(t,e,n),on:(t,e)=>l.on(t,e,n),watch:(t,n,e)=>function(t,n,e,r,o=Object.is){const l=v(e,o);let c=!1;const u=()=>{c||r(l(t()))};u();const i=n(u);return()=>{c=!0,i()}}(()=>r,t=>(o.add(t),()=>o.delete(t)),t,n,e)}}function S(t){const n=new Map;return e=>{let r=n.get(e);return r||(r=t(e),n.set(e,r)),r}}function w(t){return o.useSyncExternalStore(n=>{let e=t();return d(()=>{const r=t();Object.is(e,r)||(e=r,n())})},t,t)}function y(t,n,e=Object.is){const r=o.useRef(null),l=()=>{const o=n(t()),l=r.current;return null!==l&&e(l,o)?l:(r.current=o,o)};return o.useSyncExternalStore(n=>d(()=>{t(),n()}),l,l)}function p(){return r}function g(t){return w(o.useMemo(()=>s(t),[t]))}function x(t,n="normal"){o.useEffect(()=>{const e=d(t,n);return()=>e()},[t,n])}function j(t,n){return w(t(n))}function O(t){return l.useSyncExternalStore(t.subscribe,t.state,t.state)}function C(t,n,e=Object.is){const r=o.useMemo(()=>v(n,e),[n,e]),l=o.useCallback(()=>r(t.state()),[t,r]);return o.useSyncExternalStore(t.subscribe,l,l)}function A(t,n){o.useEffect(()=>{const e=b(t,n);return()=>null==e?void 0:e()},[t,n])}function M(t,n="normal"){"low"===n?c(t):t()}export{a as asyncAtom,f as asyncComputed,i as atom,s as computed,v as createSelector,h as createStore,d as effect,S as factoryAtom,M as scheduleReactJob,m as selectAtom,w as useAtom,y as useAtomSelector,p as useBatch,g as useComputed,x as useEffectReact,j as useFactoryAtom,O as useStore,C as useStoreSelector,A as useWatch,b as watch};
1
+ import{signal as t,schedule as e,effect as n,createScope as r,createIntentBus as s,batch as o,computed as u}from"intentx-core-z";export{computed,createScope,effect,batch as transaction}from"intentx-core-z";import*as c from"react";import i,{startTransition as a}from"react";function l(t){return function(e,n){const r=t(e),s=r.set;return r.set=(t,e="normal")=>{const o=r(),u=n?n(t,o):t;s(u,e)},r.update=(t,e="normal")=>{r.set(t(r()),e)},r}}function f(t){const e=l(t);return function(t,n){var r;const s=null!==(r=null==n?void 0:n.equals)&&void 0!==r?r:Object.is;return e(t,(t,e)=>s(t,e)?e:t)}}function d(t){const e=l(t);return function(t,n){return e(t,n)}}const v=f(t),m=d(t);function p(t){return()=>t()}function b(t,n){var r,s;const o=null!==(r=null==n?void 0:n.suspense)&&void 0!==r&&r,u=null!==(s=null==n?void 0:n.priority)&&void 0!==s?s:"normal",c=v({status:"idle"});let i=null;const a=()=>{const e=c();if("loading"===e.status)return e.promise;null==i||i.abort(),i=new AbortController;const n=t(i.signal).then(t=>(c.set({status:"success",data:t},u),t)).catch(t=>{if("AbortError"===(null==t?void 0:t.name))return Promise.resolve(void 0);throw c.set({status:"error",error:t}),t});return c.set({status:"loading",promise:n},u),n},l=()=>{null==i||i.abort()};return{read:()=>{const t=c();switch(t.status){case"success":return t.data;case"error":if(o)throw t.error;return;case"loading":if(o)throw t.promise;return;case"idle":const e=a();if(o)throw e;return}},load:a,cancel:l,invalidate:(t=u)=>{l(),c.set({status:"idle"},t),e(a,t)},status:()=>c().status,error:()=>"error"===c().status?c().error:void 0,setSuccess:(t,e=u)=>{c.set({status:"success",data:t},e)}}}function S(t,e="normal"){const n=b(t,{suspense:!0,priority:e}),r=()=>n.read();return r.invalidate=n.invalidate,r.status=n.status,r.error=n.error,r}function w(t,e){const n=b(t,e),r=()=>n.read();return r.load=n.load,r.cancel=n.cancel,r.invalidate=n.invalidate,r.status=n.status,r.error=n.error,r.setSuccess=t=>n.setSuccess(t),r}function h(t,e,r){const{immediate:s=!1,equals:o=Object.is,priority:u="normal"}=null!=r?r:{};let c,i,a=!1;const l=n(()=>{const e=t();if(!a)return a=!0,s&&f(e,c),void(c=e);o(e,c)||(f(e,c),c=e)},u);function f(t,n){const r=i;i=void 0,null==r||r(),e(t,n,t=>{i=t})}return()=>{null==i||i(),l()}}function E(t,e=Object.is){let n,r=!1;return s=>{const o=t(s);return r&&e(n,o)?n:(r=!0,n=o,o)}}function R(t,e,r,s){var o;const u=null!==(o=null==s?void 0:s.isEqual)&&void 0!==o?o:Object.is;let c;return n(()=>{const n=e(t());void 0!==c&&u(c,n)||(c=n,((null==s?void 0:s.immediate)||void 0!==c)&&r(n))})}function x(t,e,n,r,s=Object.is){const o=E(n,s);let u=!1;const c=()=>{u||r(o(t()))};c();const i=e(c);return()=>{u=!0,i()}}const y=r("default");function g(t,e=y){let n=t;const r=new Set,o=s((t,e)=>{const s=new AbortController;return{payload:t,scope:e,state:n,signal:s.signal,setState(t){t(n),r.forEach(t=>t())},emit:(t,n)=>o.emit(t,n,e)}});return{scope:e,state:()=>n,setState(t){t(n),r.forEach(t=>t())},subscribe:t=>(r.add(t),()=>r.delete(t)),emit:(t,n)=>o.emit(t,n,e),on:(t,n)=>o.on(t,n,e),watch:(t,e,s)=>x(()=>n,t=>(r.add(t),()=>r.delete(t)),t,e,s)}}function j(t,e){var n;const r=null!==(n=null==e?void 0:e.weak)&&void 0!==n&&n,s=r?new WeakMap:new Map,o=e=>{const n=s.get(e);if(void 0!==n)return n;const r=t(e);return s.set(e,r),r};return o.delete=t=>{r||s.delete(t)},o.clear=()=>{r||s.clear()},o}function O(t){return c.useSyncExternalStore(e=>n(()=>{t(),e()}),t,t)}function k(t,e,r=Object.is){const s=i.useRef(E(e,r)),o=()=>s.current(t());return i.useSyncExternalStore(e=>n(()=>{t(),e()}),o,o)}function q(){return o}function A(t,e=[]){return O(c.useMemo(()=>u(t),e))}function C(t,e="normal"){const r=c.useRef(t);r.current=t,c.useEffect(()=>{const t=n(()=>{r.current()},e);return()=>t()},[e])}function M(t,e){const n=c.useRef(t);n.current=t;const r=c.useRef(null),s=c.useRef(null);return null!==r.current&&s.current===e||(r.current=n.current(e),s.current=e),O(r.current)}function z(t){return i.useSyncExternalStore(t.subscribe,t.state,t.state)}function P(t,e,n=Object.is){const r=c.useRef(e);r.current=e;const s=c.useRef(E(t=>r.current(t),n)),o=c.useCallback(()=>s.current(t.state()),[t]);return c.useSyncExternalStore(t.subscribe,o,o)}function W(t,e,n){const r=c.useRef(e);r.current=e;const s=c.useRef(n);s.current=n,c.useEffect(()=>{const e=h(t,t=>{r.current(t)},s.current);return()=>null==e?void 0:e()},[t])}function B(t,e="normal"){"low"===e?a(t):t()}export{w as asyncAtom,S as asyncComputed,v as atom,m as atomMiddleware,f as createAtomFactory,d as createAtomWithMiddlewareFactory,E as createSelector,g as createStore,j as factoryAtom,p as readonlyAtom,B as scheduleReactJob,R as selectAtom,O as useAtom,k as useAtomSelector,q as useBatch,A as useComputed,C as useEffectReact,M as useFactoryAtom,z as useStore,P as useStoreSelector,W as useWatch,h as watch,x as watchSelector};
@@ -1 +1,2 @@
1
- export declare function useComputed<T>(fn: () => T): T;
1
+ import * as React from 'react';
2
+ export declare function useComputed<T>(fn: () => T, deps?: React.DependencyList): T;
@@ -1 +1,2 @@
1
- export declare function useWatch<T>(getter: () => T, fn: (val: T) => void): void;
1
+ import type { WatchOptions } from "../core/watch";
2
+ export declare function useWatch<T>(getter: () => T, fn: (val: T) => void, options?: WatchOptions<T>): void;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "chrono-state-z",
3
- "version": "2.1.0",
4
- "description": "Intent-first, logic-centric reactive state runtime with atoms, computed, async state, effects, and deterministic scheduling. React-agnostic core.",
3
+ "version": "2.2.0",
4
+ "description": "A fine-grained, intent-driven reactive state runtime for building complex React logic outside components.",
5
5
  "license": "MIT",
6
6
  "author": "Delpi.Kye",
7
7
  "sideEffects": false,
@@ -9,25 +9,13 @@
9
9
  "main": "build/index.cjs.js",
10
10
  "module": "build/index.esm.js",
11
11
  "types": "build/index.d.ts",
12
-
13
12
  "exports": {
14
13
  ".": {
15
14
  "types": "./build/index.d.ts",
16
15
  "import": "./build/index.esm.js",
17
16
  "require": "./build/index.cjs.js"
18
- },
19
- "./react": {
20
- "types": "./build/react/index.d.ts",
21
- "import": "./build/react/index.esm.js",
22
- "require": "./build/react/index.cjs.js"
23
- },
24
- "./devtools": {
25
- "types": "./build/devtools/index.d.ts",
26
- "import": "./build/devtools/index.esm.js",
27
- "require": "./build/devtools/index.cjs.js"
28
17
  }
29
18
  },
30
-
31
19
  "files": [
32
20
  "build"
33
21
  ],
@@ -43,35 +31,33 @@
43
31
  "type": "git",
44
32
  "url": "https://github.com/delpikye-v/chrono-state.git"
45
33
  },
46
-
47
34
  "homepage": "https://github.com/delpikye-v/chrono-state",
48
-
49
35
  "bugs": {
50
36
  "url": "https://github.com/delpikye-v/chrono-state/issues"
51
37
  },
52
-
53
38
  "keywords": [
54
39
  "state-management",
40
+ "react-state",
55
41
  "reactive",
42
+ "fine-grained",
43
+ "signals",
56
44
  "atom",
57
45
  "computed",
58
46
  "async-state",
47
+ "scheduler",
48
+ "deterministic",
59
49
  "intent",
60
- "intent-first",
61
50
  "logic-first",
62
- "effects",
63
- "scheduler",
64
51
  "headless",
65
- "react",
66
52
  "react-hooks",
67
53
  "react-18"
68
54
  ],
69
-
70
55
  "peerDependencies": {
71
- "react": "^18.0.0",
72
- "intentx-core-z": "^2.1.0"
56
+ "react": ">=18"
57
+ },
58
+ "dependencies": {
59
+ "intentx-core-z": "^2.2.1"
73
60
  },
74
-
75
61
  "devDependencies": {
76
62
  "@rollup/plugin-commonjs": "^25.0.0",
77
63
  "@rollup/plugin-node-resolve": "^15.2.3",
@@ -1 +0,0 @@
1
- export declare function computed<T>(getter: () => T): () => T;
@@ -1,2 +0,0 @@
1
- import { Priority } from "intentx-core-z";
2
- export declare function effect(fn: () => void | (() => void), priority?: Priority): () => void;
@@ -1,3 +0,0 @@
1
- export declare const effectContext: {
2
- activeEffect: (() => void) | null;
3
- };
@@ -1,22 +0,0 @@
1
- export type NodeType = 'atom' | 'computed' | 'effect';
2
- export type GraphNode = {
3
- id: number;
4
- name?: string;
5
- type: NodeType;
6
- value?: any;
7
- deps: Set<number>;
8
- highlighted?: boolean;
9
- };
10
- export type GraphSnapshotNode = {
11
- id: number;
12
- name?: string;
13
- type: NodeType;
14
- value?: any;
15
- deps: number[];
16
- highlighted?: boolean;
17
- };
18
- export declare function trackNode(type: NodeType, name?: string, value?: any): GraphNode;
19
- export declare function linkNodes(from: GraphNode, to: GraphNode): void;
20
- export declare function getGraphSnapshot(): GraphSnapshotNode[];
21
- export declare function highlightNode(id: number): void;
22
- export declare function clearHighlights(): void;
File without changes