chizu 0.2.50 → 0.2.52

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
@@ -248,4 +248,14 @@ actions.dispatch(Actions.Multicast.Update, 42, { scope: "TeamA" });
248
248
 
249
249
  Unlike broadcast which reaches all components, multicast is scoped to the named boundary – perfect for isolated widget groups, form sections, or distinct UI regions. See the [multicast recipe](./recipes/multicast-actions.md) for more details.
250
250
 
251
- For caching async results across components, define cache operations with `Cache()` and use `context.actions.cache.put()` inside handlers – on cache hit the value is returned synchronously. Use `context.actions.cache.get()` to read cached values and `context.actions.cache.delete()` to clear entries with partial channel matching. See the [cache recipe](./recipes/cache.md) for details.
251
+ To preserve a component's state across unmount/remount cycles, wrap the initial model with `Rehydrate`:
252
+
253
+ ```ts
254
+ import { useActions, Rehydrate } from "chizu";
255
+
256
+ const actions = useActions<Model, typeof Actions>(
257
+ Rehydrate(model, { UserId: props.userId }),
258
+ );
259
+ ```
260
+
261
+ When the component unmounts, its model is snapshotted into the rehydrator. On remount with the same channel key, the model is restored automatically. This is useful for tab switching, route changes, and conditionally rendered components. See the [rehydration recipe](./recipes/rehydration.md) for details.
@@ -0,0 +1,25 @@
1
+ import { Operation } from 'immertation';
2
+ /**
3
+ * Wraps a value with an operation annotation for use in initial model definitions.
4
+ * When passed as part of the initial model to `useActions`, the annotation is
5
+ * registered during hydration so that `actions.inspect` reports the field as pending
6
+ * from the very first render.
7
+ *
8
+ * @param operation - The operation type (e.g., Op.Update).
9
+ * @param value - The value to annotate.
10
+ * @returns The annotated value (typed as T for assignment compatibility).
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * import { annotate, Op } from "chizu";
15
+ *
16
+ * type Model = { user: User | null };
17
+ *
18
+ * const model: Model = {
19
+ * user: annotate(Op.Update, null),
20
+ * };
21
+ *
22
+ * // actions.inspect.user.pending() === true from the first render
23
+ * ```
24
+ */
25
+ export declare function annotate<T>(operation: Operation, value: T): T;
@@ -0,0 +1,13 @@
1
+ import { Props } from './types.ts';
2
+ import * as React from "react";
3
+ export { useRehydrator } from './utils.ts';
4
+ export type { Rehydrator } from './types.ts';
5
+ /**
6
+ * Creates a new rehydrate context for persisting model snapshots across
7
+ * component unmount/remount cycles. Automatically included in `<Boundary>`.
8
+ * Only needed directly if you want to isolate a rehydrate context.
9
+ *
10
+ * @param props.children - The children to render within the rehydrate context.
11
+ * @returns The children wrapped in a rehydrate context provider.
12
+ */
13
+ export declare function RehydrateProvider({ children }: Props): React.ReactNode;
@@ -0,0 +1,14 @@
1
+ import type * as React from "react";
2
+ /**
3
+ * Store for rehydrated model snapshots.
4
+ * Keyed by serialised channel string, values are model snapshots.
5
+ */
6
+ export type Rehydrator = {
7
+ data: Map<string, unknown>;
8
+ };
9
+ /**
10
+ * Props for the RehydrateProvider component.
11
+ */
12
+ export type Props = {
13
+ children: React.ReactNode;
14
+ };
@@ -0,0 +1,12 @@
1
+ import { Rehydrator } from './types.ts';
2
+ import * as React from "react";
3
+ /**
4
+ * React context for the shared rehydrator.
5
+ */
6
+ export declare const Context: React.Context<Rehydrator>;
7
+ /**
8
+ * Hook to access the rehydrator from context.
9
+ *
10
+ * @returns The rehydrator from the current context.
11
+ */
12
+ export declare function useRehydrator(): Rehydrator;
@@ -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, Consumer, Rehydrate, 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,8 @@
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");static TTL=/* @__PURE__ */Symbol("chizu.brand/TTL")}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 x(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 P(t){const n=w(t),r=e.isString(n)?n:n.description??"";return r.startsWith(m.actionPrefix)&&r.slice(r.lastIndexOf("/")+1)||"unknown"}function O(t){return e.isObject(t)&&u.Channel in t&&"channel"in t}function S(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 A=(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(t){if((e.isObject(t)||e.isFunction(t))&&u.Action in t)return t[u.Action];throw new Error("Invalid cache operation")}function j(t){return function(t){return(e.isObject(t)||e.isFunction(t))&&u.Cache in t&&!0===t[u.Cache]}(t)&&e.isObject(t)&&u.Channel in t&&"channel"in t}function M(e){return e?[...Object.keys(e)].toSorted().map(t=>`${t}=${String(e[t])}`).join("&"):""}function C(e,t){return Object.keys(e).every(n=>t[n]===e[n])}const _=e=>{const t=/* @__PURE__ */Symbol(`${m.cachePrefix}${e}`),n=function(n){return{[u.Action]:t,[u.Cache]:!0,[u.TTL]:e,[u.Channel]:n,channel:n}};return Object.defineProperty(n,u.Action,{value:t,enumerable:!1}),Object.defineProperty(n,u.Cache,{value:!0,enumerable:!1}),Object.defineProperty(n,u.TTL,{value:e,enumerable:!1}),n};function N(e){if(e instanceof Error){if("TimeoutError"===e.name)return h.Timedout;if("AbortError"===e.name)return h.Supplanted}return h.Errored}function k(e){return e instanceof Error?e:new Error(String(e))}const R=o(void 0);function z({handler:e,children:t}){/* @__PURE__ */
2
- return n(R.Provider,{value:e,children:t})}let L=(e=21)=>{let t="",n=crypto.getRandomValues(new Uint8Array(e|=0));for(;e--;)t+="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"[63&n[e]];return t};var T=/* @__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))(T||{}),U=/* @__PURE__ */(e=>(e[e.Produce=0]="Produce",e[e.Hydrate=1]="Hydrate",e))(U||{}),$=/* @__PURE__ */(e=>(e.Property="property",e.Process="process",e.Value="value",e.Operation="operation",e))($||{});class B{[i]=!0;static keys=new Set(Object.values($));property=null;process=null;value;operation;constructor(e,t){this.value=e,this.operation=t}assign(e,t){const n=new B(this.value,this.operation);return n.property=e,n.process=t,n}}class F{static immer=(()=>{s();const e=new a;return e.setAutoFreeze(!1),e})();static tag="κ";static id=L}function W(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 D(t){if(e.isNullable(t)||I(t))return t;if(e.isArray(t))return t.map(e=>D(e));if(e.isObject(t)){const e=Object.entries(t).map(([e,t])=>[e,D(t)]);return{...Object.fromEntries(e),[F.tag]:t[F.tag]??F.id()}}return t}function H(e){if(Array.isArray(e))return e.filter(e=>F.tag in e).map(e=>e[F.tag]??"").join(",");const t=e[F.tag];if(t)return t;try{return JSON.stringify(e)}catch{return`[unserializable:${typeof e}]`}}function I(t){return e.isNullable(t)||e.isString(t)||e.isNumber(t)||e.isBoolean(t)||"symbol"==typeof t||"bigint"==typeof t}function G(t,n,r,o,c,i){return function s(a,u=n.path){if(a instanceof B){const n=W(r,u.join("."));if(Object.entries(a).filter(([e,t])=>!B.keys.has(e)&&t instanceof B).forEach(([e,t])=>s(t,u.concat(e))),I(a.value)){if(t===U.Hydrate)return a.value;const s=u.slice(0,-1),l=s.length>0?W(r,s.join(".")):r;return e.isNullable(l)||V(l,a,u.at(-1),o,c,i),n??a.value}if(t===U.Hydrate){const e=D(s(a.value,u));return V(e,a,null,o,c,i),e}const l=n??D(a.value);return V(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)){const e=Object.entries(a).map(([e,t])=>[e,s(t,u.concat(e))]),n=Object.fromEntries(e);if(t===U.Hydrate){const e=D(n);return Object.entries(a).forEach(([t,n])=>{n instanceof B&&I(n.value)&&V(e,n,t,o,c,i)}),e}return n}return a}(n.value)}function V(e,t,n,r,o,c){const i=c(e),s=o.get(i)??[];o.set(i,[t.assign(n,r),...s])}class q{#e={};#t;#n=/* @__PURE__ */new Map;#r=/* @__PURE__ */new Set;#o=!1;constructor(e=H){this.#t=e}static pk(){return L()}static"κ"=q.pk;annotate(e,t){return new B(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=W(n(),c),a=c.slice(0,-1),u=t.isNotEmpty(a)?W(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:W(n(),r),inspect:e(r)}):"is"===a?e=>s(r).some(t=>0!==(t.operation&e)):"draft"===a?()=>t.head(s(r))?.value??W(n(),r):"settled"===a?()=>new Promise(e=>{if(t.isEmpty(s(r)))return e(W(n(),r));const o=()=>{t.isEmpty(s(r))&&(i(o),e(W(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,t=>Object.assign(t,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]=F.immer.produceWithPatches(this.#e,t);return this.#e=r.reduce((t,r)=>F.immer.applyPatches(t,[{...r,value:G(e,r,t,n,this.#n,this.#t)}]),this.#e),this.#e=D(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)}}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)),Y=r.createContext(new X);function Z(){return r.useContext(Y)}function ee({children:e}){const t=r.useMemo(()=>new X,[]);/* @__PURE__ */
3
- return n(Y.Provider,{value:t,children:e})}const te=r.createContext(/* @__PURE__ */new Map);function ne(){return r.useContext(te)}function re(){const[,e]=r.useReducer(e=>e+1,0);return e}function oe({action:t,renderer:n}){const o=Z(),c=ne(),i=re(),s=r.useMemo(()=>{const e=c.get(t);if(e)return e;const n={state:new q,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 ce({children:e}){const t=r.useMemo(()=>/* @__PURE__ */new Map,[]);/* @__PURE__ */
4
- return n(te.Provider,{value:t,children:e})}const ie=r.createContext(/* @__PURE__ */new Map);function se({children:e}){const t=r.useMemo(()=>/* @__PURE__ */new Map,[]);/* @__PURE__ */
5
- return n(ie.Provider,{value:t,children:e})}const ae=r.createContext(/* @__PURE__ */new Set);function ue({children:e}){const t=r.useMemo(()=>/* @__PURE__ */new Set,[]);/* @__PURE__ */
6
- return n(ae.Provider,{value:t,children:e})}function le({children:e}){/* @__PURE__ */
7
- return n(ee,{children:/* @__PURE__ */n(ce,{children:/* @__PURE__ */n(se,{children:/* @__PURE__ */n(ue,{children:e})})})})}const fe=r.createContext(null);function de(){return r.useContext(fe)}function he(e,t){return e?.get(t)??null}function pe({action:t,scopeName:n,renderer:o}){const c=de(),i=re(),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 q,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 me({name:e,children:t}){const o=de(),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(fe.Provider,{value:i,children:t})}function ye(e){return(t,n)=>{t.actions.produce(t=>{t.model[e]=n})}}function be(n,o=()=>({})){const i=Z(),s=de(),a=c(R),f=r.useContext(ae),h=r.useContext(ie),p=r.useMemo(()=>({...n}),[]),[m,y]=r.useState(p),b=re(),v=r.useRef(null),g=r.useRef((()=>{const e=new q;return v.current=e.hydrate(p),e})()),A=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])}(o()),_=r.useMemo(()=>new X,[]),z=r.useRef({handlers:/* @__PURE__ */new Map}),L=function(){const e=r.useRef(/* @__PURE__ */new Set),t=r.useRef(/* @__PURE__ */new Set);return r.useMemo(()=>({broadcast:e.current,multicast:t.current}),[])}(),T=r.useRef(d.Mounting),U=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((t,n,r)=>{const o=new AbortController,c={controller:o,action:t,payload:n};return f.add(c),$.current.add(c),{model:m,get phase(){return T.current},task:c,data:A,tasks:f,nodes:U.refs.current,actions:{produce(e){if(o.signal.aborted)return;const t=g.current.produce(t=>e({model:t,inspect:g.current.inspect}));y(g.current.model),r.processes.add(t),v.current&&(r.processes.add(v.current),v.current=null)},dispatch(e,t,n){if(o.signal.aborted)return;const r=w(e),c=O(e)?e.channel:void 0;if(S(e)&&n?.scope){const e=he(s,n.scope);return void(e&&e.emitter.emit(r,t,c))}(x(e)?i:_).emit(r,t,c)},annotate:(e,t)=>g.current.annotate(e,t),cache:{put(t,n){const r=E(t),o=function(t){if((e.isObject(t)||e.isFunction(t))&&u.TTL in t)return t[u.TTL];throw new Error("Invalid cache operation")}(t),c=j(t)?M(t.channel):"",i=h.get(r);if(i){const e=i.get(c);if(e&&e.expiresAt>Date.now())return e.value}return n(e=>(h.has(r)||h.set(r,/* @__PURE__ */new Map),h.get(r).set(c,{value:e,expiresAt:Date.now()+o,channel:j(t)?t.channel:void 0}),e))},get(e){const t=E(e),n=j(e)?M(e.channel):"",r=h.get(t)?.get(n);return r&&r.expiresAt>Date.now()?r.value:void 0},delete(e){const t=E(e);if(j(e)){const n=e.channel,r=h.get(t);if(r)for(const[e,t]of r)t.channel&&C(n,t.channel)&&r.delete(e)}else h.delete(t)}}}}},[m]);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},u=Promise.withResolvers(),d=F(t,o,s);try{await n(d,o)}catch(h){const e=z.current.handlers.has(l.Error),n={reason:N(h),error:k(h),action:P(t),handled:e,tasks:f};a?.(n),e&&_.emit(l.Error,n)}finally{for(const e of f)if(e===d.task){f.delete(e),$.current.delete(e);break}s.processes.forEach(e=>g.current.prune(e)),s.processes.size>0&&b(),u.resolve()}}}B.current++;const n=/* @__PURE__ */new Set;return z.current.handlers.forEach((e,r)=>{for(const{getChannel:o,handler:c}of e){const e=t(r,c,o);if(S(r)){if(s)for(const t of s.values()){const o=t.emitter;o.on(r,e),n.add(()=>o.off(r,e))}_.on(r,e),L.multicast.add(r),n.add(()=>_.off(r,e))}else x(r)?(i.on(r,e),_.on(r,e),L.broadcast.add(r),n.add(()=>{i.off(r,e),_.off(r,e)})):(_.on(r,e),n.add(()=>_.off(r,e)))}}),()=>{const e=++B.current,t=new Set(n);queueMicrotask(()=>{if(B.current===e){for(const e of $.current)e.controller.abort(),f.delete(e);$.current.clear(),T.current=d.Unmounting,_.emit(l.Unmount),T.current=d.Unmounted;for(const e of t)e()}else for(const e of t)e()})}},[_]),r.useLayoutEffect(()=>{for(const[e,t]of U.pending.current)U.emitted.current.get(e)!==t&&(U.emitted.current.set(e,t),_.emit(u.Node,t,{Name:e}));U.pending.current.clear()}),function({unicast:n,broadcastActions:o,phase:c,data:i}){const s=ne(),a=r.useRef(null),u=r.useRef(!1);r.useLayoutEffect(()=>{u.current||(u.current=!0,n.emit(l.Mount),o.forEach(t=>{const r=s.get(t),o=r?.state.model?.value;e.isNullable(o)||n.emit(t,o)}),c.current=d.Mounted)},[]),r.useLayoutEffect(()=>{if(e.isNotNullable(a.current)){const e=function(e,t){return Object.keys(t).reduce((n,r)=>e[r]!==t[r]?{...n,[r]:t[r]}:n,{})}(a.current,i);t.isNotEmpty(Object.keys(e))&&n.emit(l.Update,e)}a.current=i},[i,n])}({unicast:_,broadcastActions:L.broadcast,phase:T,data:o()});const W=r.useMemo(()=>[m,{dispatch(e,t,n){const r=w(e),o=O(e)?e.channel:void 0;if(S(e)&&n?.scope){const e=he(s,n.scope);return void(e&&e.emitter.emit(r,t,o))}(x(e)?i:_).emit(r,t,o)},consume:(e,t,n)=>S(e)&&n?.scope?r.createElement(pe,{action:w(e),scopeName:n.scope,renderer:t}):r.createElement(oe,{action:w(e),renderer:t}),get inspect(){return g.current.inspect},get nodes(){return U.refs.current},node(e,t){U.refs.current[e]=t,U.pending.current.set(e,t)}}],[m,_]);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(()=>O(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})}(z,e,t)},W}export{A as Action,le as Boundary,_ as Cache,f as Distribution,z as Error,l as Lifecycle,T as Op,T as Operation,h as Reason,me as Scope,q as State,ye as With,be as useActions,v as utils};
1
+ import{G as e,A as t}from"@mobily/ts-belt";import*as n from"react";import{createContext as r,useContext as o}from"react";import{jsx as c}from"react/jsx-runtime";import{immerable as s,enablePatches as i,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 Rehydrate=/* @__PURE__ */Symbol("chizu.brand/Rehydrate")}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},A=n.createContext({data:/* @__PURE__ */new Map});function O(e){return e?[...Object.keys(e)].toSorted().map(t=>`${t}=${String(e[t])}`).join("&"):""}function j(e,t){return{[u.Rehydrate]:!0,model:e,channel:t}}function _(e){if(e instanceof Error){if("TimeoutError"===e.name)return p.Timedout;if("AbortError"===e.name)return p.Supplanted}return p.Errored}function k(e){return e instanceof Error?e:new Error(String(e))}const R=r(void 0);function C({handler:e,children:t}){/* @__PURE__ */
2
+ return c(R.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 U=/* @__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))(U||{}),z=/* @__PURE__ */(e=>(e[e.Produce=0]="Produce",e[e.Hydrate=1]="Hydrate",e))(z||{}),L=/* @__PURE__ */(e=>(e.Property="property",e.Process="process",e.Value="value",e.Operation="operation",e))(L||{});class T{[s]=!0;static keys=new Set(Object.values(L));property=null;process=null;value;operation;constructor(e,t){this.value=e,this.operation=t}assign(e,t){const n=new T(this.value,this.operation);return n.property=e,n.process=t,n}}class B{static immer=(()=>{i();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 F(t){if(e.isNullable(t)||H(t))return t;if(e.isArray(t))return t.map(e=>F(e));if(e.isObject(t)){const e=Object.entries(t).map(([e,t])=>[e,F(t)]);return{...Object.fromEntries(e),[B.tag]:t[B.tag]??B.id()}}return t}function W(e){if(Array.isArray(e))return e.filter(e=>B.tag in e).map(e=>e[B.tag]??"").join(",");const t=e[B.tag];if(t)return t;try{return JSON.stringify(e)}catch{return`[unserializable:${typeof e}]`}}function H(t){return e.isNullable(t)||e.isString(t)||e.isNumber(t)||e.isBoolean(t)||"symbol"==typeof t||"bigint"==typeof t}function D(t,n,r,o,c,s){return function i(a,u=n.path){if(a instanceof T){const n=$(r,u.join("."));if(Object.entries(a).filter(([e,t])=>!T.keys.has(e)&&t instanceof T).forEach(([e,t])=>i(t,u.concat(e))),H(a.value)){if(t===z.Hydrate)return a.value;const i=u.slice(0,-1),l=i.length>0?$(r,i.join(".")):r;return e.isNullable(l)||I(l,a,u.at(-1),o,c,s),n??a.value}if(t===z.Hydrate){const e=F(i(a.value,u));return I(e,a,null,o,c,s),e}const l=n??F(a.value);return I(l,a,null,o,c,s),e.isNullable(n)?l:(i(a.value,u),n)}if(e.isArray(a))return a.map((e,t)=>i(e,u.concat(t)));if(e.isObject(a)){const e=Object.entries(a).map(([e,t])=>[e,i(t,u.concat(e))]),n=Object.fromEntries(e);if(t===z.Hydrate){const e=F(n);return Object.entries(a).forEach(([t,n])=>{n instanceof T&&H(n.value)&&I(e,n,t,o,c,s)}),e}return n}return a}(n.value)}function I(e,t,n,r,o,c){const s=c(e),i=o.get(s)??[];o.set(s,[t.assign(n,r),...i])}class G{#e={};#t;#n=/* @__PURE__ */new Map;#r=/* @__PURE__ */new Set;#o=!1;constructor(e=W){this.#t=e}static pk(){return N()}static"κ"=G.pk;annotate(e,t){return new T(t,e)}"δ"=this.annotate;get model(){return this.#e}get inspect(){return function(n,r,o,c,s){function i(c){const s=c.at(-1),i=$(n(),c),a=c.slice(0,-1),u=t.isNotEmpty(a)?$(n(),a):n();return[...e.isObject(i)||e.isArray(i)?r.get(o(i))?.filter(t=>e.isNullable(t.property))??[]:[],...e.isObject(u)?r.get(o(u))?.filter(e=>e.property===s)??[]:[]]}return function e(r){return new Proxy(()=>{},{get:(o,a)=>"pending"===a?()=>!t.isEmpty(i(r)):"remaining"===a?()=>t.length(i(r)):"box"===a?()=>({value:$(n(),r),inspect:e(r)}):"is"===a?e=>i(r).some(t=>0!==(t.operation&e)):"draft"===a?()=>t.head(i(r))?.value??$(n(),r):"settled"===a?()=>new Promise(e=>{if(t.isEmpty(i(r)))return e($(n(),r));const o=()=>{t.isEmpty(i(r))&&(s(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(z.Hydrate,()=>e)}produce(e){if(!this.#o)throw new Error("State must be hydrated using hydrate() before calling produce()");return this.#c(z.Produce,e)}#c(e,t){const n=/* @__PURE__ */Symbol("process"),[,r]=B.immer.produceWithPatches(this.#e,t);return this.#e=r.reduce((t,r)=>B.immer.applyPatches(t,[{...r,value:D(e,r,t,n,this.#n,this.#t)}]),this.#e),this.#e=F(this.#e),this.#s(),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.#s()}#s(){this.#r.forEach(e=>e())}observe(e){const t=()=>e(this.#e);return this.#r.add(t),()=>this.#r.delete(t)}}const V=new G;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,s){if("function"!=typeof r)throw new TypeError("The listener must be a function");var i=new o(r,c||e,s),a=n?n+t:t;return e._events[a]?e._events[a].fn?e._events[a]=[e._events[a],i]:e._events[a].push(i):(e._events[a]=i,e._eventsCount++),e}function s(e,t){0===--e._eventsCount?e._events=new r:delete e._events[t]}function i(){this._events=new r,this._eventsCount=0}Object.create&&(r.prototype=/* @__PURE__ */Object.create(null),(new r).__proto__||(n=!1)),i.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},i.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},i.prototype.listenerCount=function(e){var t=this._events[n?n+e:e];return t?t.fn?1:t.length:0},i.prototype.emit=function(e,t,r,o,c,s){var i=n?n+e:e;if(!this._events[i])return!1;var a,u,l=this._events[i],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,s),!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},i.prototype.on=function(e,t,n){return c(this,e,t,n,!1)},i.prototype.once=function(e,t,n){return c(this,e,t,n,!0)},i.prototype.removeListener=function(e,t,r,o){var c=n?n+e:e;if(!this._events[c])return this;if(!t)return s(this,c),this;var i=this._events[c];if(i.fn)i.fn!==t||o&&!i.once||r&&i.context!==r||s(this,c);else{for(var a=0,u=[],l=i.length;a<l;a++)(i[a].fn!==t||o&&!i[a].once||r&&i[a].context!==r)&&u.push(i[a]);u.length?this._events[c]=1===u.length?u[0]:u:s(this,c)}return this},i.prototype.removeAllListeners=function(e){var t;return e?this._events[t=n?n+e:e]&&s(this,t):(this._events=new r,this._eventsCount=0),this},i.prototype.off=i.prototype.removeListener,i.prototype.addListener=i.prototype.on,i.prefixed=n,i.EventEmitter=i,e.exports=i}(Q)),Q.exports)),Y=n.createContext(new X);function Z(){return n.useContext(Y)}function ee({children:e}){const t=n.useMemo(()=>new X,[]);/* @__PURE__ */
3
+ return c(Y.Provider,{value:t,children:e})}const te=n.createContext(/* @__PURE__ */new Map);function ne(){return n.useContext(te)}function re(){const[,e]=n.useReducer(e=>e+1,0);return e}function oe({action:t,renderer:r}){const o=Z(),c=ne(),s=re(),i=n.useMemo(()=>{const e=c.get(t);if(e)return e;const n={state:new G,listeners:/* @__PURE__ */new Set};return c.set(t,n),n},[t,c]);n.useLayoutEffect(()=>{function e(e){i.state.hydrate({value:e}),i.listeners.forEach(e=>e())}return i.listeners.add(s),o.on(t,e),()=>{i.listeners.delete(s),o.off(t,e)}},[t,o,i]);const a=i.state.model?.value;return e.isNullable(a)?null:r({value:a,inspect:i.state.inspect.value})}function ce({children:e}){const t=n.useMemo(()=>/* @__PURE__ */new Map,[]);/* @__PURE__ */
4
+ return c(te.Provider,{value:t,children:e})}function se({children:e}){const t=n.useMemo(()=>({data:/* @__PURE__ */new Map}),[]);/* @__PURE__ */
5
+ return c(A.Provider,{value:t,children:e})}const ie=n.createContext(/* @__PURE__ */new Set);function ae({children:e}){const t=n.useMemo(()=>/* @__PURE__ */new Set,[]);/* @__PURE__ */
6
+ return c(ie.Provider,{value:t,children:e})}function ue({children:e}){/* @__PURE__ */
7
+ return c(ee,{children:/* @__PURE__ */c(ce,{children:/* @__PURE__ */c(se,{children:/* @__PURE__ */c(ae,{children:e})})})})}const le=n.createContext(null);function fe(){return n.useContext(le)}function de(e,t){return e?.get(t)??null}function pe({action:t,scopeName:r,renderer:o}){const c=fe(),s=re(),i=n.useMemo(()=>de(c,r),[c,r]),a=n.useMemo(()=>i?function(e,t){const n=e.store.get(t);if(n)return n;const r={state:new G,listeners:/* @__PURE__ */new Set};return e.store.set(t,r),r}(i,t):null,[t,i]);if(n.useLayoutEffect(()=>{if(i&&a)return a.listeners.add(s),i.emitter.on(t,e),()=>{a.listeners.delete(s),i.emitter.off(t,e)};function e(e){a&&(a.state.hydrate({value:e}),a.listeners.forEach(e=>e()))}},[t,i,a,s]),!a)return null;const u=a.state.model?.value;return e.isNullable(u)?null:o({value:u,inspect:a.state.inspect.value})}function he({name:e,children:t}){const r=fe(),o=n.useMemo(()=>({name:e,emitter:new X,store:/* @__PURE__ */new Map,listeners:/* @__PURE__ */new Map}),[]),s=n.useMemo(()=>{const t=new Map(r??[]);return t.set(e,o),t},[r,e,o]);/* @__PURE__ */
8
+ return c(le.Provider,{value:s,children:t})}function me(e){return(t,n)=>{t.actions.produce(t=>{t.model[e]=n})}}function ye(r,c=()=>({})){const s=Z(),i=fe(),a=o(R),f=n.useContext(ie),p=re(),h=n.useRef(!1),m=n.useRef(null),y=n.useRef(new G),{model:b,save:v}=function(e){const t=n.useContext(A),r=n.useRef(null);if(!r.current)if("object"==typeof(o=e)&&null!==o&&u.Rehydrate in o&&!0===o[u.Rehydrate]){const{channel:n,model:o}=e,c=function(e,t){const n=O(t);return e.data.get(n)||null}(t,n);r.current={model:c??o,save:e=>function(e,t,n){const r=O(t);e.data.set(r,n)}(t,n,e)}}else r.current={model:e,save:()=>{}};var o;return r.current}(r);h.current||(h.current=!0,m.current=y.current.hydrate(b));const[g,M]=n.useState(()=>y.current.model),j=function(e){const t=n.useRef(e);return n.useLayoutEffect(()=>{t.current=e},[e]),n.useMemo(()=>{return n=t,Object.keys(e).reduce((e,t)=>(Object.defineProperty(e,t,{get:()=>n.current[t],enumerable:!0}),e),{});var n},[e])}(c()),C=n.useMemo(()=>new X,[]),N=n.useRef({handlers:/* @__PURE__ */new Map});N.current.handlers=/* @__PURE__ */new Map;const U=function(){const e=n.useRef(/* @__PURE__ */new Set),t=n.useRef(/* @__PURE__ */new Set);return n.useMemo(()=>({broadcast:e.current,multicast:t.current}),[])}(),z=n.useRef(d.Mounting),L=function(){const e=n.useRef({}),t=n.useRef(/* @__PURE__ */new Map),r=n.useRef(/* @__PURE__ */new Map);return n.useMemo(()=>({refs:e,pending:t,emitted:r}),[])}(),T=n.useRef(/* @__PURE__ */new Set),B=n.useRef(0),$=n.useCallback((e,t,n)=>{const r=new AbortController,o={controller:r,action:e,payload:t};return f.add(o),T.current.add(o),{model:g,get phase(){return z.current},task:o,data:j,tasks:f,nodes:L.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),m.current&&(n.processes.add(m.current),m.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=de(i,n.scope);return void(e&&e.emitter.emit(o,t,c))}(S(e)?s:C).emit(o,t,c)},annotate:(e,t)=>y.current.annotate(e,t)}}},[g]);n.useLayoutEffect(()=>{function t(t,n,r){return async function(o,c){const s=r();if(e.isNotNullable(c)&&e.isNotNullable(s)&&!function(e,t){for(const n of Object.keys(e))if(t[n]!==e[n])return!1;return!0}(c,s))return;const i={processes:/* @__PURE__ */new Set},u=Promise.withResolvers(),d=$(t,o,i);try{await n(d,o)}catch(h){const e=N.current.handlers.has(l.Error),n={reason:_(h),error:k(h),action:x(t),handled:e,tasks:f};a?.(n),e&&C.emit(l.Error,n)}finally{for(const e of f)if(e===d.task){f.delete(e),T.current.delete(e);break}i.processes.forEach(e=>y.current.prune(e)),i.processes.size>0&&p(),u.resolve()}}}B.current++;const n=/* @__PURE__ */new Set;return N.current.handlers.forEach((e,r)=>{for(const{getChannel:o,handler:c}of e){const e=t(r,c,o);if(E(r)){if(i)for(const t of i.values()){const o=t.emitter;o.on(r,e),n.add(()=>o.off(r,e))}C.on(r,e),U.multicast.add(r),n.add(()=>C.off(r,e))}else S(r)?(s.on(r,e),C.on(r,e),U.broadcast.add(r),n.add(()=>{s.off(r,e),C.off(r,e)})):(C.on(r,e),n.add(()=>C.off(r,e)))}}),()=>{const e=++B.current,t=new Set(n);queueMicrotask(()=>{if(B.current===e){v(y.current.model);for(const e of T.current)e.controller.abort(),f.delete(e);T.current.clear(),z.current=d.Unmounting,C.emit(l.Unmount),z.current=d.Unmounted;for(const e of t)e()}else for(const e of t)e()})}},[C]),n.useLayoutEffect(()=>{for(const[e,t]of L.pending.current)L.emitted.current.get(e)!==t&&(L.emitted.current.set(e,t),C.emit(u.Node,t,{Name:e}));L.pending.current.clear()}),function({unicast:r,broadcastActions:o,phase:c,data:s}){const i=ne(),a=n.useRef(null);n.useLayoutEffect(()=>{c.current===d.Mounting&&(r.emit(l.Mount),o.forEach(t=>{const n=i.get(t),o=n?.state.model?.value;e.isNullable(o)||r.emit(t,o)}),c.current=d.Mounted)},[]),n.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))&&r.emit(l.Update,e)}a.current=s},[s,r])}({unicast:C,broadcastActions:U.broadcast,phase:z,data:c()});const F=n.useMemo(()=>[g,{dispatch(e,t,n){const r=w(e),o=P(e)?e.channel:void 0;if(E(e)&&n?.scope){const e=de(i,n.scope);return void(e&&e.emitter.emit(r,t,o))}(S(e)?s:C).emit(r,t,o)},consume:(e,t,r)=>E(e)&&r?.scope?n.createElement(pe,{action:w(e),scopeName:r.scope,renderer:t}):n.createElement(oe,{action:w(e),renderer:t}),get inspect(){return y.current.inspect},get nodes(){return L.refs.current},node(e,t){L.refs.current[e]=t,L.pending.current.set(e,t)}}],[g,C]);return F.useAction=(e,t)=>{!function(e,t,r){const o=n.useRef(r);n.useLayoutEffect(()=>{o.current=r});const c=n.useRef(t);n.useLayoutEffect(()=>{c.current=t});const s=n.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)},[]),i=n.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:i,handler:s})}(N,e,t)},F}export{M as Action,ue as Boundary,f as Distribution,C as Error,l as Lifecycle,U as Op,U as Operation,p as Reason,j as Rehydrate,he as Scope,G as State,me as With,q as annotate,ye as useActions,v as utils};
@@ -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");static TTL=Symbol("chizu.brand/TTL")}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 A(e){if((t.G.isObject(e)||t.G.isFunction(e))&&s.Action in e)return e[s.Action];throw new Error("Invalid cache operation")}function O(e){return function(e){return(t.G.isObject(e)||t.G.isFunction(e))&&s.Cache in e&&!0===e[s.Cache]}(e)&&t.G.isObject(e)&&s.Channel in e&&"channel"in e}function P(e){return e?[...Object.keys(e)].toSorted().map(t=>`${t}=${String(e[t])}`).join("&"):""}function S(e,t){return Object.keys(e).every(n=>t[n]===e[n])}function E(e){if(e instanceof Error){if("TimeoutError"===e.name)return f.Timedout;if("AbortError"===e.name)return f.Supplanted}return f.Errored}function M(e){return e instanceof Error?e:new Error(String(e))}const G=r.createContext(void 0);let C=(e=21)=>{let t="",n=crypto.getRandomValues(new Uint8Array(e|=0));for(;e--;)t+="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"[63&n[e]];return t};var _=(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))(_||{}),N=(e=>(e[e.Produce=0]="Produce",e[e.Hydrate=1]="Hydrate",e))(N||{}),k=(e=>(e.Property="property",e.Process="process",e.Value="value",e.Operation="operation",e))(k||{});class R{[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 R(this.value,this.operation);return n.property=e,n.process=t,n}}class T{static immer=(()=>{o.enablePatches();const e=new o.Immer;return e.setAutoFreeze(!1),e})();static tag="κ";static id=C}function z(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 L(e){if(t.G.isNullable(e)||B(e))return e;if(t.G.isArray(e))return e.map(e=>L(e));if(t.G.isObject(e)){const t=Object.entries(e).map(([e,t])=>[e,L(t)]);return{...Object.fromEntries(t),[T.tag]:e[T.tag]??T.id()}}return e}function U(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 B(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 $(e,n,r,o,c,i){return function s(a,u=n.path){if(a instanceof R){const n=z(r,u.join("."));if(Object.entries(a).filter(([e,t])=>!R.keys.has(e)&&t instanceof R).forEach(([e,t])=>s(t,u.concat(e))),B(a.value)){if(e===N.Hydrate)return a.value;const s=u.slice(0,-1),l=s.length>0?z(r,s.join(".")):r;return t.G.isNullable(l)||D(l,a,u.at(-1),o,c,i),n??a.value}if(e===N.Hydrate){const e=L(s(a.value,u));return D(e,a,null,o,c,i),e}const l=n??L(a.value);return D(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)){const t=Object.entries(a).map(([e,t])=>[e,s(t,u.concat(e))]),n=Object.fromEntries(t);if(e===N.Hydrate){const e=L(n);return Object.entries(a).forEach(([t,n])=>{n instanceof R&&B(n.value)&&D(e,n,t,o,c,i)}),e}return n}return a}(n.value)}function D(e,t,n,r,o,c){const i=c(e),s=o.get(i)??[];o.set(i,[t.assign(n,r),...s])}class F{#e={};#t;#n=new Map;#r=new Set;#o=!1;constructor(e=U){this.#t=e}static pk(){return C()}static"κ"=F.pk;annotate(e,t){return new R(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=z(e(),o),s=o.slice(0,-1),a=t.A.isNotEmpty(s)?z(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:z(e(),r),inspect:n(r)}):"is"===a?e=>i(r).some(t=>0!==(t.operation&e)):"draft"===a?()=>t.A.head(i(r))?.value??z(e(),r):"settled"===a?()=>new Promise(n=>{if(t.A.isEmpty(i(r)))return n(z(e(),r));const s=()=>{t.A.isEmpty(i(r))&&(c(s),n(z(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(N.Hydrate,t=>Object.assign(t,e))}produce(e){if(!this.#o)throw new Error("State must be hydrated using hydrate() before calling produce()");return this.#c(N.Produce,e)}#c(e,t){const n=Symbol("process"),[,r]=T.immer.produceWithPatches(this.#e,t);return this.#e=r.reduce((t,r)=>T.immer.applyPatches(t,[{...r,value:$(e,r,t,n,this.#n,this.#t)}]),this.#e),this.#e=L(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)}}function W(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var H,I={exports:{}},q=(H||(H=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}(I)),I.exports);const V=W(q),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 F,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 F,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})}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(Q,{children:n.jsx(te,{children:n.jsx(re,{children:n.jsx(ce,{children:e})})})})},e.Cache=e=>{const t=Symbol(`${h.cachePrefix}${e}`),n=function(n){return{[s.Action]:t,[s.Cache]:!0,[s.TTL]:e,[s.Channel]:n,channel:n}};return Object.defineProperty(n,s.Action,{value:t,enumerable:!1}),Object.defineProperty(n,s.Cache,{value:!0,enumerable:!1}),Object.defineProperty(n,s.TTL,{value:e,enumerable:!1}),n},e.Distribution=u,e.Error=function({handler:e,children:t}){return n.jsx(G.Provider,{value:e,children:t})},e.Lifecycle=a,e.Op=_,e.Operation=_,e.Reason=f,e.Scope=function({name:e,children:t}){const r=se(),o=i.useMemo(()=>({name:e,emitter:new V,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.State=F,e.With=function(e){return(t,n)=>{t.actions.produce(t=>{t.model[e]=n})}},e.useActions=function(e,n=()=>({})){const o=K(),c=se(),u=r.useContext(G),f=i.useContext(oe),d=i.useContext(ne),h=i.useMemo(()=>({...e}),[]),[p,m]=i.useState(h),b=Z(),y=i.useRef(null),C=i.useRef((()=>{const e=new F;return y.current=e.hydrate(h),e})()),_=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])}(n()),N=i.useMemo(()=>new V,[]),k=i.useRef({handlers:new Map}),R=function(){const e=i.useRef(new Set),t=i.useRef(new Set);return i.useMemo(()=>({broadcast:e.current,multicast:t.current}),[])}(),T=i.useRef(l.Mounting),z=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),U=i.useRef(0),B=i.useCallback((e,n,r)=>{const i=new AbortController,a={controller:i,action:e,payload:n};return f.add(a),L.current.add(a),{model:p,get phase(){return T.current},task:a,data:_,tasks:f,nodes:z.refs.current,actions:{produce(e){if(i.signal.aborted)return;const t=C.current.produce(t=>e({model:t,inspect:C.current.inspect}));m(C.current.model),r.processes.add(t),y.current&&(r.processes.add(y.current),y.current=null)},dispatch(e,t,n){if(i.signal.aborted)return;const r=v(e),s=x(e)?e.channel:void 0;if(j(e)&&n?.scope){const e=ae(c,n.scope);return void(e&&e.emitter.emit(r,t,s))}(g(e)?o:N).emit(r,t,s)},annotate:(e,t)=>C.current.annotate(e,t),cache:{put(e,n){const r=A(e),o=function(e){if((t.G.isObject(e)||t.G.isFunction(e))&&s.TTL in e)return e[s.TTL];throw new Error("Invalid cache operation")}(e),c=O(e)?P(e.channel):"",i=d.get(r);if(i){const e=i.get(c);if(e&&e.expiresAt>Date.now())return e.value}return n(t=>(d.has(r)||d.set(r,new Map),d.get(r).set(c,{value:t,expiresAt:Date.now()+o,channel:O(e)?e.channel:void 0}),t))},get(e){const t=A(e),n=O(e)?P(e.channel):"",r=d.get(t)?.get(n);return r&&r.expiresAt>Date.now()?r.value:void 0},delete(e){const t=A(e);if(O(e)){const n=e.channel,r=d.get(t);if(r)for(const[e,t]of r)t.channel&&S(n,t.channel)&&r.delete(e)}else d.delete(t)}}}}},[p]);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},l=Promise.withResolvers(),d=B(e,o,s);try{await n(d,o)}catch(h){const t=k.current.handlers.has(a.Error),n={reason:E(h),error:M(h),action:w(e),handled:t,tasks:f};u?.(n),t&&N.emit(a.Error,n)}finally{for(const e of f)if(e===d.task){f.delete(e),L.current.delete(e);break}s.processes.forEach(e=>C.current.prune(e)),s.processes.size>0&&b(),l.resolve()}}}U.current++;const n=new Set;return k.current.handlers.forEach((t,r)=>{for(const{getChannel:i,handler:s}of t){const t=e(r,s,i);if(j(r)){if(c)for(const e of c.values()){const o=e.emitter;o.on(r,t),n.add(()=>o.off(r,t))}N.on(r,t),R.multicast.add(r),n.add(()=>N.off(r,t))}else g(r)?(o.on(r,t),N.on(r,t),R.broadcast.add(r),n.add(()=>{o.off(r,t),N.off(r,t)})):(N.on(r,t),n.add(()=>N.off(r,t)))}}),()=>{const e=++U.current,t=new Set(n);queueMicrotask(()=>{if(U.current===e){for(const e of L.current)e.controller.abort(),f.delete(e);L.current.clear(),T.current=l.Unmounting,N.emit(a.Unmount),T.current=l.Unmounted;for(const e of t)e()}else for(const e of t)e()})}},[N]),i.useLayoutEffect(()=>{for(const[e,t]of z.pending.current)z.emitted.current.get(e)!==t&&(z.emitted.current.set(e,t),N.emit(s.Node,t,{Name:e}));z.pending.current.clear()}),function({unicast:e,broadcastActions:n,phase:r,data:o}){const c=Y(),s=i.useRef(null),u=i.useRef(!1);i.useLayoutEffect(()=>{u.current||(u.current=!0,e.emit(a.Mount),n.forEach(n=>{const r=c.get(n),o=r?.state.model?.value;t.G.isNullable(o)||e.emit(n,o)}),r.current=l.Mounted)},[]),i.useLayoutEffect(()=>{if(t.G.isNotNullable(s.current)){const n=function(e,t){return Object.keys(t).reduce((n,r)=>e[r]!==t[r]?{...n,[r]:t[r]}:n,{})}(s.current,o);t.A.isNotEmpty(Object.keys(n))&&e.emit(a.Update,n)}s.current=o},[o,e])}({unicast:N,broadcastActions:R.broadcast,phase:T,data:n()});const $=i.useMemo(()=>[p,{dispatch(e,t,n){const r=v(e),i=x(e)?e.channel:void 0;if(j(e)&&n?.scope){const e=ae(c,n.scope);return void(e&&e.emitter.emit(r,t,i))}(g(e)?o:N).emit(r,t,i)},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 C.current.inspect},get nodes(){return z.refs.current},node(e,t){z.refs.current[e]=t,z.pending.current.set(e,t)}}],[p,N]);return $.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})}(k,e,t)},$},e.utils=b,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 s=c(n);class i{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 Rehydrate=Symbol("chizu.brand/Rehydrate")}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=i.Node,t=function(t){return{[i.Action]:e,[i.Payload]:void 0,[i.Channel]:t,channel:t}};return Object.defineProperty(t,i.Action,{value:e,enumerable:!1}),Object.defineProperty(t,i.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))&&i.Action in e?e[i.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(i.Broadcast in e&&e[i.Broadcast])return!0;if(i.Action in e){const t=e[i.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)&&i.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(i.Multicast in e&&e[i.Multicast])return!0;if(i.Action in e){const t=e[i.Action];return t.description?.startsWith(p.multicastActionPrefix)??!1}}return!1}const S=s.createContext({data:new Map});function P(e){return e?[...Object.keys(e)].toSorted().map(t=>`${t}=${String(e[t])}`).join("&"):""}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 M(e){return e instanceof Error?e:new Error(String(e))}const E=n.createContext(void 0);let O=(e=21)=>{let t="",n=crypto.getRandomValues(new Uint8Array(e|=0));for(;e--;)t+="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"[63&n[e]];return t};var R=(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||{}),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 _{[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 _(this.value,this.operation);return n.property=e,n.process=t,n}}class k{static immer=(()=>{o.enablePatches();const e=new o.Immer;return e.setAutoFreeze(!1),e})();static tag="κ";static id=O}function N(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 z(e){if(t.G.isNullable(e)||L(e))return e;if(t.G.isArray(e))return e.map(e=>z(e));if(t.G.isObject(e)){const t=Object.entries(e).map(([e,t])=>[e,z(t)]);return{...Object.fromEntries(t),[k.tag]:e[k.tag]??k.id()}}return e}function U(e){if(Array.isArray(e))return e.filter(e=>k.tag in e).map(e=>e[k.tag]??"").join(",");const t=e[k.tag];if(t)return t;try{return JSON.stringify(e)}catch{return`[unserializable:${typeof e}]`}}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,s){return function i(a,u=n.path){if(a instanceof _){const n=N(r,u.join("."));if(Object.entries(a).filter(([e,t])=>!_.keys.has(e)&&t instanceof _).forEach(([e,t])=>i(t,u.concat(e))),L(a.value)){if(e===C.Hydrate)return a.value;const i=u.slice(0,-1),l=i.length>0?N(r,i.join(".")):r;return t.G.isNullable(l)||B(l,a,u.at(-1),o,c,s),n??a.value}if(e===C.Hydrate){const e=z(i(a.value,u));return B(e,a,null,o,c,s),e}const l=n??z(a.value);return B(l,a,null,o,c,s),t.G.isNullable(n)?l:(i(a.value,u),n)}if(t.G.isArray(a))return a.map((e,t)=>i(e,u.concat(t)));if(t.G.isObject(a)){const t=Object.entries(a).map(([e,t])=>[e,i(t,u.concat(e))]),n=Object.fromEntries(t);if(e===C.Hydrate){const e=z(n);return Object.entries(a).forEach(([t,n])=>{n instanceof _&&L(n.value)&&B(e,n,t,o,c,s)}),e}return n}return a}(n.value)}function B(e,t,n,r,o,c){const s=c(e),i=o.get(s)??[];o.set(s,[t.assign(n,r),...i])}class ${#e={};#t;#n=new Map;#r=new Set;#o=!1;constructor(e=U){this.#t=e}static pk(){return O()}static"κ"=$.pk;annotate(e,t){return new _(t,e)}"δ"=this.annotate;get model(){return this.#e}get inspect(){return function(e,n,r,o,c){function s(o){const c=o.at(-1),s=N(e(),o),i=o.slice(0,-1),a=t.A.isNotEmpty(i)?N(e(),i):e();return[...t.G.isObject(s)||t.G.isArray(s)?n.get(r(s))?.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:(i,a)=>"pending"===a?()=>!t.A.isEmpty(s(r)):"remaining"===a?()=>t.A.length(s(r)):"box"===a?()=>({value:N(e(),r),inspect:n(r)}):"is"===a?e=>s(r).some(t=>0!==(t.operation&e)):"draft"===a?()=>t.A.head(s(r))?.value??N(e(),r):"settled"===a?()=>new Promise(n=>{if(t.A.isEmpty(s(r)))return n(N(e(),r));const i=()=>{t.A.isEmpty(s(r))&&(c(i),n(N(e(),r)))};o(i)}):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]=k.immer.produceWithPatches(this.#e,t);return this.#e=r.reduce((t,r)=>k.immer.applyPatches(t,[{...r,value:T(e,r,t,n,this.#n,this.#t)}]),this.#e),this.#e=z(this.#e),this.#s(),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.#s()}#s(){this.#r.forEach(e=>e())}observe(e){const t=()=>e(this.#e);return this.#r.add(t),()=>this.#r.delete(t)}}const W=new $;function F(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,s){if("function"!=typeof r)throw new TypeError("The listener must be a function");var i=new o(r,c||e,s),a=n?n+t:t;return e._events[a]?e._events[a].fn?e._events[a]=[e._events[a],i]:e._events[a].push(i):(e._events[a]=i,e._eventsCount++),e}function s(e,t){0===--e._eventsCount?e._events=new r:delete e._events[t]}function i(){this._events=new r,this._eventsCount=0}Object.create&&(r.prototype=Object.create(null),(new r).__proto__||(n=!1)),i.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},i.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},i.prototype.listenerCount=function(e){var t=this._events[n?n+e:e];return t?t.fn?1:t.length:0},i.prototype.emit=function(e,t,r,o,c,s){var i=n?n+e:e;if(!this._events[i])return!1;var a,u,l=this._events[i],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,s),!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},i.prototype.on=function(e,t,n){return c(this,e,t,n,!1)},i.prototype.once=function(e,t,n){return c(this,e,t,n,!0)},i.prototype.removeListener=function(e,t,r,o){var c=n?n+e:e;if(!this._events[c])return this;if(!t)return s(this,c),this;var i=this._events[c];if(i.fn)i.fn!==t||o&&!i.once||r&&i.context!==r||s(this,c);else{for(var a=0,u=[],l=i.length;a<l;a++)(i[a].fn!==t||o&&!i[a].once||r&&i[a].context!==r)&&u.push(i[a]);u.length?this._events[c]=1===u.length?u[0]:u:s(this,c)}return this},i.prototype.removeAllListeners=function(e){var t;return e?this._events[t=n?n+e:e]&&s(this,t):(this._events=new r,this._eventsCount=0),this},i.prototype.off=i.prototype.removeListener,i.prototype.addListener=i.prototype.on,i.prefixed=n,i.EventEmitter=i,e.exports=i}(H)),H.exports);const q=F(I),V=s.createContext(new q);function J(){return s.useContext(V)}function K({children:e}){const t=s.useMemo(()=>new q,[]);return r.jsx(V.Provider,{value:t,children:e})}const Q=s.createContext(new Map);function X(){return s.useContext(Q)}function Y(){const[,e]=s.useReducer(e=>e+1,0);return e}function Z({action:e,renderer:n}){const r=J(),o=X(),c=Y(),i=s.useMemo(()=>{const t=o.get(e);if(t)return t;const n={state:new $,listeners:new Set};return o.set(e,n),n},[e,o]);s.useLayoutEffect(()=>{function t(e){i.state.hydrate({value:e}),i.listeners.forEach(e=>e())}return i.listeners.add(c),r.on(e,t),()=>{i.listeners.delete(c),r.off(e,t)}},[e,r,i]);const a=i.state.model?.value;return t.G.isNullable(a)?null:n({value:a,inspect:i.state.inspect.value})}function ee({children:e}){const t=s.useMemo(()=>new Map,[]);return r.jsx(Q.Provider,{value:t,children:e})}function te({children:e}){const t=s.useMemo(()=>({data:new Map}),[]);return r.jsx(S.Provider,{value:t,children:e})}const ne=s.createContext(new Set);function re({children:e}){const t=s.useMemo(()=>new Set,[]);return r.jsx(ne.Provider,{value:t,children:e})}const oe=s.createContext(null);function ce(){return s.useContext(oe)}function se(e,t){return e?.get(t)??null}function ie({action:e,scopeName:n,renderer:r}){const o=ce(),c=Y(),i=s.useMemo(()=>se(o,n),[o,n]),a=s.useMemo(()=>i?function(e,t){const n=e.store.get(t);if(n)return n;const r={state:new $,listeners:new Set};return e.store.set(t,r),r}(i,e):null,[e,i]);if(s.useLayoutEffect(()=>{if(i&&a)return a.listeners.add(c),i.emitter.on(e,t),()=>{a.listeners.delete(c),i.emitter.off(e,t)};function t(e){a&&(a.state.hydrate({value:e}),a.listeners.forEach(e=>e()))}},[e,i,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})}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{[i.Action]:n,[i.Payload]:void 0,[i.Channel]:e,channel:e}};return Object.defineProperty(r,i.Action,{value:n,enumerable:!1}),Object.defineProperty(r,i.Payload,{value:void 0,enumerable:!1}),t===u.Broadcast&&Object.defineProperty(r,i.Broadcast,{value:!0,enumerable:!1}),t===u.Multicast&&Object.defineProperty(r,i.Multicast,{value:!0,enumerable:!1}),r},e.Boundary=function({children:e}){return r.jsx(K,{children:r.jsx(ee,{children:r.jsx(te,{children:r.jsx(re,{children:e})})})})},e.Distribution=u,e.Error=function({handler:e,children:t}){return r.jsx(E.Provider,{value:e,children:t})},e.Lifecycle=a,e.Op=R,e.Operation=R,e.Reason=f,e.Rehydrate=function(e,t){return{[i.Rehydrate]:!0,model:e,channel:t}},e.Scope=function({name:e,children:t}){const n=ce(),o=s.useMemo(()=>({name:e,emitter:new q,store:new Map,listeners:new Map}),[]),c=s.useMemo(()=>{const t=new Map(n??[]);return t.set(e,o),t},[n,e,o]);return r.jsx(oe.Provider,{value:c,children:t})},e.State=$,e.With=function(e){return(t,n)=>{t.actions.produce(t=>{t.model[e]=n})}},e.annotate=function(e,t){return W.annotate(e,t)},e.useActions=function(e,r=()=>({})){const o=J(),c=ce(),u=n.useContext(E),f=s.useContext(ne),d=Y(),p=s.useRef(!1),h=s.useRef(null),m=s.useRef(new $),{model:y,save:b}=function(e){const t=s.useContext(S),n=s.useRef(null);if(!n.current)if("object"==typeof(r=e)&&null!==r&&i.Rehydrate in r&&!0===r[i.Rehydrate]){const{channel:r,model:o}=e,c=function(e,t){const n=P(t);return e.data.get(n)||null}(t,r);n.current={model:c??o,save:e=>function(e,t,n){const r=P(t);e.data.set(r,n)}(t,r,e)}}else n.current={model:e,save:()=>{}};var r;return n.current}(e);p.current||(p.current=!0,h.current=m.current.hydrate(y));const[O,R]=s.useState(()=>m.current.model),C=function(e){const t=s.useRef(e);return s.useLayoutEffect(()=>{t.current=e},[e]),s.useMemo(()=>{return n=t,Object.keys(e).reduce((e,t)=>(Object.defineProperty(e,t,{get:()=>n.current[t],enumerable:!0}),e),{});var n},[e])}(r()),G=s.useMemo(()=>new q,[]),_=s.useRef({handlers:new Map});_.current.handlers=new Map;const k=function(){const e=s.useRef(new Set),t=s.useRef(new Set);return s.useMemo(()=>({broadcast:e.current,multicast:t.current}),[])}(),N=s.useRef(l.Mounting),z=function(){const e=s.useRef({}),t=s.useRef(new Map),n=s.useRef(new Map);return s.useMemo(()=>({refs:e,pending:t,emitted:n}),[])}(),U=s.useRef(new Set),L=s.useRef(0),T=s.useCallback((e,t,n)=>{const r=new AbortController,s={controller:r,action:e,payload:t};return f.add(s),U.current.add(s),{model:O,get phase(){return N.current},task:s,data:C,tasks:f,nodes:z.refs.current,actions:{produce(e){if(r.signal.aborted)return;const t=m.current.produce(t=>e({model:t,inspect:m.current.inspect}));R(m.current.model),n.processes.add(t),h.current&&(n.processes.add(h.current),h.current=null)},dispatch(e,t,n){if(r.signal.aborted)return;const s=v(e),i=x(e)?e.channel:void 0;if(j(e)&&n?.scope){const e=se(c,n.scope);return void(e&&e.emitter.emit(s,t,i))}(g(e)?o:G).emit(s,t,i)},annotate:(e,t)=>m.current.annotate(e,t)}}},[O]);s.useLayoutEffect(()=>{function e(e,n,r){return async function(o,c){const s=r();if(t.G.isNotNullable(c)&&t.G.isNotNullable(s)&&!function(e,t){for(const n of Object.keys(e))if(t[n]!==e[n])return!1;return!0}(c,s))return;const i={processes:new Set},l=Promise.withResolvers(),p=T(e,o,i);try{await n(p,o)}catch(h){const t=_.current.handlers.has(a.Error),n={reason:A(h),error:M(h),action:w(e),handled:t,tasks:f};u?.(n),t&&G.emit(a.Error,n)}finally{for(const e of f)if(e===p.task){f.delete(e),U.current.delete(e);break}i.processes.forEach(e=>m.current.prune(e)),i.processes.size>0&&d(),l.resolve()}}}L.current++;const n=new Set;return _.current.handlers.forEach((t,r)=>{for(const{getChannel:s,handler:i}of t){const t=e(r,i,s);if(j(r)){if(c)for(const e of c.values()){const o=e.emitter;o.on(r,t),n.add(()=>o.off(r,t))}G.on(r,t),k.multicast.add(r),n.add(()=>G.off(r,t))}else g(r)?(o.on(r,t),G.on(r,t),k.broadcast.add(r),n.add(()=>{o.off(r,t),G.off(r,t)})):(G.on(r,t),n.add(()=>G.off(r,t)))}}),()=>{const e=++L.current,t=new Set(n);queueMicrotask(()=>{if(L.current===e){b(m.current.model);for(const e of U.current)e.controller.abort(),f.delete(e);U.current.clear(),N.current=l.Unmounting,G.emit(a.Unmount),N.current=l.Unmounted;for(const e of t)e()}else for(const e of t)e()})}},[G]),s.useLayoutEffect(()=>{for(const[e,t]of z.pending.current)z.emitted.current.get(e)!==t&&(z.emitted.current.set(e,t),G.emit(i.Node,t,{Name:e}));z.pending.current.clear()}),function({unicast:e,broadcastActions:n,phase:r,data:o}){const c=X(),i=s.useRef(null);s.useLayoutEffect(()=>{r.current===l.Mounting&&(e.emit(a.Mount),n.forEach(n=>{const r=c.get(n),o=r?.state.model?.value;t.G.isNullable(o)||e.emit(n,o)}),r.current=l.Mounted)},[]),s.useLayoutEffect(()=>{if(t.G.isNotNullable(i.current)){const n=function(e,t){return Object.keys(t).reduce((n,r)=>e[r]!==t[r]?{...n,[r]:t[r]}:n,{})}(i.current,o);t.A.isNotEmpty(Object.keys(n))&&e.emit(a.Update,n)}i.current=o},[o,e])}({unicast:G,broadcastActions:k.broadcast,phase:N,data:r()});const B=s.useMemo(()=>[O,{dispatch(e,t,n){const r=v(e),s=x(e)?e.channel:void 0;if(j(e)&&n?.scope){const e=se(c,n.scope);return void(e&&e.emitter.emit(r,t,s))}(g(e)?o:G).emit(r,t,s)},consume:(e,t,n)=>j(e)&&n?.scope?s.createElement(ie,{action:v(e),scopeName:n.scope,renderer:t}):s.createElement(Z,{action:v(e),renderer:t}),get inspect(){return m.current.inspect},get nodes(){return z.refs.current},node(e,t){z.refs.current[e]=t,z.pending.current.set(e,t)}}],[O,G]);return B.useAction=(e,t)=>{!function(e,t,n){const r=s.useRef(n);s.useLayoutEffect(()=>{r.current=n});const o=s.useRef(t);s.useLayoutEffect(()=>{o.current=t});const c=s.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)},[]),i=s.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:i,handler:c})}(_,e,t)},B},e.utils=y,Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})},"object"==typeof exports&&"undefined"!=typeof module?factory(exports,require("@mobily/ts-belt"),require("react"),require("react/jsx-runtime"),require("immer")):"function"==typeof define&&define.amd?define(["exports","@mobily/ts-belt","react","react/jsx-runtime","immer"],factory):factory((global="undefined"!=typeof globalThis?globalThis:global||self).Chizu={},global.TsBelt,global.React,global.jsxRuntime,global.Immer);
@@ -1,5 +1,6 @@
1
1
  import { Data } from './types.ts';
