chizu 0.2.67 → 0.2.70
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 +25 -4
- package/dist/action/index.d.ts +1 -1
- package/dist/action/utils.d.ts +21 -0
- package/dist/boundary/components/regulators/index.d.ts +14 -0
- package/dist/boundary/components/regulators/types.d.ts +52 -0
- package/dist/boundary/components/regulators/utils.d.ts +21 -0
- package/dist/chizu.js +8 -7
- package/dist/chizu.umd.cjs +1 -1
- package/dist/error/index.d.ts +1 -1
- package/dist/error/types.d.ts +14 -1
- package/dist/hooks/types.d.ts +2 -0
- package/dist/hooks/utils.d.ts +18 -1
- package/dist/index.d.ts +3 -1
- package/dist/types/index.d.ts +56 -24
- package/dist/utils/index.d.ts +2 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -118,9 +118,13 @@ Both the model and actions type parameters default to `void`, so you can call `u
|
|
|
118
118
|
```tsx
|
|
119
119
|
import { useActions, Lifecycle } from "chizu";
|
|
120
120
|
|
|
121
|
-
|
|
121
|
+
class Actions {
|
|
122
|
+
static Mount = Lifecycle.Mount();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const actions = useActions<void, typeof Actions>();
|
|
122
126
|
|
|
123
|
-
actions.useAction(
|
|
127
|
+
actions.useAction(Actions.Mount, () => {
|
|
124
128
|
console.log("Mounted!");
|
|
125
129
|
});
|
|
126
130
|
```
|
|
@@ -227,7 +231,7 @@ function Dashboard() {
|
|
|
227
231
|
}
|
|
228
232
|
```
|
|
229
233
|
|
|
230
|
-
Components that mount after a broadcast has already been dispatched automatically receive the cached value via their `useAction` handler. If you also fetch data in `Lifecycle.Mount`, see the [mount deduplication recipe](./recipes/mount-broadcast-deduplication.md) to avoid duplicate requests.
|
|
234
|
+
Components that mount after a broadcast has already been dispatched automatically receive the cached value via their `useAction` handler. If you also fetch data in `Lifecycle.Mount()`, see the [mount deduplication recipe](./recipes/mount-broadcast-deduplication.md) to avoid duplicate requests.
|
|
231
235
|
|
|
232
236
|
For targeted event delivery, use channeled actions. Define a channel type as the second generic argument and call the action with a channel object – handlers fire when the dispatch channel matches:
|
|
233
237
|
|
|
@@ -301,7 +305,7 @@ function App() {
|
|
|
301
305
|
actions.dispatch(Actions.Multicast.Update, 42, { scope: "TeamA" });
|
|
302
306
|
```
|
|
303
307
|
|
|
304
|
-
Unlike broadcast which reaches all components, multicast is scoped to the named boundary – perfect for isolated widget groups, form sections, or distinct UI regions. Like broadcast, multicast caches dispatched values per scope – components that mount later automatically receive the cached value. See the [mount deduplication recipe](./recipes/mount-broadcast-deduplication.md) if you also fetch data in `Lifecycle.Mount`.
|
|
308
|
+
Unlike broadcast which reaches all components, multicast is scoped to the named boundary – perfect for isolated widget groups, form sections, or distinct UI regions. Like broadcast, multicast caches dispatched values per scope – components that mount later automatically receive the cached value. See the [mount deduplication recipe](./recipes/mount-broadcast-deduplication.md) if you also fetch data in `Lifecycle.Mount()`.
|
|
305
309
|
|
|
306
310
|
For components that always render inside a scope, use the `withScope` HOC to eliminate the manual `<Scope>` wrapper:
|
|
307
311
|
|
|
@@ -376,3 +380,20 @@ context.actions.invalidate(CacheStore.User({ UserId: 5 }));
|
|
|
376
380
|
```
|
|
377
381
|
|
|
378
382
|
The cache is scoped to the nearest `<Boundary>`. See the [caching recipe](./recipes/caching.md) for more details.
|
|
383
|
+
|
|
384
|
+
The action regulator lets handlers control which actions may be dispatched across all components within a `<Boundary>`. Use `context.regulator` to block or allow actions:
|
|
385
|
+
|
|
386
|
+
```ts
|
|
387
|
+
actions.useAction(Actions.Checkout, async (context) => {
|
|
388
|
+
// Allow only the cancel action during checkout
|
|
389
|
+
context.regulator.allow(Actions.Cancel);
|
|
390
|
+
|
|
391
|
+
try {
|
|
392
|
+
await processPayment(context.task.controller.signal);
|
|
393
|
+
} finally {
|
|
394
|
+
context.regulator.allow();
|
|
395
|
+
}
|
|
396
|
+
});
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
`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.
|
package/dist/action/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HandlerPayload, BroadcastPayload, MulticastPayload, Distribution, Filter } from '../types/index.ts';
|
|
2
|
-
export { getActionSymbol, isBroadcastAction, isMulticastAction, getName, isChanneledAction, } from './utils.ts';
|
|
2
|
+
export { getActionSymbol, getLifecycleType, isBroadcastAction, isMulticastAction, getName, isChanneledAction, } from './utils.ts';
|
|
3
3
|
/**
|
|
4
4
|
* Interface for the Action factory function.
|
|
5
5
|
*/
|
package/dist/action/utils.d.ts
CHANGED
|
@@ -58,6 +58,27 @@ export declare function getName(action: AnyAction): string;
|
|
|
58
58
|
* ```
|
|
59
59
|
*/
|
|
60
60
|
export declare function isChanneledAction(action: AnyAction): action is ChanneledAction;
|
|
61
|
+
/**
|
|
62
|
+
* Extracts the lifecycle type from an action's symbol description.
|
|
63
|
+
*
|
|
64
|
+
* Returns the lifecycle name (`"Mount"`, `"Unmount"`, `"Error"`, `"Update"`,
|
|
65
|
+
* `"Node"`) when the action symbol's description starts with the lifecycle
|
|
66
|
+
* prefix, or `null` for non-lifecycle actions.
|
|
67
|
+
*
|
|
68
|
+
* @param action The action to inspect.
|
|
69
|
+
* @returns The lifecycle name, or `null` if not a lifecycle action.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* class Actions {
|
|
74
|
+
* static Mount = Lifecycle.Mount();
|
|
75
|
+
* }
|
|
76
|
+
*
|
|
77
|
+
* getLifecycleType(Actions.Mount); // "Mount"
|
|
78
|
+
* getLifecycleType(Action("Increment")); // null
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
export declare function getLifecycleType(action: AnyAction): string | null;
|
|
61
82
|
/**
|
|
62
83
|
* Checks whether an action is a multicast action.
|
|
63
84
|
* Multicast actions are dispatched to all components within a named scope boundary.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Props } from './types.ts';
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
export { useRegulators, isAllowed } from './utils.ts';
|
|
4
|
+
export type { Regulator, RegulatorPolicy } from './types.ts';
|
|
5
|
+
/**
|
|
6
|
+
* Provides a shared regulator policy to all descendant components.
|
|
7
|
+
*
|
|
8
|
+
* Wrap this around your component tree (or use `<Boundary>` which includes it)
|
|
9
|
+
* to enable action regulation via `context.regulator`.
|
|
10
|
+
*
|
|
11
|
+
* @param props.children - The children to render within the regulator context.
|
|
12
|
+
* @returns The children wrapped in a regulator context provider.
|
|
13
|
+
*/
|
|
14
|
+
export declare function Regulators({ children }: Props): React.ReactNode;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ActionId } from '../tasks/types.ts';
|
|
2
|
+
import type * as React from "react";
|
|
3
|
+
/**
|
|
4
|
+
* The four policy modes that the regulator supports.
|
|
5
|
+
*
|
|
6
|
+
* - `allow-all` (default) – every action is permitted (`allow()` with no args).
|
|
7
|
+
* - `disallow-all` – every action is blocked (`disallow()` with no args).
|
|
8
|
+
* - `disallow-matching` – only the listed actions are blocked (`disallow(A, B)`).
|
|
9
|
+
* - `allow-matching` – only the listed actions are permitted (`allow(A, B)`).
|
|
10
|
+
*
|
|
11
|
+
* For "except" patterns, compose two calls:
|
|
12
|
+
* - Block all except X: `disallow()` then `allow(X)`.
|
|
13
|
+
* - Allow all except X: `allow()` then `disallow(X)`.
|
|
14
|
+
*/
|
|
15
|
+
export type RegulatorMode = "allow-all" | "disallow-all" | "disallow-matching" | "allow-matching";
|
|
16
|
+
/**
|
|
17
|
+
* Mutable policy object shared across all components in a `<Boundary>`.
|
|
18
|
+
* Mutated in-place by the `context.regulator` API – last write wins.
|
|
19
|
+
*/
|
|
20
|
+
export type RegulatorPolicy = {
|
|
21
|
+
mode: RegulatorMode;
|
|
22
|
+
actions: Set<ActionId>;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* The `context.regulator` API shape exposed to action handlers.
|
|
26
|
+
*
|
|
27
|
+
* - `disallow()` – block all actions.
|
|
28
|
+
* - `disallow(A, B)` – block only the listed actions.
|
|
29
|
+
* - `allow()` – allow all actions (reset to default).
|
|
30
|
+
* - `allow(A, B)` – allow only the listed actions.
|
|
31
|
+
*
|
|
32
|
+
* Each call replaces the previous policy entirely (last-write-wins).
|
|
33
|
+
*/
|
|
34
|
+
export type Regulator = {
|
|
35
|
+
/**
|
|
36
|
+
* Block actions. Called with no arguments, blocks everything.
|
|
37
|
+
* Called with specific actions, blocks only those actions.
|
|
38
|
+
*/
|
|
39
|
+
disallow(...actions: ReadonlyArray<{
|
|
40
|
+
readonly [x: symbol]: unknown;
|
|
41
|
+
}>): void;
|
|
42
|
+
/**
|
|
43
|
+
* Allow actions. Called with no arguments, allows everything (reset).
|
|
44
|
+
* Called with specific actions, allows only those actions.
|
|
45
|
+
*/
|
|
46
|
+
allow(...actions: ReadonlyArray<{
|
|
47
|
+
readonly [x: symbol]: unknown;
|
|
48
|
+
}>): void;
|
|
49
|
+
};
|
|
50
|
+
export type Props = {
|
|
51
|
+
children: React.ReactNode;
|
|
52
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ActionId } from '../tasks/types.ts';
|
|
2
|
+
import { RegulatorPolicy } from './types.ts';
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
/**
|
|
5
|
+
* React context holding the shared, mutable regulator policy.
|
|
6
|
+
*/
|
|
7
|
+
export declare const Context: React.Context<RegulatorPolicy>;
|
|
8
|
+
/**
|
|
9
|
+
* Hook to access the regulator policy from the nearest `<Regulators>` provider.
|
|
10
|
+
*
|
|
11
|
+
* @returns The mutable `RegulatorPolicy` object from context.
|
|
12
|
+
*/
|
|
13
|
+
export declare function useRegulators(): RegulatorPolicy;
|
|
14
|
+
/**
|
|
15
|
+
* Determines whether a given action is allowed under the current policy.
|
|
16
|
+
*
|
|
17
|
+
* @param action - The action identifier (symbol) to check.
|
|
18
|
+
* @param policy - The current regulator policy.
|
|
19
|
+
* @returns `true` if the action may proceed, `false` if it should be blocked.
|
|
20
|
+
*/
|
|
21
|
+
export declare function isAllowed(action: ActionId, policy: RegulatorPolicy): boolean;
|
package/dist/chizu.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import{G as e,A as t}from"@mobily/ts-belt";import{jsx as n}from"react/jsx-runtime";import*as r from"react";import{createContext as o,useContext as c}from"react";import{immerable as i,enablePatches as s,Immer as a}from"immer";class u{static Payload=/* @__PURE__ */Symbol("chizu.brand/Payload");static Broadcast=/* @__PURE__ */Symbol("chizu.brand/Broadcast");static Multicast=/* @__PURE__ */Symbol("chizu.brand/Multicast");static Action=/* @__PURE__ */Symbol("chizu.brand/Action");static Channel=/* @__PURE__ */Symbol("chizu.brand/Channel");static Node=/* @__PURE__ */Symbol("chizu.action.lifecycle/Node");static Cache=/* @__PURE__ */Symbol("chizu.brand/Cache")}
|
|
2
|
-
return n(
|
|
3
|
-
return n(
|
|
4
|
-
return n(
|
|
5
|
-
return n(
|
|
6
|
-
return n(
|
|
7
|
-
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 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")}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 w(e,t,n){if(t?.aborted)throw new m;for(;;){if(await n())return;await v(e,t)}}function g(e){return e?Boolean(e&&"symbol"!=typeof e):/* @__PURE__ */Symbol(`pk.${Date.now()}.${crypto.randomUUID()}`)}const x=/* @__PURE__ */Object.freeze(/* @__PURE__ */Object.defineProperty({__proto__:null,config:b,pk:g,poll:w,sleep:v,"ζ":v,"κ":g,"π":w},Symbol.toStringTag,{value:"Module"})),P=e=>"symbol"==typeof e;function E(t){return e.isString(t)||P(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(b.broadcastActionPrefix);if(P(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=E(t),r=e.isString(n)?n:n.description??"";return r.startsWith(b.actionPrefix)&&r.slice(r.lastIndexOf("/")+1)||"unknown"}function C(t){return e.isObject(t)&&u.Channel in t&&"channel"in t}function j(e){const t=E(e),n=P(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(P(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{[i]=!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 F{static immer=(()=>{s();const e=new a;return e.setAutoFreeze(!1),e})();static tag="κ";static id=z}function W(e,t){const n="string"==typeof t?""===t?[]:t.split("."):t;let r=e;for(const o of n){if(null==r)return;r=r[o]}return r}function 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),[F.tag]:t[F.tag]??F.id()}}return t}function G(e){if(Array.isArray(e))return e.filter(e=>F.tag in e).map(e=>e[F.tag]??"").join(",");const t=e[F.tag];if(t)return t;try{return JSON.stringify(e)}catch{return`[unserializable:${typeof e}]`}}function I(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,i){return function s(a,u=n.path){if(a instanceof B){const n=W(r,u.join("."));if(Object.entries(a).filter(([e,t])=>!B.keys.has(e)&&t instanceof B).forEach(([e,t])=>s(t,u.concat(e))),V(a.value)){if(t===T.Hydrate)return a.value;const s=u.slice(0,-1),l=s.length>0?W(r,s.join(".")):r;return e.isNullable(l)||J(l,a,u.at(-1),o,c,i),n??a.value}if(t===T.Hydrate){const e=H(s(a.value,u));return J(e,a,null,o,c,i),e}const l=n??H(a.value);return J(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)&&!I(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===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,i)}),e}return n}return a}(n.value)}function J(e,t,n,r,o,c){const i=c(e),s=o.get(i)??[];o.set(i,[t.assign(n,r),...s])}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,i){function s(c){const i=c.at(-1),s=W(n(),c),a=c.slice(0,-1),u=t.isNotEmpty(a)?W(n(),a):n();return[...e.isObject(s)||e.isArray(s)?r.get(o(s))?.filter(t=>e.isNullable(t.property))??[]:[],...e.isObject(u)?r.get(o(u))?.filter(e=>e.property===i)??[]:[]]}return function e(r){return new Proxy(()=>{},{get:(o,a)=>"pending"===a?()=>!t.isEmpty(s(r)):"remaining"===a?()=>t.length(s(r)):"box"===a?()=>({value:W(n(),r),inspect:e(r)}):"is"===a?e=>s(r).some(t=>0!==(t.operation&e)):"draft"===a?()=>t.head(s(r))?.value??W(n(),r):"settled"===a?()=>new Promise(e=>{if(t.isEmpty(s(r)))return e(W(n(),r));const o=()=>{t.isEmpty(s(r))&&(i(o),e(W(n(),r)))};c(o)}):e([...r,String(a)])})}([])}(()=>this.#e,this.#n,this.#t,e=>this.#r.add(e),e=>this.#r.delete(e))}hydrate(e){return this.#o=!0,this.#c(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]=F.immer.produceWithPatches(this.#e,t);return this.#e=r.reduce((t,r)=>F.immer.applyPatches(t,[{...r,value:q(e,r,t,n,this.#n,this.#t)}]),this.#e),this.#e=H(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 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,i){if("function"!=typeof r)throw new TypeError("The listener must be a function");var s=new o(r,c||e,i),a=n?n+t:t;return e._events[a]?e._events[a].fn?e._events[a]=[e._events[a],s]:e._events[a].push(s):(e._events[a]=s,e._eventsCount++),e}function i(e,t){0===--e._eventsCount?e._events=new r:delete e._events[t]}function s(){this._events=new r,this._eventsCount=0}Object.create&&(r.prototype=/* @__PURE__ */Object.create(null),(new r).__proto__||(n=!1)),s.prototype.eventNames=function(){var e,r,o=[];if(0===this._eventsCount)return o;for(r in e=this._events)t.call(e,r)&&o.push(n?r.slice(1):r);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(e)):o},s.prototype.listeners=function(e){var t=this._events[n?n+e:e];if(!t)return[];if(t.fn)return[t.fn];for(var r=0,o=t.length,c=new Array(o);r<o;r++)c[r]=t[r].fn;return c},s.prototype.listenerCount=function(e){var t=this._events[n?n+e:e];return t?t.fn?1:t.length:0},s.prototype.emit=function(e,t,r,o,c,i){var s=n?n+e:e;if(!this._events[s])return!1;var a,u,l=this._events[s],f=arguments.length;if(l.fn){switch(l.once&&this.removeListener(e,l.fn,void 0,!0),f){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,t),!0;case 3:return l.fn.call(l.context,t,r),!0;case 4:return l.fn.call(l.context,t,r,o),!0;case 5:return l.fn.call(l.context,t,r,o,c),!0;case 6:return l.fn.call(l.context,t,r,o,c,i),!0}for(u=1,a=new Array(f-1);u<f;u++)a[u-1]=arguments[u];l.fn.apply(l.context,a)}else{var d,h=l.length;for(u=0;u<h;u++)switch(l[u].once&&this.removeListener(e,l[u].fn,void 0,!0),f){case 1:l[u].fn.call(l[u].context);break;case 2:l[u].fn.call(l[u].context,t);break;case 3:l[u].fn.call(l[u].context,t,r);break;case 4:l[u].fn.call(l[u].context,t,r,o);break;default:if(!a)for(d=1,a=new Array(f-1);d<f;d++)a[d-1]=arguments[d];l[u].fn.apply(l[u].context,a)}}return!0},s.prototype.on=function(e,t,n){return c(this,e,t,n,!1)},s.prototype.once=function(e,t,n){return c(this,e,t,n,!0)},s.prototype.removeListener=function(e,t,r,o){var c=n?n+e:e;if(!this._events[c])return this;if(!t)return i(this,c),this;var s=this._events[c];if(s.fn)s.fn!==t||o&&!s.once||r&&s.context!==r||i(this,c);else{for(var a=0,u=[],l=s.length;a<l;a++)(s[a].fn!==t||o&&!s[a].once||r&&s[a].context!==r)&&u.push(s[a]);u.length?this._events[c]=1===u.length?u[0]:u:i(this,c)}return this},s.prototype.removeAllListeners=function(e){var t;return e?this._events[t=n?n+e:e]&&i(this,t):(this._events=new r,this._eventsCount=0),this},s.prototype.off=s.prototype.removeListener,s.prototype.addListener=s.prototype.on,s.prefixed=n,s.EventEmitter=s,e.exports=s}(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)}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 ie=r.createContext(/* @__PURE__ */new Map);function se({children:e}){const t=r.useMemo(()=>/* @__PURE__ */new Map,[]);/* @__PURE__ */
|
|
4
|
+
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__ */
|
|
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
|
+
return n(le.Provider,{value:t,children:e})}function de({children:e}){/* @__PURE__ */
|
|
7
|
+
return n(ce,{children:/* @__PURE__ */n(se,{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}),[]),i=r.useMemo(()=>{const t=new Map(o??[]);return t.set(e,c),t},[o,e,c]);/* @__PURE__ */
|
|
8
|
+
return n(he.Provider,{value:i,children:t})}function be(e,t){const r=`Scoped${t.displayName||t.name||"Component"}`;return{[r]:r=>/* @__PURE__ */n(ye,{name:e,children:/* @__PURE__ */n(t,{...r})})}[r]}function ve(e){return(t,n)=>{t.actions.produce(t=>{t.model[e]=n})}}function we(e,t){for(const n of e.keys())if(j(n)===t)return n;return null}function ge(){const[,e]=r.useReducer(e=>e+1,0);return e}const xe=r.createContext(/* @__PURE__ */new Map);function Pe({action:t,renderer:n}){const o=oe(),c=r.useContext(xe),i=ge(),s=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){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(a,s.state.inspect.value)}function Ee(...n){const o=e.isUndefined(n[0])||e.isFunction(n[0])?{}:n[0],i=e.isFunction(n[0])?n[0]:n[1]??(()=>({})),s=oe(),a=pe(),u=c(U),l=r.useContext(ae),f=r.useContext(ie),d=r.useContext(le),m=ge(),b=r.useRef(!1),v=r.useRef(null),w=r.useRef(new K);b.current||(b.current=!0,v.current=w.current.hydrate(o));const[g,x]=r.useState(()=>w.current.model),P=function(e){const t=r.useRef(e);return r.useLayoutEffect(()=>{t.current=e},[e]),r.useMemo(()=>{return n=t,Object.keys(e).reduce((e,t)=>(Object.defineProperty(e,t,{get:()=>n.current[t],enumerable:!0}),e),{});var n},[e])}(i()),j=r.useMemo(()=>new te,[]),M=r.useRef({handlers:/* @__PURE__ */new Map});M.current.handlers=/* @__PURE__ */new Map;const k=function(){const e=r.useRef(/* @__PURE__ */new Set),t=r.useRef(/* @__PURE__ */new Set);return r.useMemo(()=>({broadcast:e.current,multicast:t.current}),[])}(),L=r.useRef(h.Mounting),z=function(){const e=r.useRef({}),t=r.useRef(/* @__PURE__ */new Map),n=r.useRef(/* @__PURE__ */new Map);return r.useMemo(()=>({refs:e,pending:t,emitted:n}),[])}(),$=r.useRef(/* @__PURE__ */new Set),T=r.useRef(0),D=r.useCallback((e,t,n)=>{const r=new AbortController,o={controller:r,action:e,payload:t};return l.add(o),$.current.add(o),{model:w.current.model,get phase(){return L.current},task:o,data:P,tasks:l,nodes:z.refs.current,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(E(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(E(t))}}},actions:{produce(e){if(r.signal.aborted)return;const t=w.current.produce(t=>e({model:t,inspect:w.current.inspect}));x(w.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;const o=E(e),c=C(e)?e.channel:void 0;if(A(e)&&n?.scope){const e=me(a,n.scope);return void(e&&e.emitter.emit(o,t,c))}(S(e)?s:j).emit(o,t,c)},annotate:(e,t)=>w.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 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?(f.set(o,{value:i.value,expiry:Date.now()+t}),{data:i.value}):{data:null}},invalidate(e){f.delete(_(e))},async read(e,t){if(r.signal.aborted)return null;const n=E(e),o=A(e)&&t?.scope?me(a,t.scope)?.emitter??null:s;if(!o)return null;if(void 0===o.getCached(n))return null;const c=O(e),i="unknown"!==c?c[0].toLowerCase()+c.slice(1):null;if(i){const e=w.current.inspect[i];e?.pending?.()&&await new Promise((t,n)=>{if(r.signal.aborted)return void n(r.signal.reason);const o=()=>n(r.signal.reason);r.signal.addEventListener("abort",o,{once:!0}),e.settled().then(()=>{r.signal.removeEventListener("abort",o),t()})})}return o.getCached(n)??null},peek(e,t){if(r.signal.aborted)return null;const n=E(e),o=A(e)&&t?.scope?me(a,t.scope)?.emitter??null:s;return o?o.getCached(n)??null:null}}}},[g]);r.useLayoutEffect(()=>{function t(t,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)}}(t,d)){const e=we(M.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&&j.emit(e,r))}const i=r();if(e.isNotNullable(c)&&e.isNotNullable(i)&&!function(e,t){for(const n of Object.keys(e))if(t[n]!==e[n])return!1;return!0}(c,i))return;const s={processes:/* @__PURE__ */new Set},a=Promise.withResolvers(),f=D(t,o,s);try{await n(f,o)}catch(h){const e=we(M.current.handlers,"Error"),n=null!==e,r={reason:R(h),error:N(h),action:O(t),handled:n,tasks:l};u?.(r),n&&e&&j.emit(e,r)}finally{for(const e of l)if(e===f.task){l.delete(e),$.current.delete(e);break}s.processes.forEach(e=>w.current.prune(e)),s.processes.size>0&&m(),a.resolve()}}}T.current++;const n=/* @__PURE__ */new Set;return M.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))}j.on(r,e),k.multicast.add(r),n.add(()=>j.off(r,e))}else S(r)?(s.on(r,e),j.on(r,e),k.broadcast.add(r),n.add(()=>{s.off(r,e),j.off(r,e)})):(j.on(r,e),n.add(()=>j.off(r,e)))}}),()=>{const e=++T.current,t=new Set(n);queueMicrotask(()=>{if(T.current!==e){for(const e of t)e();return}for(const e of $.current)e.controller.abort(),l.delete(e);$.current.clear(),L.current=h.Unmounting;const n=we(M.current.handlers,"Unmount");n&&j.emit(n),L.current=h.Unmounted;for(const e of t)e()})}},[j]),r.useLayoutEffect(()=>{const e=we(M.current.handlers,"Node");for(const[t,n]of z.pending.current)z.emitted.current.get(t)!==n&&(z.emitted.current.set(t,n),e&&j.emit(e,n,{Name:t}));z.pending.current.clear()}),function({unicast:n,broadcast:o,dispatchers:c,scope:i,phase:s,data:a,handlers:u}){const l=r.useRef(null);r.useLayoutEffect(()=>{if(s.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)}),i&&c.multicast.forEach(t=>{for(const r of i.values()){const o=r.emitter.getCached(t);e.isNullable(o)||n.emit(t,o)}}),s.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:j,broadcast:s,dispatchers:k,scope:a,phase:L,data:i(),handlers:M.current.handlers});const B=r.useMemo(()=>[g,{dispatch(e,t,n){const r=E(e),o=C(e)?e.channel:void 0;if(A(e)&&n?.scope){const e=me(a,n.scope);return void(e&&e.emitter.emit(r,t,o))}(S(e)?s:j).emit(r,t,o)},get inspect(){return w.current.inspect},get nodes(){return z.refs.current},node(e,t){z.refs.current[e]=t,z.pending.current.set(e,t)},stream:(e,t)=>r.createElement(Pe,{action:E(e),renderer:t})}],[g,j]);return B.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(()=>C(c.current)?c.current.channel:void 0,[]),a=E(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})}(M,e,t)},B}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,ve as With,X as annotate,Ee as useActions,x 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")}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})})}async function m(e,t,n){if(t?.aborted)throw new d;for(;;){if(await n())return;await h(e,t)}}function y(e){return e?Boolean(e&&"symbol"!=typeof e):Symbol(`pk.${Date.now()}.${crypto.randomUUID()}`)}const b=Object.freeze(Object.defineProperty({__proto__:null,config:p,pk:y,poll:m,sleep:h,"ζ":h,"κ":y,"π":m},Symbol.toStringTag,{value:"Module"})),v=e=>"symbol"==typeof e;function g(e){return t.G.isString(e)||v(e)?e:(t.G.isObject(e)||t.G.isFunction(e))&&s.Action in e?e[s.Action]:e}function w(e){if(t.G.isString(e))return e.startsWith(p.broadcastActionPrefix);if(v(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 x(e){const n=g(e),r=t.G.isString(n)?n:n.description??"";return r.startsWith(p.actionPrefix)&&r.slice(r.lastIndexOf("/")+1)||"unknown"}function j(e){return t.G.isObject(e)&&s.Channel in e&&"channel"in e}function S(e){if(t.G.isString(e))return e.startsWith(p.multicastActionPrefix);if(v(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 P(e){const t=function(e){return e[s.Cache]}(e),n=function(e){return"channel"in e}(e)&&(r=e.channel)?[...Object.keys(r)].toSorted().map(e=>`${e}=${String(r[e])}`).join("&"):"";var r;return`${String(t)}:${n}`}function A(e){if(e instanceof Error){if("TimeoutError"===e.name)return f.Timedout;if("AbortError"===e.name)return f.Supplanted}return f.Errored}function O(e){return e instanceof Error?e:new Error(String(e))}const E=r.createContext(void 0);let C=(e=21)=>{let t="",n=crypto.getRandomValues(new Uint8Array(e|=0));for(;e--;)t+="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"[63&n[e]];return t};var 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||{}),k=(e=>(e[e.Produce=0]="Produce",e[e.Hydrate=1]="Hydrate",e))(k||{}),G=(e=>(e.Property="property",e.Process="process",e.Value="value",e.Operation="operation",e))(G||{});class _{[o.immerable]=!0;static keys=new Set(Object.values(G));property=null;process=null;value;operation;constructor(e,t){this.value=e,this.operation=t}assign(e,t){const n=new _(this.value,this.operation);return n.property=e,n.process=t,n}}class R{static immer=(()=>{o.enablePatches();const e=new o.Immer;return e.setAutoFreeze(!1),e})();static tag="κ";static id=C}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)||T(e))return e;if(t.G.isArray(e))return e.map(e=>z(e));if(t.G.isObject(e)&&L(e)){const t=Object.entries(e).map(([e,t])=>[e,z(t)]);return{...Object.fromEntries(t),[R.tag]:e[R.tag]??R.id()}}return e}function U(e){if(Array.isArray(e))return e.filter(e=>R.tag in e).map(e=>e[R.tag]??"").join(",");const t=e[R.tag];if(t)return t;try{return JSON.stringify(e)}catch{return`[unserializable:${typeof e}]`}}function L(e){const t=Object.getPrototypeOf(e);return t===Object.prototype||null===t}function T(e){return t.G.isNullable(e)||t.G.isString(e)||t.G.isNumber(e)||t.G.isBoolean(e)||"symbol"==typeof e||"bigint"==typeof e}function $(e,n,r,o,c,i){return function s(a,u=n.path){if(a instanceof _){const n=N(r,u.join("."));if(Object.entries(a).filter(([e,t])=>!_.keys.has(e)&&t instanceof _).forEach(([e,t])=>s(t,u.concat(e))),T(a.value)){if(e===k.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===k.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)&&!L(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===k.Hydrate){const e=z(n);return Object.entries(a).forEach(([t,n])=>{n instanceof _&&T(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 F{#e={};#t;#n=new Map;#r=new Set;#o=!1;constructor(e=U){this.#t=e}static pk(){return C()}static"κ"=F.pk;annotate(e,t){return new _(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(k.Hydrate,()=>e)}produce(e){if(!this.#o)throw new Error("State must be hydrated using hydrate() before calling produce()");return this.#c(k.Produce,e)}#c(e,t){const n=Symbol("process"),[,r]=R.immer.produceWithPatches(this.#e,t);return this.#e=r.reduce((t,r)=>R.immer.applyPatches(t,[{...r,value:$(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 F;function D(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var H,I={exports:{}},q=(H||(H=1,function(e){var t=Object.prototype.hasOwnProperty,n="~";function r(){}function o(e,t,n){this.fn=e,this.context=t,this.once=n||!1}function c(e,t,r,c,i){if("function"!=typeof r)throw new TypeError("The listener must be a function");var s=new o(r,c||e,i),a=n?n+t:t;return e._events[a]?e._events[a].fn?e._events[a]=[e._events[a],s]:e._events[a].push(s):(e._events[a]=s,e._eventsCount++),e}function i(e,t){0===--e._eventsCount?e._events=new r:delete e._events[t]}function s(){this._events=new r,this._eventsCount=0}Object.create&&(r.prototype=Object.create(null),(new r).__proto__||(n=!1)),s.prototype.eventNames=function(){var e,r,o=[];if(0===this._eventsCount)return o;for(r in e=this._events)t.call(e,r)&&o.push(n?r.slice(1):r);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(e)):o},s.prototype.listeners=function(e){var t=this._events[n?n+e:e];if(!t)return[];if(t.fn)return[t.fn];for(var r=0,o=t.length,c=new Array(o);r<o;r++)c[r]=t[r].fn;return c},s.prototype.listenerCount=function(e){var t=this._events[n?n+e:e];return t?t.fn?1:t.length:0},s.prototype.emit=function(e,t,r,o,c,i){var s=n?n+e:e;if(!this._events[s])return!1;var a,u,l=this._events[s],f=arguments.length;if(l.fn){switch(l.once&&this.removeListener(e,l.fn,void 0,!0),f){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,t),!0;case 3:return l.fn.call(l.context,t,r),!0;case 4:return l.fn.call(l.context,t,r,o),!0;case 5:return l.fn.call(l.context,t,r,o,c),!0;case 6:return l.fn.call(l.context,t,r,o,c,i),!0}for(u=1,a=new Array(f-1);u<f;u++)a[u-1]=arguments[u];l.fn.apply(l.context,a)}else{var d,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}(I)),I.exports);const V=D(q);class J extends V{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 K=i.createContext(new J);function Q(){return i.useContext(K)}function X({children:e}){const t=i.useMemo(()=>new J,[]);return n.jsx(K.Provider,{value:t,children:e})}const Y=i.createContext(new Map);function Z({children:e}){const t=i.useMemo(()=>new Map,[]);return n.jsx(Y.Provider,{value:t,children:e})}const ee=i.createContext(new Set);function te({children:e}){const t=i.useMemo(()=>new Set,[]);return n.jsx(ee.Provider,{value:t,children:e})}const ne=i.createContext(null);function re(){return i.useContext(ne)}function oe(e,t){return e?.get(t)??null}function ce({name:e,children:t}){const r=re(),o=i.useMemo(()=>({name:e,emitter:new J}),[]),c=i.useMemo(()=>{const t=new Map(r??[]);return t.set(e,o),t},[r,e,o]);return n.jsx(ne.Provider,{value:c,children:t})}function ie(){const[,e]=i.useReducer(e=>e+1,0);return e}const se=i.createContext(new Map);function ae({action:e,renderer:n}){const r=Q(),o=i.useContext(se),c=ie(),s=i.useMemo(()=>{const t=o.get(e);if(t)return t;const n={state:new F,listeners:new Set};return o.set(e,n),n},[e,o]);i.useLayoutEffect(()=>{function t(e){s.state.hydrate({value:e}),s.listeners.forEach(e=>e())}return s.listeners.add(c),r.on(e,t),()=>{s.listeners.delete(c),r.off(e,t)}},[e,r,s]);const a=s.state.model?.value;return t.G.isNullable(a)?null:n(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(X,{children:n.jsx(Z,{children:n.jsx(te,{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(E.Provider,{value:e,children:t})},e.Lifecycle=a,e.Op=M,e.Operation=M,e.Reason=f,e.Scope=ce,e.State=F,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){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=Q(),u=re(),f=r.useContext(E),d=i.useContext(ee),p=i.useContext(Y),h=ie(),m=i.useRef(!1),y=i.useRef(null),b=i.useRef(new F);m.current||(m.current=!0,y.current=b.current.hydrate(n));const[v,C]=i.useState(()=>b.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])}(o()),k=i.useMemo(()=>new V,[]),G=i.useRef({handlers:new Map});G.current.handlers=new Map;const _=function(){const e=i.useRef(new Set),t=i.useRef(new Set);return i.useMemo(()=>({broadcast:e.current,multicast:t.current}),[])}(),R=i.useRef(l.Mounting),N=function(){const e=i.useRef({}),t=i.useRef(new Map),n=i.useRef(new Map);return i.useMemo(()=>({refs:e,pending:t,emitted:n}),[])}(),z=i.useRef(new Set),U=i.useRef(0),L=i.useCallback((e,t,n)=>{const r=new AbortController,o={controller:r,action:e,payload:t};return d.add(o),z.current.add(o),{model:b.current.model,get phase(){return R.current},task:o,data:M,tasks:d,nodes:N.refs.current,actions:{produce(e){if(r.signal.aborted)return;const t=b.current.produce(t=>e({model:t,inspect:b.current.inspect}));C(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=g(e),i=j(e)?e.channel:void 0;if(S(e)&&n?.scope){const e=oe(u,n.scope);return void(e&&e.emitter.emit(o,t,i))}(w(e)?c:k).emit(o,t,i)},annotate:(e,t)=>b.current.annotate(e,t),async cacheable(e,t,n){if(r.signal.aborted)return{data:null};const o=P(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(P(e))},async read(e,t){if(r.signal.aborted)return null;const n=g(e),o=S(e)&&t?.scope?oe(u,t.scope)?.emitter??null:c;if(!o)return null;if(void 0===o.getCached(n))return null;const i=x(e),s="unknown"!==i?i[0].toLowerCase()+i.slice(1):null;if(s){const e=b.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=g(e),o=S(e)&&t?.scope?oe(u,t.scope)?.emitter??null:c;return o?o.getCached(n)??null:null}}}},[v]);i.useLayoutEffect(()=>{function e(e,n,r){return async function(o,c){const i=r();if(t.G.isNotNullable(c)&&t.G.isNotNullable(i)&&!function(e,t){for(const n of Object.keys(e))if(t[n]!==e[n])return!1;return!0}(c,i))return;const s={processes:new Set},u=Promise.withResolvers(),l=L(e,o,s);try{await n(l,o)}catch(p){const t=G.current.handlers.has(a.Error),n={reason:A(p),error:O(p),action:x(e),handled:t,tasks:d};f?.(n),t&&k.emit(a.Error,n)}finally{for(const e of d)if(e===l.task){d.delete(e),z.current.delete(e);break}s.processes.forEach(e=>b.current.prune(e)),s.processes.size>0&&h(),u.resolve()}}}U.current++;const n=new Set;return G.current.handlers.forEach((t,r)=>{for(const{getChannel:o,handler:i}of t){const t=e(r,i,o);if(S(r)){if(u)for(const e of u.values()){const o=e.emitter;o.on(r,t),n.add(()=>o.off(r,t))}k.on(r,t),_.multicast.add(r),n.add(()=>k.off(r,t))}else w(r)?(c.on(r,t),k.on(r,t),_.broadcast.add(r),n.add(()=>{c.off(r,t),k.off(r,t)})):(k.on(r,t),n.add(()=>k.off(r,t)))}}),()=>{const e=++U.current,t=new Set(n);queueMicrotask(()=>{if(U.current===e){for(const e of z.current)e.controller.abort(),d.delete(e);z.current.clear(),R.current=l.Unmounting,k.emit(a.Unmount),R.current=l.Unmounted;for(const e of t)e()}else for(const e of t)e()})}},[k]),i.useLayoutEffect(()=>{for(const[e,t]of N.pending.current)N.emitted.current.get(e)!==t&&(N.emitted.current.set(e,t),k.emit(s.Node,t,{Name:e}));N.pending.current.clear()}),function({unicast:e,broadcast:n,dispatchers:r,scope:o,phase:c,data:s}){const u=i.useRef(null);i.useLayoutEffect(()=>{c.current===l.Mounting&&(e.emit(a.Mount),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);t.A.isNotEmpty(Object.keys(n))&&e.emit(a.Update,n)}u.current=s},[s,e])}({unicast:k,broadcast:c,dispatchers:_,scope:u,phase:R,data:o()});const T=i.useMemo(()=>[v,{dispatch(e,t,n){const r=g(e),o=j(e)?e.channel:void 0;if(S(e)&&n?.scope){const e=oe(u,n.scope);return void(e&&e.emitter.emit(r,t,o))}(w(e)?c:k).emit(r,t,o)},get inspect(){return b.current.inspect},get nodes(){return N.refs.current},node(e,t){N.refs.current[e]=t,N.pending.current.set(e,t)},stream:(e,t)=>i.createElement(ae,{action:g(e),renderer:t})}],[v,k]);return T.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(()=>j(o.current)?o.current.channel:void 0,[]),a=g(t),u=e.current.handlers.get(a)??new Set;0===u.size&&e.current.handlers.set(a,u),u.add({getChannel:s,handler:c})}(G,e,t)},T},e.utils=b,e.withScope=function(e,t){const r=`Scoped${t.displayName||t.name||"Component"}`;return{[r]:r=>n.jsx(ce,{name:e,children:n.jsx(t,{...r})})}[r]},Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})},"object"==typeof exports&&"undefined"!=typeof module?factory(exports,require("@mobily/ts-belt"),require("react/jsx-runtime"),require("react"),require("immer")):"function"==typeof define&&define.amd?define(["exports","@mobily/ts-belt","react/jsx-runtime","react","immer"],factory):factory((global="undefined"!=typeof globalThis?globalThis:global||self).Chizu={},global.TsBelt,global.jsxRuntime,global.React,global.Immer);
|
|
1
|
+
var global,factory;global=this,factory=function(e,t,n,r,o){"use strict";function c(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const n in e)if("default"!==n){const r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:()=>e[n]})}return t.default=e,Object.freeze(t)}const i=c(r);class s{static Payload=Symbol("chizu.brand/Payload");static Broadcast=Symbol("chizu.brand/Broadcast");static Multicast=Symbol("chizu.brand/Multicast");static Action=Symbol("chizu.brand/Action");static Channel=Symbol("chizu.brand/Channel");static Node=Symbol("chizu.action.lifecycle/Node");static Cache=Symbol("chizu.brand/Cache")}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);
|
package/dist/error/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Props } from './types';
|
|
2
2
|
export { useError } from './utils';
|
|
3
|
-
export { Reason, AbortError, TimeoutError } from './types';
|
|
3
|
+
export { Reason, AbortError, TimeoutError, DisallowedError } from './types';
|
|
4
4
|
export type { Fault, Catcher } from './types';
|
|
5
5
|
/**
|
|
6
6
|
* Error boundary component for catching and handling errors from actions.
|
package/dist/error/types.d.ts
CHANGED
|
@@ -42,6 +42,19 @@ export declare class TimeoutError extends Error {
|
|
|
42
42
|
name: string;
|
|
43
43
|
constructor(message?: string);
|
|
44
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Error thrown when an action is blocked by the regulator policy.
|
|
47
|
+
* Works across all platforms including React Native where `DOMException` is unavailable.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* throw new DisallowedError("Action blocked by regulator");
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export declare class DisallowedError extends Error {
|
|
55
|
+
name: string;
|
|
56
|
+
constructor(message?: string);
|
|
57
|
+
}
|
|
45
58
|
/**
|
|
46
59
|
* Details about an error that occurred during action execution.
|
|
47
60
|
* @template E Custom error types to include in the union with Error.
|
|
@@ -53,7 +66,7 @@ export type Fault<E extends Error = never> = {
|
|
|
53
66
|
error: Error | E;
|
|
54
67
|
/** The name of the action that caused the error (e.g., "Increment"). */
|
|
55
68
|
action: string;
|
|
56
|
-
/** Whether the component has a `Lifecycle.Error` handler registered. */
|
|
69
|
+
/** Whether the component has a `Lifecycle.Error()` handler registered. */
|
|
57
70
|
handled: boolean;
|
|
58
71
|
/**
|
|
59
72
|
* All currently running tasks across the application.
|
package/dist/hooks/types.d.ts
CHANGED
package/dist/hooks/utils.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ export declare function isGenerator(result: unknown): result is Generator | Asyn
|
|
|
24
24
|
* - Mounting → (cached broadcast action values emitted here) → Mounted
|
|
25
25
|
* - Mounted → Unmounting → Unmounted
|
|
26
26
|
*/
|
|
27
|
-
export declare function useLifecycles({ unicast, broadcast, dispatchers, scope, phase, data, }: LifecycleConfig): void;
|
|
27
|
+
export declare function useLifecycles({ unicast, broadcast, dispatchers, scope, phase, data, handlers, }: LifecycleConfig): void;
|
|
28
28
|
/**
|
|
29
29
|
* Creates a data proxy for a given object, returning a memoized version.
|
|
30
30
|
* The proxy provides stable access to the object's properties,
|
|
@@ -69,6 +69,23 @@ export declare function useData<P extends Props>(props: P): P;
|
|
|
69
69
|
* ```
|
|
70
70
|
*/
|
|
71
71
|
export declare function With<K extends string>(key: K): <M extends Model, A extends Actions | void, D extends Props, P extends K extends keyof M ? M[K] : never>(context: HandlerContext<M, A, D>, payload: P) => void;
|
|
72
|
+
/**
|
|
73
|
+
* Scans a handler registry for a lifecycle action of the given type.
|
|
74
|
+
*
|
|
75
|
+
* When lifecycle actions become per-class instances (via `Lifecycle.Mount()`),
|
|
76
|
+
* each Actions class has its own unique symbol. Emission sites can no longer
|
|
77
|
+
* emit to a shared singleton — they must discover the component's lifecycle
|
|
78
|
+
* action by scanning the registry keys for matching lifecycle prefixes.
|
|
79
|
+
*
|
|
80
|
+
* Handler maps typically contain 5–15 entries, so the O(n) scan is trivial.
|
|
81
|
+
*
|
|
82
|
+
* @param handlers The handler map from a component's scope.
|
|
83
|
+
* @param type The lifecycle type to find (e.g. `"Mount"`, `"Unmount"`, `"Error"`).
|
|
84
|
+
* @returns The matching ActionId, or `null` if no lifecycle action of that type is registered.
|
|
85
|
+
*
|
|
86
|
+
* @internal
|
|
87
|
+
*/
|
|
88
|
+
export declare function findLifecycleAction(handlers: Map<ActionId, Set<unknown>>, type: string): ActionId | null;
|
|
72
89
|
export { isChanneledAction, getActionSymbol };
|
|
73
90
|
/**
|
|
74
91
|
* Manages sets of broadcast and multicast action IDs.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
export { Action } from './action/index.ts';
|
|
2
2
|
export { Entry } from './cache/index.ts';
|
|
3
3
|
export { Distribution, Lifecycle } from './types/index.ts';
|
|
4
|
-
export { Error, Reason } from './error/index.tsx';
|
|
4
|
+
export { Error, Reason, DisallowedError } from './error/index.tsx';
|
|
5
5
|
export { Operation, Op, State } from 'immertation';
|
|
6
6
|
export { annotate } from './annotate/index.ts';
|
|
7
7
|
export { Boundary } from './boundary/index.tsx';
|
|
8
|
+
export { Regulators } from './boundary/components/regulators/index.tsx';
|
|
8
9
|
export { Scope, withScope } from './boundary/components/scope/index.tsx';
|
|
9
10
|
export { useActions, With } from './hooks/index.ts';
|
|
10
11
|
export * as utils from './utils/index.ts';
|
|
11
12
|
export type { Box } from 'immertation';
|
|
12
13
|
export type { Fault, Catcher } from './error/index.tsx';
|
|
13
14
|
export type { Pk, Task, Tasks, Handlers } from './types/index.ts';
|
|
15
|
+
export type { Regulator } from './boundary/components/regulators/index.tsx';
|
package/dist/types/index.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ import { Operation, Process, Inspect, Box } from 'immertation';
|
|
|
2
2
|
import { ActionId, Task, Tasks } from '../boundary/components/tasks/types.ts';
|
|
3
3
|
import { Option } from '@mobily/ts-belt/Option';
|
|
4
4
|
import { Result as TsBeltResult } from '@mobily/ts-belt/Result';
|
|
5
|
+
import { Regulator } from '../boundary/components/regulators/types.ts';
|
|
6
|
+
import { Fault } from '../error/types.ts';
|
|
5
7
|
import * as React from "react";
|
|
6
8
|
export type { ActionId, Box, Task, Tasks };
|
|
7
9
|
/**
|
|
@@ -94,49 +96,59 @@ export type ChanneledCacheId<T = unknown, C = unknown> = {
|
|
|
94
96
|
readonly channel: C;
|
|
95
97
|
};
|
|
96
98
|
/**
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
+
* Factory functions for lifecycle actions.
|
|
100
|
+
*
|
|
101
|
+
* Each call returns a **unique** action symbol, enabling per-component
|
|
102
|
+
* regulation. Assign the result as a static property in your Actions class:
|
|
99
103
|
*
|
|
100
104
|
* @example
|
|
101
105
|
* ```ts
|
|
102
|
-
* class {
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
+
* export class Actions {
|
|
107
|
+
* static Mount = Lifecycle.Mount();
|
|
108
|
+
* static Unmount = Lifecycle.Unmount();
|
|
109
|
+
* static Error = Lifecycle.Error();
|
|
110
|
+
* static Update = Lifecycle.Update();
|
|
111
|
+
* static Node = Lifecycle.Node();
|
|
112
|
+
*
|
|
113
|
+
* static Increment = Action("Increment");
|
|
106
114
|
* }
|
|
115
|
+
*
|
|
116
|
+
* // Now regulating Lifecycle.Mount only blocks THIS component's mount:
|
|
117
|
+
* context.regulator.disallow(Actions.Mount);
|
|
107
118
|
* ```
|
|
108
119
|
*/
|
|
109
120
|
export declare class Lifecycle {
|
|
110
|
-
/** Triggered once
|
|
111
|
-
static
|
|
112
|
-
/** Triggered when the component unmounts. */
|
|
113
|
-
static
|
|
114
|
-
/** Triggered when an action throws
|
|
115
|
-
static
|
|
116
|
-
/** Triggered when `context.data`
|
|
117
|
-
static
|
|
121
|
+
/** Creates a Mount lifecycle action. Triggered once on component mount (`useLayoutEffect`). */
|
|
122
|
+
static Mount(): HandlerPayload<never>;
|
|
123
|
+
/** Creates an Unmount lifecycle action. Triggered when the component unmounts. */
|
|
124
|
+
static Unmount(): HandlerPayload<never>;
|
|
125
|
+
/** Creates an Error lifecycle action. Triggered when an action throws. Receives `Fault` as payload. */
|
|
126
|
+
static Error(): HandlerPayload<Fault>;
|
|
127
|
+
/** Creates an Update lifecycle action. Triggered when `context.data` changes (not on initial mount). */
|
|
128
|
+
static Update(): HandlerPayload<Record<string, unknown>>;
|
|
118
129
|
/**
|
|
119
|
-
* Triggered when a node is captured
|
|
120
|
-
* Supports channeled subscriptions by
|
|
121
|
-
*
|
|
122
|
-
* The payload is the captured node (or `null` when released).
|
|
130
|
+
* Creates a Node lifecycle action. Triggered when a DOM node is captured
|
|
131
|
+
* or released via `actions.node()`. Supports channeled subscriptions by
|
|
132
|
+
* node name.
|
|
123
133
|
*
|
|
124
134
|
* @example
|
|
125
135
|
* ```ts
|
|
136
|
+
* export class Actions {
|
|
137
|
+
* static Node = Lifecycle.Node();
|
|
138
|
+
* }
|
|
139
|
+
*
|
|
126
140
|
* // Subscribe to ALL node changes
|
|
127
|
-
* actions.useAction(
|
|
141
|
+
* actions.useAction(Actions.Node, (context, node) => {
|
|
128
142
|
* console.log("Node changed:", node);
|
|
129
143
|
* });
|
|
130
144
|
*
|
|
131
145
|
* // Subscribe to a specific node by name (channeled)
|
|
132
|
-
* actions.useAction(
|
|
133
|
-
* if (node)
|
|
134
|
-
* node.focus();
|
|
135
|
-
* }
|
|
146
|
+
* actions.useAction(Actions.Node({ Name: "input" }), (context, node) => {
|
|
147
|
+
* if (node) node.focus();
|
|
136
148
|
* });
|
|
137
149
|
* ```
|
|
138
150
|
*/
|
|
139
|
-
static Node: HandlerPayload<unknown, {
|
|
151
|
+
static Node(): HandlerPayload<unknown, {
|
|
140
152
|
Name: string;
|
|
141
153
|
}>;
|
|
142
154
|
}
|
|
@@ -540,6 +552,26 @@ export type HandlerContext<M extends Model | void, _AC extends Actions | void, D
|
|
|
540
552
|
readonly nodes: {
|
|
541
553
|
[K in keyof Nodes<M>]: Nodes<M>[K] | null;
|
|
542
554
|
};
|
|
555
|
+
/**
|
|
556
|
+
* The regulator API for controlling which actions may be dispatched.
|
|
557
|
+
*
|
|
558
|
+
* Each call replaces the previous policy entirely (last-write-wins).
|
|
559
|
+
* The policy is shared across all components within the same `<Boundary>`.
|
|
560
|
+
*
|
|
561
|
+
* @example
|
|
562
|
+
* ```ts
|
|
563
|
+
* actions.useAction(Actions.Mount, (context) => {
|
|
564
|
+
* // Block all actions except Critical
|
|
565
|
+
* context.regulator.allow(Actions.Critical);
|
|
566
|
+
* });
|
|
567
|
+
*
|
|
568
|
+
* actions.useAction(Actions.Unlock, (context) => {
|
|
569
|
+
* // Re-allow all actions
|
|
570
|
+
* context.regulator.allow();
|
|
571
|
+
* });
|
|
572
|
+
* ```
|
|
573
|
+
*/
|
|
574
|
+
readonly regulator: Regulator;
|
|
543
575
|
readonly actions: {
|
|
544
576
|
produce<F extends (draft: {
|
|
545
577
|
model: M;
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ export declare const config: {
|
|
|
13
13
|
channelPrefix: string;
|
|
14
14
|
/** Prefix for cache operation symbols. */
|
|
15
15
|
cachePrefix: string;
|
|
16
|
+
/** Prefix for lifecycle action symbols. */
|
|
17
|
+
lifecyclePrefix: string;
|
|
16
18
|
};
|
|
17
19
|
/**
|
|
18
20
|
* Returns a promise that resolves after the specified number of milliseconds.
|