chizu 0.2.53 → 0.2.55

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,31 +248,59 @@ 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
- To preserve a component's state across unmount/remount cycles, define a store with `Id` and wrap the initial model with `Rehydrate`:
251
+ For data that is expensive to fetch, use `cacheable` to cache values with a TTL. Define typed cache entries with `Entry` and call `context.actions.cacheable` inside a handler – the callback only runs when the cache is empty or expired:
252
252
 
253
253
  ```ts
254
- import { useActions, Rehydrate, Id } from "chizu";
254
+ import { Entry, useActions, Action } from "chizu";
255
+ import { O } from "@mobily/ts-belt";
255
256
 
256
- class Store {
257
- static Counter = Id<Model, { UserId: number }>();
258
- static Settings = Id<Model>();
257
+ class CacheStore {
258
+ static Pairs = Entry<CryptoPair[]>();
259
+ static User = Entry<User, { UserId: number }>();
259
260
  }
260
261
 
261
- // Channeled — independent snapshot per UserId
262
- const actions = useActions<Model, typeof Actions>(
263
- Rehydrate(model, Store.Counter({ UserId: props.userId })),
264
- );
262
+ class Actions {
263
+ static FetchPairs = Action("FetchPairs");
264
+ static FetchUser = Action("FetchUser");
265
+ }
266
+ ```
265
267
 
266
- // Unchanneled — single shared snapshot
267
- const actions = useActions<Model, typeof Actions>(
268
- Rehydrate(model, Store.Settings()),
269
- );
268
+ ```ts
269
+ actions.useAction(Actions.FetchPairs, async (context) => {
270
+ const { data } = await context.actions.cacheable(
271
+ CacheStore.Pairs,
272
+ 30_000,
273
+ async () => O.Some(await api.fetchPairs()),
274
+ );
275
+
276
+ if (data) {
277
+ context.actions.produce(({ model }) => {
278
+ model.pairs = data;
279
+ });
280
+ }
281
+ });
282
+
283
+ // Channeled &ndash; independent cache per user
284
+ actions.useAction(Actions.FetchUser, async (context) => {
285
+ const { data } = await context.actions.cacheable(
286
+ CacheStore.User({ UserId: context.data.userId }),
287
+ 60_000,
288
+ async () => O.Some(await api.fetchUser(context.data.userId)),
289
+ );
290
+
291
+ if (data) {
292
+ context.actions.produce(({ model }) => {
293
+ model.user = data;
294
+ });
295
+ }
296
+ });
270
297
  ```
271
298
 
272
- When the component unmounts, its model is snapshotted into the rehydrator. On remount with the same channel key, the model is restored automatically. Use `context.actions.invalidate` to clear a specific snapshot so the next mount starts fresh:
299
+ Only `Some` / `Ok` values are stored in the cache. `None` and `Error` results are skipped. Use `context.actions.invalidate` to clear a specific entry so the next `cacheable` call fetches fresh data:
273
300
 
274
301
  ```ts
275
- context.actions.invalidate(Store.Counter({ UserId: 5 }));
302
+ context.actions.invalidate(CacheStore.Pairs);
303
+ context.actions.invalidate(CacheStore.User({ UserId: 5 }));
276
304
  ```
277
305
 
278
- This is useful for tab switching, route changes, and conditionally rendered components. See the [rehydration recipe](./recipes/rehydration.md) for details.
306
+ The cache is scoped to the nearest `<Boundary>`. See the [caching recipe](./recipes/caching.md) for more details.
@@ -0,0 +1,13 @@
1
+ import { Props } from './types.ts';
2
+ import * as React from "react";
3
+ export { useCacheStore } from './utils.ts';
4
+ export type { CacheContext } from './types.ts';
5
+ /**
6
+ * Creates a new cache context for storing values from `context.actions.cacheable`.
7
+ * Automatically included in `<Boundary>`. Only needed directly if you want to
8
+ * isolate a cache context.
9
+ *
10
+ * @param props.children - The children to render within the cache context.
11
+ * @returns The children wrapped in a cache context provider.
12
+ */
13
+ export declare function CacheProvider({ children }: Props): React.ReactNode;
@@ -0,0 +1,19 @@
1
+ import type * as React from "react";
2
+ /**
3
+ * A single cached value with its expiry timestamp.
4
+ */
5
+ export type CacheItem = {
6
+ value: unknown;
7
+ expiry: number;
8
+ };
9
+ /**
10
+ * Store for cached values.
11
+ * Keyed by a deterministic string derived from the entry symbol and channel.
12
+ */
13
+ export type CacheContext = Map<string, CacheItem>;
14
+ /**
15
+ * Props for the CacheProvider component.
16
+ */
17
+ export type Props = {
18
+ children: React.ReactNode;
19
+ };
@@ -0,0 +1,12 @@
1
+ import { CacheContext } 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<CacheContext>;
7
+ /**
8
+ * Hook to access the cache store from context.
9
+ *
10
+ * @returns The cache Map from the nearest CacheProvider.
11
+ */
12
+ export declare function useCacheStore(): CacheContext;
@@ -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, Rehydrate, and Tasks providers.
5
+ * Wraps children with Broadcaster, Consumer, Cache, and Tasks providers.
6
6
  *
7
7
  * Use this at the root of your application or to create isolated context boundaries
8
8
  * for libraries that need their own Chizu context.