2
2
  import { Model, Props, Actions, UseActions } from '../types/index.ts';
3
+ import { Rehydrated } from '../rehydrate/index.ts';
3
4
  export { With } from './utils.ts';
4
5
  /**
5
6
  * A hook for managing state with actions.
@@ -17,64 +18,32 @@ export { With } from './utils.ts';
17
18
  *
18
19
  * @template M The model type representing the component's state.
19
20
  * @template AC The actions class containing action definitions.
20
- * @template S The data type for reactive external values.
21
- * @param initialModel The initial model state.
22
- * @param ƒ Optional function that returns reactive values as data.
21
+ * @template D The data type for reactive external values.
22
+ * @param initialModelOrRehydrated The initial model state, or a `Rehydrate(model, channel)`
23
+ * wrapper for automatic state persistence across unmount/remount cycles.
24
+ * When a `Rehydrated` wrapper is passed, the model is restored from the
25
+ * rehydrator on mount (if a matching snapshot exists) and snapshotted
26
+ * back on unmount.
27
+ * @param getData Optional function that returns reactive values as data.
23
28
  * Values returned are accessible via `context.data` in action handlers,
24
29
  * always reflecting the latest values even after await operations.
25
30
  * @returns A result `[model, actions]` with pre-typed `useAction` method.
26
31
  *
27
32
  * @example
28
33
  * ```typescript
29
- * // types.ts
30
- * type Model = { visitor: Country | null };
31
- *
32
- * export class Actions {
33
- * static Visitor = Action<Country>("Visitor");
34
- * }
35
- *
36
- * // actions.ts
37
- * export function useVisitorActions() {
38
- * const actions = useActions<Model, typeof Actions>(model);
39
- *
40
- * actions.useAction(Lifecycle.Mount, (context) => {
41
- * // Setup logic - types are pre-baked from useActions
42
- * });
43
- *
44
- * actions.useAction(Actions.Visitor, (context, country) => {
45
- * context.actions.produce((draft) => {
46
- * draft.model.visitor = country;
47
- * });
48
- * });
49
- *
50
- * actions.useAction(Lifecycle.Unmount, (context) => {
51
- * // Cleanup logic
52
- * });
53
- *
54
- * return actions;
55
- * }
56
- *
57
- * // With data for reactive external values
58
- * function useSearchActions(props: { query: string }) {
59
- * const actions = useActions<Model, typeof Actions, { query: string }>(
60
- * model,
61
- * () => ({ query: props.query })
62
- * );
63
- *
64
- * actions.useAction(Actions.Search, async (context) => {
65
- * await fetch("/search");
66
- * // context.data.query is always the latest value
67
- * console.log(context.data.query);
68
- * });
69
- *
70
- * return actions;
71
- * }
72
- *
73
- * // Component usage
74
- * function Visitor() {
75
- * const [model, actions] = useVisitorActions();
76
- * return <div>{model.visitor?.name}</div>;
77
- * }
34
+ * // Basic usage
35
+ * const actions = useActions<Model, typeof Actions>(model);
36
+ *
37
+ * // With rehydration — state survives unmount/remount
38
+ * const actions = useActions<Model, typeof Actions>(
39
+ * Rehydrate(model, { UserId: props.userId }),
40
+ * );
41
+ *
42
+ * // With reactive data
43
+ * const actions = useActions<Model, typeof Actions, { query: string }>(
44
+ * model,
45
+ * () => ({ query: props.query }),
46
+ * );
78
47
  * ```
79
48
  */
