logic-runtime-react-z 3.1.2 → 3.1.4
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 +164 -246
- package/build/index.cjs.js +1 -1
- package/build/index.d.ts +1 -5
- package/build/index.esm.js +1 -1
- package/build/logic/createLogic.d.ts +15 -10
- package/build/react/useLogic.d.ts +6 -4
- package/build/react/withLogic.d.ts +2 -1
- package/package.json +1 -11
- package/build/logic/composeLogic.d.ts +0 -21
- package/build/react/useActions.d.ts +0 -4
- package/build/react/useComputed.d.ts +0 -6
- package/build/react/useLogicSelector.d.ts +0 -2
- package/build/react/useRuntime.d.ts +0 -5
package/README.md
CHANGED
|
@@ -4,13 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
<a href="https://codesandbox.io/p/sandbox/jnd992" target="_blank">LIVE EXAMPLE</a>
|
|
6
6
|
|
|
7
|
-
**Intent-
|
|
7
|
+
**Intent-First Business Logic Runtime.**. React is a view layer. Business logic lives elsewhere.
|
|
8
8
|
|
|
9
|
-
A headless, deterministic, intent-driven runtime for frontend
|
|
10
|
-
React components stay pure. Business logic is fully testable, replayable, and framework-agnostic.
|
|
9
|
+
A headless, deterministic, intent-driven runtime for frontend and backend systems.
|
|
11
10
|
|
|
12
|
-
> **Intent is the only entry point.**
|
|
13
|
-
> **React is optional
|
|
11
|
+
> **Intent is the only entry point. Logic is deterministic.**
|
|
12
|
+
> **React is optional** — `createLogic` is the product; everything else is an adapter.
|
|
14
13
|
|
|
15
14
|
---
|
|
16
15
|
|
|
@@ -59,7 +58,7 @@ npm install logic-runtime-react-z
|
|
|
59
58
|
import { createLogic } from "logic-runtime-react-z"
|
|
60
59
|
|
|
61
60
|
const counterLogic = createLogic({
|
|
62
|
-
state: { count: 0 },
|
|
61
|
+
state: { count: 0, loading: false },
|
|
63
62
|
|
|
64
63
|
intents: bus => {
|
|
65
64
|
bus.on("inc", ({ setState }) => {
|
|
@@ -73,6 +72,28 @@ const counterLogic = createLogic({
|
|
|
73
72
|
s.count += payload
|
|
74
73
|
})
|
|
75
74
|
})
|
|
75
|
+
|
|
76
|
+
bus.on("dec", ({ setState }) => {
|
|
77
|
+
setState(s => {
|
|
78
|
+
s.count--
|
|
79
|
+
})
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
bus.on("asyncInc", async ({ setState }) => {
|
|
83
|
+
setState(s => { s.loading = true })
|
|
84
|
+
|
|
85
|
+
await new Promise(r => setTimeout(r, 1000))
|
|
86
|
+
|
|
87
|
+
setState(s => {
|
|
88
|
+
s.count++
|
|
89
|
+
s.loading = false
|
|
90
|
+
})
|
|
91
|
+
})
|
|
92
|
+
},
|
|
93
|
+
actions: {
|
|
94
|
+
add({ emit }) {
|
|
95
|
+
return (n: number) => emit("add", n)
|
|
96
|
+
}
|
|
76
97
|
},
|
|
77
98
|
})
|
|
78
99
|
|
|
@@ -111,124 +132,113 @@ computed: {
|
|
|
111
132
|
- Reading `state.count` automatically tracks dependencies.
|
|
112
133
|
- Computed values are cached and only re-evaluated when tracked dependencies change.
|
|
113
134
|
|
|
114
|
-
---
|
|
115
|
-
|
|
116
|
-
## ⚛️ React Integration (No Hooks Required)
|
|
117
135
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
```ts
|
|
121
|
-
// counter.logic.ts
|
|
122
|
-
import { createLogic, effect } from "logic-runtime-react-z"
|
|
136
|
+
---
|
|
123
137
|
|
|
124
|
-
|
|
125
|
-
name: "counter",
|
|
138
|
+
## ⚛️ React Integration
|
|
126
139
|
|
|
127
|
-
|
|
128
|
-
count: 1,
|
|
129
|
-
loading: false,
|
|
130
|
-
},
|
|
140
|
+
React is a thin adapter.
|
|
131
141
|
|
|
132
|
-
|
|
133
|
-
double: ({ state }) => state.count * 2,
|
|
134
|
-
triple: ({ state }) => state.count * 3,
|
|
135
|
-
},
|
|
142
|
+
You have **2 integration styles**:
|
|
136
143
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
setState(s => {
|
|
140
|
-
s.count++
|
|
141
|
-
})
|
|
142
|
-
})
|
|
143
|
-
|
|
144
|
-
bus.on<number>("add", ({ payload, setState }) => {
|
|
145
|
-
setState(s => {
|
|
146
|
-
s.count += payload
|
|
147
|
-
})
|
|
148
|
-
})
|
|
144
|
+
- `withLogic` → Recommended
|
|
145
|
+
- `useLogic` → Direct hook usage
|
|
149
146
|
|
|
150
|
-
|
|
151
|
-
setState(s => {
|
|
152
|
-
s.loading = true
|
|
153
|
-
})
|
|
147
|
+
#### 🧩 Option 1 — withLogic (Recommended)
|
|
154
148
|
|
|
155
|
-
|
|
149
|
+
Keeps view pure and declarative.
|
|
156
150
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
})
|
|
161
|
-
})
|
|
151
|
+
```tsx
|
|
152
|
+
import { withLogic, LogicViewProps } from "logic-runtime-react-z"
|
|
153
|
+
import { counterLogic } from "./counter.logic"
|
|
162
154
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
"inc-async",
|
|
166
|
-
effect(async ({ payload }) => {
|
|
167
|
-
console.log("effect run:", payload)
|
|
168
|
-
}).takeLatest()
|
|
169
|
-
)
|
|
170
|
-
},
|
|
155
|
+
type CounterInjected =
|
|
156
|
+
LogicViewProps<typeof counterLogic>
|
|
171
157
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
158
|
+
const CounterView = ({ state, actions, emit }: LogicViewProps) => {
|
|
159
|
+
// actions and emit => same emit
|
|
160
|
+
return (
|
|
161
|
+
<div>
|
|
162
|
+
<h2>Count: {state.count}</h2>
|
|
163
|
+
<p>Double: {state.double}</p>
|
|
164
|
+
<p>Triple: {state.triple}</p>
|
|
165
|
+
|
|
166
|
+
<button onClick={() => emit("inc")}>+</button>
|
|
167
|
+
<button onClick={() => emit("dec")}>-</button>
|
|
168
|
+
<button onClick={() => actions.add(10)}>+10 (action)</button>
|
|
169
|
+
<button onClick={() => emit("asyncInc")}>
|
|
170
|
+
{state.loading ? "Loading..." : "Async +"}
|
|
171
|
+
</button>
|
|
172
|
+
</div>
|
|
173
|
+
)
|
|
174
|
+
}
|
|
176
175
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
176
|
+
// export default withLogic(counterLogic)(CounterView)
|
|
177
|
+
export const CounterPage = withLogic(counterLogic, CounterView)
|
|
178
|
+
```
|
|
180
179
|
|
|
181
|
-
|
|
182
|
-
return (n: number) => emit("inc-async", n)
|
|
183
|
-
},
|
|
184
|
-
},
|
|
185
|
-
})
|
|
180
|
+
<b> Why this is recommended?</b>
|
|
186
181
|
|
|
187
|
-
|
|
182
|
+
- View is fully testable
|
|
183
|
+
- No hooks inside view
|
|
184
|
+
- Logic can be reused outside React
|
|
185
|
+
- Clear separation of concerns
|
|
188
186
|
|
|
189
187
|
---
|
|
190
188
|
|
|
191
|
-
|
|
189
|
+
#### 🪝 Option 2 — useLogic
|
|
190
|
+
|
|
191
|
+
Use directly inside a component.
|
|
192
192
|
|
|
193
193
|
```tsx
|
|
194
|
-
import
|
|
195
|
-
import { withLogic } from "logic-runtime-react-z"
|
|
194
|
+
import { useLogic } from "logic-runtime-react-z"
|
|
196
195
|
import { counterLogic } from "./counter.logic"
|
|
197
196
|
|
|
198
|
-
function
|
|
199
|
-
const { state, actions, emit } =
|
|
197
|
+
export function Counter() {
|
|
198
|
+
const { state, actions, emit } = useLogic(counterLogic)
|
|
200
199
|
|
|
201
200
|
return (
|
|
202
|
-
<div
|
|
203
|
-
<
|
|
204
|
-
|
|
205
|
-
<
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
<button
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
>
|
|
212
|
-
Async +5
|
|
213
|
-
</button>
|
|
214
|
-
|
|
215
|
-
<hr />
|
|
216
|
-
|
|
217
|
-
<button onClick={() => emit("inc")}>
|
|
218
|
-
emit("inc")
|
|
201
|
+
<div>
|
|
202
|
+
<h2>Count: {state.count}</h2>
|
|
203
|
+
<p>Double: {state.double}</p>
|
|
204
|
+
<p>Triple: {state.triple}</p>
|
|
205
|
+
|
|
206
|
+
<button onClick={() => emit("inc")}>+</button>
|
|
207
|
+
<button onClick={() => emit("dec")}>-</button>
|
|
208
|
+
<button onClick={() => emit("asyncInc")}>
|
|
209
|
+
{state.loading ? "Loading..." : "Async +"}
|
|
219
210
|
</button>
|
|
220
211
|
</div>
|
|
221
212
|
)
|
|
222
213
|
}
|
|
214
|
+
```
|
|
223
215
|
|
|
224
|
-
|
|
216
|
+
✔ Props are inferred when using useLogic, no manual generics required.
|
|
217
|
+
|
|
218
|
+
---
|
|
219
|
+
|
|
220
|
+
## 🌊 Async Support
|
|
221
|
+
|
|
222
|
+
Async logic is just another intent.
|
|
225
223
|
|
|
224
|
+
```ts
|
|
225
|
+
bus.on("fetchUser", async ({ setState }) => {
|
|
226
|
+
setState(s => { s.loading = true })
|
|
227
|
+
|
|
228
|
+
const data = await api.getUser()
|
|
229
|
+
|
|
230
|
+
setState(s => {
|
|
231
|
+
s.user = data
|
|
232
|
+
s.loading = false
|
|
233
|
+
})
|
|
234
|
+
})
|
|
226
235
|
```
|
|
227
236
|
|
|
228
|
-
|
|
237
|
+
No special async API needed.
|
|
229
238
|
|
|
230
239
|
---
|
|
231
240
|
|
|
241
|
+
|
|
232
242
|
## 🧪 Backend Usage (Same Runtime)
|
|
233
243
|
|
|
234
244
|
```ts
|
|
@@ -274,134 +284,12 @@ async function run() {
|
|
|
274
284
|
run()
|
|
275
285
|
```
|
|
276
286
|
|
|
277
|
-
✔ Same runtime, same behavior
|
|
278
|
-
✔ No React
|
|
279
|
-
✔ Replayable
|
|
287
|
+
✔ Same runtime, same behavior.
|
|
288
|
+
✔ No React dependency
|
|
289
|
+
✔ Replayable execution
|
|
280
290
|
|
|
281
291
|
---
|
|
282
292
|
|
|
283
|
-
## 🪝 Hooks Examples (Optional, Thin Adapters)
|
|
284
|
-
|
|
285
|
-
Hooks are optional convenience layers on top of the same logic runtime.
|
|
286
|
-
They do not own state, they only subscribe to it.
|
|
287
|
-
|
|
288
|
-
#### useRuntime – full snapshot
|
|
289
|
-
```ts
|
|
290
|
-
import { useRuntime } from "logic-runtime-react-z"
|
|
291
|
-
|
|
292
|
-
function Debug() {
|
|
293
|
-
const snapshot = useRuntime(counterLogic)
|
|
294
|
-
return <pre>{JSON.stringify(snapshot, null, 2)}</pre>
|
|
295
|
-
}
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
✔ Subscribes to full snapshot
|
|
299
|
-
✔ Includes state + computed
|
|
300
|
-
✔ Read-only
|
|
301
|
-
|
|
302
|
-
#### useActions – actions only (no re-render)
|
|
303
|
-
```ts
|
|
304
|
-
import { useActions } from "logic-runtime-react-z"
|
|
305
|
-
|
|
306
|
-
function Buttons() {
|
|
307
|
-
const actions = useActions(counterLogic)
|
|
308
|
-
|
|
309
|
-
return (
|
|
310
|
-
<>
|
|
311
|
-
<button onClick={actions.inc}>+1</button>
|
|
312
|
-
<button onClick={() => actions.add(5)}>+5</button>
|
|
313
|
-
</>
|
|
314
|
-
)
|
|
315
|
-
}
|
|
316
|
-
```
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
✔ No re-render on state change
|
|
320
|
-
✔ Fully inferred action types
|
|
321
|
-
✔ Ideal for buttons / handlers
|
|
322
|
-
|
|
323
|
-
#### useComputed – Subscribe to computed values
|
|
324
|
-
```ts
|
|
325
|
-
import { useComputed } from "logic-runtime-react-z"
|
|
326
|
-
|
|
327
|
-
function Stats() {
|
|
328
|
-
const { double, triple } = useComputed(counterLogic)
|
|
329
|
-
|
|
330
|
-
return (
|
|
331
|
-
<>
|
|
332
|
-
<div>Double: {double}</div>
|
|
333
|
-
<div>Triple: {triple}</div>
|
|
334
|
-
</>
|
|
335
|
-
)
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
function DoubleOnly() {
|
|
339
|
-
const double = useComputed(counterLogic, c => c.double)
|
|
340
|
-
return <div>{double}</div>
|
|
341
|
-
}
|
|
342
|
-
```
|
|
343
|
-
|
|
344
|
-
✔ Only derived data
|
|
345
|
-
✔ Cached & reactive
|
|
346
|
-
✔ No state mutation possible
|
|
347
|
-
|
|
348
|
-
#### useComputed with selector (recommended)
|
|
349
|
-
```ts
|
|
350
|
-
function DoubleOnly() {
|
|
351
|
-
const double = useComputed(
|
|
352
|
-
counterLogic,
|
|
353
|
-
c => c.double
|
|
354
|
-
)
|
|
355
|
-
|
|
356
|
-
return <div>Double: {double}</div>
|
|
357
|
-
}
|
|
358
|
-
```
|
|
359
|
-
|
|
360
|
-
✔ Component re-renders only when double changes
|
|
361
|
-
✔ No extra dependencies
|
|
362
|
-
✔ Type-safe selector
|
|
363
|
-
|
|
364
|
-
#### useLogicSelector – State selector (Redux-like)
|
|
365
|
-
```ts
|
|
366
|
-
import { useLogicSelector } from "logic-runtime-react-z"
|
|
367
|
-
|
|
368
|
-
function CountLabel() {
|
|
369
|
-
const count = useLogicSelector(
|
|
370
|
-
counterLogic,
|
|
371
|
-
state => state.count
|
|
372
|
-
)
|
|
373
|
-
|
|
374
|
-
return <span>{count}</span>
|
|
375
|
-
}
|
|
376
|
-
```
|
|
377
|
-
|
|
378
|
-
✔ Memoized selector
|
|
379
|
-
✔ Fine-grained subscriptions
|
|
380
|
-
✔ Familiar mental model
|
|
381
|
-
|
|
382
|
-
---
|
|
383
|
-
|
|
384
|
-
## 🧱 Composing Multiple Logic Modules
|
|
385
|
-
|
|
386
|
-
```ts
|
|
387
|
-
import { composeLogic } from "logic-runtime-react-z"
|
|
388
|
-
import { userLogic } from "./user.logic"
|
|
389
|
-
import { cartLogic } from "./cart.logic"
|
|
390
|
-
|
|
391
|
-
const app = composeLogic({
|
|
392
|
-
user: userLogic,
|
|
393
|
-
cart: cartLogic,
|
|
394
|
-
})
|
|
395
|
-
|
|
396
|
-
await app.emit("login")
|
|
397
|
-
|
|
398
|
-
const state = app.getState()
|
|
399
|
-
state.user
|
|
400
|
-
state.cart
|
|
401
|
-
|
|
402
|
-
```
|
|
403
|
-
|
|
404
|
-
---
|
|
405
293
|
|
|
406
294
|
## 🧪 Unit Test Example
|
|
407
295
|
|
|
@@ -422,55 +310,85 @@ const logic = createLogic({
|
|
|
422
310
|
},
|
|
423
311
|
})
|
|
424
312
|
|
|
425
|
-
const runtime =
|
|
313
|
+
const runtime = logic.create()
|
|
426
314
|
|
|
427
315
|
await runtime.emit("set", 4)
|
|
428
316
|
expect(runtime.computed.squared).toBe(16)
|
|
429
317
|
```
|
|
430
318
|
|
|
431
|
-
✔ Computed values are tested like plain data
|
|
432
|
-
|
|
433
319
|
---
|
|
434
320
|
|
|
435
321
|
## 🔍 Comparison
|
|
436
322
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
|
440
|
-
|
|
441
|
-
| **
|
|
442
|
-
| **
|
|
443
|
-
| **
|
|
444
|
-
| **
|
|
445
|
-
| **
|
|
446
|
-
| **
|
|
447
|
-
| **
|
|
448
|
-
| **
|
|
449
|
-
| **
|
|
450
|
-
| **
|
|
323
|
+
This is not about “better” — it's about architectural intent.
|
|
324
|
+
|
|
325
|
+
| Criteria | logic-runtime-react-z | Redux Toolkit | Zustand | Recoil | MobX |
|
|
326
|
+
|---------------------------------|------------------------------|----------------------|----------------|---------------|----------------|
|
|
327
|
+
| **Primary abstraction** | Intent runtime | Reducer store | Store | Atom graph | Observable |
|
|
328
|
+
| **Mental model** | Intent → Behavior → State | Action → Reducer | Mutate store | Atom graph | Reactive graph |
|
|
329
|
+
| **Single mutation entry** | ✅ | ✅ | ❌ | ❌ | ❌ |
|
|
330
|
+
| **Business logic isolation** | ✅ | ✅ | ⚠️ | ⚠️ | ⚠️ |
|
|
331
|
+
| **Built-in async orchestration**| ✅ | ⚠️ | ❌ | ❌ | ❌ |
|
|
332
|
+
| **Deterministic execution** | ✅ | ✅ | ⚠️ | ⚠️ | ⚠️ |
|
|
333
|
+
| **Derived state built-in** | ✅ | ❌ | ⚠️ | ✅ | ✅ |
|
|
334
|
+
| **Headless runtime** | ✅ | ⚠️ | ⚠️ | ❌ | ⚠️ |
|
|
335
|
+
| **Backend / worker ready** | ✅ | ⚠️ | ⚠️ | ❌ | ❌ |
|
|
336
|
+
| **Side-effect centralization** | ✅ | ⚠️ | ❌ | ❌ | ⚠️ |
|
|
337
|
+
| **Devtools maturity** | ⚠️ | ✅ | ⚠️ | ⚠️ | ⚠️ |
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
<br />
|
|
341
|
+
|
|
342
|
+
✅ Built-in / first-class
|
|
343
|
+
⚠️ Possible / usage-dependent
|
|
344
|
+
❌ Not built-in
|
|
451
345
|
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
### 🧠 Architectural Difference
|
|
349
|
+
|
|
350
|
+
Most state libraries focus on:
|
|
351
|
+
|
|
352
|
+
> **How state is stored and updated**
|
|
353
|
+
|
|
354
|
+
`logic-runtime-react-z` focuses on:
|
|
452
355
|
|
|
356
|
+
> **How behavior is orchestrated through intents**
|
|
453
357
|
|
|
454
|
-
|
|
358
|
+
Redux/Zustand answer:
|
|
359
|
+
> "Where is my state and how do I change it?"
|
|
360
|
+
|
|
361
|
+
This runtime answers:
|
|
362
|
+
> "What behavior is triggered by this event, and how should it execute?"
|
|
455
363
|
|
|
456
364
|
---
|
|
457
365
|
|
|
458
|
-
|
|
366
|
+
### 🧭 Positioning Summary
|
|
367
|
+
|
|
368
|
+
- Redux → Structured state container
|
|
369
|
+
- Zustand → Lightweight mutable store
|
|
370
|
+
- Recoil → Declarative dependency graph
|
|
371
|
+
- MobX → Reactive observable system
|
|
372
|
+
- **logic-runtime-react-z → Intent-first behavior runtime**
|
|
373
|
+
|
|
374
|
+
---
|
|
459
375
|
|
|
460
|
-
|
|
376
|
+
### 🎯 When This Makes Sense
|
|
461
377
|
|
|
462
|
-
|
|
378
|
+
Choose this if you need:
|
|
463
379
|
|
|
464
|
-
|
|
465
|
-
-
|
|
466
|
-
-
|
|
467
|
-
-
|
|
380
|
+
- Complex async flows
|
|
381
|
+
- Deterministic replayable behavior
|
|
382
|
+
- Logic shared between frontend & backend
|
|
383
|
+
- Strong separation between UI and domain behavior
|
|
384
|
+
- An explicit event-driven boundary
|
|
468
385
|
|
|
469
|
-
|
|
470
|
-
- async orchestration is built-in
|
|
471
|
-
- intent is the only entry point
|
|
472
|
-
- execution order is guaranteed
|
|
386
|
+
Choose simpler state tools if:
|
|
473
387
|
|
|
388
|
+
- You mostly manage UI state
|
|
389
|
+
- You don’t need orchestration
|
|
390
|
+
- Your async flows are trivial
|
|
391
|
+
- Your team prefers mutable patterns
|
|
474
392
|
|
|
475
393
|
---
|
|
476
394
|
|
|
@@ -485,7 +403,7 @@ In logic-runtime-react-z:
|
|
|
485
403
|
|
|
486
404
|
- Intents are processed sequentially
|
|
487
405
|
- State mutations are isolated
|
|
488
|
-
- Async effects follow declared strategies
|
|
406
|
+
- Async effects can follow declared execution strategies.
|
|
489
407
|
- Execution order is predictable
|
|
490
408
|
|
|
491
409
|
Given the same intent sequence, the resulting state is reproducible.
|
package/build/index.cjs.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var t=require("chrono-state-z"),e=require("intentx-core-z"),s=require("react/jsx-runtime")
|
|
1
|
+
"use strict";var t=require("chrono-state-z"),e=require("intentx-core-z"),s=require("react/jsx-runtime");function n(t){var e=Object.create(null);return t&&Object.keys(t).forEach(function(s){if("default"!==s){var n=Object.getOwnPropertyDescriptor(t,s);Object.defineProperty(e,s,n.get?n:{enumerable:!0,get:function(){return t[s]}})}}),e.default=t,Object.freeze(e)}var o=n(require("react"));class i{constructor(){this.handlers={},this.effects={},this.middlewares=[]}use(t){this.middlewares.push(t)}effect(t,e){var s,n;(null!==(s=(n=this.effects)[t])&&void 0!==s?s:n[t]=[]).push(e)}on(t,e){var s,n;const o=this.handlers[t];o&&o.length>0?console.warn(`[IntentBus] Duplicate intent handler "${t}" detected. Only the first handler will be used.`):(null!==(s=(n=this.handlers)[t])&&void 0!==s?s:n[t]=[]).push(e)}async emit(t,e){var s,n;const o=null!==(s=this.handlers[t])&&void 0!==s?s:[],i=null!==(n=this.effects[t])&&void 0!==n?n:[],r=(a=this.middlewares,c=async t=>{t.effects=i;for(const e of o)await e(t)},a.reduceRight((t,e)=>e(t),c));var a,c;await r(e)}}class r{constructor(t,s=e.createScope("logic")){this.computedAtoms={},this.subs=new Set,this.bus=new i,this.dirty=!0,this.isComputing=!1,this.computedKeys=new Set,this.markDirty=()=>{this.dirty=!0,this.subs.forEach(t=>t())},this.getSnapshot=()=>(this.dirty&&(this.snapshotCache=this.buildSnapshot(),this.dirty=!1),this.snapshotCache),this.subscribe=t=>(this.subs.add(t),()=>this.subs.delete(t)),this.onIntent=(t,e)=>{this.bus.on(t,e)},this.emit=async(t,e)=>{const s=new AbortController;await this.bus.emit(t,{payload:e,scope:this.scope,signal:s.signal,state:this.getSnapshot,setState:t=>this.setStateInternal(t),emit:this.emit})},this.scope=s,this.stateAtoms=this.createStateAtoms(t);for(const t in this.stateAtoms)this.stateAtoms[t].subscribe(this.markDirty);this.bus.use(function(){const t=new Map,e=new Map;return s=>async n=>{var o;const i=n.effects;if(!(null==i?void 0:i.length))return s(n);for(const s of i){const i=s.id;if("takeLatest"===s.strategy){null===(o=t.get(i))||void 0===o||o.abort();const e=new AbortController;t.set(i,e),await s.handler({...n,signal:e.signal})}else"debounce"===s.strategy?(clearTimeout(e.get(i)),e.set(i,setTimeout(()=>s.handler(n),s.wait))):await s.handler(n)}await s(n)}}())}createStateAtoms(e){const s={};for(const n in e)s[n]=t.atom(e[n]);return s}buildSnapshot(){const t={};for(const e in this.stateAtoms)t[e]=this.stateAtoms[e]();for(const e in this.computedAtoms)t[e]=this.computedAtoms[e]();return t}createReactiveState(){return new Proxy({},{get:(t,e)=>{const s=this.stateAtoms[e];return s?s():void 0}})}get state(){return this.getSnapshot()}get computed(){const t={};return this.computedKeys.forEach(e=>{t[e]=this.computedAtoms[e]()}),t}getComputedKey(t){return this.computedAtoms[t]()}getComputed(t){const e={};return this.computedKeys.forEach(s=>{e[s]=t[s]}),e}setStateInternal(t){this.isComputing&&console.warn("[logic-runtime] setState() called inside computed()");const e={};for(const t in this.stateAtoms)e[t]=this.stateAtoms[t]();t(e);for(const t in this.stateAtoms)e[t]!==this.stateAtoms[t]()&&this.stateAtoms[t].set(e[t])}useEffect(t,e){this.bus.effect(t,e)}attachComputed(e,s){const n=t.atom(void 0),o=this.createReactiveState();this.computedAtoms[e]=n,this.computedKeys.add(e);const i=()=>{this.isComputing=!0,n.set(s({state:o})),this.isComputing=!1};t.effect(i),i(),n.subscribe(this.markDirty)}}function a(t){const e=function(){let t=0,e=[];return{get records(){return e.slice()},record:function(s){e.push({...s,id:++t,state:structuredClone(s.state)})},replay:async function(t,s){const{from:n=0,to:o=1/0,scope:i}=null!=s?s:{},r=e.filter(t=>"emit"===t.type&&t.id>=n&&t.id<=o&&(!i||t.scope===i));for(const e of r){const s=t(e.intent,e.payload);s instanceof Promise&&await s}},clear:function(){e=[],t=0}}}();function s(){return"string"==typeof t.scope?t.scope:t.scope.name}return{timeline:e,wrap:function(){const n=t.emit.bind(t);t.emit=async(o,i)=>{e.record({type:"emit:start",intent:o,payload:i,scope:s(),state:t.getSnapshot(),timestamp:Date.now()});try{const t=n(o,i);t instanceof Promise&&await t}finally{e.record({type:"emit:end",intent:o,payload:i,scope:s(),state:t.getSnapshot(),timestamp:Date.now()})}}}}}Object.defineProperty(exports,"createSelector",{enumerable:!0,get:function(){return t.createSelector}}),exports.LogicRuntime=r,exports.attachDevtools=a,exports.createBackendRuntime=function(t){var s,n;let o=structuredClone(t);const i=()=>o,r=t=>{o={...o,...t}},c=e.createScope("backend");async function u(t,e){await l.emit(t,e,c)}const l=e.createIntentBus(t=>{const e=new AbortController;return{scope:c,payload:t,signal:e.signal,get state(){return i()},setState(){throw new Error("setState is not allowed in backend runtime")},emit:u}}),h={state:i,reset:()=>{o=structuredClone(t)},emit:u,registerIntents:function(t){for(const e in t){const s=t[e];l.on(e,async(t,e)=>{var n;const o={get state(){return i()},signal:null!==(n=t.signal)&&void 0!==n?n:(new AbortController).signal,set:r,emit:u};await s(o)},c)}},onIntent:l.on,effect:l.effect};if("production"!==(null===(n=null===(s=null===globalThis||void 0===globalThis?void 0:globalThis.process)||void 0===s?void 0:s.env)||void 0===n?void 0:n.NODE_ENV)){const t=a(h);t.wrap(h),h.devtools=t}return h},exports.createLogic=function(t){return{name:t.name,create(e){var s;const n=new r(structuredClone(t.state),e);if(t.computed)for(const e in t.computed)n.attachComputed(e,t.computed[e]);null===(s=t.intents)||void 0===s||s.call(t,{on:n.onIntent,effect:n.useEffect.bind(n)});const o={};if(t.actions){const e=Object.keys(t.actions);for(const s of e){const e=t.actions[s];o[s]=e({emit:n.emit,getState:n.getSnapshot})}}return n.actions=o,n}}},exports.effect=function(t){const e={_kind:"effect",id:Symbol("effect"),handler:t,strategy:"default",wait:0};return{...e,takeLatest(){return e.strategy="takeLatest",this},debounce(t){return e.strategy="debounce",e.wait=t,this}}},exports.useLogic=function(t,s){const n=o.useRef(null);n.current||(n.current=t.create("string"==typeof s?e.createScope(s):s));const i=n.current,r=o.useSyncExternalStore(i.subscribe,i.getSnapshot,i.getSnapshot),a=o.useCallback((t,e)=>i.emit(t,e),[i]),c=i.actions;return o.useMemo(()=>({state:r,actions:c,emit:a}),[r,c,a])},exports.withLogic=function(t,n,i){var r,a;const c=r=>{const a=o.useRef(null);a.current||(a.current=t.create("string"==typeof i?e.createScope(i):i));const c=a.current,u=o.useSyncExternalStore(c.subscribe,c.getSnapshot,c.getSnapshot),l=o.useCallback((t,e)=>c.emit(t,e),[c]),h=o.useMemo(()=>({state:u,actions:c.actions,emit:l}),[u,l,c]);return s.jsx(n,{...r,...h})};return c.displayName=`withLogic(${null!==(a=null!==(r=n.displayName)&&void 0!==r?r:n.name)&&void 0!==a?a:"View"})`,c};
|
package/build/index.d.ts
CHANGED
|
@@ -5,12 +5,8 @@ export { effect } from "./core/effect";
|
|
|
5
5
|
export type { IntentMiddleware, IntentNext, } from "./core/middleware";
|
|
6
6
|
export { createLogic } from "./logic/createLogic";
|
|
7
7
|
export type { LogicFactory, LogicActions, } from "./logic/createLogic";
|
|
8
|
-
export { composeLogic } from "./logic/composeLogic";
|
|
9
8
|
export { createBackendRuntime } from "./logic/createBackendRuntime";
|
|
10
9
|
export { withLogic } from "./react/withLogic";
|
|
11
|
-
export {
|
|
12
|
-
export { useComputed } from "./react/useComputed";
|
|
10
|
+
export type { LogicViewProps } from "./react/withLogic";
|
|
13
11
|
export { useLogic } from "./react/useLogic";
|
|
14
|
-
export { useLogicSelector } from "./react/useLogicSelector";
|
|
15
|
-
export { useRuntime } from "./react/useRuntime";
|
|
16
12
|
export * from "./devtools";
|
package/build/index.esm.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{atom as t,effect as e
|
|
1
|
+
import{atom as t,effect as e}from"chrono-state-z";export{createSelector}from"chrono-state-z";import{createScope as s,createIntentBus as n}from"intentx-core-z";import{jsx as o}from"react/jsx-runtime";import*as i from"react";class a{constructor(){this.handlers={},this.effects={},this.middlewares=[]}use(t){this.middlewares.push(t)}effect(t,e){var s,n;(null!==(s=(n=this.effects)[t])&&void 0!==s?s:n[t]=[]).push(e)}on(t,e){var s,n;const o=this.handlers[t];o&&o.length>0?console.warn(`[IntentBus] Duplicate intent handler "${t}" detected. Only the first handler will be used.`):(null!==(s=(n=this.handlers)[t])&&void 0!==s?s:n[t]=[]).push(e)}async emit(t,e){var s,n;const o=null!==(s=this.handlers[t])&&void 0!==s?s:[],i=null!==(n=this.effects[t])&&void 0!==n?n:[],a=(r=this.middlewares,c=async t=>{t.effects=i;for(const e of o)await e(t)},r.reduceRight((t,e)=>e(t),c));var r,c;await a(e)}}class r{constructor(t,e=s("logic")){this.computedAtoms={},this.subs=new Set,this.bus=new a,this.dirty=!0,this.isComputing=!1,this.computedKeys=new Set,this.markDirty=()=>{this.dirty=!0,this.subs.forEach(t=>t())},this.getSnapshot=()=>(this.dirty&&(this.snapshotCache=this.buildSnapshot(),this.dirty=!1),this.snapshotCache),this.subscribe=t=>(this.subs.add(t),()=>this.subs.delete(t)),this.onIntent=(t,e)=>{this.bus.on(t,e)},this.emit=async(t,e)=>{const s=new AbortController;await this.bus.emit(t,{payload:e,scope:this.scope,signal:s.signal,state:this.getSnapshot,setState:t=>this.setStateInternal(t),emit:this.emit})},this.scope=e,this.stateAtoms=this.createStateAtoms(t);for(const t in this.stateAtoms)this.stateAtoms[t].subscribe(this.markDirty);this.bus.use(function(){const t=new Map,e=new Map;return s=>async n=>{var o;const i=n.effects;if(!(null==i?void 0:i.length))return s(n);for(const s of i){const i=s.id;if("takeLatest"===s.strategy){null===(o=t.get(i))||void 0===o||o.abort();const e=new AbortController;t.set(i,e),await s.handler({...n,signal:e.signal})}else"debounce"===s.strategy?(clearTimeout(e.get(i)),e.set(i,setTimeout(()=>s.handler(n),s.wait))):await s.handler(n)}await s(n)}}())}createStateAtoms(e){const s={};for(const n in e)s[n]=t(e[n]);return s}buildSnapshot(){const t={};for(const e in this.stateAtoms)t[e]=this.stateAtoms[e]();for(const e in this.computedAtoms)t[e]=this.computedAtoms[e]();return t}createReactiveState(){return new Proxy({},{get:(t,e)=>{const s=this.stateAtoms[e];return s?s():void 0}})}get state(){return this.getSnapshot()}get computed(){const t={};return this.computedKeys.forEach(e=>{t[e]=this.computedAtoms[e]()}),t}getComputedKey(t){return this.computedAtoms[t]()}getComputed(t){const e={};return this.computedKeys.forEach(s=>{e[s]=t[s]}),e}setStateInternal(t){this.isComputing&&console.warn("[logic-runtime] setState() called inside computed()");const e={};for(const t in this.stateAtoms)e[t]=this.stateAtoms[t]();t(e);for(const t in this.stateAtoms)e[t]!==this.stateAtoms[t]()&&this.stateAtoms[t].set(e[t])}useEffect(t,e){this.bus.effect(t,e)}attachComputed(s,n){const o=t(void 0),i=this.createReactiveState();this.computedAtoms[s]=o,this.computedKeys.add(s);const a=()=>{this.isComputing=!0,o.set(n({state:i})),this.isComputing=!1};e(a),a(),o.subscribe(this.markDirty)}}function c(t){const e={_kind:"effect",id:Symbol("effect"),handler:t,strategy:"default",wait:0};return{...e,takeLatest(){return e.strategy="takeLatest",this},debounce(t){return e.strategy="debounce",e.wait=t,this}}}function u(t){return{name:t.name,create(e){var s;const n=new r(structuredClone(t.state),e);if(t.computed)for(const e in t.computed)n.attachComputed(e,t.computed[e]);null===(s=t.intents)||void 0===s||s.call(t,{on:n.onIntent,effect:n.useEffect.bind(n)});const o={};if(t.actions){const e=Object.keys(t.actions);for(const s of e){const e=t.actions[s];o[s]=e({emit:n.emit,getState:n.getSnapshot})}}return n.actions=o,n}}}function l(t){const e=function(){let t=0,e=[];return{get records(){return e.slice()},record:function(s){e.push({...s,id:++t,state:structuredClone(s.state)})},replay:async function(t,s){const{from:n=0,to:o=1/0,scope:i}=null!=s?s:{},a=e.filter(t=>"emit"===t.type&&t.id>=n&&t.id<=o&&(!i||t.scope===i));for(const e of a){const s=t(e.intent,e.payload);s instanceof Promise&&await s}},clear:function(){e=[],t=0}}}();function s(){return"string"==typeof t.scope?t.scope:t.scope.name}return{timeline:e,wrap:function(){const n=t.emit.bind(t);t.emit=async(o,i)=>{e.record({type:"emit:start",intent:o,payload:i,scope:s(),state:t.getSnapshot(),timestamp:Date.now()});try{const t=n(o,i);t instanceof Promise&&await t}finally{e.record({type:"emit:end",intent:o,payload:i,scope:s(),state:t.getSnapshot(),timestamp:Date.now()})}}}}}function h(t){var e,o;let i=structuredClone(t);const a=()=>i,r=t=>{i={...i,...t}},c=s("backend");async function u(t,e){await h.emit(t,e,c)}const h=n(t=>{const e=new AbortController;return{scope:c,payload:t,signal:e.signal,get state(){return a()},setState(){throw new Error("setState is not allowed in backend runtime")},emit:u}});const d={state:a,reset:()=>{i=structuredClone(t)},emit:u,registerIntents:function(t){for(const e in t){const s=t[e];h.on(e,async(t,e)=>{var n;const o={get state(){return a()},signal:null!==(n=t.signal)&&void 0!==n?n:(new AbortController).signal,set:r,emit:u};await s(o)},c)}},onIntent:h.on,effect:h.effect};if("production"!==(null===(o=null===(e=null===globalThis||void 0===globalThis?void 0:globalThis.process)||void 0===e?void 0:e.env)||void 0===o?void 0:o.NODE_ENV)){const t=l(d);t.wrap(d),d.devtools=t}return d}function d(t,e,n){var a,r;const c=a=>{const r=i.useRef(null);r.current||(r.current=t.create("string"==typeof n?s(n):n));const c=r.current,u=i.useSyncExternalStore(c.subscribe,c.getSnapshot,c.getSnapshot),l=i.useCallback((t,e)=>c.emit(t,e),[c]),h=i.useMemo(()=>({state:u,actions:c.actions,emit:l}),[u,l,c]);return o(e,{...a,...h})};return c.displayName=`withLogic(${null!==(r=null!==(a=e.displayName)&&void 0!==a?a:e.name)&&void 0!==r?r:"View"})`,c}function m(t,e){const n=i.useRef(null);n.current||(n.current=t.create("string"==typeof e?s(e):e));const o=n.current,a=i.useSyncExternalStore(o.subscribe,o.getSnapshot,o.getSnapshot),r=i.useCallback((t,e)=>o.emit(t,e),[o]),c=o.actions;return i.useMemo(()=>({state:a,actions:c,emit:r}),[a,c,r])}export{r as LogicRuntime,l as attachDevtools,h as createBackendRuntime,u as createLogic,c as effect,m as useLogic,d as withLogic};
|
|
@@ -6,18 +6,23 @@ export type LogicFactory<S extends object, C extends ComputedDef<S>, A extends L
|
|
|
6
6
|
name?: string;
|
|
7
7
|
create(scope?: Scope): LogicRuntime<S, C, A>;
|
|
8
8
|
};
|
|
9
|
-
export
|
|
9
|
+
export type ExtractLogicTypes<T> = T extends LogicFactory<infer S, infer C, infer A> ? {
|
|
10
|
+
state: Readonly<S & InferComputed<C>>;
|
|
11
|
+
actions: A;
|
|
12
|
+
emit: (intent: string, payload?: any) => Promise<void>;
|
|
13
|
+
} : never;
|
|
14
|
+
export declare function createLogic<S extends object, C extends ComputedDef<S>, ActionsDef extends Record<string, (context: {
|
|
15
|
+
emit: LogicRuntime<S, C, any>["emit"];
|
|
16
|
+
getState: () => Readonly<S & InferComputed<C>>;
|
|
17
|
+
}) => (...args: any[]) => any>>(config: {
|
|
10
18
|
name?: string;
|
|
11
19
|
state: S;
|
|
12
|
-
computed
|
|
20
|
+
computed: C;
|
|
13
21
|
intents?: (bus: {
|
|
14
|
-
on: LogicRuntime<S, C,
|
|
22
|
+
on: LogicRuntime<S, C, any>["onIntent"];
|
|
15
23
|
effect: (type: string, eff: EffectDef) => void;
|
|
16
24
|
}) => void;
|
|
17
|
-
actions
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}) => A[K];
|
|
22
|
-
};
|
|
23
|
-
}): LogicFactory<S, C, A>;
|
|
25
|
+
actions: ActionsDef;
|
|
26
|
+
}): LogicFactory<S, C, {
|
|
27
|
+
[K in keyof ActionsDef]: ReturnType<ActionsDef[K]>;
|
|
28
|
+
}>;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { Scope } from "intentx-core-z";
|
|
2
|
+
import type { LogicActions, LogicFactory } from "../logic/createLogic";
|
|
3
|
+
import type { ComputedDef } from "../core/runtime";
|
|
4
|
+
export declare function useLogic<S extends object, C extends ComputedDef<S>, A extends LogicActions>(logic: LogicFactory<S, C, A>, scope?: Scope | string): {
|
|
5
|
+
state: Readonly<S & import("../core/runtime").InferComputed<C>>;
|
|
5
6
|
actions: A;
|
|
7
|
+
emit: (intent: string, payload?: any) => Promise<void>;
|
|
6
8
|
};
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import { Scope } from "intentx-core-z";
|
|
3
|
-
import type { LogicActions, LogicFactory } from "../logic/createLogic";
|
|
3
|
+
import type { ExtractLogicTypes, LogicActions, LogicFactory } from "../logic/createLogic";
|
|
4
4
|
import type { ComputedDef, InferComputed } from "../core/runtime";
|
|
5
5
|
type InjectedProps<S extends object, C extends ComputedDef<S>, A extends LogicActions> = {
|
|
6
6
|
state: Readonly<S & InferComputed<C>>;
|
|
7
7
|
actions: A;
|
|
8
8
|
emit: (intent: string, payload?: any) => Promise<void>;
|
|
9
9
|
};
|
|
10
|
+
export type LogicViewProps<T extends LogicFactory<any, any, any>> = ExtractLogicTypes<T>;
|
|
10
11
|
export declare function withLogic<S extends object, C extends ComputedDef<S>, A extends LogicActions, P extends object>(logic: LogicFactory<S, C, A>, View: React.ComponentType<P & InjectedProps<S, C, A>>, scope?: Scope | string): React.FC<Omit<P, keyof InjectedProps<S, C, A>>>;
|
|
11
12
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "logic-runtime-react-z",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.4",
|
|
4
4
|
"description": "Intent-first business logic runtime. Deterministic, headless, and framework-agnostic.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Delpi.Kye",
|
|
@@ -14,16 +14,6 @@
|
|
|
14
14
|
"types": "./build/index.d.ts",
|
|
15
15
|
"import": "./build/index.esm.js",
|
|
16
16
|
"require": "./build/index.cjs.js"
|
|
17
|
-
},
|
|
18
|
-
"./react": {
|
|
19
|
-
"types": "./build/react/index.d.ts",
|
|
20
|
-
"import": "./build/react/index.esm.js",
|
|
21
|
-
"require": "./build/react/index.cjs.js"
|
|
22
|
-
},
|
|
23
|
-
"./devtools": {
|
|
24
|
-
"types": "./build/devtools/index.d.ts",
|
|
25
|
-
"import": "./build/devtools/index.esm.js",
|
|
26
|
-
"require": "./build/devtools/index.cjs.js"
|
|
27
17
|
}
|
|
28
18
|
},
|
|
29
19
|
"files": [
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { Scope } from "intentx-core-z";
|
|
2
|
-
import type { ComputedDef, InferComputed } from "../core/runtime";
|
|
3
|
-
import { LogicRuntime } from "../core/runtime";
|
|
4
|
-
import type { LogicFactory } from "../logic/createLogic";
|
|
5
|
-
type AnyLogicFactory = LogicFactory<any, ComputedDef<any>, any>;
|
|
6
|
-
type LogicMap = Record<string, AnyLogicFactory>;
|
|
7
|
-
type InferRuntime<L> = L extends LogicFactory<infer S, infer C, infer A> ? LogicRuntime<S, C, A> : never;
|
|
8
|
-
type InferState<M extends LogicMap> = {
|
|
9
|
-
[K in keyof M]: InferRuntime<M[K]> extends LogicRuntime<infer S, infer C, any> ? Readonly<S & InferComputed<C>> : never;
|
|
10
|
-
};
|
|
11
|
-
type InferActions<M extends LogicMap> = {
|
|
12
|
-
[K in keyof M]: InferRuntime<M[K]> extends LogicRuntime<any, any, infer A> ? A : never;
|
|
13
|
-
};
|
|
14
|
-
export declare function composeLogic<M extends LogicMap>(map: M): {
|
|
15
|
-
scope: Scope;
|
|
16
|
-
runtimes: { [K in keyof M]: InferRuntime<M[K]>; };
|
|
17
|
-
emit: <P = any>(type: string, payload?: P) => Promise<void>;
|
|
18
|
-
actions: InferActions<M>;
|
|
19
|
-
getState: () => InferState<M>;
|
|
20
|
-
};
|
|
21
|
-
export {};
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { LogicFactory, LogicActions } from "../logic/createLogic";
|
|
2
|
-
import { LogicRuntime, ComputedDef } from "../core/runtime";
|
|
3
|
-
export declare function useActions<A extends LogicActions>(runtime: LogicRuntime<any, any, A>): A;
|
|
4
|
-
export declare function useActions<S extends object, C extends ComputedDef<S>, A extends LogicActions>(logic: LogicFactory<S, C, A>): A;
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { LogicFactory } from "../logic/createLogic";
|
|
2
|
-
import { LogicRuntime, ComputedDef, InferComputed } from "../core/runtime";
|
|
3
|
-
export declare function useComputed<S extends object, C extends ComputedDef<S>>(runtime: LogicRuntime<S, C, any>): Readonly<InferComputed<C>>;
|
|
4
|
-
export declare function useComputed<S extends object, C extends ComputedDef<S>, R>(runtime: LogicRuntime<S, C, any>, selector: (computed: Readonly<InferComputed<C>>) => R): R;
|
|
5
|
-
export declare function useComputed<S extends object, C extends ComputedDef<S>, A extends Record<string, any>>(logic: LogicFactory<S, C, A>): Readonly<InferComputed<C>>;
|
|
6
|
-
export declare function useComputed<S extends object, C extends ComputedDef<S>, A extends Record<string, any>, R>(logic: LogicFactory<S, C, A>, selector: (computed: Readonly<InferComputed<C>>) => R): R;
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { ComputedDef, InferComputed } from "../core/runtime";
|
|
2
|
-
import { LogicRuntime } from "../core/runtime";
|
|
3
|
-
import type { LogicFactory } from "../logic/createLogic";
|
|
4
|
-
export declare function useRuntime<S extends object, C extends ComputedDef<S>, A extends Record<string, any>>(runtime: LogicRuntime<S, C, A>): Readonly<S & InferComputed<C>>;
|
|
5
|
-
export declare function useRuntime<S extends object, C extends ComputedDef<S>, A extends Record<string, any>>(logic: LogicFactory<S, C, A>): Readonly<S & InferComputed<C>>;
|