chizu 0.2.12 → 0.2.13

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
@@ -18,19 +18,17 @@ Strongly typed React framework using generators and efficiently updated views al
18
18
  - Mostly standard JavaScript without quirky rules and exceptions.
19
19
  - Clear separation of concerns between business logic and markup.
20
20
  - First-class support for skeleton loading using generators.
21
- - Strongly typed throughout – styles, controllers and views.
21
+ - Strongly typed throughout – styles, actions and views.
22
22
  - Avoid vendor lock-in with framework agnostic libraries such as [Shoelace](https://shoelace.style/).
23
- - Easily communicate between controllers using distributed actions.
23
+ - Easily communicate between actions using distributed actions.
24
24
  - State is mutated sequentially ([FIFO](<https://en.wikipedia.org/wiki/FIFO_(computing_and_electronics)>)) and deeply merged for queued mutations.
25
25
 
26
26
  ## Getting started
27
27
 
28
- Controllers are responsible for mutating the state of the view. In the below example the `name` is dispatched from the view to the controller, the state is updated and the view is rendered once with the updated value.
29
-
30
- <kbd>Controller</kbd>
28
+ Actions are responsible for mutating the state of the view. In the below example the `name` is dispatched from the view to the actions, the state is updated and the view is rendered with the updated value.
31
29
 
32
30
  ```tsx
33
- export default (function ProfileController(module) {
31
+ export default (function Actions(module) {
34
32
  return {
35
33
  async *[Events.Name](name) {
36
34
  return module.actions.produce((draft) => {
@@ -38,33 +36,33 @@ export default (function ProfileController(module) {
38
36
  });
39
37
  },
40
38
  };
41
- } as Controller<Module>);
39
+ } as Actions<Module>);
42
40
  ```
43
41
 
44
- <kbd>View</kbd>
45
-
46
42
  ```tsx
47
- export default (function ProfileView(module) {
43
+ export default function Profile(props: Props): React.ReactElement {
48
44
  return (
49
- <>
50
- <p>Hey {module.model.name}</p>
51
-
52
- <button
53
- onClick={() => module.actions.dispatch([Events.Name, randomName()])}
54
- >
55
- Switch profile
56
- </button>
57
- </>
45
+ <Tree<Module> using={{ model, actions, props }}>
46
+ {(module) => (
47
+ <>
48
+ <p>Hey {module.model.name}</p>
49
+
50
+ <button
51
+ onClick={() => module.actions.dispatch([Events.Name, randomName()])}
52
+ >
53
+ Switch profile
54
+ </button>
55
+ </>
56
+ )}
57
+ </Tree>
58
58
  );
59
- } as View<Module>);
59
+ }
60
60
  ```
61
61
 
62
- Fetching the name from an external source using an `actions.io` causes the controller event (`Events.Name`) and associated view to be invoked twice &ndash; once with a record of mutations to display a pending state, and then again with the model once it's been mutated.
63
-
64
- <kbd>Controller</kbd>
62
+ You can perform asynchronous operations in the action which will cause the associated view to render a second time:
65
63
 
66
64
  ```tsx
67
- export default (function ProfileController(module) {
65
+ export default (function Actions(module) {
68
66
  return {
69
67
  async *[Events.Name]() {
70
68
  yield module.actions.produce((draft) => {
@@ -78,31 +76,31 @@ export default (function ProfileController(module) {
78
76
  });
79
77
  },
80
78
  };
81
- } as Controller<Module>);
79
+ } as Actions<Module>);
82
80
  ```
83
81
 
84
- <kbd>View</kbd>
85
-
86
82
  ```tsx
87
- export default (function ProfileView(module) {
83
+ export default function Profile(props: Props): React.ReactElement {
88
84
  return (
89
- <>
90
- <p>Hey {module.model.name}</p>
91
-
92
- <button onClick={() => module.actions.dispatch([Events.Name])}>
93
- Switch profile
94
- </button>
95
- </>
85
+ <Tree<Module> using={{ model, actions, props }}>
86
+ {(module) => (
87
+ <>
88
+ <p>Hey {module.model.name}</p>
89
+
90
+ <button onClick={() => module.actions.dispatch([Events.Name])}>
91
+ Switch profile
92
+ </button>
93
+ </>
94
+ )}
95
+ </Tree>
96
96
  );
97
- } as View<Module>);
97
+ }
98
98
  ```
99
99
 
100
- <!-- In the above example the name is fetched asynchronously &ndash; however there is no feedback to the user, we can improve that by using the `module.actions.state` and `module.validate` helpers: -->
101
-
102
- <kbd>Controller</kbd>
100
+ However in the above example where the name is fetched asynchronously, there is no feedback to the user &ndash; we can improve that significantly by using the `module.actions.annotate` and `module.validate` helpers:
103
101
 
104
102
  ```tsx
105
- export default (function ProfileController(module) {
103
+ export default (function Actions(module) {
106
104
  return {
107
105
  async *[Events.Name]() {
108
106
  yield module.actions.produce((draft) => {
@@ -115,49 +113,49 @@ export default (function ProfileController(module) {
115
113
  });
116
114
  },
117
115
  };
118
- } as Controller<Module>);
116
+ } as Actions<Module>);
119
117
  ```
120
118
 
121
- <kbd>View</kbd>
122
-
123
119
  ```tsx
124
- export default (function ProfileView(module) {
120
+ export default function ProfileView(props: Props): React.ReactElement {
125
121
  return (
126
- <>
127
- <p>Hey {module.model.name}</p>
128
-
129
- {module.validate.name.pending() && <p>Switching profiles&hellip;</p>}
130
-
131
- <button
132
- disabled={module.validate.name.is(State.Op.Update)}
133
- onClick={() => module.actions.dispatch([Events.Name])}
134
- >
135
- Switch profile
136
- </button>
137
- </>
122
+ <Tree<Module> using={{ module, actions, props }}>
123
+ {(module) => (
124
+ <>
125
+ <p>Hey {module.model.name}</p>
126
+
127
+ {module.validate.name.pending() && <p>Switching profiles&hellip;</p>}
128
+
129
+ <button
130
+ disabled={module.validate.name.is(State.Op.Update)}
131
+ onClick={() => module.actions.dispatch([Events.Name])}
132
+ >
133
+ Switch profile
134
+ </button>
135
+ </>
136
+ )}
137
+ </Tree>
138
138
  );
139
- } as View<Module>);
139
+ }
140
140
  ```
141
141
 
142
142
  ## Handling Errors
143
143
 
144
- Controller actions can throw errors directly or in any of their associated `yield` actions &ndash; all unhandled errors are automatically caught and broadcast using the `Lifecycle.Error` action &ndash; you can render these [in a toast](https://github.com/fkhadra/react-toastify#readme) or similar UI.
144
+ Actions can throw errors directly or in any of their associated `yield` actions &ndash; all unhandled errors are automatically caught and broadcast using the `Lifecycle.Error` action &ndash; you can render these [in a toast](https://github.com/fkhadra/react-toastify#readme) or similar UI.
145
145
 
146
146
  You can also customise these errors a little further with your own error `enum` which describes the error type:
147
147
 
148
148
  <kbd>Types</kbd>
149
149
 
150
- ```tsx
150
+ ```ts
151
151
  export const enum Errors {
152
152
  UserValidation,
153
153
  IncorrectPassword,
154
154
  }
155
155
  ```
156
156
 
157
- <kbd>Controller</kbd>
158
-
159
157
  ```tsx
160
- export default (function ProfileController(module) {
158
+ export default (function Actions(module) {
161
159
  return {
162
160
  *[Events.Name]() {
163
161
  yield module.actions.produce((draft) => {
@@ -173,15 +171,13 @@ export default (function ProfileController(module) {
173
171
  });
174
172
  },
175
173
  };
176
- }) as Controller<Module>;
174
+ }) as Actions<Module>;
177
175
  ```
178
176
 
179
177
  However showing a toast message is not always relevant, you may want a more detailed error message such as a user not found message &ndash; although you could introduce another property for such errors in your model, you could mark the property as fallible by giving it a `Maybe` type because it then keeps everything nicely associated with the `name` property rather than creating another property:
180
178
 
181
- <kbd>Controller</kbd>
182
-
183
179
  ```tsx
184
- export default (function ProfileView(module) {
180
+ export default (function Actions(module) {
185
181
  return {
186
182
  async *[Events.Name]() {
187
183
  yield module.actions.produce((draft) => {
@@ -201,5 +197,5 @@ export default (function ProfileView(module) {
201
197
  });
202
198
  },
203
199
  };
204
- } as View<Module>);
200
+ } as Actions<Module>);
205
201
  ```
package/dist/chizu.js CHANGED
@@ -1,28 +1,27 @@
1
- var q = Object.defineProperty;
2
- var O = (t) => {
1
+ var T = Object.defineProperty;
2
+ var j = (t) => {
3
3
  throw TypeError(t);
4
4
  };
5
- var z = (t, e, n) => e in t ? q(t, e, { enumerable: !0, configurable: !0, writable: !0, value: n }) : t[e] = n;
6
- var E = (t, e, n) => z(t, typeof e != "symbol" ? e + "" : e, n), A = (t, e, n) => e.has(t) || O("Cannot " + n);
7
- var R = (t, e, n) => (A(t, e, "read from private field"), n ? n.call(t) : e.get(t)), b = (t, e, n) => e.has(t) ? O("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(t) : e.set(t, n), S = (t, e, n, r) => (A(t, e, "write to private field"), r ? r.call(t, n) : e.set(t, n), n);
8
- import { jsx as p, Fragment as F } from "react/jsx-runtime";
9
- import { Immer as T } from "immer";
10
- import v from "lodash/get";
11
- import x from "traverse";
5
+ var z = (t, e, n) => e in t ? T(t, e, { enumerable: !0, configurable: !0, writable: !0, value: n }) : t[e] = n;
6
+ var y = (t, e, n) => z(t, typeof e != "symbol" ? e + "" : e, n), k = (t, e, n) => e.has(t) || j("Cannot " + n);
7
+ var w = (t, e, n) => (k(t, e, "read from private field"), n ? n.call(t) : e.get(t)), E = (t, e, n) => e.has(t) ? j("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(t) : e.set(t, n), b = (t, e, n, r) => (k(t, e, "write to private field"), r ? r.call(t, n) : e.set(t, n), n);
8
+ import { Immer as N } from "immer";
9
+ import p from "lodash/get";
10
+ import R from "traverse";
11
+ import { jsx as $ } from "react/jsx-runtime";
12
12
  import * as a from "react";
13
- import D from "eventemitter3";
14
- import * as h from "react-router-dom";
15
- class C {
13
+ import M from "eventemitter3";
14
+ class O {
16
15
  constructor(e) {
17
16
  this.value = e;
18
17
  }
19
18
  }
20
- class $ {
19
+ class q {
21
20
  static Draft(e) {
22
- return new C(e);
21
+ return new O(e);
23
22
  }
24
23
  }
25
- E($, "Op", {
24
+ y(q, "Op", {
26
25
  Add: 1,
27
26
  Remove: 2,
28
27
  Update: 4,
@@ -30,240 +29,234 @@ E($, "Op", {
30
29
  Replace: 16
31
30
  });
32
31
  var m = /* @__PURE__ */ ((t) => (t.Mount = "lifecycle/mount", t.Node = "lifecycle/node", t.Derive = "lifecycle/derive", t.Error = "distributed/lifecycle/error", t.Unmount = "lifecycle/unmount", t))(m || {});
33
- const l = {
34
- immer: new T(),
32
+ const c = {
33
+ immer: new N(),
35
34
  annotations: Symbol("annotations")
36
35
  };
37
- l.immer.setAutoFreeze(!1);
38
- class M {
36
+ c.immer.setAutoFreeze(!1);
37
+ class S {
39
38
  constructor(e, n, r = null) {
40
- E(this, "process");
39
+ y(this, "process");
41
40
  this.value = e, this.operations = n, this.field = r, this.process = null;
42
41
  }
43
42
  attach(e) {
44
43
  return this.process = e, this;
45
44
  }
46
45
  }
47
- function J(t, e = []) {
48
- return new M(t, e);
46
+ function I(t, e = []) {
47
+ return new S(t, e);
49
48
  }
50
- class k {
49
+ class P {
51
50
  constructor(e, n = e) {
52
51
  this.stateless = e, this.stateful = n;
53
52
  }
54
53
  get validatable() {
55
- return I(this.stateful);
54
+ return U(this.stateful);
56
55
  }
57
56
  }
58
- function I(t, e = []) {
57
+ function U(t, e = []) {
59
58
  return new Proxy(t, {
60
59
  get(n, r) {
61
60
  switch (r) {
62
61
  case "is":
63
- return (s) => {
64
- const o = P(t, e);
65
- if (!o) return !1;
62
+ return (o) => {
63
+ const s = x(t, e);
64
+ if (!s) return !1;
66
65
  const u = new Set(
67
- o.flatMap((i) => i.operations)
66
+ s.flatMap((l) => l.operations)
68
67
  );
69
68
  return !!(Array.from(u).reduce(
70
- (i, f) => i | (f ?? 0),
69
+ (l, d) => l | (d ?? 0),
71
70
  0
72
- ) & s);
71
+ ) & o);
73
72
  };
74
73
  case "pending":
75
- return () => !!P(t, e);
74
+ return () => !!x(t, e);
76
75
  case "draft":
77
76
  return () => {
78
- const s = P(t, e);
79
- if (!s) return v(t, e);
80
- const o = s.flatMap((u) => u.operations).find((u) => u instanceof C);
81
- return o ? o.value : v(t, e);
77
+ const o = x(t, e);
78
+ if (!o) return p(t, e);
79
+ const s = o.flatMap((u) => u.operations).find((u) => u instanceof O);
80
+ return s ? s.value : p(t, e);
82
81
  };
83
82
  }
84
- return I(t, [...e, String(r)]);
83
+ return U(t, [...e, String(r)]);
85
84
  }
86
85
  });
87
86
  }
88
- function P(t, e) {
89
- const r = typeof v(t, e) == "object" ? e : e.slice(0, -1), s = r.length === 0 ? t : v(t, r), o = (s == null ? void 0 : s[l.annotations]) ?? [];
90
- return o.length > 0 ? o : null;
87
+ function x(t, e) {
88
+ 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[c.annotations]) ?? [];
89
+ return s.length > 0 ? s : null;
91
90
  }
92
- function Q(t, e, n) {
93
- function r(o) {
94
- return x(o).forEach(function() {
95
- if (this.key === l.annotations) {
91
+ function F(t, e, n) {
92
+ function r(s) {
93
+ return R(s).forEach(function() {
94
+ if (this.key === c.annotations) {
96
95
  this.block();
97
96
  return;
98
97
  }
99
- this.node instanceof M && this.update(this.node.value);
98
+ this.node instanceof S && this.update(this.node.value);
100
99
  });
101
100
  }
102
- function s(o) {
103
- return x(o).forEach(function() {
104
- if (this.key === l.annotations) {
101
+ function o(s) {
102
+ return R(s).forEach(function() {
103
+ if (this.key === c.annotations) {
105
104
  this.block();
106
105
  return;
107
106
  }
108
- if (this.node instanceof M) {
109
- const u = typeof this.node.value == "object", c = [
107
+ if (this.node instanceof S) {
108
+ const u = typeof this.node.value == "object", i = [
110
109
  ...u ? this.path : this.path.slice(0, -1),
111
- l.annotations
112
- ], i = v(t.stateful, c) ?? [], f = this.node.attach(e);
110
+ c.annotations
111
+ ], l = p(t.stateful, i) ?? [], d = this.node.attach(e);
113
112
  u ? this.update(
114
113
  {
115
114
  ...this.node.value,
116
- [l.annotations]: [f, ...i]
115
+ [c.annotations]: [d, ...l]
117
116
  },
118
117
  !0
119
- ) : (this.parent && (this.parent.node[l.annotations] = [f, ...i]), this.update(this.node.value, !0));
118
+ ) : (this.parent && (this.parent.node[c.annotations] = [d, ...l]), this.update(this.node.value, !0));
120
119
  }
121
120
  });
122
121
  }
123
- return new k(
124
- r(l.immer.produce(t.stateless, n)),
125
- s(l.immer.produce(t.stateful, n))
122
+ return new P(
123
+ r(c.immer.produce(t.stateless, n)),
124
+ o(c.immer.produce(t.stateful, n))
126
125
  );
127
126
  }
128
- function U(t, e) {
129
- const n = x(t.stateful).forEach(function() {
130
- if (this.key === l.annotations) {
127
+ function D(t, e) {
128
+ const n = R(t.stateful).forEach(function() {
129
+ if (this.key === c.annotations) {
131
130
  this.block();
132
131
  return;
133
132
  }
134
- if (this.node && this.node[l.annotations]) {
135
- const r = this.node[l.annotations];
133
+ if (this.node && this.node[c.annotations]) {
134
+ const r = this.node[c.annotations];
136
135
  this.update(
137
136
  {
138
137
  ...this.node,
139
- [l.annotations]: r.filter(
140
- (s) => s.process !== e
138
+ [c.annotations]: r.filter(
139
+ (o) => o.process !== e
141
140
  )
142
141
  },
143
142
  !0
144
143
  );
145
144
  }
146
145
  });
147
- return new k(t.stateless, n);
146
+ return new P(t.stateless, n);
148
147
  }
149
- function W(t) {
150
- return (e, n) => async (r = Promise.withResolvers(), s) => {
148
+ function J(t) {
149
+ return (e, n) => async (r = Promise.withResolvers(), o) => {
151
150
  if (typeof n != "function") return;
152
- const o = Symbol("process"), u = n(...s);
151
+ const s = Symbol("process"), u = n(...o);
153
152
  if (u == null)
154
153
  return void r.resolve();
155
154
  if (typeof u == "function") {
156
- const c = u(t.model.current, o);
157
- return t.model.current = U(c, o), t.update.rerender(), void r.resolve();
155
+ const i = u(t.model.current, s);
156
+ return t.model.current = D(i, s), t.update.rerender(), void r.resolve();
158
157
  }
159
158
  for (; ; ) {
160
- const { value: c, done: i } = await u.next();
161
- if (i) {
162
- const N = c(t.model.current, o);
163
- t.model.current = U(N, o), t.update.rerender();
159
+ const { value: i, done: l } = await u.next();
160
+ if (l) {
161
+ const H = i(t.model.current, s);
162
+ t.model.current = D(H, s), t.update.rerender();
164
163
  break;
165
164
  }
166
- const f = c;
167
- t.model.current = f(t.model.current, o), t.update.rerender();
165
+ const d = i;
166
+ t.model.current = d(t.model.current, s), t.update.rerender();
168
167
  }
169
168
  r.resolve();
170
169
  };
171
170
  }
172
- function _(t) {
171
+ function A(t) {
173
172
  return t.startsWith("distributed");
174
173
  }
175
- var y, w;
176
- class G extends Error {
174
+ var v, g;
175
+ class Q extends Error {
177
176
  constructor(n, r = null) {
178
177
  super(String(r));
179
- b(this, y);
180
- b(this, w);
181
- S(this, y, n), S(this, w, r);
178
+ E(this, v);
179
+ E(this, g);
180
+ b(this, v, n), b(this, g, r);
182
181
  }
183
182
  get type() {
184
- return R(this, y);
183
+ return w(this, v);
185
184
  }
186
185
  get message() {
187
- return R(this, w) || "";
186
+ return w(this, g) || "";
188
187
  }
189
188
  }
190
- y = new WeakMap(), w = new WeakMap();
191
- function K(t) {
189
+ v = new WeakMap(), g = new WeakMap();
190
+ function W(t) {
192
191
  return new Promise((e) => setTimeout(e, t));
193
192
  }
194
- function V(t) {
193
+ function G(t) {
195
194
  return t ? !!(t && typeof t != "symbol") : Symbol(`pk.${Date.now()}.${crypto.randomUUID()}`);
196
195
  }
197
- function X(t) {
198
- return t instanceof G;
196
+ function K(t) {
197
+ return t instanceof Q;
199
198
  }
200
- function g(t) {
199
+ function h(t) {
201
200
  return JSON.stringify(t);
202
201
  }
203
- const yt = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
202
+ const ft = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
204
203
  __proto__: null,
205
- hash: g,
206
- isEventError: X,
207
- pk: V,
208
- sleep: K
204
+ hash: h,
205
+ isEventError: K,
206
+ pk: G,
207
+ sleep: W
209
208
  }, Symbol.toStringTag, { value: "Module" }));
210
- function d(t, e) {
209
+ function f(t, e) {
211
210
  const n = a.useRef(null), r = a.useRef(null);
212
211
  return a.useMemo(() => {
213
- const s = g(e);
214
- if (r.current !== s) {
215
- r.current = s;
216
- const o = t();
217
- return n.current = o, o;
212
+ const o = h(e);
213
+ if (r.current !== o) {
214
+ r.current = o;
215
+ const s = t();
216
+ return n.current = s, s;
218
217
  }
219
218
  return n.current;
220
219
  }, e);
221
220
  }
222
- function j(t, e) {
221
+ function C(t, e) {
223
222
  const n = a.useRef(null);
224
223
  a.useEffect(() => {
225
- const r = g(e);
224
+ const r = h(e);
226
225
  if (n.current !== r)
227
226
  return n.current = r, t();
228
227
  }, e);
229
228
  }
230
- const B = a.createContext({
231
- appEmitter: new D()
229
+ const _ = a.createContext({
230
+ appEmitter: new M()
232
231
  });
233
- function H() {
234
- return a.useContext(B);
232
+ function B() {
233
+ return a.useContext(_);
235
234
  }
236
- function Y(t) {
235
+ function dt({ children: t }) {
237
236
  return () => {
238
- const e = d(
237
+ const e = f(
239
238
  () => ({
240
- appEmitter: new D()
239
+ appEmitter: new M()
241
240
  }),
242
241
  []
243
242
  );
244
- return /* @__PURE__ */ p(B.Provider, { value: e, children: /* @__PURE__ */ p(t, {}) });
243
+ return /* @__PURE__ */ $(_.Provider, { value: e, children: t });
245
244
  };
246
245
  }
247
- function Z(t) {
248
- return d(
246
+ function V(t) {
247
+ return f(
249
248
  () => ({
250
249
  controller: {
251
250
  get model() {
252
251
  return t.model.current.stateful;
253
252
  },
254
- get props() {
255
- return t.props.current;
256
- },
257
- get router() {
258
- return t.router.current;
259
- },
260
253
  queue: [],
261
254
  actions: {
262
255
  annotate(e, n) {
263
- return J(e, n);
256
+ return I(e, n);
264
257
  },
265
258
  produce(e) {
266
- return (n, r) => Q(n, r, e);
259
+ return (n, r) => F(n, r, e);
267
260
  },
268
261
  dispatch([e, ...n]) {
269
262
  if (e == null) return Promise.reject();
@@ -276,9 +269,6 @@ function Z(t) {
276
269
  get model() {
277
270
  return t.model.current.stateless;
278
271
  },
279
- get props() {
280
- return t.props.current;
281
- },
282
272
  get validate() {
283
273
  return t.model.current.validatable;
284
274
  },
@@ -294,111 +284,70 @@ function Z(t) {
294
284
  []
295
285
  );
296
286
  }
297
- function L(t) {
298
- return d(() => {
299
- var r, s;
300
- const e = (s = (r = t.options).controller) == null ? void 0 : s.call(r, t.actions.controller);
301
- return e ? (Object.entries(e).forEach(([o, u]) => t.dispatchers.attach(o, u)), e) : void 0;
287
+ function X(t) {
288
+ return f(() => {
289
+ const e = t.options.using.actions(t.actions.controller);
290
+ return Object.entries(e).forEach(([r, o]) => t.dispatchers.attach(r, o)), e;
302
291
  }, []);
303
292
  }
304
- function tt(t) {
305
- const e = H(), n = W(t);
306
- return d(() => {
307
- const r = new D(), s = e.appEmitter;
293
+ function Y(t) {
294
+ const e = B(), n = J(t);
295
+ return f(() => {
296
+ const r = new M(), o = e.appEmitter;
308
297
  return {
309
- attach(o, u) {
310
- const c = String(o);
311
- _(c) ? s.on(c, n(o, u)) : r.on(c, n(o, u));
298
+ attach(s, u) {
299
+ const i = String(s);
300
+ A(i) ? o.on(i, n(s, u)) : r.on(i, n(s, u));
312
301
  },
313
- dispatch(o, u, c) {
314
- const i = String(o);
315
- _(i) ? s.emit(i, c, u) : r.emit(i, c, u);
302
+ dispatch(s, u, i) {
303
+ const l = String(s);
304
+ A(l) ? o.emit(l, i, u) : r.emit(l, i, u);
316
305
  }
317
306
  };
318
307
  }, []);
319
308
  }
320
- function et() {
309
+ function Z() {
321
310
  const t = a.useRef(null);
322
- return d(() => ({ customElement: t }), []);
311
+ return f(() => ({ customElement: t }), []);
323
312
  }
324
- function nt(t) {
325
- var e, n, r, s;
326
- j(() => {
313
+ function L(t) {
314
+ C(() => {
327
315
  t.dispatchers.dispatch(m.Derive, []);
328
- }, [
329
- t.options.props,
330
- (e = t.router.current) == null ? void 0 : e.location,
331
- (n = t.router.current) == null ? void 0 : n.params,
332
- (s = (r = t.router.current) == null ? void 0 : r.search) == null ? void 0 : s[0]
333
- ]), j(() => (t.dispatchers.dispatch(m.Mount, []), t.dispatchers.dispatch(m.Node, [
316
+ }, [t.options.using.props]), C(() => (t.dispatchers.dispatch(m.Mount, []), t.dispatchers.dispatch(m.Node, [
334
317
  t.elements.customElement.current
335
318
  ]), () => t.dispatchers.dispatch(m.Unmount, [])), []);
336
319
  }
337
- function rt(t) {
338
- const e = d(() => t.options.model ?? {}, []);
339
- return a.useRef(new k(e, e));
340
- }
341
- function ot(t) {
342
- const e = a.useRef(t.options.props);
343
- return j(() => {
344
- e.current = t.options.props, t.update.rerender();
345
- }, [t.options.props]), e;
320
+ function tt(t) {
321
+ const e = f(() => t.options.using.model ?? {}, []);
322
+ return a.useRef(new P(e, e));
346
323
  }
347
- function st() {
324
+ function et() {
348
325
  return a.useRef(/* @__PURE__ */ new Set());
349
326
  }
350
- function ut() {
351
- return a.useRef(null);
352
- }
353
- function ct({ using: t, children: e }) {
354
- return h.useInRouterContext() ? /* @__PURE__ */ p(it, { using: t, children: e }) : e();
355
- }
356
- function it({ using: t, children: e }) {
357
- return t.current = {
358
- navigate: h.useNavigate(),
359
- location: h.useLocation(),
360
- params: h.useParams(),
361
- search: h.useSearchParams()
362
- }, /* @__PURE__ */ p(F, { children: e() });
363
- }
364
- function at() {
327
+ function nt() {
365
328
  const [t, e] = a.useReducer((n) => n + 1, 0);
366
- return d(() => ({ hash: t, rerender: e }), [t]);
329
+ return f(() => ({ hash: t, rerender: e }), [t]);
367
330
  }
368
- function lt({
331
+ function rt({
369
332
  options: t
370
333
  }) {
371
- const e = H(), n = at(), r = st(), s = et(), o = ut(), u = ot({ options: t, update: n }), c = rt({ options: t }), i = tt({ app: e, options: t, update: n, model: c, queue: r }), f = Z({
372
- app: e,
373
- options: t,
374
- model: c,
375
- dispatchers: i,
376
- router: o,
377
- props: u
378
- });
379
- return L({ options: t, dispatchers: i, actions: f }), nt({ options: t, dispatchers: i, elements: s, router: o, update: n }), d(() => a.createElement(t.name, {
380
- ref: s.customElement,
334
+ const e = B(), n = nt(), r = et(), o = Z(), s = tt({ options: t }), u = Y({ app: e, options: t, update: n, model: s, queue: r }), i = V({ app: e, options: t, model: s, dispatchers: u });
335
+ return X({ options: t, dispatchers: u, actions: i }), L({ options: t, dispatchers: u, elements: o, update: n }), f(() => a.createElement("x-chizu", {
336
+ ref: o.customElement,
381
337
  style: { display: "contents" },
382
- children: /* @__PURE__ */ p(ct, { using: o, children: () => t.view(f.view) })
383
- }), [n.hash]);
338
+ children: t.children(i.view)
339
+ }), [n.hash, h(t.using.props)]);
384
340
  }
385
- function ft(t) {
386
- return (e) => a.memo(
387
- (n) => lt({
388
- options: {
389
- ...e,
390
- name: t.join(""),
391
- props: n
392
- }
393
- }),
394
- (n, r) => g(n) === g(r)
395
- );
341
+ function st(t) {
342
+ return rt({ options: t });
396
343
  }
397
- const wt = { app: Y, module: ft };
344
+ const ht = a.memo(st, (t, e) => h(t) === h(e));
398
345
  export {
399
- G as EventError,
346
+ dt as Context,
347
+ Q as EventError,
400
348
  m as Lifecycle,
401
- $ as State,
402
- wt as create,
403
- yt as utils
349
+ q as State,
350
+ ht as Tree,
351
+ B as useContext,
352
+ ft as utils
404
353
  };
@@ -1 +1 @@
1
- (function(s,u){typeof exports=="object"&&typeof module<"u"?u(exports,require("react/jsx-runtime"),require("immer"),require("lodash/get"),require("traverse"),require("react"),require("eventemitter3"),require("react-router-dom")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","immer","lodash/get","traverse","react","eventemitter3","react-router-dom"],u):(s=typeof globalThis<"u"?globalThis:s||self,u(s.Chizu={},s.jsxRuntime,s.Immer,s.get,s.Traverse,s.React,s.EventEmitter3,s.ReactRouterDOM))})(this,function(s,u,a,p,E,$,S,J){"use strict";var pe=Object.defineProperty;var H=s=>{throw TypeError(s)};var ve=(s,u,a)=>u in s?pe(s,u,{enumerable:!0,configurable:!0,writable:!0,value:a}):s[u]=a;var D=(s,u,a)=>ve(s,typeof u!="symbol"?u+"":u,a),F=(s,u,a)=>u.has(s)||H("Cannot "+a);var _=(s,u,a)=>(F(s,u,"read from private field"),a?a.call(s):u.get(s)),x=(s,u,a)=>u.has(s)?H("Cannot add the same private member more than once"):u instanceof WeakSet?u.add(s):u.set(s,a),k=(s,u,a,p)=>(F(s,u,"write to private field"),p?p.call(s,a):u.set(s,a),a);var b,R;function q(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 d=q($),g=q(J);class T{constructor(t){this.value=t}}class A{static Draft(t){return new T(t)}}D(A,"Op",{Add:1,Remove:2,Update:4,Move:8,Replace:16});var y=(e=>(e.Mount="lifecycle/mount",e.Node="lifecycle/node",e.Derive="lifecycle/derive",e.Error="distributed/lifecycle/error",e.Unmount="lifecycle/unmount",e))(y||{});const h={immer:new a.Immer,annotations:Symbol("annotations")};h.immer.setAutoFreeze(!1);class j{constructor(t,n,r=null){D(this,"process");this.value=t,this.operations=n,this.field=r,this.process=null}attach(t){return this.process=t,this}}function Q(e,t=[]){return new j(e,t)}class P{constructor(t,n=t){this.stateless=t,this.stateful=n}get validatable(){return C(this.stateful)}}function C(e,t=[]){return new Proxy(e,{get(n,r){switch(r){case"is":return c=>{const o=O(e,t);if(!o)return!1;const i=new Set(o.flatMap(f=>f.operations));return!!(Array.from(i).reduce((f,m)=>f|(m??0),0)&c)};case"pending":return()=>!!O(e,t);case"draft":return()=>{const c=O(e,t);if(!c)return p(e,t);const o=c.flatMap(i=>i.operations).find(i=>i instanceof T);return o?o.value:p(e,t)}}return C(e,[...t,String(r)])}})}function O(e,t){const r=typeof p(e,t)=="object"?t:t.slice(0,-1),c=r.length===0?e:p(e,r),o=(c==null?void 0:c[h.annotations])??[];return o.length>0?o:null}function W(e,t,n){function r(o){return E(o).forEach(function(){if(this.key===h.annotations){this.block();return}this.node instanceof j&&this.update(this.node.value)})}function c(o){return E(o).forEach(function(){if(this.key===h.annotations){this.block();return}if(this.node instanceof j){const i=typeof this.node.value=="object",l=[...i?this.path:this.path.slice(0,-1),h.annotations],f=p(e.stateful,l)??[],m=this.node.attach(t);i?this.update({...this.node.value,[h.annotations]:[m,...f]},!0):(this.parent&&(this.parent.node[h.annotations]=[m,...f]),this.update(this.node.value,!0))}})}return new P(r(h.immer.produce(e.stateless,n)),c(h.immer.produce(e.stateful,n)))}function I(e,t){const n=E(e.stateful).forEach(function(){if(this.key===h.annotations){this.block();return}if(this.node&&this.node[h.annotations]){const r=this.node[h.annotations];this.update({...this.node,[h.annotations]:r.filter(c=>c.process!==t)},!0)}});return new P(e.stateless,n)}function G(e){return(t,n)=>async(r=Promise.withResolvers(),c)=>{if(typeof n!="function")return;const o=Symbol("process"),i=n(...c);if(i==null)return void r.resolve();if(typeof i=="function"){const l=i(e.model.current,o);return e.model.current=I(l,o),e.update.rerender(),void r.resolve()}for(;;){const{value:l,done:f}=await i.next();if(f){const me=l(e.model.current,o);e.model.current=I(me,o),e.update.rerender();break}const m=l;e.model.current=m(e.model.current,o),e.update.rerender()}r.resolve()}}function U(e){return e.startsWith("distributed")}class N extends Error{constructor(n,r=null){super(String(r));x(this,b);x(this,R);k(this,b,n),k(this,R,r)}get type(){return _(this,b)}get message(){return _(this,R)||""}}b=new WeakMap,R=new WeakMap;function K(e){return new Promise(t=>setTimeout(t,e))}function V(e){return e?!!(e&&typeof e!="symbol"):Symbol(`pk.${Date.now()}.${crypto.randomUUID()}`)}function X(e){return e instanceof N}function w(e){return JSON.stringify(e)}const Y=Object.freeze(Object.defineProperty({__proto__:null,hash:w,isEventError:X,pk:V,sleep:K},Symbol.toStringTag,{value:"Module"}));function v(e,t){const n=d.useRef(null),r=d.useRef(null);return d.useMemo(()=>{const c=w(t);if(r.current!==c){r.current=c;const o=e();return n.current=o,o}return n.current},t)}function M(e,t){const n=d.useRef(null);d.useEffect(()=>{const r=w(t);if(n.current!==r)return n.current=r,e()},t)}const z=d.createContext({appEmitter:new S});function B(){return d.useContext(z)}function Z(e){return()=>{const t=v(()=>({appEmitter:new S}),[]);return u.jsx(z.Provider,{value:t,children:u.jsx(e,{})})}}function L(e){return v(()=>({controller:{get model(){return e.model.current.stateful},get props(){return e.props.current},get router(){return e.router.current},queue:[],actions:{annotate(t,n){return Q(t,n)},produce(t){return(n,r)=>W(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 props(){return e.props.current},get validate(){return e.model.current.validatable},actions:{dispatch([t,...n]){if(t==null)return Promise.reject();const r=Promise.withResolvers();return e.dispatchers.dispatch(t,n,r),r.promise}}}}),[])}function ee(e){return v(()=>{var r,c;const t=(c=(r=e.options).controller)==null?void 0:c.call(r,e.actions.controller);return t?(Object.entries(t).forEach(([o,i])=>e.dispatchers.attach(o,i)),t):void 0},[])}function te(e){const t=B(),n=G(e);return v(()=>{const r=new S,c=t.appEmitter;return{attach(o,i){const l=String(o);U(l)?c.on(l,n(o,i)):r.on(l,n(o,i))},dispatch(o,i,l){const f=String(o);U(f)?c.emit(f,l,i):r.emit(f,l,i)}}},[])}function ne(){const e=d.useRef(null);return v(()=>({customElement:e}),[])}function re(e){var t,n,r,c;M(()=>{e.dispatchers.dispatch(y.Derive,[])},[e.options.props,(t=e.router.current)==null?void 0:t.location,(n=e.router.current)==null?void 0:n.params,(c=(r=e.router.current)==null?void 0:r.search)==null?void 0:c[0]]),M(()=>(e.dispatchers.dispatch(y.Mount,[]),e.dispatchers.dispatch(y.Node,[e.elements.customElement.current]),()=>e.dispatchers.dispatch(y.Unmount,[])),[])}function se(e){const t=v(()=>e.options.model??{},[]);return d.useRef(new P(t,t))}function oe(e){const t=d.useRef(e.options.props);return M(()=>{t.current=e.options.props,e.update.rerender()},[e.options.props]),t}function ue(){return d.useRef(new Set)}function ce(){return d.useRef(null)}function ie({using:e,children:t}){return g.useInRouterContext()?u.jsx(ae,{using:e,children:t}):t()}function ae({using:e,children:t}){return e.current={navigate:g.useNavigate(),location:g.useLocation(),params:g.useParams(),search:g.useSearchParams()},u.jsx(u.Fragment,{children:t()})}function le(){const[e,t]=d.useReducer(n=>n+1,0);return v(()=>({hash:e,rerender:t}),[e])}function fe({options:e}){const t=B(),n=le(),r=ue(),c=ne(),o=ce(),i=oe({options:e,update:n}),l=se({options:e}),f=te({app:t,options:e,update:n,model:l,queue:r}),m=L({app:t,options:e,model:l,dispatchers:f,router:o,props:i});return ee({options:e,dispatchers:f,actions:m}),re({options:e,dispatchers:f,elements:c,router:o,update:n}),v(()=>d.createElement(e.name,{ref:c.customElement,style:{display:"contents"},children:u.jsx(ie,{using:o,children:()=>e.view(m.view)})}),[n.hash])}function de(e){return t=>d.memo(n=>fe({options:{...t,name:e.join(""),props:n}}),(n,r)=>w(n)===w(r))}const he={app:Z,module:de};s.EventError=N,s.Lifecycle=y,s.State=A,s.create=he,s.utils=Y,Object.defineProperty(s,Symbol.toStringTag,{value:"Module"})});
1
+ (function(s,u){typeof exports=="object"&&typeof module<"u"?u(exports,require("immer"),require("lodash/get"),require("traverse"),require("react/jsx-runtime"),require("react"),require("eventemitter3")):typeof define=="function"&&define.amd?define(["exports","immer","lodash/get","traverse","react/jsx-runtime","react","eventemitter3"],u):(s=typeof globalThis<"u"?globalThis:s||self,u(s.Chizu={},s.Immer,s.get,s.Traverse,s.jsxRuntime,s.React,s.EventEmitter3))})(this,function(s,u,a,p,N,I,E){"use strict";var ae=Object.defineProperty;var B=s=>{throw TypeError(s)};var le=(s,u,a)=>u in s?ae(s,u,{enumerable:!0,configurable:!0,writable:!0,value:a}):s[u]=a;var O=(s,u,a)=>le(s,typeof u!="symbol"?u+"":u,a),H=(s,u,a)=>u.has(s)||B("Cannot "+a);var M=(s,u,a)=>(H(s,u,"read from private field"),a?a.call(s):u.get(s)),P=(s,u,a)=>u.has(s)?B("Cannot add the same private member more than once"):u instanceof WeakSet?u.add(s):u.set(s,a),D=(s,u,a,p)=>(H(s,u,"write to private field"),p?p.call(s,a):u.set(s,a),a);var g,w;function $(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 f=$(I);class k{constructor(t){this.value=t}}class T{static Draft(t){return new k(t)}}O(T,"Op",{Add:1,Remove:2,Update:4,Move:8,Replace:16});var v=(e=>(e.Mount="lifecycle/mount",e.Node="lifecycle/node",e.Derive="lifecycle/derive",e.Error="distributed/lifecycle/error",e.Unmount="lifecycle/unmount",e))(v||{});const d={immer:new u.Immer,annotations:Symbol("annotations")};d.immer.setAutoFreeze(!1);class j{constructor(t,n,r=null){O(this,"process");this.value=t,this.operations=n,this.field=r,this.process=null}attach(t){return this.process=t,this}}function F(e,t=[]){return new j(e,t)}class S{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 i=>{const o=R(e,t);if(!o)return!1;const c=new Set(o.flatMap(h=>h.operations));return!!(Array.from(c).reduce((h,b)=>h|(b??0),0)&i)};case"pending":return()=>!!R(e,t);case"draft":return()=>{const i=R(e,t);if(!i)return a(e,t);const o=i.flatMap(c=>c.operations).find(c=>c instanceof k);return o?o.value:a(e,t)}}return _(e,[...t,String(r)])}})}function R(e,t){const r=typeof a(e,t)=="object"?t:t.slice(0,-1),i=r.length===0?e:a(e,r),o=(i==null?void 0:i[d.annotations])??[];return o.length>0?o:null}function J(e,t,n){function r(o){return p(o).forEach(function(){if(this.key===d.annotations){this.block();return}this.node instanceof j&&this.update(this.node.value)})}function i(o){return p(o).forEach(function(){if(this.key===d.annotations){this.block();return}if(this.node instanceof j){const c=typeof this.node.value=="object",l=[...c?this.path:this.path.slice(0,-1),d.annotations],h=a(e.stateful,l)??[],b=this.node.attach(t);c?this.update({...this.node.value,[d.annotations]:[b,...h]},!0):(this.parent&&(this.parent.node[d.annotations]=[b,...h]),this.update(this.node.value,!0))}})}return new S(r(d.immer.produce(e.stateless,n)),i(d.immer.produce(e.stateful,n)))}function q(e,t){const n=p(e.stateful).forEach(function(){if(this.key===d.annotations){this.block();return}if(this.node&&this.node[d.annotations]){const r=this.node[d.annotations];this.update({...this.node,[d.annotations]:r.filter(i=>i.process!==t)},!0)}});return new S(e.stateless,n)}function Q(e){return(t,n)=>async(r=Promise.withResolvers(),i)=>{if(typeof n!="function")return;const o=Symbol("process"),c=n(...i);if(c==null)return void r.resolve();if(typeof c=="function"){const l=c(e.model.current,o);return e.model.current=q(l,o),e.update.rerender(),void r.resolve()}for(;;){const{value:l,done:h}=await c.next();if(h){const ce=l(e.model.current,o);e.model.current=q(ce,o),e.update.rerender();break}const b=l;e.model.current=b(e.model.current,o),e.update.rerender()}r.resolve()}}function C(e){return e.startsWith("distributed")}class A extends Error{constructor(n,r=null){super(String(r));P(this,g);P(this,w);D(this,g,n),D(this,w,r)}get type(){return M(this,g)}get message(){return M(this,w)||""}}g=new WeakMap,w=new WeakMap;function W(e){return new Promise(t=>setTimeout(t,e))}function G(e){return e?!!(e&&typeof e!="symbol"):Symbol(`pk.${Date.now()}.${crypto.randomUUID()}`)}function K(e){return e instanceof A}function y(e){return JSON.stringify(e)}const V=Object.freeze(Object.defineProperty({__proto__:null,hash:y,isEventError:K,pk:G,sleep:W},Symbol.toStringTag,{value:"Module"}));function m(e,t){const n=f.useRef(null),r=f.useRef(null);return f.useMemo(()=>{const i=y(t);if(r.current!==i){r.current=i;const o=e();return n.current=o,o}return n.current},t)}function U(e,t){const n=f.useRef(null);f.useEffect(()=>{const r=y(t);if(n.current!==r)return n.current=r,e()},t)}const z=f.createContext({appEmitter:new E});function x(){return f.useContext(z)}function X({children:e}){return()=>{const t=m(()=>({appEmitter:new E}),[]);return N.jsx(z.Provider,{value:t,children:e})}}function Y(e){return m(()=>({controller:{get model(){return e.model.current.stateful},queue:[],actions:{annotate(t,n){return F(t,n)},produce(t){return(n,r)=>J(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},actions:{dispatch([t,...n]){if(t==null)return Promise.reject();const r=Promise.withResolvers();return e.dispatchers.dispatch(t,n,r),r.promise}}}}),[])}function Z(e){return m(()=>{const t=e.options.using.actions(e.actions.controller);return Object.entries(t).forEach(([r,i])=>e.dispatchers.attach(r,i)),t},[])}function L(e){const t=x(),n=Q(e);return m(()=>{const r=new E,i=t.appEmitter;return{attach(o,c){const l=String(o);C(l)?i.on(l,n(o,c)):r.on(l,n(o,c))},dispatch(o,c,l){const h=String(o);C(h)?i.emit(h,l,c):r.emit(h,l,c)}}},[])}function ee(){const e=f.useRef(null);return m(()=>({customElement:e}),[])}function te(e){U(()=>{e.dispatchers.dispatch(v.Derive,[])},[e.options.using.props]),U(()=>(e.dispatchers.dispatch(v.Mount,[]),e.dispatchers.dispatch(v.Node,[e.elements.customElement.current]),()=>e.dispatchers.dispatch(v.Unmount,[])),[])}function ne(e){const t=m(()=>e.options.using.model??{},[]);return f.useRef(new S(t,t))}function re(){return f.useRef(new Set)}function se(){const[e,t]=f.useReducer(n=>n+1,0);return m(()=>({hash:e,rerender:t}),[e])}function oe({options:e}){const t=x(),n=se(),r=re(),i=ee(),o=ne({options:e}),c=L({app:t,options:e,update:n,model:o,queue:r}),l=Y({app:t,options:e,model:o,dispatchers:c});return Z({options:e,dispatchers:c,actions:l}),te({options:e,dispatchers:c,elements:i,update:n}),m(()=>f.createElement("x-chizu",{ref:i.customElement,style:{display:"contents"},children:e.children(l.view)}),[n.hash,y(e.using.props)])}function ue(e){return oe({options:e})}const ie=f.memo(ue,(e,t)=>y(e)===y(t));s.Context=X,s.EventError=A,s.Lifecycle=v,s.State=T,s.Tree=ie,s.useContext=x,s.utils=V,Object.defineProperty(s,Symbol.toStringTag,{value:"Module"})});
@@ -0,0 +1,4 @@
1
+ import { AppContext, Props } from './types.ts';
2
+ import * as React from "react";
3
+ export declare function useApp(): AppContext;
4
+ export declare function AppContext({ children }: Props): React.ComponentType;
@@ -5,3 +5,6 @@ export type AppContext = {
5
5
  appEmitter: EventEmitter;
6
6
  };
7
7
  export type UseApp = AppContext;
8
+ export type Props = {
9
+ children: React.ReactNode;
10
+ };
@@ -1,8 +1,7 @@
1
1
  import { EventError } from '../module/renderer/dispatchers/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, ModuleDefinition, Op, Query, Queue } from '../types/index.ts';
5
- import * as Router from "../module/renderer/router/types.ts";
4
+ import { Actions, Draft, Lifecycle, ModuleDefinition, Op, Queue } from '../types/index.ts';
6
5
  export type ControllerActions<M extends ModuleDefinition> = {
7
6
  annotate<T>(value: T, operations?: (Op | Draft<T>)[]): T;
8
7
  produce(ƒ: (model: M["Model"]) => void): (models: Models<M["Model"]>, process: Symbol) => Models<M["Model"]>;
@@ -11,9 +10,7 @@ export type ControllerActions<M extends ModuleDefinition> = {
11
10
  export type ControllerArgs<M extends ModuleDefinition> = Readonly<{
12
11
  model: Readonly<M["Model"]>;
13
12
  queue: Readonly<Queue<M["Actions"]>>;
14
- router: M["Query"] extends NonNullable<Query> ? Readonly<Router.Context<M["Query"]>> : null;
15
13
  actions: Readonly<ControllerActions<M>>;
16
- props: Readonly<M["Props"]>;
17
14
  }>;
18
15
  export type ActionEvent<M extends ModuleDefinition> = (...args: M["Actions"][number]) => ActionGenerator<M>;
19
16
  type ActionEvents<M extends ModuleDefinition> = {
package/dist/index.d.ts CHANGED
@@ -1,16 +1,12 @@
1
- import { default as app } from './app/index.tsx';
2
1
  import { ControllerDefinition } from './controller/types.ts';
3
- import { default as module } from './module/index.tsx';
4
2
  import { ViewArgs, ViewDefinition } from './view/types.ts';
5
3
  export { Lifecycle, State } from './types/index.ts';
6
4
  export * as utils from './utils/index.ts';
7
- export declare const create: {
8
- app: typeof app;
9
- module: typeof module;
10
- };
11
5
  export { EventError } from './module/renderer/dispatchers/utils.ts';
12
- export type * as Create from './types/index.ts';
6
+ export { default as Tree } from './module/index.tsx';
7
+ export { AppContext as Context, useApp as useContext, } from './context/index.tsx';
8
+ export type * as Typed from './types/index.ts';
13
9
  export type { Pk } from './types/index.ts';
14
10
  export type { ViewDefinition as View };
15
11
  export type { ViewArgs as Within };
16
- export type { ControllerDefinition as Controller };
12
+ export type { ControllerDefinition as Actions };
@@ -1,4 +1,6 @@
1
1
  import { ModuleDefinition } from '../types/index.ts';
2
- import { Options } from './types.ts';
2
+ import { UseOptions } from './types.ts';
3
3
  import * as React from "react";
4
- export default function module<M extends ModuleDefinition>(name: TemplateStringsArray): (options: Options<M>) => React.ComponentType<M["Props"]>;
4
+ declare function Tree<M extends ModuleDefinition>(options: UseOptions<M>): React.ReactNode;
5
+ declare const _default: typeof Tree;
6
+ export default _default;
@@ -1,19 +1,15 @@
1
- import { UseApp } from '../../../app/types.ts';
1
+ import { UseApp } from '../../../context/types.ts';
2
2
  import { ControllerArgs } from '../../../controller/types.ts';
3
3
  import { ModuleDefinition } from '../../../types/index.ts';
4
4
  import { ViewArgs } from '../../../view/types.ts';
5
+ import { UseOptions } from '../../types.ts';
5
6
  import { UseDispatchers } from '../dispatchers/types.ts';
6
7
  import { UseModel } from '../model/types.ts';
7
- import { UseProps } from '../props/types.ts';
8
- import { UseRouter } from '../router/types.ts';
9
- import { UseOptions } from '../types.ts';
10
8
  export type Props<M extends ModuleDefinition> = {
11
9
  app: UseApp;
12
10
  options: UseOptions<M>;
13
11
  model: UseModel;
14
12
  dispatchers: UseDispatchers;
15
- router: UseRouter;
16
- props: UseProps;
17
13
  };
18
14
  export type UseActions<M extends ModuleDefinition> = {
19
15
  controller: ControllerArgs<M>;
@@ -1,3 +1,3 @@
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> | undefined;
3
+ export default function useController<M extends ModuleDefinition>(props: Props<M>): import('../../../controller/types.ts').ControllerInstance<M>;
@@ -1,7 +1,7 @@
1
1
  import { ModuleDefinition } from '../../../types/index.ts';
2
+ import { UseOptions } from '../../types.ts';
2
3
  import { UseActions } from '../actions/types.ts';
3
4
  import { UseDispatchers } from '../dispatchers/types.ts';
4
- import { UseOptions } from '../types.ts';
5
5
  import { default as useController } from './index.ts';
6
6
  export type Props<M extends ModuleDefinition> = {
7
7
  actions: UseActions<M>;
@@ -1,8 +1,8 @@
1
- import { UseApp } from '../../../app/types.ts';
1
+ import { UseApp } from '../../../context/types.ts';
2
2
  import { ModuleDefinition } from '../../../types/index.ts';
3
+ import { UseOptions } from '../../types.ts';
3
4
  import { UseModel } from '../model/types.ts';
4
5
  import { UseQueue } from '../queue/types.ts';
5
- import { UseOptions } from '../types.ts';
6
6
  import { UseUpdate } from '../update/types.ts';
7
7
  import { default as useDispatchers } from './index.ts';
8
8
  export type Props<M extends ModuleDefinition> = {
@@ -1,15 +1,13 @@
1
1
  import { ModuleDefinition } from '../../../types/index.ts';
2
+ import { UseOptions } from '../../types.ts';
2
3
  import { UseDispatchers } from '../dispatchers/types.ts';
3
4
  import { UseElements } from '../elements/types.ts';
4
- import { UseRouter } from '../router/types.ts';
5
- import { UseOptions } from '../types.ts';
6
5
  import { UseUpdate } from '../update/types.ts';
7
6
  import { default as useLifecycles } from './index.ts';
8
7
  export type Props<M extends ModuleDefinition> = {
9
8
  options: UseOptions<M>;
10
9
  elements: UseElements;
11
10
  dispatchers: UseDispatchers;
12
- router: UseRouter;
13
11
  update: UseUpdate;
14
12
  };
15
13
  export type UseLifecycles = ReturnType<typeof useLifecycles>;
@@ -1,6 +1,6 @@
1
1
  import { default as useModel } from '.';
2
2
  import { ModuleDefinition, State } from '../../../types/index.ts';
3
- import { UseOptions } from '../types.ts';
3
+ import { UseOptions } from '../../types.ts';
4
4
  export type Props<M extends ModuleDefinition> = {
5
5
  options: UseOptions<M>;
6
6
  };
@@ -1,12 +1,8 @@
1
1
  import { ModuleDefinition } from '../../types/index.ts';
2
- import { Options } from '../types.ts';
2
+ import { UseOptions } from '../types.ts';
3
3
  export type ElementName = string;
4
4
  export type Props<M extends ModuleDefinition> = {
5
5
  options: UseOptions<M>;
6
6
  };
7
- export type UseOptions<M extends ModuleDefinition> = Options<M> & {
8
- name: ElementName;
9
- props: M["Props"];
10
- };
11
7
  export type Head<T extends any[]> = T extends [infer X, ...any[]] ? X : never;
12
8
  export type Tail<T extends any[]> = T extends [any, ...infer XS] ? XS : never;
@@ -1,9 +1,11 @@
1
1
  import { ControllerDefinition } from '../controller/types.ts';
2
2
  import { ModuleDefinition } from '../types/index.ts';
3
- import { ViewDefinition } from '../view/types.ts';
4
- export type ElementName = string;
5
- export type Options<M extends ModuleDefinition> = {
6
- model?: M["Model"];
7
- view: ViewDefinition<M>;
8
- controller?: ControllerDefinition<M>;
3
+ import { ViewArgs } from '../view/types.ts';
4
+ export type UseOptions<M extends ModuleDefinition> = {
5
+ using: {
6
+ model: M["Model"];
7
+ actions: ControllerDefinition<M>;
8
+ props?: M["Props"];
9
+ };
10
+ children(module: ViewArgs<M>): React.ReactNode;
9
11
  };
@@ -30,23 +30,15 @@ export declare enum Lifecycle {
30
30
  export type Model = Record<string, any>;
31
31
  export type Actions = [] | [ActionName] | [ActionName, ...ActionPayload];
32
32
  export type Props = Record<string, unknown>;
33
- export type Query = null | string;
34
- export type Module<T extends {
35
- Model?: Model;
36
- Actions?: Actions;
37
- Props?: Props;
38
- Query?: Query;
39
- } = {}> = {
40
- Model: T["Model"] extends Model ? T["Model"] : {};
41
- Actions: T["Actions"] extends Actions ? T["Actions"] : [];
42
- Props: T["Props"] extends Props ? T["Props"] : {};
43
- Query: T["Query"] extends Query ? T["Query"] : null;
33
+ export type Module<M extends Model, A extends Actions = [], P extends Props = {}> = {
34
+ Model: M;
35
+ Actions: A;
36
+ Props: P;
44
37
  };
45
38
  export type ModuleDefinition = {
46
39
  Model: Model;
47
40
  Actions: Actions;
48
41
  Props: Props;
49
- Query: Query;
50
42
  };
51
43
  export type Pk<T> = undefined | Symbol | T;
52
44
  export type Queue<A extends ModuleDefinition["Actions"]> = {
@@ -8,6 +8,5 @@ export type ViewArgs<M extends ModuleDefinition> = Readonly<{
8
8
  model: Readonly<M["Model"]>;
9
9
  validate: Readonly<Validatable<M["Model"]>>;
10
10
  actions: Readonly<ViewActions<M>>;
11
- props: Readonly<M["Props"]>;
12
11
  }>;
13
12
  export type ViewDefinition<M extends ModuleDefinition> = (actions: ViewArgs<M>) => React.ReactNode;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chizu",
3
- "version": "0.2.12",
3
+ "version": "0.2.13",
4
4
  "type": "module",
5
5
  "main": "./dist/chizu.js",
6
6
  "types": "./dist/index.d.ts",
@@ -1,4 +0,0 @@
1
- import { AppContext } from './types.ts';
2
- import * as React from "react";
3
- export declare function useApp(): AppContext;
4
- export default function app(Tree: React.ComponentType): React.ComponentType;
@@ -1,4 +0,0 @@
1
- import { ModuleDefinition } from '../../../types/index.ts';
2
- import { Props } from './types.ts';
3
- import * as React from "react";
4
- export default function useProps<M extends ModuleDefinition>(props: Props<M>): React.RefObject<Readonly<M["Props"]>>;
@@ -1,9 +0,0 @@
1
- import { ModuleDefinition } from '../../../types/index.ts';
2
- import { UseOptions } from '../types.ts';
3
- import { UseUpdate } from '../update/types.ts';
4
- import { default as useProps } from './index.ts';
5
- export type Props<M extends ModuleDefinition> = {
6
- options: UseOptions<M>;
7
- update: UseUpdate;
8
- };
9
- export type UseProps = ReturnType<typeof useProps>;
@@ -1,6 +0,0 @@
1
- import { Query } from '../../../types/index.ts';
2
- import { Context, Props } from './types.ts';
3
- import * as React from "react";
4
- export declare function useRouter(): React.RefObject<Partial<Context<Query>> | null>;
5
- export declare function Router({ using, children }: Props): React.ReactNode;
6
- export declare function Setup({ using, children }: Props): React.ReactNode;
@@ -1,15 +0,0 @@
1
- import { Query } from '../../../types/index.ts';
2
- import { useRouter } from './index.ts';
3
- import * as React from "react";
4
- import * as ReactRouterDOM from "react-router-dom";
5
- export type Props = {
6
- using: UseRouter;
7
- children(): React.ReactNode;
8
- };
9
- export type UseRouter = ReturnType<typeof useRouter>;
10
- export type Context<Q extends null | Query> = {
11
- navigate: ReactRouterDOM.NavigateFunction;
12
- location: ReactRouterDOM.Location;
13
- params: Q extends NonNullable<Query> ? Readonly<ReactRouterDOM.Params<Q>> : null;
14
- search: [URLSearchParams, ReactRouterDOM.SetURLSearchParams];
15
- };