80
- export declare function useActions<M extends Model, AC extends Actions, D extends Props = Props>(initialModel: M, getData?: Data<D>): UseActions<M, AC, D>;
49
+ export declare function useActions<M extends Model, AC extends Actions, D extends Props = Props>(initialModelOrRehydrated: M | Rehydrated<M>, getData?: Data<D>): UseActions<M, AC, D>;
package/dist/index.d.ts CHANGED
@@ -1,8 +1,9 @@
1
1
  export { Action } from './action/index.ts';
2
- export { Cache } from './cache/index.ts';
2
+ export { Rehydrate } from './rehydrate/index.ts';
3
3
  export { Distribution, Lifecycle } from './types/index.ts';
4
4
  export { Error, Reason } from './error/index.tsx';
5
5
  export { Operation, Op, State } from 'immertation';
6
+ export { annotate } from './annotate/index.ts';
6
7
  export { Boundary } from './boundary/index.tsx';
7
8
  export { Scope } from './boundary/components/scope/index.tsx';
8
9
  export { useActions, With } from './hooks/index.ts';
@@ -0,0 +1,54 @@
1
+ import { Filter, Model } from '../types/index.ts';
2
+ /**
3
+ * Branded wrapper for a model with rehydration metadata.
4
+ * When passed to `useActions`, the model state is automatically saved to the
5
+ * rehydrator on unmount and restored from it on remount.
6
+ */
7
+ export type Rehydrated<M extends Model = Model> = {
8
+ readonly model: M;
9
+ readonly channel: Filter;
10
+ };
11
+ /**
12
+ * Wraps an initial model with rehydration metadata.
13
+ *
14
+ * When a rehydrated model is passed to `useActions`, the component's state is
15
+ * automatically snapshotted to the rehydrator on unmount and restored from it
16
+ * on remount if a matching entry exists.
17
+ *
18
+ * The channel parameter acts as a key for the snapshot, allowing different
19
+ * component instances to maintain independent rehydrated state.
20
+ *
21
+ * @template M - The model type.
22
+ * @param model - The initial model (used as fallback when no snapshot exists).
23
+ * @param channel - Channel key identifying this component's snapshot.
24
+ * @returns A branded object containing the model and rehydration metadata.
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * const actions = useActions<Model, typeof Actions>(
29
+ * Rehydrate(model, { UserId: props.userId }),
30
+ * );
31
+ * ```
32
+ */
33
+ export declare function Rehydrate<M extends Model>(model: M, channel: Filter): Rehydrated<M>;
34
+ /**
35
+ * Type guard to detect whether a value is a `Rehydrated` wrapper.
36
+ */
37
+ export declare function isRehydrated<M extends Model>(value: M | Rehydrated<M>): value is Rehydrated<M>;
38
+ /**
39
+ * Hook that resolves the initial model from a potential `Rehydrated` wrapper.
40
+ *
41
+ * On first call, checks the rehydrator for an existing snapshot matching the
42
+ * channel key. If found, returns the snapshot; otherwise returns the initial
43
+ * model. Also returns a `save` function for persisting the model on unmount.
44
+ *
45
+ * For non-rehydrated models, `save` is a no-op.
46
+ *
47
+ * @template M - The model type.
48
+ * @param initialModelOrRehydrated - A plain model or a `Rehydrated` wrapper.
49
+ * @returns The resolved model and a save function.
50
+ */
51
+ export declare function useRehydration<M extends Model>(initialModelOrRehydrated: M | Rehydrated<M>): {
52
+ model: M;
53
+ save: (model: M) => void;
54
+ };
@@ -56,10 +56,8 @@ export declare class Brand {
56
56
  static Channel: symbol;
57
57
  /** Node capture events used by Lifecycle.Node */
58
58
  static Node: symbol;
59
- /** Identifies cache operations created with Cache() */
60
- static Cache: symbol;
61
- /** TTL value for cache operations */
62
- static TTL: symbol;
59
+ /** Identifies rehydrated model wrappers created with Rehydrate() */
60
+ static Rehydrate: symbol;
63
61
  }