@@ -0,0 +1,77 @@
1
+ import { Filter, CacheId, ChanneledCacheId } from '../types/index.ts';
2
+ export type { CacheId, ChanneledCacheId };
3
+ /**
4
+ * Creates a typed cache entry identifier for use with `context.actions.cacheable`
5
+ * and `context.actions.invalidate`.
6
+ *
7
+ * Each call produces a unique identity. The first type parameter `T` binds the
8
+ * entry to a specific value type, ensuring that `cacheable` callbacks return the
9
+ * correct type.
10
+ *
11
+ * When called with only `T`, the entry is unchanneled &mdash; a single cache slot.
12
+ * When called with `T` and `C`, the entry is channeled &mdash; independent cache
13
+ * slots per channel value.
14
+ *
15
+ * @template T - The cached value type.
16
+ * @template C - The channel type, constrained to `Filter`.
17
+ * @returns A cache entry identifier for use with `cacheable` and `invalidate`.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * import { Entry } from "chizu";
22
+ *
23
+ * class CacheStore {
24
+ * // Unchanneled &mdash; single cache slot
25
+ * static Pairs = Entry<CryptoPair[]>();
26
+ *
27
+ * // Channeled &mdash; independent slot per UserId
28
+ * static User = Entry<User, { UserId: number }>();
29
+ * }
30
+ *
31
+ * // Unchanneled usage
32
+ * await context.actions.cacheable(CacheStore.Pairs, 30_000, async () => ...);
33
+ *
34
+ * // Channeled usage
35
+ * await context.actions.cacheable(CacheStore.User({ UserId: 5 }), 60_000, async () => ...);
36
+ *
37
+ * // Invalidate
38
+ * context.actions.invalidate(CacheStore.Pairs);
39
+ * context.actions.invalidate(CacheStore.User({ UserId: 5 }));
40
+ * ```
41
+ */
42
+ export declare function Entry<T>(): CacheId<T>;
43
+ export declare function Entry<T, C extends Filter>(): CacheId<T, C>;
44
+ /**
45
+ * Extracts the identity symbol from a plain or channeled cache entry.
46
+ */
47
+ export declare function getCacheSymbol(entry: CacheId | ChanneledCacheId): symbol;
48
+ /**
49
+ * Type guard that returns `true` when the entry is a channeled cache identifier.
50
+ */
51
+ export declare function isChanneledCacheId(entry: CacheId | ChanneledCacheId): entry is ChanneledCacheId;
52
+ /**
53
+ * Serialises a channel object into a deterministic string key.
54
+ * Keys are sorted alphabetically for deterministic output.
55
+ * Returns an empty string for unchanneled operations.
56
+ */
57
+ export declare function serializeChannel(channel?: Filter): string;
58
+ /**
59
+ * Builds the cache Map key from an entry identifier.
60
+ * Combines the symbol description (unique per Entry call) with the
61
+ * serialised channel string for channeled entries.
62
+ */
63
+ export declare function getCacheKey(entry: CacheId | ChanneledCacheId): string;
64
+ /**
65
+ * Unwraps one layer of `Option` or `Result` from a value.
66
+ *
67
+ * - `Some(value)` (non-null/undefined) &rarr; `{ ok: true, value }`
68
+ * - `None` (null/undefined) &rarr; `{ ok: false }`
69
+ * - `Ok(value)` (TAG 0) &rarr; `{ ok: true, value: _0 }`
70
+ * - `Error(value)` (TAG 1) &rarr; `{ ok: false }`
71
+ */
72
+ export declare function unwrap(result: unknown): {
73
+ ok: true;
74
+ value: unknown;
75
+ } | {
76
+ ok: false;
77
+ };
package/dist/chizu.js CHANGED
@@ -1,8 +1,8 @@
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 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 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(){const e=/* @__PURE__ */Symbol();return t=>t??{_:e}}function _(e,t){return{[u.Rehydrate]:!0,model:e,channel:t}}function k(e){if(e instanceof Error){if("TimeoutError"===e.name)return p.Timedout;if("AbortError"===e.name)return p.Supplanted}return p.Errored}function R(e){return e instanceof Error?e:new Error(String(e))}const C=r(void 0);function N({handler:e,children:t}){/* @__PURE__ */
2
- return c(C.Provider,{value:e,children:t})}let U=(e=21)=>{let t="",n=crypto.getRandomValues(new Uint8Array(e|=0));for(;e--;)t+="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"[63&n[e]];return t};var z=/* @__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))(z||{}),L=/* @__PURE__ */(e=>(e[e.Produce=0]="Produce",e[e.Hydrate=1]="Hydrate",e))(L||{}),T=/* @__PURE__ */(e=>(e.Property="property",e.Process="process",e.Value="value",e.Operation="operation",e))(T||{});class B{[i]=!0;static keys=new Set(Object.values(T));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 ${static immer=(()=>{s();const e=new a;return e.setAutoFreeze(!1),e})();static tag="κ";static id=U}function F(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 W(t){if(e.isNullable(t)||D(t))return t;if(e.isArray(t))return t.map(e=>W(e));if(e.isObject(t)){const e=Object.entries(t).map(([e,t])=>[e,W(t)]);return{...Object.fromEntries(e),[$.tag]:t[$.tag]??$.id()}}return t}function H(e){if(Array.isArray(e))return e.filter(e=>$.tag in e).map(e=>e[$.tag]??"").join(",");const t=e[$.tag];if(t)return t;try{return JSON.stringify(e)}catch{return`[unserializable:${typeof e}]`}}function D(t){return e.isNullable(t)||e.isString(t)||e.isNumber(t)||e.isBoolean(t)||"symbol"==typeof t||"bigint"==typeof t}function I(t,n,r,o,c,i){return function s(a,u=n.path){if(a instanceof B){const n=F(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))),D(a.value)){if(t===L.Hydrate)return a.value;const s=u.slice(0,-1),l=s.length>0?F(r,s.join(".")):r;return e.isNullable(l)||G(l,a,u.at(-1),o,c,i),n??a.value}if(t===L.Hydrate){const e=W(s(a.value,u));return G(e,a,null,o,c,i),e}const l=n??W(a.value);return G(l,a,null,o,c,i),e.isNullable(n)?l:(s(a.value,u),n)}if(e.isArray(a))return a.map((e,t)=>s(e,u.concat(t)));if(e.isObject(a)){const e=Object.entries(a).map(([e,t])=>[e,s(t,u.concat(e))]),n=Object.fromEntries(e);if(t===L.Hydrate){const e=W(n);return Object.entries(a).forEach(([t,n])=>{n instanceof B&&D(n.value)&&G(e,n,t,o,c,i)}),e}return n}return a}(n.value)}function G(e,t,n,r,o,c){const i=c(e),s=o.get(i)??[];o.set(i,[t.assign(n,r),...s])}class V{#e={};#t;#n=/* @__PURE__ */new Map;#r=/* @__PURE__ */new Set;#o=!1;constructor(e=H){this.#t=e}static pk(){return U()}static"κ"=V.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=F(n(),c),a=c.slice(0,-1),u=t.isNotEmpty(a)?F(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:F(n(),r),inspect:e(r)}):"is"===a?e=>s(r).some(t=>0!==(t.operation&e)):"draft"===a?()=>t.head(s(r))?.value??F(n(),r):"settled"===a?()=>new Promise(e=>{if(t.isEmpty(s(r)))return e(F(n(),r));const o=()=>{t.isEmpty(s(r))&&(i(o),e(F(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(L.Hydrate,()=>e)}produce(e){if(!this.#o)throw new Error("State must be hydrated using hydrate() before calling produce()");return this.#c(L.Produce,e)}#c(e,t){const n=/* @__PURE__ */Symbol("process"),[,r]=$.immer.produceWithPatches(this.#e,t);return this.#e=r.reduce((t,r)=>$.immer.applyPatches(t,[{...r,value:I(e,r,t,n,this.#n,this.#t)}]),this.#e),this.#e=W(this.#e),this.#i(),n}prune(e){this.#n.forEach((n,r)=>{const o=n.filter(t=>t.process!==e);t.isEmpty(o)?this.#n.delete(r):this.#n.set(r,o)}),this.#i()}#i(){this.#r.forEach(e=>e())}observe(e){const t=()=>e(this.#e);return this.#r.add(t),()=>this.#r.delete(t)}}const q=new V;function J(e,t){return q.annotate(e,t)}function K(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var Q,X={exports:{}};const Y=/* @__PURE__ */K((Q||(Q=1,function(e){var t=Object.prototype.hasOwnProperty,n="~";function r(){}function o(e,t,n){this.fn=e,this.context=t,this.once=n||!1}function c(e,t,r,c,i){if("function"!=typeof r)throw new TypeError("The listener must be a function");var s=new o(r,c||e,i),a=n?n+t:t;return e._events[a]?e._events[a].fn?e._events[a]=[e._events[a],s]:e._events[a].push(s):(e._events[a]=s,e._eventsCount++),e}function i(e,t){0===--e._eventsCount?e._events=new r:delete e._events[t]}function s(){this._events=new r,this._eventsCount=0}Object.create&&(r.prototype=/* @__PURE__ */Object.create(null),(new r).__proto__||(n=!1)),s.prototype.eventNames=function(){var e,r,o=[];if(0===this._eventsCount)return o;for(r in e=this._events)t.call(e,r)&&o.push(n?r.slice(1):r);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(e)):o},s.prototype.listeners=function(e){var t=this._events[n?n+e:e];if(!t)return[];if(t.fn)return[t.fn];for(var r=0,o=t.length,c=new Array(o);r<o;r++)c[r]=t[r].fn;return c},s.prototype.listenerCount=function(e){var t=this._events[n?n+e:e];return t?t.fn?1:t.length:0},s.prototype.emit=function(e,t,r,o,c,i){var s=n?n+e:e;if(!this._events[s])return!1;var a,u,l=this._events[s],f=arguments.length;if(l.fn){switch(l.once&&this.removeListener(e,l.fn,void 0,!0),f){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,t),!0;case 3:return l.fn.call(l.context,t,r),!0;case 4:return l.fn.call(l.context,t,r,o),!0;case 5:return l.fn.call(l.context,t,r,o,c),!0;case 6:return l.fn.call(l.context,t,r,o,c,i),!0}for(u=1,a=new Array(f-1);u<f;u++)a[u-1]=arguments[u];l.fn.apply(l.context,a)}else{var d,p=l.length;for(u=0;u<p;u++)switch(l[u].once&&this.removeListener(e,l[u].fn,void 0,!0),f){case 1:l[u].fn.call(l[u].context);break;case 2:l[u].fn.call(l[u].context,t);break;case 3:l[u].fn.call(l[u].context,t,r);break;case 4:l[u].fn.call(l[u].context,t,r,o);break;default:if(!a)for(d=1,a=new Array(f-1);d<f;d++)a[d-1]=arguments[d];l[u].fn.apply(l[u].context,a)}}return!0},s.prototype.on=function(e,t,n){return c(this,e,t,n,!1)},s.prototype.once=function(e,t,n){return c(this,e,t,n,!0)},s.prototype.removeListener=function(e,t,r,o){var c=n?n+e:e;if(!this._events[c])return this;if(!t)return i(this,c),this;var s=this._events[c];if(s.fn)s.fn!==t||o&&!s.once||r&&s.context!==r||i(this,c);else{for(var a=0,u=[],l=s.length;a<l;a++)(s[a].fn!==t||o&&!s[a].once||r&&s[a].context!==r)&&u.push(s[a]);u.length?this._events[c]=1===u.length?u[0]:u:i(this,c)}return this},s.prototype.removeAllListeners=function(e){var t;return e?this._events[t=n?n+e:e]&&i(this,t):(this._events=new r,this._eventsCount=0),this},s.prototype.off=s.prototype.removeListener,s.prototype.addListener=s.prototype.on,s.prefixed=n,s.EventEmitter=s,e.exports=s}(X)),X.exports)),Z=n.createContext(new Y);function ee(){return n.useContext(Z)}function te({children:e}){const t=n.useMemo(()=>new Y,[]);/* @__PURE__ */
3
- return c(Z.Provider,{value:t,children:e})}const ne=n.createContext(/* @__PURE__ */new Map);function re(){return n.useContext(ne)}function oe(){const[,e]=n.useReducer(e=>e+1,0);return e}function ce({action:t,renderer:r}){const o=ee(),c=re(),i=oe(),s=n.useMemo(()=>{const e=c.get(t);if(e)return e;const n={state:new V,listeners:/* @__PURE__ */new Set};return c.set(t,n),n},[t,c]);n.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:r({value:a,inspect:s.state.inspect.value})}function ie({children:e}){const t=n.useMemo(()=>/* @__PURE__ */new Map,[]);/* @__PURE__ */
4
- return c(ne.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 ae=n.createContext(/* @__PURE__ */new Set);function ue({children:e}){const t=n.useMemo(()=>/* @__PURE__ */new Set,[]);/* @__PURE__ */
6
- return c(ae.Provider,{value:t,children:e})}function le({children:e}){/* @__PURE__ */
7
- return c(te,{children:/* @__PURE__ */c(ie,{children:/* @__PURE__ */c(se,{children:/* @__PURE__ */c(ue,{children:e})})})})}const fe=n.createContext(null);function de(){return n.useContext(fe)}function pe(e,t){return e?.get(t)??null}function he({action:t,scopeName:r,renderer:o}){const c=de(),i=oe(),s=n.useMemo(()=>pe(c,r),[c,r]),a=n.useMemo(()=>s?function(e,t){const n=e.store.get(t);if(n)return n;const r={state:new V,listeners:/* @__PURE__ */new Set};return e.store.set(t,r),r}(s,t):null,[t,s]);if(n.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 r=de(),o=n.useMemo(()=>({name:e,emitter:new Y,store:/* @__PURE__ */new Map,listeners:/* @__PURE__ */new Map}),[]),i=n.useMemo(()=>{const t=new Map(r??[]);return t.set(e,o),t},[r,e,o]);/* @__PURE__ */
8
- return c(fe.Provider,{value:i,children:t})}function ye(e){return(t,n)=>{t.actions.produce(t=>{t.model[e]=n})}}function be(r,c=()=>({})){const i=ee(),s=de(),a=o(C),f=n.useContext(ae),p=oe(),h=n.useRef(!1),m=n.useRef(null),y=n.useRef(new V),{model:b,save:v,invalidate:g}=function(e){const t=n.useContext(A),r=n.useRef(null);if(!r.current){const n=e=>{const n=O(e);t.data.delete(n)};if("object"==typeof(o=e)&&null!==o&&u.Rehydrate in o&&!0===o[u.Rehydrate]){const{channel:o,model:c}=e,i=function(e,t){const n=O(t);return e.data.get(n)||null}(t,o);r.current={model:i??c,save:e=>function(e,t,n){const r=O(t);e.data.set(r,n)}(t,o,e),invalidate:n}}else r.current={model:e,save:()=>{},invalidate:n}}var o;return r.current}(r);h.current||(h.current=!0,m.current=y.current.hydrate(b));const[M,j]=n.useState(()=>y.current.model),_=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()),N=n.useMemo(()=>new Y,[]),U=n.useRef({handlers:/* @__PURE__ */new Map});U.current.handlers=/* @__PURE__ */new Map;const z=function(){const e=n.useRef(/* @__PURE__ */new Set),t=n.useRef(/* @__PURE__ */new Set);return n.useMemo(()=>({broadcast:e.current,multicast:t.current}),[])}(),L=n.useRef(d.Mounting),T=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}),[])}(),B=n.useRef(/* @__PURE__ */new Set),$=n.useRef(0),F=n.useCallback((e,t,n)=>{const r=new AbortController,o={controller:r,action:e,payload:t};return f.add(o),B.current.add(o),{model:M,get phase(){return L.current},task:o,data:_,tasks:f,nodes:T.refs.current,actions:{produce(e){if(r.signal.aborted)return;const t=y.current.produce(t=>e({model:t,inspect:y.current.inspect}));j(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=pe(s,n.scope);return void(e&&e.emitter.emit(o,t,c))}(S(e)?i:N).emit(o,t,c)},annotate:(e,t)=>y.current.annotate(e,t),invalidate(e){g(e)}}}},[M]);n.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=U.current.handlers.has(l.Error),n={reason:k(h),error:R(h),action:x(t),handled:e,tasks:f};a?.(n),e&&N.emit(l.Error,n)}finally{for(const e of f)if(e===d.task){f.delete(e),B.current.delete(e);break}s.processes.forEach(e=>y.current.prune(e)),s.processes.size>0&&p(),u.resolve()}}}$.current++;const n=/* @__PURE__ */new Set;return U.current.handlers.forEach((e,r)=>{for(const{getChannel:o,handler:c}of e){const e=t(r,c,o);if(E(r)){if(s)for(const t of s.values()){const o=t.emitter;o.on(r,e),n.add(()=>o.off(r,e))}N.on(r,e),z.multicast.add(r),n.add(()=>N.off(r,e))}else S(r)?(i.on(r,e),N.on(r,e),z.broadcast.add(r),n.add(()=>{i.off(r,e),N.off(r,e)})):(N.on(r,e),n.add(()=>N.off(r,e)))}}),()=>{const e=++$.current,t=new Set(n);queueMicrotask(()=>{if($.current===e){v(y.current.model);for(const e of B.current)e.controller.abort(),f.delete(e);B.current.clear(),L.current=d.Unmounting,N.emit(l.Unmount),L.current=d.Unmounted;for(const e of t)e()}else for(const e of t)e()})}},[N]),n.useLayoutEffect(()=>{for(const[e,t]of T.pending.current)T.emitted.current.get(e)!==t&&(T.emitted.current.set(e,t),N.emit(u.Node,t,{Name:e}));T.pending.current.clear()}),function({unicast:r,broadcastActions:o,phase:c,data:i}){const s=re(),a=n.useRef(null);n.useLayoutEffect(()=>{c.current===d.Mounting&&(r.emit(l.Mount),o.forEach(t=>{const n=s.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,i);t.isNotEmpty(Object.keys(e))&&r.emit(l.Update,e)}a.current=i},[i,r])}({unicast:N,broadcastActions:z.broadcast,phase:L,data:c()});const W=n.useMemo(()=>[M,{dispatch(e,t,n){const r=w(e),o=P(e)?e.channel:void 0;if(E(e)&&n?.scope){const e=pe(s,n.scope);return void(e&&e.emitter.emit(r,t,o))}(S(e)?i:N).emit(r,t,o)},consume:(e,t,r)=>E(e)&&r?.scope?n.createElement(he,{action:w(e),scopeName:r.scope,renderer:t}):n.createElement(ce,{action:w(e),renderer:t}),get inspect(){return y.current.inspect},get nodes(){return T.refs.current},node(e,t){T.refs.current[e]=t,T.pending.current.set(e,t)}}],[M,N]);return W.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 i=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)},[]),s=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:s,handler:i})}(U,e,t)},W}export{M as Action,le as Boundary,f as Distribution,N as Error,j as Id,l as Lifecycle,z as Op,z as Operation,p as Reason,_ as Rehydrate,me as Scope,V as State,ye as With,J as annotate,be as useActions,v as utils};
1
+ import{G as e,A as t}from"@mobily/ts-belt";import{jsx as n}from"react/jsx-runtime";import*as r from"react";import{createContext as o,useContext as c}from"react";import{immerable as i,enablePatches as s,Immer as a}from"immer";class u{static Payload=/* @__PURE__ */Symbol("chizu.brand/Payload");static Broadcast=/* @__PURE__ */Symbol("chizu.brand/Broadcast");static Multicast=/* @__PURE__ */Symbol("chizu.brand/Multicast");static Action=/* @__PURE__ */Symbol("chizu.brand/Action");static Channel=/* @__PURE__ */Symbol("chizu.brand/Channel");static Node=/* @__PURE__ */Symbol("chizu.action.lifecycle/Node");static Cache=/* @__PURE__ */Symbol("chizu.brand/Cache")}class l{static Mount=/* @__PURE__ */Symbol("chizu.action.lifecycle/Mount");static Unmount=/* @__PURE__ */Symbol("chizu.action.lifecycle/Unmount");static Error=/* @__PURE__ */Symbol("chizu.action.lifecycle/Error");static Update=/* @__PURE__ */Symbol("chizu.action.lifecycle/Update");static Node=(()=>{const e=u.Node,t=function(t){return{[u.Action]:e,[u.Payload]:void 0,[u.Channel]:t,channel:t}};return Object.defineProperty(t,u.Action,{value:e,enumerable:!1}),Object.defineProperty(t,u.Payload,{value:void 0,enumerable:!1}),t})()}var f=/* @__PURE__ */(e=>(e.Unicast="unicast",e.Broadcast="broadcast",e.Multicast="multicast",e))(f||{}),d=/* @__PURE__ */(e=>(e.Mounting="mounting",e.Mounted="mounted",e.Unmounting="unmounting",e.Unmounted="unmounted",e))(d||{}),p=/* @__PURE__ */(e=>(e[e.Timedout=0]="Timedout",e[e.Supplanted=1]="Supplanted",e[e.Disallowed=2]="Disallowed",e[e.Errored=3]="Errored",e[e.Unmounted=4]="Unmounted",e))(p||{});class h extends Error{name="AbortError";constructor(e="Aborted"){super(e)}}const m={actionPrefix:"chizu.action/",broadcastActionPrefix:"chizu.action/broadcast/",multicastActionPrefix:"chizu.action/multicast/",channelPrefix:"chizu.channel/",cachePrefix:"chizu.cache/"};function y(e,t){return new Promise((n,r)=>{if(t?.aborted)return void r(new h);const o=setTimeout(n,e);t?.addEventListener("abort",()=>{clearTimeout(o),r(new h)},{once:!0})})}function b(e){return e?Boolean(e&&"symbol"!=typeof e):/* @__PURE__ */Symbol(`pk.${Date.now()}.${crypto.randomUUID()}`)}const v=/* @__PURE__ */Object.freeze(/* @__PURE__ */Object.defineProperty({__proto__:null,config:m,pk:b,sleep:y,"ζ":y,"κ":b},Symbol.toStringTag,{value:"Module"})),g=e=>"symbol"==typeof e;function w(t){return e.isString(t)||g(t)?t:(e.isObject(t)||e.isFunction(t))&&u.Action in t?t[u.Action]:t}function S(t){if(e.isString(t))return t.startsWith(m.broadcastActionPrefix);if(g(t))return t.description?.startsWith(m.broadcastActionPrefix)??!1;if(e.isObject(t)||e.isFunction(t)){if(u.Broadcast in t&&t[u.Broadcast])return!0;if(u.Action in t){const e=t[u.Action];return e.description?.startsWith(m.broadcastActionPrefix)??!1}}return!1}function x(t){const n=w(t),r=e.isString(n)?n:n.description??"";return r.startsWith(m.actionPrefix)&&r.slice(r.lastIndexOf("/")+1)||"unknown"}function P(t){return e.isObject(t)&&u.Channel in t&&"channel"in t}function E(t){if(e.isString(t))return t.startsWith(m.multicastActionPrefix);if(g(t))return t.description?.startsWith(m.multicastActionPrefix)??!1;if(e.isObject(t)||e.isFunction(t)){if(u.Multicast in t&&t[u.Multicast])return!0;if(u.Action in t){const e=t[u.Action];return e.description?.startsWith(m.multicastActionPrefix)??!1}}return!1}const M=(e,t=f.Unicast)=>{const n=t===f.Broadcast?/* @__PURE__ */Symbol(`${m.broadcastActionPrefix}${e}`):t===f.Multicast?/* @__PURE__ */Symbol(`${m.multicastActionPrefix}${e}`):/* @__PURE__ */Symbol(`${m.actionPrefix}${e}`),r=function(e){return{[u.Action]:n,[u.Payload]:void 0,[u.Channel]:e,channel:e}};return Object.defineProperty(r,u.Action,{value:n,enumerable:!1}),Object.defineProperty(r,u.Payload,{value:void 0,enumerable:!1}),t===f.Broadcast&&Object.defineProperty(r,u.Broadcast,{value:!0,enumerable:!1}),t===f.Multicast&&Object.defineProperty(r,u.Multicast,{value:!0,enumerable:!1}),r};function O(){const e=/* @__PURE__ */Symbol("chizu.cache/Entry"),t=function(t){return{[u.Cache]:e,channel:t}};return Object.defineProperty(t,u.Cache,{value:e,enumerable:!1}),t}function A(e){const t=function(e){return e[u.Cache]}(e),n=function(e){return"channel"in e}(e)&&(r=e.channel)?[...Object.keys(r)].toSorted().map(e=>`${e}=${String(r[e])}`).join("&"):"";var r;return`${String(t)}:${n}`}function j(e){if(e instanceof Error){if("TimeoutError"===e.name)return p.Timedout;if("AbortError"===e.name)return p.Supplanted}return p.Errored}function k(e){return e instanceof Error?e:new Error(String(e))}const C=o(void 0);function _({handler:e,children:t}){/* @__PURE__ */
2
+ return n(C.Provider,{value:e,children:t})}let N=(e=21)=>{let t="",n=crypto.getRandomValues(new Uint8Array(e|=0));for(;e--;)t+="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"[63&n[e]];return t};var R=/* @__PURE__ */(e=>(e[e.Add=1]="Add",e[e.Remove=2]="Remove",e[e.Update=4]="Update",e[e.Move=8]="Move",e[e.Replace=16]="Replace",e[e.Sort=32]="Sort",e[e.Create=64]="Create",e[e.Fetch=128]="Fetch",e[e.Clone=256]="Clone",e[e.Archive=512]="Archive",e[e.Restore=1024]="Restore",e[e.Merge=2048]="Merge",e[e.Reorder=4096]="Reorder",e[e.Sync=8192]="Sync",e[e.Publish=16384]="Publish",e[e.Link=32768]="Link",e[e.Unlink=65536]="Unlink",e[e.Lock=131072]="Lock",e[e.Unlock=262144]="Unlock",e[e.Import=524288]="Import",e[e.Export=1048576]="Export",e[e.Transfer=2097152]="Transfer",e))(R||{}),U=/* @__PURE__ */(e=>(e[e.Produce=0]="Produce",e[e.Hydrate=1]="Hydrate",e))(U||{}),z=/* @__PURE__ */(e=>(e.Property="property",e.Process="process",e.Value="value",e.Operation="operation",e))(z||{});class L{[i]=!0;static keys=new Set(Object.values(z));property=null;process=null;value;operation;constructor(e,t){this.value=e,this.operation=t}assign(e,t){const n=new L(this.value,this.operation);return n.property=e,n.process=t,n}}class T{static immer=(()=>{s();const e=new a;return e.setAutoFreeze(!1),e})();static tag="κ";static id=N}function $(e,t){const n="string"==typeof t?""===t?[]:t.split("."):t;let r=e;for(const o of n){if(null==r)return;r=r[o]}return r}function B(t){if(e.isNullable(t)||D(t))return t;if(e.isArray(t))return t.map(e=>B(e));if(e.isObject(t)&&W(t)){const e=Object.entries(t).map(([e,t])=>[e,B(t)]);return{...Object.fromEntries(e),[T.tag]:t[T.tag]??T.id()}}return t}function F(e){if(Array.isArray(e))return e.filter(e=>T.tag in e).map(e=>e[T.tag]??"").join(",");const t=e[T.tag];if(t)return t;try{return JSON.stringify(e)}catch{return`[unserializable:${typeof e}]`}}function W(e){const t=Object.getPrototypeOf(e);return t===Object.prototype||null===t}function D(t){return e.isNullable(t)||e.isString(t)||e.isNumber(t)||e.isBoolean(t)||"symbol"==typeof t||"bigint"==typeof t}function H(t,n,r,o,c,i){return function s(a,u=n.path){if(a instanceof L){const n=$(r,u.join("."));if(Object.entries(a).filter(([e,t])=>!L.keys.has(e)&&t instanceof L).forEach(([e,t])=>s(t,u.concat(e))),D(a.value)){if(t===U.Hydrate)return a.value;const s=u.slice(0,-1),l=s.length>0?$(r,s.join(".")):r;return e.isNullable(l)||G(l,a,u.at(-1),o,c,i),n??a.value}if(t===U.Hydrate){const e=B(s(a.value,u));return G(e,a,null,o,c,i),e}const l=n??B(a.value);return G(l,a,null,o,c,i),e.isNullable(n)?l:(s(a.value,u),n)}if(e.isArray(a))return a.map((e,t)=>s(e,u.concat(t)));if(e.isObject(a)&&!W(a))return a;if(e.isObject(a)){const e=Object.entries(a).map(([e,t])=>[e,s(t,u.concat(e))]),n=Object.fromEntries(e);if(t===U.Hydrate){const e=B(n);return Object.entries(a).forEach(([t,n])=>{n instanceof L&&D(n.value)&&G(e,n,t,o,c,i)}),e}return n}return a}(n.value)}function G(e,t,n,r,o,c){const i=c(e),s=o.get(i)??[];o.set(i,[t.assign(n,r),...s])}class I{#e={};#t;#n=/* @__PURE__ */new Map;#r=/* @__PURE__ */new Set;#o=!1;constructor(e=F){this.#t=e}static pk(){return N()}static"κ"=I.pk;annotate(e,t){return new L(t,e)}"δ"=this.annotate;get model(){return this.#e}get inspect(){return function(n,r,o,c,i){function s(c){const i=c.at(-1),s=$(n(),c),a=c.slice(0,-1),u=t.isNotEmpty(a)?$(n(),a):n();return[...e.isObject(s)||e.isArray(s)?r.get(o(s))?.filter(t=>e.isNullable(t.property))??[]:[],...e.isObject(u)?r.get(o(u))?.filter(e=>e.property===i)??[]:[]]}return function e(r){return new Proxy(()=>{},{get:(o,a)=>"pending"===a?()=>!t.isEmpty(s(r)):"remaining"===a?()=>t.length(s(r)):"box"===a?()=>({value:$(n(),r),inspect:e(r)}):"is"===a?e=>s(r).some(t=>0!==(t.operation&e)):"draft"===a?()=>t.head(s(r))?.value??$(n(),r):"settled"===a?()=>new Promise(e=>{if(t.isEmpty(s(r)))return e($(n(),r));const o=()=>{t.isEmpty(s(r))&&(i(o),e($(n(),r)))};c(o)}):e([...r,String(a)])})}([])}(()=>this.#e,this.#n,this.#t,e=>this.#r.add(e),e=>this.#r.delete(e))}hydrate(e){return this.#o=!0,this.#c(U.Hydrate,()=>e)}produce(e){if(!this.#o)throw new Error("State must be hydrated using hydrate() before calling produce()");return this.#c(U.Produce,e)}#c(e,t){const n=/* @__PURE__ */Symbol("process"),[,r]=T.immer.produceWithPatches(this.#e,t);return this.#e=r.reduce((t,r)=>T.immer.applyPatches(t,[{...r,value:H(e,r,t,n,this.#n,this.#t)}]),this.#e),this.#e=B(this.#e),this.#i(),n}prune(e){this.#n.forEach((n,r)=>{const o=n.filter(t=>t.process!==e);t.isEmpty(o)?this.#n.delete(r):this.#n.set(r,o)}),this.#i()}#i(){this.#r.forEach(e=>e())}observe(e){const t=()=>e(this.#e);return this.#r.add(t),()=>this.#r.delete(t)}}const V=new I;function q(e,t){return V.annotate(e,t)}function J(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var K,Q={exports:{}};const X=/* @__PURE__ */J((K||(K=1,function(e){var t=Object.prototype.hasOwnProperty,n="~";function r(){}function o(e,t,n){this.fn=e,this.context=t,this.once=n||!1}function c(e,t,r,c,i){if("function"!=typeof r)throw new TypeError("The listener must be a function");var s=new o(r,c||e,i),a=n?n+t:t;return e._events[a]?e._events[a].fn?e._events[a]=[e._events[a],s]:e._events[a].push(s):(e._events[a]=s,e._eventsCount++),e}function i(e,t){0===--e._eventsCount?e._events=new r:delete e._events[t]}function s(){this._events=new r,this._eventsCount=0}Object.create&&(r.prototype=/* @__PURE__ */Object.create(null),(new r).__proto__||(n=!1)),s.prototype.eventNames=function(){var e,r,o=[];if(0===this._eventsCount)return o;for(r in e=this._events)t.call(e,r)&&o.push(n?r.slice(1):r);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(e)):o},s.prototype.listeners=function(e){var t=this._events[n?n+e:e];if(!t)return[];if(t.fn)return[t.fn];for(var r=0,o=t.length,c=new Array(o);r<o;r++)c[r]=t[r].fn;return c},s.prototype.listenerCount=function(e){var t=this._events[n?n+e:e];return t?t.fn?1:t.length:0},s.prototype.emit=function(e,t,r,o,c,i){var s=n?n+e:e;if(!this._events[s])return!1;var a,u,l=this._events[s],f=arguments.length;if(l.fn){switch(l.once&&this.removeListener(e,l.fn,void 0,!0),f){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,t),!0;case 3:return l.fn.call(l.context,t,r),!0;case 4:return l.fn.call(l.context,t,r,o),!0;case 5:return l.fn.call(l.context,t,r,o,c),!0;case 6:return l.fn.call(l.context,t,r,o,c,i),!0}for(u=1,a=new Array(f-1);u<f;u++)a[u-1]=arguments[u];l.fn.apply(l.context,a)}else{var d,p=l.length;for(u=0;u<p;u++)switch(l[u].once&&this.removeListener(e,l[u].fn,void 0,!0),f){case 1:l[u].fn.call(l[u].context);break;case 2:l[u].fn.call(l[u].context,t);break;case 3:l[u].fn.call(l[u].context,t,r);break;case 4:l[u].fn.call(l[u].context,t,r,o);break;default:if(!a)for(d=1,a=new Array(f-1);d<f;d++)a[d-1]=arguments[d];l[u].fn.apply(l[u].context,a)}}return!0},s.prototype.on=function(e,t,n){return c(this,e,t,n,!1)},s.prototype.once=function(e,t,n){return c(this,e,t,n,!0)},s.prototype.removeListener=function(e,t,r,o){var c=n?n+e:e;if(!this._events[c])return this;if(!t)return i(this,c),this;var s=this._events[c];if(s.fn)s.fn!==t||o&&!s.once||r&&s.context!==r||i(this,c);else{for(var a=0,u=[],l=s.length;a<l;a++)(s[a].fn!==t||o&&!s[a].once||r&&s[a].context!==r)&&u.push(s[a]);u.length?this._events[c]=1===u.length?u[0]:u:i(this,c)}return this},s.prototype.removeAllListeners=function(e){var t;return e?this._events[t=n?n+e:e]&&i(this,t):(this._events=new r,this._eventsCount=0),this},s.prototype.off=s.prototype.removeListener,s.prototype.addListener=s.prototype.on,s.prefixed=n,s.EventEmitter=s,e.exports=s}(Q)),Q.exports)),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 I,listeners:/* @__PURE__ */new Set};return c.set(t,n),n},[t,c]);r.useLayoutEffect(()=>{function e(e){s.state.hydrate({value:e}),s.listeners.forEach(e=>e())}return s.listeners.add(i),o.on(t,e),()=>{s.listeners.delete(i),o.off(t,e)}},[t,o,s]);const a=s.state.model?.value;return e.isNullable(a)?null:n({value:a,inspect:s.state.inspect.value})}function 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 pe(e,t){return e?.get(t)??null}function he({action:t,scopeName:n,renderer:o}){const c=de(),i=re(),s=r.useMemo(()=>pe(c,n),[c,n]),a=r.useMemo(()=>s?function(e,t){const n=e.store.get(t);if(n)return n;const r={state:new I,listeners:/* @__PURE__ */new Set};return e.store.set(t,r),r}(s,t):null,[t,s]);if(r.useLayoutEffect(()=>{if(s&&a)return a.listeners.add(i),s.emitter.on(t,e),()=>{a.listeners.delete(i),s.emitter.off(t,e)};function e(e){a&&(a.state.hydrate({value:e}),a.listeners.forEach(e=>e()))}},[t,s,a,i]),!a)return null;const u=a.state.model?.value;return e.isNullable(u)?null:o({value:u,inspect:a.state.inspect.value})}function 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(C),f=r.useContext(ae),p=r.useContext(ie),h=re(),m=r.useRef(!1),y=r.useRef(null),b=r.useRef(new I);m.current||(m.current=!0,y.current=b.current.hydrate(n));const[v,g]=r.useState(()=>b.current.model),M=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()),O=r.useMemo(()=>new X,[]),_=r.useRef({handlers:/* @__PURE__ */new Map});_.current.handlers=/* @__PURE__ */new Map;const N=function(){const e=r.useRef(/* @__PURE__ */new Set),t=r.useRef(/* @__PURE__ */new Set);return r.useMemo(()=>({broadcast:e.current,multicast:t.current}),[])}(),R=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}),[])}(),z=r.useRef(/* @__PURE__ */new Set),L=r.useRef(0),T=r.useCallback((e,t,n)=>{const r=new AbortController,o={controller:r,action:e,payload:t};return f.add(o),z.current.add(o),{model:v,get phase(){return R.current},task:o,data:M,tasks:f,nodes:U.refs.current,actions:{produce(e){if(r.signal.aborted)return;const t=b.current.produce(t=>e({model:t,inspect:b.current.inspect}));g(b.current.model),n.processes.add(t),y.current&&(n.processes.add(y.current),y.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=pe(s,n.scope);return void(e&&e.emitter.emit(o,t,c))}(S(e)?i:O).emit(o,t,c)},annotate:(e,t)=>b.current.annotate(e,t),async cacheable(e,t,n){if(r.signal.aborted)return{data:null};const o=A(e),c=p.get(o);if(c&&Date.now()<c.expiry)return{data:c.value};const i=function(e){return null!=e&&"object"==typeof e&&"TAG"in e?0===e.TAG?{ok:!0,value:e._0}:{ok:!1}:null==e?{ok:!1}:{ok:!0,value:e}}(await n());return i.ok?(p.set(o,{value:i.value,expiry:Date.now()+t}),{data:i.value}):{data:null}},invalidate(e){p.delete(A(e))}}}},[v]);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=T(t,o,s);try{await n(d,o)}catch(p){const e=_.current.handlers.has(l.Error),n={reason:j(p),error:k(p),action:x(t),handled:e,tasks:f};a?.(n),e&&O.emit(l.Error,n)}finally{for(const e of f)if(e===d.task){f.delete(e),z.current.delete(e);break}s.processes.forEach(e=>b.current.prune(e)),s.processes.size>0&&h(),u.resolve()}}}L.current++;const n=/* @__PURE__ */new Set;return _.current.handlers.forEach((e,r)=>{for(const{getChannel:o,handler:c}of e){const e=t(r,c,o);if(E(r)){if(s)for(const t of s.values()){const o=t.emitter;o.on(r,e),n.add(()=>o.off(r,e))}O.on(r,e),N.multicast.add(r),n.add(()=>O.off(r,e))}else S(r)?(i.on(r,e),O.on(r,e),N.broadcast.add(r),n.add(()=>{i.off(r,e),O.off(r,e)})):(O.on(r,e),n.add(()=>O.off(r,e)))}}),()=>{const e=++L.current,t=new Set(n);queueMicrotask(()=>{if(L.current===e){for(const e of z.current)e.controller.abort(),f.delete(e);z.current.clear(),R.current=d.Unmounting,O.emit(l.Unmount),R.current=d.Unmounted;for(const e of t)e()}else for(const e of t)e()})}},[O]),r.useLayoutEffect(()=>{for(const[e,t]of U.pending.current)U.emitted.current.get(e)!==t&&(U.emitted.current.set(e,t),O.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);r.useLayoutEffect(()=>{c.current===d.Mounting&&(n.emit(l.Mount),o.forEach(t=>{const r=s.get(t),o=r?.state.model?.value;e.isNullable(o)||n.emit(t,o)}),c.current=d.Mounted)},[]),r.useLayoutEffect(()=>{if(e.isNotNullable(a.current)){const e=function(e,t){return Object.keys(t).reduce((n,r)=>e[r]!==t[r]?{...n,[r]:t[r]}:n,{})}(a.current,i);t.isNotEmpty(Object.keys(e))&&n.emit(l.Update,e)}a.current=i},[i,n])}({unicast:O,broadcastActions:N.broadcast,phase:R,data:o()});const $=r.useMemo(()=>[v,{dispatch(e,t,n){const r=w(e),o=P(e)?e.channel:void 0;if(E(e)&&n?.scope){const e=pe(s,n.scope);return void(e&&e.emitter.emit(r,t,o))}(S(e)?i:O).emit(r,t,o)},consume:(e,t,n)=>E(e)&&n?.scope?r.createElement(he,{action:w(e),scopeName:n.scope,renderer:t}):r.createElement(oe,{action:w(e),renderer:t}),get inspect(){return b.current.inspect},get nodes(){return U.refs.current},node(e,t){U.refs.current[e]=t,U.pending.current.set(e,t)}}],[v,O]);return $.useAction=(e,t)=>{!function(e,t,n){const o=r.useRef(n);r.useLayoutEffect(()=>{o.current=n});const c=r.useRef(t);r.useLayoutEffect(()=>{c.current=t});const i=r.useCallback(async(e,t)=>{const n=o.current;if("GeneratorFunction"===n.constructor.name||"AsyncGeneratorFunction"===n.constructor.name){const r=n(e,t);for await(const e of r);}else await n(e,t)},[]),s=r.useCallback(()=>P(c.current)?c.current.channel:void 0,[]),a=w(t),u=e.current.handlers.get(a)??/* @__PURE__ */new Set;0===u.size&&e.current.handlers.set(a,u),u.add({getChannel:s,handler:i})}(_,e,t)},$}export{M as Action,le as Boundary,f as Distribution,O as Entry,_ as Error,l as Lifecycle,R as Op,R as Operation,p as Reason,me as Scope,I as State,ye as With,q as annotate,be 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(n);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 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=s.Node,t=function(t){return{[s.Action]:e,[s.Payload]:void 0,[s.Channel]:t,channel:t}};return Object.defineProperty(t,s.Action,{value:e,enumerable:!1}),Object.defineProperty(t,s.Payload,{value:void 0,enumerable:!1}),t})()}var u=(e=>(e.Unicast="unicast",e.Broadcast="broadcast",e.Multicast="multicast",e))(u||{}),l=(e=>(e.Mounting="mounting",e.Mounted="mounted",e.Unmounting="unmounting",e.Unmounted="unmounted",e))(l||{}),f=(e=>(e[e.Timedout=0]="Timedout",e[e.Supplanted=1]="Supplanted",e[e.Disallowed=2]="Disallowed",e[e.Errored=3]="Errored",e[e.Unmounted=4]="Unmounted",e))(f||{});class d extends Error{name="AbortError";constructor(e="Aborted"){super(e)}}const p={actionPrefix:"chizu.action/",broadcastActionPrefix:"chizu.action/broadcast/",multicastActionPrefix:"chizu.action/multicast/",channelPrefix:"chizu.channel/",cachePrefix:"chizu.cache/"};function h(e,t){return new Promise((n,r)=>{if(t?.aborted)return void r(new d);const o=setTimeout(n,e);t?.addEventListener("abort",()=>{clearTimeout(o),r(new d)},{once:!0})})}function m(e){return e?Boolean(e&&"symbol"!=typeof e):Symbol(`pk.${Date.now()}.${crypto.randomUUID()}`)}const y=Object.freeze(Object.defineProperty({__proto__:null,config:p,pk:m,sleep:h,"ζ":h,"κ":m},Symbol.toStringTag,{value:"Module"})),b=e=>"symbol"==typeof e;function v(e){return t.G.isString(e)||b(e)?e:(t.G.isObject(e)||t.G.isFunction(e))&&s.Action in e?e[s.Action]:e}function g(e){if(t.G.isString(e))return e.startsWith(p.broadcastActionPrefix);if(b(e))return e.description?.startsWith(p.broadcastActionPrefix)??!1;if(t.G.isObject(e)||t.G.isFunction(e)){if(s.Broadcast in e&&e[s.Broadcast])return!0;if(s.Action in e){const t=e[s.Action];return t.description?.startsWith(p.broadcastActionPrefix)??!1}}return!1}function w(e){const n=v(e),r=t.G.isString(n)?n:n.description??"";return r.startsWith(p.actionPrefix)&&r.slice(r.lastIndexOf("/")+1)||"unknown"}function x(e){return t.G.isObject(e)&&s.Channel in e&&"channel"in e}function j(e){if(t.G.isString(e))return e.startsWith(p.multicastActionPrefix);if(b(e))return e.description?.startsWith(p.multicastActionPrefix)??!1;if(t.G.isObject(e)||t.G.isFunction(e)){if(s.Multicast in e&&e[s.Multicast])return!0;if(s.Action in e){const t=e[s.Action];return t.description?.startsWith(p.multicastActionPrefix)??!1}}return!1}const S=i.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||{}),_=(e=>(e[e.Produce=0]="Produce",e[e.Hydrate=1]="Hydrate",e))(_||{}),C=(e=>(e.Property="property",e.Process="process",e.Value="value",e.Operation="operation",e))(C||{});class G{[o.immerable]=!0;static keys=new Set(Object.values(C));property=null;process=null;value;operation;constructor(e,t){this.value=e,this.operation=t}assign(e,t){const n=new G(this.value,this.operation);return n.property=e,n.process=t,n}}class 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,i){return function s(a,u=n.path){if(a instanceof G){const n=N(r,u.join("."));if(Object.entries(a).filter(([e,t])=>!G.keys.has(e)&&t instanceof G).forEach(([e,t])=>s(t,u.concat(e))),L(a.value)){if(e===_.Hydrate)return a.value;const s=u.slice(0,-1),l=s.length>0?N(r,s.join(".")):r;return t.G.isNullable(l)||B(l,a,u.at(-1),o,c,i),n??a.value}if(e===_.Hydrate){const e=z(s(a.value,u));return B(e,a,null,o,c,i),e}const l=n??z(a.value);return B(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===_.Hydrate){const e=z(n);return Object.entries(a).forEach(([t,n])=>{n instanceof G&&L(n.value)&&B(e,n,t,o,c,i)}),e}return n}return a}(n.value)}function B(e,t,n,r,o,c){const i=c(e),s=o.get(i)??[];o.set(i,[t.assign(n,r),...s])}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 G(t,e)}"δ"=this.annotate;get model(){return this.#e}get inspect(){return function(e,n,r,o,c){function i(o){const c=o.at(-1),i=N(e(),o),s=o.slice(0,-1),a=t.A.isNotEmpty(s)?N(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:N(e(),r),inspect:n(r)}):"is"===a?e=>i(r).some(t=>0!==(t.operation&e)):"draft"===a?()=>t.A.head(i(r))?.value??N(e(),r):"settled"===a?()=>new Promise(n=>{if(t.A.isEmpty(i(r)))return n(N(e(),r));const s=()=>{t.A.isEmpty(i(r))&&(c(s),n(N(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(_.Hydrate,()=>e)}produce(e){if(!this.#o)throw new Error("State must be hydrated using hydrate() before calling produce()");return this.#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.#i(),n}prune(e){this.#n.forEach((n,r)=>{const o=n.filter(t=>t.process!==e);t.A.isEmpty(o)?this.#n.delete(r):this.#n.set(r,o)}),this.#i()}#i(){this.#r.forEach(e=>e())}observe(e){const t=()=>e(this.#e);return this.#r.add(t),()=>this.#r.delete(t)}}const W=new $;function F(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var I,D={exports:{}},H=(I||(I=1,function(e){var t=Object.prototype.hasOwnProperty,n="~";function r(){}function o(e,t,n){this.fn=e,this.context=t,this.once=n||!1}function c(e,t,r,c,i){if("function"!=typeof r)throw new TypeError("The listener must be a function");var s=new o(r,c||e,i),a=n?n+t:t;return e._events[a]?e._events[a].fn?e._events[a]=[e._events[a],s]:e._events[a].push(s):(e._events[a]=s,e._eventsCount++),e}function i(e,t){0===--e._eventsCount?e._events=new r:delete e._events[t]}function s(){this._events=new r,this._eventsCount=0}Object.create&&(r.prototype=Object.create(null),(new r).__proto__||(n=!1)),s.prototype.eventNames=function(){var e,r,o=[];if(0===this._eventsCount)return o;for(r in e=this._events)t.call(e,r)&&o.push(n?r.slice(1):r);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(e)):o},s.prototype.listeners=function(e){var t=this._events[n?n+e:e];if(!t)return[];if(t.fn)return[t.fn];for(var r=0,o=t.length,c=new Array(o);r<o;r++)c[r]=t[r].fn;return c},s.prototype.listenerCount=function(e){var t=this._events[n?n+e:e];return t?t.fn?1:t.length:0},s.prototype.emit=function(e,t,r,o,c,i){var s=n?n+e:e;if(!this._events[s])return!1;var a,u,l=this._events[s],f=arguments.length;if(l.fn){switch(l.once&&this.removeListener(e,l.fn,void 0,!0),f){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,t),!0;case 3:return l.fn.call(l.context,t,r),!0;case 4:return l.fn.call(l.context,t,r,o),!0;case 5:return l.fn.call(l.context,t,r,o,c),!0;case 6:return l.fn.call(l.context,t,r,o,c,i),!0}for(u=1,a=new Array(f-1);u<f;u++)a[u-1]=arguments[u];l.fn.apply(l.context,a)}else{var d,p=l.length;for(u=0;u<p;u++)switch(l[u].once&&this.removeListener(e,l[u].fn,void 0,!0),f){case 1:l[u].fn.call(l[u].context);break;case 2:l[u].fn.call(l[u].context,t);break;case 3:l[u].fn.call(l[u].context,t,r);break;case 4:l[u].fn.call(l[u].context,t,r,o);break;default:if(!a)for(d=1,a=new Array(f-1);d<f;d++)a[d-1]=arguments[d];l[u].fn.apply(l[u].context,a)}}return!0},s.prototype.on=function(e,t,n){return c(this,e,t,n,!1)},s.prototype.once=function(e,t,n){return c(this,e,t,n,!0)},s.prototype.removeListener=function(e,t,r,o){var c=n?n+e:e;if(!this._events[c])return this;if(!t)return i(this,c),this;var s=this._events[c];if(s.fn)s.fn!==t||o&&!s.once||r&&s.context!==r||i(this,c);else{for(var a=0,u=[],l=s.length;a<l;a++)(s[a].fn!==t||o&&!s[a].once||r&&s[a].context!==r)&&u.push(s[a]);u.length?this._events[c]=1===u.length?u[0]:u:i(this,c)}return this},s.prototype.removeAllListeners=function(e){var t;return e?this._events[t=n?n+e:e]&&i(this,t):(this._events=new r,this._eventsCount=0),this},s.prototype.off=s.prototype.removeListener,s.prototype.addListener=s.prototype.on,s.prefixed=n,s.EventEmitter=s,e.exports=s}(D)),D.exports);const q=F(H),V=i.createContext(new q);function J(){return i.useContext(V)}function K({children:e}){const t=i.useMemo(()=>new q,[]);return r.jsx(V.Provider,{value:t,children:e})}const Q=i.createContext(new Map);function X(){return i.useContext(Q)}function Y(){const[,e]=i.useReducer(e=>e+1,0);return e}function Z({action:e,renderer:n}){const r=J(),o=X(),c=Y(),s=i.useMemo(()=>{const t=o.get(e);if(t)return t;const n={state:new $,listeners:new Set};return o.set(e,n),n},[e,o]);i.useLayoutEffect(()=>{function t(e){s.state.hydrate({value:e}),s.listeners.forEach(e=>e())}return s.listeners.add(c),r.on(e,t),()=>{s.listeners.delete(c),r.off(e,t)}},[e,r,s]);const a=s.state.model?.value;return t.G.isNullable(a)?null:n({value:a,inspect:s.state.inspect.value})}function ee({children:e}){const t=i.useMemo(()=>new Map,[]);return r.jsx(Q.Provider,{value:t,children:e})}function te({children:e}){const t=i.useMemo(()=>({data:new Map}),[]);return r.jsx(S.Provider,{value:t,children:e})}const ne=i.createContext(new Set);function re({children:e}){const t=i.useMemo(()=>new Set,[]);return r.jsx(ne.Provider,{value:t,children:e})}const oe=i.createContext(null);function ce(){return i.useContext(oe)}function ie(e,t){return e?.get(t)??null}function se({action:e,scopeName:n,renderer:r}){const o=ce(),c=Y(),s=i.useMemo(()=>ie(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 $,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(`${p.broadcastActionPrefix}${e}`):t===u.Multicast?Symbol(`${p.multicastActionPrefix}${e}`):Symbol(`${p.actionPrefix}${e}`),r=function(e){return{[s.Action]:n,[s.Payload]:void 0,[s.Channel]:e,channel:e}};return Object.defineProperty(r,s.Action,{value:n,enumerable:!1}),Object.defineProperty(r,s.Payload,{value:void 0,enumerable:!1}),t===u.Broadcast&&Object.defineProperty(r,s.Broadcast,{value:!0,enumerable:!1}),t===u.Multicast&&Object.defineProperty(r,s.Multicast,{value:!0,enumerable:!1}),r},e.Boundary=function({children:e}){return 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.Id=function(){const e=Symbol();return t=>t??{_:e}},e.Lifecycle=a,e.Op=R,e.Operation=R,e.Reason=f,e.Rehydrate=function(e,t){return{[s.Rehydrate]:!0,model:e,channel:t}},e.Scope=function({name:e,children:t}){const n=ce(),o=i.useMemo(()=>({name:e,emitter:new q,store:new Map,listeners:new Map}),[]),c=i.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=i.useContext(ne),d=Y(),p=i.useRef(!1),h=i.useRef(null),m=i.useRef(new $),{model:y,save:b,invalidate:O}=function(e){const t=i.useContext(S),n=i.useRef(null);if(!n.current){const o=e=>{const n=P(e);t.data.delete(n)};if("object"==typeof(r=e)&&null!==r&&s.Rehydrate in r&&!0===r[s.Rehydrate]){const{channel:r,model:c}=e,i=function(e,t){const n=P(t);return e.data.get(n)||null}(t,r);n.current={model:i??c,save:e=>function(e,t,n){const r=P(t);e.data.set(r,n)}(t,r,e),invalidate:o}}else n.current={model:e,save:()=>{},invalidate:o}}var r;return n.current}(e);p.current||(p.current=!0,h.current=m.current.hydrate(y));const[R,_]=i.useState(()=>m.current.model),C=function(e){const t=i.useRef(e);return i.useLayoutEffect(()=>{t.current=e},[e]),i.useMemo(()=>{return n=t,Object.keys(e).reduce((e,t)=>(Object.defineProperty(e,t,{get:()=>n.current[t],enumerable:!0}),e),{});var n},[e])}(r()),G=i.useMemo(()=>new q,[]),k=i.useRef({handlers:new Map});k.current.handlers=new Map;const N=function(){const e=i.useRef(new Set),t=i.useRef(new Set);return i.useMemo(()=>({broadcast:e.current,multicast:t.current}),[])}(),z=i.useRef(l.Mounting),U=function(){const e=i.useRef({}),t=i.useRef(new Map),n=i.useRef(new Map);return i.useMemo(()=>({refs:e,pending:t,emitted:n}),[])}(),L=i.useRef(new Set),T=i.useRef(0),B=i.useCallback((e,t,n)=>{const r=new AbortController,i={controller:r,action:e,payload:t};return f.add(i),L.current.add(i),{model:R,get phase(){return z.current},task:i,data:C,tasks:f,nodes:U.refs.current,actions:{produce(e){if(r.signal.aborted)return;const t=m.current.produce(t=>e({model:t,inspect:m.current.inspect}));_(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 i=v(e),s=x(e)?e.channel:void 0;if(j(e)&&n?.scope){const e=ie(c,n.scope);return void(e&&e.emitter.emit(i,t,s))}(g(e)?o:G).emit(i,t,s)},annotate:(e,t)=>m.current.annotate(e,t),invalidate(e){O(e)}}}},[R]);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(),p=B(e,o,s);try{await n(p,o)}catch(h){const t=k.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),L.current.delete(e);break}s.processes.forEach(e=>m.current.prune(e)),s.processes.size>0&&d(),l.resolve()}}}T.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))}G.on(r,t),N.multicast.add(r),n.add(()=>G.off(r,t))}else g(r)?(o.on(r,t),G.on(r,t),N.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=++T.current,t=new Set(n);queueMicrotask(()=>{if(T.current===e){b(m.current.model);for(const e of L.current)e.controller.abort(),f.delete(e);L.current.clear(),z.current=l.Unmounting,G.emit(a.Unmount),z.current=l.Unmounted;for(const e of t)e()}else for(const e of t)e()})}},[G]),i.useLayoutEffect(()=>{for(const[e,t]of U.pending.current)U.emitted.current.get(e)!==t&&(U.emitted.current.set(e,t),G.emit(s.Node,t,{Name:e}));U.pending.current.clear()}),function({unicast:e,broadcastActions:n,phase:r,data:o}){const c=X(),s=i.useRef(null);i.useLayoutEffect(()=>{r.current===l.Mounting&&(e.emit(a.Mount),n.forEach(n=>{const r=c.get(n),o=r?.state.model?.value;t.G.isNullable(o)||e.emit(n,o)}),r.current=l.Mounted)},[]),i.useLayoutEffect(()=>{if(t.G.isNotNullable(s.current)){const n=function(e,t){return Object.keys(t).reduce((n,r)=>e[r]!==t[r]?{...n,[r]:t[r]}:n,{})}(s.current,o);t.A.isNotEmpty(Object.keys(n))&&e.emit(a.Update,n)}s.current=o},[o,e])}({unicast:G,broadcastActions:N.broadcast,phase:z,data:r()});const W=i.useMemo(()=>[R,{dispatch(e,t,n){const r=v(e),i=x(e)?e.channel:void 0;if(j(e)&&n?.scope){const e=ie(c,n.scope);return void(e&&e.emitter.emit(r,t,i))}(g(e)?o:G).emit(r,t,i)},consume:(e,t,n)=>j(e)&&n?.scope?i.createElement(se,{action:v(e),scopeName:n.scope,renderer:t}):i.createElement(Z,{action:v(e),renderer:t}),get inspect(){return m.current.inspect},get nodes(){return U.refs.current},node(e,t){U.refs.current[e]=t,U.pending.current.set(e,t)}}],[R,G]);return W.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)},W},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
+ var global,factory;global=this,factory=function(e,t,n,r,o){"use strict";function c(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const n in e)if("default"!==n){const r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:()=>e[n]})}return t.default=e,Object.freeze(t)}const i=c(r);class s{static Payload=Symbol("chizu.brand/Payload");static Broadcast=Symbol("chizu.brand/Broadcast");static Multicast=Symbol("chizu.brand/Multicast");static Action=Symbol("chizu.brand/Action");static Channel=Symbol("chizu.brand/Channel");static Node=Symbol("chizu.action.lifecycle/Node");static Cache=Symbol("chizu.brand/Cache")}class a{static Mount=Symbol("chizu.action.lifecycle/Mount");static Unmount=Symbol("chizu.action.lifecycle/Unmount");static Error=Symbol("chizu.action.lifecycle/Error");static Update=Symbol("chizu.action.lifecycle/Update");static Node=(()=>{const e=s.Node,t=function(t){return{[s.Action]:e,[s.Payload]:void 0,[s.Channel]:t,channel:t}};return Object.defineProperty(t,s.Action,{value:e,enumerable:!1}),Object.defineProperty(t,s.Payload,{value:void 0,enumerable:!1}),t})()}var u=(e=>(e.Unicast="unicast",e.Broadcast="broadcast",e.Multicast="multicast",e))(u||{}),l=(e=>(e.Mounting="mounting",e.Mounted="mounted",e.Unmounting="unmounting",e.Unmounted="unmounted",e))(l||{}),f=(e=>(e[e.Timedout=0]="Timedout",e[e.Supplanted=1]="Supplanted",e[e.Disallowed=2]="Disallowed",e[e.Errored=3]="Errored",e[e.Unmounted=4]="Unmounted",e))(f||{});class d extends Error{name="AbortError";constructor(e="Aborted"){super(e)}}const p={actionPrefix:"chizu.action/",broadcastActionPrefix:"chizu.action/broadcast/",multicastActionPrefix:"chizu.action/multicast/",channelPrefix:"chizu.channel/",cachePrefix:"chizu.cache/"};function h(e,t){return new Promise((n,r)=>{if(t?.aborted)return void r(new d);const o=setTimeout(n,e);t?.addEventListener("abort",()=>{clearTimeout(o),r(new d)},{once:!0})})}function m(e){return e?Boolean(e&&"symbol"!=typeof e):Symbol(`pk.${Date.now()}.${crypto.randomUUID()}`)}const y=Object.freeze(Object.defineProperty({__proto__:null,config:p,pk:m,sleep:h,"ζ":h,"κ":m},Symbol.toStringTag,{value:"Module"})),b=e=>"symbol"==typeof e;function v(e){return t.G.isString(e)||b(e)?e:(t.G.isObject(e)||t.G.isFunction(e))&&s.Action in e?e[s.Action]:e}function g(e){if(t.G.isString(e))return e.startsWith(p.broadcastActionPrefix);if(b(e))return e.description?.startsWith(p.broadcastActionPrefix)??!1;if(t.G.isObject(e)||t.G.isFunction(e)){if(s.Broadcast in e&&e[s.Broadcast])return!0;if(s.Action in e){const t=e[s.Action];return t.description?.startsWith(p.broadcastActionPrefix)??!1}}return!1}function w(e){const n=v(e),r=t.G.isString(n)?n:n.description??"";return r.startsWith(p.actionPrefix)&&r.slice(r.lastIndexOf("/")+1)||"unknown"}function x(e){return t.G.isObject(e)&&s.Channel in e&&"channel"in e}function j(e){if(t.G.isString(e))return e.startsWith(p.multicastActionPrefix);if(b(e))return e.description?.startsWith(p.multicastActionPrefix)??!1;if(t.G.isObject(e)||t.G.isFunction(e)){if(s.Multicast in e&&e[s.Multicast])return!0;if(s.Action in e){const t=e[s.Action];return t.description?.startsWith(p.multicastActionPrefix)??!1}}return!1}function S(e){const t=function(e){return e[s.Cache]}(e),n=function(e){return"channel"in e}(e)&&(r=e.channel)?[...Object.keys(r)].toSorted().map(e=>`${e}=${String(r[e])}`).join("&"):"";var r;return`${String(t)}:${n}`}function P(e){if(e instanceof Error){if("TimeoutError"===e.name)return f.Timedout;if("AbortError"===e.name)return f.Supplanted}return f.Errored}function A(e){return e instanceof Error?e:new Error(String(e))}const O=r.createContext(void 0);let E=(e=21)=>{let t="",n=crypto.getRandomValues(new Uint8Array(e|=0));for(;e--;)t+="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"[63&n[e]];return t};var M=(e=>(e[e.Add=1]="Add",e[e.Remove=2]="Remove",e[e.Update=4]="Update",e[e.Move=8]="Move",e[e.Replace=16]="Replace",e[e.Sort=32]="Sort",e[e.Create=64]="Create",e[e.Fetch=128]="Fetch",e[e.Clone=256]="Clone",e[e.Archive=512]="Archive",e[e.Restore=1024]="Restore",e[e.Merge=2048]="Merge",e[e.Reorder=4096]="Reorder",e[e.Sync=8192]="Sync",e[e.Publish=16384]="Publish",e[e.Link=32768]="Link",e[e.Unlink=65536]="Unlink",e[e.Lock=131072]="Lock",e[e.Unlock=262144]="Unlock",e[e.Import=524288]="Import",e[e.Export=1048576]="Export",e[e.Transfer=2097152]="Transfer",e))(M||{}),C=(e=>(e[e.Produce=0]="Produce",e[e.Hydrate=1]="Hydrate",e))(C||{}),k=(e=>(e.Property="property",e.Process="process",e.Value="value",e.Operation="operation",e))(k||{});class G{[o.immerable]=!0;static keys=new Set(Object.values(k));property=null;process=null;value;operation;constructor(e,t){this.value=e,this.operation=t}assign(e,t){const n=new G(this.value,this.operation);return n.property=e,n.process=t,n}}class _{static immer=(()=>{o.enablePatches();const e=new o.Immer;return e.setAutoFreeze(!1),e})();static tag="κ";static id=E}function R(e,t){const n="string"==typeof t?""===t?[]:t.split("."):t;let r=e;for(const o of n){if(null==r)return;r=r[o]}return r}function N(e){if(t.G.isNullable(e)||L(e))return e;if(t.G.isArray(e))return e.map(e=>N(e));if(t.G.isObject(e)&&U(e)){const t=Object.entries(e).map(([e,t])=>[e,N(t)]);return{...Object.fromEntries(t),[_.tag]:e[_.tag]??_.id()}}return e}function z(e){if(Array.isArray(e))return e.filter(e=>_.tag in e).map(e=>e[_.tag]??"").join(",");const t=e[_.tag];if(t)return t;try{return JSON.stringify(e)}catch{return`[unserializable:${typeof e}]`}}function U(e){const t=Object.getPrototypeOf(e);return t===Object.prototype||null===t}function L(e){return t.G.isNullable(e)||t.G.isString(e)||t.G.isNumber(e)||t.G.isBoolean(e)||"symbol"==typeof e||"bigint"==typeof e}function T(e,n,r,o,c,i){return function s(a,u=n.path){if(a instanceof G){const n=R(r,u.join("."));if(Object.entries(a).filter(([e,t])=>!G.keys.has(e)&&t instanceof G).forEach(([e,t])=>s(t,u.concat(e))),L(a.value)){if(e===C.Hydrate)return a.value;const s=u.slice(0,-1),l=s.length>0?R(r,s.join(".")):r;return t.G.isNullable(l)||B(l,a,u.at(-1),o,c,i),n??a.value}if(e===C.Hydrate){const e=N(s(a.value,u));return B(e,a,null,o,c,i),e}const l=n??N(a.value);return B(l,a,null,o,c,i),t.G.isNullable(n)?l:(s(a.value,u),n)}if(t.G.isArray(a))return a.map((e,t)=>s(e,u.concat(t)));if(t.G.isObject(a)&&!U(a))return a;if(t.G.isObject(a)){const t=Object.entries(a).map(([e,t])=>[e,s(t,u.concat(e))]),n=Object.fromEntries(t);if(e===C.Hydrate){const e=N(n);return Object.entries(a).forEach(([t,n])=>{n instanceof G&&L(n.value)&&B(e,n,t,o,c,i)}),e}return n}return a}(n.value)}function B(e,t,n,r,o,c){const i=c(e),s=o.get(i)??[];o.set(i,[t.assign(n,r),...s])}class ${#e={};#t;#n=new Map;#r=new Set;#o=!1;constructor(e=z){this.#t=e}static pk(){return E()}static"κ"=$.pk;annotate(e,t){return new G(t,e)}"δ"=this.annotate;get model(){return this.#e}get inspect(){return function(e,n,r,o,c){function i(o){const c=o.at(-1),i=R(e(),o),s=o.slice(0,-1),a=t.A.isNotEmpty(s)?R(e(),s):e();return[...t.G.isObject(i)||t.G.isArray(i)?n.get(r(i))?.filter(e=>t.G.isNullable(e.property))??[]:[],...t.G.isObject(a)?n.get(r(a))?.filter(e=>e.property===c)??[]:[]]}return function n(r){return new Proxy(()=>{},{get:(s,a)=>"pending"===a?()=>!t.A.isEmpty(i(r)):"remaining"===a?()=>t.A.length(i(r)):"box"===a?()=>({value:R(e(),r),inspect:n(r)}):"is"===a?e=>i(r).some(t=>0!==(t.operation&e)):"draft"===a?()=>t.A.head(i(r))?.value??R(e(),r):"settled"===a?()=>new Promise(n=>{if(t.A.isEmpty(i(r)))return n(R(e(),r));const s=()=>{t.A.isEmpty(i(r))&&(c(s),n(R(e(),r)))};o(s)}):n([...r,String(a)])})}([])}(()=>this.#e,this.#n,this.#t,e=>this.#r.add(e),e=>this.#r.delete(e))}hydrate(e){return this.#o=!0,this.#c(C.Hydrate,()=>e)}produce(e){if(!this.#o)throw new Error("State must be hydrated using hydrate() before calling produce()");return this.#c(C.Produce,e)}#c(e,t){const n=Symbol("process"),[,r]=_.immer.produceWithPatches(this.#e,t);return this.#e=r.reduce((t,r)=>_.immer.applyPatches(t,[{...r,value:T(e,r,t,n,this.#n,this.#t)}]),this.#e),this.#e=N(this.#e),this.#i(),n}prune(e){this.#n.forEach((n,r)=>{const o=n.filter(t=>t.process!==e);t.A.isEmpty(o)?this.#n.delete(r):this.#n.set(r,o)}),this.#i()}#i(){this.#r.forEach(e=>e())}observe(e){const t=()=>e(this.#e);return this.#r.add(t),()=>this.#r.delete(t)}}const W=new $;function D(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var F,H={exports:{}},I=(F||(F=1,function(e){var t=Object.prototype.hasOwnProperty,n="~";function r(){}function o(e,t,n){this.fn=e,this.context=t,this.once=n||!1}function c(e,t,r,c,i){if("function"!=typeof r)throw new TypeError("The listener must be a function");var s=new o(r,c||e,i),a=n?n+t:t;return e._events[a]?e._events[a].fn?e._events[a]=[e._events[a],s]:e._events[a].push(s):(e._events[a]=s,e._eventsCount++),e}function i(e,t){0===--e._eventsCount?e._events=new r:delete e._events[t]}function s(){this._events=new r,this._eventsCount=0}Object.create&&(r.prototype=Object.create(null),(new r).__proto__||(n=!1)),s.prototype.eventNames=function(){var e,r,o=[];if(0===this._eventsCount)return o;for(r in e=this._events)t.call(e,r)&&o.push(n?r.slice(1):r);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(e)):o},s.prototype.listeners=function(e){var t=this._events[n?n+e:e];if(!t)return[];if(t.fn)return[t.fn];for(var r=0,o=t.length,c=new Array(o);r<o;r++)c[r]=t[r].fn;return c},s.prototype.listenerCount=function(e){var t=this._events[n?n+e:e];return t?t.fn?1:t.length:0},s.prototype.emit=function(e,t,r,o,c,i){var s=n?n+e:e;if(!this._events[s])return!1;var a,u,l=this._events[s],f=arguments.length;if(l.fn){switch(l.once&&this.removeListener(e,l.fn,void 0,!0),f){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,t),!0;case 3:return l.fn.call(l.context,t,r),!0;case 4:return l.fn.call(l.context,t,r,o),!0;case 5:return l.fn.call(l.context,t,r,o,c),!0;case 6:return l.fn.call(l.context,t,r,o,c,i),!0}for(u=1,a=new Array(f-1);u<f;u++)a[u-1]=arguments[u];l.fn.apply(l.context,a)}else{var d,p=l.length;for(u=0;u<p;u++)switch(l[u].once&&this.removeListener(e,l[u].fn,void 0,!0),f){case 1:l[u].fn.call(l[u].context);break;case 2:l[u].fn.call(l[u].context,t);break;case 3:l[u].fn.call(l[u].context,t,r);break;case 4:l[u].fn.call(l[u].context,t,r,o);break;default:if(!a)for(d=1,a=new Array(f-1);d<f;d++)a[d-1]=arguments[d];l[u].fn.apply(l[u].context,a)}}return!0},s.prototype.on=function(e,t,n){return c(this,e,t,n,!1)},s.prototype.once=function(e,t,n){return c(this,e,t,n,!0)},s.prototype.removeListener=function(e,t,r,o){var c=n?n+e:e;if(!this._events[c])return this;if(!t)return i(this,c),this;var s=this._events[c];if(s.fn)s.fn!==t||o&&!s.once||r&&s.context!==r||i(this,c);else{for(var a=0,u=[],l=s.length;a<l;a++)(s[a].fn!==t||o&&!s[a].once||r&&s[a].context!==r)&&u.push(s[a]);u.length?this._events[c]=1===u.length?u[0]:u:i(this,c)}return this},s.prototype.removeAllListeners=function(e){var t;return e?this._events[t=n?n+e:e]&&i(this,t):(this._events=new r,this._eventsCount=0),this},s.prototype.off=s.prototype.removeListener,s.prototype.addListener=s.prototype.on,s.prefixed=n,s.EventEmitter=s,e.exports=s}(H)),H.exports);const q=D(I),V=i.createContext(new q);function J(){return i.useContext(V)}function K({children:e}){const t=i.useMemo(()=>new q,[]);return n.jsx(V.Provider,{value:t,children:e})}const Q=i.createContext(new Map);function X(){return i.useContext(Q)}function Y(){const[,e]=i.useReducer(e=>e+1,0);return e}function Z({action:e,renderer:n}){const r=J(),o=X(),c=Y(),s=i.useMemo(()=>{const t=o.get(e);if(t)return t;const n={state:new $,listeners:new Set};return o.set(e,n),n},[e,o]);i.useLayoutEffect(()=>{function t(e){s.state.hydrate({value:e}),s.listeners.forEach(e=>e())}return s.listeners.add(c),r.on(e,t),()=>{s.listeners.delete(c),r.off(e,t)}},[e,r,s]);const a=s.state.model?.value;return t.G.isNullable(a)?null:n({value:a,inspect:s.state.inspect.value})}function ee({children:e}){const t=i.useMemo(()=>new Map,[]);return n.jsx(Q.Provider,{value:t,children:e})}const te=i.createContext(new Map);function ne({children:e}){const t=i.useMemo(()=>new Map,[]);return n.jsx(te.Provider,{value:t,children:e})}const re=i.createContext(new Set);function oe({children:e}){const t=i.useMemo(()=>new Set,[]);return n.jsx(re.Provider,{value:t,children:e})}const ce=i.createContext(null);function ie(){return i.useContext(ce)}function se(e,t){return e?.get(t)??null}function ae({action:e,scopeName:n,renderer:r}){const o=ie(),c=Y(),s=i.useMemo(()=>se(o,n),[o,n]),a=i.useMemo(()=>s?function(e,t){const n=e.store.get(t);if(n)return n;const r={state:new $,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(`${p.broadcastActionPrefix}${e}`):t===u.Multicast?Symbol(`${p.multicastActionPrefix}${e}`):Symbol(`${p.actionPrefix}${e}`),r=function(e){return{[s.Action]:n,[s.Payload]:void 0,[s.Channel]:e,channel:e}};return Object.defineProperty(r,s.Action,{value:n,enumerable:!1}),Object.defineProperty(r,s.Payload,{value:void 0,enumerable:!1}),t===u.Broadcast&&Object.defineProperty(r,s.Broadcast,{value:!0,enumerable:!1}),t===u.Multicast&&Object.defineProperty(r,s.Multicast,{value:!0,enumerable:!1}),r},e.Boundary=function({children:e}){return n.jsx(K,{children:n.jsx(ee,{children:n.jsx(ne,{children:n.jsx(oe,{children:e})})})})},e.Distribution=u,e.Entry=function(){const e=Symbol("chizu.cache/Entry"),t=function(t){return{[s.Cache]:e,channel:t}};return Object.defineProperty(t,s.Cache,{value:e,enumerable:!1}),t},e.Error=function({handler:e,children:t}){return n.jsx(O.Provider,{value:e,children:t})},e.Lifecycle=a,e.Op=M,e.Operation=M,e.Reason=f,e.Scope=function({name:e,children:t}){const r=ie(),o=i.useMemo(()=>({name:e,emitter:new q,store:new Map,listeners:new Map}),[]),c=i.useMemo(()=>{const t=new Map(r??[]);return t.set(e,o),t},[r,e,o]);return n.jsx(ce.Provider,{value:c,children:t})},e.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,n=()=>({})){const o=J(),c=ie(),u=r.useContext(O),f=i.useContext(re),d=i.useContext(te),p=Y(),h=i.useRef(!1),m=i.useRef(null),y=i.useRef(new $);h.current||(h.current=!0,m.current=y.current.hydrate(e));const[b,E]=i.useState(()=>y.current.model),M=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()),C=i.useMemo(()=>new q,[]),k=i.useRef({handlers:new Map});k.current.handlers=new Map;const G=function(){const e=i.useRef(new Set),t=i.useRef(new Set);return i.useMemo(()=>({broadcast:e.current,multicast:t.current}),[])}(),_=i.useRef(l.Mounting),R=function(){const e=i.useRef({}),t=i.useRef(new Map),n=i.useRef(new Map);return i.useMemo(()=>({refs:e,pending:t,emitted:n}),[])}(),N=i.useRef(new Set),z=i.useRef(0),U=i.useCallback((e,t,n)=>{const r=new AbortController,i={controller:r,action:e,payload:t};return f.add(i),N.current.add(i),{model:b,get phase(){return _.current},task:i,data:M,tasks:f,nodes:R.refs.current,actions:{produce(e){if(r.signal.aborted)return;const t=y.current.produce(t=>e({model:t,inspect:y.current.inspect}));E(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 i=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(i,t,s))}(g(e)?o:C).emit(i,t,s)},annotate:(e,t)=>y.current.annotate(e,t),async cacheable(e,t,n){if(r.signal.aborted)return{data:null};const o=S(e),c=d.get(o);if(c&&Date.now()<c.expiry)return{data:c.value};const i=function(e){return null!=e&&"object"==typeof e&&"TAG"in e?0===e.TAG?{ok:!0,value:e._0}:{ok:!1}:null==e?{ok:!1}:{ok:!0,value:e}}(await n());return i.ok?(d.set(o,{value:i.value,expiry:Date.now()+t}),{data:i.value}):{data:null}},invalidate(e){d.delete(S(e))}}}},[b]);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=U(e,o,s);try{await n(d,o)}catch(h){const t=k.current.handlers.has(a.Error),n={reason:P(h),error:A(h),action:w(e),handled:t,tasks:f};u?.(n),t&&C.emit(a.Error,n)}finally{for(const e of f)if(e===d.task){f.delete(e),N.current.delete(e);break}s.processes.forEach(e=>y.current.prune(e)),s.processes.size>0&&p(),l.resolve()}}}z.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))}C.on(r,t),G.multicast.add(r),n.add(()=>C.off(r,t))}else g(r)?(o.on(r,t),C.on(r,t),G.broadcast.add(r),n.add(()=>{o.off(r,t),C.off(r,t)})):(C.on(r,t),n.add(()=>C.off(r,t)))}}),()=>{const e=++z.current,t=new Set(n);queueMicrotask(()=>{if(z.current===e){for(const e of N.current)e.controller.abort(),f.delete(e);N.current.clear(),_.current=l.Unmounting,C.emit(a.Unmount),_.current=l.Unmounted;for(const e of t)e()}else for(const e of t)e()})}},[C]),i.useLayoutEffect(()=>{for(const[e,t]of R.pending.current)R.emitted.current.get(e)!==t&&(R.emitted.current.set(e,t),C.emit(s.Node,t,{Name:e}));R.pending.current.clear()}),function({unicast:e,broadcastActions:n,phase:r,data:o}){const c=X(),s=i.useRef(null);i.useLayoutEffect(()=>{r.current===l.Mounting&&(e.emit(a.Mount),n.forEach(n=>{const r=c.get(n),o=r?.state.model?.value;t.G.isNullable(o)||e.emit(n,o)}),r.current=l.Mounted)},[]),i.useLayoutEffect(()=>{if(t.G.isNotNullable(s.current)){const n=function(e,t){return Object.keys(t).reduce((n,r)=>e[r]!==t[r]?{...n,[r]:t[r]}:n,{})}(s.current,o);t.A.isNotEmpty(Object.keys(n))&&e.emit(a.Update,n)}s.current=o},[o,e])}({unicast:C,broadcastActions:G.broadcast,phase:_,data:n()});const L=i.useMemo(()=>[b,{dispatch(e,t,n){const r=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(r,t,i))}(g(e)?o:C).emit(r,t,i)},consume:(e,t,n)=>j(e)&&n?.scope?i.createElement(ae,{action:v(e),scopeName:n.scope,renderer:t}):i.createElement(Z,{action:v(e),renderer:t}),get inspect(){return y.current.inspect},get nodes(){return R.refs.current},node(e,t){R.refs.current[e]=t,R.pending.current.set(e,t)}}],[b,C]);return L.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)},L},e.utils=y,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,6 +1,5 @@
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';
4
3
  export { With } from './utils.ts';
5
4
  /**
6
5
  * A hook for managing state with actions.
@@ -19,11 +18,7 @@ export { With } from './utils.ts';
19
18
  * @template M The model type representing the component's state.
20
19
  * @template AC The actions class containing action definitions.
21
20
  * @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.
21
+ * @param initialModel The initial model state.
27
22
  * @param getData Optional function that returns reactive values as data.
28
23
  * Values returned are accessible via `context.data` in action handlers,
29
24
  * always reflecting the latest values even after await operations.
@@ -34,11 +29,6 @@ export { With } from './utils.ts';
34
29
  * // Basic usage
35
30
  * const actions = useActions<Model, typeof Actions>(model);
36
31
  *
37
- * // With rehydration — state survives unmount/remount
38
- * const actions = useActions<Model, typeof Actions>(
39
- * Rehydrate(model, { UserId: props.userId }),
40
- * );
41
- *
42
32
  * // With reactive data
43
33
  * const actions = useActions<Model, typeof Actions, { query: string }>(
44
34
  * model,
@@ -46,4 +36,4 @@ export { With } from './utils.ts';
46
36
  * );
47
37
  * ```
48
38
  */
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>;
39
+ export declare function useActions<M extends Model, AC extends Actions, D extends Props = Props>(initialModel: M, getData?: Data<D>): UseActions<M, AC, D>;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { Action } from './action/index.ts';
2
- export { Rehydrate, Id } from './rehydrate/index.ts';
2
+ export { Entry } from './cache/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';
@@ -11,4 +11,4 @@ export * as utils from './utils/index.ts';
11
11
  export type { Box } from 'immertation';
12
12
  export type { Fault, Catcher } from './error/index.tsx';
13
13
  export type { Pk, Task, Tasks, Handlers } from './types/index.ts';
14
- export type { StoreId } from './rehydrate/index.ts';
14
+ export type { CacheId, ChanneledCacheId } from './cache/index.ts';
@@ -1,6 +1,8 @@
1
1
  import { Operation, Process, Inspect, Box } from 'immertation';
2
2
  import { ActionId, Task, Tasks } from '../boundary/components/tasks/types.ts';
3
3
  import { ConsumerRenderer } from '../boundary/components/consumer/index.tsx';
4
+ import { Option } from '@mobily/ts-belt/Option';
5
+ import { Result as TsBeltResult } from '@mobily/ts-belt/Result';
4
6
  import type * as React from "react";
5
7
  export type { ActionId, Box, Task, Tasks };
6
8
  export type { ConsumerRenderer };
@@ -56,9 +58,41 @@ export declare class Brand {
56
58
  static Channel: symbol;
57
59
  /** Node capture events used by Lifecycle.Node */
58
60
  static Node: symbol;
59
- /** Identifies rehydrated model wrappers created with Rehydrate() */
60
- static Rehydrate: symbol;
61
+ /** Identifies cache entry identifiers created with Entry() */
62
+ static Cache: symbol;
61
63
  }
64
+ /**
65
+ * Phantom brand symbol for value type tracking on cache entry identifiers.
66
+ * Uses a function type `(t: T) => T` to enforce invariance, preventing
67
+ * a cache entry declared for one type from being used with a different type.
68
+ * @internal
69
+ */
70
+ declare const CacheValueBrand: unique symbol;
71
+ /**
72
+ * A branded cache entry identifier.
73
+ *
74
+ * When the second type parameter `C` is provided, the entry becomes callable
75
+ * to produce channeled identifiers for independent cache slots per channel.
76
+ *
77
+ * @template T - The cached value type.
78
+ * @template C - The channel type for channeled entries (defaults to never).
79
+ */
80
+ export type CacheId<T = unknown, C extends Filter = never> = {
81
+ readonly [CacheValueBrand]?: (t: T) => T;
82
+ } & ([C] extends [never] ? unknown : {
83
+ (channel: C): ChanneledCacheId<T, C>;
84
+ });
85
+ /**
86
+ * Result of calling a channeled cache entry with a channel argument.
87
+ * Contains the entry identity and the channel data for scoped cache access.
88
+ *
89
+ * @template T - The cached value type.
90
+ * @template C - The channel type.
91
+ */
92
+ export type ChanneledCacheId<T = unknown, C = unknown> = {
93
+ readonly [CacheValueBrand]?: (t: T) => T;
94
+ readonly channel: C;
95
+ };
62
96
  /**
63
97
  * Lifecycle actions that trigger at specific points in a component's lifecycle.
64
98
  * Define handlers for these in your actions class to respond to lifecycle events.
@@ -504,21 +538,44 @@ export type HandlerContext<M extends Model, _AC extends Actions, D extends Props
504
538
  dispatch(action: ActionOrChanneled, payload?: unknown, options?: MulticastOptions): void;
505
539
  annotate<T>(operation: Operation, value: T): T;
506
540
  /**
507
- * Removes a rehydration snapshot from the store.
541
+ * Fetches a value from the cache or executes the callback if not cached / expired.
542
+ *
543
+ * The callback must return an `Option<T>` or `Result<T, E>`. Only `Some` / `Ok`
544
+ * values are stored; `None` / `Error` results are skipped and `{ data: null }`
545
+ * is returned. Exactly one layer of `Option` / `Result` is unwrapped.
508
546
  *
509
- * Use this to invalidate persisted state for a specific channel key,
510
- * so that the next mount of the target component starts fresh instead
511
- * of restoring stale data.
547
+ * @param entry - The cache entry identifier (from `Entry()`).
548
+ * @param ttl - Time-to-live in milliseconds.
549
+ * @param fn - Async callback that produces the value to cache.
550
+ * @returns An object with `data` set to the cached or freshly-fetched value, or `null`.
551
+ *
552
+ * @example
553
+ * ```ts
554
+ * const { data } = await context.actions.cacheable(
555
+ * CacheStore.Pairs,
556
+ * 30_000,
557
+ * async () => Some(await api.fetchPairs()),
558
+ * );
559
+ * ```
560
+ */
561
+ cacheable<T>(entry: CacheId<T> | ChanneledCacheId<T>, ttl: number, fn: () => Promise<Option<T>>): Promise<{
562
+ data: T | null;
563
+ }>;
564
+ cacheable<T>(entry: CacheId<T> | ChanneledCacheId<T>, ttl: number, fn: () => Promise<TsBeltResult<T, unknown>>): Promise<{
565
+ data: T | null;
566
+ }>;
567
+ /**
568
+ * Removes a cached value from the store.
512
569
  *
513
- * @param channel - The channel key identifying the snapshot to remove.
570
+ * @param entry - The cache entry identifier to invalidate.
514
571
  *
515
572
  * @example
516
573
  * ```ts
517
- * context.actions.invalidate(Store.Counter({ UserId: 5 }));
518
- * context.actions.invalidate(Store.Settings());
574
+ * context.actions.invalidate(CacheStore.Pairs);
575
+ * context.actions.invalidate(CacheStore.User({ UserId: 5 }));
519
576
  * ```
520
577
  */
521
- invalidate(channel: Filter): void;
578
+ invalidate(entry: CacheId<unknown> | ChanneledCacheId<unknown>): void;
522
579
  };
