chizu 0.2.70 → 0.2.72
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 +47 -0
- package/dist/boundary/components/broadcast/utils.d.ts +5 -0
- package/dist/chizu.js +6 -6
- package/dist/chizu.umd.cjs +1 -1
- package/dist/hooks/index.d.ts +2 -2
- package/dist/hooks/types.d.ts +4 -4
- package/dist/hooks/utils.d.ts +14 -1
- package/dist/index.d.ts +1 -1
- package/dist/types/index.d.ts +148 -38
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -215,6 +215,22 @@ actions.useAction(Actions.Check, (context) => {
|
|
|
215
215
|
});
|
|
216
216
|
```
|
|
217
217
|
|
|
218
|
+
Dispatch is awaitable – `context.actions.dispatch` returns a `Promise<void>` that resolves when all triggered handlers have completed. This prevents UI flashes where local state changes before upstream handlers finish:
|
|
219
|
+
|
|
220
|
+
```tsx
|
|
221
|
+
actions.useAction(Actions.Mount, async (context) => {
|
|
222
|
+
// Wait for all PaymentSent handlers across the app to finish.
|
|
223
|
+
await context.actions.dispatch(Actions.Broadcast.PaymentSent);
|
|
224
|
+
|
|
225
|
+
// Safe to update local state now — upstream work is done.
|
|
226
|
+
context.actions.produce(({ model }) => {
|
|
227
|
+
model.loading = false;
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Generator handlers are excluded from the await — they run in the background and do not block the dispatch promise, since they are typically long-lived (polling, SSE streams, etc.).
|
|
233
|
+
|
|
218
234
|
You can also render broadcast values declaratively in JSX with `actions.stream`. The renderer callback receives `(value, inspect)` and returns React nodes:
|
|
219
235
|
|
|
220
236
|
```tsx
|
|
@@ -397,3 +413,34 @@ actions.useAction(Actions.Checkout, async (context) => {
|
|
|
397
413
|
```
|
|
398
414
|
|
|
399
415
|
`disallow()` blocks all, `disallow(A, B)` blocks specific actions, `allow()` allows all (reset), and `allow(A, B)` allows only those actions. Each call replaces the previous policy (last-write-wins). Blocked actions fire `Reason.Disallowed` through the error system without allocating resources. See the [action regulator recipe](./recipes/action-regulator.md) for more details.
|
|
416
|
+
|
|
417
|
+
Toggling boolean UI state – modals, sidebars, drawers – is one of the most common patterns. Instead of defining actions and handlers, use the `actions.features` methods:
|
|
418
|
+
|
|
419
|
+
```tsx
|
|
420
|
+
import { useActions } from "chizu";
|
|
421
|
+
import type { Meta } from "chizu";
|
|
422
|
+
|
|
423
|
+
type F = {
|
|
424
|
+
paymentDialog: boolean;
|
|
425
|
+
sidebar: boolean;
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
type Model = {
|
|
429
|
+
name: string;
|
|
430
|
+
meta: Meta.Features<F>;
|
|
431
|
+
};
|
|
432
|
+
|
|
433
|
+
const [model, actions] = useFeatureActions();
|
|
434
|
+
|
|
435
|
+
// Mutate via actions.features
|
|
436
|
+
actions.features.invert("paymentDialog");
|
|
437
|
+
actions.features.on("paymentDialog");
|
|
438
|
+
actions.features.off("paymentDialog");
|
|
439
|
+
|
|
440
|
+
// Read from model
|
|
441
|
+
{
|
|
442
|
+
model.meta.features.paymentDialog && <PaymentDialog />;
|
|
443
|
+
}
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
The methods also work inside action handlers via `context.actions.features`. See the [feature toggles recipe](./recipes/feature-toggles.md) for more details.
|
|
@@ -11,6 +11,11 @@ import * as React from "react";
|
|
|
11
11
|
export declare class BroadcastEmitter extends EventEmitter {
|
|
12
12
|
private cache;
|
|
13
13
|
emit(event: string | symbol, ...args: unknown[]): boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Cache a value for a given event without emitting to listeners.
|
|
16
|
+
* Used by {@link emitAsync} to preserve caching when bypassing `emit()`.
|
|
17
|
+
*/
|
|
18
|
+
setCache(event: string | symbol, value: unknown): void;
|
|
14
19
|
/**
|
|
15
20
|
* Retrieve the last emitted payload for a given event.
|
|
16
21
|
*/
|
package/dist/chizu.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{G as e,A as t}from"@mobily/ts-belt";import{jsx as n}from"react/jsx-runtime";import*as r from"react";import{createContext as o,useContext as c}from"react";import{immerable as
|
|
2
|
-
return n(U.Provider,{value:e,children:t})}let z=(e=21)=>{let t="",n=crypto.getRandomValues(new Uint8Array(e|=0));for(;e--;)t+="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"[63&n[e]];return t};var $=/* @__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))($||{}),T=/* @__PURE__ */(e=>(e[e.Produce=0]="Produce",e[e.Hydrate=1]="Hydrate",e))(T||{}),D=/* @__PURE__ */(e=>(e.Property="property",e.Process="process",e.Value="value",e.Operation="operation",e))(D||{});class B{[
|
|
3
|
-
return n(re.Provider,{value:t,children:e})}const
|
|
4
|
-
return n(
|
|
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 s,enablePatches as i,Immer as a}from"immer";class u{static Payload=/* @__PURE__ */Symbol("chizu.brand/Payload");static Broadcast=/* @__PURE__ */Symbol("chizu.brand/Broadcast");static Multicast=/* @__PURE__ */Symbol("chizu.brand/Multicast");static Action=/* @__PURE__ */Symbol("chizu.brand/Action");static Channel=/* @__PURE__ */Symbol("chizu.brand/Channel");static Node=/* @__PURE__ */Symbol("chizu.action.lifecycle/Node");static Cache=/* @__PURE__ */Symbol("chizu.brand/Cache")}function l(e){const t=/* @__PURE__ */Symbol(`chizu.action.lifecycle/${e}`),n=function(e){return{[u.Action]:t,[u.Payload]:void 0,[u.Channel]:e,channel:e}};return Object.defineProperty(n,u.Action,{value:t,enumerable:!1}),Object.defineProperty(n,u.Payload,{value:void 0,enumerable:!1}),n}class f{static Mount(){return l("Mount")}static Unmount(){return l("Unmount")}static Error(){return l("Error")}static Update(){return l("Update")}static Node(){return l("Node")}}var d=/* @__PURE__ */(e=>(e.Unicast="unicast",e.Broadcast="broadcast",e.Multicast="multicast",e))(d||{}),h=/* @__PURE__ */(e=>(e.Mounting="mounting",e.Mounted="mounted",e.Unmounting="unmounting",e.Unmounted="unmounted",e))(h||{}),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 m extends Error{name="AbortError";constructor(e="Aborted"){super(e)}}class y extends Error{name="DisallowedError";constructor(e="Disallowed"){super(e)}}const b={actionPrefix:"chizu.action/",broadcastActionPrefix:"chizu.action/broadcast/",multicastActionPrefix:"chizu.action/multicast/",channelPrefix:"chizu.channel/",cachePrefix:"chizu.cache/",lifecyclePrefix:"chizu.action.lifecycle/"};function v(e,t){return new Promise((n,r)=>{if(t?.aborted)return void r(new m);const o=setTimeout(n,e);t?.addEventListener("abort",()=>{clearTimeout(o),r(new m)},{once:!0})})}async function g(e,t,n){if(t?.aborted)throw new m;for(;;){if(await n())return;await v(e,t)}}function w(e){return e?Boolean(e&&"symbol"!=typeof e):/* @__PURE__ */Symbol(`pk.${Date.now()}.${crypto.randomUUID()}`)}const P=/* @__PURE__ */Object.freeze(/* @__PURE__ */Object.defineProperty({__proto__:null,config:b,pk:w,poll:g,sleep:v,"ζ":v,"κ":w,"π":g},Symbol.toStringTag,{value:"Module"})),x=e=>"symbol"==typeof e;function S(t){return e.isString(t)||x(t)?t:(e.isObject(t)||e.isFunction(t))&&u.Action in t?t[u.Action]:t}function E(t){if(e.isString(t))return t.startsWith(b.broadcastActionPrefix);if(x(t))return t.description?.startsWith(b.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(b.broadcastActionPrefix)??!1}}return!1}function O(t){const n=S(t),r=e.isString(n)?n:n.description??"";return r.startsWith(b.actionPrefix)&&r.slice(r.lastIndexOf("/")+1)||"unknown"}function j(t){return e.isObject(t)&&u.Channel in t&&"channel"in t}function C(e){const t=S(e),n=x(t)?t.description??"":t;return n.startsWith(b.lifecyclePrefix)&&n.slice(b.lifecyclePrefix.length)||null}function A(t){if(e.isString(t))return t.startsWith(b.multicastActionPrefix);if(x(t))return t.description?.startsWith(b.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(b.multicastActionPrefix)??!1}}return!1}const M=(e,t=d.Unicast)=>{const n=t===d.Broadcast?/* @__PURE__ */Symbol(`${b.broadcastActionPrefix}${e}`):t===d.Multicast?/* @__PURE__ */Symbol(`${b.multicastActionPrefix}${e}`):/* @__PURE__ */Symbol(`${b.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===d.Broadcast&&Object.defineProperty(r,u.Broadcast,{value:!0,enumerable:!1}),t===d.Multicast&&Object.defineProperty(r,u.Multicast,{value:!0,enumerable:!1}),r};function k(){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 _(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 R(e){if(e instanceof Error){if("TimeoutError"===e.name)return p.Timedout;if("AbortError"===e.name)return p.Supplanted;if("DisallowedError"===e.name)return p.Disallowed}return p.Errored}function N(e){return e instanceof Error?e:new Error(String(e))}const U=o(void 0);function L({handler:e,children:t}){/* @__PURE__ */
|
|
2
|
+
return n(U.Provider,{value:e,children:t})}let z=(e=21)=>{let t="",n=crypto.getRandomValues(new Uint8Array(e|=0));for(;e--;)t+="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"[63&n[e]];return t};var $=/* @__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))($||{}),T=/* @__PURE__ */(e=>(e[e.Produce=0]="Produce",e[e.Hydrate=1]="Hydrate",e))(T||{}),D=/* @__PURE__ */(e=>(e.Property="property",e.Process="process",e.Value="value",e.Operation="operation",e))(D||{});class B{[s]=!0;static keys=new Set(Object.values(D));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 W{static immer=(()=>{i();const e=new a;return e.setAutoFreeze(!1),e})();static tag="κ";static id=z}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 H(t){if(e.isNullable(t)||V(t))return t;if(e.isArray(t))return t.map(e=>H(e));if(e.isObject(t)&&I(t)){const e=Object.entries(t).map(([e,t])=>[e,H(t)]);return{...Object.fromEntries(e),[W.tag]:t[W.tag]??W.id()}}return t}function G(e){if(Array.isArray(e))return e.filter(e=>W.tag in e).map(e=>e[W.tag]??"").join(",");const t=e[W.tag];if(t)return t;try{return JSON.stringify(e)}catch{return`[unserializable:${typeof e}]`}}function I(e){const t=Object.getPrototypeOf(e);return t===Object.prototype||null===t}function V(t){return e.isNullable(t)||e.isString(t)||e.isNumber(t)||e.isBoolean(t)||"symbol"==typeof t||"bigint"==typeof t}function q(t,n,r,o,c,s){return function i(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])=>i(t,u.concat(e))),V(a.value)){if(t===T.Hydrate)return a.value;const i=u.slice(0,-1),l=i.length>0?F(r,i.join(".")):r;return e.isNullable(l)||J(l,a,u.at(-1),o,c,s),n??a.value}if(t===T.Hydrate){const e=H(i(a.value,u));return J(e,a,null,o,c,s),e}const l=n??H(a.value);return J(l,a,null,o,c,s),e.isNullable(n)?l:(i(a.value,u),n)}if(e.isArray(a))return a.map((e,t)=>i(e,u.concat(t)));if(e.isObject(a)&&!I(a))return a;if(e.isObject(a)){const e=Object.entries(a).map(([e,t])=>[e,i(t,u.concat(e))]),n=Object.fromEntries(e);if(t===T.Hydrate){const e=H(n);return Object.entries(a).forEach(([t,n])=>{n instanceof B&&V(n.value)&&J(e,n,t,o,c,s)}),e}return n}return a}(n.value)}function J(e,t,n,r,o,c){const s=c(e),i=o.get(s)??[];o.set(s,[t.assign(n,r),...i])}class K{#e={};#t;#n=/* @__PURE__ */new Map;#r=/* @__PURE__ */new Set;#o=!1;constructor(e=G){this.#t=e}static pk(){return z()}static"κ"=K.pk;annotate(e,t){return new B(t,e)}"δ"=this.annotate;get model(){return this.#e}get inspect(){return function(n,r,o,c,s){function i(c){const s=c.at(-1),i=F(n(),c),a=c.slice(0,-1),u=t.isNotEmpty(a)?F(n(),a):n();return[...e.isObject(i)||e.isArray(i)?r.get(o(i))?.filter(t=>e.isNullable(t.property))??[]:[],...e.isObject(u)?r.get(o(u))?.filter(e=>e.property===s)??[]:[]]}return function e(r){return new Proxy(()=>{},{get:(o,a)=>"pending"===a?()=>!t.isEmpty(i(r)):"remaining"===a?()=>t.length(i(r)):"box"===a?()=>({value:F(n(),r),inspect:e(r)}):"is"===a?e=>i(r).some(t=>0!==(t.operation&e)):"draft"===a?()=>t.head(i(r))?.value??F(n(),r):"settled"===a?()=>new Promise(e=>{if(t.isEmpty(i(r)))return e(F(n(),r));const o=()=>{t.isEmpty(i(r))&&(s(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(T.Hydrate,()=>e)}produce(e){if(!this.#o)throw new Error("State must be hydrated using hydrate() before calling produce()");return this.#c(T.Produce,e)}#c(e,t){const n=/* @__PURE__ */Symbol("process"),[,r]=W.immer.produceWithPatches(this.#e,t);return this.#e=r.reduce((t,r)=>W.immer.applyPatches(t,[{...r,value:q(e,r,t,n,this.#n,this.#t)}]),this.#e),this.#e=H(this.#e),this.#s(),n}prune(e){this.#n.forEach((n,r)=>{const o=n.filter(t=>t.process!==e);t.isEmpty(o)?this.#n.delete(r):this.#n.set(r,o)}),this.#s()}#s(){this.#r.forEach(e=>e())}observe(e){const t=()=>e(this.#e);return this.#r.add(t),()=>this.#r.delete(t)}}const Q=new K;function X(e,t){return Q.annotate(e,t)}function Y(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var Z,ee={exports:{}};const te=/* @__PURE__ */Y((Z||(Z=1,function(e){var t=Object.prototype.hasOwnProperty,n="~";function r(){}function o(e,t,n){this.fn=e,this.context=t,this.once=n||!1}function c(e,t,r,c,s){if("function"!=typeof r)throw new TypeError("The listener must be a function");var i=new o(r,c||e,s),a=n?n+t:t;return e._events[a]?e._events[a].fn?e._events[a]=[e._events[a],i]:e._events[a].push(i):(e._events[a]=i,e._eventsCount++),e}function s(e,t){0===--e._eventsCount?e._events=new r:delete e._events[t]}function i(){this._events=new r,this._eventsCount=0}Object.create&&(r.prototype=/* @__PURE__ */Object.create(null),(new r).__proto__||(n=!1)),i.prototype.eventNames=function(){var e,r,o=[];if(0===this._eventsCount)return o;for(r in e=this._events)t.call(e,r)&&o.push(n?r.slice(1):r);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(e)):o},i.prototype.listeners=function(e){var t=this._events[n?n+e:e];if(!t)return[];if(t.fn)return[t.fn];for(var r=0,o=t.length,c=new Array(o);r<o;r++)c[r]=t[r].fn;return c},i.prototype.listenerCount=function(e){var t=this._events[n?n+e:e];return t?t.fn?1:t.length:0},i.prototype.emit=function(e,t,r,o,c,s){var i=n?n+e:e;if(!this._events[i])return!1;var a,u,l=this._events[i],f=arguments.length;if(l.fn){switch(l.once&&this.removeListener(e,l.fn,void 0,!0),f){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,t),!0;case 3:return l.fn.call(l.context,t,r),!0;case 4:return l.fn.call(l.context,t,r,o),!0;case 5:return l.fn.call(l.context,t,r,o,c),!0;case 6:return l.fn.call(l.context,t,r,o,c,s),!0}for(u=1,a=new Array(f-1);u<f;u++)a[u-1]=arguments[u];l.fn.apply(l.context,a)}else{var d,h=l.length;for(u=0;u<h;u++)switch(l[u].once&&this.removeListener(e,l[u].fn,void 0,!0),f){case 1:l[u].fn.call(l[u].context);break;case 2:l[u].fn.call(l[u].context,t);break;case 3:l[u].fn.call(l[u].context,t,r);break;case 4:l[u].fn.call(l[u].context,t,r,o);break;default:if(!a)for(d=1,a=new Array(f-1);d<f;d++)a[d-1]=arguments[d];l[u].fn.apply(l[u].context,a)}}return!0},i.prototype.on=function(e,t,n){return c(this,e,t,n,!1)},i.prototype.once=function(e,t,n){return c(this,e,t,n,!0)},i.prototype.removeListener=function(e,t,r,o){var c=n?n+e:e;if(!this._events[c])return this;if(!t)return s(this,c),this;var i=this._events[c];if(i.fn)i.fn!==t||o&&!i.once||r&&i.context!==r||s(this,c);else{for(var a=0,u=[],l=i.length;a<l;a++)(i[a].fn!==t||o&&!i[a].once||r&&i[a].context!==r)&&u.push(i[a]);u.length?this._events[c]=1===u.length?u[0]:u:s(this,c)}return this},i.prototype.removeAllListeners=function(e){var t;return e?this._events[t=n?n+e:e]&&s(this,t):(this._events=new r,this._eventsCount=0),this},i.prototype.off=i.prototype.removeListener,i.prototype.addListener=i.prototype.on,i.prefixed=n,i.EventEmitter=i,e.exports=i}(ee)),ee.exports));class ne extends te{cache=/* @__PURE__ */new Map;emit(e,...t){return this.cache.set(e,t[0]),super.emit(e,...t)}setCache(e,t){this.cache.set(e,t)}getCached(e){return this.cache.get(e)}}const re=r.createContext(new ne);function oe(){return r.useContext(re)}function ce({children:e}){const t=r.useMemo(()=>new ne,[]);/* @__PURE__ */
|
|
3
|
+
return n(re.Provider,{value:t,children:e})}const se=r.createContext(/* @__PURE__ */new Map);function ie({children:e}){const t=r.useMemo(()=>/* @__PURE__ */new Map,[]);/* @__PURE__ */
|
|
4
|
+
return n(se.Provider,{value:t,children:e})}const ae=r.createContext(/* @__PURE__ */new Set);function ue({children:e}){const t=r.useMemo(()=>/* @__PURE__ */new Set,[]);/* @__PURE__ */
|
|
5
5
|
return n(ae.Provider,{value:t,children:e})}const le=r.createContext({mode:"allow-all",actions:/* @__PURE__ */new Set});function fe({children:e}){const t=r.useMemo(()=>({mode:"allow-all",actions:/* @__PURE__ */new Set}),[]);/* @__PURE__ */
|
|
6
6
|
return n(le.Provider,{value:t,children:e})}function de({children:e}){/* @__PURE__ */
|
|
7
|
-
return n(ce,{children:/* @__PURE__ */n(
|
|
8
|
-
return n(he.Provider,{value:
|
|
7
|
+
return n(ce,{children:/* @__PURE__ */n(ie,{children:/* @__PURE__ */n(fe,{children:/* @__PURE__ */n(ue,{children:e})})})})}const he=r.createContext(null);function pe(){return r.useContext(he)}function me(e,t){return e?.get(t)??null}function ye({name:e,children:t}){const o=pe(),c=r.useMemo(()=>({name:e,emitter:new ne}),[]),s=r.useMemo(()=>{const t=new Map(o??[]);return t.set(e,c),t},[o,e,c]);/* @__PURE__ */
|
|
8
|
+
return n(he.Provider,{value:s,children:t})}function be(e,t){const r=`Scoped${t.displayName||t.name||"Component"}`;return{[r]:r=>/* @__PURE__ */n(ye,{name:e,children:/* @__PURE__ */n(t,{...r})})}[r]}function ve(e,t,...n){e instanceof ne&&e.setCache(t,n[0]);const r=e.listeners(t);return 0===r.length?Promise.resolve():Promise.all(r.map(e=>Promise.resolve(e(...n)))).then(()=>{})}function ge(e){return(t,n)=>{t.actions.produce(t=>{t.model[e]=n})}}function we(e,t){for(const n of e.keys())if(C(n)===t)return n;return null}function Pe(){const[,e]=r.useReducer(e=>e+1,0);return e}const xe=r.createContext(/* @__PURE__ */new Map);function Se({action:t,renderer:n}){const o=oe(),c=r.useContext(xe),s=Pe(),i=r.useMemo(()=>{const e=c.get(t);if(e)return e;const n={state:new K,listeners:/* @__PURE__ */new Set};return c.set(t,n),n},[t,c]);r.useLayoutEffect(()=>{function e(e){i.state.hydrate({value:e}),i.listeners.forEach(e=>e())}return i.listeners.add(s),o.on(t,e),()=>{i.listeners.delete(s),o.off(t,e)}},[t,o,i]);const a=i.state.model?.value;return e.isNullable(a)?null:n(a,i.state.inspect.value)}function Ee(...n){const o=e.isUndefined(n[0])||e.isFunction(n[0])?{}:n[0],s=e.isFunction(n[0])?n[0]:n[1]??(()=>({})),i=oe(),a=pe(),u=c(U),l=r.useContext(ae),f=r.useContext(se),d=r.useContext(le),m=Pe(),b=r.useRef(!1),v=r.useRef(null),g=r.useRef(new K),w=r.useRef({features:null,nodes:null});function P(){null===w.current.features&&null===w.current.nodes||(g.current.model.meta={...null!==w.current.features?{features:w.current.features}:{},...null!==w.current.nodes?{nodes:w.current.nodes}:{}})}if(!b.current){b.current=!0;const e=o,t=e.meta;t?.features&&(w.current.features=t.features),t?.nodes&&(w.current.nodes=t.nodes);const{meta:n,...r}=e;v.current=g.current.hydrate(r),P()}const[x,C]=r.useState(()=>g.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])}(s()),k=r.useMemo(()=>new te,[]),L=r.useRef({handlers:/* @__PURE__ */new Map});L.current.handlers=/* @__PURE__ */new Map;const z=function(){const e=r.useRef(/* @__PURE__ */new Set),t=r.useRef(/* @__PURE__ */new Set);return r.useMemo(()=>({broadcast:e.current,multicast:t.current}),[])}(),$=r.useRef(h.Mounting),T=function(){const e=r.useRef({}),t=r.useRef(/* @__PURE__ */new Map),n=r.useRef(/* @__PURE__ */new Map);return r.useMemo(()=>({refs:e,pending:t,emitted:n}),[])}(),D=r.useRef(/* @__PURE__ */new Set),B=r.useRef(0),W=r.useCallback((e,t,n)=>{const r=new AbortController,o={controller:r,action:e,payload:t};return l.add(o),D.current.add(o),{model:g.current.model,get phase(){return $.current},task:o,data:M,tasks:l,get meta(){return{nodes:T.refs.current,features:w.current.features??{}}},regulator:{disallow(...e){if(d.actions.clear(),0===e.length)d.mode="disallow-all";else{d.mode="disallow-matching";for(const t of e)d.actions.add(S(t))}},allow(...e){if(d.actions.clear(),0===e.length)d.mode="allow-all";else{d.mode="allow-matching";for(const t of e)d.actions.add(S(t))}}},actions:{produce(e){if(r.signal.aborted)return;const t=g.current.produce(t=>{e({model:t,inspect:g.current.inspect})});P(),C(g.current.model),n.processes.add(t),v.current&&(n.processes.add(v.current),v.current=null)},dispatch(e,t,n){if(r.signal.aborted)return Promise.resolve();const o=S(e),c=j(e)?e.channel:void 0;if(A(e)&&n?.scope){const e=me(a,n.scope);return e?ve(e.emitter,o,t,c):Promise.resolve()}return ve(E(e)?i:k,o,t,c)},annotate:(e,t)=>g.current.annotate(e,t),async cacheable(e,t,n){if(r.signal.aborted)return{data:null};const o=_(e),c=f.get(o);if(c&&Date.now()<c.expiry)return{data:c.value};const s=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 s.ok?(f.set(o,{value:s.value,expiry:Date.now()+t}),{data:s.value}):{data:null}},invalidate(e){f.delete(_(e))},features:{on(e){r.signal.aborted||(w.current.features={...w.current.features,[e]:!0},P(),C(g.current.model),v.current&&(n.processes.add(v.current),v.current=null))},off(e){r.signal.aborted||(w.current.features={...w.current.features,[e]:!1},P(),C(g.current.model),v.current&&(n.processes.add(v.current),v.current=null))},invert(e){if(r.signal.aborted)return;const t=w.current.features?.[e]??!1;w.current.features={...w.current.features,[e]:!t},P(),C(g.current.model),v.current&&(n.processes.add(v.current),v.current=null)}},async read(e,t){if(r.signal.aborted)return null;const n=S(e),o=A(e)&&t?.scope?me(a,t.scope)?.emitter??null:i;if(!o)return null;if(void 0===o.getCached(n))return null;const c=O(e),s="unknown"!==c?c[0].toLowerCase()+c.slice(1):null;if(s){const e=g.current.inspect[s];e?.pending?.()&&await new Promise((t,n)=>{if(r.signal.aborted)return void n(r.signal.reason);const o=()=>n(r.signal.reason);r.signal.addEventListener("abort",o,{once:!0}),e.settled().then(()=>{r.signal.removeEventListener("abort",o),t()})})}return o.getCached(n)??null},peek(e,t){if(r.signal.aborted)return null;const n=S(e),o=A(e)&&t?.scope?me(a,t.scope)?.emitter??null:i;return o?o.getCached(n)??null:null}}}},[x]);r.useLayoutEffect(()=>{function t(t,n,r){return function(o,c){if(!function(e,t){switch(t.mode){case"allow-all":return!0;case"disallow-all":return!1;case"disallow-matching":return!t.actions.has(e);case"allow-matching":return t.actions.has(e)}}(t,d)){const e=we(L.current.handlers,"Error"),n=null!==e,r={reason:p.Disallowed,error:new y,action:O(t),handled:n,tasks:l};return u?.(r),void(n&&e&&k.emit(e,r))}const s=r();if(e.isNotNullable(c)&&e.isNotNullable(s)&&!function(e,t){for(const n of Object.keys(e))if(t[n]!==e[n])return!1;return!0}(c,s))return;const i={processes:/* @__PURE__ */new Set},a=Promise.withResolvers(),f=W(t,o,i);function h(e){const n=we(L.current.handlers,"Error"),r=null!==n,o={reason:R(e),error:N(e),action:O(t),handled:r,tasks:l};u?.(o),r&&n&&k.emit(n,o)}function b(){for(const e of l)if(e===f.task){l.delete(e),D.current.delete(e);break}i.processes.forEach(e=>g.current.prune(e)),i.processes.size>0&&m(),a.resolve()}let v;try{v=n(f,o)}catch(w){return h(w),void b()}if(!function(e){if(!e||"object"!=typeof e)return!1;const t=Object.prototype.toString.call(e);return"[object Generator]"===t||"[object AsyncGenerator]"===t}(v))return Promise.resolve(v).catch(h).finally(b),a.promise;(async()=>{for await(const e of v);})().catch(h).finally(b)}}B.current++;const n=/* @__PURE__ */new Set;return L.current.handlers.forEach((e,r)=>{for(const{getChannel:o,handler:c}of e){const e=t(r,c,o);if(A(r)){if(a)for(const t of a.values()){const o=t.emitter;o.on(r,e),n.add(()=>o.off(r,e))}k.on(r,e),z.multicast.add(r),n.add(()=>k.off(r,e))}else E(r)?(i.on(r,e),k.on(r,e),z.broadcast.add(r),n.add(()=>{i.off(r,e),k.off(r,e)})):(k.on(r,e),n.add(()=>k.off(r,e)))}}),()=>{const e=++B.current,t=new Set(n);queueMicrotask(()=>{if(B.current!==e){for(const e of t)e();return}for(const e of D.current)e.controller.abort(),l.delete(e);D.current.clear(),$.current=h.Unmounting;const n=we(L.current.handlers,"Unmount");n&&k.emit(n),$.current=h.Unmounted;for(const e of t)e()})}},[k]),r.useLayoutEffect(()=>{const e=we(L.current.handlers,"Node");let t=!1;for(const[n,r]of T.pending.current)if(T.emitted.current.get(n)!==r){if(T.emitted.current.set(n,r),null!==w.current.nodes){const e={...w.current.nodes};e[n]=r,w.current.nodes=e,t=!0}e&&k.emit(e,r,{Name:n})}t&&(P(),C(g.current.model)),T.pending.current.clear()}),function({unicast:n,broadcast:o,dispatchers:c,scope:s,phase:i,data:a,handlers:u}){const l=r.useRef(null);r.useLayoutEffect(()=>{if(i.current!==h.Mounting)return;const t=we(u,"Mount");t&&n.emit(t),c.broadcast.forEach(t=>{const r=o.getCached(t);e.isNullable(r)||n.emit(t,r)}),s&&c.multicast.forEach(t=>{for(const r of s.values()){const o=r.emitter.getCached(t);e.isNullable(o)||n.emit(t,o)}}),i.current=h.Mounted},[]),r.useLayoutEffect(()=>{if(e.isNotNullable(l.current)){const e=function(e,t){return Object.keys(t).reduce((n,r)=>e[r]!==t[r]?{...n,[r]:t[r]}:n,{})}(l.current,a);if(t.isNotEmpty(Object.keys(e))){const t=we(u,"Update");t&&n.emit(t,e)}}l.current=a},[a,n])}({unicast:k,broadcast:i,dispatchers:z,scope:a,phase:$,data:s(),handlers:L.current.handlers});const F=r.useMemo(()=>[x,{dispatch(e,t,n){const r=S(e),o=j(e)?e.channel:void 0;if(A(e)&&n?.scope){const e=me(a,n.scope);return e?ve(e.emitter,r,t,o):Promise.resolve()}return ve(E(e)?i:k,r,t,o)},get inspect(){return g.current.inspect},get meta(){return{nodes:T.refs.current,features:w.current.features??{}}},node(e,t){T.refs.current[e]=t,T.pending.current.set(e,t)},features:{on(e){w.current.features={...w.current.features,[e]:!0},P(),C(g.current.model)},off(e){w.current.features={...w.current.features,[e]:!1},P(),C(g.current.model)},invert(e){const t=w.current.features?.[e]??!1;w.current.features={...w.current.features,[e]:!t},P(),C(g.current.model)}},stream:(e,t)=>r.createElement(Se,{action:S(e),renderer:t})}],[x,k]);return F.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 s=r.useCallback((e,t)=>o.current(e,t),[]),i=r.useCallback(()=>j(c.current)?c.current.channel:void 0,[]),a=S(t),u=e.current.handlers.get(a)??/* @__PURE__ */new Set;0===u.size&&e.current.handlers.set(a,u),u.add({getChannel:i,handler:s})}(L,e,t)},F}export{M as Action,de as Boundary,y as DisallowedError,d as Distribution,k as Entry,L as Error,f as Lifecycle,$ as Op,$ as Operation,p as Reason,fe as Regulators,ye as Scope,K as State,ge as With,X as annotate,Ee as useActions,P as utils,be as withScope};
|
package/dist/chizu.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var global,factory;global=this,factory=function(e,t,n,r,o){"use strict";function c(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const n in e)if("default"!==n){const r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:()=>e[n]})}return t.default=e,Object.freeze(t)}const i=c(r);class s{static Payload=Symbol("chizu.brand/Payload");static Broadcast=Symbol("chizu.brand/Broadcast");static Multicast=Symbol("chizu.brand/Multicast");static Action=Symbol("chizu.brand/Action");static Channel=Symbol("chizu.brand/Channel");static Node=Symbol("chizu.action.lifecycle/Node");static Cache=Symbol("chizu.brand/Cache")}function a(e){const t=Symbol(`chizu.action.lifecycle/${e}`),n=function(e){return{[s.Action]:t,[s.Payload]:void 0,[s.Channel]:e,channel:e}};return Object.defineProperty(n,s.Action,{value:t,enumerable:!1}),Object.defineProperty(n,s.Payload,{value:void 0,enumerable:!1}),n}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)}}class h extends Error{name="DisallowedError";constructor(e="Disallowed"){super(e)}}const p={actionPrefix:"chizu.action/",broadcastActionPrefix:"chizu.action/broadcast/",multicastActionPrefix:"chizu.action/multicast/",channelPrefix:"chizu.channel/",cachePrefix:"chizu.cache/",lifecyclePrefix:"chizu.action.lifecycle/"};function m(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})})}async function y(e,t,n){if(t?.aborted)throw new d;for(;;){if(await n())return;await m(e,t)}}function b(e){return e?Boolean(e&&"symbol"!=typeof e):Symbol(`pk.${Date.now()}.${crypto.randomUUID()}`)}const v=Object.freeze(Object.defineProperty({__proto__:null,config:p,pk:b,poll:y,sleep:m,"ζ":m,"κ":b,"π":y},Symbol.toStringTag,{value:"Module"})),g=e=>"symbol"==typeof e;function w(e){return t.G.isString(e)||g(e)?e:(t.G.isObject(e)||t.G.isFunction(e))&&s.Action in e?e[s.Action]:e}function x(e){if(t.G.isString(e))return e.startsWith(p.broadcastActionPrefix);if(g(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 j(e){const n=w(e),r=t.G.isString(n)?n:n.description??"";return r.startsWith(p.actionPrefix)&&r.slice(r.lastIndexOf("/")+1)||"unknown"}function P(e){return t.G.isObject(e)&&s.Channel in e&&"channel"in e}function S(e){const t=w(e),n=g(t)?t.description??"":t;return n.startsWith(p.lifecyclePrefix)&&n.slice(p.lifecyclePrefix.length)||null}function E(e){if(t.G.isString(e))return e.startsWith(p.multicastActionPrefix);if(g(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 A(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 O(e){if(e instanceof Error){if("TimeoutError"===e.name)return f.Timedout;if("AbortError"===e.name)return f.Supplanted;if("DisallowedError"===e.name)return f.Disallowed}return f.Errored}function C(e){return e instanceof Error?e:new Error(String(e))}const M=r.createContext(void 0);let k=(e=21)=>{let t="",n=crypto.getRandomValues(new Uint8Array(e|=0));for(;e--;)t+="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"[63&n[e]];return t};var G=(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))(G||{}),_=(e=>(e[e.Produce=0]="Produce",e[e.Hydrate=1]="Hydrate",e))(_||{}),R=(e=>(e.Property="property",e.Process="process",e.Value="value",e.Operation="operation",e))(R||{});class N{[o.immerable]=!0;static keys=new Set(Object.values(R));property=null;process=null;value;operation;constructor(e,t){this.value=e,this.operation=t}assign(e,t){const n=new N(this.value,this.operation);return n.property=e,n.process=t,n}}class U{static immer=(()=>{o.enablePatches();const e=new o.Immer;return e.setAutoFreeze(!1),e})();static tag="κ";static id=k}function L(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)||$(e))return e;if(t.G.isArray(e))return e.map(e=>z(e));if(t.G.isObject(e)&&D(e)){const t=Object.entries(e).map(([e,t])=>[e,z(t)]);return{...Object.fromEntries(t),[U.tag]:e[U.tag]??U.id()}}return e}function T(e){if(Array.isArray(e))return e.filter(e=>U.tag in e).map(e=>e[U.tag]??"").join(",");const t=e[U.tag];if(t)return t;try{return JSON.stringify(e)}catch{return`[unserializable:${typeof e}]`}}function D(e){const t=Object.getPrototypeOf(e);return t===Object.prototype||null===t}function $(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 B(e,n,r,o,c,i){return function s(a,u=n.path){if(a instanceof N){const n=L(r,u.join("."));if(Object.entries(a).filter(([e,t])=>!N.keys.has(e)&&t instanceof N).forEach(([e,t])=>s(t,u.concat(e))),$(a.value)){if(e===_.Hydrate)return a.value;const s=u.slice(0,-1),l=s.length>0?L(r,s.join(".")):r;return t.G.isNullable(l)||F(l,a,u.at(-1),o,c,i),n??a.value}if(e===_.Hydrate){const e=z(s(a.value,u));return F(e,a,null,o,c,i),e}const l=n??z(a.value);return F(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)&&!D(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===_.Hydrate){const e=z(n);return Object.entries(a).forEach(([t,n])=>{n instanceof N&&$(n.value)&&F(e,n,t,o,c,i)}),e}return n}return a}(n.value)}function F(e,t,n,r,o,c){const i=c(e),s=o.get(i)??[];o.set(i,[t.assign(n,r),...s])}class W{#e={};#t;#n=new Map;#r=new Set;#o=!1;constructor(e=T){this.#t=e}static pk(){return k()}static"κ"=W.pk;annotate(e,t){return new N(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=L(e(),o),s=o.slice(0,-1),a=t.A.isNotEmpty(s)?L(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:L(e(),r),inspect:n(r)}):"is"===a?e=>i(r).some(t=>0!==(t.operation&e)):"draft"===a?()=>t.A.head(i(r))?.value??L(e(),r):"settled"===a?()=>new Promise(n=>{if(t.A.isEmpty(i(r)))return n(L(e(),r));const s=()=>{t.A.isEmpty(i(r))&&(c(s),n(L(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]=U.immer.produceWithPatches(this.#e,t);return this.#e=r.reduce((t,r)=>U.immer.applyPatches(t,[{...r,value:B(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 H=new W;function I(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var q,V={exports:{}},J=(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=Object.create(null),(new r).__proto__||(n=!1)),s.prototype.eventNames=function(){var e,r,o=[];if(0===this._eventsCount)return o;for(r in e=this._events)t.call(e,r)&&o.push(n?r.slice(1):r);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(e)):o},s.prototype.listeners=function(e){var t=this._events[n?n+e:e];if(!t)return[];if(t.fn)return[t.fn];for(var r=0,o=t.length,c=new Array(o);r<o;r++)c[r]=t[r].fn;return c},s.prototype.listenerCount=function(e){var t=this._events[n?n+e:e];return t?t.fn?1:t.length:0},s.prototype.emit=function(e,t,r,o,c,i){var s=n?n+e:e;if(!this._events[s])return!1;var a,u,l=this._events[s],f=arguments.length;if(l.fn){switch(l.once&&this.removeListener(e,l.fn,void 0,!0),f){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,t),!0;case 3:return l.fn.call(l.context,t,r),!0;case 4:return l.fn.call(l.context,t,r,o),!0;case 5:return l.fn.call(l.context,t,r,o,c),!0;case 6:return l.fn.call(l.context,t,r,o,c,i),!0}for(u=1,a=new Array(f-1);u<f;u++)a[u-1]=arguments[u];l.fn.apply(l.context,a)}else{var d,h=l.length;for(u=0;u<h;u++)switch(l[u].once&&this.removeListener(e,l[u].fn,void 0,!0),f){case 1:l[u].fn.call(l[u].context);break;case 2:l[u].fn.call(l[u].context,t);break;case 3:l[u].fn.call(l[u].context,t,r);break;case 4:l[u].fn.call(l[u].context,t,r,o);break;default:if(!a)for(d=1,a=new Array(f-1);d<f;d++)a[d-1]=arguments[d];l[u].fn.apply(l[u].context,a)}}return!0},s.prototype.on=function(e,t,n){return c(this,e,t,n,!1)},s.prototype.once=function(e,t,n){return c(this,e,t,n,!0)},s.prototype.removeListener=function(e,t,r,o){var c=n?n+e:e;if(!this._events[c])return this;if(!t)return i(this,c),this;var s=this._events[c];if(s.fn)s.fn!==t||o&&!s.once||r&&s.context!==r||i(this,c);else{for(var a=0,u=[],l=s.length;a<l;a++)(s[a].fn!==t||o&&!s[a].once||r&&s[a].context!==r)&&u.push(s[a]);u.length?this._events[c]=1===u.length?u[0]:u:i(this,c)}return this},s.prototype.removeAllListeners=function(e){var t;return e?this._events[t=n?n+e:e]&&i(this,t):(this._events=new r,this._eventsCount=0),this},s.prototype.off=s.prototype.removeListener,s.prototype.addListener=s.prototype.on,s.prefixed=n,s.EventEmitter=s,e.exports=s}(V)),V.exports);const K=I(J);class Q extends K{cache=new Map;emit(e,...t){return this.cache.set(e,t[0]),super.emit(e,...t)}getCached(e){return this.cache.get(e)}}const X=i.createContext(new Q);function Y(){return i.useContext(X)}function Z({children:e}){const t=i.useMemo(()=>new Q,[]);return n.jsx(X.Provider,{value:t,children:e})}const ee=i.createContext(new Map);function te({children:e}){const t=i.useMemo(()=>new Map,[]);return n.jsx(ee.Provider,{value:t,children:e})}const ne=i.createContext(new Set);function re({children:e}){const t=i.useMemo(()=>new Set,[]);return n.jsx(ne.Provider,{value:t,children:e})}const oe=i.createContext({mode:"allow-all",actions:new Set});function ce({children:e}){const t=i.useMemo(()=>({mode:"allow-all",actions:new Set}),[]);return n.jsx(oe.Provider,{value:t,children:e})}const ie=i.createContext(null);function se(){return i.useContext(ie)}function ae(e,t){return e?.get(t)??null}function ue({name:e,children:t}){const r=se(),o=i.useMemo(()=>({name:e,emitter:new Q}),[]),c=i.useMemo(()=>{const t=new Map(r??[]);return t.set(e,o),t},[r,e,o]);return n.jsx(ie.Provider,{value:c,children:t})}function le(e,t){for(const n of e.keys())if(S(n)===t)return n;return null}function fe(){const[,e]=i.useReducer(e=>e+1,0);return e}const de=i.createContext(new Map);function he({action:e,renderer:n}){const r=Y(),o=i.useContext(de),c=fe(),s=i.useMemo(()=>{const t=o.get(e);if(t)return t;const n={state:new W,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(a,s.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(Z,{children:n.jsx(te,{children:n.jsx(ce,{children:n.jsx(re,{children:e})})})})},e.DisallowedError=h,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(M.Provider,{value:e,children:t})},e.Lifecycle=class{static Mount(){return a("Mount")}static Unmount(){return a("Unmount")}static Error(){return a("Error")}static Update(){return a("Update")}static Node(){return a("Node")}},e.Op=G,e.Operation=G,e.Reason=f,e.Regulators=ce,e.Scope=ue,e.State=W,e.With=function(e){return(t,n)=>{t.actions.produce(t=>{t.model[e]=n})}},e.annotate=function(e,t){return H.annotate(e,t)},e.useActions=function(...e){const n=t.G.isUndefined(e[0])||t.G.isFunction(e[0])?{}:e[0],o=t.G.isFunction(e[0])?e[0]:e[1]??(()=>({})),c=Y(),s=se(),a=r.useContext(M),u=i.useContext(ne),d=i.useContext(ee),p=i.useContext(oe),m=fe(),y=i.useRef(!1),b=i.useRef(null),v=i.useRef(new W);y.current||(y.current=!0,b.current=v.current.hydrate(n));const[g,S]=i.useState(()=>v.current.model),k=function(e){const t=i.useRef(e);return i.useLayoutEffect(()=>{t.current=e},[e]),i.useMemo(()=>{return n=t,Object.keys(e).reduce((e,t)=>(Object.defineProperty(e,t,{get:()=>n.current[t],enumerable:!0}),e),{});var n},[e])}(o()),G=i.useMemo(()=>new K,[]),_=i.useRef({handlers:new Map});_.current.handlers=new Map;const R=function(){const e=i.useRef(new Set),t=i.useRef(new Set);return i.useMemo(()=>({broadcast:e.current,multicast:t.current}),[])}(),N=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),z=i.useRef(0),T=i.useCallback((e,t,n)=>{const r=new AbortController,o={controller:r,action:e,payload:t};return u.add(o),L.current.add(o),{model:v.current.model,get phase(){return N.current},task:o,data:k,tasks:u,nodes:U.refs.current,regulator:{disallow(...e){if(p.actions.clear(),0===e.length)p.mode="disallow-all";else{p.mode="disallow-matching";for(const t of e)p.actions.add(w(t))}},allow(...e){if(p.actions.clear(),0===e.length)p.mode="allow-all";else{p.mode="allow-matching";for(const t of e)p.actions.add(w(t))}}},actions:{produce(e){if(r.signal.aborted)return;const t=v.current.produce(t=>e({model:t,inspect:v.current.inspect}));S(v.current.model),n.processes.add(t),b.current&&(n.processes.add(b.current),b.current=null)},dispatch(e,t,n){if(r.signal.aborted)return;const o=w(e),i=P(e)?e.channel:void 0;if(E(e)&&n?.scope){const e=ae(s,n.scope);return void(e&&e.emitter.emit(o,t,i))}(x(e)?c:G).emit(o,t,i)},annotate:(e,t)=>v.current.annotate(e,t),async cacheable(e,t,n){if(r.signal.aborted)return{data:null};const o=A(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(A(e))},async read(e,t){if(r.signal.aborted)return null;const n=w(e),o=E(e)&&t?.scope?ae(s,t.scope)?.emitter??null:c;if(!o)return null;if(void 0===o.getCached(n))return null;const i=j(e),a="unknown"!==i?i[0].toLowerCase()+i.slice(1):null;if(a){const e=v.current.inspect[a];e?.pending?.()&&await new Promise((t,n)=>{if(r.signal.aborted)return void n(r.signal.reason);const o=()=>n(r.signal.reason);r.signal.addEventListener("abort",o,{once:!0}),e.settled().then(()=>{r.signal.removeEventListener("abort",o),t()})})}return o.getCached(n)??null},peek(e,t){if(r.signal.aborted)return null;const n=w(e),o=E(e)&&t?.scope?ae(s,t.scope)?.emitter??null:c;return o?o.getCached(n)??null:null}}}},[g]);i.useLayoutEffect(()=>{function e(e,n,r){return async function(o,c){if(!function(e,t){switch(t.mode){case"allow-all":return!0;case"disallow-all":return!1;case"disallow-matching":return!t.actions.has(e);case"allow-matching":return t.actions.has(e)}}(e,p)){const t=le(_.current.handlers,"Error"),n=null!==t,r={reason:f.Disallowed,error:new h,action:j(e),handled:n,tasks:u};return a?.(r),void(n&&t&&G.emit(t,r))}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=T(e,o,s);try{await n(d,o)}catch(y){const t=le(_.current.handlers,"Error"),n=null!==t,r={reason:O(y),error:C(y),action:j(e),handled:n,tasks:u};a?.(r),n&&t&&G.emit(t,r)}finally{for(const e of u)if(e===d.task){u.delete(e),L.current.delete(e);break}s.processes.forEach(e=>v.current.prune(e)),s.processes.size>0&&m(),l.resolve()}}}z.current++;const n=new Set;return _.current.handlers.forEach((t,r)=>{for(const{getChannel:o,handler:i}of t){const t=e(r,i,o);if(E(r)){if(s)for(const e of s.values()){const o=e.emitter;o.on(r,t),n.add(()=>o.off(r,t))}G.on(r,t),R.multicast.add(r),n.add(()=>G.off(r,t))}else x(r)?(c.on(r,t),G.on(r,t),R.broadcast.add(r),n.add(()=>{c.off(r,t),G.off(r,t)})):(G.on(r,t),n.add(()=>G.off(r,t)))}}),()=>{const e=++z.current,t=new Set(n);queueMicrotask(()=>{if(z.current!==e){for(const e of t)e();return}for(const e of L.current)e.controller.abort(),u.delete(e);L.current.clear(),N.current=l.Unmounting;const n=le(_.current.handlers,"Unmount");n&&G.emit(n),N.current=l.Unmounted;for(const e of t)e()})}},[G]),i.useLayoutEffect(()=>{const e=le(_.current.handlers,"Node");for(const[t,n]of U.pending.current)U.emitted.current.get(t)!==n&&(U.emitted.current.set(t,n),e&&G.emit(e,n,{Name:t}));U.pending.current.clear()}),function({unicast:e,broadcast:n,dispatchers:r,scope:o,phase:c,data:s,handlers:a}){const u=i.useRef(null);i.useLayoutEffect(()=>{if(c.current!==l.Mounting)return;const i=le(a,"Mount");i&&e.emit(i),r.broadcast.forEach(r=>{const o=n.getCached(r);t.G.isNullable(o)||e.emit(r,o)}),o&&r.multicast.forEach(n=>{for(const r of o.values()){const o=r.emitter.getCached(n);t.G.isNullable(o)||e.emit(n,o)}}),c.current=l.Mounted},[]),i.useLayoutEffect(()=>{if(t.G.isNotNullable(u.current)){const n=function(e,t){return Object.keys(t).reduce((n,r)=>e[r]!==t[r]?{...n,[r]:t[r]}:n,{})}(u.current,s);if(t.A.isNotEmpty(Object.keys(n))){const t=le(a,"Update");t&&e.emit(t,n)}}u.current=s},[s,e])}({unicast:G,broadcast:c,dispatchers:R,scope:s,phase:N,data:o(),handlers:_.current.handlers});const D=i.useMemo(()=>[g,{dispatch(e,t,n){const r=w(e),o=P(e)?e.channel:void 0;if(E(e)&&n?.scope){const e=ae(s,n.scope);return void(e&&e.emitter.emit(r,t,o))}(x(e)?c:G).emit(r,t,o)},get inspect(){return v.current.inspect},get nodes(){return U.refs.current},node(e,t){U.refs.current[e]=t,U.pending.current.set(e,t)},stream:(e,t)=>i.createElement(he,{action:w(e),renderer:t})}],[g,G]);return D.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(()=>P(o.current)?o.current.channel:void 0,[]),a=w(t),u=e.current.handlers.get(a)??new Set;0===u.size&&e.current.handlers.set(a,u),u.add({getChannel:s,handler:c})}(_,e,t)},D},e.utils=v,e.withScope=function(e,t){const r=`Scoped${t.displayName||t.name||"Component"}`;return{[r]:r=>n.jsx(ue,{name:e,children:n.jsx(t,{...r})})}[r]},Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})},"object"==typeof exports&&"undefined"!=typeof module?factory(exports,require("@mobily/ts-belt"),require("react/jsx-runtime"),require("react"),require("immer")):"function"==typeof define&&define.amd?define(["exports","@mobily/ts-belt","react/jsx-runtime","react","immer"],factory):factory((global="undefined"!=typeof globalThis?globalThis:global||self).Chizu={},global.TsBelt,global.jsxRuntime,global.React,global.Immer);
|
|
1
|
+
var global,factory;global=this,factory=function(e,t,n,r,o){"use strict";function c(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const n in e)if("default"!==n){const r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:()=>e[n]})}return t.default=e,Object.freeze(t)}const s=c(r);class i{static Payload=Symbol("chizu.brand/Payload");static Broadcast=Symbol("chizu.brand/Broadcast");static Multicast=Symbol("chizu.brand/Multicast");static Action=Symbol("chizu.brand/Action");static Channel=Symbol("chizu.brand/Channel");static Node=Symbol("chizu.action.lifecycle/Node");static Cache=Symbol("chizu.brand/Cache")}function a(e){const t=Symbol(`chizu.action.lifecycle/${e}`),n=function(e){return{[i.Action]:t,[i.Payload]:void 0,[i.Channel]:e,channel:e}};return Object.defineProperty(n,i.Action,{value:t,enumerable:!1}),Object.defineProperty(n,i.Payload,{value:void 0,enumerable:!1}),n}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)}}class h extends Error{name="DisallowedError";constructor(e="Disallowed"){super(e)}}const p={actionPrefix:"chizu.action/",broadcastActionPrefix:"chizu.action/broadcast/",multicastActionPrefix:"chizu.action/multicast/",channelPrefix:"chizu.channel/",cachePrefix:"chizu.cache/",lifecyclePrefix:"chizu.action.lifecycle/"};function m(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})})}async function b(e,t,n){if(t?.aborted)throw new d;for(;;){if(await n())return;await m(e,t)}}function y(e){return e?Boolean(e&&"symbol"!=typeof e):Symbol(`pk.${Date.now()}.${crypto.randomUUID()}`)}const v=Object.freeze(Object.defineProperty({__proto__:null,config:p,pk:y,poll:b,sleep:m,"ζ":m,"κ":y,"π":b},Symbol.toStringTag,{value:"Module"})),g=e=>"symbol"==typeof e;function w(e){return t.G.isString(e)||g(e)?e:(t.G.isObject(e)||t.G.isFunction(e))&&i.Action in e?e[i.Action]:e}function x(e){if(t.G.isString(e))return e.startsWith(p.broadcastActionPrefix);if(g(e))return e.description?.startsWith(p.broadcastActionPrefix)??!1;if(t.G.isObject(e)||t.G.isFunction(e)){if(i.Broadcast in e&&e[i.Broadcast])return!0;if(i.Action in e){const t=e[i.Action];return t.description?.startsWith(p.broadcastActionPrefix)??!1}}return!1}function j(e){const n=w(e),r=t.G.isString(n)?n:n.description??"";return r.startsWith(p.actionPrefix)&&r.slice(r.lastIndexOf("/")+1)||"unknown"}function P(e){return t.G.isObject(e)&&i.Channel in e&&"channel"in e}function S(e){const t=w(e),n=g(t)?t.description??"":t;return n.startsWith(p.lifecyclePrefix)&&n.slice(p.lifecyclePrefix.length)||null}function E(e){if(t.G.isString(e))return e.startsWith(p.multicastActionPrefix);if(g(e))return e.description?.startsWith(p.multicastActionPrefix)??!1;if(t.G.isObject(e)||t.G.isFunction(e)){if(i.Multicast in e&&e[i.Multicast])return!0;if(i.Action in e){const t=e[i.Action];return t.description?.startsWith(p.multicastActionPrefix)??!1}}return!1}function O(e){const t=function(e){return e[i.Cache]}(e),n=function(e){return"channel"in e}(e)&&(r=e.channel)?[...Object.keys(r)].toSorted().map(e=>`${e}=${String(r[e])}`).join("&"):"";var r;return`${String(t)}:${n}`}function A(e){if(e instanceof Error){if("TimeoutError"===e.name)return f.Timedout;if("AbortError"===e.name)return f.Supplanted;if("DisallowedError"===e.name)return f.Disallowed}return f.Errored}function C(e){return e instanceof Error?e:new Error(String(e))}const M=r.createContext(void 0);let k=(e=21)=>{let t="",n=crypto.getRandomValues(new Uint8Array(e|=0));for(;e--;)t+="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"[63&n[e]];return t};var G=(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))(G||{}),_=(e=>(e[e.Produce=0]="Produce",e[e.Hydrate=1]="Hydrate",e))(_||{}),R=(e=>(e.Property="property",e.Process="process",e.Value="value",e.Operation="operation",e))(R||{});class N{[o.immerable]=!0;static keys=new Set(Object.values(R));property=null;process=null;value;operation;constructor(e,t){this.value=e,this.operation=t}assign(e,t){const n=new N(this.value,this.operation);return n.property=e,n.process=t,n}}class U{static immer=(()=>{o.enablePatches();const e=new o.Immer;return e.setAutoFreeze(!1),e})();static tag="κ";static id=k}function L(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)||$(e))return e;if(t.G.isArray(e))return e.map(e=>z(e));if(t.G.isObject(e)&&D(e)){const t=Object.entries(e).map(([e,t])=>[e,z(t)]);return{...Object.fromEntries(t),[U.tag]:e[U.tag]??U.id()}}return e}function T(e){if(Array.isArray(e))return e.filter(e=>U.tag in e).map(e=>e[U.tag]??"").join(",");const t=e[U.tag];if(t)return t;try{return JSON.stringify(e)}catch{return`[unserializable:${typeof e}]`}}function D(e){const t=Object.getPrototypeOf(e);return t===Object.prototype||null===t}function $(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 B(e,n,r,o,c,s){return function i(a,u=n.path){if(a instanceof N){const n=L(r,u.join("."));if(Object.entries(a).filter(([e,t])=>!N.keys.has(e)&&t instanceof N).forEach(([e,t])=>i(t,u.concat(e))),$(a.value)){if(e===_.Hydrate)return a.value;const i=u.slice(0,-1),l=i.length>0?L(r,i.join(".")):r;return t.G.isNullable(l)||W(l,a,u.at(-1),o,c,s),n??a.value}if(e===_.Hydrate){const e=z(i(a.value,u));return W(e,a,null,o,c,s),e}const l=n??z(a.value);return W(l,a,null,o,c,s),t.G.isNullable(n)?l:(i(a.value,u),n)}if(t.G.isArray(a))return a.map((e,t)=>i(e,u.concat(t)));if(t.G.isObject(a)&&!D(a))return a;if(t.G.isObject(a)){const t=Object.entries(a).map(([e,t])=>[e,i(t,u.concat(e))]),n=Object.fromEntries(t);if(e===_.Hydrate){const e=z(n);return Object.entries(a).forEach(([t,n])=>{n instanceof N&&$(n.value)&&W(e,n,t,o,c,s)}),e}return n}return a}(n.value)}function W(e,t,n,r,o,c){const s=c(e),i=o.get(s)??[];o.set(s,[t.assign(n,r),...i])}class F{#e={};#t;#n=new Map;#r=new Set;#o=!1;constructor(e=T){this.#t=e}static pk(){return k()}static"κ"=F.pk;annotate(e,t){return new N(t,e)}"δ"=this.annotate;get model(){return this.#e}get inspect(){return function(e,n,r,o,c){function s(o){const c=o.at(-1),s=L(e(),o),i=o.slice(0,-1),a=t.A.isNotEmpty(i)?L(e(),i):e();return[...t.G.isObject(s)||t.G.isArray(s)?n.get(r(s))?.filter(e=>t.G.isNullable(e.property))??[]:[],...t.G.isObject(a)?n.get(r(a))?.filter(e=>e.property===c)??[]:[]]}return function n(r){return new Proxy(()=>{},{get:(i,a)=>"pending"===a?()=>!t.A.isEmpty(s(r)):"remaining"===a?()=>t.A.length(s(r)):"box"===a?()=>({value:L(e(),r),inspect:n(r)}):"is"===a?e=>s(r).some(t=>0!==(t.operation&e)):"draft"===a?()=>t.A.head(s(r))?.value??L(e(),r):"settled"===a?()=>new Promise(n=>{if(t.A.isEmpty(s(r)))return n(L(e(),r));const i=()=>{t.A.isEmpty(s(r))&&(c(i),n(L(e(),r)))};o(i)}):n([...r,String(a)])})}([])}(()=>this.#e,this.#n,this.#t,e=>this.#r.add(e),e=>this.#r.delete(e))}hydrate(e){return this.#o=!0,this.#c(_.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]=U.immer.produceWithPatches(this.#e,t);return this.#e=r.reduce((t,r)=>U.immer.applyPatches(t,[{...r,value:B(e,r,t,n,this.#n,this.#t)}]),this.#e),this.#e=z(this.#e),this.#s(),n}prune(e){this.#n.forEach((n,r)=>{const o=n.filter(t=>t.process!==e);t.A.isEmpty(o)?this.#n.delete(r):this.#n.set(r,o)}),this.#s()}#s(){this.#r.forEach(e=>e())}observe(e){const t=()=>e(this.#e);return this.#r.add(t),()=>this.#r.delete(t)}}const H=new F;function I(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var q,V={exports:{}},J=(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,s){if("function"!=typeof r)throw new TypeError("The listener must be a function");var i=new o(r,c||e,s),a=n?n+t:t;return e._events[a]?e._events[a].fn?e._events[a]=[e._events[a],i]:e._events[a].push(i):(e._events[a]=i,e._eventsCount++),e}function s(e,t){0===--e._eventsCount?e._events=new r:delete e._events[t]}function i(){this._events=new r,this._eventsCount=0}Object.create&&(r.prototype=Object.create(null),(new r).__proto__||(n=!1)),i.prototype.eventNames=function(){var e,r,o=[];if(0===this._eventsCount)return o;for(r in e=this._events)t.call(e,r)&&o.push(n?r.slice(1):r);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(e)):o},i.prototype.listeners=function(e){var t=this._events[n?n+e:e];if(!t)return[];if(t.fn)return[t.fn];for(var r=0,o=t.length,c=new Array(o);r<o;r++)c[r]=t[r].fn;return c},i.prototype.listenerCount=function(e){var t=this._events[n?n+e:e];return t?t.fn?1:t.length:0},i.prototype.emit=function(e,t,r,o,c,s){var i=n?n+e:e;if(!this._events[i])return!1;var a,u,l=this._events[i],f=arguments.length;if(l.fn){switch(l.once&&this.removeListener(e,l.fn,void 0,!0),f){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,t),!0;case 3:return l.fn.call(l.context,t,r),!0;case 4:return l.fn.call(l.context,t,r,o),!0;case 5:return l.fn.call(l.context,t,r,o,c),!0;case 6:return l.fn.call(l.context,t,r,o,c,s),!0}for(u=1,a=new Array(f-1);u<f;u++)a[u-1]=arguments[u];l.fn.apply(l.context,a)}else{var d,h=l.length;for(u=0;u<h;u++)switch(l[u].once&&this.removeListener(e,l[u].fn,void 0,!0),f){case 1:l[u].fn.call(l[u].context);break;case 2:l[u].fn.call(l[u].context,t);break;case 3:l[u].fn.call(l[u].context,t,r);break;case 4:l[u].fn.call(l[u].context,t,r,o);break;default:if(!a)for(d=1,a=new Array(f-1);d<f;d++)a[d-1]=arguments[d];l[u].fn.apply(l[u].context,a)}}return!0},i.prototype.on=function(e,t,n){return c(this,e,t,n,!1)},i.prototype.once=function(e,t,n){return c(this,e,t,n,!0)},i.prototype.removeListener=function(e,t,r,o){var c=n?n+e:e;if(!this._events[c])return this;if(!t)return s(this,c),this;var i=this._events[c];if(i.fn)i.fn!==t||o&&!i.once||r&&i.context!==r||s(this,c);else{for(var a=0,u=[],l=i.length;a<l;a++)(i[a].fn!==t||o&&!i[a].once||r&&i[a].context!==r)&&u.push(i[a]);u.length?this._events[c]=1===u.length?u[0]:u:s(this,c)}return this},i.prototype.removeAllListeners=function(e){var t;return e?this._events[t=n?n+e:e]&&s(this,t):(this._events=new r,this._eventsCount=0),this},i.prototype.off=i.prototype.removeListener,i.prototype.addListener=i.prototype.on,i.prefixed=n,i.EventEmitter=i,e.exports=i}(V)),V.exports);const K=I(J);class Q extends K{cache=new Map;emit(e,...t){return this.cache.set(e,t[0]),super.emit(e,...t)}setCache(e,t){this.cache.set(e,t)}getCached(e){return this.cache.get(e)}}const X=s.createContext(new Q);function Y(){return s.useContext(X)}function Z({children:e}){const t=s.useMemo(()=>new Q,[]);return n.jsx(X.Provider,{value:t,children:e})}const ee=s.createContext(new Map);function te({children:e}){const t=s.useMemo(()=>new Map,[]);return n.jsx(ee.Provider,{value:t,children:e})}const ne=s.createContext(new Set);function re({children:e}){const t=s.useMemo(()=>new Set,[]);return n.jsx(ne.Provider,{value:t,children:e})}const oe=s.createContext({mode:"allow-all",actions:new Set});function ce({children:e}){const t=s.useMemo(()=>({mode:"allow-all",actions:new Set}),[]);return n.jsx(oe.Provider,{value:t,children:e})}const se=s.createContext(null);function ie(){return s.useContext(se)}function ae(e,t){return e?.get(t)??null}function ue({name:e,children:t}){const r=ie(),o=s.useMemo(()=>({name:e,emitter:new Q}),[]),c=s.useMemo(()=>{const t=new Map(r??[]);return t.set(e,o),t},[r,e,o]);return n.jsx(se.Provider,{value:c,children:t})}function le(e,t,...n){e instanceof Q&&e.setCache(t,n[0]);const r=e.listeners(t);return 0===r.length?Promise.resolve():Promise.all(r.map(e=>Promise.resolve(e(...n)))).then(()=>{})}function fe(e,t){for(const n of e.keys())if(S(n)===t)return n;return null}function de(){const[,e]=s.useReducer(e=>e+1,0);return e}const he=s.createContext(new Map);function pe({action:e,renderer:n}){const r=Y(),o=s.useContext(he),c=de(),i=s.useMemo(()=>{const t=o.get(e);if(t)return t;const n={state:new F,listeners:new Set};return o.set(e,n),n},[e,o]);s.useLayoutEffect(()=>{function t(e){i.state.hydrate({value:e}),i.listeners.forEach(e=>e())}return i.listeners.add(c),r.on(e,t),()=>{i.listeners.delete(c),r.off(e,t)}},[e,r,i]);const a=i.state.model?.value;return t.G.isNullable(a)?null:n(a,i.state.inspect.value)}e.Action=(e,t=u.Unicast)=>{const n=t===u.Broadcast?Symbol(`${p.broadcastActionPrefix}${e}`):t===u.Multicast?Symbol(`${p.multicastActionPrefix}${e}`):Symbol(`${p.actionPrefix}${e}`),r=function(e){return{[i.Action]:n,[i.Payload]:void 0,[i.Channel]:e,channel:e}};return Object.defineProperty(r,i.Action,{value:n,enumerable:!1}),Object.defineProperty(r,i.Payload,{value:void 0,enumerable:!1}),t===u.Broadcast&&Object.defineProperty(r,i.Broadcast,{value:!0,enumerable:!1}),t===u.Multicast&&Object.defineProperty(r,i.Multicast,{value:!0,enumerable:!1}),r},e.Boundary=function({children:e}){return n.jsx(Z,{children:n.jsx(te,{children:n.jsx(ce,{children:n.jsx(re,{children:e})})})})},e.DisallowedError=h,e.Distribution=u,e.Entry=function(){const e=Symbol("chizu.cache/Entry"),t=function(t){return{[i.Cache]:e,channel:t}};return Object.defineProperty(t,i.Cache,{value:e,enumerable:!1}),t},e.Error=function({handler:e,children:t}){return n.jsx(M.Provider,{value:e,children:t})},e.Lifecycle=class{static Mount(){return a("Mount")}static Unmount(){return a("Unmount")}static Error(){return a("Error")}static Update(){return a("Update")}static Node(){return a("Node")}},e.Op=G,e.Operation=G,e.Reason=f,e.Regulators=ce,e.Scope=ue,e.State=F,e.With=function(e){return(t,n)=>{t.actions.produce(t=>{t.model[e]=n})}},e.annotate=function(e,t){return H.annotate(e,t)},e.useActions=function(...e){const n=t.G.isUndefined(e[0])||t.G.isFunction(e[0])?{}:e[0],o=t.G.isFunction(e[0])?e[0]:e[1]??(()=>({})),c=Y(),i=ie(),a=r.useContext(M),u=s.useContext(ne),d=s.useContext(ee),p=s.useContext(oe),m=de(),b=s.useRef(!1),y=s.useRef(null),v=s.useRef(new F),g=s.useRef({features:null,nodes:null});function S(){null===g.current.features&&null===g.current.nodes||(v.current.model.meta={...null!==g.current.features?{features:g.current.features}:{},...null!==g.current.nodes?{nodes:g.current.nodes}:{}})}if(!b.current){b.current=!0;const e=n,t=e.meta;t?.features&&(g.current.features=t.features),t?.nodes&&(g.current.nodes=t.nodes);const{meta:r,...o}=e;y.current=v.current.hydrate(o),S()}const[k,G]=s.useState(()=>v.current.model),_=function(e){const t=s.useRef(e);return s.useLayoutEffect(()=>{t.current=e},[e]),s.useMemo(()=>{return n=t,Object.keys(e).reduce((e,t)=>(Object.defineProperty(e,t,{get:()=>n.current[t],enumerable:!0}),e),{});var n},[e])}(o()),R=s.useMemo(()=>new K,[]),N=s.useRef({handlers:new Map});N.current.handlers=new Map;const U=function(){const e=s.useRef(new Set),t=s.useRef(new Set);return s.useMemo(()=>({broadcast:e.current,multicast:t.current}),[])}(),L=s.useRef(l.Mounting),z=function(){const e=s.useRef({}),t=s.useRef(new Map),n=s.useRef(new Map);return s.useMemo(()=>({refs:e,pending:t,emitted:n}),[])}(),T=s.useRef(new Set),D=s.useRef(0),$=s.useCallback((e,t,n)=>{const r=new AbortController,o={controller:r,action:e,payload:t};return u.add(o),T.current.add(o),{model:v.current.model,get phase(){return L.current},task:o,data:_,tasks:u,get meta(){return{nodes:z.refs.current,features:g.current.features??{}}},regulator:{disallow(...e){if(p.actions.clear(),0===e.length)p.mode="disallow-all";else{p.mode="disallow-matching";for(const t of e)p.actions.add(w(t))}},allow(...e){if(p.actions.clear(),0===e.length)p.mode="allow-all";else{p.mode="allow-matching";for(const t of e)p.actions.add(w(t))}}},actions:{produce(e){if(r.signal.aborted)return;const t=v.current.produce(t=>{e({model:t,inspect:v.current.inspect})});S(),G(v.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 Promise.resolve();const o=w(e),s=P(e)?e.channel:void 0;if(E(e)&&n?.scope){const e=ae(i,n.scope);return e?le(e.emitter,o,t,s):Promise.resolve()}return le(x(e)?c:R,o,t,s)},annotate:(e,t)=>v.current.annotate(e,t),async cacheable(e,t,n){if(r.signal.aborted)return{data:null};const o=O(e),c=d.get(o);if(c&&Date.now()<c.expiry)return{data:c.value};const s=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 s.ok?(d.set(o,{value:s.value,expiry:Date.now()+t}),{data:s.value}):{data:null}},invalidate(e){d.delete(O(e))},features:{on(e){r.signal.aborted||(g.current.features={...g.current.features,[e]:!0},S(),G(v.current.model),y.current&&(n.processes.add(y.current),y.current=null))},off(e){r.signal.aborted||(g.current.features={...g.current.features,[e]:!1},S(),G(v.current.model),y.current&&(n.processes.add(y.current),y.current=null))},invert(e){if(r.signal.aborted)return;const t=g.current.features?.[e]??!1;g.current.features={...g.current.features,[e]:!t},S(),G(v.current.model),y.current&&(n.processes.add(y.current),y.current=null)}},async read(e,t){if(r.signal.aborted)return null;const n=w(e),o=E(e)&&t?.scope?ae(i,t.scope)?.emitter??null:c;if(!o)return null;if(void 0===o.getCached(n))return null;const s=j(e),a="unknown"!==s?s[0].toLowerCase()+s.slice(1):null;if(a){const e=v.current.inspect[a];e?.pending?.()&&await new Promise((t,n)=>{if(r.signal.aborted)return void n(r.signal.reason);const o=()=>n(r.signal.reason);r.signal.addEventListener("abort",o,{once:!0}),e.settled().then(()=>{r.signal.removeEventListener("abort",o),t()})})}return o.getCached(n)??null},peek(e,t){if(r.signal.aborted)return null;const n=w(e),o=E(e)&&t?.scope?ae(i,t.scope)?.emitter??null:c;return o?o.getCached(n)??null:null}}}},[k]);s.useLayoutEffect(()=>{function e(e,n,r){return function(o,c){if(!function(e,t){switch(t.mode){case"allow-all":return!0;case"disallow-all":return!1;case"disallow-matching":return!t.actions.has(e);case"allow-matching":return t.actions.has(e)}}(e,p)){const t=fe(N.current.handlers,"Error"),n=null!==t,r={reason:f.Disallowed,error:new h,action:j(e),handled:n,tasks:u};return a?.(r),void(n&&t&&R.emit(t,r))}const s=r();if(t.G.isNotNullable(c)&&t.G.isNotNullable(s)&&!function(e,t){for(const n of Object.keys(e))if(t[n]!==e[n])return!1;return!0}(c,s))return;const i={processes:new Set},l=Promise.withResolvers(),d=$(e,o,i);function b(t){const n=fe(N.current.handlers,"Error"),r=null!==n,o={reason:A(t),error:C(t),action:j(e),handled:r,tasks:u};a?.(o),r&&n&&R.emit(n,o)}function y(){for(const e of u)if(e===d.task){u.delete(e),T.current.delete(e);break}i.processes.forEach(e=>v.current.prune(e)),i.processes.size>0&&m(),l.resolve()}let g;try{g=n(d,o)}catch(w){return b(w),void y()}if(!function(e){if(!e||"object"!=typeof e)return!1;const t=Object.prototype.toString.call(e);return"[object Generator]"===t||"[object AsyncGenerator]"===t}(g))return Promise.resolve(g).catch(b).finally(y),l.promise;(async()=>{for await(const e of g);})().catch(b).finally(y)}}D.current++;const n=new Set;return N.current.handlers.forEach((t,r)=>{for(const{getChannel:o,handler:s}of t){const t=e(r,s,o);if(E(r)){if(i)for(const e of i.values()){const o=e.emitter;o.on(r,t),n.add(()=>o.off(r,t))}R.on(r,t),U.multicast.add(r),n.add(()=>R.off(r,t))}else x(r)?(c.on(r,t),R.on(r,t),U.broadcast.add(r),n.add(()=>{c.off(r,t),R.off(r,t)})):(R.on(r,t),n.add(()=>R.off(r,t)))}}),()=>{const e=++D.current,t=new Set(n);queueMicrotask(()=>{if(D.current!==e){for(const e of t)e();return}for(const e of T.current)e.controller.abort(),u.delete(e);T.current.clear(),L.current=l.Unmounting;const n=fe(N.current.handlers,"Unmount");n&&R.emit(n),L.current=l.Unmounted;for(const e of t)e()})}},[R]),s.useLayoutEffect(()=>{const e=fe(N.current.handlers,"Node");let t=!1;for(const[n,r]of z.pending.current)if(z.emitted.current.get(n)!==r){if(z.emitted.current.set(n,r),null!==g.current.nodes){const e={...g.current.nodes};e[n]=r,g.current.nodes=e,t=!0}e&&R.emit(e,r,{Name:n})}t&&(S(),G(v.current.model)),z.pending.current.clear()}),function({unicast:e,broadcast:n,dispatchers:r,scope:o,phase:c,data:i,handlers:a}){const u=s.useRef(null);s.useLayoutEffect(()=>{if(c.current!==l.Mounting)return;const s=fe(a,"Mount");s&&e.emit(s),r.broadcast.forEach(r=>{const o=n.getCached(r);t.G.isNullable(o)||e.emit(r,o)}),o&&r.multicast.forEach(n=>{for(const r of o.values()){const o=r.emitter.getCached(n);t.G.isNullable(o)||e.emit(n,o)}}),c.current=l.Mounted},[]),s.useLayoutEffect(()=>{if(t.G.isNotNullable(u.current)){const n=function(e,t){return Object.keys(t).reduce((n,r)=>e[r]!==t[r]?{...n,[r]:t[r]}:n,{})}(u.current,i);if(t.A.isNotEmpty(Object.keys(n))){const t=fe(a,"Update");t&&e.emit(t,n)}}u.current=i},[i,e])}({unicast:R,broadcast:c,dispatchers:U,scope:i,phase:L,data:o(),handlers:N.current.handlers});const B=s.useMemo(()=>[k,{dispatch(e,t,n){const r=w(e),o=P(e)?e.channel:void 0;if(E(e)&&n?.scope){const e=ae(i,n.scope);return e?le(e.emitter,r,t,o):Promise.resolve()}return le(x(e)?c:R,r,t,o)},get inspect(){return v.current.inspect},get meta(){return{nodes:z.refs.current,features:g.current.features??{}}},node(e,t){z.refs.current[e]=t,z.pending.current.set(e,t)},features:{on(e){g.current.features={...g.current.features,[e]:!0},S(),G(v.current.model)},off(e){g.current.features={...g.current.features,[e]:!1},S(),G(v.current.model)},invert(e){const t=g.current.features?.[e]??!1;g.current.features={...g.current.features,[e]:!t},S(),G(v.current.model)}},stream:(e,t)=>s.createElement(pe,{action:w(e),renderer:t})}],[k,R]);return B.useAction=(e,t)=>{!function(e,t,n){const r=s.useRef(n);s.useLayoutEffect(()=>{r.current=n});const o=s.useRef(t);s.useLayoutEffect(()=>{o.current=t});const c=s.useCallback((e,t)=>r.current(e,t),[]),i=s.useCallback(()=>P(o.current)?o.current.channel:void 0,[]),a=w(t),u=e.current.handlers.get(a)??new Set;0===u.size&&e.current.handlers.set(a,u),u.add({getChannel:i,handler:c})}(N,e,t)},B},e.utils=v,e.withScope=function(e,t){const r=`Scoped${t.displayName||t.name||"Component"}`;return{[r]:r=>n.jsx(ue,{name:e,children:n.jsx(t,{...r})})}[r]},Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})},"object"==typeof exports&&"undefined"!=typeof module?factory(exports,require("@mobily/ts-belt"),require("react/jsx-runtime"),require("react"),require("immer")):"function"==typeof define&&define.amd?define(["exports","@mobily/ts-belt","react/jsx-runtime","react","immer"],factory):factory((global="undefined"!=typeof globalThis?globalThis:global||self).Chizu={},global.TsBelt,global.jsxRuntime,global.React,global.Immer);
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Data } from './types.ts';
|
|
2
|
-
import { Model, Props, Actions, UseActions } from '../types/index.ts';
|
|
2
|
+
import { Model, Props, Actions, UseActions, ValidateFeatures, NullableNodes } from '../types/index.ts';
|
|
3
3
|
export { With } from './utils.ts';
|
|
4
4
|
/**
|
|
5
5
|
* A hook for managing state with actions.
|
|
@@ -40,4 +40,4 @@ export { With } from './utils.ts';
|
|
|
40
40
|
* ```
|
|
41
41
|
*/
|
|
42
42
|
export declare function useActions<_M extends void = void, A extends Actions | void = void, D extends Props = Props>(getData?: Data<D>): UseActions<void, A, D>;
|
|
43
|
-
export declare function useActions<M extends Model, A extends Actions | void = void, D extends Props = Props>(initialModel: M
|
|
43
|
+
export declare function useActions<M extends Model, A extends Actions | void = void, D extends Props = Props>(initialModel: NullableNodes<M> & ValidateFeatures<M>, getData?: Data<D>): UseActions<M, A, D>;
|
package/dist/hooks/types.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { default as EventEmitter } from 'eventemitter3';
|
|
2
2
|
import { RefObject } from 'react';
|
|
3
|
-
import { Model, HandlerContext, Actions, Props, Tasks, ActionId, Phase, Filter,
|
|
3
|
+
import { Model, HandlerContext, Actions, Props, Tasks, ActionId, Phase, Filter, ExtractNodes } from '../types/index.ts';
|
|
4
4
|
import { BroadcastEmitter } from '../boundary/components/broadcast/utils.ts';
|
|
5
5
|
import { ScopeContext } from '../boundary/components/scope/types.ts';
|
|
6
6
|
/**
|
|
@@ -12,12 +12,12 @@ import { ScopeContext } from '../boundary/components/scope/types.ts';
|
|
|
12
12
|
export type References<M extends Model | void> = {
|
|
13
13
|
/** Ref containing captured DOM nodes by name */
|
|
14
14
|
refs: RefObject<{
|
|
15
|
-
[K in keyof
|
|
15
|
+
[K in keyof ExtractNodes<M>]: ExtractNodes<M>[K] | null;
|
|
16
16
|
}>;
|
|
17
17
|
/** Ref containing pending node captures to be processed after render */
|
|
18
|
-
pending: RefObject<Map<keyof
|
|
18
|
+
pending: RefObject<Map<keyof ExtractNodes<M>, ExtractNodes<M>[keyof ExtractNodes<M>] | null>>;
|
|
19
19
|
/** Ref containing last emitted node values to detect true changes */
|
|
20
|
-
emitted: RefObject<Map<keyof
|
|
20
|
+
emitted: RefObject<Map<keyof ExtractNodes<M>, ExtractNodes<M>[keyof ExtractNodes<M>] | null>>;
|
|
21
21
|
};
|
|
22
22
|
/**
|
|
23
23
|
* Function signature for action handlers registered via `useAction`.
|
package/dist/hooks/utils.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RefObject } from 'react';
|
|
2
2
|
import { Props, Model, Actions, Filter, ActionId, HandlerPayload, ChanneledAction, HandlerContext } from '../types/index.ts';
|
|
3
|
+
import { default as EventEmitter } from 'eventemitter3';
|
|
3
4
|
import { Dispatchers, LifecycleConfig, References, Scope } from './types.ts';
|
|
4
5
|
import { isChanneledAction, getActionSymbol } from '../action/index.ts';
|
|
5
6
|
import * as React from "react";
|
|
@@ -9,9 +10,21 @@ import * as React from "react";
|
|
|
9
10
|
*/
|
|
10
11
|
export declare function withGetters<P extends Props>(a: P, b: RefObject<P>): P;
|
|
11
12
|
/**
|
|
12
|
-
* Checks if the given result is a generator or async generator.
|
|
13
|
+
* Checks if the given result is a generator or async generator object.
|
|
14
|
+
* Uses `Object.prototype.toString` which reliably returns
|
|
15
|
+
* `"[object Generator]"` or `"[object AsyncGenerator]"` regardless of
|
|
16
|
+
* the generator function's name.
|
|
13
17
|
*/
|
|
14
18
|
export declare function isGenerator(result: unknown): result is Generator | AsyncGenerator;
|
|
19
|
+
/**
|
|
20
|
+
* Invokes all listeners for an event and returns a promise that resolves
|
|
21
|
+
* when every handler has settled. For {@link BroadcastEmitter} instances the
|
|
22
|
+
* payload is cached before listeners fire so late-mounting components still
|
|
23
|
+
* see the latest value.
|
|
24
|
+
*
|
|
25
|
+
* @internal
|
|
26
|
+
*/
|
|
27
|
+
export declare function emitAsync(emitter: EventEmitter, event: string | symbol, ...args: unknown[]): Promise<void>;
|
|
15
28
|
/**
|
|
16
29
|
* Emits lifecycle events for component mount and DOM attachment.
|
|
17
30
|
* Also invokes broadcast action handlers with cached values on mount.
|
package/dist/index.d.ts
CHANGED
|
@@ -11,5 +11,5 @@ export { useActions, With } from './hooks/index.ts';
|
|
|
11
11
|
export * as utils from './utils/index.ts';
|
|
12
12
|
export type { Box } from 'immertation';
|
|
13
13
|
export type { Fault, Catcher } from './error/index.tsx';
|
|
14
|
-
export type { Pk, Task, Tasks, Handlers } from './types/index.ts';
|
|
14
|
+
export type { Pk, Task, Tasks, Handlers, Meta } from './types/index.ts';
|
|
15
15
|
export type { Regulator } from './boundary/components/regulators/index.tsx';
|
package/dist/types/index.d.ts
CHANGED
|
@@ -421,22 +421,106 @@ type AssertSync<F> = IsAsync<F> extends true ? "Error: async functions are not a
|
|
|
421
421
|
export type Props = Record<string, unknown>;
|
|
422
422
|
/**
|
|
423
423
|
* Extracts the nodes type from a Model.
|
|
424
|
-
* If the model has a `nodes` property, returns its type.
|
|
424
|
+
* If the model has a `meta.nodes` property, returns its type.
|
|
425
425
|
* Otherwise returns an empty record.
|
|
426
426
|
*
|
|
427
427
|
* @example
|
|
428
428
|
* ```ts
|
|
429
429
|
* type Model = {
|
|
430
430
|
* count: number;
|
|
431
|
-
* nodes: {
|
|
431
|
+
* meta: { nodes: { container: HTMLButtonElement | null } };
|
|
432
432
|
* };
|
|
433
433
|
*
|
|
434
|
-
* type N =
|
|
434
|
+
* type N = ExtractNodes<Model>; // { container: HTMLButtonElement | null }
|
|
435
435
|
* ```
|
|
436
436
|
*/
|
|
437
|
-
export type
|
|
438
|
-
|
|
439
|
-
|
|
437
|
+
export type ExtractNodes<M> = M extends {
|
|
438
|
+
meta: {
|
|
439
|
+
nodes: infer N extends Record<string, unknown>;
|
|
440
|
+
};
|
|
441
|
+
} ? N : Record<never, unknown>;
|
|
442
|
+
/**
|
|
443
|
+
* Transforms `meta.nodes` values to include `| null`, reflecting
|
|
444
|
+
* that node refs are initially `null` until a DOM element is captured.
|
|
445
|
+
* Models without `meta.nodes` pass through unchanged.
|
|
446
|
+
*
|
|
447
|
+
* @internal
|
|
448
|
+
*/
|
|
449
|
+
export type NullableNodes<M> = M extends {
|
|
450
|
+
meta: infer Meta & {
|
|
451
|
+
nodes: infer N extends Record<string, unknown>;
|
|
452
|
+
};
|
|
453
|
+
} ? Omit<M, "meta"> & {
|
|
454
|
+
meta: Omit<Meta, "nodes"> & {
|
|
455
|
+
nodes: {
|
|
456
|
+
[K in keyof N]: N[K] | null;
|
|
457
|
+
};
|
|
458
|
+
};
|
|
459
|
+
} : M;
|
|
460
|
+
/**
|
|
461
|
+
* Extracts the `meta.features` property from a Model type.
|
|
462
|
+
* If the model has a `meta.features` property whose values are all booleans,
|
|
463
|
+
* returns its type. Otherwise returns an empty record, making the
|
|
464
|
+
* `features` methods effectively uncallable.
|
|
465
|
+
*
|
|
466
|
+
* @example
|
|
467
|
+
* ```ts
|
|
468
|
+
* type Model = { count: number; meta: { features: { sidebar: boolean; modal: boolean } } };
|
|
469
|
+
* type F = FeatureFlags<Model>; // { sidebar: boolean; modal: boolean }
|
|
470
|
+
* ```
|
|
471
|
+
*/
|
|
472
|
+
export type FeatureFlags<M> = M extends {
|
|
473
|
+
meta: {
|
|
474
|
+
features: infer F extends Record<string, boolean>;
|
|
475
|
+
};
|
|
476
|
+
} ? F : Record<never, boolean>;
|
|
477
|
+
/**
|
|
478
|
+
* Resolves to `unknown` when the model has no `meta.features` or all
|
|
479
|
+
* feature values are booleans. Resolves to a descriptive string literal when
|
|
480
|
+
* any value is not a boolean, causing an intersection with the model type
|
|
481
|
+
* to become `never` and producing a compile-time error.
|
|
482
|
+
*
|
|
483
|
+
* @internal
|
|
484
|
+
*/
|
|
485
|
+
export type ValidateFeatures<M> = M extends {
|
|
486
|
+
meta: {
|
|
487
|
+
features: infer F;
|
|
488
|
+
};
|
|
489
|
+
} ? F extends Record<string, boolean> ? unknown : "meta.features values must all be boolean" : unknown;
|
|
490
|
+
/**
|
|
491
|
+
* Utility type for the `meta` model property. Combines optional `nodes`
|
|
492
|
+
* and `features` sub-objects into a single meta shape.
|
|
493
|
+
*
|
|
494
|
+
* - When `N` is provided, produces `{ nodes: { [K in keyof N]: N[K] | null } }`.
|
|
495
|
+
* - When `F` is provided, produces `{ features: F }`.
|
|
496
|
+
* - Pass `void` to omit either sub-object.
|
|
497
|
+
*
|
|
498
|
+
* @template N - Node type record (e.g. `{ input: HTMLInputElement }`)
|
|
499
|
+
* @template F - Feature flags record (e.g. `{ sidebar: boolean }`)
|
|
500
|
+
*
|
|
501
|
+
* @example
|
|
502
|
+
* ```ts
|
|
503
|
+
* import type { Meta } from "chizu";
|
|
504
|
+
*
|
|
505
|
+
* type Model = {
|
|
506
|
+
* count: number;
|
|
507
|
+
* meta: Meta<{ input: HTMLInputElement }, { sidebar: boolean }>;
|
|
508
|
+
* };
|
|
509
|
+
* // Equivalent to:
|
|
510
|
+
* // meta: { nodes: { input: HTMLInputElement | null }; features: { sidebar: boolean } }
|
|
511
|
+
* ```
|
|
512
|
+
*/
|
|
513
|
+
export type Meta<N extends Record<string, unknown> | void = void, F extends Record<string, boolean> | void = void> = ([N] extends [void] ? unknown : {
|
|
514
|
+
nodes: {
|
|
515
|
+
[K in keyof N]: N[K] | null;
|
|
516
|
+
};
|
|
517
|
+
}) & ([F] extends [void] ? unknown : {
|
|
518
|
+
features: F;
|
|
519
|
+
});
|
|
520
|
+
export declare namespace Meta {
|
|
521
|
+
type Nodes<N extends Record<string, unknown>> = Meta<N>;
|
|
522
|
+
type Features<F extends Record<string, boolean>> = Meta<void, F>;
|
|
523
|
+
}
|
|
440
524
|
/**
|
|
441
525
|
* Constraint type for action containers.
|
|
442
526
|
* Actions are symbols grouped in an object (typically a class with static properties).
|
|
@@ -539,18 +623,20 @@ export type HandlerContext<M extends Model | void, _AC extends Actions | void, D
|
|
|
539
623
|
*/
|
|
540
624
|
readonly tasks: ReadonlySet<Task>;
|
|
541
625
|
/**
|
|
542
|
-
*
|
|
543
|
-
* Nodes may be `null` if not yet captured or if the node was unmounted.
|
|
626
|
+
* Meta properties including captured DOM nodes and feature flags.
|
|
544
627
|
*
|
|
545
628
|
* @example
|
|
546
629
|
* ```ts
|
|
547
630
|
* actions.useAction(Actions.Focus, (context) => {
|
|
548
|
-
* context.nodes.input?.focus();
|
|
631
|
+
* context.meta.nodes.input?.focus();
|
|
549
632
|
* });
|
|
550
633
|
* ```
|
|
551
634
|
*/
|
|
552
|
-
readonly
|
|
553
|
-
|
|
635
|
+
readonly meta: {
|
|
636
|
+
readonly nodes: {
|
|
637
|
+
[K in keyof ExtractNodes<M>]: ExtractNodes<M>[K] | null;
|
|
638
|
+
};
|
|
639
|
+
readonly features: Readonly<FeatureFlags<M>>;
|
|
554
640
|
};
|
|
555
641
|
/**
|
|
556
642
|
* The regulator API for controlling which actions may be dispatched.
|
|
@@ -574,10 +660,10 @@ export type HandlerContext<M extends Model | void, _AC extends Actions | void, D
|
|
|
574
660
|
readonly regulator: Regulator;
|
|
575
661
|
readonly actions: {
|
|
576
662
|
produce<F extends (draft: {
|
|
577
|
-
model: M
|
|
663
|
+
model: Omit<M, "meta">;
|
|
578
664
|
readonly inspect: Readonly<Inspect<M>>;
|
|
579
665
|
}) => void>(ƒ: F & AssertSync<F>): void;
|
|
580
|
-
dispatch(action: ActionOrChanneled, payload?: unknown, options?: MulticastOptions): void
|
|
666
|
+
dispatch(action: ActionOrChanneled, payload?: unknown, options?: MulticastOptions): Promise<void>;
|
|
581
667
|
annotate<T>(operation: Operation, value: T): T;
|
|
582
668
|
/**
|
|
583
669
|
* Fetches a value from the cache or executes the callback if not cached / expired.
|
|
@@ -618,6 +704,21 @@ export type HandlerContext<M extends Model | void, _AC extends Actions | void, D
|
|
|
618
704
|
* ```
|
|
619
705
|
*/
|
|
620
706
|
invalidate(entry: CacheId<unknown> | ChanneledCacheId<unknown>): void;
|
|
707
|
+
/**
|
|
708
|
+
* Feature toggle methods for mutating boolean flags on the model.
|
|
709
|
+
*
|
|
710
|
+
* @example
|
|
711
|
+
* ```ts
|
|
712
|
+
* context.actions.features.on("sidebar");
|
|
713
|
+
* context.actions.features.off("sidebar");
|
|
714
|
+
* context.actions.features.invert("sidebar");
|
|
715
|
+
* ```
|
|
716
|
+
*/
|
|
717
|
+
features: {
|
|
718
|
+
on<K extends keyof FeatureFlags<M>>(name: K): void;
|
|
719
|
+
off<K extends keyof FeatureFlags<M>>(name: K): void;
|
|
720
|
+
invert<K extends keyof FeatureFlags<M>>(name: K): void;
|
|
721
|
+
};
|
|
621
722
|
/**
|
|
622
723
|
* Reads the latest broadcast or multicast value, waiting for annotations to settle.
|
|
623
724
|
*
|
|
@@ -748,7 +849,7 @@ export type Handlers<M extends Model | void, AC extends Actions | void, D extend
|
|
|
748
849
|
[K in OwnKeys<AC>]: OwnKeys<AC[K]> extends never ? (context: HandlerContext<M, AC, D>, ...args: [Payload<AC[K] & HandlerPayload<unknown>>] extends [never] ? [] : [payload: Payload<AC[K] & HandlerPayload<unknown>>]) => void | Promise<void> | AsyncGenerator | Generator : Handlers<M, AC[K] & Actions, D>;
|
|
749
850
|
};
|
|
750
851
|
export type UseActions<M extends Model | void, AC extends Actions | void, D extends Props = Props> = [
|
|
751
|
-
Readonly<M
|
|
852
|
+
Readonly<NullableNodes<M>>,
|
|
752
853
|
{
|
|
753
854
|
/**
|
|
754
855
|
* Dispatches an action with an optional payload.
|
|
@@ -762,45 +863,38 @@ export type UseActions<M extends Model | void, AC extends Actions | void, D exte
|
|
|
762
863
|
* @param payload - The payload to send with the action
|
|
763
864
|
* @param options - For multicast actions, must include `{ scope: "ScopeName" }`
|
|
764
865
|
*/
|
|
765
|
-
dispatch<P>(action: HandlerPayload<P>, payload?: P, options?: MulticastOptions): void
|
|
766
|
-
dispatch<P>(action: BroadcastPayload<P>, payload?: P, options?: MulticastOptions): void
|
|
767
|
-
dispatch<P>(action: MulticastPayload<P>, payload: P, options: MulticastOptions): void
|
|
768
|
-
dispatch<P, C extends Filter>(action: ChanneledAction<P, C>, payload?: P, options?: MulticastOptions): void
|
|
866
|
+
dispatch<P>(action: HandlerPayload<P>, payload?: P, options?: MulticastOptions): Promise<void>;
|
|
867
|
+
dispatch<P>(action: BroadcastPayload<P>, payload?: P, options?: MulticastOptions): Promise<void>;
|
|
868
|
+
dispatch<P>(action: MulticastPayload<P>, payload: P, options: MulticastOptions): Promise<void>;
|
|
869
|
+
dispatch<P, C extends Filter>(action: ChanneledAction<P, C>, payload?: P, options?: MulticastOptions): Promise<void>;
|
|
769
870
|
inspect: Inspect<M>;
|
|
770
871
|
/**
|
|
771
|
-
*
|
|
772
|
-
* Nodes may be `null` if not yet captured or if the node was unmounted.
|
|
872
|
+
* Meta properties including captured DOM nodes and feature flags.
|
|
773
873
|
*
|
|
774
874
|
* @example
|
|
775
875
|
* ```tsx
|
|
776
|
-
*
|
|
777
|
-
*
|
|
778
|
-
* nodes: { input: HTMLInputElement };
|
|
779
|
-
* };
|
|
780
|
-
* const [model, actions] = useActions<Model, typeof Actions>(model);
|
|
781
|
-
*
|
|
782
|
-
* // Access captured nodes
|
|
783
|
-
* actions.nodes.input?.focus();
|
|
876
|
+
* actions.meta.nodes.input?.focus();
|
|
877
|
+
* actions.meta.features.sidebar; // boolean
|
|
784
878
|
* ```
|
|
785
879
|
*/
|
|
786
|
-
|
|
787
|
-
|
|
880
|
+
meta: {
|
|
881
|
+
readonly nodes: {
|
|
882
|
+
[K in keyof ExtractNodes<M>]: ExtractNodes<M>[K] | null;
|
|
883
|
+
};
|
|
884
|
+
readonly features: Readonly<FeatureFlags<M>>;
|
|
788
885
|
};
|
|
789
886
|
/**
|
|
790
|
-
* Captures a DOM node for later access via `
|
|
791
|
-
* Use as a ref callback on JSX
|
|
887
|
+
* Captures a DOM node for later access via `meta.nodes`.
|
|
888
|
+
* Use as a ref callback on JSX elements.
|
|
792
889
|
*
|
|
793
|
-
* @param name - The node key (must match a key in
|
|
890
|
+
* @param name - The node key (must match a key in the model's `meta.nodes`)
|
|
794
891
|
* @param node - The DOM node or null (when unmounting)
|
|
795
892
|
*
|
|
796
893
|
* @example
|
|
797
894
|
* ```tsx
|
|
798
895
|
* type Model = {
|
|
799
896
|
* count: number;
|
|
800
|
-
*
|
|
801
|
-
* container: HTMLDivElement;
|
|
802
|
-
* input: HTMLInputElement;
|
|
803
|
-
* };
|
|
897
|
+
* meta: Meta<{ container: HTMLDivElement; input: HTMLInputElement }>;
|
|
804
898
|
* };
|
|
805
899
|
*
|
|
806
900
|
* const [model, actions] = useActions<Model, typeof Actions>(model);
|
|
@@ -812,7 +906,23 @@ export type UseActions<M extends Model | void, AC extends Actions | void, D exte
|
|
|
812
906
|
* );
|
|
813
907
|
* ```
|
|
814
908
|
*/
|
|
815
|
-
node<K extends keyof
|
|
909
|
+
node<K extends keyof ExtractNodes<M>>(name: K, node: ExtractNodes<M>[K] | null): void;
|
|
910
|
+
/**
|
|
911
|
+
* Feature toggle methods for mutating boolean flags on the model.
|
|
912
|
+
*
|
|
913
|
+
* @example
|
|
914
|
+
* ```tsx
|
|
915
|
+
* actions.features.on("sidebar");
|
|
916
|
+
* actions.features.invert("sidebar");
|
|
917
|
+
*
|
|
918
|
+
* {model.meta.features.sidebar && <Sidebar />}
|
|
919
|
+
* ```
|
|
920
|
+
*/
|
|
921
|
+
features: {
|
|
922
|
+
on<K extends keyof FeatureFlags<M>>(name: K): void;
|
|
923
|
+
off<K extends keyof FeatureFlags<M>>(name: K): void;
|
|
924
|
+
invert<K extends keyof FeatureFlags<M>>(name: K): void;
|
|
925
|
+
};
|
|
816
926
|
/**
|
|
817
927
|
* Streams broadcast values declaratively in JSX using a render-prop pattern.
|
|
818
928
|
*
|