64
62
  /**
65
63
  * Lifecycle actions that trigger at specific points in a component's lifecycle.
@@ -279,56 +277,6 @@ export type BroadcastPayload<P = unknown, C extends Filter = never> = HandlerPay
279
277
  * ```
280
278
  */
281
279
  export type MulticastPayload<P = unknown, C extends Filter = never> = HandlerPayload<P, C> & {};
282
- /**
283
- * Branded type for cache operations created with `Cache()`.
284
- * Cache operations identify cached async results and carry a TTL for expiration.
285
- *
286
- * When a channel type is specified, the cache operation becomes callable to
287
- * create channeled cache keys for targeted lookups.
288
- *
289
- * @template C - The channel type for keyed cache entries (defaults to never)
290
- *
291
- * @example
292
- * ```ts
293
- * export class CacheStore {
294
- * static User = Cache<{ UserId: number }>(30_000); // 30s TTL, channeled
295
- * static Config = Cache(60_000); // 60s TTL, unchanneled
296
- * }
297
- *
298
- * // Channeled usage
299
- * context.actions.cache.put(CacheStore.User({ UserId: 5 }), () => fetchUser(5));
300
- * context.actions.cache.delete(CacheStore.User({ UserId: 5 }));
301
- * ```
302
- */
303
- export type CachePayload<C extends Filter = never> = {} & ([C] extends [never] ? unknown : {
304
- (channel: C): ChanneledCache<C>;
305
- });
306
- /**
307
- * Result of calling a cache operation with a channel argument.
308
- * Contains the cache reference and the channel data for keyed lookup.
309
- *
310
- * @template C - The channel type
311
- */
312
- export type ChanneledCache<C = unknown> = {
313
- readonly channel: C;
314
- };
315
- /**
316
- * Union type representing either a plain or channeled cache operation.
317
- * Used in `cache.put`, `cache.get`, and `cache.delete` signatures.
318
- */
319
- export type AnyCacheOperation = CachePayload<Filter> | ChanneledCache;
320
- /**
321
- * Interface for the Cache factory function.
322
- */
323
- export type CacheFactory = {
324
- /**
325
- * Creates a new cache operation with a TTL in milliseconds.
326
- * @template C The channel type for keyed cache entries (defaults to never).
327
- * @param ttl Time-to-live in milliseconds.
328
- * @returns A typed cache operation object.
329
- */
330
- <C extends Filter = never>(ttl: number): CachePayload<C>;
331
- };
332
280
  /**
333
281
  * Options for multicast dispatch.
334
282
  * Required when dispatching a multicast action.
@@ -555,76 +503,6 @@ export type HandlerContext<M extends Model, _AC extends Actions, D extends Props
555
503
  }) => void>(ƒ: F & AssertSync<F>): void;
556
504
  dispatch(action: ActionOrChanneled, payload?: unknown, options?: MulticastOptions): void;
557
505
  annotate<T>(operation: Operation, value: T): T;
558
- /**
559
- * Cache operations for reading, writing, and deleting cached values.
560
- */
561
- cache: {
562
- /**
563
- * Retrieves a value from cache if available and within TTL,
564
- * otherwise executes the async function and caches the result.
565
- *
566
- * Returns `T` synchronously on cache hit, or `Promise<T>` on cache miss.
567
- * Using `await` handles both cases uniformly.
568
- *
569
- * @param operation - The cache operation (plain or channeled).
570
- * @param fn - Async function receiving a `cache` callback. Call `cache(value)` to store the value; if not called, nothing is cached.
571
- * @returns The cached or freshly fetched value.
572
- *
573
- * @example
574
- * ```ts
575
- * const user = await context.actions.cache.put(
576
- * CacheOps.User({ UserId: 5 }),
577
- * async (cache) => {
578
- * const response = await fetchUser(5);
579
- * return response.error ? response : cache(response);
580
- * },
581
- * );
582
- * ```
583
- */
584
- put<T>(operation: AnyCacheOperation, fn: (cache: (value: T) => T) => Promise<T>): T | Promise<T>;
585
- /**
586
- * Reads a cached value for a cache operation without triggering a fetch.
587
- * Returns `undefined` if no entry exists or the entry has expired.
588
- *
589
- * @template T - The expected value type.
590
- * @param operation - The cache operation (plain or channeled).
591
- * @returns The cached value, or `undefined` if not found or expired.
592
- *
593
- * @example
594
- * ```ts
595
- * const user = context.actions.cache.get<User>(CacheStore.User({ UserId: 5 }));
596
- * if (user) {
597
- * context.actions.produce(({ model }) => {
598
- * model.user = user;
599
- * });
600
- * }
601
- * ```
602
- */
603
- get<T>(operation: AnyCacheOperation): T | undefined;
604
- /**
605
- * Deletes cache entries for a cache operation.
606
- *
607
- * With a channeled operation, deletes all entries whose channel
608
- * contains the specified keys (partial match). For example,
609
- * `cache.delete(CacheOps.User({ UserId: 5 }))` removes entries for
610
- * `{ UserId: 5 }`, `{ UserId: 5, Role: "admin" }`, etc.
611
- *
612
- * With a plain (unchanneled) operation, deletes all entries
613
- * for that operation regardless of channel.
614
- *
615
- * @param operation - The cache operation (plain or channeled).
616
- *
617
- * @example
618
- * ```ts
619
- * // Delete specific cache entry (partial channel match)
620
- * context.actions.cache.delete(CacheOps.User({ UserId: 5 }));
621
- *
622
- * // Delete ALL user cache entries
623
- * context.actions.cache.delete(CacheOps.User);
624
- * ```
625
- */
626
- delete(operation: AnyCacheOperation): void;
627
- };
628
506
  };
