logic-runtime-react-z 1.0.0 → 1.0.1

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
@@ -1,4 +1,4 @@
1
- ## 🔀 logic-runtime-react-z
1
+ ## ⚙️ logic-runtime-react-z
2
2
 
3
3
  [![NPM](https://img.shields.io/npm/v/logic-runtime-react-z.svg)](https://www.npmjs.com/package/logic-runtime-react-z)
4
4
  ![Downloads](https://img.shields.io/npm/dt/logic-runtime-react-z.svg)
@@ -156,12 +156,14 @@ const counterLogic = createLogic({
156
156
  },
157
157
 
158
158
  intents: bus => {
159
- bus.on("inc", ({ state, setState }) => {
159
+ bus.on("inc", ({ state, setState, emit }) => {
160
160
  // state is READONLY snapshot (read-only)
161
161
  // ❌ state.count++
162
162
  setState(s => {
163
163
  s.count += 1
164
164
  })
165
+
166
+ // emit("inc") ❌ no nested
165
167
  })
166
168
 
167
169
  // Intent handlers can be sync or async
@@ -314,13 +316,12 @@ runtime.devtools?.timeline.replay(runtime.emit)
314
316
  | `intents` | `(bus) => void` | Defines **business actions** (intent handlers). Intents describe behavior, not UI. |
315
317
  | `plugins` | `LogicPlugin<S, C>[]?` | Runtime extensions (devtools, logging, persistence, analytics, etc.). |
316
318
 
317
-
318
319
  ---
319
320
 
320
321
  ## 🔍 Comparison
321
322
 
322
- | Feature | logic-runtime-react-z | Redux | Zustand |
323
- | --------------- | ---------------------- | ----- | -------- |
323
+ | Feature | logic-runtime-react-z | Redux | Zustand |
324
+ | --------------- | ----------------------- | ----- | -------- |
324
325
  | No-hook UI | ✅ | ❌ | ❌ |
325
326
  | Intent-first | ✅ | ❌ | ❌ |
326
327
  | Async built-in | ✅ | ⚠️ | ⚠️ |
@@ -13,17 +13,8 @@ type ComposedLogic = {
13
13
  };
14
14
  export declare function composeLogic(...entries: ComposedLogic[]): {
15
15
  create(scope?: string): {
16
- /**
17
- * merged state
18
- */
19
16
  readonly state: any;
20
- /**
21
- * ASYNC emit
22
- */
23
17
  emit(intent: string, payload?: any): Promise<any[]>;
24
- /**
25
- * subscription fan-out
26
- */
27
18
  subscribe(fn: () => void): () => void;
28
19
  };
29
20
  };
@@ -1,14 +1,8 @@
1
1
  import { Timeline } from "./timeline";
2
- /**
3
- * Devtools public API
4
- */
5
2
  export type Devtools = {
6
3
  timeline: Timeline;
7
4
  wrap(runtime: RuntimeLike): void;
8
5
  };
9
- /**
10
- * Minimal runtime surface for devtools
11
- */
12
6
  type RuntimeLike = {
13
7
  scope: string;
14
8
  emit(intent: string, payload?: any): Promise<void>;
@@ -1,16 +1,7 @@
1
1
  import type { Effect } from "./types";
2
2
  export declare function composeEffects<W, R>(effects: Effect<W, R>[]): Effect<W, R>;
3
- /**
4
- * takeLatest
5
- */
6
3
  export declare function takeLatest<W, R>(): Effect<W, R>;
7
- /**
8
- * debounce
9
- */
10
4
  export declare function debounce<W, R>(ms: number): Effect<W, R>;
11
- /**
12
- * retry
13
- */
14
5
  export declare function retry<W, R>(count?: number): Effect<W, R>;
15
6
  export type EffectBuilder<W, R> = Effect<W, R> & {
16
7
  takeLatest(): EffectBuilder<W, R>;
@@ -1,11 +1,10 @@
1
1
  import type { IntentHandler, Effect } from "./types";
2
- export declare function createIntentBus<W extends object, // Writable State
3
- R extends object = W, // Read State (snapshot / derived)
4
- P = any>(scope: string): {
2
+ export declare function createIntentBus<W extends object, R extends object = W, P = any>(scope: string): {
5
3
  on: (intent: string, handler: IntentHandler<W, R, P>) => void;
6
4
  effect: (intent: string, fx: Effect<W, R, P>) => void;
7
5
  emit: (intent: string, payload: P, ctx: {
8
6
  getState: () => R;
9
7
  setState: (fn: (s: W) => void) => void;
8
+ emit: (intent: string, payload?: any) => Promise<void>;
10
9
  }) => Promise<void>;
11
10
  };
@@ -8,25 +8,10 @@ export type IntentRecord<S = any> = {
8
8
  readonly state: Readonly<S>;
9
9
  readonly timestamp: number;
10
10
  };
11
- /**
12
- * Unified emit function:
13
- * - sync emit → void
14
- * - async emit → Promise<void>
15
- */
16
11
  export type EmitFn = (intent: string, payload?: any) => void | Promise<void>;
17
12
  export type Timeline<S = any> = {
18
- /** immutable snapshot */
19
13
  readonly records: readonly IntentRecord<S>[];
20
- /** record one event */
21
14
  record(entry: Omit<IntentRecord<S>, "id">): void;
22
- /**
23
- * Replay intent records.
24
- *
25
- * ⚠️ Notes:
26
- * - only replays `type === "emit"`
27
- * - replay is sequential
28
- * - replay does NOT record new timeline entries
29
- */
30
15
  replay(emit: EmitFn, options?: {
31
16
  from?: number;
32
17
  to?: number;
@@ -1,24 +1,20 @@
1
1
  import type { Timeline } from "./timeline";
2
2
  export type Listener = () => void;
3
3
  export type EffectCtx<W = any, R = W, P = any> = {
4
- /** full snapshot: base + computed */
5
4
  state: Readonly<R>;
6
5
  payload: P;
7
6
  signal: AbortSignal;
8
7
  scope: string;
9
- /** only base state is mutable */
8
+ emit(intent: string, payload?: any): Promise<void>;
10
9
  setState: (fn: (s: W) => void) => void;
11
10
  };
12
11
  export type IntentHandler<W = any, R = W, P = any> = (ctx: EffectCtx<W, R, P>) => void | Promise<void>;
13
12
  export type Effect<W = any, R = W, P = any> = (next: IntentHandler<W, R, P>) => IntentHandler<W, R, P>;
14
13
  export type LogicRuntime<S extends object, C extends object = {}> = {
15
14
  scope: string;
16
- /** full snapshot */
17
15
  state(): Readonly<S & C>;
18
- /** base state only */
19
16
  setState(mutator: (s: S) => void): void;
20
17
  reset(): void;
21
- /** await full intent pipeline */
22
18
  emit(intent: string, payload?: any): Promise<void>;
23
19
  subscribe(fn: Listener): () => void;
24
20
  onIntent(intent: string, handler: IntentHandler<S, S & C>): void;
@@ -1 +1 @@
1
- "use strict";var t=require("react/jsx-runtime");function e(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 n,r,o=e(require("react"));function c(t){const e=new Map,n=new Map,r=new Map;return{on:function(t,n){const r=e.get(t)||[];r.push(n),e.set(t,r)},effect:function(t,e){const r=n.get(t)||[];r.push(e),n.set(t,r)},emit:async function(o,c,s){const a=(e=>`${t}:${e}`)(o),i=r.get(a);null==i||i.abort();const u=new AbortController;r.set(a,u);const l=e.get(o)||[],f=n.get(o)||[];for(const e of l){let n=e;for(let t=f.length-1;t>=0;t--)n=f[t](n);await n({state:s.getState(),payload:c,signal:u.signal,scope:t,setState:s.setState})}}}}function s(t){const e=function(){let t=0,e=[];return{get records(){return e.slice()},record:function(n){e.push({...n,id:++t,state:structuredClone(n.state)})},replay:async function(t,n){const{from:r=0,to:o=1/0,scope:c}=null!=n?n:{},s=e.filter(t=>"emit"===t.type&&t.id>=r&&t.id<=o&&(!c||t.scope===c));for(const e of s){const n=t(e.intent,e.payload);n instanceof Promise&&await n}},clear:function(){e=[],t=0}}}();return{timeline:e,wrap:function(){const n=t.emit.bind(t);t.emit=async(r,o)=>{e.record({type:"emit:start",intent:r,payload:o,scope:t.scope,state:t.state(),timestamp:Date.now()});try{await n(r,o)}finally{e.record({type:"emit:end",intent:r,payload:o,scope:t.scope,state:t.state(),timestamp:Date.now()})}}}}}let a=0;const i="production"!==(null===(r=null===(n=null===globalThis||void 0===globalThis?void 0:globalThis.process)||void 0===n?void 0:n.env)||void 0===r?void 0:r.NODE_ENV);const u=[],l=[];function f(){let t=null;return e=>async n=>(null==t||t.abort(),t=new AbortController,e({...n,signal:t.signal}))}function p(t){let e;return n=>r=>{clearTimeout(e),e=setTimeout(()=>n(r),t)}}function d(t=3){return e=>async n=>{let r;for(let o=0;o<t;o++)try{return await e(n)}catch(t){r=t}throw r}}exports.composeLogic=function(...t){return{create(e){const n=t.map(t=>{var n;if("logic"in t){const r=t.logic.create(null!==(n=t.namespace)&&void 0!==n?n:e);return{namespace:t.namespace,inst:r}}return{namespace:null,inst:t.create(e)}});return{get state(){const t={};for(const{namespace:e,inst:r}of n){const n=r.state();e?t[e]=n:Object.assign(t,n)}return t},async emit(t,e){const r=n.map(({inst:n})=>{var r;return null===(r=n.emit)||void 0===r?void 0:r.call(n,t,e)});return Promise.all(r.filter(Boolean))},subscribe(t){const e=n.map(e=>e.inst.subscribe(t));return()=>{e.forEach(t=>t())}}}}}},exports.createLogic=function(t){var e;const n=null!==(e=t.name)&&void 0!==e?e:"logic";return{create(e){var r,o;const f=null!=e?e:`${n}:${++a}`,p=structuredClone(t.state),d=function(t){let e=t;const n=new Set;return{getState:function(){return e},setState:function(t){const r=e,o=structuredClone(r);t(o),Object.is(r,o)||(e=o,n.forEach(t=>t()))},subscribe:function(t){return n.add(t),()=>n.delete(t)}}}(structuredClone(t.state)),m=function(){const t=new Map,e=new Map,n=new Map;return{compute:function(n,r,o){if(t.has(n))return t.get(n);const c=new Set,s=r({state:new Proxy(o,{get:(t,e,n)=>("string"==typeof e&&e in t&&c.add(e),Reflect.get(t,e,n))})});return t.set(n,s),e.set(n,c),s},invalidate:function(r){e.forEach((e,o)=>{var c;e.has(r)&&(t.delete(o),null===(c=n.get(o))||void 0===c||c.forEach(t=>t()))})},subscribe:function(t,e){var r;const o=null!==(r=n.get(t))&&void 0!==r?r:new Set;return o.add(e),n.set(t,o),()=>o.delete(e)},reset:function(){t.clear(),e.clear(),n.forEach(t=>{t.forEach(t=>t())})}}}(),g=c(f);null===(r=t.intents)||void 0===r||r.call(t,g);let b=null,v=null;function y(){const e=d.getState();if(e===b&&v)return v;const n={};var r;return t.computed&&(r=t.computed,Object.keys(r)).forEach(r=>{n[r]=m.compute(r,t.computed[r],e)}),b=e,v=Object.assign({},e,n),v}function h(t){const e=d.getState();d.setState(n=>{t(n);for(const t in n)e[t]!==n[t]&&m.invalidate(t)})}const w={scope:f,state:()=>y(),setState:h,reset(){!function(){var t;d.setState(()=>structuredClone(p)),null===(t=m.reset)||void 0===t||t.call(m),b=null,v=null}()},async emit(t,e){const n=y();u.forEach(r=>r({intent:t,payload:e,state:n,scope:f}));try{await g.emit(t,e,{getState:y,setState:h})}finally{l.forEach(n=>n({intent:t,payload:e,state:y(),scope:f}))}},subscribe:d.subscribe,onIntent(t,e){g.on(t,e)},__internal:{onEmitStart(t){u.push(t)},onEmitEnd(t){l.push(t)}}};let S;return null===(o=t.plugins)||void 0===o||o.forEach(t=>t.setup(w)),i&&(S=s(w),S.wrap(w)),{...w,devtools:S}}}},exports.createSelector=function(t,e=Object.is){let n,r=null;return o=>{if(null!==r){const c=t(o);return e(n,c)?n:(n=c,r=o,c)}return r=o,n=t(o),n}},exports.createSignal=function(t){let e=t;const n=new Set;return{get:()=>e,set(t){Object.is(e,t)||(e=t,n.forEach(t=>t()))},subscribe:t=>(n.add(t),()=>n.delete(t))}},exports.debounce=p,exports.effect=function(t){const e=[t],n=t=>{return(n=e,t=>n.reduceRight((t,e)=>e(t),t))(t);var n};return n.takeLatest=()=>(e.push(f()),n),n.debounce=t=>(e.push(p(t)),n),n.retry=(t=3)=>(e.push(d(t)),n),n},exports.retry=d,exports.takeLatest=f,exports.withLogic=function(e,n){var r,c;const s=r=>{const c=o.useRef(null);c.current||(c.current=e.create());const s=c.current,a=o.useSyncExternalStore(s.subscribe,s.state,s.state),i=o.useCallback((t,e)=>s.emit(t,e),[s]);return t.jsx(n,{...r,state:a,emit:i})};return s.displayName=`withLogic(${null!==(c=null!==(r=n.displayName)&&void 0!==r?r:n.name)&&void 0!==c?c:"View"})`,s};
1
+ "use strict";var t=require("react/jsx-runtime");function e(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 n,r,o=e(require("react"));function c(t){const e=new Map,n=new Map,r=new Map;return{on:function(t,n){const r=e.get(t)||[];r.push(n),e.set(t,r)},effect:function(t,e){const r=n.get(t)||[];r.push(e),n.set(t,r)},emit:async function(o,c,s){const a=(e=>`${t}:${e}`)(o),i=r.get(a);null==i||i.abort();const u=new AbortController;r.set(a,u);const l=e.get(o)||[],f=n.get(o)||[];for(const e of l){let n=e;for(let t=f.length-1;t>=0;t--)n=f[t](n);await n({state:s.getState(),payload:c,signal:u.signal,scope:t,emit:s.emit,setState:s.setState})}}}}function s(t){const e=function(){let t=0,e=[];return{get records(){return e.slice()},record:function(n){e.push({...n,id:++t,state:structuredClone(n.state)})},replay:async function(t,n){const{from:r=0,to:o=1/0,scope:c}=null!=n?n:{},s=e.filter(t=>"emit"===t.type&&t.id>=r&&t.id<=o&&(!c||t.scope===c));for(const e of s){const n=t(e.intent,e.payload);n instanceof Promise&&await n}},clear:function(){e=[],t=0}}}();return{timeline:e,wrap:function(){const n=t.emit.bind(t);t.emit=async(r,o)=>{e.record({type:"emit:start",intent:r,payload:o,scope:t.scope,state:t.state(),timestamp:Date.now()});try{await n(r,o)}finally{e.record({type:"emit:end",intent:r,payload:o,scope:t.scope,state:t.state(),timestamp:Date.now()})}}}}}let a=0;const i="production"!==(null===(r=null===(n=null===globalThis||void 0===globalThis?void 0:globalThis.process)||void 0===n?void 0:n.env)||void 0===r?void 0:r.NODE_ENV);const u=[],l=[];function f(){let t=null;return e=>async n=>(null==t||t.abort(),t=new AbortController,e({...n,signal:t.signal}))}function p(t){let e;return n=>r=>{clearTimeout(e),e=setTimeout(()=>n(r),t)}}function d(t=3){return e=>async n=>{let r;for(let o=0;o<t;o++)try{return await e(n)}catch(t){r=t}throw r}}exports.composeLogic=function(...t){return{create(e){const n=t.map(t=>{var n;if("logic"in t){const r=t.logic.create(null!==(n=t.namespace)&&void 0!==n?n:e);return{namespace:t.namespace,inst:r}}return{namespace:null,inst:t.create(e)}});return{get state(){const t={};for(const{namespace:e,inst:r}of n){const n=r.state();e?t[e]=n:Object.assign(t,n)}return t},async emit(t,e){const r=n.map(({inst:n})=>{var r;return null===(r=n.emit)||void 0===r?void 0:r.call(n,t,e)});return Promise.all(r.filter(Boolean))},subscribe(t){const e=n.map(e=>e.inst.subscribe(t));return()=>{e.forEach(t=>t())}}}}}},exports.createLogic=function(t){var e;const n=null!==(e=t.name)&&void 0!==e?e:"logic";return{create(e){var r,o;const f=null!=e?e:`${n}:${++a}`,p=structuredClone(t.state),d=function(t){let e=t;const n=new Set;return{getState:function(){return e},setState:function(t){const r=e,o=structuredClone(r);t(o),Object.is(r,o)||(e=o,n.forEach(t=>t()))},subscribe:function(t){return n.add(t),()=>n.delete(t)}}}(structuredClone(t.state)),m=function(){const t=new Map,e=new Map,n=new Map;return{compute:function(n,r,o){if(t.has(n))return t.get(n);const c=new Set,s=r({state:new Proxy(o,{get:(t,e,n)=>("string"==typeof e&&e in t&&c.add(e),Reflect.get(t,e,n))})});return t.set(n,s),e.set(n,c),s},invalidate:function(r){e.forEach((e,o)=>{var c;e.has(r)&&(t.delete(o),null===(c=n.get(o))||void 0===c||c.forEach(t=>t()))})},subscribe:function(t,e){var r;const o=null!==(r=n.get(t))&&void 0!==r?r:new Set;return o.add(e),n.set(t,o),()=>o.delete(e)},reset:function(){t.clear(),e.clear(),n.forEach(t=>{t.forEach(t=>t())})}}}(),g=c(f);null===(r=t.intents)||void 0===r||r.call(t,g);let b=null,v=null;function y(){const e=d.getState();if(e===b&&v)return v;const n={};var r;return t.computed&&(r=t.computed,Object.keys(r)).forEach(r=>{n[r]=m.compute(r,t.computed[r],e)}),b=e,v=Object.assign({},e,n),v}function h(t){const e=d.getState();d.setState(n=>{t(n);for(const t in n)e[t]!==n[t]&&m.invalidate(t)})}const w={scope:f,state:()=>y(),setState:h,reset(){!function(){var t;d.setState(()=>structuredClone(p)),null===(t=m.reset)||void 0===t||t.call(m),b=null,v=null}()},async emit(t,e){const n=y();u.forEach(r=>r({intent:t,payload:e,state:n,scope:f}));try{await g.emit(t,e,{getState:y,setState:h,emit:w.emit})}finally{l.forEach(n=>n({intent:t,payload:e,state:y(),scope:f}))}},subscribe:d.subscribe,onIntent(t,e){g.on(t,e)},__internal:{onEmitStart(t){u.push(t)},onEmitEnd(t){l.push(t)}}};let S;return null===(o=t.plugins)||void 0===o||o.forEach(t=>t.setup(w)),i&&(S=s(w),S.wrap(w)),{...w,devtools:S}}}},exports.createSelector=function(t,e=Object.is){let n,r=null;return o=>{if(null!==r){const c=t(o);return e(n,c)?n:(n=c,r=o,c)}return r=o,n=t(o),n}},exports.createSignal=function(t){let e=t;const n=new Set;return{get:()=>e,set(t){Object.is(e,t)||(e=t,n.forEach(t=>t()))},subscribe:t=>(n.add(t),()=>n.delete(t))}},exports.debounce=p,exports.effect=function(t){const e=[t],n=t=>{return(n=e,t=>n.reduceRight((t,e)=>e(t),t))(t);var n};return n.takeLatest=()=>(e.push(f()),n),n.debounce=t=>(e.push(p(t)),n),n.retry=(t=3)=>(e.push(d(t)),n),n},exports.retry=d,exports.takeLatest=f,exports.withLogic=function(e,n){var r,c;const s=r=>{const c=o.useRef(null);c.current||(c.current=e.create());const s=c.current,a=o.useSyncExternalStore(s.subscribe,s.state,s.state),i=o.useCallback((t,e)=>s.emit(t,e),[s]);return t.jsx(n,{...r,state:a,emit:i})};return s.displayName=`withLogic(${null!==(c=null!==(r=n.displayName)&&void 0!==r?r:n.name)&&void 0!==c?c:"View"})`,s};
@@ -1 +1 @@
1
- import{jsx as t}from"react/jsx-runtime";import*as e from"react";function n(t){let e=t;const n=new Set;return{get:()=>e,set(t){Object.is(e,t)||(e=t,n.forEach(t=>t()))},subscribe:t=>(n.add(t),()=>n.delete(t))}}function o(t){const e=new Map,n=new Map,o=new Map;return{on:function(t,n){const o=e.get(t)||[];o.push(n),e.set(t,o)},effect:function(t,e){const o=n.get(t)||[];o.push(e),n.set(t,o)},emit:async function(r,s,c){const a=(e=>`${t}:${e}`)(r),i=o.get(a);null==i||i.abort();const u=new AbortController;o.set(a,u);const l=e.get(r)||[],f=n.get(r)||[];for(const e of l){let n=e;for(let t=f.length-1;t>=0;t--)n=f[t](n);await n({state:c.getState(),payload:s,signal:u.signal,scope:t,setState:c.setState})}}}}function r(t){const e=function(){let t=0,e=[];return{get records(){return e.slice()},record:function(n){e.push({...n,id:++t,state:structuredClone(n.state)})},replay:async function(t,n){const{from:o=0,to:r=1/0,scope:s}=null!=n?n:{},c=e.filter(t=>"emit"===t.type&&t.id>=o&&t.id<=r&&(!s||t.scope===s));for(const e of c){const n=t(e.intent,e.payload);n instanceof Promise&&await n}},clear:function(){e=[],t=0}}}();return{timeline:e,wrap:function(){const n=t.emit.bind(t);t.emit=async(o,r)=>{e.record({type:"emit:start",intent:o,payload:r,scope:t.scope,state:t.state(),timestamp:Date.now()});try{await n(o,r)}finally{e.record({type:"emit:end",intent:o,payload:r,scope:t.scope,state:t.state(),timestamp:Date.now()})}}}}}var s,c;let a=0;const i="production"!==(null===(c=null===(s=null===globalThis||void 0===globalThis?void 0:globalThis.process)||void 0===s?void 0:s.env)||void 0===c?void 0:c.NODE_ENV);const u=[],l=[];function f(t){var e;const n=null!==(e=t.name)&&void 0!==e?e:"logic";return{create(e){var s,c;const f=null!=e?e:`${n}:${++a}`,d=structuredClone(t.state),p=function(t){let e=t;const n=new Set;return{getState:function(){return e},setState:function(t){const o=e,r=structuredClone(o);t(r),Object.is(o,r)||(e=r,n.forEach(t=>t()))},subscribe:function(t){return n.add(t),()=>n.delete(t)}}}(structuredClone(t.state)),m=function(){const t=new Map,e=new Map,n=new Map;return{compute:function(n,o,r){if(t.has(n))return t.get(n);const s=new Set,c=o({state:new Proxy(r,{get:(t,e,n)=>("string"==typeof e&&e in t&&s.add(e),Reflect.get(t,e,n))})});return t.set(n,c),e.set(n,s),c},invalidate:function(o){e.forEach((e,r)=>{var s;e.has(o)&&(t.delete(r),null===(s=n.get(r))||void 0===s||s.forEach(t=>t()))})},subscribe:function(t,e){var o;const r=null!==(o=n.get(t))&&void 0!==o?o:new Set;return r.add(e),n.set(t,r),()=>r.delete(e)},reset:function(){t.clear(),e.clear(),n.forEach(t=>{t.forEach(t=>t())})}}}(),g=o(f);null===(s=t.intents)||void 0===s||s.call(t,g);let b=null,v=null;function h(){const e=p.getState();if(e===b&&v)return v;const n={};var o;return t.computed&&(o=t.computed,Object.keys(o)).forEach(o=>{n[o]=m.compute(o,t.computed[o],e)}),b=e,v=Object.assign({},e,n),v}function y(t){const e=p.getState();p.setState(n=>{t(n);for(const t in n)e[t]!==n[t]&&m.invalidate(t)})}const w={scope:f,state:()=>h(),setState:y,reset(){!function(){var t;p.setState(()=>structuredClone(d)),null===(t=m.reset)||void 0===t||t.call(m),b=null,v=null}()},async emit(t,e){const n=h();u.forEach(o=>o({intent:t,payload:e,state:n,scope:f}));try{await g.emit(t,e,{getState:h,setState:y})}finally{l.forEach(n=>n({intent:t,payload:e,state:h(),scope:f}))}},subscribe:p.subscribe,onIntent(t,e){g.on(t,e)},__internal:{onEmitStart(t){u.push(t)},onEmitEnd(t){l.push(t)}}};let S;return null===(c=t.plugins)||void 0===c||c.forEach(t=>t.setup(w)),i&&(S=r(w),S.wrap(w)),{...w,devtools:S}}}}function d(...t){return{create(e){const n=t.map(t=>{var n;if("logic"in t){const o=t.logic.create(null!==(n=t.namespace)&&void 0!==n?n:e);return{namespace:t.namespace,inst:o}}return{namespace:null,inst:t.create(e)}});return{get state(){const t={};for(const{namespace:e,inst:o}of n){const n=o.state();e?t[e]=n:Object.assign(t,n)}return t},async emit(t,e){const o=n.map(({inst:n})=>{var o;return null===(o=n.emit)||void 0===o?void 0:o.call(n,t,e)});return Promise.all(o.filter(Boolean))},subscribe(t){const e=n.map(e=>e.inst.subscribe(t));return()=>{e.forEach(t=>t())}}}}}}function p(){let t=null;return e=>async n=>(null==t||t.abort(),t=new AbortController,e({...n,signal:t.signal}))}function m(t){let e;return n=>o=>{clearTimeout(e),e=setTimeout(()=>n(o),t)}}function g(t=3){return e=>async n=>{let o;for(let r=0;r<t;r++)try{return await e(n)}catch(t){o=t}throw o}}function b(t){const e=[t],n=t=>{return(n=e,t=>n.reduceRight((t,e)=>e(t),t))(t);var n};return n.takeLatest=()=>(e.push(p()),n),n.debounce=t=>(e.push(m(t)),n),n.retry=(t=3)=>(e.push(g(t)),n),n}function v(t,e=Object.is){let n,o=null;return r=>{if(null!==o){const s=t(r);return e(n,s)?n:(n=s,o=r,s)}return o=r,n=t(r),n}}function h(n,o){var r,s;const c=r=>{const s=e.useRef(null);s.current||(s.current=n.create());const c=s.current,a=e.useSyncExternalStore(c.subscribe,c.state,c.state),i=e.useCallback((t,e)=>c.emit(t,e),[c]);return t(o,{...r,state:a,emit:i})};return c.displayName=`withLogic(${null!==(s=null!==(r=o.displayName)&&void 0!==r?r:o.name)&&void 0!==s?s:"View"})`,c}export{d as composeLogic,f as createLogic,v as createSelector,n as createSignal,m as debounce,b as effect,g as retry,p as takeLatest,h as withLogic};
1
+ import{jsx as t}from"react/jsx-runtime";import*as e from"react";function n(t){let e=t;const n=new Set;return{get:()=>e,set(t){Object.is(e,t)||(e=t,n.forEach(t=>t()))},subscribe:t=>(n.add(t),()=>n.delete(t))}}function o(t){const e=new Map,n=new Map,o=new Map;return{on:function(t,n){const o=e.get(t)||[];o.push(n),e.set(t,o)},effect:function(t,e){const o=n.get(t)||[];o.push(e),n.set(t,o)},emit:async function(r,s,c){const a=(e=>`${t}:${e}`)(r),i=o.get(a);null==i||i.abort();const u=new AbortController;o.set(a,u);const l=e.get(r)||[],f=n.get(r)||[];for(const e of l){let n=e;for(let t=f.length-1;t>=0;t--)n=f[t](n);await n({state:c.getState(),payload:s,signal:u.signal,scope:t,emit:c.emit,setState:c.setState})}}}}function r(t){const e=function(){let t=0,e=[];return{get records(){return e.slice()},record:function(n){e.push({...n,id:++t,state:structuredClone(n.state)})},replay:async function(t,n){const{from:o=0,to:r=1/0,scope:s}=null!=n?n:{},c=e.filter(t=>"emit"===t.type&&t.id>=o&&t.id<=r&&(!s||t.scope===s));for(const e of c){const n=t(e.intent,e.payload);n instanceof Promise&&await n}},clear:function(){e=[],t=0}}}();return{timeline:e,wrap:function(){const n=t.emit.bind(t);t.emit=async(o,r)=>{e.record({type:"emit:start",intent:o,payload:r,scope:t.scope,state:t.state(),timestamp:Date.now()});try{await n(o,r)}finally{e.record({type:"emit:end",intent:o,payload:r,scope:t.scope,state:t.state(),timestamp:Date.now()})}}}}}var s,c;let a=0;const i="production"!==(null===(c=null===(s=null===globalThis||void 0===globalThis?void 0:globalThis.process)||void 0===s?void 0:s.env)||void 0===c?void 0:c.NODE_ENV);const u=[],l=[];function f(t){var e;const n=null!==(e=t.name)&&void 0!==e?e:"logic";return{create(e){var s,c;const f=null!=e?e:`${n}:${++a}`,d=structuredClone(t.state),p=function(t){let e=t;const n=new Set;return{getState:function(){return e},setState:function(t){const o=e,r=structuredClone(o);t(r),Object.is(o,r)||(e=r,n.forEach(t=>t()))},subscribe:function(t){return n.add(t),()=>n.delete(t)}}}(structuredClone(t.state)),m=function(){const t=new Map,e=new Map,n=new Map;return{compute:function(n,o,r){if(t.has(n))return t.get(n);const s=new Set,c=o({state:new Proxy(r,{get:(t,e,n)=>("string"==typeof e&&e in t&&s.add(e),Reflect.get(t,e,n))})});return t.set(n,c),e.set(n,s),c},invalidate:function(o){e.forEach((e,r)=>{var s;e.has(o)&&(t.delete(r),null===(s=n.get(r))||void 0===s||s.forEach(t=>t()))})},subscribe:function(t,e){var o;const r=null!==(o=n.get(t))&&void 0!==o?o:new Set;return r.add(e),n.set(t,r),()=>r.delete(e)},reset:function(){t.clear(),e.clear(),n.forEach(t=>{t.forEach(t=>t())})}}}(),g=o(f);null===(s=t.intents)||void 0===s||s.call(t,g);let b=null,v=null;function h(){const e=p.getState();if(e===b&&v)return v;const n={};var o;return t.computed&&(o=t.computed,Object.keys(o)).forEach(o=>{n[o]=m.compute(o,t.computed[o],e)}),b=e,v=Object.assign({},e,n),v}function y(t){const e=p.getState();p.setState(n=>{t(n);for(const t in n)e[t]!==n[t]&&m.invalidate(t)})}const w={scope:f,state:()=>h(),setState:y,reset(){!function(){var t;p.setState(()=>structuredClone(d)),null===(t=m.reset)||void 0===t||t.call(m),b=null,v=null}()},async emit(t,e){const n=h();u.forEach(o=>o({intent:t,payload:e,state:n,scope:f}));try{await g.emit(t,e,{getState:h,setState:y,emit:w.emit})}finally{l.forEach(n=>n({intent:t,payload:e,state:h(),scope:f}))}},subscribe:p.subscribe,onIntent(t,e){g.on(t,e)},__internal:{onEmitStart(t){u.push(t)},onEmitEnd(t){l.push(t)}}};let S;return null===(c=t.plugins)||void 0===c||c.forEach(t=>t.setup(w)),i&&(S=r(w),S.wrap(w)),{...w,devtools:S}}}}function d(...t){return{create(e){const n=t.map(t=>{var n;if("logic"in t){const o=t.logic.create(null!==(n=t.namespace)&&void 0!==n?n:e);return{namespace:t.namespace,inst:o}}return{namespace:null,inst:t.create(e)}});return{get state(){const t={};for(const{namespace:e,inst:o}of n){const n=o.state();e?t[e]=n:Object.assign(t,n)}return t},async emit(t,e){const o=n.map(({inst:n})=>{var o;return null===(o=n.emit)||void 0===o?void 0:o.call(n,t,e)});return Promise.all(o.filter(Boolean))},subscribe(t){const e=n.map(e=>e.inst.subscribe(t));return()=>{e.forEach(t=>t())}}}}}}function p(){let t=null;return e=>async n=>(null==t||t.abort(),t=new AbortController,e({...n,signal:t.signal}))}function m(t){let e;return n=>o=>{clearTimeout(e),e=setTimeout(()=>n(o),t)}}function g(t=3){return e=>async n=>{let o;for(let r=0;r<t;r++)try{return await e(n)}catch(t){o=t}throw o}}function b(t){const e=[t],n=t=>{return(n=e,t=>n.reduceRight((t,e)=>e(t),t))(t);var n};return n.takeLatest=()=>(e.push(p()),n),n.debounce=t=>(e.push(m(t)),n),n.retry=(t=3)=>(e.push(g(t)),n),n}function v(t,e=Object.is){let n,o=null;return r=>{if(null!==o){const s=t(r);return e(n,s)?n:(n=s,o=r,s)}return o=r,n=t(r),n}}function h(n,o){var r,s;const c=r=>{const s=e.useRef(null);s.current||(s.current=n.create());const c=s.current,a=e.useSyncExternalStore(c.subscribe,c.state,c.state),i=e.useCallback((t,e)=>c.emit(t,e),[c]);return t(o,{...r,state:a,emit:i})};return c.displayName=`withLogic(${null!==(s=null!==(r=o.displayName)&&void 0!==r?r:o.name)&&void 0!==s?s:"View"})`,c}export{d as composeLogic,f as createLogic,v as createSelector,n as createSignal,m as debounce,b as effect,g as retry,p as takeLatest,h as withLogic};
@@ -1,8 +1,4 @@
1
1
  import * as React from "react";
2
- /**
3
- * Logic instance surface for React adapter
4
- * (matches LogicRuntime)
5
- */
6
2
  type LogicInstance<S> = {
7
3
  state(): Readonly<S>;
8
4
  emit(intent: string, payload?: any): Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "logic-runtime-react-z",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Intent-first runtime for React. No hooks. Deterministic state. Orchestrated effects.",
5
5
  "license": "MIT",
6
6
  "author": "Delpi.Kye",