chizu 0.2.34 → 0.2.35
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 +88 -118
- package/dist/action/index.d.ts +13 -6
- package/dist/broadcast/index.d.ts +7 -7
- package/dist/broadcast/index.test.d.ts +1 -0
- package/dist/broadcast/utils.d.ts +9 -4
- package/dist/chizu.js +180 -96
- package/dist/chizu.umd.cjs +2 -2
- package/dist/error/index.d.ts +10 -4
- package/dist/error/index.test.d.ts +1 -0
- package/dist/error/utils.d.ts +11 -0
- package/dist/hooks/index.d.ts +7 -7
- package/dist/hooks/utils.d.ts +1 -1
- package/dist/hooks/utils.test.d.ts +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/types/index.d.ts +4 -2
- package/dist/use/index.d.ts +28 -3
- package/dist/use/types.d.ts +9 -3
- package/dist/use/utils.d.ts +12 -3
- package/dist/use/utils.test.d.ts +1 -0
- package/dist/utils/index.d.ts +7 -1
- package/dist/utils/index.test.d.ts +1 -0
- package/package.json +3 -1
- package/dist/decorators/index.d.ts +0 -6
- package/dist/utils/sleep/index.d.ts +0 -1
- /package/dist/{broadcast/utils.test.d.ts → action/index.test.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -14,9 +14,10 @@ Strongly typed React framework using generators and efficiently updated views al
|
|
|
14
14
|
1. [Benefits](#benefits)
|
|
15
15
|
1. [Getting started](#getting-started)
|
|
16
16
|
1. [Error handling](#error-handling)
|
|
17
|
-
|
|
18
|
-
1. [
|
|
19
|
-
1. [
|
|
17
|
+
1. [Model annotations](#model-annotations)
|
|
18
|
+
1. [Lifecycle actions](#lifecycle-actions)
|
|
19
|
+
1. [Distributed actions](#distributed-actions)
|
|
20
|
+
1. [Action decorators](#action-decorators)
|
|
20
21
|
|
|
21
22
|
## Benefits
|
|
22
23
|
|
|
@@ -81,17 +82,19 @@ export class Actions {
|
|
|
81
82
|
}
|
|
82
83
|
|
|
83
84
|
export default function useNameActions() {
|
|
84
|
-
const nameAction = useAction<Model, typeof Actions
|
|
85
|
-
context
|
|
86
|
-
draft
|
|
87
|
-
|
|
85
|
+
const nameAction = useAction<Model, typeof Actions, "Name">(
|
|
86
|
+
async (context) => {
|
|
87
|
+
context.actions.produce((draft) => {
|
|
88
|
+
draft.name = null;
|
|
89
|
+
});
|
|
88
90
|
|
|
89
|
-
|
|
91
|
+
const name = await fetch(/* ... */);
|
|
90
92
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
93
|
+
context.actions.produce((draft) => {
|
|
94
|
+
draft.name = name;
|
|
95
|
+
});
|
|
96
|
+
},
|
|
97
|
+
);
|
|
95
98
|
|
|
96
99
|
return useActions<Model, typeof Actions>(
|
|
97
100
|
model,
|
|
@@ -120,160 +123,127 @@ export default function Profile(props: Props): React.ReactElement {
|
|
|
120
123
|
|
|
121
124
|
## Error handling
|
|
122
125
|
|
|
123
|
-
Chizu provides a simple way to catch errors that occur within your actions. You can use the `
|
|
126
|
+
Chizu provides a simple way to catch errors that occur within your actions. You can use the `Error` component to wrap your application and provide an error handler. This handler will be called whenever an error is thrown in an action.
|
|
124
127
|
|
|
125
128
|
```tsx
|
|
126
|
-
import {
|
|
129
|
+
import { Error } from "chizu";
|
|
127
130
|
|
|
128
131
|
const App = () => (
|
|
129
|
-
<
|
|
132
|
+
<Error handler={(error) => console.error(error)}>
|
|
130
133
|
<Profile />
|
|
131
|
-
</
|
|
134
|
+
</Error>
|
|
132
135
|
);
|
|
133
136
|
```
|
|
134
137
|
|
|
135
|
-
##
|
|
138
|
+
## Model annotations
|
|
139
|
+
|
|
140
|
+
Model annotations allow you to track the state of async operations on individual model fields. This is useful for showing loading indicators, optimistic updates, and tracking pending changes.
|
|
141
|
+
|
|
142
|
+
Use `context.actions.annotate` to mark a value with an operation type. The view can then inspect the field to check if it's pending, get the draft value, or check the operation type:
|
|
136
143
|
|
|
137
144
|
```ts
|
|
138
145
|
import { Op } from "chizu";
|
|
139
146
|
|
|
140
|
-
// Mark a value as pending with an operation
|
|
141
147
|
context.actions.produce((model) => {
|
|
142
148
|
model.name = context.actions.annotate(Op.Update, "New Name");
|
|
143
149
|
});
|
|
150
|
+
```
|
|
144
151
|
|
|
145
|
-
|
|
146
|
-
actions.inspect.name.pending(); // true
|
|
147
|
-
|
|
148
|
-
// Get remaining count of pending operations
|
|
149
|
-
actions.inspect.name.remaining(); // 1 (next: actions.inspect.name.draft())
|
|
152
|
+
In the view, use `actions.inspect` to check the state of annotated fields:
|
|
150
153
|
|
|
151
|
-
|
|
152
|
-
actions.inspect.name.
|
|
154
|
+
```ts
|
|
155
|
+
actions.inspect.name.pending(); // true if operation is in progress
|
|
156
|
+
actions.inspect.name.remaining(); // count of pending operations
|
|
157
|
+
actions.inspect.name.draft(); // the next value to be applied
|
|
158
|
+
actions.inspect.name.is(Op.Update); // check specific operation type
|
|
153
159
|
```
|
|
154
160
|
|
|
155
|
-
|
|
161
|
+
## Lifecycle actions
|
|
156
162
|
|
|
157
|
-
|
|
158
|
-
export default <Actions<Module>>function Actions(module) {
|
|
159
|
-
return {
|
|
160
|
-
async *[Action.Name]() {
|
|
161
|
-
yield module.actions.produce((draft) => {
|
|
162
|
-
draft.name = module.actions.annotate(null);
|
|
163
|
-
});
|
|
163
|
+
Chizu provides lifecycle actions that trigger at specific points in a component's lifecycle. Import `Lifecycle` from Chizu:
|
|
164
164
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
draft.name = name;
|
|
168
|
-
});
|
|
169
|
-
},
|
|
170
|
-
};
|
|
171
|
-
};
|
|
172
|
-
```
|
|
165
|
+
```ts
|
|
166
|
+
import { Lifecycle } from "chizu";
|
|
173
167
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
{(module) => (
|
|
179
|
-
<>
|
|
180
|
-
<p>Hey {module.model.name}</p>
|
|
181
|
-
|
|
182
|
-
{module.validate.name.pending() && <p>Switching profiles…</p>}
|
|
183
|
-
|
|
184
|
-
<button
|
|
185
|
-
disabled={module.validate.name.is(State.Op.Update)}
|
|
186
|
-
onClick={() => module.actions.dispatch([Action.Name])}
|
|
187
|
-
>
|
|
188
|
-
Switch profile
|
|
189
|
-
</button>
|
|
190
|
-
</>
|
|
191
|
-
)}
|
|
192
|
-
</Scope>
|
|
193
|
-
);
|
|
168
|
+
class {
|
|
169
|
+
[Lifecycle.Mount] = mountAction;
|
|
170
|
+
[Lifecycle.Node] = nodeAction;
|
|
171
|
+
[Lifecycle.Unmount] = unmountAction;
|
|
194
172
|
}
|
|
195
173
|
```
|
|
196
174
|
|
|
197
|
-
|
|
175
|
+
- **`Lifecycle.Mount`** – Triggered once when the component mounts (`useLayoutEffect`).
|
|
176
|
+
- **`Lifecycle.Node`** – Triggered after the component renders (`useEffect`).
|
|
177
|
+
- **`Lifecycle.Unmount`** – Triggered when the component unmounts.
|
|
198
178
|
|
|
199
179
|
## Distributed actions
|
|
200
180
|
|
|
201
|
-
|
|
181
|
+
Distributed actions allow different components to communicate with each other. Unlike regular actions which are scoped to a single component, distributed actions are broadcast to all mounted components that have defined a handler for them.
|
|
182
|
+
|
|
183
|
+
To create a distributed action, use `createDistributedAction` instead of `createAction`. A good pattern is to define distributed actions in a shared class that other action classes can extend:
|
|
202
184
|
|
|
203
185
|
```ts
|
|
204
|
-
|
|
205
|
-
|
|
186
|
+
import { createAction, createDistributedAction } from "chizu";
|
|
187
|
+
|
|
188
|
+
export class DistributedActions {
|
|
189
|
+
static SignedOut = createDistributedAction();
|
|
206
190
|
}
|
|
207
191
|
|
|
208
|
-
export
|
|
192
|
+
export class Actions extends DistributedActions {
|
|
193
|
+
static Increment = createAction();
|
|
194
|
+
}
|
|
209
195
|
```
|
|
210
196
|
|
|
211
|
-
|
|
197
|
+
Any component that defines a handler for `DistributedActions.SignedOut` will receive the action when it's dispatched from any other component. For direct access to the broadcast emitter, use `useBroadcast()`.
|
|
212
198
|
|
|
213
|
-
|
|
214
|
-
export type Actions = DistributedActions | [Action.Task, string]; // etc...
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
## Module dispatch
|
|
199
|
+
## Action decorators
|
|
218
200
|
|
|
219
|
-
|
|
201
|
+
Chizu provides decorators to add common functionality to your actions. Import `use` from Chizu and apply decorators to action properties:
|
|
220
202
|
|
|
221
203
|
```ts
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
// ...
|
|
225
|
-
|
|
226
|
-
module.actions.dispatch([Action.Task, "My task that needs to be done."]);
|
|
204
|
+
import { use } from "chizu";
|
|
227
205
|
```
|
|
228
206
|
|
|
229
|
-
|
|
207
|
+
### `use.exclusive()`
|
|
208
|
+
|
|
209
|
+
Ensures only one instance of an action runs at a time. When a new action is dispatched, any previous running instance is automatically aborted. Use `context.signal` to cancel in-flight requests:
|
|
230
210
|
|
|
231
211
|
```ts
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
}
|
|
212
|
+
const searchAction = useAction<Model, typeof Actions, "Search">(
|
|
213
|
+
async (context, query) => {
|
|
214
|
+
const response = await fetch(`/search?q=${query}`, {
|
|
215
|
+
signal: context.signal,
|
|
216
|
+
});
|
|
217
|
+
},
|
|
218
|
+
);
|
|
219
|
+
|
|
220
|
+
return useActions<Model, typeof Actions>(
|
|
221
|
+
model,
|
|
222
|
+
class {
|
|
223
|
+
@use.exclusive()
|
|
224
|
+
[Actions.Search] = searchAction;
|
|
225
|
+
},
|
|
226
|
+
);
|
|
235
227
|
```
|
|
236
228
|
|
|
237
|
-
|
|
229
|
+
### `use.reactive(() => [dependencies])`
|
|
238
230
|
|
|
239
|
-
|
|
231
|
+
Automatically triggers an action when its dependencies change. Dependencies must be primitives (strings, numbers, booleans, etc.) which means you never have to worry about referential equality:
|
|
240
232
|
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
return {
|
|
248
|
-
[Action.Name](name) {
|
|
249
|
-
return module.actions.produce((draft) => {
|
|
250
|
-
draft.name = context.name;
|
|
251
|
-
});
|
|
252
|
-
},
|
|
253
|
-
};
|
|
254
|
-
};
|
|
233
|
+
```ts
|
|
234
|
+
class {
|
|
235
|
+
@use.reactive(() => [props.userId])
|
|
236
|
+
[Actions.FetchUser] = fetchUserAction;
|
|
237
|
+
}
|
|
255
238
|
```
|
|
256
239
|
|
|
257
|
-
|
|
240
|
+
### `use.debug()`
|
|
258
241
|
|
|
259
|
-
|
|
260
|
-
export default function Profile(props: Props): React.ReactElement {
|
|
261
|
-
const name = React.useContext(NameContext);
|
|
242
|
+
Logs detailed timing information for debugging, including when the action started, how many `produce` calls were made, and total duration:
|
|
262
243
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
<p>Hey {module.model.name}</p>
|
|
268
|
-
|
|
269
|
-
<button
|
|
270
|
-
onClick={() => module.actions.dispatch([Action.Name, randomName()])}
|
|
271
|
-
>
|
|
272
|
-
Switch profile
|
|
273
|
-
</button>
|
|
274
|
-
</>
|
|
275
|
-
)}
|
|
276
|
-
</Scope>
|
|
277
|
-
);
|
|
244
|
+
```ts
|
|
245
|
+
class {
|
|
246
|
+
@use.debug()
|
|
247
|
+
[Actions.Submit] = submitAction;
|
|
278
248
|
}
|
|
279
|
-
```
|
|
249
|
+
```
|
package/dist/action/index.d.ts
CHANGED
|
@@ -1,19 +1,26 @@
|
|
|
1
|
-
import { Action, Payload } from '../types';
|
|
1
|
+
import { Action, Payload } from '../types/index.ts';
|
|
2
2
|
/**
|
|
3
3
|
* Defines a new action with a given payload type.
|
|
4
4
|
*
|
|
5
5
|
* @template T The type of the payload that the action will carry.
|
|
6
|
-
* @param
|
|
7
|
-
* @returns
|
|
6
|
+
* @param name An optional name for the action, used for debugging purposes.
|
|
7
|
+
* @returns A new action symbol.
|
|
8
8
|
*/
|
|
9
9
|
export declare function createAction<T = never>(name?: string): Payload<T>;
|
|
10
10
|
/**
|
|
11
11
|
* Defines a new distributed action with a given payload type.
|
|
12
|
-
* Distributed actions
|
|
12
|
+
* Distributed actions are broadcast to all mounted components that have defined a handler for them.
|
|
13
13
|
*
|
|
14
14
|
* @template T The type of the payload that the action will carry.
|
|
15
|
-
* @param
|
|
16
|
-
* @returns
|
|
15
|
+
* @param name An optional name for the action, used for debugging purposes.
|
|
16
|
+
* @returns A new distributed action symbol.
|
|
17
17
|
*/
|
|
18
18
|
export declare function createDistributedAction<T = never>(name?: string): Payload<T>;
|
|
19
|
+
/**
|
|
20
|
+
* Checks whether an action is a distributed action.
|
|
21
|
+
* Distributed actions are broadcast to all mounted components that have defined a handler for them.
|
|
22
|
+
*
|
|
23
|
+
* @param action The action to check.
|
|
24
|
+
* @returns True if the action is a distributed action, false otherwise.
|
|
25
|
+
*/
|
|
19
26
|
export declare function isDistributedAction(action: Action): boolean;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Props } from './types.ts';
|
|
2
2
|
import * as React from "react";
|
|
3
|
-
export
|
|
3
|
+
export { useBroadcast } from './utils.ts';
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* with the app's broadcast context.
|
|
5
|
+
* Creates a new broadcast context for distributed actions. Only needed if you
|
|
6
|
+
* want to isolate a broadcast context, useful for libraries that want to provide
|
|
7
|
+
* their own broadcast context without interfering with the app's broadcast context.
|
|
8
8
|
*
|
|
9
|
-
* @param
|
|
10
|
-
* @returns
|
|
9
|
+
* @param props.children - The children to render within the broadcast context.
|
|
10
|
+
* @returns The children wrapped in a broadcast context provider.
|
|
11
11
|
*/
|
|
12
12
|
export declare function Broadcaster({ children }: Props): React.ReactNode;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
+
import { BroadcastContext } from './types.ts';
|
|
2
|
+
import * as React from "react";
|
|
1
3
|
/**
|
|
2
|
-
*
|
|
4
|
+
* React context for broadcasting distributed actions across components.
|
|
5
|
+
*/
|
|
6
|
+
export declare const Context: React.Context<BroadcastContext>;
|
|
7
|
+
/**
|
|
8
|
+
* Hook to access the broadcast context for emitting and listening to distributed actions.
|
|
3
9
|
*
|
|
4
|
-
* @
|
|
5
|
-
* @returns {boolean}
|
|
10
|
+
* @returns The broadcast context containing the EventEmitter instance.
|
|
6
11
|
*/
|
|
7
|
-
export declare function
|
|
12
|
+
export declare function useBroadcast(): BroadcastContext;
|
package/dist/chizu.js
CHANGED
|
@@ -1,168 +1,252 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import * as
|
|
3
|
-
import { createContext as
|
|
4
|
-
import
|
|
5
|
-
import { State as
|
|
6
|
-
import { Op as
|
|
7
|
-
const
|
|
8
|
-
function
|
|
9
|
-
return
|
|
10
|
-
}
|
|
11
|
-
function
|
|
1
|
+
import { jsx as x } from "react/jsx-runtime";
|
|
2
|
+
import * as i from "react";
|
|
3
|
+
import { createContext as P, useContext as j } from "react";
|
|
4
|
+
import v from "eventemitter3";
|
|
5
|
+
import { State as _ } from "immertation";
|
|
6
|
+
import { Op as te, Operation as ne, State as oe } from "immertation";
|
|
7
|
+
const C = P(void 0);
|
|
8
|
+
function A() {
|
|
9
|
+
return j(C);
|
|
10
|
+
}
|
|
11
|
+
function q({
|
|
12
12
|
handler: e,
|
|
13
13
|
children: t
|
|
14
14
|
}) {
|
|
15
|
-
return /* @__PURE__ */
|
|
15
|
+
return /* @__PURE__ */ x(C.Provider, { value: e, children: t });
|
|
16
16
|
}
|
|
17
|
-
function
|
|
17
|
+
function H(e = "anonymous") {
|
|
18
18
|
return Symbol(`chizu.action/${e}`);
|
|
19
19
|
}
|
|
20
|
-
function
|
|
20
|
+
function J(e = "anonymous") {
|
|
21
21
|
return Symbol(`chizu.action/distributed/${e}`);
|
|
22
22
|
}
|
|
23
|
-
function
|
|
23
|
+
function w(e) {
|
|
24
24
|
return e.toString().startsWith("Symbol(chizu.action/distributed/");
|
|
25
25
|
}
|
|
26
|
-
|
|
26
|
+
const $ = Symbol("chizu.action.context");
|
|
27
|
+
class h {
|
|
27
28
|
static Mount = Symbol("lifecycle/mount");
|
|
28
29
|
static Node = Symbol("lifecycle/node");
|
|
29
30
|
static Derive = Symbol("lifecycle/derive");
|
|
30
31
|
static Error = Symbol("lifecycle/error");
|
|
31
32
|
static Unmount = Symbol("lifecycle/unmount");
|
|
32
33
|
}
|
|
33
|
-
function
|
|
34
|
+
function D(e) {
|
|
34
35
|
return new Promise((t) => setTimeout(t, e));
|
|
35
36
|
}
|
|
36
|
-
function
|
|
37
|
+
function k(e) {
|
|
37
38
|
return e ? !!(e && typeof e != "symbol") : Symbol(`pk.${Date.now()}.${crypto.randomUUID()}`);
|
|
38
39
|
}
|
|
39
|
-
const
|
|
40
|
-
function
|
|
41
|
-
return (t,
|
|
40
|
+
const F = k;
|
|
41
|
+
function M(e) {
|
|
42
|
+
return (t, n) => {
|
|
42
43
|
t.actions.produce((s) => {
|
|
43
|
-
s[e] =
|
|
44
|
+
s[e] = n;
|
|
44
45
|
});
|
|
45
46
|
};
|
|
46
47
|
}
|
|
47
|
-
const
|
|
48
|
+
const R = M, K = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
48
49
|
__proto__: null,
|
|
49
|
-
pk:
|
|
50
|
-
set:
|
|
51
|
-
sleep:
|
|
52
|
-
κ:
|
|
53
|
-
λ:
|
|
54
|
-
}, Symbol.toStringTag, { value: "Module" })),
|
|
55
|
-
instance: new
|
|
50
|
+
pk: k,
|
|
51
|
+
set: M,
|
|
52
|
+
sleep: D,
|
|
53
|
+
κ: F,
|
|
54
|
+
λ: R
|
|
55
|
+
}, Symbol.toStringTag, { value: "Module" })), O = i.createContext({
|
|
56
|
+
instance: new v()
|
|
56
57
|
});
|
|
57
|
-
function
|
|
58
|
-
return
|
|
58
|
+
function G() {
|
|
59
|
+
return i.useContext(O);
|
|
59
60
|
}
|
|
60
|
-
function
|
|
61
|
+
function Q({
|
|
61
62
|
children: e
|
|
62
63
|
}) {
|
|
63
|
-
const t =
|
|
64
|
-
instance: new
|
|
64
|
+
const t = i.useMemo(() => ({
|
|
65
|
+
instance: new v()
|
|
65
66
|
}), []);
|
|
66
|
-
return /* @__PURE__ */
|
|
67
|
+
return /* @__PURE__ */ x(O.Provider, { value: t, children: e });
|
|
67
68
|
}
|
|
68
|
-
function
|
|
69
|
-
return Object.keys(e).reduce((
|
|
69
|
+
function I(e, t) {
|
|
70
|
+
return Object.keys(e).reduce((n, s) => (Object.defineProperty(n, s, {
|
|
70
71
|
get() {
|
|
71
72
|
return t.current[s];
|
|
72
73
|
},
|
|
73
74
|
enumerable: !0
|
|
74
|
-
}),
|
|
75
|
+
}), n), {});
|
|
75
76
|
}
|
|
76
|
-
const
|
|
77
|
-
function
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
const E = /* @__PURE__ */ new WeakMap(), S = /* @__PURE__ */ new WeakMap();
|
|
78
|
+
function L(e) {
|
|
79
|
+
return typeof e == "symbol" ? e.description ?? "unknown" : e;
|
|
80
|
+
}
|
|
81
|
+
const V = {
|
|
82
|
+
/**
|
|
83
|
+
* Ensures only one instance of an action runs at a time. When dispatched again,
|
|
84
|
+
* the previous instance is aborted via `context.signal`.
|
|
85
|
+
*
|
|
86
|
+
* @returns A decorator function for the action.
|
|
87
|
+
*/
|
|
88
|
+
exclusive() {
|
|
89
|
+
return function(e, t) {
|
|
90
|
+
t.addInitializer(function() {
|
|
91
|
+
const n = this, s = n[t.name];
|
|
92
|
+
n[t.name] = async (u) => (E.get(n)?.controller.abort(), E.set(n, u[$]), await s.call(n, u));
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
},
|
|
96
|
+
/**
|
|
97
|
+
* Automatically triggers an action when its primitive dependencies change.
|
|
98
|
+
* Dependencies must be primitives (strings, numbers, booleans, etc.) to avoid
|
|
99
|
+
* referential equality issues.
|
|
100
|
+
*
|
|
101
|
+
* @param getDependencies A function returning an array of primitive dependencies.
|
|
102
|
+
* @returns A decorator function for the action.
|
|
103
|
+
*/
|
|
104
|
+
reactive(e) {
|
|
105
|
+
return function(t, n) {
|
|
106
|
+
n.addInitializer(function() {
|
|
107
|
+
const s = this, u = S.get(s) ?? [];
|
|
108
|
+
u.push({
|
|
109
|
+
action: n.name,
|
|
110
|
+
getDependencies: e
|
|
111
|
+
}), S.set(s, u);
|
|
112
|
+
});
|
|
113
|
+
};
|
|
114
|
+
},
|
|
115
|
+
/**
|
|
116
|
+
* Logs detailed timing and debugging information for the action, including
|
|
117
|
+
* start time, produce call timings, and total duration.
|
|
118
|
+
*
|
|
119
|
+
* @returns A decorator function for the action.
|
|
120
|
+
*/
|
|
121
|
+
debug() {
|
|
122
|
+
return function(e, t) {
|
|
123
|
+
t.addInitializer(function() {
|
|
124
|
+
const n = this, s = n[t.name], u = L(t.name);
|
|
125
|
+
n[t.name] = async (m) => {
|
|
126
|
+
let p = 0;
|
|
127
|
+
const f = performance.now(), y = [];
|
|
128
|
+
console.group(`🔧 Action: ${u}`), console.log("⏱️ Started at:", (/* @__PURE__ */ new Date()).toISOString());
|
|
129
|
+
const g = m.actions.produce, a = {
|
|
130
|
+
...m,
|
|
131
|
+
actions: {
|
|
132
|
+
...m.actions,
|
|
133
|
+
produce: (o) => {
|
|
134
|
+
p++;
|
|
135
|
+
const r = performance.now(), c = g(o), d = performance.now() - r;
|
|
136
|
+
return y.push(d), console.log(` 📝 produce #${p}: ${d.toFixed(2)}ms`), c;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
try {
|
|
141
|
+
const o = await s.call(n, a), c = performance.now() - f;
|
|
142
|
+
return console.log("─".repeat(40)), console.log(`📊 Summary for ${u}:`), console.log(` Total produce calls: ${p}`), y.length > 0 && console.log(` Produce times: ${y.map((l) => l.toFixed(2) + "ms").join(", ")}`), console.log(` ⏱️ Total duration: ${c.toFixed(2)}ms`), console.groupEnd(), o;
|
|
143
|
+
} catch (o) {
|
|
144
|
+
const r = performance.now();
|
|
145
|
+
throw console.error(`❌ Error in ${u}:`, o), console.log(` ⏱️ Failed after: ${(r - f).toFixed(2)}ms`), console.groupEnd(), o;
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
});
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
function X(e) {
|
|
153
|
+
const t = A();
|
|
154
|
+
return i.useCallback(async (n, s) => {
|
|
80
155
|
try {
|
|
81
156
|
if (e.constructor.name === "GeneratorFunction" || e.constructor.name === "AsyncGeneratorFunction") {
|
|
82
|
-
const
|
|
83
|
-
for await (const
|
|
157
|
+
const m = e(n, s);
|
|
158
|
+
for await (const p of m) ;
|
|
84
159
|
} else
|
|
85
|
-
await e(
|
|
86
|
-
} catch (
|
|
160
|
+
await e(n, s);
|
|
161
|
+
} catch (u) {
|
|
87
162
|
console.error(`Chizu
|
|
88
163
|
|
|
89
|
-
`,
|
|
164
|
+
`, u), t?.(u);
|
|
90
165
|
}
|
|
91
166
|
}, [e, t]);
|
|
92
167
|
}
|
|
93
|
-
function
|
|
94
|
-
const
|
|
168
|
+
function Y(e, t) {
|
|
169
|
+
const n = G(), [s, u] = i.useState(e), m = i.useRef(new _(e)), p = T({
|
|
95
170
|
model: s
|
|
96
|
-
}),
|
|
171
|
+
}), f = i.useMemo(() => new v(), []), y = i.useRef({
|
|
172
|
+
previous: /* @__PURE__ */ new Map()
|
|
173
|
+
}), g = i.useCallback((a) => {
|
|
97
174
|
const o = new AbortController();
|
|
98
175
|
return {
|
|
99
176
|
signal: o.signal,
|
|
100
177
|
actions: {
|
|
101
|
-
produce(
|
|
178
|
+
produce(r) {
|
|
102
179
|
if (o.signal.aborted) return;
|
|
103
|
-
const
|
|
104
|
-
|
|
180
|
+
const c = m.current.mutate((l) => r(l));
|
|
181
|
+
u(m.current.model), a.processes.add(c);
|
|
105
182
|
},
|
|
106
|
-
dispatch(...[
|
|
107
|
-
o.signal.aborted || (
|
|
183
|
+
dispatch(...[r, c]) {
|
|
184
|
+
o.signal.aborted || (w(r) ? n.instance.emit(r, c) : f.emit(r, c));
|
|
108
185
|
},
|
|
109
|
-
annotate(
|
|
110
|
-
return
|
|
186
|
+
annotate(r, c) {
|
|
187
|
+
return m.current.annotate(r, c);
|
|
111
188
|
}
|
|
112
189
|
},
|
|
113
|
-
[
|
|
190
|
+
[$]: {
|
|
114
191
|
controller: o
|
|
115
192
|
}
|
|
116
193
|
};
|
|
117
|
-
}, [
|
|
118
|
-
return
|
|
119
|
-
const
|
|
120
|
-
Object.getOwnPropertySymbols(
|
|
121
|
-
const
|
|
122
|
-
if (
|
|
123
|
-
return void
|
|
124
|
-
const
|
|
194
|
+
}, [p.model]);
|
|
195
|
+
return i.useLayoutEffect(() => {
|
|
196
|
+
const a = new t();
|
|
197
|
+
Object.getOwnPropertySymbols(a).forEach((o) => {
|
|
198
|
+
const r = o;
|
|
199
|
+
if (w(o))
|
|
200
|
+
return void n.instance.on(o, async (c) => {
|
|
201
|
+
const l = {
|
|
125
202
|
processes: /* @__PURE__ */ new Set()
|
|
126
|
-
},
|
|
127
|
-
await
|
|
203
|
+
}, d = Promise.withResolvers();
|
|
204
|
+
await a[r](g(l), c), l.processes.forEach((b) => m.current.prune(b)), d.resolve();
|
|
128
205
|
});
|
|
129
|
-
|
|
130
|
-
const
|
|
206
|
+
f.on(o, async (c) => {
|
|
207
|
+
const l = {
|
|
131
208
|
processes: /* @__PURE__ */ new Set()
|
|
132
|
-
},
|
|
133
|
-
await
|
|
209
|
+
}, d = Promise.withResolvers();
|
|
210
|
+
await a[r](g(l), c), l.processes.forEach((b) => m.current.prune(b)), d.resolve();
|
|
134
211
|
});
|
|
135
212
|
});
|
|
136
|
-
}, [
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
213
|
+
}, [f]), i.useEffect(() => {
|
|
214
|
+
const a = new t();
|
|
215
|
+
(S.get(a) ?? []).forEach((r) => {
|
|
216
|
+
const c = r.getDependencies(), l = y.current.previous.get(r.action) ?? [];
|
|
217
|
+
(c.length !== l.length || c.some((b, z) => !Object.is(b, l[z]))) && (y.current.previous.set(r.action, [...c]), f.emit(r.action));
|
|
218
|
+
});
|
|
219
|
+
}), i.useLayoutEffect(() => (f.emit(h.Mount), () => void f.emit(h.Unmount)), []), i.useEffect(() => {
|
|
220
|
+
f.emit(h.Node);
|
|
221
|
+
}, []), i.useMemo(() => [s, {
|
|
222
|
+
dispatch(...[a, o]) {
|
|
223
|
+
w(a) ? n.instance.emit(a, o) : f.emit(a, o);
|
|
141
224
|
},
|
|
142
225
|
consume() {
|
|
143
226
|
},
|
|
144
227
|
get inspect() {
|
|
145
|
-
return
|
|
228
|
+
return m.current.inspect;
|
|
146
229
|
}
|
|
147
|
-
}], [s,
|
|
230
|
+
}], [s, f]);
|
|
148
231
|
}
|
|
149
|
-
function
|
|
150
|
-
const t =
|
|
151
|
-
return
|
|
232
|
+
function T(e) {
|
|
233
|
+
const t = i.useRef(e);
|
|
234
|
+
return i.useLayoutEffect(() => {
|
|
152
235
|
t.current = e;
|
|
153
|
-
}, [e]),
|
|
236
|
+
}, [e]), i.useMemo(() => I(e, t), [e]);
|
|
154
237
|
}
|
|
155
238
|
export {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
239
|
+
Q as Broadcaster,
|
|
240
|
+
q as Error,
|
|
241
|
+
h as Lifecycle,
|
|
242
|
+
te as Op,
|
|
243
|
+
ne as Operation,
|
|
244
|
+
oe as State,
|
|
245
|
+
H as createAction,
|
|
246
|
+
J as createDistributedAction,
|
|
247
|
+
V as use,
|
|
248
|
+
X as useAction,
|
|
249
|
+
Y as useActions,
|
|
250
|
+
T as useSnapshot,
|
|
251
|
+
K as utils
|
|
168
252
|
};
|
package/dist/chizu.umd.cjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(o,b){typeof exports=="object"&&typeof module<"u"?b(exports,require("react/jsx-runtime"),require("react"),require("eventemitter3"),require("immertation")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react","eventemitter3","immertation"],b):(o=typeof globalThis<"u"?globalThis:o||self,b(o.Chizu={},o.jsxRuntime,o.React,o.EventEmitter3,o.Immertation))})(this,(function(o,b,O,j,w){"use strict";function D(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const n in e)if(n!=="default"){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 u=D(O),C=O.createContext(void 0);function x(){return O.useContext(C)}function T({handler:e,children:t}){return b.jsx(C.Provider,{value:e,children:t})}function F(e="anonymous"){return Symbol(`chizu.action/${e}`)}function I(e="anonymous"){return Symbol(`chizu.action/distributed/${e}`)}function E(e){return e.toString().startsWith("Symbol(chizu.action/distributed/")}const $=Symbol("chizu.action.context");class S{static Mount=Symbol("lifecycle/mount");static Node=Symbol("lifecycle/node");static Derive=Symbol("lifecycle/derive");static Error=Symbol("lifecycle/error");static Unmount=Symbol("lifecycle/unmount")}function G(e){return new Promise(t=>setTimeout(t,e))}function M(e){return e?!!(e&&typeof e!="symbol"):Symbol(`pk.${Date.now()}.${crypto.randomUUID()}`)}const L=M;function k(e){return(t,n)=>{t.actions.produce(r=>{r[e]=n})}}const R=Object.freeze(Object.defineProperty({__proto__:null,pk:M,set:k,sleep:G,κ:L,λ:k},Symbol.toStringTag,{value:"Module"})),z=u.createContext({instance:new j});function q(){return u.useContext(z)}function B({children:e}){const t=u.useMemo(()=>({instance:new j}),[]);return b.jsx(z.Provider,{value:t,children:e})}function N(e,t){return Object.keys(e).reduce((n,r)=>(Object.defineProperty(n,r,{get(){return t.current[r]},enumerable:!0}),n),{})}const A=new WeakMap,P=new WeakMap;function U(e){return typeof e=="symbol"?e.description??"unknown":e}const W={exclusive(){return function(e,t){t.addInitializer(function(){const n=this,r=n[t.name];n[t.name]=async a=>(A.get(n)?.controller.abort(),A.set(n,a[$]),await r.call(n,a))})}},reactive(e){return function(t,n){n.addInitializer(function(){const r=this,a=P.get(r)??[];a.push({action:n.name,getDependencies:e}),P.set(r,a)})}},debug(){return function(e,t){t.addInitializer(function(){const n=this,r=n[t.name],a=U(t.name);n[t.name]=async m=>{let y=0;const d=performance.now(),g=[];console.group(`🔧 Action: ${a}`),console.log("⏱️ Started at:",new Date().toISOString());const v=m.actions.produce,l={...m,actions:{...m.actions,produce:c=>{y++;const s=performance.now(),i=v(c),p=performance.now()-s;return g.push(p),console.log(` 📝 produce #${y}: ${p.toFixed(2)}ms`),i}}};try{const c=await r.call(n,l),i=performance.now()-d;return console.log("─".repeat(40)),console.log(`📊 Summary for ${a}:`),console.log(` Total produce calls: ${y}`),g.length>0&&console.log(` Produce times: ${g.map(f=>f.toFixed(2)+"ms").join(", ")}`),console.log(` ⏱️ Total duration: ${i.toFixed(2)}ms`),console.groupEnd(),c}catch(c){const s=performance.now();throw console.error(`❌ Error in ${a}:`,c),console.log(` ⏱️ Failed after: ${(s-d).toFixed(2)}ms`),console.groupEnd(),c}}})}}};function H(e){const t=x();return u.useCallback(async(n,r)=>{try{if(e.constructor.name==="GeneratorFunction"||e.constructor.name==="AsyncGeneratorFunction"){const m=e(n,r);for await(const y of m);}else await e(n,r)}catch(a){console.error(`Chizu
|
|
2
2
|
|
|
3
|
-
`,
|
|
3
|
+
`,a),t?.(a)}},[e,t])}function J(e,t){const n=q(),[r,a]=u.useState(e),m=u.useRef(new w.State(e)),y=_({model:r}),d=u.useMemo(()=>new j,[]),g=u.useRef({previous:new Map}),v=u.useCallback(l=>{const c=new AbortController;return{signal:c.signal,actions:{produce(s){if(c.signal.aborted)return;const i=m.current.mutate(f=>s(f));a(m.current.model),l.processes.add(i)},dispatch(...[s,i]){c.signal.aborted||(E(s)?n.instance.emit(s,i):d.emit(s,i))},annotate(s,i){return m.current.annotate(s,i)}},[$]:{controller:c}}},[y.model]);return u.useLayoutEffect(()=>{const l=new t;Object.getOwnPropertySymbols(l).forEach(c=>{const s=c;if(E(c))return void n.instance.on(c,async i=>{const f={processes:new Set},p=Promise.withResolvers();await l[s](v(f),i),f.processes.forEach(h=>m.current.prune(h)),p.resolve()});d.on(c,async i=>{const f={processes:new Set},p=Promise.withResolvers();await l[s](v(f),i),f.processes.forEach(h=>m.current.prune(h)),p.resolve()})})},[d]),u.useEffect(()=>{const l=new t;(P.get(l)??[]).forEach(s=>{const i=s.getDependencies(),f=g.current.previous.get(s.action)??[];(i.length!==f.length||i.some((h,K)=>!Object.is(h,f[K])))&&(g.current.previous.set(s.action,[...i]),d.emit(s.action))})}),u.useLayoutEffect(()=>(d.emit(S.Mount),()=>void d.emit(S.Unmount)),[]),u.useEffect(()=>{d.emit(S.Node)},[]),u.useMemo(()=>[r,{dispatch(...[l,c]){E(l)?n.instance.emit(l,c):d.emit(l,c)},consume(){},get inspect(){return m.current.inspect}}],[r,d])}function _(e){const t=u.useRef(e);return u.useLayoutEffect(()=>{t.current=e},[e]),u.useMemo(()=>N(e,t),[e])}Object.defineProperty(o,"Op",{enumerable:!0,get:()=>w.Op}),Object.defineProperty(o,"Operation",{enumerable:!0,get:()=>w.Operation}),Object.defineProperty(o,"State",{enumerable:!0,get:()=>w.State}),o.Broadcaster=B,o.Error=T,o.Lifecycle=S,o.createAction=F,o.createDistributedAction=I,o.use=W,o.useAction=H,o.useActions=J,o.useSnapshot=_,o.utils=R,Object.defineProperty(o,Symbol.toStringTag,{value:"Module"})}));
|
package/dist/error/index.d.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { Props } from './types';
|
|
2
|
+
export { useError } from './utils';
|
|
3
|
+
/**
|
|
4
|
+
* Error boundary component for catching and handling errors from actions.
|
|
5
|
+
*
|
|
6
|
+
* @param props.handler - The error handler function to call when an error occurs.
|
|
7
|
+
* @param props.children - The children to render within the error boundary.
|
|
8
|
+
* @returns The children wrapped in an error context provider.
|
|
9
|
+
*/
|
|
10
|
+
export declare function Error({ handler, children }: Props): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ErrorHandler } from './types.ts';
|
|
2
|
+
/**
|
|
3
|
+
* React context for handling errors that occur within actions.
|
|
4
|
+
*/
|
|
5
|
+
export declare const ErrorContext: import('react').Context<ErrorHandler | undefined>;
|
|
6
|
+
/**
|
|
7
|
+
* Hook to access the error handler from the nearest Error provider.
|
|
8
|
+
*
|
|
9
|
+
* @returns The error handler function, or undefined if not within an Error provider.
|
|
10
|
+
*/
|
|
11
|
+
export declare function useError(): ErrorHandler | undefined;
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Context, Model, Payload, Props, ActionsClass, Actions, UseActions } from '../types/index.ts';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Creates a memoized action handler.
|
|
4
4
|
*
|
|
5
|
-
* @template
|
|
6
|
-
* @template
|
|
7
|
-
* @template
|
|
8
|
-
* @param
|
|
9
|
-
* @returns
|
|
5
|
+
* @template M The type of the model.
|
|
6
|
+
* @template AC The type of the actions class.
|
|
7
|
+
* @template K The specific action key being handled.
|
|
8
|
+
* @param handler The action handler function that receives context and optional payload.
|
|
9
|
+
* @returns A memoized async function that executes the handler with error handling.
|
|
10
10
|
*/
|
|
11
11
|
export declare function useAction<M extends Model, AC extends ActionsClass<any>, K extends Exclude<keyof AC, "prototype"> | never = never>(handler: (context: Context<M, AC>, payload: [K] extends [never] ? unknown : AC[K] extends Payload<infer P> ? P : unknown) => void | Promise<void> | AsyncGenerator | Generator): (context: Context<M, AC>, payload: [K] extends [never] ? unknown : AC[K] extends Payload<infer P> ? P : unknown) => Promise<void>;
|
|
12
12
|
/**
|
|
@@ -44,7 +44,7 @@ export declare function useAction<M extends Model, AC extends ActionsClass<any>,
|
|
|
44
44
|
*
|
|
45
45
|
* // In your component
|
|
46
46
|
* function Counter() {
|
|
47
|
-
* const [model, actions] =
|
|
47
|
+
* const [model, actions] = useCounterActions();
|
|
48
48
|
*
|
|
49
49
|
* return (
|
|
50
50
|
* <div>
|
package/dist/hooks/utils.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { Error } from './error/index.tsx';
|
|
2
2
|
export { createAction, createDistributedAction } from './action/index.ts';
|
|
3
3
|
export type { Pk, Context, ActionInstance, ActionsClass, UseActions, Actions, } from './types/index.ts';
|
|
4
4
|
export { Lifecycle } from './types/index.ts';
|
|
@@ -7,3 +7,4 @@ export { Broadcaster } from './broadcast/index.tsx';
|
|
|
7
7
|
export { useActions, useAction, useSnapshot } from './hooks/index.ts';
|
|
8
8
|
export { Operation, Op, State } from 'immertation';
|
|
9
9
|
export type { Box } from 'immertation';
|
|
10
|
+
export { use } from './use/index.ts';
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Operation, Process, Inspect } from 'immertation';
|
|
2
|
-
|
|
2
|
+
export declare const context: unique symbol;
|
|
3
3
|
export declare class Lifecycle {
|
|
4
4
|
static Mount: symbol;
|
|
5
5
|
static Node: symbol;
|
|
@@ -15,6 +15,8 @@ export type Payload<T = unknown> = symbol & {
|
|
|
15
15
|
[PayloadKey]: T;
|
|
16
16
|
};
|
|
17
17
|
type PayloadType<A> = A extends Payload<infer P> ? P : never;
|
|
18
|
+
type IsAsync<F> = F extends (...args: any[]) => Promise<any> ? true : false;
|
|
19
|
+
type AssertSync<F> = IsAsync<F> extends true ? "Error: async functions are not allowed in produce" : F;
|
|
18
20
|
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
19
21
|
export type Props = Record<string, unknown>;
|
|
20
22
|
export type Action = symbol | string;
|
|
@@ -34,7 +36,7 @@ export type Context<M extends Model, AC extends ActionsClass<any>> = {
|
|
|
34
36
|
model: M;
|
|
35
37
|
signal: AbortSignal;
|
|
36
38
|
actions: {
|
|
37
|
-
produce
|
|
39
|
+
produce<F extends (model: M) => void>(ƒ: F & AssertSync<F>): M;
|
|
38
40
|
dispatch<A extends AC[keyof AC] & Payload<any>>(...args: [PayloadType<A>] extends [never] ? [A] : [A, PayloadType<A>]): void;
|
|
39
41
|
annotate<T>(operation: Operation, value: T): T;
|
|
40
42
|
};
|
package/dist/use/index.d.ts
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
|
-
import { Field } from './types';
|
|
2
|
-
export { context } from './utils';
|
|
1
|
+
import { Field, Primitive } from './types.ts';
|
|
2
|
+
export { context, entries } from './utils.ts';
|
|
3
|
+
/**
|
|
4
|
+
* Action decorators for adding common functionality to action handlers.
|
|
5
|
+
*/
|
|
3
6
|
export declare const use: {
|
|
4
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Ensures only one instance of an action runs at a time. When dispatched again,
|
|
9
|
+
* the previous instance is aborted via `context.signal`.
|
|
10
|
+
*
|
|
11
|
+
* @returns A decorator function for the action.
|
|
12
|
+
*/
|
|
13
|
+
exclusive(): (_: undefined, field: Field) => void;
|
|
14
|
+
/**
|
|
15
|
+
* Automatically triggers an action when its primitive dependencies change.
|
|
16
|
+
* Dependencies must be primitives (strings, numbers, booleans, etc.) to avoid
|
|
17
|
+
* referential equality issues.
|
|
18
|
+
*
|
|
19
|
+
* @param getDependencies A function returning an array of primitive dependencies.
|
|
20
|
+
* @returns A decorator function for the action.
|
|
21
|
+
*/
|
|
22
|
+
reactive(getDependencies: () => Primitive[]): (_: undefined, field: Field) => void;
|
|
23
|
+
/**
|
|
24
|
+
* Logs detailed timing and debugging information for the action, including
|
|
25
|
+
* start time, produce call timings, and total duration.
|
|
26
|
+
*
|
|
27
|
+
* @returns A decorator function for the action.
|
|
28
|
+
*/
|
|
29
|
+
debug(): (_: undefined, field: Field) => void;
|
|
5
30
|
};
|
package/dist/use/types.d.ts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
import { ActionsClass, Context, Model, Payload } from '../types';
|
|
2
|
-
export type
|
|
1
|
+
import { ActionsClass, Context, Model, Payload } from '../types/index.ts';
|
|
2
|
+
export type Primitive = string | number | boolean | null | undefined | symbol | bigint;
|
|
3
|
+
export type Field = ClassFieldDecoratorContext<object, (...args: any[]) => any>;
|
|
3
4
|
export type Args = Context<Model, ActionsClass<Record<string, Payload>>>;
|
|
4
5
|
export type Instance = Record<string | symbol, unknown>;
|
|
5
6
|
export type Method = (args: Args) => Promise<unknown>;
|
|
6
|
-
export type
|
|
7
|
+
export type Internals = {
|
|
7
8
|
controller: AbortController;
|
|
8
9
|
};
|
|
10
|
+
export type Entry = {
|
|
11
|
+
action: string | symbol;
|
|
12
|
+
getDependencies(): Primitive[];
|
|
13
|
+
};
|
|
14
|
+
export type Entries = Entry[];
|
package/dist/use/utils.d.ts
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
export
|
|
1
|
+
import { context } from '../types/index.ts';
|
|
2
|
+
import { Internals, Entries } from './types.ts';
|
|
3
|
+
export { context };
|
|
4
|
+
export declare const internals: WeakMap<object, Internals>;
|
|
5
|
+
export declare const entries: WeakMap<object, Entries>;
|
|
6
|
+
/**
|
|
7
|
+
* Extracts a readable name from an action symbol or string.
|
|
8
|
+
*
|
|
9
|
+
* @param name The action name as a symbol or string.
|
|
10
|
+
* @returns A human-readable string representation of the action name.
|
|
11
|
+
*/
|
|
12
|
+
export declare function actionName(name: string | symbol): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { ActionsClass, Context, Model, Payload, Pk } from '../types/index.ts';
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Returns a promise that resolves after the specified number of milliseconds.
|
|
4
|
+
*
|
|
5
|
+
* @param ms The number of milliseconds to sleep.
|
|
6
|
+
* @returns A promise that resolves after the delay.
|
|
7
|
+
*/
|
|
8
|
+
export declare function sleep(ms: number): Promise<void>;
|
|
3
9
|
/**
|
|
4
10
|
* Generates a unique primary key.
|
|
5
11
|
* @returns A new unique symbol representing the primary key.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chizu",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.35",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./dist/chizu.js",
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"@faker-js/faker": "^10.1.0",
|
|
45
45
|
"@jest/globals": "^30.2.0",
|
|
46
46
|
"@mobily/ts-belt": "^3.13.1",
|
|
47
|
+
"@playwright/test": "^1.57.0",
|
|
47
48
|
"@testing-library/dom": "^10.4.1",
|
|
48
49
|
"@testing-library/jest-dom": "^6.9.1",
|
|
49
50
|
"@testing-library/react": "^16.3.0",
|
|
@@ -64,6 +65,7 @@
|
|
|
64
65
|
"jest": "^30.2.0",
|
|
65
66
|
"jest-environment-jsdom": "^30.2.0",
|
|
66
67
|
"lucide-react": "^0.555.0",
|
|
68
|
+
"madge": "^8.0.0",
|
|
67
69
|
"prettier": "^3.7.4",
|
|
68
70
|
"ramda": "^0.32.0",
|
|
69
71
|
"react": "^19.2.1",
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export declare function Distributed(): (_value: unknown, context: ClassFieldDecoratorContext) => (initialValue: any) => any;
|
|
2
|
-
declare const _default: {
|
|
3
|
-
Synchronous(target: any, propertyKey: string): (...args: any[]) => any;
|
|
4
|
-
Debounce(target: any, propertyKey: string): (...args: any[]) => any;
|
|
5
|
-
};
|
|
6
|
-
export default _default;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export default function sleep(ms: number): Promise<void>;
|
|
File without changes
|