629
507
  };
630
508
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chizu",
3
- "version": "0.2.50",
3
+ "version": "0.2.52",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "packageManager": "yarn@1.22.22",
@@ -15,7 +15,7 @@
15
15
  },
16
16
  "dependencies": {
17
17
  "eventemitter3": "^5.0.1",
18
- "immertation": "^0.1.23"
18
+ "immertation": "^0.1.25"
19
19
  },
20
20
  "peerDependencies": {
21
21
  "@mobily/ts-belt": "^3.0.0",
@@ -38,7 +38,6 @@
38
38
  "@babel/preset-env": "^7.28.5",
39
39
  "@babel/preset-react": "^7.28.5",
40
40
  "@babel/preset-typescript": "^7.28.5",
41
- "antd": "^6.1.4",
42
41
  "@emotion/css": "^11.13.5",
43
42
  "@eslint/js": "^9.39.2",
44
43
  "@faker-js/faker": "^10.2.0",
@@ -54,6 +53,7 @@
54
53
  "@types/react-dom": "^19.2.3",
55
54
  "@types/traverse": "^0.6.37",
56
55
  "@vitejs/plugin-react": "^5.1.2",
56
+ "antd": "^6.1.4",
57
57
  "commit-and-tag-version": "^12.6.1",
58
58
  "dayjs": "^1.11.19",
59
59
  "dexie": "^4.2.1",
@@ -1,14 +0,0 @@
1
- import { Props } from './types.ts';
2
- import * as React from "react";
3
- export { useCache } from './utils.ts';
4
- export type { CacheEntry, CacheStore } from './types.ts';
5
- /**
6
- * Creates a new cache context for caching async results within action handlers.
7
- * Automatically included in `<Boundary>`. Only needed directly if you want to
8
- * isolate a cache context, useful for libraries that want their own cache
9
- * without interfering with the app's cache.
10
- *
11
- * @param props.children - The children to render within the cache context.
12
- * @returns The children wrapped in a cache context provider.
13
- */
14
- export declare function CacheProvider({ children }: Props): React.ReactNode;
@@ -1,24 +0,0 @@
1
- import { Filter } from '../../../types/index.ts';
2
- import type * as React from "react";
3
- /**
4
- * A single cache entry with its stored value, expiration timestamp, and
5
- * original channel for partial-match invalidation.
6
- */
7
- export type CacheEntry = {
8
- value: unknown;
9
- expiresAt: number;
10
- channel: Filter | undefined;
11
- };
12
- /**
13
- * The cache store: outer Map keyed by operation symbol, inner Map keyed
14
- * by serialised channel string.
15
- *
16
- * For unchanneled cache operations, the inner key is an empty string "".
17
- */
18
- export type CacheStore = Map<symbol, Map<string, CacheEntry>>;
19
- /**
20
- * Props for the CacheProvider component.
21
- */
22
- export type Props = {
23
- children: React.ReactNode;
24
- };
@@ -1,12 +0,0 @@
1
- import { CacheStore } from './types.ts';
2
- import * as React from "react";
3
- /**
4
- * React context for the shared cache store.
5
- */
6
- export declare const Context: React.Context<CacheStore>;
7
- /**
8
- * Hook to access the cache store from context.
9
- *
10
- * @returns The cache store Map from the current context.
11
- */
12
- export declare function useCache(): CacheStore;
@@ -1,29 +0,0 @@
1
- import { CacheFactory } from '../types/index.ts';
2
- export { getCacheSymbol, getCacheTtl, isCacheOperation, isChanneledCache, serializeChannel, matchesCacheChannel, } from './utils.ts';
3
- /**
4
- * Creates a new cache operation with a TTL (time-to-live) in milliseconds.
5
- *
6
- * Cache operations are identifiers used with `context.actions.cache.put()` and
7
- * `context.actions.cache.delete()` to manage cached async results. They follow the
8
- * same channel pattern as actions.
9
- *
10
- * @template C - The channel type for keyed cache entries (defaults to never).
11
- * @param ttl - Time-to-live in milliseconds.
12
- * @returns A typed cache operation object.
13
- *
14
- * @example
15
- * ```ts
16
- * export class CacheStore {
17
- * static User = Cache<{ UserId: number }>(30_000); // 30s TTL, channeled
18
- * static Config = Cache(60_000); // 60s TTL, unchanneled
19
- * }
20
- *
21
- * // Channeled usage
22
- * context.actions.cache.put(CacheStore.User({ UserId: 5 }), () => fetchUser(5));
23
- *
24
- * // Deletion (partial channel match)
25
- * context.actions.cache.delete(CacheStore.User({ UserId: 5 }));
26
- * context.actions.cache.delete(CacheStore.User); // clears all
27
- * ```
28
- */
29
- export declare const Cache: CacheFactory;
@@ -1,48 +0,0 @@
1
- import { Filter } from '../types/index.ts';
2
- /**
3
- * Extracts the underlying symbol from a cache operation or channeled cache.
4
- *
5
- * @param operation The cache operation to extract the symbol from.
6
- * @returns The underlying symbol.
7
- */
8
- export declare function getCacheSymbol(operation: unknown): symbol;
9
- /**
10
- * Extracts the TTL from a cache operation or channeled cache.
11
- *
12
- * @param operation The cache operation to extract the TTL from.
13
- * @returns The TTL in milliseconds.
14
- */
15
- export declare function getCacheTtl(operation: unknown): number;
16
- /**
17
- * Checks whether a value is a cache operation.
18
- *
19
- * @param value The value to check.
20
- * @returns True if the value is a cache operation.
21
- */
22
- export declare function isCacheOperation(value: unknown): boolean;
23
- /**
24
- * Checks whether a value is a channeled cache operation.
25
- *
26
- * @param value The value to check.
27
- * @returns True if the value is a channeled cache operation with a channel property.
28
- */
29
- export declare function isChanneledCache(value: unknown): boolean;
30
- /**
31
- * Serialises a channel object into a deterministic string key for cache lookup.
32
- * Keys are sorted alphabetically for deterministic output.
33
- * Returns an empty string for unchanneled operations.
34
- *
35
- * @param channel The channel object to serialise.
36
- * @returns A deterministic string representation of the channel.
37
- */
38
- export declare function serializeChannel(channel?: Filter): string;
39
- /**
40
- * Checks whether an invalidation channel partially matches a stored channel.
41
- * Returns true if ALL keys in the invalidation channel exist in the stored
42
- * channel with matching values.
43
- *
44
- * @param invalidateChannel The channel from the invalidation call.
45
- * @param storedChannel The channel stored with the cache entry.
46
- * @returns True if the invalidation channel is a subset of the stored channel.
47
- */
48
- export declare function matchesCacheChannel(invalidateChannel: Filter, storedChannel: Filter): boolean;