@directive-run/react 0.1.1 → 0.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 +97 -7
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -9
- package/dist/index.d.ts +19 -9
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
# @directive-run/react
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@directive-run/react)
|
|
4
|
+
[](https://www.npmjs.com/package/@directive-run/react)
|
|
5
|
+
[](https://bundlephobia.com/package/@directive-run/react)
|
|
6
|
+
|
|
7
|
+
React hooks for [Directive](https://www.npmjs.com/package/@directive-run/core). Built on `useSyncExternalStore` for tear-free reads with concurrent rendering support.
|
|
4
8
|
|
|
5
9
|
## Install
|
|
6
10
|
|
|
@@ -8,12 +12,43 @@ React hooks for Directive. Provides `useSyncExternalStore`-based hooks for readi
|
|
|
8
12
|
npm install @directive-run/core @directive-run/react
|
|
9
13
|
```
|
|
10
14
|
|
|
11
|
-
##
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
Define a module in a shared file, then use it in any component:
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
// system.ts
|
|
21
|
+
import { createModule, createSystem, t } from "@directive-run/core";
|
|
22
|
+
|
|
23
|
+
const counter = createModule("counter", {
|
|
24
|
+
schema: {
|
|
25
|
+
facts: { count: t.number() },
|
|
26
|
+
derivations: { doubled: t.number() },
|
|
27
|
+
events: { increment: {}, decrement: {} },
|
|
28
|
+
requirements: {},
|
|
29
|
+
},
|
|
30
|
+
init: (facts) => {
|
|
31
|
+
facts.count = 0;
|
|
32
|
+
},
|
|
33
|
+
derive: {
|
|
34
|
+
doubled: (facts) => facts.count * 2,
|
|
35
|
+
},
|
|
36
|
+
events: {
|
|
37
|
+
increment: (facts) => { facts.count += 1; },
|
|
38
|
+
decrement: (facts) => { facts.count -= 1; },
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
export const system = createSystem({ module: counter });
|
|
43
|
+
system.start();
|
|
44
|
+
```
|
|
12
45
|
|
|
13
46
|
```tsx
|
|
47
|
+
// Counter.tsx
|
|
14
48
|
import { useFact, useDerived, useEvents } from "@directive-run/react";
|
|
49
|
+
import { system } from "./system";
|
|
15
50
|
|
|
16
|
-
function Counter(
|
|
51
|
+
export function Counter() {
|
|
17
52
|
const count = useFact(system, "count");
|
|
18
53
|
const doubled = useDerived(system, "doubled");
|
|
19
54
|
const events = useEvents(system);
|
|
@@ -22,22 +57,77 @@ function Counter({ system }) {
|
|
|
22
57
|
<div>
|
|
23
58
|
<p>Count: {count} (doubled: {doubled})</p>
|
|
24
59
|
<button onClick={() => events.increment()}>+</button>
|
|
60
|
+
<button onClick={() => events.decrement()}>−</button>
|
|
25
61
|
</div>
|
|
26
62
|
);
|
|
27
63
|
}
|
|
28
64
|
```
|
|
29
65
|
|
|
30
|
-
##
|
|
66
|
+
## useSelector
|
|
67
|
+
|
|
68
|
+
Auto-tracking selector over facts and derivations. Subscribes only to the keys your selector reads:
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
import { useSelector } from "@directive-run/react";
|
|
72
|
+
import { system } from "./system";
|
|
73
|
+
|
|
74
|
+
function Summary() {
|
|
75
|
+
const label = useSelector(system, (state) => {
|
|
76
|
+
return state.count > 10 ? "High" : "Low";
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
return <span>{label}</span>;
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## API Reference
|
|
84
|
+
|
|
85
|
+
### Core Hooks
|
|
86
|
+
|
|
87
|
+
| Hook | Return Type | Description |
|
|
88
|
+
|------|------------|-------------|
|
|
89
|
+
| `useFact(system, key)` | `T \| undefined` | Subscribe to a single fact value |
|
|
90
|
+
| `useFact(system, [keys])` | `Pick<Facts, K>` | Subscribe to multiple facts |
|
|
91
|
+
| `useDerived(system, key)` | `T` | Subscribe to a single derivation |
|
|
92
|
+
| `useDerived(system, [keys])` | `Pick<Derivations, K>` | Subscribe to multiple derivations |
|
|
93
|
+
| `useSelector(system, fn)` | `R` | Auto-tracking selector with optional equality function |
|
|
94
|
+
| `useEvents(system)` | `Events` | Memoized events dispatcher |
|
|
95
|
+
| `useDispatch(system)` | `(event) => void` | Low-level dispatch function |
|
|
96
|
+
|
|
97
|
+
### Advanced Hooks
|
|
31
98
|
|
|
32
|
-
|
|
99
|
+
| Hook | Return Type | Description |
|
|
100
|
+
|------|------------|-------------|
|
|
101
|
+
| `useWatch(system, key, cb)` | `void` | Side-effect on fact or derivation change (no re-render) |
|
|
102
|
+
| `useInspect(system)` | `InspectState` | Consolidated system state (isSettled, unmet, inflight) |
|
|
103
|
+
| `useRequirementStatus(plugin, type)` | `RequirementTypeStatus` | Requirement loading/error state |
|
|
104
|
+
| `useExplain(system, reqId)` | `string \| null` | Human-readable requirement explanation |
|
|
105
|
+
| `useConstraintStatus(system)` | `ConstraintInfo[]` | All constraint states |
|
|
106
|
+
| `useOptimisticUpdate(system)` | `{ mutate, isPending, error, rollback }` | Optimistic mutation with auto-rollback |
|
|
107
|
+
| `useTimeTravel(system)` | `TimeTravelState \| null` | Undo/redo navigation |
|
|
108
|
+
|
|
109
|
+
### React-Specific
|
|
110
|
+
|
|
111
|
+
| Export | Description |
|
|
112
|
+
|--------|-------------|
|
|
113
|
+
| `useDirective(module, options?)` | Scoped system with selected facts/derivations |
|
|
114
|
+
| `useDirectiveRef(module)` | Scoped system lifecycle (start on mount, destroy on unmount) |
|
|
115
|
+
| `useSuspenseRequirement(plugin, type)` | Suspense-compatible requirement status |
|
|
116
|
+
| `useHydratedSystem(module)` | Client-side system hydrated from server snapshot |
|
|
117
|
+
| `DirectiveDevTools` | Floating dev panel (tree-shaken in production) |
|
|
118
|
+
| `DirectiveHydrator` | SSR/RSC snapshot provider |
|
|
119
|
+
| `shallowEqual` | Shallow equality helper for selectors |
|
|
33
120
|
|
|
34
121
|
## Peer Dependencies
|
|
35
122
|
|
|
36
123
|
- `react >= 18`
|
|
37
124
|
- `@directive-run/core`
|
|
38
125
|
|
|
126
|
+
## Documentation
|
|
127
|
+
|
|
128
|
+
- [React Adapter Guide](https://directive.run/docs/adapters/react)
|
|
129
|
+
- [API Reference](https://directive.run/docs/api)
|
|
130
|
+
|
|
39
131
|
## License
|
|
40
132
|
|
|
41
133
|
MIT
|
|
42
|
-
|
|
43
|
-
[Full documentation](https://directive.run/docs)
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var react=require('react'),core=require('@directive-run/core'),adapterUtils=require('@directive-run/core/adapter-utils'),jsxRuntime=require('react/jsx-runtime');var M=Symbol("directive.uninitialized");function me(e,t){return adapterUtils.assertSystem("useFact",e),process.env.NODE_ENV!=="production"&&typeof t=="function"&&console.error("[Directive] useFact() received a function. Did you mean useSelector()? useFact() takes a string key or array of keys, not a selector function."),Array.isArray(t)?oe(e,t):se(e,t)}function se(e,t){process.env.NODE_ENV!=="production"&&(t in e.facts.$store.toObject()||console.warn(`[Directive] useFact("${t}") \u2014 fact not found in store. Check that "${t}" is defined in your module's schema.`));let r=react.useCallback(s=>e.facts.$store.subscribe([t],s),[e,t]),i=react.useCallback(()=>e.facts[t],[e,t]);return react.useSyncExternalStore(r,i,i)}function oe(e,t){let r=react.useRef(M),i=react.useCallback(o=>e.facts.$store.subscribe(t,o),[e,...t]),s=react.useCallback(()=>{let o={};for(let n of t)o[n]=e.facts[n];if(r.current!==M){let n=true;for(let u of t)if(!Object.is(r.current[u],o[u])){n=false;break}if(n)return r.current}return r.current=o,o},[e,...t]);return react.useSyncExternalStore(i,s,s)}function he(e,t){return adapterUtils.assertSystem("useDerived",e),process.env.NODE_ENV!=="production"&&typeof t=="function"&&console.error("[Directive] useDerived() received a function. Did you mean useSelector()? useDerived() takes a string key or array of keys, not a selector function."),Array.isArray(t)?ue(e,t):ie(e,t)}function ie(e,t){process.env.NODE_ENV!=="production"&&(t in e.derive||console.warn(`[Directive] useDerived("${t}") \u2014 derivation not found. Check that "${t}" is defined in your module's derive property.`));let r=react.useCallback(s=>e.subscribe([t],s),[e,t]),i=react.useCallback(()=>e.read(t),[e,t]);return react.useSyncExternalStore(r,i,i)}function ue(e,t){let r=react.useRef(M),i=react.useCallback(o=>e.subscribe(t,o),[e,...t]),s=react.useCallback(()=>{let o={};for(let n of t)o[n]=e.read(n);if(r.current!==M){let n=true;for(let u of t)if(!Object.is(r.current[u],o[u])){n=false;break}if(n)return r.current}return r.current=o,o},[e,...t]);return react.useSyncExternalStore(i,s,s)}function Re(e,t,r,i){let s,o=false,n;typeof r=="function"&&i===void 0?n=r:(r!==void 0&&(s=r,o=true),n=i??adapterUtils.defaultEquality),process.env.NODE_ENV!=="production"&&!e&&!o&&console.error("[Directive] useSelector() received a null/undefined system without a default value. Provide a default value as the 3rd parameter: useSelector(system, selector, defaultValue)");let u=react.useRef(t),l=react.useRef(n),S=react.useRef(s);u.current=t,l.current=n,S.current=s;let c=react.useRef([]),g=react.useRef([]),y=react.useRef(M),D=react.useRef([]),h=react.useMemo(()=>e?new Set(Object.keys(e.derive)):new Set,[e]),R=react.useCallback(()=>e?adapterUtils.runTrackedSelector(e,h,u.current):{value:S.current,factKeys:[],deriveKeys:[]},[e,h]),a=react.useCallback(b=>{if(!e)return ()=>{};let K=()=>{for(let p of D.current)p();D.current=[];let{factKeys:F,deriveKeys:T}=R();c.current=F,g.current=T,F.length>0?D.current.push(e.facts.$store.subscribe(F,()=>{let p=R();adapterUtils.depsChanged(c.current,p.factKeys,g.current,p.deriveKeys)&&K(),b();})):T.length===0&&D.current.push(e.facts.$store.subscribeAll(b)),T.length>0&&D.current.push(e.subscribe(T,()=>{let p=R();adapterUtils.depsChanged(c.current,p.factKeys,g.current,p.deriveKeys)&&K(),b();}));};return K(),()=>{for(let F of D.current)F();D.current=[];}},[e,R]),x=react.useCallback(()=>{let b;if(!e)b=S.current;else {let{value:K}=R();b=K===void 0&&o?S.current:K;}return y.current!==M&&l.current(y.current,b)?y.current:(y.current=b,b)},[R,e,o]);return react.useSyncExternalStore(a,x,x)}function xe(e){return adapterUtils.assertSystem("useDispatch",e),react.useCallback(t=>{e.dispatch(t);},[e])}function De(e,t,r,i){adapterUtils.assertSystem("useWatch",e);let s=t==="fact"&&typeof r=="string"&&typeof i=="function",o=s?r:t,n=s?i:r,u=react.useRef(n);u.current=n,react.useEffect(()=>e.watch(o,(l,S)=>{u.current(l,S);}),[e,o]);}function L(e,t){adapterUtils.assertSystem("useInspect",e);let r=ae(e),i=t?.throttleMs,[s,o]=react.useState(r),n=react.useRef(null);return react.useEffect(()=>{if(!i||i<=0){n.current?.cleanup(),n.current=null;return}return n.current?.cleanup(),n.current=adapterUtils.createThrottle((...u)=>{o(u[0]);},i),()=>{n.current?.cleanup(),n.current=null;}},[i]),react.useEffect(()=>{n.current&&n.current.throttled(r);},[r]),!i||i<=0?r:s}function ce(e){return adapterUtils.computeInspectState(e)}function ae(e){let t=react.useRef(null),r=react.useRef([]),i=react.useRef([]),s=react.useRef(null),o=react.useCallback(u=>{let l=e.facts.$store.subscribeAll(u),S=e.onSettledChange(u);return ()=>{l(),S();}},[e]),n=react.useCallback(()=>{let u=ce(e),l=u.unmet.length===r.current.length&&u.unmet.every((g,y)=>g.id===r.current[y]),S=u.inflight.length===i.current.length&&u.inflight.every((g,y)=>g.id===i.current[y]),c=u.isSettled===s.current;return l&&S&&c&&t.current?t.current:(t.current=u,r.current=u.unmet.map(g=>g.id),i.current=u.inflight.map(g=>g.id),s.current=u.isSettled,u)},[e]);return react.useSyncExternalStore(o,n,n)}function ke(e){adapterUtils.assertSystem("useTimeTravel",e);let t=react.useRef(null),r=react.useCallback(s=>e.onTimeTravelChange(s),[e]),i=react.useCallback(()=>{let s=adapterUtils.buildTimeTravelState(e);return s?(t.current&&t.current.canUndo===s.canUndo&&t.current.canRedo===s.canRedo&&t.current.currentIndex===s.currentIndex&&t.current.totalSnapshots===s.totalSnapshots&&t.current.isPaused===s.isPaused||(t.current=s),t.current):null},[e]);return react.useSyncExternalStore(r,i,i)}function Me(e,t){return Array.isArray(t)?de(e,t):le(e,t)}function le(e,t){let r=react.useRef(M),i=react.useCallback(o=>e.subscribe(o),[e]),s=react.useCallback(()=>{let o=e.getStatus(t);if(r.current!==M){let n=r.current;if(n.pending===o.pending&&n.inflight===o.inflight&&n.failed===o.failed&&n.isLoading===o.isLoading&&n.hasError===o.hasError&&n.lastError===o.lastError)return r.current}return r.current=o,o},[e,t]);return react.useSyncExternalStore(i,s,s)}function de(e,t){let r=react.useRef(null),i=react.useRef(""),s=react.useCallback(n=>e.subscribe(n),[e]),o=react.useCallback(()=>{let n={},u=[];for(let S of t){let c=e.getStatus(S);n[S]=c,u.push(`${S}:${c.pending}:${c.inflight}:${c.failed}:${c.hasError}:${c.lastError?.message??""}`);}let l=u.join("|");return l!==i.current&&(i.current=l,r.current=n),r.current??n},[e,...t]);return react.useSyncExternalStore(s,o,o)}var $=new WeakMap;function _(e){let t=$.get(e);return t||(t=new Map,$.set(e,t)),t}function Ie(e,t){return Array.isArray(t)?Se(e,t):fe(e,t)}function fe(e,t){let r=e.getStatus(t);if(r.hasError&&r.lastError)throw r.lastError;if(r.isLoading){let i=_(e),s=i.get(t);throw s||(s=new Promise(o=>{let n=e.subscribe(()=>{e.getStatus(t).isLoading||(i.delete(t),n(),o());});}),i.set(t,s)),s}return r}function Se(e,t){let r={},i=false,s=null;for(let o of t){let n=e.getStatus(o);r[o]=n,n.hasError&&n.lastError&&!s&&(s=n.lastError),n.isLoading&&(i=true);}if(s)throw s;if(i){let o=_(e),n=t.slice().sort().join(","),u=o.get(n);throw u||(u=new Promise(l=>{let S=e.subscribe(()=>{t.every(g=>!e.getStatus(g).isLoading)&&(o.delete(n),S(),l());});}),o.set(n,u)),u}return r}function B(e,t){let r=react.useRef(null),i=react.useRef(null),s=t?.status===true;if(!r.current){let o="id"in e&&"schema"in e,n=o?e:e.module,u=o?{}:e,l=t?.plugins??u.plugins??[],S=t?.debug??u.debug,c=t?.errorBoundary??u.errorBoundary,g=t?.tickMs??u.tickMs,y=t?.zeroConfig??u.zeroConfig,D=t?.initialFacts??u.initialFacts,h=[...l];s&&(i.current=core.createRequirementStatusPlugin(),h=[...h,i.current.plugin]),r.current=core.createSystem({module:n,plugins:h.length>0?h:void 0,debug:S,errorBoundary:c,tickMs:g,zeroConfig:y,initialFacts:D});}return react.useEffect(()=>{let o=r.current;return o?.start(),()=>{o?.destroy(),r.current=null,i.current=null;}},[]),s?{system:r.current,statusPlugin:i.current}:r.current}function we(e,t={}){let{facts:r,derived:i,status:s,...o}=t,n=r??[],u=i??[],l=n.length===0&&u.length===0,S=s?B(e,{status:true,...o}):B(e,o),c=s?S.system:S,g=s?S.statusPlugin:void 0,y=react.useMemo(()=>l?Object.keys(c.derive):[],[c,l]),D=react.useCallback(p=>{let I=[];return l?(I.push(c.facts.$store.subscribeAll(p)),y.length>0&&I.push(c.subscribe(y,p))):(n.length>0&&I.push(c.facts.$store.subscribe(n,p)),u.length>0&&I.push(c.subscribe(u,p))),()=>{for(let P of I)P();}},[c,l,...n,...u,...y]),h=react.useRef(M),R=react.useRef(M),a=react.useRef(null),x=react.useCallback(()=>{let p,I,P,N;if(l){p=c.facts.$store.toObject(),P=Object.keys(p),I={};for(let k of y)I[k]=c.read(k);N=y;}else {p={};for(let k of n)p[k]=c.facts[k];P=n,I={};for(let k of u)I[k]=c.read(k);N=u;}let C=h.current!==M;if(C){let k=h.current;if(Object.keys(k).length!==P.length)C=false;else for(let V of P)if(!Object.is(k[V],p[V])){C=false;break}}let q=R.current!==M;if(q){let k=R.current;if(Object.keys(k).length!==N.length)q=false;else for(let V of N)if(!Object.is(k[V],I[V])){q=false;break}}let z=C?h.current:p,H=q?R.current:I;return C||(h.current=p),q||(R.current=I),C&&q&&a.current||(a.current={facts:z,derived:H}),a.current},[c,l,...n,...u,...y]),b=react.useSyncExternalStore(D,x,x),K=react.useCallback(p=>c.dispatch(p),[c]),F=pe(c),T={system:c,dispatch:K,events:F,facts:b.facts,derived:b.derived};return s&&g?{...T,statusPlugin:g}:T}function Ke({system:e,position:t="bottom-right",defaultOpen:r=false}){let[i,s]=react.useState(r),o=react.useRef(null),{isSettled:n,unmet:u,inflight:l}=L(e);react.useEffect(()=>{i&&o.current&&o.current.focus();},[i]);let S=react.useCallback(a=>e.facts.$store.subscribeAll(a),[e]),c=react.useRef(M),g=react.useCallback(()=>{let a=e.facts.$store.toObject();if(c.current!==M){let x=Object.keys(c.current),b=Object.keys(a);if(x.length===b.length){let K=true;for(let F of b)if(!Object.is(c.current[F],a[F])){K=false;break}if(K)return c.current}}return c.current=a,a},[e]),y=react.useSyncExternalStore(S,g,g);if(process.env.NODE_ENV==="production")return null;let D={position:"fixed",zIndex:99999,...t.includes("bottom")?{bottom:12}:{top:12},...t.includes("right")?{right:12}:{left:12}};if(!i)return jsxRuntime.jsx("button",{type:"button",onClick:()=>s(true),"aria-label":`Open Directive DevTools${n?"":" (system working)"}`,"aria-expanded":false,style:{...D,background:"#1a1a2e",color:"#e0e0e0",border:"1px solid #333",borderRadius:6,padding:"6px 12px",cursor:"pointer",fontFamily:"monospace",fontSize:12},children:n?"Directive":"Directive..."});let h=Object.keys(e.derive),R={};for(let a of h)try{R[a]=e.read(a);}catch{R[a]="<error>";}return jsxRuntime.jsxs("div",{role:"region","aria-label":"Directive DevTools",tabIndex:-1,onKeyDown:a=>{a.key==="Escape"&&s(false);},style:{...D,background:"#1a1a2e",color:"#e0e0e0",border:"1px solid #333",borderRadius:8,padding:12,fontFamily:"monospace",fontSize:11,maxWidth:380,maxHeight:500,overflow:"auto",boxShadow:"0 4px 20px rgba(0,0,0,0.5)"},children:[jsxRuntime.jsxs("div",{style:{display:"flex",justifyContent:"space-between",marginBottom:8},children:[jsxRuntime.jsx("strong",{style:{color:"#7c8aff"},children:"Directive DevTools"}),jsxRuntime.jsx("button",{ref:o,type:"button",onClick:()=>s(false),"aria-label":"Close DevTools",style:{background:"none",border:"none",color:"#888",cursor:"pointer",fontSize:14},children:"\xD7"})]}),jsxRuntime.jsx("div",{style:{marginBottom:6},"aria-live":"polite",children:jsxRuntime.jsx("span",{style:{color:n?"#4ade80":"#fbbf24"},children:n?"Settled":"Working..."})}),jsxRuntime.jsxs("details",{open:true,children:[jsxRuntime.jsxs("summary",{style:{cursor:"pointer",color:"#7c8aff",marginBottom:4},children:["Facts (",Object.keys(y).length,")"]}),jsxRuntime.jsxs("table",{style:{width:"100%",borderCollapse:"collapse",fontSize:11},children:[jsxRuntime.jsx("thead",{children:jsxRuntime.jsxs("tr",{children:[jsxRuntime.jsx("th",{style:{textAlign:"left",padding:"2px 4px",color:"#7c8aff"},children:"Key"}),jsxRuntime.jsx("th",{style:{textAlign:"left",padding:"2px 4px",color:"#7c8aff"},children:"Value"})]})}),jsxRuntime.jsx("tbody",{children:Object.entries(y).map(([a,x])=>{let b;try{b=typeof x=="object"?JSON.stringify(x):String(x);}catch{b="<error>";}return jsxRuntime.jsxs("tr",{style:{borderBottom:"1px solid #2a2a4a"},children:[jsxRuntime.jsx("td",{style:{padding:"2px 4px",color:"#a0a0c0"},children:a}),jsxRuntime.jsx("td",{style:{padding:"2px 4px"},children:b})]},a)})})]})]}),h.length>0&&jsxRuntime.jsxs("details",{children:[jsxRuntime.jsxs("summary",{style:{cursor:"pointer",color:"#7c8aff",marginBottom:4},children:["Derivations (",h.length,")"]}),jsxRuntime.jsxs("table",{style:{width:"100%",borderCollapse:"collapse",fontSize:11},children:[jsxRuntime.jsx("thead",{children:jsxRuntime.jsxs("tr",{children:[jsxRuntime.jsx("th",{style:{textAlign:"left",padding:"2px 4px",color:"#7c8aff"},children:"Key"}),jsxRuntime.jsx("th",{style:{textAlign:"left",padding:"2px 4px",color:"#7c8aff"},children:"Value"})]})}),jsxRuntime.jsx("tbody",{children:Object.entries(R).map(([a,x])=>jsxRuntime.jsxs("tr",{style:{borderBottom:"1px solid #2a2a4a"},children:[jsxRuntime.jsx("td",{style:{padding:"2px 4px",color:"#a0a0c0"},children:a}),jsxRuntime.jsx("td",{style:{padding:"2px 4px"},children:typeof x=="object"?JSON.stringify(x):String(x)})]},a))})]})]}),l.length>0&&jsxRuntime.jsxs("details",{open:true,children:[jsxRuntime.jsxs("summary",{style:{cursor:"pointer",color:"#fbbf24",marginBottom:4},children:["Inflight (",l.length,")"]}),jsxRuntime.jsx("ul",{style:{margin:0,paddingLeft:16},children:l.map(a=>jsxRuntime.jsxs("li",{style:{fontSize:11},children:[a.resolverId," (",a.id,")"]},a.id))})]}),u.length>0&&jsxRuntime.jsxs("details",{open:true,children:[jsxRuntime.jsxs("summary",{style:{cursor:"pointer",color:"#f87171",marginBottom:4},children:["Unmet (",u.length,")"]}),jsxRuntime.jsx("ul",{style:{margin:0,paddingLeft:16},children:u.map(a=>jsxRuntime.jsxs("li",{style:{fontSize:11},children:[a.requirement.type," from ",a.fromConstraint]},a.id))})]})]})}function pe(e){return adapterUtils.assertSystem("useEvents",e),react.useMemo(()=>e.events,[e])}function Fe(e,t){adapterUtils.assertSystem("useExplain",e);let r=react.useCallback(s=>{let o=e.facts.$store.subscribeAll(s),n=e.onSettledChange(s);return ()=>{o(),n();}},[e]),i=react.useCallback(()=>e.explain(t),[e,t]);return react.useSyncExternalStore(r,i,i)}function Ee(e,t){adapterUtils.assertSystem("useConstraintStatus",e);let r=L(e);return react.useMemo(()=>{let i=e.inspect();return t?i.constraints.find(s=>s.id===t)??null:i.constraints},[e,t,r])}function Te(e,t,r){adapterUtils.assertSystem("useOptimisticUpdate",e);let[i,s]=react.useState(false),[o,n]=react.useState(null),u=react.useRef(null),l=react.useCallback(()=>{u.current&&(e.restore(u.current),u.current=null),s(false),n(null);},[e]),S=react.useCallback(c=>{u.current=e.getSnapshot(),s(true),n(null),e.batch(c);},[e]);return react.useEffect(()=>{if(!(!t||!r||!i))return t.subscribe(()=>{let c=t.getStatus(r);!c.isLoading&&!c.hasError?(u.current=null,s(false)):c.hasError&&(n(c.lastError),l());})},[t,r,i,l]),{mutate:S,isPending:i,error:o,rollback:l}}var W=react.createContext(null);function Pe({snapshot:e,children:t}){return jsxRuntime.jsx(W.Provider,{value:e,children:t})}function Ce(e,t){let r=react.useContext(W),i=react.useMemo(()=>r?.data?{...t??{},initialFacts:{...t?.initialFacts??{},...r.data}}:t??{},[r,t]);return B(e,i)}Object.defineProperty(exports,"shallowEqual",{enumerable:true,get:function(){return adapterUtils.shallowEqual}});exports.DirectiveDevTools=Ke;exports.DirectiveHydrator=Pe;exports.useConstraintStatus=Ee;exports.useDerived=he;exports.useDirective=we;exports.useDirectiveRef=B;exports.useDispatch=xe;exports.useEvents=pe;exports.useExplain=Fe;exports.useFact=me;exports.useHydratedSystem=Ce;exports.useInspect=L;exports.useOptimisticUpdate=Te;exports.useRequirementStatus=Me;exports.useSelector=Re;exports.useSuspenseRequirement=Ie;exports.useTimeTravel=ke;exports.useWatch=De;//# sourceMappingURL=index.cjs.map
|
|
1
|
+
'use strict';var react=require('react'),core=require('@directive-run/core'),adapterUtils=require('@directive-run/core/adapter-utils'),jsxRuntime=require('react/jsx-runtime');var k=Symbol("directive.uninitialized");function me(e,t){return adapterUtils.assertSystem("useFact",e),process.env.NODE_ENV!=="production"&&typeof t=="function"&&console.error("[Directive] useFact() received a function. Did you mean useSelector()? useFact() takes a string key or array of keys, not a selector function."),Array.isArray(t)?oe(e,t):se(e,t)}function se(e,t){process.env.NODE_ENV!=="production"&&(t in e.facts.$store.toObject()||console.warn(`[Directive] useFact("${t}") \u2014 fact not found in store. Check that "${t}" is defined in your module's schema.`));let r=react.useCallback(s=>e.facts.$store.subscribe([t],s),[e,t]),i=react.useCallback(()=>e.facts[t],[e,t]);return react.useSyncExternalStore(r,i,i)}function oe(e,t){let r=react.useRef(k),i=react.useCallback(o=>e.facts.$store.subscribe(t,o),[e,...t]),s=react.useCallback(()=>{let o={};for(let n of t)o[n]=e.facts[n];if(r.current!==k){let n=true;for(let u of t)if(!Object.is(r.current[u],o[u])){n=false;break}if(n)return r.current}return r.current=o,o},[e,...t]);return react.useSyncExternalStore(i,s,s)}function he(e,t){return adapterUtils.assertSystem("useDerived",e),process.env.NODE_ENV!=="production"&&typeof t=="function"&&console.error("[Directive] useDerived() received a function. Did you mean useSelector()? useDerived() takes a string key or array of keys, not a selector function."),Array.isArray(t)?ue(e,t):ie(e,t)}function ie(e,t){process.env.NODE_ENV!=="production"&&(t in e.derive||console.warn(`[Directive] useDerived("${t}") \u2014 derivation not found. Check that "${t}" is defined in your module's derive property.`));let r=react.useCallback(s=>e.subscribe([t],s),[e,t]),i=react.useCallback(()=>e.read(t),[e,t]);return react.useSyncExternalStore(r,i,i)}function ue(e,t){let r=react.useRef(k),i=react.useCallback(o=>e.subscribe(t,o),[e,...t]),s=react.useCallback(()=>{let o={};for(let n of t)o[n]=e.read(n);if(r.current!==k){let n=true;for(let u of t)if(!Object.is(r.current[u],o[u])){n=false;break}if(n)return r.current}return r.current=o,o},[e,...t]);return react.useSyncExternalStore(i,s,s)}function Re(e,t,r,i){let s,o=false,n=i??adapterUtils.defaultEquality;r!==void 0&&(s=r,o=true),process.env.NODE_ENV!=="production"&&!e&&!o&&console.error("[Directive] useSelector() received a null/undefined system without a default value. Provide a default value as the 3rd parameter: useSelector(system, selector, defaultValue)");let u=react.useRef(t),d=react.useRef(n),S=react.useRef(s);u.current=t,d.current=n,S.current=s;let c=react.useRef([]),g=react.useRef([]),y=react.useRef(k),D=react.useRef([]),h=react.useMemo(()=>e?new Set(Object.keys(e.derive)):new Set,[e]),R=react.useCallback(()=>e?adapterUtils.runTrackedSelector(e,h,u.current):{value:S.current,factKeys:[],deriveKeys:[]},[e,h]),a=react.useCallback(b=>{if(!e)return ()=>{};let K=()=>{for(let p of D.current)p();D.current=[];let{factKeys:F,deriveKeys:T}=R();c.current=F,g.current=T,F.length>0?D.current.push(e.facts.$store.subscribe(F,()=>{let p=R();adapterUtils.depsChanged(c.current,p.factKeys,g.current,p.deriveKeys)&&K(),b();})):T.length===0&&D.current.push(e.facts.$store.subscribeAll(b)),T.length>0&&D.current.push(e.subscribe(T,()=>{let p=R();adapterUtils.depsChanged(c.current,p.factKeys,g.current,p.deriveKeys)&&K(),b();}));};return K(),()=>{for(let F of D.current)F();D.current=[];}},[e,R]),x=react.useCallback(()=>{let b;if(!e)b=S.current;else {let{value:K}=R();b=K===void 0&&o?S.current:K;}return y.current!==k&&d.current(y.current,b)?y.current:(y.current=b,b)},[R,e,o]);return react.useSyncExternalStore(a,x,x)}function xe(e){return adapterUtils.assertSystem("useDispatch",e),react.useCallback(t=>{e.dispatch(t);},[e])}function De(e,t,r){adapterUtils.assertSystem("useWatch",e);let i=react.useRef(r);i.current=r,react.useEffect(()=>e.watch(t,(s,o)=>{i.current(s,o);}),[e,t]);}function L(e,t){adapterUtils.assertSystem("useInspect",e);let r=ae(e),i=t?.throttleMs,[s,o]=react.useState(r),n=react.useRef(null);return react.useEffect(()=>{if(!i||i<=0){n.current?.cleanup(),n.current=null;return}return n.current?.cleanup(),n.current=adapterUtils.createThrottle((...u)=>{o(u[0]);},i),()=>{n.current?.cleanup(),n.current=null;}},[i]),react.useEffect(()=>{n.current&&n.current.throttled(r);},[r]),!i||i<=0?r:s}function ce(e){return adapterUtils.computeInspectState(e)}function ae(e){let t=react.useRef(null),r=react.useRef([]),i=react.useRef([]),s=react.useRef(null),o=react.useCallback(u=>{let d=e.facts.$store.subscribeAll(u),S=e.onSettledChange(u);return ()=>{d(),S();}},[e]),n=react.useCallback(()=>{let u=ce(e),d=u.unmet.length===r.current.length&&u.unmet.every((g,y)=>g.id===r.current[y]),S=u.inflight.length===i.current.length&&u.inflight.every((g,y)=>g.id===i.current[y]),c=u.isSettled===s.current;return d&&S&&c&&t.current?t.current:(t.current=u,r.current=u.unmet.map(g=>g.id),i.current=u.inflight.map(g=>g.id),s.current=u.isSettled,u)},[e]);return react.useSyncExternalStore(o,n,n)}function Me(e){adapterUtils.assertSystem("useTimeTravel",e);let t=react.useRef(null),r=react.useCallback(s=>e.onTimeTravelChange(s),[e]),i=react.useCallback(()=>{let s=adapterUtils.buildTimeTravelState(e);return s?(t.current&&t.current.canUndo===s.canUndo&&t.current.canRedo===s.canRedo&&t.current.currentIndex===s.currentIndex&&t.current.totalSnapshots===s.totalSnapshots&&t.current.isPaused===s.isPaused||(t.current=s),t.current):null},[e]);return react.useSyncExternalStore(r,i,i)}function ke(e,t){return Array.isArray(t)?de(e,t):le(e,t)}function le(e,t){let r=react.useRef(k),i=react.useCallback(o=>e.subscribe(o),[e]),s=react.useCallback(()=>{let o=e.getStatus(t);if(r.current!==k){let n=r.current;if(n.pending===o.pending&&n.inflight===o.inflight&&n.failed===o.failed&&n.isLoading===o.isLoading&&n.hasError===o.hasError&&n.lastError===o.lastError)return r.current}return r.current=o,o},[e,t]);return react.useSyncExternalStore(i,s,s)}function de(e,t){let r=react.useRef(null),i=react.useRef(""),s=react.useCallback(n=>e.subscribe(n),[e]),o=react.useCallback(()=>{let n={},u=[];for(let S of t){let c=e.getStatus(S);n[S]=c,u.push(`${S}:${c.pending}:${c.inflight}:${c.failed}:${c.hasError}:${c.lastError?.message??""}`);}let d=u.join("|");return d!==i.current&&(i.current=d,r.current=n),r.current??n},[e,...t]);return react.useSyncExternalStore(s,o,o)}var $=new WeakMap;function _(e){let t=$.get(e);return t||(t=new Map,$.set(e,t)),t}function Ie(e,t){return Array.isArray(t)?Se(e,t):fe(e,t)}function fe(e,t){let r=e.getStatus(t);if(r.hasError&&r.lastError)throw r.lastError;if(r.isLoading){let i=_(e),s=i.get(t);throw s||(s=new Promise(o=>{let n=e.subscribe(()=>{e.getStatus(t).isLoading||(i.delete(t),n(),o());});}),i.set(t,s)),s}return r}function Se(e,t){let r={},i=false,s=null;for(let o of t){let n=e.getStatus(o);r[o]=n,n.hasError&&n.lastError&&!s&&(s=n.lastError),n.isLoading&&(i=true);}if(s)throw s;if(i){let o=_(e),n=t.slice().sort().join(","),u=o.get(n);throw u||(u=new Promise(d=>{let S=e.subscribe(()=>{t.every(g=>!e.getStatus(g).isLoading)&&(o.delete(n),S(),d());});}),o.set(n,u)),u}return r}function B(e,t){let r=react.useRef(null),i=react.useRef(null),s=t?.status===true;if(!r.current){let o="id"in e&&"schema"in e,n=o?e:e.module,u=o?{}:e,d=t?.plugins??u.plugins??[],S=t?.debug??u.debug,c=t?.errorBoundary??u.errorBoundary,g=t?.tickMs??u.tickMs,y=t?.zeroConfig??u.zeroConfig,D=t?.initialFacts??u.initialFacts,h=[...d];s&&(i.current=core.createRequirementStatusPlugin(),h=[...h,i.current.plugin]),r.current=core.createSystem({module:n,plugins:h.length>0?h:void 0,debug:S,errorBoundary:c,tickMs:g,zeroConfig:y,initialFacts:D});}return react.useEffect(()=>{let o=r.current;return o?.start(),()=>{o?.destroy(),r.current=null,i.current=null;}},[]),s?{system:r.current,statusPlugin:i.current}:r.current}function we(e,t={}){let{facts:r,derived:i,status:s,...o}=t,n=r??[],u=i??[],d=n.length===0&&u.length===0,S=s?B(e,{status:true,...o}):B(e,o),c=s?S.system:S,g=s?S.statusPlugin:void 0,y=react.useMemo(()=>d?Object.keys(c.derive):[],[c,d]),D=react.useCallback(p=>{let I=[];return d?(I.push(c.facts.$store.subscribeAll(p)),y.length>0&&I.push(c.subscribe(y,p))):(n.length>0&&I.push(c.facts.$store.subscribe(n,p)),u.length>0&&I.push(c.subscribe(u,p))),()=>{for(let P of I)P();}},[c,d,...n,...u,...y]),h=react.useRef(k),R=react.useRef(k),a=react.useRef(null),x=react.useCallback(()=>{let p,I,P,A;if(d){p=c.facts.$store.toObject(),P=Object.keys(p),I={};for(let M of y)I[M]=c.read(M);A=y;}else {p={};for(let M of n)p[M]=c.facts[M];P=n,I={};for(let M of u)I[M]=c.read(M);A=u;}let C=h.current!==k;if(C){let M=h.current;if(Object.keys(M).length!==P.length)C=false;else for(let U of P)if(!Object.is(M[U],p[U])){C=false;break}}let O=R.current!==k;if(O){let M=R.current;if(Object.keys(M).length!==A.length)O=false;else for(let U of A)if(!Object.is(M[U],I[U])){O=false;break}}let W=C?h.current:p,H=O?R.current:I;return C||(h.current=p),O||(R.current=I),C&&O&&a.current||(a.current={facts:W,derived:H}),a.current},[c,d,...n,...u,...y]),b=react.useSyncExternalStore(D,x,x),K=react.useCallback(p=>c.dispatch(p),[c]),F=pe(c),T={system:c,dispatch:K,events:F,facts:b.facts,derived:b.derived};return s&&g?{...T,statusPlugin:g}:T}function Ke({system:e,position:t="bottom-right",defaultOpen:r=false}){let[i,s]=react.useState(r),o=react.useRef(null),{isSettled:n,unmet:u,inflight:d}=L(e);react.useEffect(()=>{i&&o.current&&o.current.focus();},[i]);let S=react.useCallback(a=>e.facts.$store.subscribeAll(a),[e]),c=react.useRef(k),g=react.useCallback(()=>{let a=e.facts.$store.toObject();if(c.current!==k){let x=Object.keys(c.current),b=Object.keys(a);if(x.length===b.length){let K=true;for(let F of b)if(!Object.is(c.current[F],a[F])){K=false;break}if(K)return c.current}}return c.current=a,a},[e]),y=react.useSyncExternalStore(S,g,g);if(process.env.NODE_ENV==="production")return null;let D={position:"fixed",zIndex:99999,...t.includes("bottom")?{bottom:12}:{top:12},...t.includes("right")?{right:12}:{left:12}};if(!i)return jsxRuntime.jsx("button",{type:"button",onClick:()=>s(true),"aria-label":`Open Directive DevTools${n?"":" (system working)"}`,"aria-expanded":false,style:{...D,background:"#1a1a2e",color:"#e0e0e0",border:"1px solid #333",borderRadius:6,padding:"6px 12px",cursor:"pointer",fontFamily:"monospace",fontSize:12},children:n?"Directive":"Directive..."});let h=Object.keys(e.derive),R={};for(let a of h)try{R[a]=e.read(a);}catch{R[a]="<error>";}return jsxRuntime.jsxs("div",{role:"region","aria-label":"Directive DevTools",tabIndex:-1,onKeyDown:a=>{a.key==="Escape"&&s(false);},style:{...D,background:"#1a1a2e",color:"#e0e0e0",border:"1px solid #333",borderRadius:8,padding:12,fontFamily:"monospace",fontSize:11,maxWidth:380,maxHeight:500,overflow:"auto",boxShadow:"0 4px 20px rgba(0,0,0,0.5)"},children:[jsxRuntime.jsxs("div",{style:{display:"flex",justifyContent:"space-between",marginBottom:8},children:[jsxRuntime.jsx("strong",{style:{color:"#7c8aff"},children:"Directive DevTools"}),jsxRuntime.jsx("button",{ref:o,type:"button",onClick:()=>s(false),"aria-label":"Close DevTools",style:{background:"none",border:"none",color:"#888",cursor:"pointer",fontSize:14},children:"\xD7"})]}),jsxRuntime.jsx("div",{style:{marginBottom:6},"aria-live":"polite",children:jsxRuntime.jsx("span",{style:{color:n?"#4ade80":"#fbbf24"},children:n?"Settled":"Working..."})}),jsxRuntime.jsxs("details",{open:true,children:[jsxRuntime.jsxs("summary",{style:{cursor:"pointer",color:"#7c8aff",marginBottom:4},children:["Facts (",Object.keys(y).length,")"]}),jsxRuntime.jsxs("table",{style:{width:"100%",borderCollapse:"collapse",fontSize:11},children:[jsxRuntime.jsx("thead",{children:jsxRuntime.jsxs("tr",{children:[jsxRuntime.jsx("th",{style:{textAlign:"left",padding:"2px 4px",color:"#7c8aff"},children:"Key"}),jsxRuntime.jsx("th",{style:{textAlign:"left",padding:"2px 4px",color:"#7c8aff"},children:"Value"})]})}),jsxRuntime.jsx("tbody",{children:Object.entries(y).map(([a,x])=>{let b;try{b=typeof x=="object"?JSON.stringify(x):String(x);}catch{b="<error>";}return jsxRuntime.jsxs("tr",{style:{borderBottom:"1px solid #2a2a4a"},children:[jsxRuntime.jsx("td",{style:{padding:"2px 4px",color:"#a0a0c0"},children:a}),jsxRuntime.jsx("td",{style:{padding:"2px 4px"},children:b})]},a)})})]})]}),h.length>0&&jsxRuntime.jsxs("details",{children:[jsxRuntime.jsxs("summary",{style:{cursor:"pointer",color:"#7c8aff",marginBottom:4},children:["Derivations (",h.length,")"]}),jsxRuntime.jsxs("table",{style:{width:"100%",borderCollapse:"collapse",fontSize:11},children:[jsxRuntime.jsx("thead",{children:jsxRuntime.jsxs("tr",{children:[jsxRuntime.jsx("th",{style:{textAlign:"left",padding:"2px 4px",color:"#7c8aff"},children:"Key"}),jsxRuntime.jsx("th",{style:{textAlign:"left",padding:"2px 4px",color:"#7c8aff"},children:"Value"})]})}),jsxRuntime.jsx("tbody",{children:Object.entries(R).map(([a,x])=>jsxRuntime.jsxs("tr",{style:{borderBottom:"1px solid #2a2a4a"},children:[jsxRuntime.jsx("td",{style:{padding:"2px 4px",color:"#a0a0c0"},children:a}),jsxRuntime.jsx("td",{style:{padding:"2px 4px"},children:typeof x=="object"?JSON.stringify(x):String(x)})]},a))})]})]}),d.length>0&&jsxRuntime.jsxs("details",{open:true,children:[jsxRuntime.jsxs("summary",{style:{cursor:"pointer",color:"#fbbf24",marginBottom:4},children:["Inflight (",d.length,")"]}),jsxRuntime.jsx("ul",{style:{margin:0,paddingLeft:16},children:d.map(a=>jsxRuntime.jsxs("li",{style:{fontSize:11},children:[a.resolverId," (",a.id,")"]},a.id))})]}),u.length>0&&jsxRuntime.jsxs("details",{open:true,children:[jsxRuntime.jsxs("summary",{style:{cursor:"pointer",color:"#f87171",marginBottom:4},children:["Unmet (",u.length,")"]}),jsxRuntime.jsx("ul",{style:{margin:0,paddingLeft:16},children:u.map(a=>jsxRuntime.jsxs("li",{style:{fontSize:11},children:[a.requirement.type," from ",a.fromConstraint]},a.id))})]})]})}function pe(e){return adapterUtils.assertSystem("useEvents",e),react.useMemo(()=>e.events,[e])}function Fe(e,t){adapterUtils.assertSystem("useExplain",e);let r=react.useCallback(s=>{let o=e.facts.$store.subscribeAll(s),n=e.onSettledChange(s);return ()=>{o(),n();}},[e]),i=react.useCallback(()=>e.explain(t),[e,t]);return react.useSyncExternalStore(r,i,i)}function Ee(e,t){adapterUtils.assertSystem("useConstraintStatus",e);let r=L(e);return react.useMemo(()=>{let i=e.inspect();return t?i.constraints.find(s=>s.id===t)??null:i.constraints},[e,t,r])}function Te(e,t,r){adapterUtils.assertSystem("useOptimisticUpdate",e);let[i,s]=react.useState(false),[o,n]=react.useState(null),u=react.useRef(null),d=react.useCallback(()=>{u.current&&(e.restore(u.current),u.current=null),s(false),n(null);},[e]),S=react.useCallback(c=>{u.current=e.getSnapshot(),s(true),n(null),e.batch(c);},[e]);return react.useEffect(()=>{if(!(!t||!r||!i))return t.subscribe(()=>{let c=t.getStatus(r);!c.isLoading&&!c.hasError?(u.current=null,s(false)):c.hasError&&(n(c.lastError),d());})},[t,r,i,d]),{mutate:S,isPending:i,error:o,rollback:d}}var z=react.createContext(null);function Pe({snapshot:e,children:t}){return jsxRuntime.jsx(z.Provider,{value:e,children:t})}function Ce(e,t){let r=react.useContext(z),i=react.useMemo(()=>r?.data?{...t??{},initialFacts:{...t?.initialFacts??{},...r.data}}:t??{},[r,t]);return B(e,i)}Object.defineProperty(exports,"shallowEqual",{enumerable:true,get:function(){return adapterUtils.shallowEqual}});exports.DirectiveDevTools=Ke;exports.DirectiveHydrator=Pe;exports.useConstraintStatus=Ee;exports.useDerived=he;exports.useDirective=we;exports.useDirectiveRef=B;exports.useDispatch=xe;exports.useEvents=pe;exports.useExplain=Fe;exports.useFact=me;exports.useHydratedSystem=Ce;exports.useInspect=L;exports.useOptimisticUpdate=Te;exports.useRequirementStatus=ke;exports.useSelector=Re;exports.useSuspenseRequirement=Ie;exports.useTimeTravel=Me;exports.useWatch=De;//# sourceMappingURL=index.cjs.map
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|