chizu 0.2.64 → 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 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 simply want to read the `name` when it's updated we can use consume:
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
- export default function Subscriptions(): React.ReactElement {
183
- return (
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
- However if we want to listen for it and perform another operation in our local component we can do that via `useAction`:
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.consume`:
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.consume(Actions.Broadcast.Name);
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
- // Consume with scope
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 &ndash; 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.
@@ -3,10 +3,10 @@ import * as React from "react";
3
3
  /**
4
4
  * EventEmitter subclass that caches the latest payload per event.
5
5
  *
6
- * When a broadcast action is dispatched, the payload is stored so that
7
- * late-mounting components can replay it via {@link useLifecycles} —
8
- * even when no `consume()` call created a Partition to cache the value
9
- * in the consumer Map.
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
10
  */
11
11
  export declare class BroadcastEmitter extends EventEmitter {
12
12
  private cache;
@@ -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 supports `consume()` for declarative rendering
20
- * and provides late-mounted components with the most recent dispatched value.
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 { default as EventEmitter } from 'eventemitter3';
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 EventEmitter and consumer store.
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
- /** EventEmitter for multicast events within this scope */
22
- emitter: EventEmitter;
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.
@@ -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, Consumer, Cache, and Tasks providers.
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||{}),p=/* @__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))(p||{});class h 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 h);const o=setTimeout(n,e);t?.addEventListener("abort",()=>{clearTimeout(o),r(new h)},{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 S(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 x(t){const n=w(t),r=e.isString(n)?n:n.description??"";return r.startsWith(m.actionPrefix)&&r.slice(r.lastIndexOf("/")+1)||"unknown"}function P(t){return e.isObject(t)&&u.Channel in t&&"channel"in t}function E(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 M=(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 O(){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 A(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 j(e){if(e instanceof Error){if("TimeoutError"===e.name)return p.Timedout;if("AbortError"===e.name)return p.Supplanted}return p.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 N=(e=21)=>{let t="",n=crypto.getRandomValues(new Uint8Array(e|=0));for(;e--;)t+="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"[63&n[e]];return t};var R=/* @__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))(R||{}),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=N}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 N()}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,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}(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(){return r.useContext(Z)}function te({children:e}){const t=r.useMemo(()=>new Y,[]);/* @__PURE__ */
3
- return n(Z.Provider,{value:t,children:e})}const ne=r.createContext(/* @__PURE__ */new Map);function re(){return r.useContext(ne)}function oe(){const[,e]=r.useReducer(e=>e+1,0);return e}function ce({action:t,renderer:n}){const o=ee(),c=re(),i=oe(),s=r.useMemo(()=>{const e=c.get(t);if(e)return e;const n={state:new I,listeners:/* @__PURE__ */new Set};return c.set(t,n),n},[t,c]);r.useLayoutEffect(()=>{function e(e){s.state.hydrate({value:e}),s.listeners.forEach(e=>e())}return s.listeners.add(i),o.on(t,e),()=>{s.listeners.delete(i),o.off(t,e)}},[t,o,s]);const a=s.state.model?.value;return e.isNullable(a)?null:n({value:a,inspect:s.state.inspect.value})}function ie({children:e}){const t=r.useMemo(()=>/* @__PURE__ */new Map,[]);/* @__PURE__ */
4
- return n(ne.Provider,{value:t,children:e})}const se=r.createContext(/* @__PURE__ */new Map);function ae({children:e}){const t=r.useMemo(()=>/* @__PURE__ */new Map,[]);/* @__PURE__ */
5
- return n(se.Provider,{value:t,children:e})}const ue=r.createContext(/* @__PURE__ */new Set);function le({children:e}){const t=r.useMemo(()=>/* @__PURE__ */new Set,[]);/* @__PURE__ */
6
- return n(ue.Provider,{value:t,children:e})}function fe({children:e}){/* @__PURE__ */
7
- return n(te,{children:/* @__PURE__ */n(ie,{children:/* @__PURE__ */n(ae,{children:/* @__PURE__ */n(le,{children:e})})})})}const de=r.createContext(null);function pe(){return r.useContext(de)}function he(e,t){return e?.get(t)??null}function me({action:t,scopeName:n,renderer:o}){const c=pe(),i=oe(),s=r.useMemo(()=>he(c,n),[c,n]),a=r.useMemo(()=>s?function(e,t){const n=e.store.get(t);if(n)return n;const r={state:new I,listeners:/* @__PURE__ */new Set};return e.store.set(t,r),r}(s,t):null,[t,s]);if(r.useLayoutEffect(()=>{if(s&&a)return a.listeners.add(i),s.emitter.on(t,e),()=>{a.listeners.delete(i),s.emitter.off(t,e)};function e(e){a&&(a.state.hydrate({value:e}),a.listeners.forEach(e=>e()))}},[t,s,a,i]),!a)return null;const u=a.state.model?.value;return e.isNullable(u)?null:o({value:u,inspect:a.state.inspect.value})}function ye({name:e,children:t}){const o=pe(),c=r.useMemo(()=>({name:e,emitter:new X,store:/* @__PURE__ */new Map,listeners:/* @__PURE__ */new Map}),[]),i=r.useMemo(()=>{const t=new Map(o??[]);return t.set(e,c),t},[o,e,c]);/* @__PURE__ */
8
- return n(de.Provider,{value:i,children:t})}function be(e,t){const r=`Scoped${t.displayName||t.name||"Component"}`;return{[r]:r=>/* @__PURE__ */n(ye,{name:e,children:/* @__PURE__ */n(t,{...r})})}[r]}function ve(e){return(t,n)=>{t.actions.produce(t=>{t.model[e]=n})}}function ge(...n){const o=e.isUndefined(n[0])||e.isFunction(n[0])?{}:n[0],i=e.isFunction(n[0])?n[0]:n[1]??(()=>({})),s=ee(),a=pe(),f=re(),p=c(k),m=r.useContext(ue),y=r.useContext(se),b=oe(),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=P(e)?e.channel:void 0;if(E(e)&&n?.scope){const e=he(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=he(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:C(f),action:x(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,broadcast:o,broadcastActions:c,phase:i,data:s}){const a=re(),u=r.useRef(null);r.useLayoutEffect(()=>{i.current===d.Mounting&&(n.emit(l.Mount),c.forEach(t=>{const r=a.get(t),c=r?.state.model?.value;if(!e.isNullable(c))return void n.emit(t,c);const i=o.getCached(t);e.isNullable(i)||n.emit(t,i)}),i.current=d.Mounted)},[]),r.useLayoutEffect(()=>{if(e.isNotNullable(u.current)){const e=function(e,t){return Object.keys(t).reduce((n,r)=>e[r]!==t[r]?{...n,[r]:t[r]}:n,{})}(u.current,s);t.isNotEmpty(Object.keys(e))&&n.emit(l.Update,e)}u.current=s},[s,n])}({unicast:R,broadcast:s,broadcastActions:z.broadcast,phase:L,data:i()});const W=r.useMemo(()=>[O,{dispatch(e,t,n){const r=w(e),o=P(e)?e.channel:void 0;if(E(e)&&n?.scope){const e=he(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(me,{action:w(e),scopeName:n.scope,renderer:t}):r.createElement(ce,{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(()=>P(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,fe as Boundary,f as Distribution,O as Entry,_ as Error,l as Lifecycle,R as Op,R as Operation,p as Reason,ye as Scope,I as State,ve as With,q as annotate,ge as useActions,v as utils,be 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};
@@ -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);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(){return i.useContext(J)}function Q({children:e}){const t=i.useMemo(()=>new V,[]);return n.jsx(J.Provider,{value:t,children:e})}const X=i.createContext(new Map);function Y(){return i.useContext(X)}function Z(){const[,e]=i.useReducer(e=>e+1,0);return e}function ee({action:e,renderer:n}){const r=K(),o=Y(),c=Z(),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 te({children:e}){const t=i.useMemo(()=>new Map,[]);return n.jsx(X.Provider,{value:t,children:e})}const ne=i.createContext(new Map);function re({children:e}){const t=i.useMemo(()=>new Map,[]);return n.jsx(ne.Provider,{value:t,children:e})}const oe=i.createContext(new Set);function ce({children:e}){const t=i.useMemo(()=>new Set,[]);return n.jsx(oe.Provider,{value:t,children:e})}const ie=i.createContext(null);function se(){return i.useContext(ie)}function ae(e,t){return e?.get(t)??null}function ue({action:e,scopeName:n,renderer:r}){const o=se(),c=Z(),s=i.useMemo(()=>ae(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 le({name:e,children:t}){const r=se(),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(ie.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(Q,{children:n.jsx(te,{children:n.jsx(re,{children:n.jsx(ce,{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=le,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=K(),u=se(),f=Y(),p=r.useContext(O),h=i.useContext(oe),m=i.useContext(ne),y=Z(),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=ae(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=ae(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,broadcast:n,broadcastActions:r,phase:o,data:c}){const s=Y(),u=i.useRef(null);i.useLayoutEffect(()=>{o.current===l.Mounting&&(e.emit(a.Mount),r.forEach(r=>{const o=s.get(r),c=o?.state.model?.value;if(!t.G.isNullable(c))return void e.emit(r,c);const i=n.getCached(r);t.G.isNullable(i)||e.emit(r,i)}),o.current=l.Mounted)},[]),i.useLayoutEffect(()=>{if(t.G.isNotNullable(u.current)){const n=function(e,t){return Object.keys(t).reduce((n,r)=>e[r]!==t[r]?{...n,[r]:t[r]}:n,{})}(u.current,c);t.A.isNotEmpty(Object.keys(n))&&e.emit(a.Update,n)}u.current=c},[c,e])}({unicast:_,broadcast:c,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=ae(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(ue,{action:v(e),scopeName:n.scope,renderer:t}):i.createElement(ee,{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(le,{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);
@@ -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`, `consume`, `inspect`, and `useAction`
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.
@@ -23,17 +23,17 @@ export type References<M extends Model | void> = {
23
23
  * Receives the reactive context and payload, returning void or a promise/generator.
24
24
  *
25
25
  * @template M - The model type
26
- * @template AC - The actions class type
26
+ * @template A - The actions class type
27
27
  * @template D - The data props type
28
28
  */
29
- export type Handler<M extends Model | void = Model, AC extends Actions | void = Actions, D extends Props = Props> = (context: HandlerContext<M, AC, D>, payload: unknown) => void | Promise<void> | AsyncGenerator | Generator;
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;
30
30
  /**
31
31
  * Entry for an action handler with a reactive channel getter.
32
32
  * When getChannel returns undefined, the handler fires for all dispatches.
33
33
  * When getChannel returns a channel, dispatches must match.
34
34
  */
35
- export type HandlerEntry<M extends Model | void = Model, AC extends Actions | void = Actions, D extends Props = Props> = {
36
- handler: Handler<M, AC, D>;
35
+ export type HandlerEntry<M extends Model | void = Model, A extends Actions | void = Actions, D extends Props = Props> = {
36
+ handler: Handler<M, A, D>;
37
37
  getChannel: () => Filter | undefined;
38
38
  };
39
39
  /**
@@ -41,12 +41,12 @@ export type HandlerEntry<M extends Model | void = Model, AC extends Actions | vo
41
41
  * Maps action IDs to sets of handler entries (with optional channels).
42
42
  *
43
43
  * @template M - The model type
44
- * @template AC - The actions class type
44
+ * @template A - The actions class type
45
45
  * @template D - The data props type
46
46
  */
47
- export type Scope<M extends Model | void = Model, AC extends Actions | void = Actions, D extends Props = Props> = {
47
+ export type Scope<M extends Model | void = Model, A extends Actions | void = Actions, D extends Props = Props> = {
48
48
  /** All handlers for each action, with optional channels */
49
- handlers: Map<ActionId, Set<HandlerEntry<M, AC, D>>>;
49
+ handlers: Map<ActionId, Set<HandlerEntry<M, A, D>>>;
50
50
  };
51
51
  /**
52
52
  * Function type for the data snapshot passed to useActions.
@@ -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, AC extends Actions | void, D extends Props, P extends K extends keyof M ? M[K] : never>(context: HandlerContext<M, AC, D>, payload: P) => void;
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, AC extends Actions | void, D extends Props>(scope: React.RefObject<Scope<M, AC, D>>, action: ActionId | HandlerPayload | ChanneledAction, handler: (context: HandlerContext<M, AC, D>, payload: unknown) => void | Promise<void> | AsyncGenerator | Generator): 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.
@@ -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** &ndash; 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** &ndash; Action is distributed to all mounted components that have defined
151
- * a handler for it. Can be consumed with `actions.consume()`.
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 and can be consumed with `actions.consume()`.
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 `consume()`. Attempting to consume
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
- * // This fails to compile - Increment is a local action
280
- * const Increment = Action<number>("Increment");
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 ChanneledAction<infer P, any> ? P : A extends HandlerPayload<infer P, any> ? P : never;
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 from the consumer store.
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
- * **Important:** A JSX-side `consume()` or `<Partition>` must have populated
601
- * the store for this value to be available.
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 latest dispatched value, or `null`.
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.consume(Actions.Broadcast.User);
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
- consume<T>(action: BroadcastPayload<T>): Promise<T | null>;
620
- consume<T>(action: MulticastPayload<T>, options: MulticastOptions): Promise<T | null>;
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, consume, and inspect capabilities
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
- * Produces a union of all valid dot-notated key paths that resolve to leaf actions
674
- * (i.e. values with `Brand.Action`) within an actions object.
675
- *
676
- * Flat actions like `SetName` produce `"SetName"`.
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 FlattenKeys<AC, Prefix extends string = never> = {
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
- * Higher-Kinded Type (HKT) emulation for action handlers.
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
- * TypeScript doesn't natively support HKTs (types that return types), but this
691
- * pattern emulates them using mapped types with indexed access.
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
- * Supports both flat and nested action classes with dot notation:
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 work as before
687
+ * // Flat actions
716
688
  * export const handleSetName: H["SetName"] = (context, name) => { ... };
717
689
  *
718
- * // Nested actions use dot notation
719
- * export const handlePaymentSent: H["Broadcast.PaymentSent"] = (context) => { ... };
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 FlattenKeys<AC>]: (context: HandlerContext<M, AC, D>, payload: Payload<DeepAction<AC, K> & HandlerPayload<unknown>>) => void | Promise<void> | AsyncGenerator | Generator;
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,6 +1,6 @@
1
1
  {
2
2
  "name": "chizu",
3
- "version": "0.2.64",
3
+ "version": "0.2.65",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "packageManager": "yarn@1.22.22",
@@ -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;