523
580
  };
524
581
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chizu",
3
- "version": "0.2.53",
3
+ "version": "0.2.55",
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.25"
18
+ "immertation": "^0.1.26"
19
19
  },
20
20
  "peerDependencies": {
21
21
  "@mobily/ts-belt": "^3.0.0",
@@ -1,13 +0,0 @@
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;
@@ -1,14 +0,0 @@
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
- };
@@ -1,12 +0,0 @@
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;
@@ -1,138 +0,0 @@
1
- import { Filter, Model } from '../types/index.ts';
2
- /**
3
- * Serialises a channel object into a deterministic string key.
4
- * Keys are sorted alphabetically for deterministic output.
5
- * Returns an empty string for unchanneled operations.
6
- */
7
- export declare function serializeChannel(channel?: Filter): string;
8
- /**
9
- * Phantom brand symbol for model type tracking on store identifiers.
10
- * Uses a function type `(m: M) => M` to enforce invariance, preventing
11
- * a store entry declared for one model from being used with a different model.
12
- * @internal
13
- */
14
- declare const StoreModelBrand: unique symbol;
15
- /**
16
- * A `Filter` branded with a phantom model type `M`.
17
- *
18
- * Returned by `Id<M>()` and `Id<M, C>()`, this type carries the model at
19
- * the type level so that `Rehydrate(model, storeId)` can verify at compile
20
- * time that the model and the store entry agree on the model shape.
21
- *
22
- * The phantom brand uses a function type `(m: M) => M` to enforce invariance —
23
- * `StoreId<A>` is not assignable to `StoreId<B>` unless `A` and `B` are
24
- * identical, preventing accidental cross-component snapshot usage.
25
- *
26
- * @template M - The model type this store entry is scoped to.
27
- */
28
- export type StoreId<M extends Model = Model> = Filter & {
29
- readonly [StoreModelBrand]?: (m: M) => M;
30
- };
31
- /**
32
- * Branded wrapper for a model with rehydration metadata.
33
- * When passed to `useActions`, the model state is automatically saved to the
34
- * rehydrator on unmount and restored from it on remount.
35
- */
36
- export type Rehydrated<M extends Model = Model> = {
37
- readonly model: M;
38
- readonly channel: Filter;
39
- };
40
- /**
41
- * Creates a typed store entry for rehydration snapshots.
42
- *
43
- * The first type parameter `M` binds the store entry to a specific model type,
44
- * ensuring that `Rehydrate(model, storeId)` produces a compile-time error if
45
- * the model and store entry disagree on the model shape.
46
- *
47
- * When called with only `M`, returns a nullary function that produces a unique
48
- * `StoreId<M>` — useful for components with a single instance (unchanneled).
49
- *
50
- * When called with `M` and `C`, returns a unary function that passes through
51
- * the channel object as `C & StoreId<M>` — useful for components with multiple
52
- * instances keyed by some identifier (channeled).
53
- *
54
- * @template M - The model type this store entry is scoped to.
55
- * @template C - The channel type, constrained to `Filter` (object of non-nullable primitives).
56
- * @returns A function that produces a `StoreId<M>` for use with `Rehydrate` and `invalidate`.
57
- *
58
- * @example
59
- * ```ts
60
- * import { Id, Rehydrate } from "chizu";
61
- *
62
- * type CounterModel = { count: number };
63
- *
64
- * class Store {
65
- * // Unchanneled — one snapshot for all instances
66
- * static Settings = Id<SettingsModel>();
67
- *
68
- * // Channeled — independent snapshot per UserId
69
- * static Counter = Id<CounterModel, { UserId: number }>();
70
- * }
71
- *
72
- * // Unchanneled usage
73
- * const actions = useActions<SettingsModel, typeof Actions>(
74
- * Rehydrate(model, Store.Settings()),
75
- * );
76
- *
77
- * // Channeled usage
78
- * const actions = useActions<CounterModel, typeof Actions>(
79
- * Rehydrate(model, Store.Counter({ UserId: props.userId })),
80
- * );
81
- *
82
- * // Compile error — model mismatch!
83
- * // Rehydrate(settingsModel, Store.Counter({ UserId: 1 }));
84
- *
85
- * // Invalidate a specific snapshot
86
- * context.actions.invalidate(Store.Counter({ UserId: 5 }));
87
- * context.actions.invalidate(Store.Settings());
88
- * ```
89
- */
90
- export declare function Id<M extends Model>(): () => StoreId<M>;
91
- export declare function Id<M extends Model, C extends Filter>(): (channel: C) => C & StoreId<M>;
92
- /**
93
- * Wraps an initial model with rehydration metadata.
94
- *
95
- * When a rehydrated model is passed to `useActions`, the component's state is
96
- * automatically snapshotted to the rehydrator on unmount and restored from it
97
- * on remount if a matching entry exists.
98
- *
99
- * The channel must be a `StoreId<M>` produced by `Id<M>()` or `Id<M, C>()`.
100
- * TypeScript verifies that the model type `M` of the store entry matches the
101
- * model being passed, preventing accidental cross-component snapshot usage.
102
- *
103
- * @template M - The model type.
104
- * @param model - The initial model (used as fallback when no snapshot exists).
105
- * @param channel - A `StoreId<M>` identifying this component's snapshot.
106
- * @returns A branded object containing the model and rehydration metadata.
107
- *
108
- * @example
109
- * ```ts
110
- * const actions = useActions<Model, typeof Actions>(
111
- * Rehydrate(model, Store.Counter({ UserId: props.userId })),
112
- * );
113
- * ```
114
- */
115
- export declare function Rehydrate<M extends Model>(model: M, channel: StoreId<M>): Rehydrated<M>;
116
- /**
117
- * Type guard to detect whether a value is a `Rehydrated` wrapper.
118
- */
119
- export declare function isRehydrated<M extends Model>(value: M | Rehydrated<M>): value is Rehydrated<M>;
120
- /**
121
- * Hook that resolves the initial model from a potential `Rehydrated` wrapper.
122
- *
123
- * On first call, checks the rehydrator for an existing snapshot matching the
124
- * channel key. If found, returns the snapshot; otherwise returns the initial
125
- * model. Also returns a `save` function for persisting the model on unmount.
126
- *
127
- * For non-rehydrated models, `save` is a no-op.
128
- *
129
- * @template M - The model type.
130
- * @param initialModelOrRehydrated - A plain model or a `Rehydrated` wrapper.
131
- * @returns The resolved model and a save function.
132
- */
133
- export declare function useRehydration<M extends Model>(initialModelOrRehydrated: M | Rehydrated<M>): {
134
- model: M;
135
- save: (model: M) => void;
136
- invalidate: (channel: Filter) => void;
137
- };
138
- export {};