@usenagi/core 0.2.0 → 0.4.0

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/dist/main.es.js CHANGED
@@ -1,31 +1,38 @@
1
- //#region lib/utils/isAbortError.ts
1
+ //#region lib/core/addon.ts
2
2
  function e(e) {
3
- return (e instanceof DOMException || e instanceof Error) && e.name === "AbortError";
3
+ return e;
4
4
  }
5
5
  //#endregion
6
- //#region lib/core/internal/pending.ts
6
+ //#region lib/core/_internal/addonRegistry.ts
7
7
  function t() {
8
- let e = /* @__PURE__ */ new Map();
9
- return {
10
- add(t) {
11
- let n = e.get(t);
12
- n && n.abort();
13
- let r = new AbortController();
14
- return e.set(t, r), {
15
- signal: r.signal,
16
- complete() {
17
- return e.get(t) !== r || r.signal.aborted ? !1 : (e.delete(t), !0);
18
- },
19
- abort() {
20
- e.get(t) === r && (r.abort(), e.delete(t));
21
- }
22
- };
8
+ let e = /* @__PURE__ */ new Set(), t = [], n = [], r = [], i = {
9
+ get installedAddons() {
10
+ return e;
11
+ },
12
+ addComponentMiddleware(e) {
13
+ t.push(e);
14
+ },
15
+ addMountMiddleware(e) {
16
+ n.push(e);
17
+ },
18
+ addUnmountMiddleware(e) {
19
+ r.push(e);
23
20
  },
24
- abort(t) {
25
- let n = e.get(t);
26
- n && (n.abort(), e.delete(t));
21
+ composeComponent(e) {
22
+ return t.reduce((e, t) => t(e), e);
23
+ },
24
+ composeMount(e, t, r) {
25
+ return n.reduce((e, n) => n(e, t, r), e);
26
+ },
27
+ composeUnmount(e) {
28
+ return r.reduce((e, t) => t(e), e);
29
+ },
30
+ install(t) {
31
+ if (e.has(t.name)) throw Error(`[nagi] addon "${t.name}" is already installed`);
32
+ t.install(i), e.add(t.name);
27
33
  }
28
34
  };
35
+ return i;
29
36
  }
30
37
  //#endregion
31
38
  //#region lib/core/error.ts
@@ -57,7 +64,7 @@ function i(e) {
57
64
  return e instanceof r;
58
65
  }
59
66
  //#endregion
60
- //#region lib/core/internal/registry.ts
67
+ //#region lib/core/_internal/registry.ts
61
68
  var a = /* @__PURE__ */ new WeakMap();
62
69
  function o(e, t) {
63
70
  let n = a.get(e);
@@ -65,10 +72,10 @@ function o(e, t) {
65
72
  a.set(e, t);
66
73
  }
67
74
  //#endregion
68
- //#region lib/core/component.ts
75
+ //#region lib/core/_internal/component.ts
69
76
  var s = /* @__PURE__ */ function(e) {
70
77
  return e.MOUNTED = "Mounted", e.UNMOUNTED = "Unmounted", e;
71
- }({}), c = 0, l = class {
78
+ }(s || {}), c = 0, l = class {
72
79
  Mounted = [];
73
80
  Unmounted = [];
74
81
  parent = null;
@@ -116,85 +123,93 @@ var s = /* @__PURE__ */ function(e) {
116
123
  get childElements() {
117
124
  return this.#e.map((e) => e.element);
118
125
  }
119
- };
120
- function u(e) {
121
- return e === void 0 ? (e) => (t) => ({
122
- name: e.name,
123
- setup(n) {
124
- return e.setup(n, t);
125
- }
126
- }) : e;
126
+ }, u;
127
+ function d(e) {
128
+ if (!u) throw Error(`"${e}" called outside setup() will never be run.`);
129
+ return u;
127
130
  }
128
- //#endregion
129
- //#region lib/core/runtime.ts
130
- var d;
131
- function f(e) {
132
- if (!d) throw Error(`"${e}" called outside setup() will never be run.`);
133
- return d;
134
- }
135
- function p(e, t, n) {
136
- let a = new l(t, e.name), o = d;
137
- d = a;
131
+ function f(e, t, n = {}) {
132
+ let a = new l(t, e.name), o = u;
133
+ u = a;
138
134
  try {
139
135
  o && (a.parent = o), a.props = n, a.current = e.setup(t, n) || {};
140
136
  } catch (e) {
141
- throw d = o, i(e) ? e : r.create("setup", a, e, o, { props: a.props });
137
+ throw u = o, i(e) ? e : r.create("setup", a, e, o, { props: a.props });
142
138
  }
143
- return d = o, a;
139
+ return u = o, a;
144
140
  }
145
141
  //#endregion
146
142
  //#region lib/core/app.ts
147
- function m(n = {}) {
148
- let { scheduler: r } = n, i = t();
149
- return {
150
- component(t, { priority: n, when: a } = {}) {
151
- return (s, c = {}) => {
152
- function l() {
153
- let e = p(t, s, c);
154
- return o(s, e), e.onMount(), e;
155
- }
156
- if (!r) return l();
157
- let u = i.add(s), d = () => {
158
- r.schedule(() => {
159
- u.complete() && l();
160
- }, {
161
- priority: n,
162
- signal: u.signal
163
- });
164
- };
165
- a ? a(s, u.signal).then(() => {
166
- u.signal.aborted || d();
167
- }, (t) => {
168
- e(t) || (u.abort(), queueMicrotask(() => {
169
- throw t;
170
- }));
171
- }) : d();
172
- };
143
+ function p() {
144
+ let e = t(), n = (e) => {
145
+ for (let t of e) {
146
+ let e = a.get(t);
147
+ e && (e.onUnmount(), a.delete(t));
148
+ }
149
+ }, r = {
150
+ install(...t) {
151
+ return t.forEach(e.install), r;
173
152
  },
174
- unmount(e) {
175
- for (let t of e) {
176
- i.abort(t);
177
- let e = a.get(t);
178
- e && (e.onUnmount(), a.delete(t));
179
- }
153
+ component(t, n = {}) {
154
+ let r = e.composeComponent(t), i = e.composeMount((e, t) => {
155
+ let n = f(r, e, t);
156
+ return o(e, n), n.onMount(), n;
157
+ }, r, n);
158
+ return (e, t = {}) => i(e, t);
159
+ },
160
+ unmount(t) {
161
+ e.composeUnmount(n)(t);
180
162
  }
181
163
  };
164
+ return r;
165
+ }
166
+ //#endregion
167
+ //#region lib/core/component.ts
168
+ function m(e) {
169
+ return e;
170
+ }
171
+ //#endregion
172
+ //#region lib/core/context.ts
173
+ function h() {
174
+ let e = Symbol();
175
+ return [{ _id: e }, () => {
176
+ let t = d("createContext.use");
177
+ for (; t !== null;) {
178
+ if (t.provides.has(e)) return t.provides.get(e);
179
+ t = t.parent;
180
+ }
181
+ throw Error("createContext.use: no provider found");
182
+ }];
183
+ }
184
+ function g(e, t) {
185
+ return (n) => ({
186
+ name: n.name,
187
+ setup(r, i) {
188
+ return d(`withContext.${n.name}`).provides.set(e._id, t), n.setup(r, i);
189
+ }
190
+ });
182
191
  }
183
192
  //#endregion
184
193
  //#region lib/core/lifecycle.ts
185
- function h(e) {
194
+ function _(e) {
186
195
  return (t) => {
187
- f(e)[e].push(t);
196
+ d(e)[e].push(t);
188
197
  };
189
198
  }
190
- var g = h(s.MOUNTED), _ = h(s.UNMOUNTED), v = Symbol("watch"), y = null, b = class {
199
+ var v = _(s.MOUNTED), y = _(s.UNMOUNTED);
200
+ //#endregion
201
+ //#region lib/core/props.ts
202
+ function b() {}
203
+ //#endregion
204
+ //#region lib/core/reactivity.ts
205
+ var x = Symbol("watch"), S = null, C = class {
191
206
  #e;
192
207
  #t = /* @__PURE__ */ new Set();
193
208
  constructor(e) {
194
209
  this.#e = e;
195
210
  }
196
211
  get value() {
197
- return y !== null && y.add(this), this.#e;
212
+ return S !== null && S.add(this), this.#e;
198
213
  }
199
214
  set value(e) {
200
215
  if (Object.is(e, this.#e)) return;
@@ -202,12 +217,12 @@ var g = h(s.MOUNTED), _ = h(s.UNMOUNTED), v = Symbol("watch"), y = null, b = cla
202
217
  this.#e = e;
203
218
  for (let n of Array.from(this.#t)) n(e, t);
204
219
  }
205
- [v](e) {
220
+ [x](e) {
206
221
  return this.#t.add(e), () => {
207
222
  this.#t.delete(e);
208
223
  };
209
224
  }
210
- }, x = (e) => new b(e), S = class {
225
+ }, w = (e) => new C(e), T = class {
211
226
  #e;
212
227
  constructor(e) {
213
228
  this.#e = e;
@@ -215,75 +230,54 @@ var g = h(s.MOUNTED), _ = h(s.UNMOUNTED), v = Symbol("watch"), y = null, b = cla
215
230
  get value() {
216
231
  return this.#e.value;
217
232
  }
218
- [v](e) {
219
- return this.#e[v](e);
233
+ [x](e) {
234
+ return this.#e[x](e);
220
235
  }
221
- }, C = (e) => new S(e);
222
- function w(e, t) {
223
- return e[v](t);
236
+ }, E = (e) => new T(e);
237
+ function D(e, t) {
238
+ return e[x](t);
224
239
  }
225
- function T(e, t) {
226
- _(w(e, t));
240
+ function O(e, t) {
241
+ y(D(e, t));
227
242
  }
228
- function E(e) {
229
- let t = x(void 0), n = [], r = () => {
243
+ function k(e) {
244
+ let t = w(void 0), n = [], r = () => {
230
245
  n.forEach((e) => {
231
246
  e();
232
247
  }), n = [];
233
248
  }, i = () => {
234
249
  r();
235
- let a = y, o = /* @__PURE__ */ new Set();
236
- y = o;
250
+ let a = S, o = /* @__PURE__ */ new Set();
251
+ S = o;
237
252
  let s;
238
253
  try {
239
254
  s = e();
240
255
  } finally {
241
- y = a;
256
+ S = a;
242
257
  }
243
258
  t.value = s;
244
- for (let e of o) n.push(e[v](() => {
259
+ for (let e of o) n.push(e[x](() => {
245
260
  i();
246
261
  }));
247
262
  };
248
- return i(), _(r), C(t);
263
+ return i(), y(r), E(t);
249
264
  }
250
265
  //#endregion
251
- //#region lib/hooks/createContext.ts
252
- function D() {
253
- let e = Symbol();
254
- return [{ _id: e }, () => {
255
- let t = f("createContext.use");
256
- for (; t !== null;) {
257
- if (t.provides.has(e)) return t.provides.get(e);
258
- t = t.parent;
259
- }
260
- throw Error("createContext.use: no provider found");
261
- }];
262
- }
263
- function O(e, t) {
264
- return (n) => ({
265
- name: n.name,
266
- setup(r, i) {
267
- return f(`withContext.${n.name}`).provides.set(e._id, t), n.setup(r, i);
268
- }
269
- });
270
- }
271
- //#endregion
272
- //#region lib/hooks/domRefs.ts
273
- function k(e, t) {
266
+ //#region lib/hooks/core/useDomRef.ts
267
+ function A(e, t) {
274
268
  return t.some((t) => t !== e && t.contains(e));
275
269
  }
276
- function A(e, t, n) {
277
- let r = `[data-ref="${CSS.escape(e)}"]`, i = Array.from(t.querySelectorAll(r)).filter((e) => !k(e, n));
270
+ function j(e, t, n) {
271
+ let r = `[data-ref="${CSS.escape(e)}"]`, i = Array.from(t.querySelectorAll(r)).filter((e) => !A(e, n));
278
272
  return i.length === 0 ? null : i.length === 1 ? i[0] : i;
279
273
  }
280
- function j(e, t) {
274
+ function M(e, t) {
281
275
  let n = /* @__PURE__ */ new Map();
282
276
  return new Proxy({}, {
283
277
  get(r, i) {
284
278
  if (typeof i == "symbol" || i === "then") return;
285
279
  if (n.has(i)) return n.get(i);
286
- let a = A(i, e, t());
280
+ let a = j(i, e, t());
287
281
  return n.set(i, a), a;
288
282
  },
289
283
  has(e, t) {
@@ -301,22 +295,43 @@ function j(e, t) {
301
295
  }
302
296
  });
303
297
  }
298
+ function N() {
299
+ let e = d("useDomRef");
300
+ return { refs: M(e.element, () => e.childElements) };
301
+ }
304
302
  //#endregion
305
- //#region lib/hooks/useDomRef.ts
306
- function M() {
307
- let e = f("useDomRef");
308
- return { refs: j(e.element, () => e.childElements) };
303
+ //#region lib/hooks/core/useSlot.ts
304
+ function P() {
305
+ let e = d("useSlot");
306
+ return {
307
+ addChild(t, n, r) {
308
+ let i = (t) => {
309
+ let i = f(n, t, r);
310
+ return e.addChild(i), i;
311
+ };
312
+ return Array.isArray(t) ? t.map((e) => i(e)) : [i(t)];
313
+ },
314
+ removeChild(t) {
315
+ t.forEach((t) => {
316
+ try {
317
+ e.removeChild(t);
318
+ } catch (n) {
319
+ console.error("[nagi] removeChild failed", r.create("removeChild", t, n, e));
320
+ }
321
+ });
322
+ }
323
+ };
309
324
  }
310
325
  //#endregion
311
326
  //#region lib/hooks/useEvent.ts
312
- function N(e, t, n, r) {
313
- g(() => (e.addEventListener(t, n, r), () => {
327
+ function F(e, t, n, r) {
328
+ v(() => (e.addEventListener(t, n, r), () => {
314
329
  e.removeEventListener(t, n, r);
315
330
  }));
316
331
  }
317
332
  //#endregion
318
333
  //#region lib/hooks/useIntersectionWatch.ts
319
- function P(e, t, n = {
334
+ function I(e, t, n = {
320
335
  rootMargin: "0px",
321
336
  threshold: .1
322
337
  }) {
@@ -326,9 +341,9 @@ function P(e, t, n = {
326
341
  r.observe(e);
327
342
  }) : r.observe(e);
328
343
  }
329
- i(e), _(() => {
344
+ v(() => (i(e), () => {
330
345
  r.disconnect();
331
- });
346
+ }));
332
347
  function a(e) {
333
348
  r.unobserve(e);
334
349
  }
@@ -336,37 +351,14 @@ function P(e, t, n = {
336
351
  }
337
352
  //#endregion
338
353
  //#region lib/hooks/useMediaQuery.ts
339
- function F(e, t) {
340
- let n = window.matchMedia(e), r = x(n.matches), i = null;
354
+ function L(e, t) {
355
+ let n = window.matchMedia(e), r = w(n.matches), i = null;
341
356
  function a(e) {
342
357
  r.value = e.matches, e.matches ? i = t() : (i?.(), i = null);
343
358
  }
344
- return g(() => (n.addEventListener("change", a), n.matches && (i = t()), () => {
359
+ return v(() => (n.addEventListener("change", a), n.matches && (i = t()), () => {
345
360
  i?.(), n.removeEventListener("change", a);
346
- })), { matchesQuery: C(r) };
347
- }
348
- //#endregion
349
- //#region lib/hooks/useSlot.ts
350
- function I() {
351
- let e = f("useSlot");
352
- return {
353
- addChild(t, n, r = {}) {
354
- let i = (t) => {
355
- let i = p(n, t, r);
356
- return e.addChild(i), i;
357
- };
358
- return Array.isArray(t) ? t.map((e) => i(e)) : [i(t)];
359
- },
360
- removeChild(t) {
361
- t.forEach((t) => {
362
- try {
363
- e.removeChild(t);
364
- } catch (n) {
365
- console.error("[nagi] removeChild failed", r.create("removeChild", t, n, e));
366
- }
367
- });
368
- }
369
- };
361
+ })), { matchesQuery: E(r) };
370
362
  }
371
363
  //#endregion
372
- export { r as LifecycleError, m as create, D as createContext, u as defineComponent, i as isLifecycleError, C as readonly, x as signal, E as useComputed, M as useDomRef, N as useEvent, P as useIntersectionWatch, F as useMediaQuery, g as useMount, I as useSlot, _ as useUnmount, T as useWatch, O as withContext };
364
+ export { r as LifecycleError, p as create, h as createContext, e as defineAddon, m as defineComponent, i as isLifecycleError, b as propTypes, E as readonly, w as signal, k as useComputed, N as useDomRef, F as useEvent, I as useIntersectionWatch, L as useMediaQuery, v as useMount, P as useSlot, y as useUnmount, O as useWatch, g as withContext };
package/dist/main.umd.js CHANGED
@@ -1 +1 @@
1
- (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.Lake={}))})(this,function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});function t(e){return(e instanceof DOMException||e instanceof Error)&&e.name===`AbortError`}function n(){let e=new Map;return{add(t){let n=e.get(t);n&&n.abort();let r=new AbortController;return e.set(t,r),{signal:r.signal,complete(){return e.get(t)!==r||r.signal.aborted?!1:(e.delete(t),!0)},abort(){e.get(t)===r&&(r.abort(),e.delete(t))}}},abort(t){let n=e.get(t);n&&(n.abort(),e.delete(t))}}}function r(e){let t=[],n=e;for(;n;)t.unshift(n.name),n=n.parent;return t.join(` > `)}var i=class e extends Error{details;constructor(e){super(`[nagi] Component error in phase "${e.phase}" for "${e.name}"${e.path?` (${e.path})`:``}`,{cause:e.cause}),this.name=`LifecycleError`,this.details=e}static create(t,n,i,a=n.parent,o){return new e({phase:t,name:n.name,uid:n.uid,path:r(n),parentName:a?.name,parentUid:a?.uid,element:n.element,cause:i,...o})}};function a(e){return e instanceof i}var o=new WeakMap;function s(e,t){let n=o.get(e);if(n)throw i.create(`mount`,t,Error(`Component "${n.name}" (${n.uid}) is already mounted on this element`),n);o.set(e,t)}var c=function(e){return e.MOUNTED=`Mounted`,e.UNMOUNTED=`Unmounted`,e}({}),l=0,u=class{Mounted=[];Unmounted=[];parent=null;#e=[];uid;name;current={};props={};element;provides=new Map;constructor(e,t){this.uid=`${t}.${l++}`,this.name=t,this.element=e}onMount=()=>{let e=[];for(let t of this.Mounted)try{let n=t();typeof n==`function`&&e.push(n)}catch(e){console.error(`[nagi] onMount hook failed`,i.create(`mount`,this,e))}this.Unmounted.push(...e)};onUnmount=()=>{for(let e of this.Unmounted)try{e()}catch(e){console.error(`[nagi] onUnmount cleanup failed`,i.create(`unmount`,this,e))}for(let e of this.#e)e.onUnmount()};addChild=e=>{this.#e.push(e),e.parent=this;try{e.onMount()}catch(t){let n=this.#e.indexOf(e);throw n!==-1&&this.#e.splice(n,1),e.parent=null,t}};removeChild=e=>{let t=this.#e.indexOf(e);t!==-1&&(this.#e.splice(t,1),e.parent=null,e.onUnmount())};get childElements(){return this.#e.map(e=>e.element)}};function d(e){return e===void 0?e=>t=>({name:e.name,setup(n){return e.setup(n,t)}}):e}var f;function p(e){if(!f)throw Error(`"${e}" called outside setup() will never be run.`);return f}function m(e,t,n){let r=new u(t,e.name),o=f;f=r;try{o&&(r.parent=o),r.props=n,r.current=e.setup(t,n)||{}}catch(e){throw f=o,a(e)?e:i.create(`setup`,r,e,o,{props:r.props})}return f=o,r}function h(e={}){let{scheduler:r}=e,i=n();return{component(e,{priority:n,when:a}={}){return(o,c={})=>{function l(){let t=m(e,o,c);return s(o,t),t.onMount(),t}if(!r)return l();let u=i.add(o),d=()=>{r.schedule(()=>{u.complete()&&l()},{priority:n,signal:u.signal})};a?a(o,u.signal).then(()=>{u.signal.aborted||d()},e=>{t(e)||(u.abort(),queueMicrotask(()=>{throw e}))}):d()}},unmount(e){for(let t of e){i.abort(t);let e=o.get(t);e&&(e.onUnmount(),o.delete(t))}}}}function g(e){return t=>{p(e)[e].push(t)}}var _=g(c.MOUNTED),v=g(c.UNMOUNTED),y=Symbol(`watch`),b=null,x=class{#e;#t=new Set;constructor(e){this.#e=e}get value(){return b!==null&&b.add(this),this.#e}set value(e){if(Object.is(e,this.#e))return;let t=this.#e;this.#e=e;for(let n of Array.from(this.#t))n(e,t)}[y](e){return this.#t.add(e),()=>{this.#t.delete(e)}}},S=e=>new x(e),C=class{#e;constructor(e){this.#e=e}get value(){return this.#e.value}[y](e){return this.#e[y](e)}},w=e=>new C(e);function T(e,t){return e[y](t)}function E(e,t){v(T(e,t))}function D(e){let t=S(void 0),n=[],r=()=>{n.forEach(e=>{e()}),n=[]},i=()=>{r();let a=b,o=new Set;b=o;let s;try{s=e()}finally{b=a}t.value=s;for(let e of o)n.push(e[y](()=>{i()}))};return i(),v(r),w(t)}function O(){let e=Symbol();return[{_id:e},()=>{let t=p(`createContext.use`);for(;t!==null;){if(t.provides.has(e))return t.provides.get(e);t=t.parent}throw Error(`createContext.use: no provider found`)}]}function k(e,t){return n=>({name:n.name,setup(r,i){return p(`withContext.${n.name}`).provides.set(e._id,t),n.setup(r,i)}})}function A(e,t){return t.some(t=>t!==e&&t.contains(e))}function j(e,t,n){let r=`[data-ref="${CSS.escape(e)}"]`,i=Array.from(t.querySelectorAll(r)).filter(e=>!A(e,n));return i.length===0?null:i.length===1?i[0]:i}function M(e,t){let n=new Map;return new Proxy({},{get(r,i){if(typeof i==`symbol`||i===`then`)return;if(n.has(i))return n.get(i);let a=j(i,e,t());return n.set(i,a),a},has(e,t){return typeof t==`string`},ownKeys(){return[]},getOwnPropertyDescriptor(){},set(){return!1},deleteProperty(){return!1}})}function N(){let e=p(`useDomRef`);return{refs:M(e.element,()=>e.childElements)}}function P(e,t,n,r){_(()=>(e.addEventListener(t,n,r),()=>{e.removeEventListener(t,n,r)}))}function F(e,t,n={rootMargin:`0px`,threshold:.1}){let r=new IntersectionObserver(t,n);function i(e){Array.isArray(e)?e.forEach(e=>{r.observe(e)}):r.observe(e)}i(e),v(()=>{r.disconnect()});function a(e){r.unobserve(e)}return{unwatch:a}}function I(e,t){let n=window.matchMedia(e),r=S(n.matches),i=null;function a(e){r.value=e.matches,e.matches?i=t():(i?.(),i=null)}return _(()=>(n.addEventListener(`change`,a),n.matches&&(i=t()),()=>{i?.(),n.removeEventListener(`change`,a)})),{matchesQuery:w(r)}}function L(){let e=p(`useSlot`);return{addChild(t,n,r={}){let i=t=>{let i=m(n,t,r);return e.addChild(i),i};return Array.isArray(t)?t.map(e=>i(e)):[i(t)]},removeChild(t){t.forEach(t=>{try{e.removeChild(t)}catch(n){console.error(`[nagi] removeChild failed`,i.create(`removeChild`,t,n,e))}})}}}e.LifecycleError=i,e.create=h,e.createContext=O,e.defineComponent=d,e.isLifecycleError=a,e.readonly=w,e.signal=S,e.useComputed=D,e.useDomRef=N,e.useEvent=P,e.useIntersectionWatch=F,e.useMediaQuery=I,e.useMount=_,e.useSlot=L,e.useUnmount=v,e.useWatch=E,e.withContext=k});
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.Nagi={}))})(this,function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});function t(e){return e}function n(){let e=new Set,t=[],n=[],r=[],i={get installedAddons(){return e},addComponentMiddleware(e){t.push(e)},addMountMiddleware(e){n.push(e)},addUnmountMiddleware(e){r.push(e)},composeComponent(e){return t.reduce((e,t)=>t(e),e)},composeMount(e,t,r){return n.reduce((e,n)=>n(e,t,r),e)},composeUnmount(e){return r.reduce((e,t)=>t(e),e)},install(t){if(e.has(t.name))throw Error(`[nagi] addon "${t.name}" is already installed`);t.install(i),e.add(t.name)}};return i}function r(e){let t=[],n=e;for(;n;)t.unshift(n.name),n=n.parent;return t.join(` > `)}var i=class e extends Error{details;constructor(e){super(`[nagi] Component error in phase "${e.phase}" for "${e.name}"${e.path?` (${e.path})`:``}`,{cause:e.cause}),this.name=`LifecycleError`,this.details=e}static create(t,n,i,a=n.parent,o){return new e({phase:t,name:n.name,uid:n.uid,path:r(n),parentName:a?.name,parentUid:a?.uid,element:n.element,cause:i,...o})}};function a(e){return e instanceof i}var o=new WeakMap;function s(e,t){let n=o.get(e);if(n)throw i.create(`mount`,t,Error(`Component "${n.name}" (${n.uid}) is already mounted on this element`),n);o.set(e,t)}var c=function(e){return e.MOUNTED=`Mounted`,e.UNMOUNTED=`Unmounted`,e}(c||{}),l=0,u=class{Mounted=[];Unmounted=[];parent=null;#e=[];uid;name;current={};props={};element;provides=new Map;constructor(e,t){this.uid=`${t}.${l++}`,this.name=t,this.element=e}onMount=()=>{let e=[];for(let t of this.Mounted)try{let n=t();typeof n==`function`&&e.push(n)}catch(e){console.error(`[nagi] onMount hook failed`,i.create(`mount`,this,e))}this.Unmounted.push(...e)};onUnmount=()=>{for(let e of this.Unmounted)try{e()}catch(e){console.error(`[nagi] onUnmount cleanup failed`,i.create(`unmount`,this,e))}for(let e of this.#e)e.onUnmount()};addChild=e=>{this.#e.push(e),e.parent=this;try{e.onMount()}catch(t){let n=this.#e.indexOf(e);throw n!==-1&&this.#e.splice(n,1),e.parent=null,t}};removeChild=e=>{let t=this.#e.indexOf(e);t!==-1&&(this.#e.splice(t,1),e.parent=null,e.onUnmount())};get childElements(){return this.#e.map(e=>e.element)}},d;function f(e){if(!d)throw Error(`"${e}" called outside setup() will never be run.`);return d}function p(e,t,n={}){let r=new u(t,e.name),o=d;d=r;try{o&&(r.parent=o),r.props=n,r.current=e.setup(t,n)||{}}catch(e){throw d=o,a(e)?e:i.create(`setup`,r,e,o,{props:r.props})}return d=o,r}function m(){let e=n(),t=e=>{for(let t of e){let e=o.get(t);e&&(e.onUnmount(),o.delete(t))}},r={install(...t){return t.forEach(e.install),r},component(t,n={}){let r=e.composeComponent(t),i=e.composeMount((e,t)=>{let n=p(r,e,t);return s(e,n),n.onMount(),n},r,n);return(e,t={})=>i(e,t)},unmount(n){e.composeUnmount(t)(n)}};return r}function h(e){return e}function g(){let e=Symbol();return[{_id:e},()=>{let t=f(`createContext.use`);for(;t!==null;){if(t.provides.has(e))return t.provides.get(e);t=t.parent}throw Error(`createContext.use: no provider found`)}]}function _(e,t){return n=>({name:n.name,setup(r,i){return f(`withContext.${n.name}`).provides.set(e._id,t),n.setup(r,i)}})}function v(e){return t=>{f(e)[e].push(t)}}var y=v(c.MOUNTED),b=v(c.UNMOUNTED);function x(){}var S=Symbol(`watch`),C=null,w=class{#e;#t=new Set;constructor(e){this.#e=e}get value(){return C!==null&&C.add(this),this.#e}set value(e){if(Object.is(e,this.#e))return;let t=this.#e;this.#e=e;for(let n of Array.from(this.#t))n(e,t)}[S](e){return this.#t.add(e),()=>{this.#t.delete(e)}}},T=e=>new w(e),E=class{#e;constructor(e){this.#e=e}get value(){return this.#e.value}[S](e){return this.#e[S](e)}},D=e=>new E(e);function O(e,t){return e[S](t)}function k(e,t){b(O(e,t))}function A(e){let t=T(void 0),n=[],r=()=>{n.forEach(e=>{e()}),n=[]},i=()=>{r();let a=C,o=new Set;C=o;let s;try{s=e()}finally{C=a}t.value=s;for(let e of o)n.push(e[S](()=>{i()}))};return i(),b(r),D(t)}function j(e,t){return t.some(t=>t!==e&&t.contains(e))}function M(e,t,n){let r=`[data-ref="${CSS.escape(e)}"]`,i=Array.from(t.querySelectorAll(r)).filter(e=>!j(e,n));return i.length===0?null:i.length===1?i[0]:i}function N(e,t){let n=new Map;return new Proxy({},{get(r,i){if(typeof i==`symbol`||i===`then`)return;if(n.has(i))return n.get(i);let a=M(i,e,t());return n.set(i,a),a},has(e,t){return typeof t==`string`},ownKeys(){return[]},getOwnPropertyDescriptor(){},set(){return!1},deleteProperty(){return!1}})}function P(){let e=f(`useDomRef`);return{refs:N(e.element,()=>e.childElements)}}function F(){let e=f(`useSlot`);return{addChild(t,n,r){let i=t=>{let i=p(n,t,r);return e.addChild(i),i};return Array.isArray(t)?t.map(e=>i(e)):[i(t)]},removeChild(t){t.forEach(t=>{try{e.removeChild(t)}catch(n){console.error(`[nagi] removeChild failed`,i.create(`removeChild`,t,n,e))}})}}}function I(e,t,n,r){y(()=>(e.addEventListener(t,n,r),()=>{e.removeEventListener(t,n,r)}))}function L(e,t,n={rootMargin:`0px`,threshold:.1}){let r=new IntersectionObserver(t,n);function i(e){Array.isArray(e)?e.forEach(e=>{r.observe(e)}):r.observe(e)}y(()=>(i(e),()=>{r.disconnect()}));function a(e){r.unobserve(e)}return{unwatch:a}}function R(e,t){let n=window.matchMedia(e),r=T(n.matches),i=null;function a(e){r.value=e.matches,e.matches?i=t():(i?.(),i=null)}return y(()=>(n.addEventListener(`change`,a),n.matches&&(i=t()),()=>{i?.(),n.removeEventListener(`change`,a)})),{matchesQuery:D(r)}}e.LifecycleError=i,e.create=m,e.createContext=g,e.defineAddon=t,e.defineComponent=h,e.isLifecycleError=a,e.propTypes=x,e.readonly=D,e.signal=T,e.useComputed=A,e.useDomRef=P,e.useEvent=I,e.useIntersectionWatch=L,e.useMediaQuery=R,e.useMount=y,e.useSlot=F,e.useUnmount=b,e.useWatch=k,e.withContext=_});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usenagi/core",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Composition-API ergonomics for vanilla DOM. Bring your own mounter.",
5
5
  "main": "./dist/main.umd.js",
6
6
  "module": "./dist/main.es.js",
@@ -61,10 +61,10 @@
61
61
  "devDependencies": {
62
62
  "@biomejs/biome": "^2.4.13",
63
63
  "happy-dom": "^20.9.0",
64
- "oxlint": "^1.61.0",
64
+ "oxlint": "^1.66.0",
65
65
  "typescript": "^6.0.3",
66
- "vite": "^8.0.10",
67
- "vitest": "^4.1.5"
66
+ "vite": "^8.0.14",
67
+ "vitest": "^4.1.7"
68
68
  },
69
69
  "type": "module",
70
70
  "sideEffects": false
@@ -0,0 +1,11 @@
1
+ import type { RefElement } from "../../../types";
2
+ type PendingMounts = {
3
+ add(el: RefElement): {
4
+ readonly signal: AbortSignal;
5
+ complete(): boolean;
6
+ abort(): void;
7
+ };
8
+ abort(el: RefElement): void;
9
+ };
10
+ declare function createPendingMounts(): PendingMounts;
11
+ export {};
@@ -0,0 +1,11 @@
1
+ import type { SchedulePriority } from "../../../types";
2
+ type Scheduler = {
3
+ schedule(task: () => void, options?: {
4
+ priority?: SchedulePriority;
5
+ signal?: AbortSignal;
6
+ }): void;
7
+ };
8
+ declare function createScheduler(opts?: {
9
+ priority?: SchedulePriority;
10
+ }): Scheduler;
11
+ export {};
@@ -1,4 +1,10 @@
1
- import type { SchedulePriority, Scheduler } from "../../types";
2
- export declare function createScheduler(opts?: {
1
+ import type { Cue, SchedulePriority } from "../../types";
2
+ declare module "../../core/addon" {
3
+ interface MountOptions {
4
+ priority?: SchedulePriority;
5
+ when?: Cue;
6
+ }
7
+ }
8
+ export declare function schedulerAddon(opts?: {
3
9
  priority?: SchedulePriority;
4
- }): Scheduler;
10
+ }): import("../../main").Addon;
@@ -0,0 +1,10 @@
1
+ import type { ComponentSetup } from "../../types";
2
+ import type { Addon, AddonContext, MountFn, MountOptions, UnmountFn } from "../addon";
3
+ type AddonRegistry = AddonContext & {
4
+ composeComponent<S extends ComponentSetup>(setup: S): S;
5
+ composeMount(mountFn: MountFn, setup: ComponentSetup, opts: MountOptions): MountFn;
6
+ composeUnmount(unmountFn: UnmountFn): UnmountFn;
7
+ install(addon: Addon): void;
8
+ };
9
+ declare function createAddonRegistry(): AddonRegistry;
10
+ export {};
@@ -0,0 +1,24 @@
1
+ import type { ComponentContext, ComponentSetup, ExposedSetup, RefElement } from "../../types";
2
+ declare enum LifecycleHooks {
3
+ MOUNTED = "Mounted",
4
+ UNMOUNTED = "Unmounted"
5
+ }
6
+ declare class ComponentContextImpl<T = any> implements ComponentContext<ExposedSetup<T>> {
7
+ #private;
8
+ private [LifecycleHooks.MOUNTED];
9
+ private [LifecycleHooks.UNMOUNTED];
10
+ parent: ComponentContextImpl | null;
11
+ readonly uid: string;
12
+ readonly name: ComponentContext["name"];
13
+ current: ExposedSetup<T>;
14
+ props: Parameters<ComponentSetup<T>["setup"]>[1];
15
+ element: ComponentContext["element"];
16
+ provides: Map<symbol, unknown>;
17
+ constructor(element: RefElement, name: string);
18
+ onMount: () => void;
19
+ onUnmount: () => void;
20
+ addChild: (child: ComponentContextImpl) => void;
21
+ removeChild: (child: ComponentContextImpl) => void;
22
+ get childElements(): RefElement[];
23
+ }
24
+ export {};
@@ -0,0 +1,5 @@
1
+ import type { RefElement } from "../../types";
2
+ import type { ComponentContextImpl } from "./component";
3
+ declare const DOM_COMPONENT_INSTANCE: WeakMap<RefElement, ComponentContextImpl<any>>;
4
+ declare function bindDOMNodeToComponent(el: RefElement, component: ComponentContextImpl): void;
5
+ export {};
@@ -0,0 +1,28 @@
1
+ import type { ComponentSetup, RefElement } from "../types";
2
+ declare const mountOptionsBrand: unique symbol;
3
+ /** Options for `app.component(setup, opts)` — extended by mount addons. */
4
+ export interface MountOptions {
5
+ readonly [mountOptionsBrand]?: never;
6
+ }
7
+ /** Mount after addon middleware runs — may return void when mount is deferred (e.g. scheduler). */
8
+ export type MountFn = (el: RefElement, props: Record<string, any>) => any;
9
+ export type UnmountFn = (targets: RefElement[]) => void;
10
+ export type ComponentMiddleware = <S extends ComponentSetup>(comp: S) => S;
11
+ export type MountMiddleware = (next: MountFn, setup: ComponentSetup, opts: MountOptions) => MountFn;
12
+ export type UnmountMiddleware = (next: UnmountFn) => UnmountFn;
13
+ export type Addon = {
14
+ readonly name: string;
15
+ install(ctx: AddonContext): void;
16
+ };
17
+ export type AddonContext = {
18
+ readonly installedAddons: ReadonlySet<string>;
19
+ addComponentMiddleware(middleware: ComponentMiddleware): void;
20
+ addMountMiddleware(middleware: MountMiddleware): void;
21
+ addUnmountMiddleware(middleware: UnmountMiddleware): void;
22
+ };
23
+ /**
24
+ * Identity helper for type inference only — no runtime effect.
25
+ */
26
+ export declare function defineAddon(addon: Addon): Addon;
27
+ export declare function defineAddon<TOptions>(factory: (options?: TOptions) => Addon): (options?: TOptions) => Addon;
28
+ export {};
@@ -1,27 +1,9 @@
1
- import type { ComponentSetup, Cue, RefElement, SchedulePriority, Scheduler } from "../types";
2
- import type { ComponentContext } from "./component";
3
- type AppOptions = {
4
- priority?: SchedulePriority;
5
- };
6
- type AsyncAppOptions = AppOptions & {
7
- when?: Cue;
8
- };
9
- type SyncApp = {
10
- component<S extends ComponentSetup>(wrap: S, opts?: AppOptions): (el: RefElement, props?: Record<string, any>) => ComponentContext<ReturnType<S["setup"]>>;
11
- unmount(targets: RefElement[]): void;
12
- };
13
- type AsyncApp = {
14
- component<S extends ComponentSetup>(wrap: S, opts?: AsyncAppOptions): (el: RefElement, props?: Record<string, any>) => void;
1
+ import type { ComponentContext, ComponentSetup, ExposedSetup, RefElement } from "../types";
2
+ import type { Addon, MountOptions } from "./addon";
3
+ type App = {
4
+ install(...addons: Addon[]): App;
5
+ component<S extends ComponentSetup>(component: S, opts?: MountOptions): (el: RefElement, props?: Record<string, any>) => ComponentContext<ExposedSetup<ReturnType<S["setup"]>>> | void;
15
6
  unmount(targets: RefElement[]): void;
16
7
  };
17
- export declare function create(): SyncApp;
18
- export declare function create(config: {
19
- scheduler?: undefined;
20
- }): SyncApp;
21
- export declare function create(config: {
22
- scheduler: Scheduler;
23
- }): AsyncApp;
24
- export declare function create(config: {
25
- scheduler?: Scheduler | undefined;
26
- }): SyncApp | AsyncApp;
8
+ export declare function create(): App;
27
9
  export {};