chizu 0.2.21 → 0.2.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -9,8 +9,9 @@ Strongly typed React framework using generators and efficiently updated views al
9
9
  1. [Benefits](#benefits)
10
10
  1. [Getting started](#getting-started)
11
11
  1. [Handling errors](#handling-errors)
12
- 1. [Distributed events](#distributed-events)
13
- 1. [Module context](#module-context)
12
+ 1. [Distributed actions](#distributed-actions)
13
+ 1. [Module dispatch](#module-dispatch)
14
+ 1. [Associated context](#associated-context)
14
15
 
15
16
  ## Benefits
16
17
 
@@ -32,7 +33,7 @@ Actions are responsible for mutating the state of the view. In the below example
32
33
  ```tsx
33
34
  export default <Actions<Module>>function Actions(module) {
34
35
  return {
35
- [Events.Name](name) {
36
+ [Action.Name](name) {
36
37
  return module.actions.produce((draft) => {
37
38
  draft.name = name;
38
39
  });
@@ -44,19 +45,19 @@ export default <Actions<Module>>function Actions(module) {
44
45
  ```tsx
45
46
  export default function Profile(props: Props): React.ReactElement {
46
47
  return (
47
- <Tree<Module> using={{ model, actions, props }}>
48
+ <Scope<Module> using={{ model, actions, props }}>
48
49
  {(module) => (
49
50
  <>
50
51
  <p>Hey {module.model.name}</p>
51
52
 
52
53
  <button
53
- onClick={() => module.actions.dispatch([Events.Name, randomName()])}
54
+ onClick={() => module.actions.dispatch([Action.Name, randomName()])}
54
55
  >
55
56
  Switch profile
56
57
  </button>
57
58
  </>
58
59
  )}
59
- </Tree>
60
+ </Scope>
60
61
  );
61
62
  }
62
63
  ```
@@ -66,7 +67,7 @@ You can perform asynchronous operations in the action which will cause the assoc
66
67
  ```tsx
67
68
  export default <Actions<Module>>function Actions(module) {
68
69
  return {
69
- async *[Events.Name]() {
70
+ async *[Action.Name]() {
70
71
  yield module.actions.produce((draft) => {
71
72
  draft.name = null;
72
73
  });
@@ -84,17 +85,17 @@ export default <Actions<Module>>function Actions(module) {
84
85
  ```tsx
85
86
  export default function Profile(props: Props): React.ReactElement {
86
87
  return (
87
- <Tree<Module> using={{ model, actions, props }}>
88
+ <Scope<Module> using={{ model, actions, props }}>
88
89
  {(module) => (
89
90
  <>
90
91
  <p>Hey {module.model.name}</p>
91
92
 
92
- <button onClick={() => module.actions.dispatch([Events.Name])}>
93
+ <button onClick={() => module.actions.dispatch([Action.Name])}>
93
94
  Switch profile
94
95
  </button>
95
96
  </>
96
97
  )}
97
- </Tree>
98
+ </Scope>
98
99
  );
99
100
  }
100
101
  ```
@@ -104,7 +105,7 @@ However in the above example where the name is fetched asynchronously, there is
104
105
  ```tsx
105
106
  export default <Actions<Module>>function Actions(module) {
106
107
  return {
107
- async *[Events.Name]() {
108
+ async *[Action.Name]() {
108
109
  yield module.actions.produce((draft) => {
109
110
  draft.name = module.actions.annotate(null);
110
111
  });
@@ -121,7 +122,7 @@ export default <Actions<Module>>function Actions(module) {
121
122
  ```tsx
122
123
  export default function ProfileView(props: Props): React.ReactElement {
123
124
  return (
124
- <Tree<Module> using={{ module, actions, props }}>
125
+ <Scope<Module> using={{ module, actions, props }}>
125
126
  {(module) => (
126
127
  <>
127
128
  <p>Hey {module.model.name}</p>
@@ -130,13 +131,13 @@ export default function ProfileView(props: Props): React.ReactElement {
130
131
 
131
132
  <button
132
133
  disabled={module.validate.name.is(State.Op.Update)}
133
- onClick={() => module.actions.dispatch([Events.Name])}
134
+ onClick={() => module.actions.dispatch([Action.Name])}
134
135
  >
135
136
  Switch profile
136
137
  </button>
137
138
  </>
138
139
  )}
139
- </Tree>
140
+ </Scope>
140
141
  );
141
142
  }
142
143
  ```
@@ -148,7 +149,7 @@ Most errors are likely to occur in the actions because the views should be free
148
149
  ```tsx
149
150
  export default <Actions<Module>>function Actions(module) {
150
151
  return {
151
- *[Events.Name]() {
152
+ *[Action.Name]() {
152
153
  yield module.actions.produce((draft) => {
153
154
  draft.name = null;
154
155
  });
@@ -165,12 +166,12 @@ export default <Actions<Module>>function Actions(module) {
165
166
 
166
167
  However in eventualities where an error has not been caught in an action then the `Lifecycle.Error` is the next best thing &ndash; use it to display a toast message and log it your chosen error log service.
167
168
 
168
- Additionally when rendering an error may be thrown which prevents the DOM from updating as you'd expect &ndash; perhaps a side effect has delivered an unexpected data structure. In those cases again `Lifecycle.Error` is your friend. When such an error is thrown the component channel will be switched to `Channel.Error` which you detect using `module.channel.is(Channel.Error)` and switch to an alternative markup that _should_ render, within that you could display a button to attempt recovery &ndash; simply call an action again and update the meta to switch the channel back to `Channel.Default`:
169
+ Additionally when rendering an error may be thrown which prevents the DOM from updating as you'd expect &ndash; perhaps a side effect has delivered an unexpected data structure. In those cases again `Lifecycle.Error` is your friend. When such an error is thrown the component boundary will be switched to `Boundary.Error` which you detect using `module.boundary.is(Boundary.Error)` and switch to an alternative markup that _should_ render, within that you could display a button to attempt recovery &ndash; simply call an action again and update the meta to switch the boundary back to `Boundary.Default`:
169
170
 
170
171
  ```tsx
171
172
  export default <Actions<Module>>function Actions(module) {
172
173
  return {
173
- *[Events.Recover]() {
174
+ *[Action.Recover]() {
174
175
  yield module.actions.produce((draft) => {
175
176
  draft.name = null;
176
177
  });
@@ -178,7 +179,7 @@ export default <Actions<Module>>function Actions(module) {
178
179
  const name = await fetch(/* ... */);
179
180
 
180
181
  return module.actions.produce((draft, meta) => {
181
- meta.channel = Channel.Default;
182
+ meta.boundary = Boundary.Default;
182
183
  draft.name = name;
183
184
  });
184
185
  },
@@ -186,34 +187,62 @@ export default <Actions<Module>>function Actions(module) {
186
187
  };
187
188
  ```
188
189
 
189
- If the component again throws an error after attempting recovery, it will simply switch back to the `Channel.Error` again.
190
+ If the component again throws an error after attempting recovery, it will simply switch back to the `Boundary.Error` again.
190
191
 
191
- ## Distributed events
192
+ ## Distributed actions
192
193
 
193
194
  Actions can communicate with other mounted actions using the `DistributedActions` approach. You can configure the enum and union type in the root of your application:
194
195
 
195
196
  ```ts
196
- export enum DistributedEvents {
197
+ export enum DistributedAction {
197
198
  SignedOut = "distributed/signed-out",
198
199
  }
199
200
 
200
- export type DistributedActions = [DistributedEvents.SignedOut];
201
+ export type DistributedActions = [DistributedAction.SignedOut];
201
202
  ```
202
203
 
203
- Note that you must prefix the enum name with `distributed` for it to behave as a distributed event, otherwise it'll be considered a module event only. Once you have the distributed events you simply need to augment the module actions union with the `DistributedActions` and use it as you do other actions:
204
+ Note that you must prefix the enum name with `distributed` for it to behave as a distributed event, otherwise it'll be considered a module event only. Once you have the distributed actions you simply need to augment the module actions union with the `DistributedActions` and use it as you do other actions:
204
205
 
205
206
  ```ts
206
- export type Actions = DistributedActions | [Events.Task, string]; // etc...
207
+ export type Actions = DistributedActions | [Action.Task, string]; // etc...
207
208
  ```
208
209
 
209
- ## Module context
210
+ ## Module dispatch
210
211
 
211
- In the eventuality that you have a component but don't want associated actions, models, etc&hellip; but want to still fire events either the closest module or a distributed event, you can use the `useModule` hook:
212
+ In the eventuality that you have a component but don't want associated actions, models, etc&hellip; but want to still fire actions either the closest module or a distributed action, you can use the `useScoped` hook:
212
213
 
213
214
  ```ts
214
- const module = useModule<Module>();
215
+ const module = useScoped<Module>();
215
216
 
216
217
  // ...
217
218
 
218
- module.actions.dispatch([Event.Task, "My task that needs to be done."]);
219
+ module.actions.dispatch([Action.Task, "My task that needs to be done."]);
220
+ ```
221
+
222
+ Alternatively you can pass the current module as a prop to your components using the `Scoped` helper:
223
+
224
+ ```ts
225
+ export type Props = {
226
+ module: Scoped<Module>;
227
+ };
228
+ ```
229
+
230
+ ## Associated context
231
+
232
+ In many cases you'll still want to retrieve contextual values from within actions &ndash; which you can do by using the `module.actions.context` function:
233
+
234
+ ```tsx
235
+ export default <Actions<Module>>function Actions(module) {
236
+ const context = module.actions.context({
237
+ name: NameContext
238
+ });
239
+
240
+ return {
241
+ [Action.Name](name) {
242
+ return module.actions.produce((draft) => {
243
+ draft.name = context.name;
244
+ });
245
+ },
246
+ };
247
+ };
219
248
  ```
@@ -1,4 +1,12 @@
1
1
  import { BroadcastContext, Props } from './types.ts';
2
2
  import * as React from "react";
3
3
  export declare function useBroadcast(): BroadcastContext;
4
- export declare function BroadcastProvider({ children }: Props): React.ReactNode;
4
+ /**
5
+ * Note: only needed if you want to create a new broadcast context, useful for
6
+ * libraries that want to provide their own broadcast context without intefering
7
+ * with the app's broadcast context.
8
+ *
9
+ * @param param0 - { children }: Props
10
+ * @returns {React.ReactNode}
11
+ */
12
+ export declare function Broadcaster({ children }: Props): React.ReactNode;
@@ -1,7 +1,7 @@
1
1
  import { default as EventEmitter } from 'eventemitter3';
2
2
  import * as React from "react";
3
3
  export type BroadcastContext = {
4
- appEmitter: EventEmitter;
4
+ instance: EventEmitter;
5
5
  };
6
6
  export type UseBroadcast = BroadcastContext;
7
7
  export type Props = {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Check if the name is a broadcast event.
2
+ * Check if the name is a broadcast action.
3
3
  *
4
4
  * @param name {string}
5
5
  * @returns {boolean}
package/dist/chizu.js CHANGED
@@ -1,184 +1,185 @@
1
1
  var J = Object.defineProperty;
2
- var C = (t) => {
2
+ var U = (t) => {
3
3
  throw TypeError(t);
4
4
  };
5
5
  var Q = (t, e, n) => e in t ? J(t, e, { enumerable: !0, configurable: !0, writable: !0, value: n }) : t[e] = n;
6
- var g = (t, e, n) => Q(t, typeof e != "symbol" ? e + "" : e, n), O = (t, e, n) => e.has(t) || C("Cannot " + n);
7
- var b = (t, e, n) => (O(t, e, "read from private field"), n ? n.call(t) : e.get(t)), x = (t, e, n) => e.has(t) ? C("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(t) : e.set(t, n), R = (t, e, n, r) => (O(t, e, "write to private field"), r ? r.call(t, n) : e.set(t, n), n);
8
- import { jsx as k } from "react/jsx-runtime";
9
- import * as i from "react";
10
- import U from "eventemitter3";
11
- import { Immer as W, enablePatches as G } from "immer";
12
- import p from "lodash/get";
13
- import M from "traverse";
14
- class $ {
6
+ var E = (t, e, n) => Q(t, typeof e != "symbol" ? e + "" : e, n), _ = (t, e, n) => e.has(t) || U("Cannot " + n);
7
+ var w = (t, e, n) => (_(t, e, "read from private field"), n ? n.call(t) : e.get(t)), x = (t, e, n) => e.has(t) ? U("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(t) : e.set(t, n), R = (t, e, n, r) => (_(t, e, "write to private field"), r ? r.call(t, n) : e.set(t, n), n);
8
+ import { jsx as P } from "react/jsx-runtime";
9
+ import * as u from "react";
10
+ import { useRef as W } from "react";
11
+ import k from "eventemitter3";
12
+ import { Immer as G, enablePatches as K } from "immer";
13
+ import m from "lodash/get";
14
+ import j from "traverse";
15
+ class B {
15
16
  constructor(e) {
16
17
  this.value = e;
17
18
  }
18
19
  }
19
- class K {
20
+ class V {
20
21
  static Draft(e) {
21
- return new $(e);
22
+ return new B(e);
22
23
  }
23
24
  }
24
- g(K, "Op", {
25
+ E(V, "Op", {
25
26
  Add: 1,
26
27
  Remove: 2,
27
28
  Update: 4,
28
29
  Move: 8,
29
30
  Replace: 16
30
31
  });
31
- var f = /* @__PURE__ */ ((t) => (t.Mount = "lifecycle/mount", t.Node = "lifecycle/node", t.Derive = "lifecycle/derive", t.Error = "lifecycle/error", t.Unmount = "lifecycle/unmount", t))(f || {}), j = /* @__PURE__ */ ((t) => (t[t.Default = 0] = "Default", t[t.Error = 1] = "Error", t))(j || {});
32
- function V(t) {
32
+ var f = /* @__PURE__ */ ((t) => (t.Mount = "lifecycle/mount", t.Node = "lifecycle/node", t.Derive = "lifecycle/derive", t.Error = "lifecycle/error", t.Unmount = "lifecycle/unmount", t))(f || {}), M = /* @__PURE__ */ ((t) => (t[t.Default = 0] = "Default", t[t.Error = 1] = "Error", t))(M || {});
33
+ function X(t) {
33
34
  return new Promise((e) => setTimeout(e, t));
34
35
  }
35
- function X(t) {
36
+ function Y(t) {
36
37
  return t ? !!(t && typeof t != "symbol") : Symbol(`pk.${Date.now()}.${crypto.randomUUID()}`);
37
38
  }
38
- function m(t) {
39
+ function p(t) {
39
40
  return JSON.stringify(t);
40
41
  }
41
- const y = Symbol("meta"), wt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
42
+ const g = Symbol("meta"), Et = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
42
43
  __proto__: null,
43
- hash: m,
44
- meta: y,
45
- pk: X,
46
- sleep: V
44
+ hash: p,
45
+ meta: g,
46
+ pk: Y,
47
+ sleep: X
47
48
  }, Symbol.toStringTag, { value: "Module" }));
48
- function l(t, e) {
49
- const n = i.useRef(null), r = i.useRef(null);
50
- return i.useMemo(() => {
51
- const o = m(e);
52
- if (r.current !== o) {
53
- r.current = o;
54
- const s = t();
55
- return n.current = s, s;
49
+ function d(t, e) {
50
+ const n = u.useRef(null), r = u.useRef(null);
51
+ return u.useMemo(() => {
52
+ const s = p(e);
53
+ if (r.current !== s) {
54
+ r.current = s;
55
+ const o = t();
56
+ return n.current = o, o;
56
57
  }
57
58
  return n.current;
58
59
  }, e);
59
60
  }
60
- function _(t, e) {
61
- const n = i.useRef(null);
62
- i.useEffect(() => {
63
- const r = m(e);
61
+ function A(t, e) {
62
+ const n = u.useRef(null);
63
+ u.useEffect(() => {
64
+ const r = p(e);
64
65
  if (n.current !== r)
65
66
  return n.current = r, t();
66
67
  }, e);
67
68
  }
68
- const H = i.createContext({
69
- appEmitter: new U()
69
+ const H = u.createContext({
70
+ instance: new k()
70
71
  });
71
72
  function T() {
72
- return i.useContext(H);
73
+ return u.useContext(H);
73
74
  }
74
- function yt({ children: t }) {
75
- const e = l(
75
+ function wt({ children: t }) {
76
+ const e = d(
76
77
  () => ({
77
- appEmitter: new U()
78
+ instance: new k()
78
79
  }),
79
80
  []
80
81
  );
81
- return /* @__PURE__ */ k(H.Provider, { value: e, children: t });
82
+ return /* @__PURE__ */ P(H.Provider, { value: e, children: t });
82
83
  }
83
84
  const a = {
84
- immer: new W(),
85
+ immer: new G(),
85
86
  annotations: Symbol("annotations")
86
87
  };
87
- G();
88
+ K();
88
89
  a.immer.setAutoFreeze(!1);
89
- class P {
90
+ class C {
90
91
  constructor(e, n, r = null) {
91
- g(this, "process");
92
+ E(this, "process");
92
93
  this.value = e, this.operations = n, this.field = r, this.process = null;
93
94
  }
94
95
  attach(e) {
95
96
  return this.process = e, this;
96
97
  }
97
98
  }
98
- function Y(t, e = []) {
99
- return new P(t, e);
99
+ function Z(t, e = []) {
100
+ return new C(t, e);
100
101
  }
101
- class A {
102
+ class O {
102
103
  constructor(e, n = e) {
103
104
  this.stateless = e, this.stateful = n;
104
105
  }
105
106
  get validatable() {
106
- return z(this.stateful);
107
+ return $(this.stateful);
107
108
  }
108
109
  }
109
- function z(t, e = []) {
110
+ function $(t, e = []) {
110
111
  return new Proxy(t, {
111
112
  get(n, r) {
112
113
  switch (r) {
113
114
  case "is":
114
- return (o) => {
115
- const s = S(t, e);
116
- if (!s) return !1;
115
+ return (s) => {
116
+ const o = S(t, e);
117
+ if (!o) return !1;
117
118
  const c = new Set(
118
- s.flatMap((d) => d.operations)
119
+ o.flatMap((l) => l.operations)
119
120
  );
120
121
  return !!(Array.from(c).reduce(
121
- (d, h) => d | (h ?? 0),
122
+ (l, h) => l | (h ?? 0),
122
123
  0
123
- ) & o);
124
+ ) & s);
124
125
  };
125
126
  case "pending":
126
127
  return () => !!S(t, e);
127
128
  case "draft":
128
129
  return () => {
129
- const o = S(t, e);
130
- if (!o) return p(t, e);
131
- const s = o.flatMap((c) => c.operations).find((c) => c instanceof $);
132
- return s ? s.value : p(t, e);
130
+ const s = S(t, e);
131
+ if (!s) return m(t, e);
132
+ const o = s.flatMap((c) => c.operations).find((c) => c instanceof B);
133
+ return o ? o.value : m(t, e);
133
134
  };
134
135
  }
135
- return z(t, [...e, String(r)]);
136
+ return $(t, [...e, String(r)]);
136
137
  }
137
138
  });
138
139
  }
139
140
  function S(t, e) {
140
- const r = typeof p(t, e) == "object" ? e : e.slice(0, -1), o = r.length === 0 ? t : p(t, r), s = (o == null ? void 0 : o[a.annotations]) ?? [];
141
- return s.length > 0 ? s : null;
141
+ const r = typeof m(t, e) == "object" ? e : e.slice(0, -1), s = r.length === 0 ? t : m(t, r), o = (s == null ? void 0 : s[a.annotations]) ?? [];
142
+ return o.length > 0 ? o : null;
142
143
  }
143
- function q(t, e, n) {
144
+ function z(t, e, n) {
144
145
  function r(c) {
145
- return M(c).forEach(function() {
146
+ return j(c).forEach(function() {
146
147
  if (this.key === a.annotations) {
147
148
  this.block();
148
149
  return;
149
150
  }
150
- this.node instanceof P && this.update(this.node.value);
151
+ this.node instanceof C && this.update(this.node.value);
151
152
  });
152
153
  }
153
- function o(c) {
154
- return M(c).forEach(function() {
154
+ function s(c) {
155
+ return j(c).forEach(function() {
155
156
  if (this.key === a.annotations) {
156
157
  this.block();
157
158
  return;
158
159
  }
159
- if (this.node instanceof P) {
160
- const u = typeof this.node.value == "object", d = [
161
- ...u ? this.path : this.path.slice(0, -1),
160
+ if (this.node instanceof C) {
161
+ const i = typeof this.node.value == "object", l = [
162
+ ...i ? this.path : this.path.slice(0, -1),
162
163
  a.annotations
163
- ], h = p(t.stateful, d) ?? [], w = this.node.attach(e);
164
- u ? this.update(
164
+ ], h = m(t.stateful, l) ?? [], b = this.node.attach(e);
165
+ i ? this.update(
165
166
  {
166
167
  ...this.node.value,
167
- [a.annotations]: [w, ...h]
168
+ [a.annotations]: [b, ...h]
168
169
  },
169
170
  !0
170
- ) : (this.parent && (this.parent.node[a.annotations] = [w, ...h]), this.update(this.node.value, !0));
171
+ ) : (this.parent && (this.parent.node[a.annotations] = [b, ...h]), this.update(this.node.value, !0));
171
172
  }
172
173
  });
173
174
  }
174
- const s = (c) => n(c, c[y]);
175
- return new A(
176
- r(a.immer.produce(t.stateless, s)),
177
- o(a.immer.produce(t.stateful, s))
175
+ const o = (c) => n(c, c[g]);
176
+ return new O(
177
+ r(a.immer.produce(t.stateless, o)),
178
+ s(a.immer.produce(t.stateful, o))
178
179
  );
179
180
  }
180
181
  function D(t, e) {
181
- const n = M(t.stateful).forEach(function() {
182
+ const n = j(t.stateful).forEach(function() {
182
183
  if (this.key === a.annotations) {
183
184
  this.block();
184
185
  return;
@@ -189,17 +190,17 @@ function D(t, e) {
189
190
  {
190
191
  ...this.node,
191
192
  [a.annotations]: r.filter(
192
- (o) => o.process !== e
193
+ (s) => s.process !== e
193
194
  )
194
195
  },
195
196
  !0
196
197
  );
197
198
  }
198
199
  });
199
- return new A(t.stateless, n);
200
+ return new O(t.stateless, n);
200
201
  }
201
- function Z(t) {
202
- return l(
202
+ function L(t) {
203
+ return d(
203
204
  () => ({
204
205
  controller: {
205
206
  get model() {
@@ -208,15 +209,27 @@ function Z(t) {
208
209
  queue: [],
209
210
  actions: {
210
211
  annotate(e, n) {
211
- return Y(e, n);
212
+ return Z(e, n);
212
213
  },
213
214
  produce(e) {
214
- return (n, r) => q(n, r, e);
215
+ return (n, r) => z(n, r, e);
215
216
  },
216
217
  dispatch([e, ...n]) {
217
218
  if (e == null) return Promise.reject();
218
219
  const r = Promise.withResolvers();
219
220
  return t.dispatchers.dispatch(e, n, r), r.promise;
221
+ },
222
+ context(e) {
223
+ const n = Object.keys(e);
224
+ return t.context.use.current = e, t.context.update(), n.reduce(
225
+ (r, s) => ({
226
+ ...r,
227
+ get [s]() {
228
+ return t.context.registry.current[s];
229
+ }
230
+ }),
231
+ {}
232
+ );
220
233
  }
221
234
  }
222
235
  },
@@ -227,9 +240,9 @@ function Z(t) {
227
240
  get validate() {
228
241
  return t.model.current.validatable;
229
242
  },
230
- channel: {
243
+ boundary: {
231
244
  is(e) {
232
- return t.model.current.stateless[y].channel === e;
245
+ return t.model.current.stateless[g].boundary === e;
233
246
  }
234
247
  },
235
248
  actions: {
@@ -244,171 +257,181 @@ function Z(t) {
244
257
  []
245
258
  );
246
259
  }
247
- function L(t) {
248
- return l(() => {
249
- const e = t.options.using.actions(t.actions.controller);
250
- return Object.entries(e).forEach(([r, o]) => t.dispatchers.attach(r, o)), e;
260
+ function tt(t) {
261
+ const e = W(null);
262
+ return e.current == null && (e.current = t.options.using.actions(t.actions.controller)), d(() => {
263
+ if (e.current)
264
+ return Object.entries(e.current).forEach(([r, s]) => t.dispatchers.attach(r, s)), e.current;
251
265
  }, []);
252
266
  }
253
267
  function N(t) {
254
268
  return t.startsWith("distributed");
255
269
  }
256
- function gt(t) {
257
- return t instanceof B;
270
+ function xt(t) {
271
+ return t instanceof I;
258
272
  }
259
- function bt(t) {
260
- return t instanceof B;
273
+ function q(t) {
274
+ return t instanceof I || t instanceof Error ? t : new Error("Unknown error", { cause: t });
261
275
  }
262
- function I(t) {
263
- return t instanceof B || t instanceof Error ? t : new Error("Unknown error", { cause: t });
264
- }
265
- var v, E;
266
- class B extends Error {
276
+ var v, y;
277
+ class I extends Error {
267
278
  constructor(n, r = null) {
268
279
  super(String(r));
269
280
  x(this, v);
270
- x(this, E);
271
- R(this, v, n), R(this, E, r);
281
+ x(this, y);
282
+ R(this, v, n), R(this, y, r);
272
283
  }
273
284
  get type() {
274
- return b(this, v);
285
+ return w(this, v);
275
286
  }
276
287
  get message() {
277
- return b(this, E) || "";
288
+ return w(this, y) || "";
278
289
  }
279
290
  }
280
- v = new WeakMap(), E = new WeakMap();
281
- function tt({
291
+ v = new WeakMap(), y = new WeakMap();
292
+ function et({
282
293
  children: t
283
294
  }) {
284
295
  return t();
285
296
  }
286
- function et(t) {
287
- return (e, n) => async (r = Promise.withResolvers(), o) => {
297
+ function nt(t) {
298
+ return (e, n) => async (r = Promise.withResolvers(), s) => {
288
299
  if (typeof n != "function") return;
289
- const s = Symbol("process"), c = n(...o);
300
+ const o = Symbol("process"), c = n(...s);
290
301
  try {
291
302
  if (c == null) return;
292
303
  if (typeof c == "function") {
293
- const u = c(t.model.current, s);
294
- t.model.current = D(u, s), t.update.rerender(), r.resolve();
304
+ const i = c(t.model.current, o);
305
+ t.model.current = D(i, o), t.update.rerender(), r.resolve();
295
306
  return;
296
307
  }
297
308
  for (; ; ) {
298
- const { value: u, done: d } = await c.next();
299
- if (d) {
300
- const w = u(t.model.current, s);
301
- t.model.current = D(w, s), t.update.rerender();
309
+ const { value: i, done: l } = await c.next();
310
+ if (l) {
311
+ const b = i(t.model.current, o);
312
+ t.model.current = D(b, o), t.update.rerender();
302
313
  break;
303
314
  }
304
- const h = u;
305
- t.model.current = h(t.model.current, s), t.update.rerender(), r.resolve();
315
+ const h = i;
316
+ t.model.current = h(t.model.current, o), t.update.rerender(), r.resolve();
306
317
  }
307
- } catch (u) {
308
- D(t.model.current, s), t.update.rerender(), t.unicast.emit(f.Error, r, [I(u)]);
318
+ } catch (i) {
319
+ D(t.model.current, o), t.update.rerender(), t.unicast.emit(f.Error, r, [q(i)]);
309
320
  }
310
321
  };
311
322
  }
312
- function nt(t) {
313
- const e = T(), n = l(() => new U(), []), r = et({ ...t, unicast: n });
314
- return l(() => ({
315
- attach(o, s) {
316
- const c = String(o);
317
- N(c) ? e.appEmitter.on(c, r(o, s)) : n.on(c, r(o, s));
323
+ function rt(t) {
324
+ const e = T(), n = d(() => new k(), []), r = nt({ ...t, unicast: n });
325
+ return d(() => ({
326
+ attach(s, o) {
327
+ const c = String(s);
328
+ N(c) ? e.instance.on(c, r(s, o)) : n.on(c, r(s, o));
318
329
  },
319
- dispatch(o, s, c) {
320
- const u = String(o);
321
- N(u) ? e.appEmitter.emit(u, c, s) : n.emit(u, c, s);
330
+ dispatch(s, o, c) {
331
+ const i = String(s);
332
+ N(i) ? e.instance.emit(i, c, o) : n.emit(i, c, o);
322
333
  }
323
334
  }), []);
324
335
  }
325
- function rt() {
326
- const t = i.useRef(null);
327
- return l(() => ({ customElement: t }), []);
336
+ function st() {
337
+ const t = u.useRef(null);
338
+ return d(() => ({ customElement: t }), []);
328
339
  }
329
- function st(t) {
330
- _(() => {
340
+ function ot(t) {
341
+ A(() => {
331
342
  t.dispatchers.dispatch(f.Derive, []);
332
- }, [t.options.using.props]), _(() => (t.dispatchers.dispatch(f.Mount, []), t.dispatchers.dispatch(f.Node, [
343
+ }, [t.options.using.props]), A(() => (t.dispatchers.dispatch(f.Mount, []), t.dispatchers.dispatch(f.Node, [
333
344
  t.elements.customElement.current
334
345
  ]), () => t.dispatchers.dispatch(f.Unmount, [])), []);
335
346
  }
336
- function ot(t) {
337
- const e = l(() => ({ ...t.options.using.model ?? {}, [y]: { channel: j.Default } }), []);
338
- return i.useRef(new A(e, e));
339
- }
340
- function ct() {
341
- return i.useRef(/* @__PURE__ */ new Set());
347
+ function ct(t) {
348
+ const e = d(() => ({ ...t.options.using.model ?? {}, [g]: { boundary: M.Default } }), []);
349
+ return u.useRef(new O(e, e));
342
350
  }
343
351
  function ut() {
344
- const [t, e] = i.useReducer((n) => n + 1, 0);
345
- return l(() => ({ hash: t, rerender: e }), [t]);
352
+ return u.useRef(/* @__PURE__ */ new Set());
353
+ }
354
+ function it() {
355
+ const [t, e] = u.useReducer((n) => n + 1, 0);
356
+ return d(() => ({ hash: t, rerender: e }), [t]);
346
357
  }
347
- const it = {
358
+ const at = {
348
359
  elementName: "x-chizu"
349
- }, F = i.createContext(
360
+ }, F = u.createContext(
350
361
  null
351
362
  );
352
- function xt() {
353
- const t = i.useContext(F);
354
- if (!t) throw new Error("useModule must be used within a module.");
363
+ function Rt() {
364
+ const t = u.useContext(F);
365
+ if (!t)
366
+ throw new Error("useScoped is not being used within a scoped module.");
355
367
  return t;
356
368
  }
357
- class at extends i.Component {
369
+ class lt extends u.Component {
358
370
  constructor(e) {
359
371
  super(e), this.state = { error: null };
360
372
  }
361
373
  componentDidCatch(e) {
362
- const n = Symbol("process"), r = q(this.props.model.current, n, (o, s) => {
363
- s.channel = j.Error;
374
+ const n = Symbol("process"), r = z(this.props.model.current, n, (s, o) => {
375
+ o.boundary = M.Error;
364
376
  });
365
- this.props.model.current = r, this.props.update.rerender(), this.props.dispatchers.dispatch(f.Error, [I(e)]);
377
+ this.props.model.current = r, this.props.update.rerender(), this.props.dispatchers.dispatch(f.Error, [q(e)]);
366
378
  }
367
379
  render() {
368
- return /* @__PURE__ */ k(tt, { children: this.props.children });
380
+ return /* @__PURE__ */ P(et, { children: this.props.children });
369
381
  }
370
382
  }
371
- function lt({
383
+ function dt() {
384
+ const t = u.useRef({}), e = u.useRef({});
385
+ function n() {
386
+ e.current = Object.fromEntries(
387
+ Object.entries(t.current).map(([r, s]) => [r, u.use(s)])
388
+ );
389
+ }
390
+ return n(), d(() => ({ use: t, registry: e, update: n }), []);
391
+ }
392
+ function ft({
372
393
  options: t
373
394
  }) {
374
- const e = ut(), n = ct(), r = rt(), o = T(), s = ot({ options: t }), c = nt({
375
- broadcast: o,
395
+ const e = it(), n = ut(), r = st(), s = T(), o = dt(), c = ct({ options: t }), i = rt({
396
+ broadcast: s,
376
397
  options: t,
377
398
  update: e,
378
- model: s,
399
+ model: c,
379
400
  queue: n
380
- }), u = Z({ model: s, dispatchers: c });
381
- return L({ options: t, dispatchers: c, actions: u }), st({ options: t, dispatchers: c, elements: r }), l(() => i.createElement(at, {
382
- model: s,
383
- dispatchers: c,
401
+ }), l = L({
402
+ model: c,
403
+ dispatchers: i,
404
+ context: o
405
+ });
406
+ return tt({ options: t, dispatchers: i, actions: l }), ot({ options: t, dispatchers: i, elements: r }), d(() => u.createElement(lt, {
407
+ model: c,
408
+ dispatchers: i,
384
409
  update: e,
385
- module: u.view,
410
+ module: l.view,
386
411
  children() {
387
- return i.createElement(F.Provider, {
388
- value: u.view,
412
+ return u.createElement(F.Provider, {
413
+ value: l.view,
389
414
  // eslint-disable-next-line react/no-children-prop
390
- children: i.createElement(it.elementName, {
415
+ children: u.createElement(at.elementName, {
391
416
  ref: r.customElement,
392
417
  style: { display: "contents" },
393
- children: t.children(u.view)
418
+ children: t.children(l.view)
394
419
  })
395
420
  });
396
421
  }
397
- }), [e.hash, m(t.using.props)]);
422
+ }), [e.hash, p(t.using.props), p(o.registry)]);
398
423
  }
399
- function dt(t) {
400
- return /* @__PURE__ */ k(lt, { options: t });
424
+ function St(t) {
425
+ return /* @__PURE__ */ P(ft, { options: t });
401
426
  }
402
- const Rt = i.memo(dt, (t, e) => m(t) === m(e));
403
427
  export {
404
- yt as BroadcastProvider,
405
- j as Channel,
428
+ M as Boundary,
429
+ wt as Broadcaster,
406
430
  f as Lifecycle,
407
- K as State,
408
- Rt as Tree,
409
- B as UserError,
410
- gt as isActionError,
411
- bt as isUserError,
412
- xt as useModule,
413
- wt as utils
431
+ St as Scope,
432
+ V as State,
433
+ I as TypedError,
434
+ xt as isTypedError,
435
+ Rt as useScoped,
436
+ Et as utils
414
437
  };
@@ -1 +1 @@
1
- (function(s,i){typeof exports=="object"&&typeof module<"u"?i(exports,require("react/jsx-runtime"),require("react"),require("eventemitter3"),require("immer"),require("lodash/get"),require("traverse")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react","eventemitter3","immer","lodash/get","traverse"],i):(s=typeof globalThis<"u"?globalThis:s||self,i(s.Chizu={},s.jsxRuntime,s.React,s.EventEmitter3,s.Immer,s.get,s.Traverse))})(this,function(s,i,d,v,q,w,D){"use strict";var Ee=Object.defineProperty;var W=s=>{throw TypeError(s)};var we=(s,i,d)=>i in s?Ee(s,i,{enumerable:!0,configurable:!0,writable:!0,value:d}):s[i]=d;var k=(s,i,d)=>we(s,typeof i!="symbol"?i+"":i,d),G=(s,i,d)=>i.has(s)||W("Cannot "+d);var _=(s,i,d)=>(G(s,i,"read from private field"),d?d.call(s):i.get(s)),C=(s,i,d)=>i.has(s)?W("Cannot add the same private member more than once"):i instanceof WeakSet?i.add(s):i.set(s,d),T=(s,i,d,v)=>(G(s,i,"write to private field"),v?v.call(s,d):i.set(s,d),d);var b,g;function K(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 l=K(d);class A{constructor(t){this.value=t}}class B{static Draft(t){return new A(t)}}k(B,"Op",{Add:1,Remove:2,Update:4,Move:8,Replace:16});var m=(e=>(e.Mount="lifecycle/mount",e.Node="lifecycle/node",e.Derive="lifecycle/derive",e.Error="lifecycle/error",e.Unmount="lifecycle/unmount",e))(m||{}),S=(e=>(e[e.Default=0]="Default",e[e.Error=1]="Error",e))(S||{});function V(e){return new Promise(t=>setTimeout(t,e))}function X(e){return e?!!(e&&typeof e!="symbol"):Symbol(`pk.${Date.now()}.${crypto.randomUUID()}`)}function y(e){return JSON.stringify(e)}const j=Symbol("meta"),Y=Object.freeze(Object.defineProperty({__proto__:null,hash:y,meta:j,pk:X,sleep:V},Symbol.toStringTag,{value:"Module"}));function h(e,t){const n=l.useRef(null),r=l.useRef(null);return l.useMemo(()=>{const c=y(t);if(r.current!==c){r.current=c;const o=e();return n.current=o,o}return n.current},t)}function N(e,t){const n=l.useRef(null);l.useEffect(()=>{const r=y(t);if(n.current!==r)return n.current=r,e()},t)}const z=l.createContext({appEmitter:new v});function $(){return l.useContext(z)}function Z({children:e}){const t=h(()=>({appEmitter:new v}),[]);return i.jsx(z.Provider,{value:t,children:e})}const f={immer:new q.Immer,annotations:Symbol("annotations")};q.enablePatches(),f.immer.setAutoFreeze(!1);class R{constructor(t,n,r=null){k(this,"process");this.value=t,this.operations=n,this.field=r,this.process=null}attach(t){return this.process=t,this}}function L(e,t=[]){return new R(e,t)}class O{constructor(t,n=t){this.stateless=t,this.stateful=n}get validatable(){return H(this.stateful)}}function H(e,t=[]){return new Proxy(e,{get(n,r){switch(r){case"is":return c=>{const o=x(e,t);if(!o)return!1;const u=new Set(o.flatMap(p=>p.operations));return!!(Array.from(u).reduce((p,E)=>p|(E??0),0)&c)};case"pending":return()=>!!x(e,t);case"draft":return()=>{const c=x(e,t);if(!c)return w(e,t);const o=c.flatMap(u=>u.operations).find(u=>u instanceof A);return o?o.value:w(e,t)}}return H(e,[...t,String(r)])}})}function x(e,t){const r=typeof w(e,t)=="object"?t:t.slice(0,-1),c=r.length===0?e:w(e,r),o=(c==null?void 0:c[f.annotations])??[];return o.length>0?o:null}function I(e,t,n){function r(u){return D(u).forEach(function(){if(this.key===f.annotations){this.block();return}this.node instanceof R&&this.update(this.node.value)})}function c(u){return D(u).forEach(function(){if(this.key===f.annotations){this.block();return}if(this.node instanceof R){const a=typeof this.node.value=="object",p=[...a?this.path:this.path.slice(0,-1),f.annotations],E=w(e.stateful,p)??[],M=this.node.attach(t);a?this.update({...this.node.value,[f.annotations]:[M,...E]},!0):(this.parent&&(this.parent.node[f.annotations]=[M,...E]),this.update(this.node.value,!0))}})}const o=u=>n(u,u[j]);return new O(r(f.immer.produce(e.stateless,o)),c(f.immer.produce(e.stateful,o)))}function U(e,t){const n=D(e.stateful).forEach(function(){if(this.key===f.annotations){this.block();return}if(this.node&&this.node[f.annotations]){const r=this.node[f.annotations];this.update({...this.node,[f.annotations]:r.filter(c=>c.process!==t)},!0)}});return new O(e.stateless,n)}function ee(e){return h(()=>({controller:{get model(){return e.model.current.stateful},queue:[],actions:{annotate(t,n){return L(t,n)},produce(t){return(n,r)=>I(n,r,t)},dispatch([t,...n]){if(t==null)return Promise.reject();const r=Promise.withResolvers();return e.dispatchers.dispatch(t,n,r),r.promise}}},view:{get model(){return e.model.current.stateless},get validate(){return e.model.current.validatable},channel:{is(t){return e.model.current.stateless[j].channel===t}},actions:{dispatch([t,...n]){if(t==null)return Promise.reject();const r=Promise.withResolvers();return e.dispatchers.dispatch(t,n,r),r.promise}}}}),[])}function te(e){return h(()=>{const t=e.options.using.actions(e.actions.controller);return Object.entries(t).forEach(([r,c])=>e.dispatchers.attach(r,c)),t},[])}function F(e){return e.startsWith("distributed")}function ne(e){return e instanceof P}function re(e){return e instanceof P}function J(e){return e instanceof P||e instanceof Error?e:new Error("Unknown error",{cause:e})}class P extends Error{constructor(n,r=null){super(String(r));C(this,b);C(this,g);T(this,b,n),T(this,g,r)}get type(){return _(this,b)}get message(){return _(this,g)||""}}b=new WeakMap,g=new WeakMap;function se({children:e}){return e()}function oe(e){return(t,n)=>async(r=Promise.withResolvers(),c)=>{if(typeof n!="function")return;const o=Symbol("process"),u=n(...c);try{if(u==null)return;if(typeof u=="function"){const a=u(e.model.current,o);e.model.current=U(a,o),e.update.rerender(),r.resolve();return}for(;;){const{value:a,done:p}=await u.next();if(p){const M=a(e.model.current,o);e.model.current=U(M,o),e.update.rerender();break}const E=a;e.model.current=E(e.model.current,o),e.update.rerender(),r.resolve()}}catch(a){U(e.model.current,o),e.update.rerender(),e.unicast.emit(m.Error,r,[J(a)])}}}function ce(e){const t=$(),n=h(()=>new v,[]),r=oe({...e,unicast:n});return h(()=>({attach(c,o){const u=String(c);F(u)?t.appEmitter.on(u,r(c,o)):n.on(u,r(c,o))},dispatch(c,o,u){const a=String(c);F(a)?t.appEmitter.emit(a,u,o):n.emit(a,u,o)}}),[])}function ue(){const e=l.useRef(null);return h(()=>({customElement:e}),[])}function ie(e){N(()=>{e.dispatchers.dispatch(m.Derive,[])},[e.options.using.props]),N(()=>(e.dispatchers.dispatch(m.Mount,[]),e.dispatchers.dispatch(m.Node,[e.elements.customElement.current]),()=>e.dispatchers.dispatch(m.Unmount,[])),[])}function ae(e){const t=h(()=>({...e.options.using.model??{},[j]:{channel:S.Default}}),[]);return l.useRef(new O(t,t))}function le(){return l.useRef(new Set)}function de(){const[e,t]=l.useReducer(n=>n+1,0);return h(()=>({hash:e,rerender:t}),[e])}const fe={elementName:"x-chizu"},Q=l.createContext(null);function he(){const e=l.useContext(Q);if(!e)throw new Error("useModule must be used within a module.");return e}class me extends l.Component{constructor(t){super(t),this.state={error:null}}componentDidCatch(t){const n=Symbol("process"),r=I(this.props.model.current,n,(c,o)=>{o.channel=S.Error});this.props.model.current=r,this.props.update.rerender(),this.props.dispatchers.dispatch(m.Error,[J(t)])}render(){return i.jsx(se,{children:this.props.children})}}function pe({options:e}){const t=de(),n=le(),r=ue(),c=$(),o=ae({options:e}),u=ce({broadcast:c,options:e,update:t,model:o,queue:n}),a=ee({model:o,dispatchers:u});return te({options:e,dispatchers:u,actions:a}),ie({options:e,dispatchers:u,elements:r}),h(()=>l.createElement(me,{model:o,dispatchers:u,update:t,module:a.view,children(){return l.createElement(Q.Provider,{value:a.view,children:l.createElement(fe.elementName,{ref:r.customElement,style:{display:"contents"},children:e.children(a.view)})})}}),[t.hash,y(e.using.props)])}function ve(e){return i.jsx(pe,{options:e})}const ye=l.memo(ve,(e,t)=>y(e)===y(t));s.BroadcastProvider=Z,s.Channel=S,s.Lifecycle=m,s.State=B,s.Tree=ye,s.UserError=P,s.isActionError=ne,s.isUserError=re,s.useModule=he,s.utils=Y,Object.defineProperty(s,Symbol.toStringTag,{value:"Module"})});
1
+ (function(s,u){typeof exports=="object"&&typeof module<"u"?u(exports,require("react/jsx-runtime"),require("react"),require("eventemitter3"),require("immer"),require("lodash/get"),require("traverse")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react","eventemitter3","immer","lodash/get","traverse"],u):(s=typeof globalThis<"u"?globalThis:s||self,u(s.Chizu={},s.jsxRuntime,s.React,s.EventEmitter3,s.Immer,s.get,s.Traverse))})(this,function(s,u,d,y,U,b,O){"use strict";var ve=Object.defineProperty;var W=s=>{throw TypeError(s)};var be=(s,u,d)=>u in s?ve(s,u,{enumerable:!0,configurable:!0,writable:!0,value:d}):s[u]=d;var k=(s,u,d)=>be(s,typeof u!="symbol"?u+"":u,d),G=(s,u,d)=>u.has(s)||W("Cannot "+d);var T=(s,u,d)=>(G(s,u,"read from private field"),d?d.call(s):u.get(s)),_=(s,u,d)=>u.has(s)?W("Cannot add the same private member more than once"):u instanceof WeakSet?u.add(s):u.set(s,d),q=(s,u,d,y)=>(G(s,u,"write to private field"),y?y.call(s,d):u.set(s,d),d);var g,E;function K(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 a=K(d);class A{constructor(t){this.value=t}}class B{static Draft(t){return new A(t)}}k(B,"Op",{Add:1,Remove:2,Update:4,Move:8,Replace:16});var p=(e=>(e.Mount="lifecycle/mount",e.Node="lifecycle/node",e.Derive="lifecycle/derive",e.Error="lifecycle/error",e.Unmount="lifecycle/unmount",e))(p||{}),S=(e=>(e[e.Default=0]="Default",e[e.Error=1]="Error",e))(S||{});function V(e){return new Promise(t=>setTimeout(t,e))}function X(e){return e?!!(e&&typeof e!="symbol"):Symbol(`pk.${Date.now()}.${crypto.randomUUID()}`)}function w(e){return JSON.stringify(e)}const j=Symbol("meta"),Y=Object.freeze(Object.defineProperty({__proto__:null,hash:w,meta:j,pk:X,sleep:V},Symbol.toStringTag,{value:"Module"}));function m(e,t){const n=a.useRef(null),r=a.useRef(null);return a.useMemo(()=>{const o=w(t);if(r.current!==o){r.current=o;const c=e();return n.current=c,c}return n.current},t)}function N(e,t){const n=a.useRef(null);a.useEffect(()=>{const r=w(t);if(n.current!==r)return n.current=r,e()},t)}const z=a.createContext({instance:new y});function H(){return a.useContext(z)}function Z({children:e}){const t=m(()=>({instance:new y}),[]);return u.jsx(z.Provider,{value:t,children:e})}const f={immer:new U.Immer,annotations:Symbol("annotations")};U.enablePatches(),f.immer.setAutoFreeze(!1);class R{constructor(t,n,r=null){k(this,"process");this.value=t,this.operations=n,this.field=r,this.process=null}attach(t){return this.process=t,this}}function L(e,t=[]){return new R(e,t)}class D{constructor(t,n=t){this.stateless=t,this.stateful=n}get validatable(){return $(this.stateful)}}function $(e,t=[]){return new Proxy(e,{get(n,r){switch(r){case"is":return o=>{const c=P(e,t);if(!c)return!1;const i=new Set(c.flatMap(h=>h.operations));return!!(Array.from(i).reduce((h,v)=>h|(v??0),0)&o)};case"pending":return()=>!!P(e,t);case"draft":return()=>{const o=P(e,t);if(!o)return b(e,t);const c=o.flatMap(i=>i.operations).find(i=>i instanceof A);return c?c.value:b(e,t)}}return $(e,[...t,String(r)])}})}function P(e,t){const r=typeof b(e,t)=="object"?t:t.slice(0,-1),o=r.length===0?e:b(e,r),c=(o==null?void 0:o[f.annotations])??[];return c.length>0?c:null}function I(e,t,n){function r(i){return O(i).forEach(function(){if(this.key===f.annotations){this.block();return}this.node instanceof R&&this.update(this.node.value)})}function o(i){return O(i).forEach(function(){if(this.key===f.annotations){this.block();return}if(this.node instanceof R){const l=typeof this.node.value=="object",h=[...l?this.path:this.path.slice(0,-1),f.annotations],v=b(e.stateful,h)??[],x=this.node.attach(t);l?this.update({...this.node.value,[f.annotations]:[x,...v]},!0):(this.parent&&(this.parent.node[f.annotations]=[x,...v]),this.update(this.node.value,!0))}})}const c=i=>n(i,i[j]);return new D(r(f.immer.produce(e.stateless,c)),o(f.immer.produce(e.stateful,c)))}function C(e,t){const n=O(e.stateful).forEach(function(){if(this.key===f.annotations){this.block();return}if(this.node&&this.node[f.annotations]){const r=this.node[f.annotations];this.update({...this.node,[f.annotations]:r.filter(o=>o.process!==t)},!0)}});return new D(e.stateless,n)}function ee(e){return m(()=>({controller:{get model(){return e.model.current.stateful},queue:[],actions:{annotate(t,n){return L(t,n)},produce(t){return(n,r)=>I(n,r,t)},dispatch([t,...n]){if(t==null)return Promise.reject();const r=Promise.withResolvers();return e.dispatchers.dispatch(t,n,r),r.promise},context(t){const n=Object.keys(t);return e.context.use.current=t,e.context.update(),n.reduce((r,o)=>({...r,get[o](){return e.context.registry.current[o]}}),{})}}},view:{get model(){return e.model.current.stateless},get validate(){return e.model.current.validatable},boundary:{is(t){return e.model.current.stateless[j].boundary===t}},actions:{dispatch([t,...n]){if(t==null)return Promise.reject();const r=Promise.withResolvers();return e.dispatchers.dispatch(t,n,r),r.promise}}}}),[])}function te(e){const t=d.useRef(null);return t.current==null&&(t.current=e.options.using.actions(e.actions.controller)),m(()=>{if(t.current)return Object.entries(t.current).forEach(([r,o])=>e.dispatchers.attach(r,o)),t.current},[])}function F(e){return e.startsWith("distributed")}function ne(e){return e instanceof M}function J(e){return e instanceof M||e instanceof Error?e:new Error("Unknown error",{cause:e})}class M extends Error{constructor(n,r=null){super(String(r));_(this,g);_(this,E);q(this,g,n),q(this,E,r)}get type(){return T(this,g)}get message(){return T(this,E)||""}}g=new WeakMap,E=new WeakMap;function re({children:e}){return e()}function se(e){return(t,n)=>async(r=Promise.withResolvers(),o)=>{if(typeof n!="function")return;const c=Symbol("process"),i=n(...o);try{if(i==null)return;if(typeof i=="function"){const l=i(e.model.current,c);e.model.current=C(l,c),e.update.rerender(),r.resolve();return}for(;;){const{value:l,done:h}=await i.next();if(h){const x=l(e.model.current,c);e.model.current=C(x,c),e.update.rerender();break}const v=l;e.model.current=v(e.model.current,c),e.update.rerender(),r.resolve()}}catch(l){C(e.model.current,c),e.update.rerender(),e.unicast.emit(p.Error,r,[J(l)])}}}function oe(e){const t=H(),n=m(()=>new y,[]),r=se({...e,unicast:n});return m(()=>({attach(o,c){const i=String(o);F(i)?t.instance.on(i,r(o,c)):n.on(i,r(o,c))},dispatch(o,c,i){const l=String(o);F(l)?t.instance.emit(l,i,c):n.emit(l,i,c)}}),[])}function ce(){const e=a.useRef(null);return m(()=>({customElement:e}),[])}function ue(e){N(()=>{e.dispatchers.dispatch(p.Derive,[])},[e.options.using.props]),N(()=>(e.dispatchers.dispatch(p.Mount,[]),e.dispatchers.dispatch(p.Node,[e.elements.customElement.current]),()=>e.dispatchers.dispatch(p.Unmount,[])),[])}function ie(e){const t=m(()=>({...e.options.using.model??{},[j]:{boundary:S.Default}}),[]);return a.useRef(new D(t,t))}function ae(){return a.useRef(new Set)}function le(){const[e,t]=a.useReducer(n=>n+1,0);return m(()=>({hash:e,rerender:t}),[e])}const de={elementName:"x-chizu"},Q=a.createContext(null);function fe(){const e=a.useContext(Q);if(!e)throw new Error("useScoped is not being used within a scoped module.");return e}class he extends a.Component{constructor(t){super(t),this.state={error:null}}componentDidCatch(t){const n=Symbol("process"),r=I(this.props.model.current,n,(o,c)=>{c.boundary=S.Error});this.props.model.current=r,this.props.update.rerender(),this.props.dispatchers.dispatch(p.Error,[J(t)])}render(){return u.jsx(re,{children:this.props.children})}}function me(){const e=a.useRef({}),t=a.useRef({});function n(){t.current=Object.fromEntries(Object.entries(e.current).map(([r,o])=>[r,a.use(o)]))}return n(),m(()=>({use:e,registry:t,update:n}),[])}function pe({options:e}){const t=le(),n=ae(),r=ce(),o=H(),c=me(),i=ie({options:e}),l=oe({broadcast:o,options:e,update:t,model:i,queue:n}),h=ee({model:i,dispatchers:l,context:c});return te({options:e,dispatchers:l,actions:h}),ue({options:e,dispatchers:l,elements:r}),m(()=>a.createElement(he,{model:i,dispatchers:l,update:t,module:h.view,children(){return a.createElement(Q.Provider,{value:h.view,children:a.createElement(de.elementName,{ref:r.customElement,style:{display:"contents"},children:e.children(h.view)})})}}),[t.hash,w(e.using.props),w(c.registry)])}function ye(e){return u.jsx(pe,{options:e})}s.Boundary=S,s.Broadcaster=Z,s.Lifecycle=p,s.Scope=ye,s.State=B,s.TypedError=M,s.isTypedError=ne,s.useScoped=fe,s.utils=Y,Object.defineProperty(s,Symbol.toStringTag,{value:"Module"})});
@@ -0,0 +1,7 @@
1
+ import { Context } from '../types/index.ts';
2
+ import * as React from "react";
3
+ export default function useContext<C extends Context>(): {
4
+ use: React.RefObject<import('../types/index.ts').Props>;
5
+ registry: React.RefObject<import('../types/index.ts').Props>;
6
+ update: () => void;
7
+ };
@@ -0,0 +1,2 @@
1
+ import { default as useContext } from './index.ts';
2
+ export type UseContext = ReturnType<typeof useContext>;
@@ -1,11 +1,12 @@
1
- import { UserError } from '../errors/utils.ts';
1
+ import { TypedError } from '../errors/utils.ts';
2
2
  import { Models } from '../module/renderer/model/utils.ts';
3
3
  import { Head } from '../module/renderer/types.ts';
4
- import { Actions, Draft, Lifecycle, Meta, ModuleDefinition, Op, Queue } from '../types/index.ts';
4
+ import { Actions, Context, Draft, Lifecycle, Meta, ModuleDefinition, Op, Queue } from '../types/index.ts';
5
5
  export type ControllerActions<M extends ModuleDefinition> = {
6
6
  annotate<T>(value: T, operations?: (Op | Draft<T>)[]): T;
7
7
  produce(ƒ: (model: M["Model"], meta: Meta) => void): (models: Models<M["Model"]>, process: symbol) => Models<M["Model"]>;
8
8
  dispatch(action: M["Actions"]): Promise<void>;
9
+ context<C extends Context>(context: C): C;
9
10
  };
10
11
  export type ControllerArgs<M extends ModuleDefinition> = Readonly<{
11
12
  model: Readonly<M["Model"]>;
@@ -22,7 +23,7 @@ export type ControllerInstance<M extends ModuleDefinition> = {
22
23
  [Lifecycle.Mount]?(): ActionGenerator<M>;
23
24
  [Lifecycle.Derive]?(): ActionGenerator<M>;
24
25
  [Lifecycle.Node]?(tree: HTMLElement): ActionGenerator<M>;
25
- [Lifecycle.Error]?(error: Error | UserError): ActionGenerator<M>;
26
+ [Lifecycle.Error]?(error: Error | TypedError): ActionGenerator<M>;
26
27
  [Lifecycle.Unmount]?(): ActionGenerator<M>;
27
28
  } & Partial<ActionEvents<M>>;
28
29
  type Payload<A extends Actions, K> = A extends [K, infer P] ? P : never;
@@ -1,22 +1,27 @@
1
1
  import { ModuleDefinition } from '../types/index.ts';
2
2
  import { Props } from './types.ts';
3
- export declare function isActionError(error: Error | UserError): error is UserError;
4
- export declare function isUserError(error: Error | UserError): error is UserError;
3
+ /**
4
+ * Check if the error is an instance of TypedError.
5
+ *
6
+ * @param error {Error | TypedError}
7
+ * @returns {boolean}
8
+ */
9
+ export declare function isTypedError(error: Error | TypedError): error is TypedError;
5
10
  /**
6
11
  * Convert an unknown error into a known error type.
7
12
  *
8
13
  * @function intoError
9
14
  * @param error {unknown} - The error to convert to a known error type.
10
- * @returns {Error | UserError}
15
+ * @returns {Error | TypedError}
11
16
  */
12
- export declare function intoError(error: unknown): Error | UserError;
17
+ export declare function intoError(error: unknown): Error | TypedError;
13
18
  /**
14
- * @class UserError
19
+ * @class TypedError
15
20
  * @extends Error
16
21
  * @param type {string} - The type of the error.
17
22
  * @param message {string} - The error message.
18
23
  */
19
- export declare class UserError extends Error {
24
+ export declare class TypedError extends Error {
20
25
  #private;
21
26
  constructor(type: number | string | symbol, message?: null | string);
22
27
  get type(): number | string | symbol;
package/dist/index.d.ts CHANGED
@@ -1,13 +1,11 @@
1
1
  import { ControllerDefinition } from './controller/types.ts';
2
- import { ViewArgs, ViewDefinition } from './view/types.ts';
3
- export { Lifecycle, State, Channel } from './types/index.ts';
2
+ import { ViewArgs } from './view/types.ts';
3
+ export { Lifecycle, State, Boundary } from './types/index.ts';
4
4
  export * as utils from './utils/index.ts';
5
- export { default as Tree } from './module/index.tsx';
6
- export { BroadcastProvider } from './broadcast/index.tsx';
7
- export { useModule } from './module/renderer/utils.ts';
8
- export { isActionError, isUserError, UserError } from './errors/utils.ts';
9
- export type * as Typed from './types/index.ts';
10
- export type { Pk } from './types/index.ts';
11
- export type { ViewDefinition as View };
12
- export type { ViewArgs as Within };
5
+ export { default as Scope } from './module/index.tsx';
6
+ export { Broadcaster } from './broadcast/index.tsx';
7
+ export { useScoped } from './module/renderer/utils.ts';
8
+ export { isTypedError, TypedError } from './errors/utils.ts';
9
+ export type { Schema, Pk } from './types/index.ts';
10
+ export type { ViewArgs as Scoped };
13
11
  export type { ControllerDefinition as Actions };
@@ -1,6 +1,4 @@
1
1
  import { ModuleDefinition } from '../types/index.ts';
2
2
  import { UseOptions } from './types.ts';
3
3
  import * as React from "react";
4
- declare function Tree<M extends ModuleDefinition>(options: UseOptions<M>): React.ReactNode;
5
- declare const _default: typeof Tree;
6
- export default _default;
4
+ export default function Scope<M extends ModuleDefinition>(options: UseOptions<M>): React.ReactNode;
@@ -1,4 +1,5 @@
1
1
  import { UseBroadcast } from '../../../broadcast/types.ts';
2
+ import { UseContext } from '../../../context/types.ts';
2
3
  import { ControllerArgs } from '../../../controller/types.ts';
3
4
  import { ModuleDefinition } from '../../../types/index.ts';
4
5
  import { ViewArgs } from '../../../view/types.ts';
@@ -10,6 +11,7 @@ export type Props<M extends ModuleDefinition> = {
10
11
  options: UseOptions<M>;
11
12
  model: UseModel;
12
13
  dispatchers: UseDispatchers;
14
+ context: UseContext;
13
15
  };
14
16
  export type UseActions<M extends ModuleDefinition> = {
15
17
  controller: ControllerArgs<M>;
@@ -1,3 +1,4 @@
1
1
  import { ModuleDefinition } from '../../../types/index.ts';
2
2
  import { Props } from './types.ts';
3
- export default function useController<M extends ModuleDefinition>(props: Props<M>): import('../../../controller/types.ts').ControllerInstance<M>;
3
+ import { ControllerInstance } from '../../../controller/types.ts';
4
+ export default function useController<M extends ModuleDefinition>(props: Props<M>): ControllerInstance<M> | undefined;
@@ -5,4 +5,4 @@ export declare const config: {
5
5
  elementName: string;
6
6
  };
7
7
  export declare const Context: React.Context<ViewArgs<ModuleDefinition> | null>;
8
- export declare function useModule<M extends ModuleDefinition>(): ViewArgs<M>;
8
+ export declare function useScoped<M extends ModuleDefinition>(): ViewArgs<M>;
@@ -30,7 +30,8 @@ export declare enum Lifecycle {
30
30
  export type Model = Record<symbol | string, any>;
31
31
  export type Actions = [] | [ActionName] | [ActionName, ...ActionPayload];
32
32
  export type Props = Record<string, unknown>;
33
- export type Module<M extends Model, A extends Actions = [], P extends Props = Record<string, never>> = {
33
+ export type Context = Props;
34
+ export type Schema<M extends Model, A extends Actions = [], P extends Props = Record<string, never>> = {
34
35
  Model: M;
35
36
  Actions: A;
36
37
  Props: P;
@@ -50,11 +51,11 @@ export type Queue<A extends ModuleDefinition["Actions"]> = {
50
51
  export type Task = PromiseWithResolvers<void>;
51
52
  export type Process = symbol;
52
53
  export type Op = number;
53
- export declare enum Channel {
54
+ export declare enum Boundary {
54
55
  Default = 0,
55
56
  Error = 1
56
57
  }
57
58
  export type Meta = {
58
- channel: Channel;
59
+ boundary: Boundary;
59
60
  };
60
61
  export {};
@@ -1,13 +1,13 @@
1
1
  import { Validatable } from '../module/renderer/model/types.ts';
2
- import { Channel, ModuleDefinition } from '../types/index.ts';
2
+ import { Boundary, ModuleDefinition } from '../types/index.ts';
3
3
  import * as React from "react";
4
4
  export type ViewActions<M extends ModuleDefinition> = {
5
5
  dispatch(action: M["Actions"]): Promise<void>;
6
6
  };
7
7
  export type ViewArgs<M extends ModuleDefinition> = Readonly<{
8
8
  model: Readonly<M["Model"]>;
9
- channel: {
10
- is(channel: Channel): boolean;
9
+ boundary: {
10
+ is(boundary: Boundary): boolean;
11
11
  };
12
12
  validate: Readonly<Validatable<M["Model"]>>;
13
13
  actions: Readonly<ViewActions<M>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chizu",
3
- "version": "0.2.21",
3
+ "version": "0.2.23",
4
4
  "type": "module",
5
5
  "main": "./dist/chizu.js",
6
6
  "types": "./dist/index.d.ts",