chizu 0.2.63 → 0.2.65
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 +22 -18
- package/dist/boundary/components/broadcast/index.d.ts +1 -1
- package/dist/boundary/components/broadcast/types.d.ts +6 -4
- package/dist/boundary/components/broadcast/utils.d.ts +20 -4
- package/dist/boundary/components/scope/index.d.ts +2 -3
- package/dist/boundary/components/scope/types.d.ts +4 -10
- package/dist/boundary/index.d.ts +1 -1
- package/dist/chizu.js +7 -8
- package/dist/chizu.umd.cjs +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/types.d.ts +9 -7
- package/dist/hooks/utils.d.ts +3 -3
- package/dist/types/index.d.ts +72 -95
- package/package.json +1 -1
- package/dist/boundary/components/scope/partition.d.ts +0 -32
package/README.md
CHANGED
|
@@ -176,20 +176,15 @@ actions.useAction(Actions.Profile, async (context) => {
|
|
|
176
176
|
});
|
|
177
177
|
```
|
|
178
178
|
|
|
179
|
-
Once we have the broadcast action if we
|
|
179
|
+
Once we have the broadcast action, if we want to derive a value from the broadcast payload onto the model, use `derive`:
|
|
180
180
|
|
|
181
181
|
```tsx
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
Manage your subscriptions for your{" "}
|
|
186
|
-
{actions.consume(Actions.Broadcast.Name, (name) => name.value)} account.
|
|
187
|
-
</>
|
|
188
|
-
);
|
|
189
|
-
}
|
|
182
|
+
const [model] = actions.derive("name", Actions.Broadcast.Name, (name) => name);
|
|
183
|
+
|
|
184
|
+
// model.name is null until the first dispatch, then stays in sync
|
|
190
185
|
```
|
|
191
186
|
|
|
192
|
-
|
|
187
|
+
If we want to listen for it and perform another operation in our local component we can do that via `useAction`:
|
|
193
188
|
|
|
194
189
|
```tsx
|
|
195
190
|
actions.useAction(Actions.Broadcast.Name, async (context, name) => {
|
|
@@ -201,11 +196,11 @@ actions.useAction(Actions.Broadcast.Name, async (context, name) => {
|
|
|
201
196
|
});
|
|
202
197
|
```
|
|
203
198
|
|
|
204
|
-
Or read the latest broadcast value directly in a handler with `context.actions.
|
|
199
|
+
Or read the latest broadcast value directly in a handler with `context.actions.read`:
|
|
205
200
|
|
|
206
201
|
```tsx
|
|
207
202
|
actions.useAction(Actions.FetchFriends, async (context) => {
|
|
208
|
-
const name = await context.actions.
|
|
203
|
+
const name = await context.actions.read(Actions.Broadcast.Name);
|
|
209
204
|
if (!name) return;
|
|
210
205
|
const friends = await fetch(api.friends(name));
|
|
211
206
|
context.actions.produce(({ model }) => {
|
|
@@ -285,12 +280,8 @@ function App() {
|
|
|
285
280
|
// Dispatch to all components within "TeamA" scope
|
|
286
281
|
actions.dispatch(Actions.Multicast.Update, 42, { scope: "TeamA" });
|
|
287
282
|
|
|
288
|
-
//
|
|
289
|
-
|
|
290
|
-
actions.consume(Actions.Multicast.Update, (box) => box.value, {
|
|
291
|
-
scope: "TeamA",
|
|
292
|
-
});
|
|
293
|
-
}
|
|
283
|
+
// Subscribe to multicast values with derive
|
|
284
|
+
const [model] = actions.derive("score", Actions.Multicast.Update, (v) => v);
|
|
294
285
|
```
|
|
295
286
|
|
|
296
287
|
Unlike broadcast which reaches all components, multicast is scoped to the named boundary – perfect for isolated widget groups, form sections, or distinct UI regions.
|
|
@@ -368,3 +359,16 @@ context.actions.invalidate(CacheStore.User({ UserId: 5 }));
|
|
|
368
359
|
```
|
|
369
360
|
|
|
370
361
|
The cache is scoped to the nearest `<Boundary>`. See the [caching recipe](./recipes/caching.md) for more details.
|
|
362
|
+
|
|
363
|
+
When you want to expose a derived value alongside your model without storing it separately, use `derive` to overlay computed properties on top of the model:
|
|
364
|
+
|
|
365
|
+
```tsx
|
|
366
|
+
return actions
|
|
367
|
+
.derive("greeting", (model) => `Hello #${model.count}`)
|
|
368
|
+
.derive("doubled", Actions.Broadcast.Counter, (counter) => counter * 2)
|
|
369
|
+
.derive("label", Actions.Decrement, () => "decremented");
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
Model-based entries receive the current model, evaluate on every render, and always have a value. Action-based entries are `null` before the action fires; callback parameters are auto-typed from the action's payload. Calls are chained, and the component renders once even when a normal handler and a derived entry fire together.
|
|
373
|
+
|
|
374
|
+
See the [derived values recipe](./recipes/derived-values.md) for more details.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Props } from './types.ts';
|
|
2
2
|
import * as React from "react";
|
|
3
|
-
export { useBroadcast } from './utils.ts';
|
|
3
|
+
export { useBroadcast, BroadcastEmitter } from './utils.ts';
|
|
4
4
|
/**
|
|
5
5
|
* Creates a new broadcast context for distributed actions. Only needed if you
|
|
6
6
|
* want to isolate a broadcast context, useful for libraries that want to provide
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BroadcastEmitter } from './utils.ts';
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
/**
|
|
4
|
-
* The broadcast context is
|
|
4
|
+
* The broadcast context is a BroadcastEmitter used for distributed actions across components.
|
|
5
|
+
* Extends EventEmitter with a per-action value cache so late-mounting components can replay
|
|
6
|
+
* broadcast values even without a Partition (from `consume()`).
|
|
5
7
|
*/
|
|
6
|
-
export type BroadcastContext =
|
|
8
|
+
export type BroadcastContext = BroadcastEmitter;
|
|
7
9
|
/**
|
|
8
10
|
* Return type for the useBroadcast hook.
|
|
9
|
-
* Provides access to the shared
|
|
11
|
+
* Provides access to the shared BroadcastEmitter for emitting and subscribing to distributed actions.
|
|
10
12
|
*/
|
|
11
13
|
export type UseBroadcast = BroadcastContext;
|
|
12
14
|
/**
|
|
@@ -1,12 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { default as EventEmitter } from 'eventemitter3';
|
|
2
2
|
import * as React from "react";
|
|
3
|
+
/**
|
|
4
|
+
* EventEmitter subclass that caches the latest payload per event.
|
|
5
|
+
*
|
|
6
|
+
* When a broadcast or multicast action is dispatched, the payload is
|
|
7
|
+
* stored so that late-mounting components can replay it via
|
|
8
|
+
* {@link useLifecycles} and handlers can read it via
|
|
9
|
+
* `context.actions.read()`.
|
|
10
|
+
*/
|
|
11
|
+
export declare class BroadcastEmitter extends EventEmitter {
|
|
12
|
+
private cache;
|
|
13
|
+
emit(event: string | symbol, ...args: unknown[]): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Retrieve the last emitted payload for a given event.
|
|
16
|
+
*/
|
|
17
|
+
getCached(event: string | symbol): unknown;
|
|
18
|
+
}
|
|
3
19
|
/**
|
|
4
20
|
* React context for broadcasting distributed actions across components.
|
|
5
21
|
*/
|
|
6
|
-
export declare const Context: React.Context<
|
|
22
|
+
export declare const Context: React.Context<BroadcastEmitter>;
|
|
7
23
|
/**
|
|
8
24
|
* Hook to access the broadcast EventEmitter for emitting and listening to distributed actions.
|
|
9
25
|
*
|
|
10
|
-
* @returns The
|
|
26
|
+
* @returns The BroadcastEmitter instance for distributed actions.
|
|
11
27
|
*/
|
|
12
|
-
export declare function useBroadcast():
|
|
28
|
+
export declare function useBroadcast(): BroadcastEmitter;
|
|
@@ -3,7 +3,6 @@ import { ComponentType, ReactNode } from 'react';
|
|
|
3
3
|
import * as React from "react";
|
|
4
4
|
export { useScope, getScope } from './utils.ts';
|
|
5
5
|
export type { ScopeEntry, ScopeContext } from './types.ts';
|
|
6
|
-
export { MulticastPartition } from './partition.tsx';
|
|
7
6
|
/**
|
|
8
7
|
* Creates a named scope boundary for multicast actions.
|
|
9
8
|
*
|
|
@@ -16,8 +15,8 @@ export { MulticastPartition } from './partition.tsx';
|
|
|
16
15
|
* communication channel. When dispatching, the nearest ancestor scope
|
|
17
16
|
* with the matching name receives the event.
|
|
18
17
|
*
|
|
19
|
-
* Like Broadcast, multicast
|
|
20
|
-
*
|
|
18
|
+
* Like Broadcast, multicast caches the most recent dispatched value so that
|
|
19
|
+
* late-mounted components can read it via `context.actions.read()`.
|
|
21
20
|
*
|
|
22
21
|
* @param props.name - The unique name for this scope
|
|
23
22
|
* @param props.children - Components within the scope boundary
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Entry } from '../consumer/types.ts';
|
|
3
|
-
import { ActionId } from '../tasks/types.ts';
|
|
1
|
+
import { BroadcastEmitter } from '../broadcast/utils.ts';
|
|
4
2
|
import type * as React from "react";
|
|
5
3
|
/**
|
|
6
4
|
* Props for the Scope component.
|
|
@@ -13,17 +11,13 @@ export type Props = {
|
|
|
13
11
|
};
|
|
14
12
|
/**
|
|
15
13
|
* Represents a single scope in the ancestor chain.
|
|
16
|
-
* Each scope has its own
|
|
14
|
+
* Each scope has its own BroadcastEmitter for multicast events and caching.
|
|
17
15
|
*/
|
|
18
16
|
export type ScopeEntry = {
|
|
19
17
|
/** The name of this scope */
|
|
20
18
|
name: string;
|
|
21
|
-
/**
|
|
22
|
-
emitter:
|
|
23
|
-
/** Consumer store for late-mounting components (like Broadcast) */
|
|
24
|
-
store: Map<ActionId, Entry>;
|
|
25
|
-
/** Listeners for store changes (for consume() re-renders) */
|
|
26
|
-
listeners: Map<ActionId, Set<() => void>>;
|
|
19
|
+
/** BroadcastEmitter for multicast events within this scope (caches last payload per event) */
|
|
20
|
+
emitter: BroadcastEmitter;
|
|
27
21
|
};
|
|
28
22
|
/**
|
|
29
23
|
* The scope context is a flattened map of all ancestor scopes by name.
|
package/dist/boundary/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Props } from './types.ts';
|
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
/**
|
|
4
4
|
* Creates a unified context boundary for all Chizu features.
|
|
5
|
-
* Wraps children with Broadcaster,
|
|
5
|
+
* Wraps children with Broadcaster, Cache, and Tasks providers.
|
|
6
6
|
*
|
|
7
7
|
* Use this at the root of your application or to create isolated context boundaries
|
|
8
8
|
* for libraries that need their own Chizu context.
|
package/dist/chizu.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import{G as e,A as t}from"@mobily/ts-belt";import{jsx as n}from"react/jsx-runtime";import*as r from"react";import{createContext as o,useContext as c}from"react";import{immerable as i,enablePatches as s,Immer as a}from"immer";class u{static Payload=/* @__PURE__ */Symbol("chizu.brand/Payload");static Broadcast=/* @__PURE__ */Symbol("chizu.brand/Broadcast");static Multicast=/* @__PURE__ */Symbol("chizu.brand/Multicast");static Action=/* @__PURE__ */Symbol("chizu.brand/Action");static Channel=/* @__PURE__ */Symbol("chizu.brand/Channel");static Node=/* @__PURE__ */Symbol("chizu.action.lifecycle/Node");static Cache=/* @__PURE__ */Symbol("chizu.brand/Cache")}class l{static Mount=/* @__PURE__ */Symbol("chizu.action.lifecycle/Mount");static Unmount=/* @__PURE__ */Symbol("chizu.action.lifecycle/Unmount");static Error=/* @__PURE__ */Symbol("chizu.action.lifecycle/Error");static Update=/* @__PURE__ */Symbol("chizu.action.lifecycle/Update");static Node=(()=>{const e=u.Node,t=function(t){return{[u.Action]:e,[u.Payload]:void 0,[u.Channel]:t,channel:t}};return Object.defineProperty(t,u.Action,{value:e,enumerable:!1}),Object.defineProperty(t,u.Payload,{value:void 0,enumerable:!1}),t})()}var f=/* @__PURE__ */(e=>(e.Unicast="unicast",e.Broadcast="broadcast",e.Multicast="multicast",e))(f||{}),d=/* @__PURE__ */(e=>(e.Mounting="mounting",e.Mounted="mounted",e.Unmounting="unmounting",e.Unmounted="unmounted",e))(d||{}),
|
|
2
|
-
return n(
|
|
3
|
-
return n(
|
|
4
|
-
return n(te.Provider,{value:t,children:e})}const
|
|
5
|
-
return n(
|
|
6
|
-
return n(
|
|
7
|
-
return n(
|
|
8
|
-
return n(fe.Provider,{value:i,children:t})}function ye(e,t){const r=`Scoped${t.displayName||t.name||"Component"}`;return{[r]:r=>/* @__PURE__ */n(me,{name:e,children:/* @__PURE__ */n(t,{...r})})}[r]}function be(e){return(t,n)=>{t.actions.produce(t=>{t.model[e]=n})}}function ve(...n){const o=e.isUndefined(n[0])||e.isFunction(n[0])?{}:n[0],i=e.isFunction(n[0])?n[0]:n[1]??(()=>({})),s=Z(),a=de(),f=ne(),p=c(C),m=r.useContext(ae),y=r.useContext(ie),b=re(),v=r.useRef(!1),g=r.useRef(null),M=r.useRef(new I);v.current||(v.current=!0,g.current=M.current.hydrate(o));const[O,_]=r.useState(()=>M.current.model),N=function(e){const t=r.useRef(e);return r.useLayoutEffect(()=>{t.current=e},[e]),r.useMemo(()=>{return n=t,Object.keys(e).reduce((e,t)=>(Object.defineProperty(e,t,{get:()=>n.current[t],enumerable:!0}),e),{});var n},[e])}(i()),R=r.useMemo(()=>new X,[]),U=r.useRef({handlers:/* @__PURE__ */new Map});U.current.handlers=/* @__PURE__ */new Map;const z=function(){const e=r.useRef(/* @__PURE__ */new Set),t=r.useRef(/* @__PURE__ */new Set);return r.useMemo(()=>({broadcast:e.current,multicast:t.current}),[])}(),L=r.useRef(d.Mounting),T=function(){const e=r.useRef({}),t=r.useRef(/* @__PURE__ */new Map),n=r.useRef(/* @__PURE__ */new Map);return r.useMemo(()=>({refs:e,pending:t,emitted:n}),[])}(),$=r.useRef(/* @__PURE__ */new Set),B=r.useRef(0),F=r.useCallback((e,t,n)=>{const r=new AbortController,o={controller:r,action:e,payload:t};return m.add(o),$.current.add(o),{model:M.current.model,get phase(){return L.current},task:o,data:N,tasks:m,nodes:T.refs.current,actions:{produce(e){if(r.signal.aborted)return;const t=M.current.produce(t=>e({model:t,inspect:M.current.inspect}));_(M.current.model),n.processes.add(t),g.current&&(n.processes.add(g.current),g.current=null)},dispatch(e,t,n){if(r.signal.aborted)return;const o=w(e),c=x(e)?e.channel:void 0;if(E(e)&&n?.scope){const e=pe(a,n.scope);return void(e&&e.emitter.emit(o,t,c))}(S(e)?s:R).emit(o,t,c)},annotate:(e,t)=>M.current.annotate(e,t),async cacheable(e,t,n){if(r.signal.aborted)return{data:null};const o=A(e),c=y.get(o);if(c&&Date.now()<c.expiry)return{data:c.value};const i=function(e){return null!=e&&"object"==typeof e&&"TAG"in e?0===e.TAG?{ok:!0,value:e._0}:{ok:!1}:null==e?{ok:!1}:{ok:!0,value:e}}(await n());return i.ok?(y.set(o,{value:i.value,expiry:Date.now()+t}),{data:i.value}):{data:null}},invalidate(e){y.delete(A(e))},async consume(e,t){if(r.signal.aborted)return null;const n=w(e);let o;if(E(e)&&t?.scope){const e=pe(a,t.scope);if(!e)return null;o=e.store.get(n)}else o=f.get(n);if(!o?.state.model?.value)return null;const c=o.state.inspect;return c.value.pending()&&await new Promise((e,t)=>{if(r.signal.aborted)return void t(new h);const n=()=>t(new h);r.signal.addEventListener("abort",n,{once:!0}),c.value.settled().then(()=>{r.signal.removeEventListener("abort",n),e()})}),o.state.model.value}}}},[O]);r.useLayoutEffect(()=>{function t(t,n,r){return async function(o,c){const i=r();if(e.isNotNullable(c)&&e.isNotNullable(i)&&!function(e,t){for(const n of Object.keys(e))if(t[n]!==e[n])return!1;return!0}(c,i))return;const s={processes:/* @__PURE__ */new Set},a=Promise.withResolvers(),u=F(t,o,s);try{await n(u,o)}catch(f){const e=U.current.handlers.has(l.Error),n={reason:j(f),error:k(f),action:P(t),handled:e,tasks:m};p?.(n),e&&R.emit(l.Error,n)}finally{for(const e of m)if(e===u.task){m.delete(e),$.current.delete(e);break}s.processes.forEach(e=>M.current.prune(e)),s.processes.size>0&&b(),a.resolve()}}}B.current++;const n=/* @__PURE__ */new Set;return U.current.handlers.forEach((e,r)=>{for(const{getChannel:o,handler:c}of e){const e=t(r,c,o);if(E(r)){if(a)for(const t of a.values()){const o=t.emitter;o.on(r,e),n.add(()=>o.off(r,e))}R.on(r,e),z.multicast.add(r),n.add(()=>R.off(r,e))}else S(r)?(s.on(r,e),R.on(r,e),z.broadcast.add(r),n.add(()=>{s.off(r,e),R.off(r,e)})):(R.on(r,e),n.add(()=>R.off(r,e)))}}),()=>{const e=++B.current,t=new Set(n);queueMicrotask(()=>{if(B.current===e){for(const e of $.current)e.controller.abort(),m.delete(e);$.current.clear(),L.current=d.Unmounting,R.emit(l.Unmount),L.current=d.Unmounted;for(const e of t)e()}else for(const e of t)e()})}},[R]),r.useLayoutEffect(()=>{for(const[e,t]of T.pending.current)T.emitted.current.get(e)!==t&&(T.emitted.current.set(e,t),R.emit(u.Node,t,{Name:e}));T.pending.current.clear()}),function({unicast:n,broadcastActions:o,phase:c,data:i}){const s=ne(),a=r.useRef(null);r.useLayoutEffect(()=>{c.current===d.Mounting&&(n.emit(l.Mount),o.forEach(t=>{const r=s.get(t),o=r?.state.model?.value;e.isNullable(o)||n.emit(t,o)}),c.current=d.Mounted)},[]),r.useLayoutEffect(()=>{if(e.isNotNullable(a.current)){const e=function(e,t){return Object.keys(t).reduce((n,r)=>e[r]!==t[r]?{...n,[r]:t[r]}:n,{})}(a.current,i);t.isNotEmpty(Object.keys(e))&&n.emit(l.Update,e)}a.current=i},[i,n])}({unicast:R,broadcastActions:z.broadcast,phase:L,data:i()});const W=r.useMemo(()=>[O,{dispatch(e,t,n){const r=w(e),o=x(e)?e.channel:void 0;if(E(e)&&n?.scope){const e=pe(a,n.scope);return void(e&&e.emitter.emit(r,t,o))}(S(e)?s:R).emit(r,t,o)},consume:(e,t,n)=>E(e)&&n?.scope?r.createElement(he,{action:w(e),scopeName:n.scope,renderer:t}):r.createElement(oe,{action:w(e),renderer:t}),get inspect(){return M.current.inspect},get nodes(){return T.refs.current},node(e,t){T.refs.current[e]=t,T.pending.current.set(e,t)}}],[O,R]);return W.useAction=(e,t)=>{!function(e,t,n){const o=r.useRef(n);r.useLayoutEffect(()=>{o.current=n});const c=r.useRef(t);r.useLayoutEffect(()=>{c.current=t});const i=r.useCallback(async(e,t)=>{const n=o.current;if("GeneratorFunction"===n.constructor.name||"AsyncGeneratorFunction"===n.constructor.name){const r=n(e,t);for await(const e of r);}else await n(e,t)},[]),s=r.useCallback(()=>x(c.current)?c.current.channel:void 0,[]),a=w(t),u=e.current.handlers.get(a)??/* @__PURE__ */new Set;0===u.size&&e.current.handlers.set(a,u),u.add({getChannel:s,handler:i})}(U,e,t)},W}export{M as Action,le as Boundary,f as Distribution,O as Entry,_ as Error,l as Lifecycle,R as Op,R as Operation,p as Reason,me as Scope,I as State,be as With,q as annotate,ve as useActions,v as utils,ye as withScope};
|
|
1
|
+
import{G as e,A as t}from"@mobily/ts-belt";import{jsx as n}from"react/jsx-runtime";import*as r from"react";import{createContext as o,useContext as c}from"react";import{immerable as i,enablePatches as s,Immer as a}from"immer";class u{static Payload=/* @__PURE__ */Symbol("chizu.brand/Payload");static Broadcast=/* @__PURE__ */Symbol("chizu.brand/Broadcast");static Multicast=/* @__PURE__ */Symbol("chizu.brand/Multicast");static Action=/* @__PURE__ */Symbol("chizu.brand/Action");static Channel=/* @__PURE__ */Symbol("chizu.brand/Channel");static Node=/* @__PURE__ */Symbol("chizu.action.lifecycle/Node");static Cache=/* @__PURE__ */Symbol("chizu.brand/Cache")}class l{static Mount=/* @__PURE__ */Symbol("chizu.action.lifecycle/Mount");static Unmount=/* @__PURE__ */Symbol("chizu.action.lifecycle/Unmount");static Error=/* @__PURE__ */Symbol("chizu.action.lifecycle/Error");static Update=/* @__PURE__ */Symbol("chizu.action.lifecycle/Update");static Node=(()=>{const e=u.Node,t=function(t){return{[u.Action]:e,[u.Payload]:void 0,[u.Channel]:t,channel:t}};return Object.defineProperty(t,u.Action,{value:e,enumerable:!1}),Object.defineProperty(t,u.Payload,{value:void 0,enumerable:!1}),t})()}var f=/* @__PURE__ */(e=>(e.Unicast="unicast",e.Broadcast="broadcast",e.Multicast="multicast",e))(f||{}),d=/* @__PURE__ */(e=>(e.Mounting="mounting",e.Mounted="mounted",e.Unmounting="unmounting",e.Unmounted="unmounted",e))(d||{}),h=/* @__PURE__ */(e=>(e[e.Timedout=0]="Timedout",e[e.Supplanted=1]="Supplanted",e[e.Disallowed=2]="Disallowed",e[e.Errored=3]="Errored",e[e.Unmounted=4]="Unmounted",e))(h||{});class p extends Error{name="AbortError";constructor(e="Aborted"){super(e)}}const m={actionPrefix:"chizu.action/",broadcastActionPrefix:"chizu.action/broadcast/",multicastActionPrefix:"chizu.action/multicast/",channelPrefix:"chizu.channel/",cachePrefix:"chizu.cache/"};function y(e,t){return new Promise((n,r)=>{if(t?.aborted)return void r(new p);const o=setTimeout(n,e);t?.addEventListener("abort",()=>{clearTimeout(o),r(new p)},{once:!0})})}function b(e){return e?Boolean(e&&"symbol"!=typeof e):/* @__PURE__ */Symbol(`pk.${Date.now()}.${crypto.randomUUID()}`)}const v=/* @__PURE__ */Object.freeze(/* @__PURE__ */Object.defineProperty({__proto__:null,config:m,pk:b,sleep:y,"ζ":y,"κ":b},Symbol.toStringTag,{value:"Module"})),g=e=>"symbol"==typeof e;function w(t){return e.isString(t)||g(t)?t:(e.isObject(t)||e.isFunction(t))&&u.Action in t?t[u.Action]:t}function P(t){if(e.isString(t))return t.startsWith(m.broadcastActionPrefix);if(g(t))return t.description?.startsWith(m.broadcastActionPrefix)??!1;if(e.isObject(t)||e.isFunction(t)){if(u.Broadcast in t&&t[u.Broadcast])return!0;if(u.Action in t){const e=t[u.Action];return e.description?.startsWith(m.broadcastActionPrefix)??!1}}return!1}function S(t){const n=w(t),r=e.isString(n)?n:n.description??"";return r.startsWith(m.actionPrefix)&&r.slice(r.lastIndexOf("/")+1)||"unknown"}function x(t){return e.isObject(t)&&u.Channel in t&&"channel"in t}function A(t){if(e.isString(t))return t.startsWith(m.multicastActionPrefix);if(g(t))return t.description?.startsWith(m.multicastActionPrefix)??!1;if(e.isObject(t)||e.isFunction(t)){if(u.Multicast in t&&t[u.Multicast])return!0;if(u.Action in t){const e=t[u.Action];return e.description?.startsWith(m.multicastActionPrefix)??!1}}return!1}const O=(e,t=f.Unicast)=>{const n=t===f.Broadcast?/* @__PURE__ */Symbol(`${m.broadcastActionPrefix}${e}`):t===f.Multicast?/* @__PURE__ */Symbol(`${m.multicastActionPrefix}${e}`):/* @__PURE__ */Symbol(`${m.actionPrefix}${e}`),r=function(e){return{[u.Action]:n,[u.Payload]:void 0,[u.Channel]:e,channel:e}};return Object.defineProperty(r,u.Action,{value:n,enumerable:!1}),Object.defineProperty(r,u.Payload,{value:void 0,enumerable:!1}),t===f.Broadcast&&Object.defineProperty(r,u.Broadcast,{value:!0,enumerable:!1}),t===f.Multicast&&Object.defineProperty(r,u.Multicast,{value:!0,enumerable:!1}),r};function E(){const e=/* @__PURE__ */Symbol("chizu.cache/Entry"),t=function(t){return{[u.Cache]:e,channel:t}};return Object.defineProperty(t,u.Cache,{value:e,enumerable:!1}),t}function j(e){const t=function(e){return e[u.Cache]}(e),n=function(e){return"channel"in e}(e)&&(r=e.channel)?[...Object.keys(r)].toSorted().map(e=>`${e}=${String(r[e])}`).join("&"):"";var r;return`${String(t)}:${n}`}function M(e){if(e instanceof Error){if("TimeoutError"===e.name)return h.Timedout;if("AbortError"===e.name)return h.Supplanted}return h.Errored}function C(e){return e instanceof Error?e:new Error(String(e))}const k=o(void 0);function _({handler:e,children:t}){/* @__PURE__ */
|
|
2
|
+
return n(k.Provider,{value:e,children:t})}let R=(e=21)=>{let t="",n=crypto.getRandomValues(new Uint8Array(e|=0));for(;e--;)t+="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"[63&n[e]];return t};var N=/* @__PURE__ */(e=>(e[e.Add=1]="Add",e[e.Remove=2]="Remove",e[e.Update=4]="Update",e[e.Move=8]="Move",e[e.Replace=16]="Replace",e[e.Sort=32]="Sort",e[e.Create=64]="Create",e[e.Fetch=128]="Fetch",e[e.Clone=256]="Clone",e[e.Archive=512]="Archive",e[e.Restore=1024]="Restore",e[e.Merge=2048]="Merge",e[e.Reorder=4096]="Reorder",e[e.Sync=8192]="Sync",e[e.Publish=16384]="Publish",e[e.Link=32768]="Link",e[e.Unlink=65536]="Unlink",e[e.Lock=131072]="Lock",e[e.Unlock=262144]="Unlock",e[e.Import=524288]="Import",e[e.Export=1048576]="Export",e[e.Transfer=2097152]="Transfer",e))(N||{}),U=/* @__PURE__ */(e=>(e[e.Produce=0]="Produce",e[e.Hydrate=1]="Hydrate",e))(U||{}),z=/* @__PURE__ */(e=>(e.Property="property",e.Process="process",e.Value="value",e.Operation="operation",e))(z||{});class L{[i]=!0;static keys=new Set(Object.values(z));property=null;process=null;value;operation;constructor(e,t){this.value=e,this.operation=t}assign(e,t){const n=new L(this.value,this.operation);return n.property=e,n.process=t,n}}class T{static immer=(()=>{s();const e=new a;return e.setAutoFreeze(!1),e})();static tag="κ";static id=R}function $(e,t){const n="string"==typeof t?""===t?[]:t.split("."):t;let r=e;for(const o of n){if(null==r)return;r=r[o]}return r}function B(t){if(e.isNullable(t)||D(t))return t;if(e.isArray(t))return t.map(e=>B(e));if(e.isObject(t)&&W(t)){const e=Object.entries(t).map(([e,t])=>[e,B(t)]);return{...Object.fromEntries(e),[T.tag]:t[T.tag]??T.id()}}return t}function F(e){if(Array.isArray(e))return e.filter(e=>T.tag in e).map(e=>e[T.tag]??"").join(",");const t=e[T.tag];if(t)return t;try{return JSON.stringify(e)}catch{return`[unserializable:${typeof e}]`}}function W(e){const t=Object.getPrototypeOf(e);return t===Object.prototype||null===t}function D(t){return e.isNullable(t)||e.isString(t)||e.isNumber(t)||e.isBoolean(t)||"symbol"==typeof t||"bigint"==typeof t}function H(t,n,r,o,c,i){return function s(a,u=n.path){if(a instanceof L){const n=$(r,u.join("."));if(Object.entries(a).filter(([e,t])=>!L.keys.has(e)&&t instanceof L).forEach(([e,t])=>s(t,u.concat(e))),D(a.value)){if(t===U.Hydrate)return a.value;const s=u.slice(0,-1),l=s.length>0?$(r,s.join(".")):r;return e.isNullable(l)||G(l,a,u.at(-1),o,c,i),n??a.value}if(t===U.Hydrate){const e=B(s(a.value,u));return G(e,a,null,o,c,i),e}const l=n??B(a.value);return G(l,a,null,o,c,i),e.isNullable(n)?l:(s(a.value,u),n)}if(e.isArray(a))return a.map((e,t)=>s(e,u.concat(t)));if(e.isObject(a)&&!W(a))return a;if(e.isObject(a)){const e=Object.entries(a).map(([e,t])=>[e,s(t,u.concat(e))]),n=Object.fromEntries(e);if(t===U.Hydrate){const e=B(n);return Object.entries(a).forEach(([t,n])=>{n instanceof L&&D(n.value)&&G(e,n,t,o,c,i)}),e}return n}return a}(n.value)}function G(e,t,n,r,o,c){const i=c(e),s=o.get(i)??[];o.set(i,[t.assign(n,r),...s])}class I{#e={};#t;#n=/* @__PURE__ */new Map;#r=/* @__PURE__ */new Set;#o=!1;constructor(e=F){this.#t=e}static pk(){return R()}static"κ"=I.pk;annotate(e,t){return new L(t,e)}"δ"=this.annotate;get model(){return this.#e}get inspect(){return function(n,r,o,c,i){function s(c){const i=c.at(-1),s=$(n(),c),a=c.slice(0,-1),u=t.isNotEmpty(a)?$(n(),a):n();return[...e.isObject(s)||e.isArray(s)?r.get(o(s))?.filter(t=>e.isNullable(t.property))??[]:[],...e.isObject(u)?r.get(o(u))?.filter(e=>e.property===i)??[]:[]]}return function e(r){return new Proxy(()=>{},{get:(o,a)=>"pending"===a?()=>!t.isEmpty(s(r)):"remaining"===a?()=>t.length(s(r)):"box"===a?()=>({value:$(n(),r),inspect:e(r)}):"is"===a?e=>s(r).some(t=>0!==(t.operation&e)):"draft"===a?()=>t.head(s(r))?.value??$(n(),r):"settled"===a?()=>new Promise(e=>{if(t.isEmpty(s(r)))return e($(n(),r));const o=()=>{t.isEmpty(s(r))&&(i(o),e($(n(),r)))};c(o)}):e([...r,String(a)])})}([])}(()=>this.#e,this.#n,this.#t,e=>this.#r.add(e),e=>this.#r.delete(e))}hydrate(e){return this.#o=!0,this.#c(U.Hydrate,()=>e)}produce(e){if(!this.#o)throw new Error("State must be hydrated using hydrate() before calling produce()");return this.#c(U.Produce,e)}#c(e,t){const n=/* @__PURE__ */Symbol("process"),[,r]=T.immer.produceWithPatches(this.#e,t);return this.#e=r.reduce((t,r)=>T.immer.applyPatches(t,[{...r,value:H(e,r,t,n,this.#n,this.#t)}]),this.#e),this.#e=B(this.#e),this.#i(),n}prune(e){this.#n.forEach((n,r)=>{const o=n.filter(t=>t.process!==e);t.isEmpty(o)?this.#n.delete(r):this.#n.set(r,o)}),this.#i()}#i(){this.#r.forEach(e=>e())}observe(e){const t=()=>e(this.#e);return this.#r.add(t),()=>this.#r.delete(t)}}const V=new I;function q(e,t){return V.annotate(e,t)}function J(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var K,Q={exports:{}};const X=/* @__PURE__ */J((K||(K=1,function(e){var t=Object.prototype.hasOwnProperty,n="~";function r(){}function o(e,t,n){this.fn=e,this.context=t,this.once=n||!1}function c(e,t,r,c,i){if("function"!=typeof r)throw new TypeError("The listener must be a function");var s=new o(r,c||e,i),a=n?n+t:t;return e._events[a]?e._events[a].fn?e._events[a]=[e._events[a],s]:e._events[a].push(s):(e._events[a]=s,e._eventsCount++),e}function i(e,t){0===--e._eventsCount?e._events=new r:delete e._events[t]}function s(){this._events=new r,this._eventsCount=0}Object.create&&(r.prototype=/* @__PURE__ */Object.create(null),(new r).__proto__||(n=!1)),s.prototype.eventNames=function(){var e,r,o=[];if(0===this._eventsCount)return o;for(r in e=this._events)t.call(e,r)&&o.push(n?r.slice(1):r);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(e)):o},s.prototype.listeners=function(e){var t=this._events[n?n+e:e];if(!t)return[];if(t.fn)return[t.fn];for(var r=0,o=t.length,c=new Array(o);r<o;r++)c[r]=t[r].fn;return c},s.prototype.listenerCount=function(e){var t=this._events[n?n+e:e];return t?t.fn?1:t.length:0},s.prototype.emit=function(e,t,r,o,c,i){var s=n?n+e:e;if(!this._events[s])return!1;var a,u,l=this._events[s],f=arguments.length;if(l.fn){switch(l.once&&this.removeListener(e,l.fn,void 0,!0),f){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,t),!0;case 3:return l.fn.call(l.context,t,r),!0;case 4:return l.fn.call(l.context,t,r,o),!0;case 5:return l.fn.call(l.context,t,r,o,c),!0;case 6:return l.fn.call(l.context,t,r,o,c,i),!0}for(u=1,a=new Array(f-1);u<f;u++)a[u-1]=arguments[u];l.fn.apply(l.context,a)}else{var d,h=l.length;for(u=0;u<h;u++)switch(l[u].once&&this.removeListener(e,l[u].fn,void 0,!0),f){case 1:l[u].fn.call(l[u].context);break;case 2:l[u].fn.call(l[u].context,t);break;case 3:l[u].fn.call(l[u].context,t,r);break;case 4:l[u].fn.call(l[u].context,t,r,o);break;default:if(!a)for(d=1,a=new Array(f-1);d<f;d++)a[d-1]=arguments[d];l[u].fn.apply(l[u].context,a)}}return!0},s.prototype.on=function(e,t,n){return c(this,e,t,n,!1)},s.prototype.once=function(e,t,n){return c(this,e,t,n,!0)},s.prototype.removeListener=function(e,t,r,o){var c=n?n+e:e;if(!this._events[c])return this;if(!t)return i(this,c),this;var s=this._events[c];if(s.fn)s.fn!==t||o&&!s.once||r&&s.context!==r||i(this,c);else{for(var a=0,u=[],l=s.length;a<l;a++)(s[a].fn!==t||o&&!s[a].once||r&&s[a].context!==r)&&u.push(s[a]);u.length?this._events[c]=1===u.length?u[0]:u:i(this,c)}return this},s.prototype.removeAllListeners=function(e){var t;return e?this._events[t=n?n+e:e]&&i(this,t):(this._events=new r,this._eventsCount=0),this},s.prototype.off=s.prototype.removeListener,s.prototype.addListener=s.prototype.on,s.prefixed=n,s.EventEmitter=s,e.exports=s}(Q)),Q.exports));class Y extends X{cache=/* @__PURE__ */new Map;emit(e,...t){return this.cache.set(e,t[0]),super.emit(e,...t)}getCached(e){return this.cache.get(e)}}const Z=r.createContext(new Y);function ee({children:e}){const t=r.useMemo(()=>new Y,[]);/* @__PURE__ */
|
|
3
|
+
return n(Z.Provider,{value:t,children:e})}const te=r.createContext(/* @__PURE__ */new Map);function ne({children:e}){const t=r.useMemo(()=>/* @__PURE__ */new Map,[]);/* @__PURE__ */
|
|
4
|
+
return n(te.Provider,{value:t,children:e})}const re=r.createContext(/* @__PURE__ */new Set);function oe({children:e}){const t=r.useMemo(()=>/* @__PURE__ */new Set,[]);/* @__PURE__ */
|
|
5
|
+
return n(re.Provider,{value:t,children:e})}function ce({children:e}){/* @__PURE__ */
|
|
6
|
+
return n(ee,{children:/* @__PURE__ */n(ne,{children:/* @__PURE__ */n(oe,{children:e})})})}const ie=r.createContext(null);function se(){return r.useContext(ie)}function ae(e,t){return e?.get(t)??null}function ue({name:e,children:t}){const o=se(),c=r.useMemo(()=>({name:e,emitter:new Y}),[]),i=r.useMemo(()=>{const t=new Map(o??[]);return t.set(e,c),t},[o,e,c]);/* @__PURE__ */
|
|
7
|
+
return n(ie.Provider,{value:i,children:t})}function le(e,t){const r=`Scoped${t.displayName||t.name||"Component"}`;return{[r]:r=>/* @__PURE__ */n(ue,{name:e,children:/* @__PURE__ */n(t,{...r})})}[r]}function fe(e){return(t,n)=>{t.actions.produce(t=>{t.model[e]=n})}}function de(e,t,n){const o=r.useRef(n);r.useLayoutEffect(()=>{o.current=n});const c=r.useRef(t);r.useLayoutEffect(()=>{c.current=t});const i=r.useCallback(async(e,t)=>{const n=o.current;if("GeneratorFunction"===n.constructor.name||"AsyncGeneratorFunction"===n.constructor.name){const r=n(e,t);for await(const e of r);}else await n(e,t)},[]),s=r.useCallback(()=>x(c.current)?c.current.channel:void 0,[]),a=w(t),u=e.current.handlers.get(a)??/* @__PURE__ */new Set;0===u.size&&e.current.handlers.set(a,u),u.add({getChannel:s,handler:i})}function he(...n){const o=e.isUndefined(n[0])||e.isFunction(n[0])?{}:n[0],i=e.isFunction(n[0])?n[0]:n[1]??(()=>({})),s=r.useContext(Z),a=se(),f=c(k),h=r.useContext(re),p=r.useContext(te),m=function(){const[,e]=r.useReducer(e=>e+1,0);return e}(),y=r.useRef(!1),b=r.useRef(null),v=r.useRef(new I);y.current||(y.current=!0,b.current=v.current.hydrate(o));const[g,O]=r.useState(()=>v.current.model),E=function(e){const t=r.useRef(e);return r.useLayoutEffect(()=>{t.current=e},[e]),r.useMemo(()=>{return n=t,Object.keys(e).reduce((e,t)=>(Object.defineProperty(e,t,{get:()=>n.current[t],enumerable:!0}),e),{});var n},[e])}(i()),_=r.useMemo(()=>new X,[]),R=r.useRef({handlers:/* @__PURE__ */new Map});R.current.handlers=/* @__PURE__ */new Map;const N=function(){const e=r.useRef(/* @__PURE__ */new Set),t=r.useRef(/* @__PURE__ */new Set);return r.useMemo(()=>({broadcast:e.current,multicast:t.current}),[])}(),U=r.useRef(d.Mounting),z=function(){const e=r.useRef({}),t=r.useRef(/* @__PURE__ */new Map),n=r.useRef(/* @__PURE__ */new Map);return r.useMemo(()=>({refs:e,pending:t,emitted:n}),[])}(),L=r.useRef(/* @__PURE__ */new Set),T=r.useRef(0),$=r.useCallback((e,t,n)=>{const r=new AbortController,o={controller:r,action:e,payload:t};return h.add(o),L.current.add(o),{model:v.current.model,get phase(){return U.current},task:o,data:E,tasks:h,nodes:z.refs.current,actions:{produce(e){if(r.signal.aborted)return;const t=v.current.produce(t=>e({model:t,inspect:v.current.inspect}));O(v.current.model),n.processes.add(t),b.current&&(n.processes.add(b.current),b.current=null)},dispatch(e,t,n){if(r.signal.aborted)return;const o=w(e),c=x(e)?e.channel:void 0;if(A(e)&&n?.scope){const e=ae(a,n.scope);return void(e&&e.emitter.emit(o,t,c))}(P(e)?s:_).emit(o,t,c)},annotate:(e,t)=>v.current.annotate(e,t),async cacheable(e,t,n){if(r.signal.aborted)return{data:null};const o=j(e),c=p.get(o);if(c&&Date.now()<c.expiry)return{data:c.value};const i=function(e){return null!=e&&"object"==typeof e&&"TAG"in e?0===e.TAG?{ok:!0,value:e._0}:{ok:!1}:null==e?{ok:!1}:{ok:!0,value:e}}(await n());return i.ok?(p.set(o,{value:i.value,expiry:Date.now()+t}),{data:i.value}):{data:null}},invalidate(e){p.delete(j(e))},async read(e,t){if(r.signal.aborted)return null;const n=w(e),o=A(e)&&t?.scope?ae(a,t.scope)?.emitter??null:s;if(!o)return null;if(void 0===o.getCached(n))return null;const c=S(e),i="unknown"!==c?c[0].toLowerCase()+c.slice(1):null;if(i){const e=v.current.inspect[i];e?.pending?.()&&await new Promise((t,n)=>{if(r.signal.aborted)return void n(r.signal.reason);const o=()=>n(r.signal.reason);r.signal.addEventListener("abort",o,{once:!0}),e.settled().then(()=>{r.signal.removeEventListener("abort",o),t()})})}return o.getCached(n)??null}}}},[g]);r.useLayoutEffect(()=>{function t(t,n,r){return async function(o,c){const i=r();if(e.isNotNullable(c)&&e.isNotNullable(i)&&!function(e,t){for(const n of Object.keys(e))if(t[n]!==e[n])return!1;return!0}(c,i))return;const s={processes:/* @__PURE__ */new Set},a=Promise.withResolvers(),u=$(t,o,s);try{await n(u,o)}catch(d){const e=R.current.handlers.has(l.Error),n={reason:M(d),error:C(d),action:S(t),handled:e,tasks:h};f?.(n),e&&_.emit(l.Error,n)}finally{for(const e of h)if(e===u.task){h.delete(e),L.current.delete(e);break}s.processes.forEach(e=>v.current.prune(e)),s.processes.size>0&&m(),a.resolve()}}}T.current++;const n=/* @__PURE__ */new Set;return R.current.handlers.forEach((e,r)=>{for(const{getChannel:o,handler:c}of e){const e=t(r,c,o);if(A(r)){if(a)for(const t of a.values()){const o=t.emitter;o.on(r,e),n.add(()=>o.off(r,e))}_.on(r,e),N.multicast.add(r),n.add(()=>_.off(r,e))}else P(r)?(s.on(r,e),_.on(r,e),N.broadcast.add(r),n.add(()=>{s.off(r,e),_.off(r,e)})):(_.on(r,e),n.add(()=>_.off(r,e)))}}),()=>{const e=++T.current,t=new Set(n);queueMicrotask(()=>{if(T.current===e){for(const e of L.current)e.controller.abort(),h.delete(e);L.current.clear(),U.current=d.Unmounting,_.emit(l.Unmount),U.current=d.Unmounted;for(const e of t)e()}else for(const e of t)e()})}},[_]),r.useLayoutEffect(()=>{for(const[e,t]of z.pending.current)z.emitted.current.get(e)!==t&&(z.emitted.current.set(e,t),_.emit(u.Node,t,{Name:e}));z.pending.current.clear()}),function({unicast:n,broadcast:o,broadcastActions:c,phase:i,data:s}){const a=r.useRef(null);r.useLayoutEffect(()=>{i.current===d.Mounting&&(n.emit(l.Mount),c.forEach(t=>{const r=o.getCached(t);e.isNullable(r)||n.emit(t,r)}),i.current=d.Mounted)},[]),r.useLayoutEffect(()=>{if(e.isNotNullable(a.current)){const e=function(e,t){return Object.keys(t).reduce((n,r)=>e[r]!==t[r]?{...n,[r]:t[r]}:n,{})}(a.current,s);t.isNotEmpty(Object.keys(e))&&n.emit(l.Update,e)}a.current=s},[s,n])}({unicast:_,broadcast:s,broadcastActions:N.broadcast,phase:U,data:i()});const B=r.useMemo(()=>[g,{dispatch(e,t,n){const r=w(e),o=x(e)?e.channel:void 0;if(A(e)&&n?.scope){const e=ae(a,n.scope);return void(e&&e.emitter.emit(r,t,o))}(P(e)?s:_).emit(r,t,o)},get inspect(){return v.current.inspect},get nodes(){return z.refs.current},node(e,t){z.refs.current[e]=t,z.pending.current.set(e,t)}}],[g,_]);B.useAction=(e,t)=>{de(R,e,t)};const F=B,W=r.useRef({}),D=t=>{t.derive=(t,n,r)=>{if(e.isNullable(r))W.current[t]=n(F[0]);else if(r){t in W.current||(W.current[t]=null);const e=r;de(R,n,(n,r)=>{W.current[t]=e(r),m()})}const o=[{...F[0],...W.current},F[1]];return o.useAction=F.useAction,D(o),o}};return D(F),F}export{O as Action,ce as Boundary,f as Distribution,E as Entry,_ as Error,l as Lifecycle,N as Op,N as Operation,h as Reason,ue as Scope,I as State,fe as With,q as annotate,he as useActions,v as utils,le as withScope};
|
package/dist/chizu.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var global,factory;global=this,factory=function(e,t,n,r,o){"use strict";function c(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const n in e)if("default"!==n){const r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:()=>e[n]})}return t.default=e,Object.freeze(t)}const i=c(r);class s{static Payload=Symbol("chizu.brand/Payload");static Broadcast=Symbol("chizu.brand/Broadcast");static Multicast=Symbol("chizu.brand/Multicast");static Action=Symbol("chizu.brand/Action");static Channel=Symbol("chizu.brand/Channel");static Node=Symbol("chizu.action.lifecycle/Node");static Cache=Symbol("chizu.brand/Cache")}class a{static Mount=Symbol("chizu.action.lifecycle/Mount");static Unmount=Symbol("chizu.action.lifecycle/Unmount");static Error=Symbol("chizu.action.lifecycle/Error");static Update=Symbol("chizu.action.lifecycle/Update");static Node=(()=>{const e=s.Node,t=function(t){return{[s.Action]:e,[s.Payload]:void 0,[s.Channel]:t,channel:t}};return Object.defineProperty(t,s.Action,{value:e,enumerable:!1}),Object.defineProperty(t,s.Payload,{value:void 0,enumerable:!1}),t})()}var u=(e=>(e.Unicast="unicast",e.Broadcast="broadcast",e.Multicast="multicast",e))(u||{}),l=(e=>(e.Mounting="mounting",e.Mounted="mounted",e.Unmounting="unmounting",e.Unmounted="unmounted",e))(l||{}),f=(e=>(e[e.Timedout=0]="Timedout",e[e.Supplanted=1]="Supplanted",e[e.Disallowed=2]="Disallowed",e[e.Errored=3]="Errored",e[e.Unmounted=4]="Unmounted",e))(f||{});class d extends Error{name="AbortError";constructor(e="Aborted"){super(e)}}const p={actionPrefix:"chizu.action/",broadcastActionPrefix:"chizu.action/broadcast/",multicastActionPrefix:"chizu.action/multicast/",channelPrefix:"chizu.channel/",cachePrefix:"chizu.cache/"};function h(e,t){return new Promise((n,r)=>{if(t?.aborted)return void r(new d);const o=setTimeout(n,e);t?.addEventListener("abort",()=>{clearTimeout(o),r(new d)},{once:!0})})}function m(e){return e?Boolean(e&&"symbol"!=typeof e):Symbol(`pk.${Date.now()}.${crypto.randomUUID()}`)}const y=Object.freeze(Object.defineProperty({__proto__:null,config:p,pk:m,sleep:h,"ζ":h,"κ":m},Symbol.toStringTag,{value:"Module"})),b=e=>"symbol"==typeof e;function v(e){return t.G.isString(e)||b(e)?e:(t.G.isObject(e)||t.G.isFunction(e))&&s.Action in e?e[s.Action]:e}function g(e){if(t.G.isString(e))return e.startsWith(p.broadcastActionPrefix);if(b(e))return e.description?.startsWith(p.broadcastActionPrefix)??!1;if(t.G.isObject(e)||t.G.isFunction(e)){if(s.Broadcast in e&&e[s.Broadcast])return!0;if(s.Action in e){const t=e[s.Action];return t.description?.startsWith(p.broadcastActionPrefix)??!1}}return!1}function w(e){const n=v(e),r=t.G.isString(n)?n:n.description??"";return r.startsWith(p.actionPrefix)&&r.slice(r.lastIndexOf("/")+1)||"unknown"}function x(e){return t.G.isObject(e)&&s.Channel in e&&"channel"in e}function j(e){if(t.G.isString(e))return e.startsWith(p.multicastActionPrefix);if(b(e))return e.description?.startsWith(p.multicastActionPrefix)??!1;if(t.G.isObject(e)||t.G.isFunction(e)){if(s.Multicast in e&&e[s.Multicast])return!0;if(s.Action in e){const t=e[s.Action];return t.description?.startsWith(p.multicastActionPrefix)??!1}}return!1}function S(e){const t=function(e){return e[s.Cache]}(e),n=function(e){return"channel"in e}(e)&&(r=e.channel)?[...Object.keys(r)].toSorted().map(e=>`${e}=${String(r[e])}`).join("&"):"";var r;return`${String(t)}:${n}`}function P(e){if(e instanceof Error){if("TimeoutError"===e.name)return f.Timedout;if("AbortError"===e.name)return f.Supplanted}return f.Errored}function A(e){return e instanceof Error?e:new Error(String(e))}const O=r.createContext(void 0);let E=(e=21)=>{let t="",n=crypto.getRandomValues(new Uint8Array(e|=0));for(;e--;)t+="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"[63&n[e]];return t};var M=(e=>(e[e.Add=1]="Add",e[e.Remove=2]="Remove",e[e.Update=4]="Update",e[e.Move=8]="Move",e[e.Replace=16]="Replace",e[e.Sort=32]="Sort",e[e.Create=64]="Create",e[e.Fetch=128]="Fetch",e[e.Clone=256]="Clone",e[e.Archive=512]="Archive",e[e.Restore=1024]="Restore",e[e.Merge=2048]="Merge",e[e.Reorder=4096]="Reorder",e[e.Sync=8192]="Sync",e[e.Publish=16384]="Publish",e[e.Link=32768]="Link",e[e.Unlink=65536]="Unlink",e[e.Lock=131072]="Lock",e[e.Unlock=262144]="Unlock",e[e.Import=524288]="Import",e[e.Export=1048576]="Export",e[e.Transfer=2097152]="Transfer",e))(M||{}),C=(e=>(e[e.Produce=0]="Produce",e[e.Hydrate=1]="Hydrate",e))(C||{}),G=(e=>(e.Property="property",e.Process="process",e.Value="value",e.Operation="operation",e))(G||{});class k{[o.immerable]=!0;static keys=new Set(Object.values(G));property=null;process=null;value;operation;constructor(e,t){this.value=e,this.operation=t}assign(e,t){const n=new k(this.value,this.operation);return n.property=e,n.process=t,n}}class _{static immer=(()=>{o.enablePatches();const e=new o.Immer;return e.setAutoFreeze(!1),e})();static tag="κ";static id=E}function R(e,t){const n="string"==typeof t?""===t?[]:t.split("."):t;let r=e;for(const o of n){if(null==r)return;r=r[o]}return r}function N(e){if(t.G.isNullable(e)||L(e))return e;if(t.G.isArray(e))return e.map(e=>N(e));if(t.G.isObject(e)&&U(e)){const t=Object.entries(e).map(([e,t])=>[e,N(t)]);return{...Object.fromEntries(t),[_.tag]:e[_.tag]??_.id()}}return e}function z(e){if(Array.isArray(e))return e.filter(e=>_.tag in e).map(e=>e[_.tag]??"").join(",");const t=e[_.tag];if(t)return t;try{return JSON.stringify(e)}catch{return`[unserializable:${typeof e}]`}}function U(e){const t=Object.getPrototypeOf(e);return t===Object.prototype||null===t}function L(e){return t.G.isNullable(e)||t.G.isString(e)||t.G.isNumber(e)||t.G.isBoolean(e)||"symbol"==typeof e||"bigint"==typeof e}function T(e,n,r,o,c,i){return function s(a,u=n.path){if(a instanceof k){const n=R(r,u.join("."));if(Object.entries(a).filter(([e,t])=>!k.keys.has(e)&&t instanceof k).forEach(([e,t])=>s(t,u.concat(e))),L(a.value)){if(e===C.Hydrate)return a.value;const s=u.slice(0,-1),l=s.length>0?R(r,s.join(".")):r;return t.G.isNullable(l)||$(l,a,u.at(-1),o,c,i),n??a.value}if(e===C.Hydrate){const e=N(s(a.value,u));return $(e,a,null,o,c,i),e}const l=n??N(a.value);return $(l,a,null,o,c,i),t.G.isNullable(n)?l:(s(a.value,u),n)}if(t.G.isArray(a))return a.map((e,t)=>s(e,u.concat(t)));if(t.G.isObject(a)&&!U(a))return a;if(t.G.isObject(a)){const t=Object.entries(a).map(([e,t])=>[e,s(t,u.concat(e))]),n=Object.fromEntries(t);if(e===C.Hydrate){const e=N(n);return Object.entries(a).forEach(([t,n])=>{n instanceof k&&L(n.value)&&$(e,n,t,o,c,i)}),e}return n}return a}(n.value)}function $(e,t,n,r,o,c){const i=c(e),s=o.get(i)??[];o.set(i,[t.assign(n,r),...s])}class B{#e={};#t;#n=new Map;#r=new Set;#o=!1;constructor(e=z){this.#t=e}static pk(){return E()}static"κ"=B.pk;annotate(e,t){return new k(t,e)}"δ"=this.annotate;get model(){return this.#e}get inspect(){return function(e,n,r,o,c){function i(o){const c=o.at(-1),i=R(e(),o),s=o.slice(0,-1),a=t.A.isNotEmpty(s)?R(e(),s):e();return[...t.G.isObject(i)||t.G.isArray(i)?n.get(r(i))?.filter(e=>t.G.isNullable(e.property))??[]:[],...t.G.isObject(a)?n.get(r(a))?.filter(e=>e.property===c)??[]:[]]}return function n(r){return new Proxy(()=>{},{get:(s,a)=>"pending"===a?()=>!t.A.isEmpty(i(r)):"remaining"===a?()=>t.A.length(i(r)):"box"===a?()=>({value:R(e(),r),inspect:n(r)}):"is"===a?e=>i(r).some(t=>0!==(t.operation&e)):"draft"===a?()=>t.A.head(i(r))?.value??R(e(),r):"settled"===a?()=>new Promise(n=>{if(t.A.isEmpty(i(r)))return n(R(e(),r));const s=()=>{t.A.isEmpty(i(r))&&(c(s),n(R(e(),r)))};o(s)}):n([...r,String(a)])})}([])}(()=>this.#e,this.#n,this.#t,e=>this.#r.add(e),e=>this.#r.delete(e))}hydrate(e){return this.#o=!0,this.#c(C.Hydrate,()=>e)}produce(e){if(!this.#o)throw new Error("State must be hydrated using hydrate() before calling produce()");return this.#c(C.Produce,e)}#c(e,t){const n=Symbol("process"),[,r]=_.immer.produceWithPatches(this.#e,t);return this.#e=r.reduce((t,r)=>_.immer.applyPatches(t,[{...r,value:T(e,r,t,n,this.#n,this.#t)}]),this.#e),this.#e=N(this.#e),this.#i(),n}prune(e){this.#n.forEach((n,r)=>{const o=n.filter(t=>t.process!==e);t.A.isEmpty(o)?this.#n.delete(r):this.#n.set(r,o)}),this.#i()}#i(){this.#r.forEach(e=>e())}observe(e){const t=()=>e(this.#e);return this.#r.add(t),()=>this.#r.delete(t)}}const F=new B;function W(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var D,H={exports:{}},I=(D||(D=1,function(e){var t=Object.prototype.hasOwnProperty,n="~";function r(){}function o(e,t,n){this.fn=e,this.context=t,this.once=n||!1}function c(e,t,r,c,i){if("function"!=typeof r)throw new TypeError("The listener must be a function");var s=new o(r,c||e,i),a=n?n+t:t;return e._events[a]?e._events[a].fn?e._events[a]=[e._events[a],s]:e._events[a].push(s):(e._events[a]=s,e._eventsCount++),e}function i(e,t){0===--e._eventsCount?e._events=new r:delete e._events[t]}function s(){this._events=new r,this._eventsCount=0}Object.create&&(r.prototype=Object.create(null),(new r).__proto__||(n=!1)),s.prototype.eventNames=function(){var e,r,o=[];if(0===this._eventsCount)return o;for(r in e=this._events)t.call(e,r)&&o.push(n?r.slice(1):r);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(e)):o},s.prototype.listeners=function(e){var t=this._events[n?n+e:e];if(!t)return[];if(t.fn)return[t.fn];for(var r=0,o=t.length,c=new Array(o);r<o;r++)c[r]=t[r].fn;return c},s.prototype.listenerCount=function(e){var t=this._events[n?n+e:e];return t?t.fn?1:t.length:0},s.prototype.emit=function(e,t,r,o,c,i){var s=n?n+e:e;if(!this._events[s])return!1;var a,u,l=this._events[s],f=arguments.length;if(l.fn){switch(l.once&&this.removeListener(e,l.fn,void 0,!0),f){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,t),!0;case 3:return l.fn.call(l.context,t,r),!0;case 4:return l.fn.call(l.context,t,r,o),!0;case 5:return l.fn.call(l.context,t,r,o,c),!0;case 6:return l.fn.call(l.context,t,r,o,c,i),!0}for(u=1,a=new Array(f-1);u<f;u++)a[u-1]=arguments[u];l.fn.apply(l.context,a)}else{var d,p=l.length;for(u=0;u<p;u++)switch(l[u].once&&this.removeListener(e,l[u].fn,void 0,!0),f){case 1:l[u].fn.call(l[u].context);break;case 2:l[u].fn.call(l[u].context,t);break;case 3:l[u].fn.call(l[u].context,t,r);break;case 4:l[u].fn.call(l[u].context,t,r,o);break;default:if(!a)for(d=1,a=new Array(f-1);d<f;d++)a[d-1]=arguments[d];l[u].fn.apply(l[u].context,a)}}return!0},s.prototype.on=function(e,t,n){return c(this,e,t,n,!1)},s.prototype.once=function(e,t,n){return c(this,e,t,n,!0)},s.prototype.removeListener=function(e,t,r,o){var c=n?n+e:e;if(!this._events[c])return this;if(!t)return i(this,c),this;var s=this._events[c];if(s.fn)s.fn!==t||o&&!s.once||r&&s.context!==r||i(this,c);else{for(var a=0,u=[],l=s.length;a<l;a++)(s[a].fn!==t||o&&!s[a].once||r&&s[a].context!==r)&&u.push(s[a]);u.length?this._events[c]=1===u.length?u[0]:u:i(this,c)}return this},s.prototype.removeAllListeners=function(e){var t;return e?this._events[t=n?n+e:e]&&i(this,t):(this._events=new r,this._eventsCount=0),this},s.prototype.off=s.prototype.removeListener,s.prototype.addListener=s.prototype.on,s.prefixed=n,s.EventEmitter=s,e.exports=s}(H)),H.exports);const q=W(I),V=i.createContext(new q);function J(){return i.useContext(V)}function K({children:e}){const t=i.useMemo(()=>new q,[]);return n.jsx(V.Provider,{value:t,children:e})}const Q=i.createContext(new Map);function X(){return i.useContext(Q)}function Y(){const[,e]=i.useReducer(e=>e+1,0);return e}function Z({action:e,renderer:n}){const r=J(),o=X(),c=Y(),s=i.useMemo(()=>{const t=o.get(e);if(t)return t;const n={state:new B,listeners:new Set};return o.set(e,n),n},[e,o]);i.useLayoutEffect(()=>{function t(e){s.state.hydrate({value:e}),s.listeners.forEach(e=>e())}return s.listeners.add(c),r.on(e,t),()=>{s.listeners.delete(c),r.off(e,t)}},[e,r,s]);const a=s.state.model?.value;return t.G.isNullable(a)?null:n({value:a,inspect:s.state.inspect.value})}function ee({children:e}){const t=i.useMemo(()=>new Map,[]);return n.jsx(Q.Provider,{value:t,children:e})}const te=i.createContext(new Map);function ne({children:e}){const t=i.useMemo(()=>new Map,[]);return n.jsx(te.Provider,{value:t,children:e})}const re=i.createContext(new Set);function oe({children:e}){const t=i.useMemo(()=>new Set,[]);return n.jsx(re.Provider,{value:t,children:e})}const ce=i.createContext(null);function ie(){return i.useContext(ce)}function se(e,t){return e?.get(t)??null}function ae({action:e,scopeName:n,renderer:r}){const o=ie(),c=Y(),s=i.useMemo(()=>se(o,n),[o,n]),a=i.useMemo(()=>s?function(e,t){const n=e.store.get(t);if(n)return n;const r={state:new B,listeners:new Set};return e.store.set(t,r),r}(s,e):null,[e,s]);if(i.useLayoutEffect(()=>{if(s&&a)return a.listeners.add(c),s.emitter.on(e,t),()=>{a.listeners.delete(c),s.emitter.off(e,t)};function t(e){a&&(a.state.hydrate({value:e}),a.listeners.forEach(e=>e()))}},[e,s,a,c]),!a)return null;const u=a.state.model?.value;return t.G.isNullable(u)?null:r({value:u,inspect:a.state.inspect.value})}function ue({name:e,children:t}){const r=ie(),o=i.useMemo(()=>({name:e,emitter:new q,store:new Map,listeners:new Map}),[]),c=i.useMemo(()=>{const t=new Map(r??[]);return t.set(e,o),t},[r,e,o]);return n.jsx(ce.Provider,{value:c,children:t})}e.Action=(e,t=u.Unicast)=>{const n=t===u.Broadcast?Symbol(`${p.broadcastActionPrefix}${e}`):t===u.Multicast?Symbol(`${p.multicastActionPrefix}${e}`):Symbol(`${p.actionPrefix}${e}`),r=function(e){return{[s.Action]:n,[s.Payload]:void 0,[s.Channel]:e,channel:e}};return Object.defineProperty(r,s.Action,{value:n,enumerable:!1}),Object.defineProperty(r,s.Payload,{value:void 0,enumerable:!1}),t===u.Broadcast&&Object.defineProperty(r,s.Broadcast,{value:!0,enumerable:!1}),t===u.Multicast&&Object.defineProperty(r,s.Multicast,{value:!0,enumerable:!1}),r},e.Boundary=function({children:e}){return n.jsx(K,{children:n.jsx(ee,{children:n.jsx(ne,{children:n.jsx(oe,{children:e})})})})},e.Distribution=u,e.Entry=function(){const e=Symbol("chizu.cache/Entry"),t=function(t){return{[s.Cache]:e,channel:t}};return Object.defineProperty(t,s.Cache,{value:e,enumerable:!1}),t},e.Error=function({handler:e,children:t}){return n.jsx(O.Provider,{value:e,children:t})},e.Lifecycle=a,e.Op=M,e.Operation=M,e.Reason=f,e.Scope=ue,e.State=B,e.With=function(e){return(t,n)=>{t.actions.produce(t=>{t.model[e]=n})}},e.annotate=function(e,t){return F.annotate(e,t)},e.useActions=function(...e){const n=t.G.isUndefined(e[0])||t.G.isFunction(e[0])?{}:e[0],o=t.G.isFunction(e[0])?e[0]:e[1]??(()=>({})),c=J(),u=ie(),f=X(),p=r.useContext(O),h=i.useContext(re),m=i.useContext(te),y=Y(),b=i.useRef(!1),E=i.useRef(null),M=i.useRef(new B);b.current||(b.current=!0,E.current=M.current.hydrate(n));const[C,G]=i.useState(()=>M.current.model),k=function(e){const t=i.useRef(e);return i.useLayoutEffect(()=>{t.current=e},[e]),i.useMemo(()=>{return n=t,Object.keys(e).reduce((e,t)=>(Object.defineProperty(e,t,{get:()=>n.current[t],enumerable:!0}),e),{});var n},[e])}(o()),_=i.useMemo(()=>new q,[]),R=i.useRef({handlers:new Map});R.current.handlers=new Map;const N=function(){const e=i.useRef(new Set),t=i.useRef(new Set);return i.useMemo(()=>({broadcast:e.current,multicast:t.current}),[])}(),z=i.useRef(l.Mounting),U=function(){const e=i.useRef({}),t=i.useRef(new Map),n=i.useRef(new Map);return i.useMemo(()=>({refs:e,pending:t,emitted:n}),[])}(),L=i.useRef(new Set),T=i.useRef(0),$=i.useCallback((e,t,n)=>{const r=new AbortController,o={controller:r,action:e,payload:t};return h.add(o),L.current.add(o),{model:M.current.model,get phase(){return z.current},task:o,data:k,tasks:h,nodes:U.refs.current,actions:{produce(e){if(r.signal.aborted)return;const t=M.current.produce(t=>e({model:t,inspect:M.current.inspect}));G(M.current.model),n.processes.add(t),E.current&&(n.processes.add(E.current),E.current=null)},dispatch(e,t,n){if(r.signal.aborted)return;const o=v(e),i=x(e)?e.channel:void 0;if(j(e)&&n?.scope){const e=se(u,n.scope);return void(e&&e.emitter.emit(o,t,i))}(g(e)?c:_).emit(o,t,i)},annotate:(e,t)=>M.current.annotate(e,t),async cacheable(e,t,n){if(r.signal.aborted)return{data:null};const o=S(e),c=m.get(o);if(c&&Date.now()<c.expiry)return{data:c.value};const i=function(e){return null!=e&&"object"==typeof e&&"TAG"in e?0===e.TAG?{ok:!0,value:e._0}:{ok:!1}:null==e?{ok:!1}:{ok:!0,value:e}}(await n());return i.ok?(m.set(o,{value:i.value,expiry:Date.now()+t}),{data:i.value}):{data:null}},invalidate(e){m.delete(S(e))},async consume(e,t){if(r.signal.aborted)return null;const n=v(e);let o;if(j(e)&&t?.scope){const e=se(u,t.scope);if(!e)return null;o=e.store.get(n)}else o=f.get(n);if(!o?.state.model?.value)return null;const c=o.state.inspect;return c.value.pending()&&await new Promise((e,t)=>{if(r.signal.aborted)return void t(new d);const n=()=>t(new d);r.signal.addEventListener("abort",n,{once:!0}),c.value.settled().then(()=>{r.signal.removeEventListener("abort",n),e()})}),o.state.model.value}}}},[C]);i.useLayoutEffect(()=>{function e(e,n,r){return async function(o,c){const i=r();if(t.G.isNotNullable(c)&&t.G.isNotNullable(i)&&!function(e,t){for(const n of Object.keys(e))if(t[n]!==e[n])return!1;return!0}(c,i))return;const s={processes:new Set},u=Promise.withResolvers(),l=$(e,o,s);try{await n(l,o)}catch(f){const t=R.current.handlers.has(a.Error),n={reason:P(f),error:A(f),action:w(e),handled:t,tasks:h};p?.(n),t&&_.emit(a.Error,n)}finally{for(const e of h)if(e===l.task){h.delete(e),L.current.delete(e);break}s.processes.forEach(e=>M.current.prune(e)),s.processes.size>0&&y(),u.resolve()}}}T.current++;const n=new Set;return R.current.handlers.forEach((t,r)=>{for(const{getChannel:o,handler:i}of t){const t=e(r,i,o);if(j(r)){if(u)for(const e of u.values()){const o=e.emitter;o.on(r,t),n.add(()=>o.off(r,t))}_.on(r,t),N.multicast.add(r),n.add(()=>_.off(r,t))}else g(r)?(c.on(r,t),_.on(r,t),N.broadcast.add(r),n.add(()=>{c.off(r,t),_.off(r,t)})):(_.on(r,t),n.add(()=>_.off(r,t)))}}),()=>{const e=++T.current,t=new Set(n);queueMicrotask(()=>{if(T.current===e){for(const e of L.current)e.controller.abort(),h.delete(e);L.current.clear(),z.current=l.Unmounting,_.emit(a.Unmount),z.current=l.Unmounted;for(const e of t)e()}else for(const e of t)e()})}},[_]),i.useLayoutEffect(()=>{for(const[e,t]of U.pending.current)U.emitted.current.get(e)!==t&&(U.emitted.current.set(e,t),_.emit(s.Node,t,{Name:e}));U.pending.current.clear()}),function({unicast:e,broadcastActions:n,phase:r,data:o}){const c=X(),s=i.useRef(null);i.useLayoutEffect(()=>{r.current===l.Mounting&&(e.emit(a.Mount),n.forEach(n=>{const r=c.get(n),o=r?.state.model?.value;t.G.isNullable(o)||e.emit(n,o)}),r.current=l.Mounted)},[]),i.useLayoutEffect(()=>{if(t.G.isNotNullable(s.current)){const n=function(e,t){return Object.keys(t).reduce((n,r)=>e[r]!==t[r]?{...n,[r]:t[r]}:n,{})}(s.current,o);t.A.isNotEmpty(Object.keys(n))&&e.emit(a.Update,n)}s.current=o},[o,e])}({unicast:_,broadcastActions:N.broadcast,phase:z,data:o()});const F=i.useMemo(()=>[C,{dispatch(e,t,n){const r=v(e),o=x(e)?e.channel:void 0;if(j(e)&&n?.scope){const e=se(u,n.scope);return void(e&&e.emitter.emit(r,t,o))}(g(e)?c:_).emit(r,t,o)},consume:(e,t,n)=>j(e)&&n?.scope?i.createElement(ae,{action:v(e),scopeName:n.scope,renderer:t}):i.createElement(Z,{action:v(e),renderer:t}),get inspect(){return M.current.inspect},get nodes(){return U.refs.current},node(e,t){U.refs.current[e]=t,U.pending.current.set(e,t)}}],[C,_]);return F.useAction=(e,t)=>{!function(e,t,n){const r=i.useRef(n);i.useLayoutEffect(()=>{r.current=n});const o=i.useRef(t);i.useLayoutEffect(()=>{o.current=t});const c=i.useCallback(async(e,t)=>{const n=r.current;if("GeneratorFunction"===n.constructor.name||"AsyncGeneratorFunction"===n.constructor.name){const r=n(e,t);for await(const e of r);}else await n(e,t)},[]),s=i.useCallback(()=>x(o.current)?o.current.channel:void 0,[]),a=v(t),u=e.current.handlers.get(a)??new Set;0===u.size&&e.current.handlers.set(a,u),u.add({getChannel:s,handler:c})}(R,e,t)},F},e.utils=y,e.withScope=function(e,t){const r=`Scoped${t.displayName||t.name||"Component"}`;return{[r]:r=>n.jsx(ue,{name:e,children:n.jsx(t,{...r})})}[r]},Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})},"object"==typeof exports&&"undefined"!=typeof module?factory(exports,require("@mobily/ts-belt"),require("react/jsx-runtime"),require("react"),require("immer")):"function"==typeof define&&define.amd?define(["exports","@mobily/ts-belt","react/jsx-runtime","react","immer"],factory):factory((global="undefined"!=typeof globalThis?globalThis:global||self).Chizu={},global.TsBelt,global.jsxRuntime,global.React,global.Immer);
|
|
1
|
+
var global,factory;global=this,factory=function(e,t,n,r,o){"use strict";function c(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const n in e)if("default"!==n){const r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:()=>e[n]})}return t.default=e,Object.freeze(t)}const i=c(r);class s{static Payload=Symbol("chizu.brand/Payload");static Broadcast=Symbol("chizu.brand/Broadcast");static Multicast=Symbol("chizu.brand/Multicast");static Action=Symbol("chizu.brand/Action");static Channel=Symbol("chizu.brand/Channel");static Node=Symbol("chizu.action.lifecycle/Node");static Cache=Symbol("chizu.brand/Cache")}class a{static Mount=Symbol("chizu.action.lifecycle/Mount");static Unmount=Symbol("chizu.action.lifecycle/Unmount");static Error=Symbol("chizu.action.lifecycle/Error");static Update=Symbol("chizu.action.lifecycle/Update");static Node=(()=>{const e=s.Node,t=function(t){return{[s.Action]:e,[s.Payload]:void 0,[s.Channel]:t,channel:t}};return Object.defineProperty(t,s.Action,{value:e,enumerable:!1}),Object.defineProperty(t,s.Payload,{value:void 0,enumerable:!1}),t})()}var u=(e=>(e.Unicast="unicast",e.Broadcast="broadcast",e.Multicast="multicast",e))(u||{}),l=(e=>(e.Mounting="mounting",e.Mounted="mounted",e.Unmounting="unmounting",e.Unmounted="unmounted",e))(l||{}),f=(e=>(e[e.Timedout=0]="Timedout",e[e.Supplanted=1]="Supplanted",e[e.Disallowed=2]="Disallowed",e[e.Errored=3]="Errored",e[e.Unmounted=4]="Unmounted",e))(f||{});class d extends Error{name="AbortError";constructor(e="Aborted"){super(e)}}const h={actionPrefix:"chizu.action/",broadcastActionPrefix:"chizu.action/broadcast/",multicastActionPrefix:"chizu.action/multicast/",channelPrefix:"chizu.channel/",cachePrefix:"chizu.cache/"};function p(e,t){return new Promise((n,r)=>{if(t?.aborted)return void r(new d);const o=setTimeout(n,e);t?.addEventListener("abort",()=>{clearTimeout(o),r(new d)},{once:!0})})}function m(e){return e?Boolean(e&&"symbol"!=typeof e):Symbol(`pk.${Date.now()}.${crypto.randomUUID()}`)}const b=Object.freeze(Object.defineProperty({__proto__:null,config:h,pk:m,sleep:p,"ζ":p,"κ":m},Symbol.toStringTag,{value:"Module"})),y=e=>"symbol"==typeof e;function v(e){return t.G.isString(e)||y(e)?e:(t.G.isObject(e)||t.G.isFunction(e))&&s.Action in e?e[s.Action]:e}function g(e){if(t.G.isString(e))return e.startsWith(h.broadcastActionPrefix);if(y(e))return e.description?.startsWith(h.broadcastActionPrefix)??!1;if(t.G.isObject(e)||t.G.isFunction(e)){if(s.Broadcast in e&&e[s.Broadcast])return!0;if(s.Action in e){const t=e[s.Action];return t.description?.startsWith(h.broadcastActionPrefix)??!1}}return!1}function w(e){const n=v(e),r=t.G.isString(n)?n:n.description??"";return r.startsWith(h.actionPrefix)&&r.slice(r.lastIndexOf("/")+1)||"unknown"}function x(e){return t.G.isObject(e)&&s.Channel in e&&"channel"in e}function j(e){if(t.G.isString(e))return e.startsWith(h.multicastActionPrefix);if(y(e))return e.description?.startsWith(h.multicastActionPrefix)??!1;if(t.G.isObject(e)||t.G.isFunction(e)){if(s.Multicast in e&&e[s.Multicast])return!0;if(s.Action in e){const t=e[s.Action];return t.description?.startsWith(h.multicastActionPrefix)??!1}}return!1}function S(e){const t=function(e){return e[s.Cache]}(e),n=function(e){return"channel"in e}(e)&&(r=e.channel)?[...Object.keys(r)].toSorted().map(e=>`${e}=${String(r[e])}`).join("&"):"";var r;return`${String(t)}:${n}`}function A(e){if(e instanceof Error){if("TimeoutError"===e.name)return f.Timedout;if("AbortError"===e.name)return f.Supplanted}return f.Errored}function P(e){return e instanceof Error?e:new Error(String(e))}const O=r.createContext(void 0);let E=(e=21)=>{let t="",n=crypto.getRandomValues(new Uint8Array(e|=0));for(;e--;)t+="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"[63&n[e]];return t};var M=(e=>(e[e.Add=1]="Add",e[e.Remove=2]="Remove",e[e.Update=4]="Update",e[e.Move=8]="Move",e[e.Replace=16]="Replace",e[e.Sort=32]="Sort",e[e.Create=64]="Create",e[e.Fetch=128]="Fetch",e[e.Clone=256]="Clone",e[e.Archive=512]="Archive",e[e.Restore=1024]="Restore",e[e.Merge=2048]="Merge",e[e.Reorder=4096]="Reorder",e[e.Sync=8192]="Sync",e[e.Publish=16384]="Publish",e[e.Link=32768]="Link",e[e.Unlink=65536]="Unlink",e[e.Lock=131072]="Lock",e[e.Unlock=262144]="Unlock",e[e.Import=524288]="Import",e[e.Export=1048576]="Export",e[e.Transfer=2097152]="Transfer",e))(M||{}),C=(e=>(e[e.Produce=0]="Produce",e[e.Hydrate=1]="Hydrate",e))(C||{}),k=(e=>(e.Property="property",e.Process="process",e.Value="value",e.Operation="operation",e))(k||{});class G{[o.immerable]=!0;static keys=new Set(Object.values(k));property=null;process=null;value;operation;constructor(e,t){this.value=e,this.operation=t}assign(e,t){const n=new G(this.value,this.operation);return n.property=e,n.process=t,n}}class _{static immer=(()=>{o.enablePatches();const e=new o.Immer;return e.setAutoFreeze(!1),e})();static tag="κ";static id=E}function R(e,t){const n="string"==typeof t?""===t?[]:t.split("."):t;let r=e;for(const o of n){if(null==r)return;r=r[o]}return r}function N(e){if(t.G.isNullable(e)||L(e))return e;if(t.G.isArray(e))return e.map(e=>N(e));if(t.G.isObject(e)&&U(e)){const t=Object.entries(e).map(([e,t])=>[e,N(t)]);return{...Object.fromEntries(t),[_.tag]:e[_.tag]??_.id()}}return e}function z(e){if(Array.isArray(e))return e.filter(e=>_.tag in e).map(e=>e[_.tag]??"").join(",");const t=e[_.tag];if(t)return t;try{return JSON.stringify(e)}catch{return`[unserializable:${typeof e}]`}}function U(e){const t=Object.getPrototypeOf(e);return t===Object.prototype||null===t}function L(e){return t.G.isNullable(e)||t.G.isString(e)||t.G.isNumber(e)||t.G.isBoolean(e)||"symbol"==typeof e||"bigint"==typeof e}function T(e,n,r,o,c,i){return function s(a,u=n.path){if(a instanceof G){const n=R(r,u.join("."));if(Object.entries(a).filter(([e,t])=>!G.keys.has(e)&&t instanceof G).forEach(([e,t])=>s(t,u.concat(e))),L(a.value)){if(e===C.Hydrate)return a.value;const s=u.slice(0,-1),l=s.length>0?R(r,s.join(".")):r;return t.G.isNullable(l)||$(l,a,u.at(-1),o,c,i),n??a.value}if(e===C.Hydrate){const e=N(s(a.value,u));return $(e,a,null,o,c,i),e}const l=n??N(a.value);return $(l,a,null,o,c,i),t.G.isNullable(n)?l:(s(a.value,u),n)}if(t.G.isArray(a))return a.map((e,t)=>s(e,u.concat(t)));if(t.G.isObject(a)&&!U(a))return a;if(t.G.isObject(a)){const t=Object.entries(a).map(([e,t])=>[e,s(t,u.concat(e))]),n=Object.fromEntries(t);if(e===C.Hydrate){const e=N(n);return Object.entries(a).forEach(([t,n])=>{n instanceof G&&L(n.value)&&$(e,n,t,o,c,i)}),e}return n}return a}(n.value)}function $(e,t,n,r,o,c){const i=c(e),s=o.get(i)??[];o.set(i,[t.assign(n,r),...s])}class B{#e={};#t;#n=new Map;#r=new Set;#o=!1;constructor(e=z){this.#t=e}static pk(){return E()}static"κ"=B.pk;annotate(e,t){return new G(t,e)}"δ"=this.annotate;get model(){return this.#e}get inspect(){return function(e,n,r,o,c){function i(o){const c=o.at(-1),i=R(e(),o),s=o.slice(0,-1),a=t.A.isNotEmpty(s)?R(e(),s):e();return[...t.G.isObject(i)||t.G.isArray(i)?n.get(r(i))?.filter(e=>t.G.isNullable(e.property))??[]:[],...t.G.isObject(a)?n.get(r(a))?.filter(e=>e.property===c)??[]:[]]}return function n(r){return new Proxy(()=>{},{get:(s,a)=>"pending"===a?()=>!t.A.isEmpty(i(r)):"remaining"===a?()=>t.A.length(i(r)):"box"===a?()=>({value:R(e(),r),inspect:n(r)}):"is"===a?e=>i(r).some(t=>0!==(t.operation&e)):"draft"===a?()=>t.A.head(i(r))?.value??R(e(),r):"settled"===a?()=>new Promise(n=>{if(t.A.isEmpty(i(r)))return n(R(e(),r));const s=()=>{t.A.isEmpty(i(r))&&(c(s),n(R(e(),r)))};o(s)}):n([...r,String(a)])})}([])}(()=>this.#e,this.#n,this.#t,e=>this.#r.add(e),e=>this.#r.delete(e))}hydrate(e){return this.#o=!0,this.#c(C.Hydrate,()=>e)}produce(e){if(!this.#o)throw new Error("State must be hydrated using hydrate() before calling produce()");return this.#c(C.Produce,e)}#c(e,t){const n=Symbol("process"),[,r]=_.immer.produceWithPatches(this.#e,t);return this.#e=r.reduce((t,r)=>_.immer.applyPatches(t,[{...r,value:T(e,r,t,n,this.#n,this.#t)}]),this.#e),this.#e=N(this.#e),this.#i(),n}prune(e){this.#n.forEach((n,r)=>{const o=n.filter(t=>t.process!==e);t.A.isEmpty(o)?this.#n.delete(r):this.#n.set(r,o)}),this.#i()}#i(){this.#r.forEach(e=>e())}observe(e){const t=()=>e(this.#e);return this.#r.add(t),()=>this.#r.delete(t)}}const F=new B;function W(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var D,H={exports:{}},I=(D||(D=1,function(e){var t=Object.prototype.hasOwnProperty,n="~";function r(){}function o(e,t,n){this.fn=e,this.context=t,this.once=n||!1}function c(e,t,r,c,i){if("function"!=typeof r)throw new TypeError("The listener must be a function");var s=new o(r,c||e,i),a=n?n+t:t;return e._events[a]?e._events[a].fn?e._events[a]=[e._events[a],s]:e._events[a].push(s):(e._events[a]=s,e._eventsCount++),e}function i(e,t){0===--e._eventsCount?e._events=new r:delete e._events[t]}function s(){this._events=new r,this._eventsCount=0}Object.create&&(r.prototype=Object.create(null),(new r).__proto__||(n=!1)),s.prototype.eventNames=function(){var e,r,o=[];if(0===this._eventsCount)return o;for(r in e=this._events)t.call(e,r)&&o.push(n?r.slice(1):r);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(e)):o},s.prototype.listeners=function(e){var t=this._events[n?n+e:e];if(!t)return[];if(t.fn)return[t.fn];for(var r=0,o=t.length,c=new Array(o);r<o;r++)c[r]=t[r].fn;return c},s.prototype.listenerCount=function(e){var t=this._events[n?n+e:e];return t?t.fn?1:t.length:0},s.prototype.emit=function(e,t,r,o,c,i){var s=n?n+e:e;if(!this._events[s])return!1;var a,u,l=this._events[s],f=arguments.length;if(l.fn){switch(l.once&&this.removeListener(e,l.fn,void 0,!0),f){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,t),!0;case 3:return l.fn.call(l.context,t,r),!0;case 4:return l.fn.call(l.context,t,r,o),!0;case 5:return l.fn.call(l.context,t,r,o,c),!0;case 6:return l.fn.call(l.context,t,r,o,c,i),!0}for(u=1,a=new Array(f-1);u<f;u++)a[u-1]=arguments[u];l.fn.apply(l.context,a)}else{var d,h=l.length;for(u=0;u<h;u++)switch(l[u].once&&this.removeListener(e,l[u].fn,void 0,!0),f){case 1:l[u].fn.call(l[u].context);break;case 2:l[u].fn.call(l[u].context,t);break;case 3:l[u].fn.call(l[u].context,t,r);break;case 4:l[u].fn.call(l[u].context,t,r,o);break;default:if(!a)for(d=1,a=new Array(f-1);d<f;d++)a[d-1]=arguments[d];l[u].fn.apply(l[u].context,a)}}return!0},s.prototype.on=function(e,t,n){return c(this,e,t,n,!1)},s.prototype.once=function(e,t,n){return c(this,e,t,n,!0)},s.prototype.removeListener=function(e,t,r,o){var c=n?n+e:e;if(!this._events[c])return this;if(!t)return i(this,c),this;var s=this._events[c];if(s.fn)s.fn!==t||o&&!s.once||r&&s.context!==r||i(this,c);else{for(var a=0,u=[],l=s.length;a<l;a++)(s[a].fn!==t||o&&!s[a].once||r&&s[a].context!==r)&&u.push(s[a]);u.length?this._events[c]=1===u.length?u[0]:u:i(this,c)}return this},s.prototype.removeAllListeners=function(e){var t;return e?this._events[t=n?n+e:e]&&i(this,t):(this._events=new r,this._eventsCount=0),this},s.prototype.off=s.prototype.removeListener,s.prototype.addListener=s.prototype.on,s.prefixed=n,s.EventEmitter=s,e.exports=s}(H)),H.exports);const q=W(I);class V extends q{cache=new Map;emit(e,...t){return this.cache.set(e,t[0]),super.emit(e,...t)}getCached(e){return this.cache.get(e)}}const J=i.createContext(new V);function K({children:e}){const t=i.useMemo(()=>new V,[]);return n.jsx(J.Provider,{value:t,children:e})}const Q=i.createContext(new Map);function X({children:e}){const t=i.useMemo(()=>new Map,[]);return n.jsx(Q.Provider,{value:t,children:e})}const Y=i.createContext(new Set);function Z({children:e}){const t=i.useMemo(()=>new Set,[]);return n.jsx(Y.Provider,{value:t,children:e})}const ee=i.createContext(null);function te(){return i.useContext(ee)}function ne(e,t){return e?.get(t)??null}function re({name:e,children:t}){const r=te(),o=i.useMemo(()=>({name:e,emitter:new V}),[]),c=i.useMemo(()=>{const t=new Map(r??[]);return t.set(e,o),t},[r,e,o]);return n.jsx(ee.Provider,{value:c,children:t})}function oe(e,t,n){const r=i.useRef(n);i.useLayoutEffect(()=>{r.current=n});const o=i.useRef(t);i.useLayoutEffect(()=>{o.current=t});const c=i.useCallback(async(e,t)=>{const n=r.current;if("GeneratorFunction"===n.constructor.name||"AsyncGeneratorFunction"===n.constructor.name){const r=n(e,t);for await(const e of r);}else await n(e,t)},[]),s=i.useCallback(()=>x(o.current)?o.current.channel:void 0,[]),a=v(t),u=e.current.handlers.get(a)??new Set;0===u.size&&e.current.handlers.set(a,u),u.add({getChannel:s,handler:c})}e.Action=(e,t=u.Unicast)=>{const n=t===u.Broadcast?Symbol(`${h.broadcastActionPrefix}${e}`):t===u.Multicast?Symbol(`${h.multicastActionPrefix}${e}`):Symbol(`${h.actionPrefix}${e}`),r=function(e){return{[s.Action]:n,[s.Payload]:void 0,[s.Channel]:e,channel:e}};return Object.defineProperty(r,s.Action,{value:n,enumerable:!1}),Object.defineProperty(r,s.Payload,{value:void 0,enumerable:!1}),t===u.Broadcast&&Object.defineProperty(r,s.Broadcast,{value:!0,enumerable:!1}),t===u.Multicast&&Object.defineProperty(r,s.Multicast,{value:!0,enumerable:!1}),r},e.Boundary=function({children:e}){return n.jsx(K,{children:n.jsx(X,{children:n.jsx(Z,{children:e})})})},e.Distribution=u,e.Entry=function(){const e=Symbol("chizu.cache/Entry"),t=function(t){return{[s.Cache]:e,channel:t}};return Object.defineProperty(t,s.Cache,{value:e,enumerable:!1}),t},e.Error=function({handler:e,children:t}){return n.jsx(O.Provider,{value:e,children:t})},e.Lifecycle=a,e.Op=M,e.Operation=M,e.Reason=f,e.Scope=re,e.State=B,e.With=function(e){return(t,n)=>{t.actions.produce(t=>{t.model[e]=n})}},e.annotate=function(e,t){return F.annotate(e,t)},e.useActions=function(...e){const n=t.G.isUndefined(e[0])||t.G.isFunction(e[0])?{}:e[0],o=t.G.isFunction(e[0])?e[0]:e[1]??(()=>({})),c=i.useContext(J),u=te(),f=r.useContext(O),d=i.useContext(Y),h=i.useContext(Q),p=function(){const[,e]=i.useReducer(e=>e+1,0);return e}(),m=i.useRef(!1),b=i.useRef(null),y=i.useRef(new B);m.current||(m.current=!0,b.current=y.current.hydrate(n));const[E,M]=i.useState(()=>y.current.model),C=function(e){const t=i.useRef(e);return i.useLayoutEffect(()=>{t.current=e},[e]),i.useMemo(()=>{return n=t,Object.keys(e).reduce((e,t)=>(Object.defineProperty(e,t,{get:()=>n.current[t],enumerable:!0}),e),{});var n},[e])}(o()),k=i.useMemo(()=>new q,[]),G=i.useRef({handlers:new Map});G.current.handlers=new Map;const _=function(){const e=i.useRef(new Set),t=i.useRef(new Set);return i.useMemo(()=>({broadcast:e.current,multicast:t.current}),[])}(),R=i.useRef(l.Mounting),N=function(){const e=i.useRef({}),t=i.useRef(new Map),n=i.useRef(new Map);return i.useMemo(()=>({refs:e,pending:t,emitted:n}),[])}(),z=i.useRef(new Set),U=i.useRef(0),L=i.useCallback((e,t,n)=>{const r=new AbortController,o={controller:r,action:e,payload:t};return d.add(o),z.current.add(o),{model:y.current.model,get phase(){return R.current},task:o,data:C,tasks:d,nodes:N.refs.current,actions:{produce(e){if(r.signal.aborted)return;const t=y.current.produce(t=>e({model:t,inspect:y.current.inspect}));M(y.current.model),n.processes.add(t),b.current&&(n.processes.add(b.current),b.current=null)},dispatch(e,t,n){if(r.signal.aborted)return;const o=v(e),i=x(e)?e.channel:void 0;if(j(e)&&n?.scope){const e=ne(u,n.scope);return void(e&&e.emitter.emit(o,t,i))}(g(e)?c:k).emit(o,t,i)},annotate:(e,t)=>y.current.annotate(e,t),async cacheable(e,t,n){if(r.signal.aborted)return{data:null};const o=S(e),c=h.get(o);if(c&&Date.now()<c.expiry)return{data:c.value};const i=function(e){return null!=e&&"object"==typeof e&&"TAG"in e?0===e.TAG?{ok:!0,value:e._0}:{ok:!1}:null==e?{ok:!1}:{ok:!0,value:e}}(await n());return i.ok?(h.set(o,{value:i.value,expiry:Date.now()+t}),{data:i.value}):{data:null}},invalidate(e){h.delete(S(e))},async read(e,t){if(r.signal.aborted)return null;const n=v(e),o=j(e)&&t?.scope?ne(u,t.scope)?.emitter??null:c;if(!o)return null;if(void 0===o.getCached(n))return null;const i=w(e),s="unknown"!==i?i[0].toLowerCase()+i.slice(1):null;if(s){const e=y.current.inspect[s];e?.pending?.()&&await new Promise((t,n)=>{if(r.signal.aborted)return void n(r.signal.reason);const o=()=>n(r.signal.reason);r.signal.addEventListener("abort",o,{once:!0}),e.settled().then(()=>{r.signal.removeEventListener("abort",o),t()})})}return o.getCached(n)??null}}}},[E]);i.useLayoutEffect(()=>{function e(e,n,r){return async function(o,c){const i=r();if(t.G.isNotNullable(c)&&t.G.isNotNullable(i)&&!function(e,t){for(const n of Object.keys(e))if(t[n]!==e[n])return!1;return!0}(c,i))return;const s={processes:new Set},u=Promise.withResolvers(),l=L(e,o,s);try{await n(l,o)}catch(h){const t=G.current.handlers.has(a.Error),n={reason:A(h),error:P(h),action:w(e),handled:t,tasks:d};f?.(n),t&&k.emit(a.Error,n)}finally{for(const e of d)if(e===l.task){d.delete(e),z.current.delete(e);break}s.processes.forEach(e=>y.current.prune(e)),s.processes.size>0&&p(),u.resolve()}}}U.current++;const n=new Set;return G.current.handlers.forEach((t,r)=>{for(const{getChannel:o,handler:i}of t){const t=e(r,i,o);if(j(r)){if(u)for(const e of u.values()){const o=e.emitter;o.on(r,t),n.add(()=>o.off(r,t))}k.on(r,t),_.multicast.add(r),n.add(()=>k.off(r,t))}else g(r)?(c.on(r,t),k.on(r,t),_.broadcast.add(r),n.add(()=>{c.off(r,t),k.off(r,t)})):(k.on(r,t),n.add(()=>k.off(r,t)))}}),()=>{const e=++U.current,t=new Set(n);queueMicrotask(()=>{if(U.current===e){for(const e of z.current)e.controller.abort(),d.delete(e);z.current.clear(),R.current=l.Unmounting,k.emit(a.Unmount),R.current=l.Unmounted;for(const e of t)e()}else for(const e of t)e()})}},[k]),i.useLayoutEffect(()=>{for(const[e,t]of N.pending.current)N.emitted.current.get(e)!==t&&(N.emitted.current.set(e,t),k.emit(s.Node,t,{Name:e}));N.pending.current.clear()}),function({unicast:e,broadcast:n,broadcastActions:r,phase:o,data:c}){const s=i.useRef(null);i.useLayoutEffect(()=>{o.current===l.Mounting&&(e.emit(a.Mount),r.forEach(r=>{const o=n.getCached(r);t.G.isNullable(o)||e.emit(r,o)}),o.current=l.Mounted)},[]),i.useLayoutEffect(()=>{if(t.G.isNotNullable(s.current)){const n=function(e,t){return Object.keys(t).reduce((n,r)=>e[r]!==t[r]?{...n,[r]:t[r]}:n,{})}(s.current,c);t.A.isNotEmpty(Object.keys(n))&&e.emit(a.Update,n)}s.current=c},[c,e])}({unicast:k,broadcast:c,broadcastActions:_.broadcast,phase:R,data:o()});const T=i.useMemo(()=>[E,{dispatch(e,t,n){const r=v(e),o=x(e)?e.channel:void 0;if(j(e)&&n?.scope){const e=ne(u,n.scope);return void(e&&e.emitter.emit(r,t,o))}(g(e)?c:k).emit(r,t,o)},get inspect(){return y.current.inspect},get nodes(){return N.refs.current},node(e,t){N.refs.current[e]=t,N.pending.current.set(e,t)}}],[E,k]);T.useAction=(e,t)=>{oe(G,e,t)};const $=T,F=i.useRef({}),W=e=>{e.derive=(e,n,r)=>{if(t.G.isNullable(r))F.current[e]=n($[0]);else if(r){e in F.current||(F.current[e]=null);const t=r;oe(G,n,(n,r)=>{F.current[e]=t(r),p()})}const o=[{...$[0],...F.current},$[1]];return o.useAction=$.useAction,W(o),o}};return W($),$},e.utils=b,e.withScope=function(e,t){const r=`Scoped${t.displayName||t.name||"Component"}`;return{[r]:r=>n.jsx(re,{name:e,children:n.jsx(t,{...r})})}[r]},Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})},"object"==typeof exports&&"undefined"!=typeof module?factory(exports,require("@mobily/ts-belt"),require("react/jsx-runtime"),require("react"),require("immer")):"function"==typeof define&&define.amd?define(["exports","@mobily/ts-belt","react/jsx-runtime","react","immer"],factory):factory((global="undefined"!=typeof globalThis?globalThis:global||self).Chizu={},global.TsBelt,global.jsxRuntime,global.React,global.Immer);
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export { With } from './utils.ts';
|
|
|
10
10
|
*
|
|
11
11
|
* The hook returns a result containing:
|
|
12
12
|
* 1. The current model state
|
|
13
|
-
* 2. An actions object with `dispatch`, `
|
|
13
|
+
* 2. An actions object with `dispatch`, `inspect`, and `useAction`
|
|
14
14
|
*
|
|
15
15
|
* The `inspect` property provides access to Immertation's annotation system,
|
|
16
16
|
* allowing you to check for pending operations on model properties.
|
package/dist/hooks/types.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { default as EventEmitter } from 'eventemitter3';
|
|
2
2
|
import { RefObject } from 'react';
|
|
3
3
|
import { Model, HandlerContext, Actions, Props, Tasks, ActionId, Phase, Filter, Nodes } from '../types/index.ts';
|
|
4
|
+
import { BroadcastEmitter } from '../boundary/components/broadcast/utils.ts';
|
|
4
5
|
/**
|
|
5
6
|
* Return type for the useNodes hook.
|
|
6
7
|
* Contains refs for captured nodes, pending captures, and last emitted nodes.
|
|
@@ -22,17 +23,17 @@ export type References<M extends Model | void> = {
|
|
|
22
23
|
* Receives the reactive context and payload, returning void or a promise/generator.
|
|
23
24
|
*
|
|
24
25
|
* @template M - The model type
|
|
25
|
-
* @template
|
|
26
|
+
* @template A - The actions class type
|
|
26
27
|
* @template D - The data props type
|
|
27
28
|
*/
|
|
28
|
-
export type Handler<M extends Model | void = Model,
|
|
29
|
+
export type Handler<M extends Model | void = Model, A extends Actions | void = Actions, D extends Props = Props> = (context: HandlerContext<M, A, D>, payload: unknown) => void | Promise<void> | AsyncGenerator | Generator;
|
|
29
30
|
/**
|
|
30
31
|
* Entry for an action handler with a reactive channel getter.
|
|
31
32
|
* When getChannel returns undefined, the handler fires for all dispatches.
|
|
32
33
|
* When getChannel returns a channel, dispatches must match.
|
|
33
34
|
*/
|
|
34
|
-
export type HandlerEntry<M extends Model | void = Model,
|
|
35
|
-
handler: Handler<M,
|
|
35
|
+
export type HandlerEntry<M extends Model | void = Model, A extends Actions | void = Actions, D extends Props = Props> = {
|
|
36
|
+
handler: Handler<M, A, D>;
|
|
36
37
|
getChannel: () => Filter | undefined;
|
|
37
38
|
};
|
|
38
39
|
/**
|
|
@@ -40,12 +41,12 @@ export type HandlerEntry<M extends Model | void = Model, AC extends Actions | vo
|
|
|
40
41
|
* Maps action IDs to sets of handler entries (with optional channels).
|
|
41
42
|
*
|
|
42
43
|
* @template M - The model type
|
|
43
|
-
* @template
|
|
44
|
+
* @template A - The actions class type
|
|
44
45
|
* @template D - The data props type
|
|
45
46
|
*/
|
|
46
|
-
export type Scope<M extends Model | void = Model,
|
|
47
|
+
export type Scope<M extends Model | void = Model, A extends Actions | void = Actions, D extends Props = Props> = {
|
|
47
48
|
/** All handlers for each action, with optional channels */
|
|
48
|
-
handlers: Map<ActionId, Set<HandlerEntry<M,
|
|
49
|
+
handlers: Map<ActionId, Set<HandlerEntry<M, A, D>>>;
|
|
49
50
|
};
|
|
50
51
|
/**
|
|
51
52
|
* Function type for the data snapshot passed to useActions.
|
|
@@ -59,6 +60,7 @@ export type Data<D extends Props = Props> = () => D;
|
|
|
59
60
|
*/
|
|
60
61
|
export type LifecycleConfig = {
|
|
61
62
|
unicast: EventEmitter;
|
|
63
|
+
broadcast: BroadcastEmitter;
|
|
62
64
|
tasks: Tasks;
|
|
63
65
|
broadcastActions: Set<ActionId>;
|
|
64
66
|
phase: RefObject<Phase>;
|
package/dist/hooks/utils.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ export declare function isGenerator(result: unknown): result is Generator | Asyn
|
|
|
24
24
|
* - Mounting → (cached broadcast action values emitted here) → Mounted
|
|
25
25
|
* - Mounted → Unmounting → Unmounted
|
|
26
26
|
*/
|
|
27
|
-
export declare function useLifecycles({ unicast, broadcastActions, phase, data, }: LifecycleConfig): void;
|
|
27
|
+
export declare function useLifecycles({ unicast, broadcast, broadcastActions, phase, data, }: LifecycleConfig): void;
|
|
28
28
|
/**
|
|
29
29
|
* Creates a data proxy for a given object, returning a memoized version.
|
|
30
30
|
* The proxy provides stable access to the object's properties,
|
|
@@ -68,7 +68,7 @@ export declare function useData<P extends Props>(props: P): P;
|
|
|
68
68
|
* actions.useAction(Actions.Visitor, With("name")); // Country -> string ✗
|
|
69
69
|
* ```
|
|
70
70
|
*/
|
|
71
|
-
export declare function With<K extends string>(key: K): <M extends Model,
|
|
71
|
+
export declare function With<K extends string>(key: K): <M extends Model, A extends Actions | void, D extends Props, P extends K extends keyof M ? M[K] : never>(context: HandlerContext<M, A, D>, payload: P) => void;
|
|
72
72
|
export { isChanneledAction, getActionSymbol };
|
|
73
73
|
/**
|
|
74
74
|
* Return type for useActionSets hook.
|
|
@@ -139,7 +139,7 @@ export declare function useActionSets(): ActionSets;
|
|
|
139
139
|
*
|
|
140
140
|
* @internal
|
|
141
141
|
*/
|
|
142
|
-
export declare function useRegisterHandler<M extends Model | void,
|
|
142
|
+
export declare function useRegisterHandler<M extends Model | void, A extends Actions | void, D extends Props>(scope: React.RefObject<Scope<M, A, D>>, action: ActionId | HandlerPayload | ChanneledAction, handler: (context: HandlerContext<M, A, D>, payload: unknown) => void | Promise<void> | AsyncGenerator | Generator): void;
|
|
143
143
|
/**
|
|
144
144
|
* Manages captured DOM nodes for a model type.
|
|
145
145
|
* Returns refs for nodes, pending captures, and last emitted nodes.
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { Operation, Process, Inspect, Box } from 'immertation';
|
|
2
2
|
import { ActionId, Task, Tasks } from '../boundary/components/tasks/types.ts';
|
|
3
|
-
import { ConsumerRenderer } from '../boundary/components/consumer/index.tsx';
|
|
4
3
|
import { Option } from '@mobily/ts-belt/Option';
|
|
5
4
|
import { Result as TsBeltResult } from '@mobily/ts-belt/Result';
|
|
6
|
-
import type * as React from "react";
|
|
7
5
|
export type { ActionId, Box, Task, Tasks };
|
|
8
|
-
export type { ConsumerRenderer };
|
|
9
6
|
/**
|
|
10
7
|
* Type for objects with a Brand.Action symbol property.
|
|
11
8
|
* Used for type-safe access to the action symbol.
|
|
@@ -148,7 +145,7 @@ export declare class Lifecycle {
|
|
|
148
145
|
* - **Unicast** – Action is scoped to the component that defines it and cannot be
|
|
149
146
|
* consumed by other components. This is the default behaviour.
|
|
150
147
|
* - **Broadcast** – Action is distributed to all mounted components that have defined
|
|
151
|
-
* a handler for it.
|
|
148
|
+
* a handler for it. Values are cached for late-mounting components.
|
|
152
149
|
*
|
|
153
150
|
* @example
|
|
154
151
|
* ```ts
|
|
@@ -261,24 +258,21 @@ export type ChanneledAction<P = unknown, C = unknown> = {
|
|
|
261
258
|
};
|
|
262
259
|
/**
|
|
263
260
|
* Branded type for broadcast action objects created with `Action()` and `Distribution.Broadcast`.
|
|
264
|
-
* Broadcast actions are sent to all mounted components
|
|
261
|
+
* Broadcast actions are sent to all mounted components. Values are cached so that
|
|
262
|
+
* late-mounting components receive the most recent payload.
|
|
265
263
|
*
|
|
266
264
|
* This type extends `HandlerPayload<P, C>` with an additional brand to enforce at compile-time
|
|
267
|
-
* that only broadcast actions can be passed to `
|
|
268
|
-
* a local action will result in a TypeScript error.
|
|
265
|
+
* that only broadcast actions can be passed to `context.actions.read()`.
|
|
269
266
|
*
|
|
270
267
|
* @template P - The payload type for the action
|
|
271
268
|
* @template C - The channel type for channeled dispatches (defaults to never)
|
|
272
269
|
*
|
|
273
270
|
* @example
|
|
274
271
|
* ```ts
|
|
275
|
-
* // This compiles - SignedOut is a broadcast action
|
|
276
272
|
* const SignedOut = Action<User>("SignedOut", Distribution.Broadcast);
|
|
277
|
-
* actions.consume(SignedOut, (box) => <div>{box.value.name}</div>);
|
|
278
273
|
*
|
|
279
|
-
* //
|
|
280
|
-
* const
|
|
281
|
-
* actions.consume(Increment, ...); // Type error!
|
|
274
|
+
* // Read the latest value inside a handler
|
|
275
|
+
* const user = await context.actions.read(SignedOut);
|
|
282
276
|
* ```
|
|
283
277
|
*/
|
|
284
278
|
export type BroadcastPayload<P = unknown, C extends Filter = never> = HandlerPayload<P, C> & {
|
|
@@ -342,7 +336,9 @@ export type MulticastOptions = {
|
|
|
342
336
|
*
|
|
343
337
|
* @template A - The action type (HandlerPayload or ChanneledAction)
|
|
344
338
|
*/
|
|
345
|
-
export type Payload<A> = A extends
|
|
339
|
+
export type Payload<A> = A extends {
|
|
340
|
+
readonly [Brand.Payload]: infer P;
|
|
341
|
+
} ? P : never;
|
|
346
342
|
/**
|
|
347
343
|
* Filter object for channeled actions.
|
|
348
344
|
* Must be an object where each value is a non-nullable primitive.
|
|
@@ -590,24 +586,20 @@ export type HandlerContext<M extends Model | void, _AC extends Actions | void, D
|
|
|
590
586
|
*/
|
|
591
587
|
invalidate(entry: CacheId<unknown> | ChanneledCacheId<unknown>): void;
|
|
592
588
|
/**
|
|
593
|
-
* Reads the latest broadcast or multicast value
|
|
594
|
-
*
|
|
595
|
-
* Returns the raw value `T` or `null` if no value has been dispatched.
|
|
596
|
-
* If the value has pending annotations, awaits `settled()` before returning.
|
|
597
|
-
* Respects the task's abort signal — returns `null` if the task is aborted
|
|
598
|
-
* while waiting.
|
|
589
|
+
* Reads the latest broadcast or multicast value, waiting for it if necessary.
|
|
599
590
|
*
|
|
600
|
-
*
|
|
601
|
-
*
|
|
591
|
+
* If a value has already been dispatched it resolves immediately.
|
|
592
|
+
* Otherwise it waits until the next dispatch of the action.
|
|
593
|
+
* Resolves with `null` if the task is aborted before a value arrives.
|
|
602
594
|
*
|
|
603
595
|
* @param action - The broadcast or multicast action to read.
|
|
604
596
|
* @param options - For multicast actions, must include `{ scope: "ScopeName" }`.
|
|
605
|
-
* @returns The
|
|
597
|
+
* @returns The dispatched value, or `null` if aborted.
|
|
606
598
|
*
|
|
607
599
|
* @example
|
|
608
600
|
* ```ts
|
|
609
601
|
* actions.useAction(Actions.FetchPosts, async (context) => {
|
|
610
|
-
* const user = await context.actions.
|
|
602
|
+
* const user = await context.actions.read(Actions.Broadcast.User);
|
|
611
603
|
* if (!user) return;
|
|
612
604
|
* const posts = await fetchPosts(user.id, {
|
|
613
605
|
* signal: context.task.controller.signal,
|
|
@@ -616,8 +608,8 @@ export type HandlerContext<M extends Model | void, _AC extends Actions | void, D
|
|
|
616
608
|
* });
|
|
617
609
|
* ```
|
|
618
610
|
*/
|
|
619
|
-
|
|
620
|
-
|
|
611
|
+
read<T>(action: BroadcastPayload<T>): Promise<T | null>;
|
|
612
|
+
read<T>(action: MulticastPayload<T>, options: MulticastOptions): Promise<T | null>;
|
|
621
613
|
};
|
|
622
614
|
};
|
|
623
615
|
/**
|
|
@@ -625,7 +617,7 @@ export type HandlerContext<M extends Model | void, _AC extends Actions | void, D
|
|
|
625
617
|
*
|
|
626
618
|
* A tuple containing:
|
|
627
619
|
* 1. The current model state of type M
|
|
628
|
-
* 2. An actions object with dispatch
|
|
620
|
+
* 2. An actions object with dispatch and inspect capabilities
|
|
629
621
|
*
|
|
630
622
|
* @template M - The model type representing the component's state
|
|
631
623
|
* @template AC - The actions class containing action definitions
|
|
@@ -640,9 +632,6 @@ export type HandlerContext<M extends Model | void, _AC extends Actions | void, D
|
|
|
640
632
|
* // Dispatch actions
|
|
641
633
|
* actions.dispatch(Actions.Increment, 5);
|
|
642
634
|
*
|
|
643
|
-
* // Consume action values declaratively
|
|
644
|
-
* {actions.consume(Actions.Data, (box) => box.value.name)}
|
|
645
|
-
*
|
|
646
635
|
* // Check pending state
|
|
647
636
|
* actions.inspect.count.pending();
|
|
648
637
|
* ```
|
|
@@ -658,39 +647,22 @@ export type HandlerContext<M extends Model | void, _AC extends Actions | void, D
|
|
|
658
647
|
*
|
|
659
648
|
* @see {@link Handlers} for the recommended HKT pattern
|
|
660
649
|
*/
|
|
661
|
-
export type Handler<M extends Model | void, AC extends Actions | void, K extends keyof AC & string, D extends Props = Props> = (context: HandlerContext<M, AC, D>, payload: Payload<AC[K] & HandlerPayload<unknown>>) => void | Promise<void> | AsyncGenerator | Generator;
|
|
662
|
-
/**
|
|
663
|
-
* Resolves the action value at a (possibly dot-notated) path within an actions object.
|
|
664
|
-
* For a simple key like `"SetName"`, returns `AC["SetName"]`.
|
|
665
|
-
* For a dotted key like `"Broadcast.PaymentSent"`, recursively resolves to
|
|
666
|
-
* `AC["Broadcast"]["PaymentSent"]`.
|
|
667
|
-
*
|
|
668
|
-
* @template AC - The actions object to traverse
|
|
669
|
-
* @template K - The key path (may contain dots)
|
|
670
|
-
*/
|
|
671
|
-
type DeepAction<AC, K extends string> = K extends `${infer Head}.${infer Tail}` ? Head extends keyof AC ? DeepAction<AC[Head], Tail> : never : K extends keyof AC ? AC[K] : never;
|
|
650
|
+
export type Handler<M extends Model | void, AC extends Actions | void, K extends keyof AC & string, D extends Props = Props> = (context: HandlerContext<M, AC, D>, ...args: [Payload<AC[K] & HandlerPayload<unknown>>] extends [never] ? [] : [payload: Payload<AC[K] & HandlerPayload<unknown>>]) => void | Promise<void> | AsyncGenerator | Generator;
|
|
672
651
|
/**
|
|
673
|
-
*
|
|
674
|
-
*
|
|
675
|
-
*
|
|
676
|
-
*
|
|
677
|
-
* Nested namespaces like `Broadcast = { PaymentSent, PaymentLink }` produce
|
|
678
|
-
* `"Broadcast.PaymentSent" | "Broadcast.PaymentLink"`.
|
|
679
|
-
*
|
|
680
|
-
* @template AC - The actions object to flatten
|
|
681
|
-
* @template Prefix - Accumulated prefix for recursion (defaults to never)
|
|
652
|
+
* String keys of `AC` excluding inherited `prototype` from class constructors.
|
|
653
|
+
* When action containers are classes (`typeof MyActions`), TypeScript includes
|
|
654
|
+
* `"prototype"` in `keyof`. Excluding it prevents `prototype` from appearing
|
|
655
|
+
* as a handler key and avoids recursion into Function internals.
|
|
682
656
|
*/
|
|
683
|
-
type
|
|
684
|
-
[K in keyof AC & string]: keyof AC[K] & string extends never ? [Prefix] extends [never] ? K : `${Prefix}.${K}` : FlattenKeys<AC[K], [Prefix] extends [never] ? K : `${Prefix}.${K}`>;
|
|
685
|
-
}[keyof AC & string];
|
|
657
|
+
type OwnKeys<AC> = Exclude<keyof AC & string, "prototype">;
|
|
686
658
|
/**
|
|
687
|
-
*
|
|
688
|
-
* Creates a mapped type where each action key maps to its fully-typed handler.
|
|
659
|
+
* Recursive mapped type for action handlers that mirrors the action class hierarchy.
|
|
689
660
|
*
|
|
690
|
-
*
|
|
691
|
-
*
|
|
661
|
+
* For leaf actions (values with no own string keys, i.e. `HandlerPayload`), produces
|
|
662
|
+
* a handler function signature. For namespace objects (containing nested actions),
|
|
663
|
+
* produces a nested `Handlers` object.
|
|
692
664
|
*
|
|
693
|
-
*
|
|
665
|
+
* Access handlers using bracket notation matching the action structure:
|
|
694
666
|
*
|
|
695
667
|
* @template M - The model type
|
|
696
668
|
* @template AC - The actions class type
|
|
@@ -712,16 +684,21 @@ type FlattenKeys<AC, Prefix extends string = never> = {
|
|
|
712
684
|
*
|
|
713
685
|
* type H = Handlers<Model, typeof Actions>;
|
|
714
686
|
*
|
|
715
|
-
* // Flat actions
|
|
687
|
+
* // Flat actions
|
|
716
688
|
* export const handleSetName: H["SetName"] = (context, name) => { ... };
|
|
717
689
|
*
|
|
718
|
-
* // Nested actions use
|
|
719
|
-
* export const handlePaymentSent: H["Broadcast
|
|
690
|
+
* // Nested actions use chained bracket notation
|
|
691
|
+
* export const handlePaymentSent: H["Broadcast"]["PaymentSent"] = (context) => { ... };
|
|
720
692
|
* ```
|
|
721
693
|
*/
|
|
722
694
|
export type Handlers<M extends Model | void, AC extends Actions | void, D extends Props = Props> = {
|
|
723
|
-
[K in
|
|
695
|
+
[K in OwnKeys<AC>]: OwnKeys<AC[K]> extends never ? (context: HandlerContext<M, AC, D>, ...args: [Payload<AC[K] & HandlerPayload<unknown>>] extends [never] ? [] : [payload: Payload<AC[K] & HandlerPayload<unknown>>]) => void | Promise<void> | AsyncGenerator | Generator : Handlers<M, AC[K] & Actions, D>;
|
|
724
696
|
};
|
|
697
|
+
/**
|
|
698
|
+
* Union of action types accepted by `derive` configuration entries.
|
|
699
|
+
* @internal
|
|
700
|
+
*/
|
|
701
|
+
type DerivedAction = HandlerPayload<any> | ChanneledAction<any, any>;
|
|
725
702
|
export type UseActions<M extends Model | void, AC extends Actions | void, D extends Props = Props> = [
|
|
726
703
|
Readonly<M>,
|
|
727
704
|
{
|
|
@@ -741,39 +718,6 @@ export type UseActions<M extends Model | void, AC extends Actions | void, D exte
|
|
|
741
718
|
dispatch<P>(action: BroadcastPayload<P>, payload?: P, options?: MulticastOptions): void;
|
|
742
719
|
dispatch<P>(action: MulticastPayload<P>, payload: P, options: MulticastOptions): void;
|
|
743
720
|
dispatch<P, C extends Filter>(action: ChanneledAction<P, C>, payload?: P, options?: MulticastOptions): void;
|
|
744
|
-
/**
|
|
745
|
-
* Subscribes to a distributed or multicast action's values and renders based on the callback.
|
|
746
|
-
* The callback receives a Box with `value` (the payload) and `inspect` (for annotation status).
|
|
747
|
-
* On mount, displays the most recent value from the Consumer/Scope store if available.
|
|
748
|
-
*
|
|
749
|
-
* Supports three usage patterns:
|
|
750
|
-
* 1. Consuming broadcast actions from the local actions class (with autocomplete)
|
|
751
|
-
* 2. Consuming any broadcast action from external modules
|
|
752
|
-
* 3. Consuming multicast actions with a scope name
|
|
753
|
-
*
|
|
754
|
-
* @param action - The distributed or multicast action to consume
|
|
755
|
-
* @param renderer - Render function receiving the Box
|
|
756
|
-
* @param options - For multicast actions, must include `{ scope: "ScopeName" }`
|
|
757
|
-
* @returns React element rendered by the callback
|
|
758
|
-
*
|
|
759
|
-
* @example
|
|
760
|
-
* ```tsx
|
|
761
|
-
* // Local broadcast action (from same actions class)
|
|
762
|
-
* {actions.consume(Actions.Visitor, (visitor) =>
|
|
763
|
-
* visitor.inspect.pending() ? "Loading..." : visitor.value.name
|
|
764
|
-
* )}
|
|
765
|
-
*
|
|
766
|
-
* // External broadcast action
|
|
767
|
-
* {actions.consume(SharedActions.Counter, (counter) => counter.value)}
|
|
768
|
-
*
|
|
769
|
-
* // Multicast action with scope
|
|
770
|
-
* {actions.consume(Actions.Multicast.Update, (update) => update.value, { scope: "MyScope" })}
|
|
771
|
-
* ```
|
|
772
|
-
*/
|
|
773
|
-
consume<T>(action: BroadcastPayload<T>, renderer: ConsumerRenderer<T>): React.ReactNode;
|
|
774
|
-
consume<T>(action: MulticastPayload<T>, renderer: ConsumerRenderer<T>, options: MulticastOptions): React.ReactNode;
|
|
775
|
-
consume<K extends keyof AC>(action: AC[K] & BroadcastPayload<unknown>, renderer: ConsumerRenderer<Payload<AC[K]>>): React.ReactNode;
|
|
776
|
-
consume<K extends keyof AC>(action: AC[K] & MulticastPayload<unknown>, renderer: ConsumerRenderer<Payload<AC[K]>>, options: MulticastOptions): React.ReactNode;
|
|
777
721
|
inspect: Inspect<M>;
|
|
778
722
|
/**
|
|
779
723
|
* Captured DOM nodes registered via `node()`.
|
|
@@ -849,5 +793,38 @@ export type UseActions<M extends Model | void, AC extends Actions | void, D exte
|
|
|
849
793
|
* });
|
|
850
794
|
* ```
|
|
851
795
|
*/
|
|
852
|
-
useAction<A extends ActionId | HandlerPayload | ChanneledAction>(action: A, handler: (context: HandlerContext<M, AC, D>, payload: Payload<A>) => void | Promise<void> | AsyncGenerator | Generator): void;
|
|
796
|
+
useAction<A extends ActionId | HandlerPayload | ChanneledAction>(action: A, handler: (context: HandlerContext<M, AC, D>, ...args: [Payload<A>] extends [never] ? [] : [payload: Payload<A>]) => void | Promise<void> | AsyncGenerator | Generator): void;
|
|
797
|
+
/**
|
|
798
|
+
* Derives a model property from the current model state. The selector
|
|
799
|
+
* evaluates synchronously on every render and always has a value.
|
|
800
|
+
*
|
|
801
|
+
* @param key - The property name to add to the model
|
|
802
|
+
* @param selector - A function receiving the current model, returning the derived value
|
|
803
|
+
* @returns A new UseActions tuple with the model extended by the derived property
|
|
804
|
+
*
|
|
805
|
+
* @example
|
|
806
|
+
* ```ts
|
|
807
|
+
* actions.derive('greeting', (model) => `Hey ${model.name}`);
|
|
808
|
+
* ```
|
|
809
|
+
*/
|
|
810
|
+
derive<K extends string, R>(key: M extends void ? never : K, selector: (model: Readonly<M>) => R): UseActions<M & Record<K, R>, AC, D>;
|
|
811
|
+
/**
|
|
812
|
+
* Derives a model property from an action's payload. When the action fires,
|
|
813
|
+
* the callback runs and the return value is applied to the model under the
|
|
814
|
+
* given key. Before the action fires the value is `null`.
|
|
815
|
+
*
|
|
816
|
+
* Works with unicast, broadcast, multicast, and channeled actions.
|
|
817
|
+
* For broadcast actions, cached values are replayed on mount.
|
|
818
|
+
*
|
|
819
|
+
* @param key - The property name to add to the model
|
|
820
|
+
* @param action - The action to subscribe to
|
|
821
|
+
* @param callback - Receives the action payload, returns the derived value
|
|
822
|
+
* @returns A new UseActions tuple with the model extended by the derived property
|
|
823
|
+
*
|
|
824
|
+
* @example
|
|
825
|
+
* ```ts
|
|
826
|
+
* actions.derive('doubled', Actions.Broadcast.Counter, (counter) => counter * 2);
|
|
827
|
+
* ```
|
|
828
|
+
*/
|
|
829
|
+
derive<K extends string, A extends DerivedAction, R>(key: M extends void ? never : K, action: A, callback: [Payload<A>] extends [never] ? () => R : (payload: Payload<A>) => R): UseActions<M & Record<K, R | null>, AC, D>;
|
|
853
830
|
};
|
package/package.json
CHANGED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { ConsumerRenderer } from '../consumer/types.ts';
|
|
2
|
-
import { ActionId } from '../tasks/types.ts';
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
/**
|
|
5
|
-
* Props for the MulticastPartition component.
|
|
6
|
-
*/
|
|
7
|
-
export type Props<T> = {
|
|
8
|
-
/** The multicast action symbol to subscribe to */
|
|
9
|
-
action: ActionId;
|
|
10
|
-
/** The scope name to subscribe to */
|
|
11
|
-
scopeName: string;
|
|
12
|
-
/** Callback that receives a Box and returns React nodes */
|
|
13
|
-
renderer: ConsumerRenderer<T>;
|
|
14
|
-
};
|
|
15
|
-
/**
|
|
16
|
-
* Renders output for multicast `consume()` by subscribing to scope action events.
|
|
17
|
-
*
|
|
18
|
-
* Similar to the broadcast Partition component, but subscribes to a named scope's
|
|
19
|
-
* EventEmitter instead of the global broadcast emitter.
|
|
20
|
-
*
|
|
21
|
-
* On mount, if a value was previously dispatched for this action within the scope,
|
|
22
|
-
* it renders immediately with that cached value. If no value exists yet, it renders
|
|
23
|
-
* `null` until the first dispatch.
|
|
24
|
-
*
|
|
25
|
-
* @template T - The payload type for the action
|
|
26
|
-
* @param props.action - The multicast action symbol to subscribe to
|
|
27
|
-
* @param props.scopeName - The scope name to subscribe to
|
|
28
|
-
* @param props.renderer - Callback that receives a Box and returns React nodes
|
|
29
|
-
* @returns The result of calling renderer with the Box, or null if no value/scope exists
|
|
30
|
-
* @internal
|
|
31
|
-
*/
|
|
32
|
-
export declare function MulticastPartition<T extends object>({ action, scopeName, renderer, }: Props<T>): React.ReactNode;
|