@junojs/core 0.1.2 → 0.1.4

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/index.js CHANGED
@@ -1,896 +1,815 @@
1
- var j = Object.defineProperty;
2
- var O = (i, t, e) => t in i ? j(i, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : i[t] = e;
3
- var h = (i, t, e) => O(i, typeof t != "symbol" ? t + "" : t, e);
4
1
  import "reflect-metadata";
5
- function z(i) {
6
- return (t) => {
7
- i.shadow === void 0 && (i.shadow = !0), Reflect.defineMetadata("nf:config", i, t);
8
- };
9
- }
10
- function K() {
11
- return (i, t) => {
12
- const e = Reflect.getMetadata("nf:states", i) || [];
13
- e.push(t), Reflect.defineMetadata("nf:states", e, i);
14
- };
15
- }
16
- function Z() {
17
- return (i, t) => {
18
- const e = Reflect.getMetadata("nf:inputs", i) || [];
19
- e.push(t), Reflect.defineMetadata("nf:inputs", e, i);
20
- };
21
- }
22
- function G(i) {
23
- return (t, e) => {
24
- const s = Reflect.getMetadata("nf:params", t) || [];
25
- s.push({ key: e, paramName: i || e }), Reflect.defineMetadata("nf:params", s, t);
26
- };
27
- }
28
- function Q(i) {
29
- return (t, e) => {
30
- Reflect.defineMetadata("nf:inject", i, t, e);
31
- };
32
- }
33
- function X() {
34
- return (i, t) => {
35
- const e = Reflect.getMetadata("nf:transforms", i) || [];
36
- e.push(t), Reflect.defineMetadata("nf:transforms", e, i);
37
- };
38
- }
39
- function B() {
40
- return (i, t) => {
41
- const e = Reflect.getMetadata("nf:actions", i) || [];
42
- e.push(t), Reflect.defineMetadata("nf:actions", e, i);
43
- };
44
- }
45
- function Y(i) {
46
- return (t, e) => {
47
- const s = Reflect.getMetadata("nf:provides", t) || [];
48
- s.push({ key: i, property: e }), Reflect.defineMetadata("nf:provides", s, t);
49
- };
50
- }
51
- function tt(i) {
52
- return (t, e) => {
53
- const s = Reflect.getMetadata("nf:injects", t) || [];
54
- s.push({ key: i, property: e }), Reflect.defineMetadata("nf:injects", s, t);
55
- };
56
- }
57
- function et(i) {
58
- return (t) => {
59
- const e = Reflect.getMetadata("nf:refine", t) || [];
60
- e.push(i), Reflect.defineMetadata("nf:refine", e, t);
61
- };
62
- }
63
- function st(i, t) {
64
- return (e, s) => {
65
- const n = Reflect.getMetadata("nf:validates", e) || [];
66
- n.push({ key: s, predicate: i, message: t }), Reflect.defineMetadata("nf:validates", n, e);
67
- };
68
- }
69
- function nt(i) {
70
- return (t, e) => {
71
- Reflect.defineMetadata("nf:intercept", i, t, e);
72
- };
73
- }
74
- function it(i) {
75
- return (t) => {
76
- Reflect.defineMetadata("nf:canActivate", i, t);
77
- };
78
- }
79
- function rt() {
80
- return (i, t) => {
81
- const e = Reflect.getMetadata("nf:host-properties", i) || [];
82
- e.push(t), Reflect.defineMetadata("nf:host-properties", e, i);
83
- };
84
- }
85
- function at(i) {
86
- return (t) => {
87
- Reflect.defineMetadata("nf:schema", i, t);
88
- };
89
- }
90
- function ot(i = "local") {
91
- return (t, e) => {
92
- const s = Reflect.getMetadata("nf:persist", t) || [];
93
- s.push({
94
- property: e,
95
- storage: i,
96
- key: `nf:${t.constructor.name}:${e}`
97
- }), Reflect.defineMetadata("nf:persist", s, t);
98
- };
99
- }
100
- function L(i) {
101
- if (!(typeof window > "u"))
102
- return i === "session" ? window.sessionStorage : window.localStorage;
103
- }
104
- function q(i) {
105
- const t = Reflect.getMetadata("nf:persist", i) || [];
106
- for (const e of t) {
107
- const s = L(e.storage);
108
- if (!s) continue;
109
- const n = s.getItem(e.key);
110
- if (n !== null)
111
- try {
112
- i[e.property] = JSON.parse(n);
113
- } catch {
114
- i[e.property] = n;
115
- }
116
- }
117
- }
118
- function D(i, t, e) {
119
- const n = (Reflect.getMetadata("nf:persist", i) || []).find((r) => r.property === t);
120
- if (n) {
121
- const r = L(n.storage);
122
- r && r.setItem(n.key, JSON.stringify(e));
123
- }
124
- }
125
- function U(i, t) {
126
- const e = Reflect.getMetadata("nf:states", i) || [], s = Reflect.getMetadata("nf:inputs", i) || [], n = [...e, ...s, "errors"];
127
- let r;
128
- return r = new Proxy(i, {
129
- set(o, a, c) {
130
- const l = o[a];
131
- return o[a] = c, n.includes(a) && l !== c && (D(o, a, c), t()), !0;
132
- },
133
- get(o, a) {
134
- const c = o[a];
135
- return typeof c == "function" ? c.bind(r) : c;
136
- }
137
- }), r;
138
- }
139
- class V {
140
- static render(t, e) {
141
- const r = new DOMParser().parseFromString(`<div>${t}</div>`, "text/html").body.firstElementChild;
142
- return r ? (this.processNode(r, e), r) : document.createElement("div");
143
- }
144
- static processNode(t, e) {
145
- var c, l, f, p;
146
- if (t.nodeType === Node.TEXT_NODE) {
147
- t.textContent = this.interpolate(t.textContent || "", e);
148
- return;
149
- }
150
- if (t.nodeType !== Node.ELEMENT_NODE) return;
151
- const s = t, n = s.tagName.toLowerCase();
152
- if (n === "for") {
153
- const m = (((c = s.getAttribute("each")) == null ? void 0 : c.trim()) || "").replace(/^\{/, "").replace(/\}$/, "").match(/(?:\(\s*([a-zA-Z_$]\w*)\s*,\s*([a-zA-Z_$]\w*)\s*\)|([a-zA-Z_$]\w*))\s+in\s+(.+)/);
154
- if (m) {
155
- const g = m[1] || m[3], y = m[2], v = m[4], T = this.evaluateExpression(v, e), w = document.createDocumentFragment();
156
- Array.isArray(T) && T.forEach((E, C) => {
157
- const _ = Object.create(e);
158
- _[g] = E, y && (_[y] = C);
159
- const P = s.cloneNode(!0);
160
- for (Array.from(P.childNodes).forEach((k) => this.processNode(k, _)); P.firstChild; )
161
- w.appendChild(P.firstChild);
162
- }), (l = s.parentNode) == null || l.replaceChild(w, s);
163
- }
164
- return;
165
- }
166
- if (n === "if") {
167
- const d = (((f = s.getAttribute("condition")) == null ? void 0 : f.trim()) || "").replace(/^\{/, "").replace(/\}$/, "");
168
- let m = !1;
169
- try {
170
- m = !!new Function("ctx", `with(ctx) { return ${d} }`)(e);
171
- } catch (w) {
172
- console.error(`JunoEngine condition error: ${d}`, w);
173
- }
174
- const g = document.createDocumentFragment(), y = Array.from(s.childNodes), v = y.findIndex((w) => {
175
- var E;
176
- return ((E = w.tagName) == null ? void 0 : E.toLowerCase()) === "else";
177
- });
178
- (m ? v !== -1 ? y.slice(0, v) : y : v !== -1 ? Array.from(y[v].childNodes) : []).forEach((w) => {
179
- const E = w.cloneNode(!0);
180
- this.processNode(E, e), g.appendChild(E);
181
- }), (p = s.parentNode) == null || p.replaceChild(g, s);
182
- return;
183
- }
184
- const r = Array.from(s.attributes), o = n.includes("-");
185
- r.forEach((u) => {
186
- const d = /^\{[^{}]+\}$/.test(u.value);
187
- if (o && d) {
188
- const m = u.value.slice(1, -1), g = this.evaluateExpression(m, e), y = u.name.replace(/-([a-z])/g, (v) => v[1].toUpperCase());
189
- s[y] = g;
190
- } else {
191
- const m = this.interpolate(u.value, e);
192
- m !== u.value && s.setAttribute(u.name, m);
193
- }
194
- }), Array.from(s.childNodes).forEach((u) => this.processNode(u, e));
195
- }
196
- static evaluateExpression(t, e) {
197
- const s = t.trim().split("|").map((c) => c.trim()), n = s[0], r = s[1], o = e.__transforms__ || {};
198
- let a;
199
- try {
200
- /^[\w.]+$/.test(n) ? a = n.split(".").reduce((c, l) => c == null ? void 0 : c[l], e) : a = new Function("ctx", `with(ctx) { return ${n} }`)(e);
201
- } catch {
202
- return;
203
- }
204
- return r && o[r] && (a = o[r](a)), a;
205
- }
206
- static interpolate(t, e) {
207
- return t.replace(/\{((?:[^{}]|\{[^{}]*\})*)\}/g, (s, n) => {
208
- const r = this.evaluateExpression(n, e);
209
- return r !== void 0 ? String(r) : "";
210
- });
211
- }
212
- }
213
- function F(i, t) {
214
- let e;
215
- typeof t == "string" ? e = new DOMParser().parseFromString(`<body>${t}</body>`, "text/html").body : e = t;
216
- const s = i instanceof ShadowRoot ? i : document, n = s.activeElement, r = n && n.id ? `#${n.id}` : null, o = n ? n.selectionStart : null, a = n ? n.selectionEnd : null;
217
- if (I(i, e, i), r) {
218
- const c = i.querySelector(r);
219
- c && c !== s.activeElement && (c.focus(), o !== null && a !== null && c.setSelectionRange(o, a));
220
- }
221
- }
222
- function I(i, t, e) {
223
- const s = Array.from(i.childNodes), n = Array.from(t.childNodes), r = Math.max(s.length, n.length);
224
- for (let o = 0; o < r; o++) {
225
- const a = s[o], c = n[o];
226
- if (!a) {
227
- i.appendChild(c);
228
- continue;
229
- }
230
- if (!c) {
231
- i.removeChild(a);
232
- continue;
233
- }
234
- if (a.nodeType !== c.nodeType || a.tagName !== c.tagName) {
235
- i.replaceChild(c, a);
236
- continue;
237
- }
238
- if (a.nodeType === Node.TEXT_NODE) {
239
- a.textContent !== c.textContent && (a.textContent = c.textContent);
240
- continue;
241
- }
242
- if (a.nodeType === Node.ELEMENT_NODE) {
243
- const l = a, f = c, p = l.getAttributeNames(), u = f.getAttributeNames();
244
- for (const d of p)
245
- f.hasAttribute(d) || l.removeAttribute(d);
246
- for (const d of u) {
247
- const m = f.getAttribute(d);
248
- l.getAttribute(d) !== m && l.setAttribute(d, m);
249
- const g = d.replace(/-([a-z])/g, (y) => y[1].toUpperCase());
250
- l.tagName.includes("-") && f[g] !== void 0 && (l[g] = f[g]);
251
- }
252
- if (l instanceof HTMLInputElement || l instanceof HTMLTextAreaElement) {
253
- const d = f.value || f.getAttribute("value") || "";
254
- l.value !== d && (l.value = d);
255
- }
256
- (!l.tagName.includes("-") || l === e) && I(l, f, e);
257
- }
258
- }
259
- }
260
- const x = class x {
261
- constructor() {
262
- h(this, "routes", []);
263
- h(this, "listeners", []);
264
- h(this, "lastTab", null);
265
- h(this, "lastParams", {});
266
- typeof window < "u" && (window.addEventListener("popstate", () => this.handleLocationChange()), window.addEventListener("hashchange", () => this.handleLocationChange()));
267
- }
268
- static get instance() {
269
- return x._instance || (x._instance = new x()), x._instance;
270
- }
271
- /**
272
- * Register available routes.
273
- */
274
- register(t) {
275
- this.routes = t;
276
- }
277
- /**
278
- * Programmatically navigate to a path.
279
- */
280
- navigate(t, e = !0) {
281
- if (typeof window > "u") return;
282
- const s = t.startsWith("/") ? t : `/${t}`;
283
- window.location.pathname !== s && (window.history.pushState({}, "", s), e && this.handleLocationChange());
284
- }
285
- /**
286
- * Subscribe to route changes.
287
- */
288
- onRouteMatch(t) {
289
- return this.listeners.push(t), this.lastTab !== null ? t(this.lastTab, this.lastParams) : this.handleLocationChange(), () => {
290
- this.listeners = this.listeners.filter((e) => e !== t);
291
- };
292
- }
293
- /**
294
- * Manually trigger initial route matching (e.g. on page load).
295
- */
296
- init() {
297
- this.handleLocationChange();
298
- }
299
- async handleLocationChange() {
300
- if (typeof window > "u") return;
301
- const t = window.location.pathname;
302
- let e, s = {};
303
- for (const n of this.routes) {
304
- if (n.path === t || `/${n.tab}` === t) {
305
- e = n;
306
- break;
307
- }
308
- if (n.path.includes("/:")) {
309
- const r = n.path.split("/"), o = t.split("/");
310
- if (r.length === o.length) {
311
- let a = !0;
312
- const c = {};
313
- for (let l = 0; l < r.length; l++)
314
- if (r[l].startsWith(":"))
315
- c[r[l].substring(1)] = o[l];
316
- else if (r[l] !== o[l]) {
317
- a = !1;
318
- break;
319
- }
320
- if (a) {
321
- e = n, s = c;
322
- break;
323
- }
324
- }
325
- }
326
- }
327
- if (e) {
328
- if (e.canActivate)
329
- try {
330
- const n = await e.canActivate();
331
- if (n === !1)
332
- return;
333
- if (typeof n == "string") {
334
- this.navigate(n);
335
- return;
336
- }
337
- } catch (n) {
338
- console.error(`Route guard error on ${e.path}:`, n);
339
- return;
340
- }
341
- e.title && (document.title = e.title), this.notify(e.tab, s);
342
- } else if (t === "/" || t === "") {
343
- const n = this.routes[0];
344
- n && this.notify(n.tab, {});
345
- }
346
- }
347
- notify(t, e) {
348
- this.lastTab = t, this.lastParams = e, this.listeners.forEach((s) => s(t, e));
349
- }
350
- /**
351
- * Get the current path.
352
- */
353
- get currentPath() {
354
- return typeof window < "u" ? window.location.pathname : "/";
355
- }
2
+ //#region src/core/decorators.ts
3
+ function e(e) {
4
+ return (t) => {
5
+ e.shadow === void 0 && (e.shadow = !0), Reflect.defineMetadata("nf:config", e, t);
6
+ };
7
+ }
8
+ function t() {
9
+ return (e, t) => {
10
+ let n = Reflect.getMetadata("nf:states", e) || [];
11
+ n.push(t), Reflect.defineMetadata("nf:states", n, e);
12
+ };
13
+ }
14
+ function n() {
15
+ return (e, t) => {
16
+ let n = Reflect.getMetadata("nf:inputs", e) || [];
17
+ n.push(t), Reflect.defineMetadata("nf:inputs", n, e);
18
+ };
19
+ }
20
+ function r(e) {
21
+ return (t, n) => {
22
+ let r = Reflect.getMetadata("nf:params", t) || [];
23
+ r.push({
24
+ key: n,
25
+ paramName: e || n
26
+ }), Reflect.defineMetadata("nf:params", r, t);
27
+ };
28
+ }
29
+ function i(e) {
30
+ return (t, n) => {
31
+ Reflect.defineMetadata("nf:inject", e, t, n);
32
+ };
33
+ }
34
+ function a() {
35
+ return (e, t) => {
36
+ let n = Reflect.getMetadata("nf:transforms", e) || [];
37
+ n.push(t), Reflect.defineMetadata("nf:transforms", n, e);
38
+ };
39
+ }
40
+ function o() {
41
+ return (e, t) => {
42
+ let n = Reflect.getMetadata("nf:actions", e) || [];
43
+ n.push(t), Reflect.defineMetadata("nf:actions", n, e);
44
+ };
45
+ }
46
+ function s(e) {
47
+ return (t, n) => {
48
+ let r = Reflect.getMetadata("nf:provides", t) || [];
49
+ r.push({
50
+ key: e,
51
+ property: n
52
+ }), Reflect.defineMetadata("nf:provides", r, t);
53
+ };
54
+ }
55
+ function c(e) {
56
+ return (t, n) => {
57
+ let r = Reflect.getMetadata("nf:injects", t) || [];
58
+ r.push({
59
+ key: e,
60
+ property: n
61
+ }), Reflect.defineMetadata("nf:injects", r, t);
62
+ };
63
+ }
64
+ function l(e) {
65
+ return (t) => {
66
+ let n = Reflect.getMetadata("nf:refine", t) || [];
67
+ n.push(e), Reflect.defineMetadata("nf:refine", n, t);
68
+ };
69
+ }
70
+ function u(e, t) {
71
+ return (n, r) => {
72
+ let i = Reflect.getMetadata("nf:validates", n) || [];
73
+ i.push({
74
+ key: r,
75
+ predicate: e,
76
+ message: t
77
+ }), Reflect.defineMetadata("nf:validates", i, n);
78
+ };
79
+ }
80
+ function d(e) {
81
+ return (t, n) => {
82
+ Reflect.defineMetadata("nf:intercept", e, t, n);
83
+ };
84
+ }
85
+ function f(e) {
86
+ return (t) => {
87
+ Reflect.defineMetadata("nf:canActivate", e, t);
88
+ };
89
+ }
90
+ function p() {
91
+ return (e, t) => {
92
+ let n = Reflect.getMetadata("nf:host-properties", e) || [];
93
+ n.push(t), Reflect.defineMetadata("nf:host-properties", n, e);
94
+ };
95
+ }
96
+ function m(e) {
97
+ return (t) => {
98
+ Reflect.defineMetadata("nf:schema", e, t);
99
+ };
100
+ }
101
+ //#endregion
102
+ //#region src/core/persist.ts
103
+ function h(e = "local") {
104
+ return (t, n) => {
105
+ let r = Reflect.getMetadata("nf:persist", t) || [];
106
+ r.push({
107
+ property: n,
108
+ storage: e,
109
+ key: `nf:${t.constructor.name}:${n}`
110
+ }), Reflect.defineMetadata("nf:persist", r, t);
111
+ };
112
+ }
113
+ function g(e) {
114
+ if (!(typeof window > "u")) return e === "session" ? window.sessionStorage : window.localStorage;
115
+ }
116
+ function _(e) {
117
+ let t = Reflect.getMetadata("nf:persist", e) || [];
118
+ for (let n of t) {
119
+ let t = g(n.storage);
120
+ if (!t) continue;
121
+ let r = t.getItem(n.key);
122
+ if (r !== null) try {
123
+ e[n.property] = JSON.parse(r);
124
+ } catch {
125
+ e[n.property] = r;
126
+ }
127
+ }
128
+ }
129
+ function v(e, t, n) {
130
+ let r = (Reflect.getMetadata("nf:persist", e) || []).find((e) => e.property === t);
131
+ if (r) {
132
+ let e = g(r.storage);
133
+ e && e.setItem(r.key, JSON.stringify(n));
134
+ }
135
+ }
136
+ //#endregion
137
+ //#region src/core/reactivity.ts
138
+ function y(e, t) {
139
+ let n = Reflect.getMetadata("nf:states", e) || [], r = Reflect.getMetadata("nf:inputs", e) || [], i = [
140
+ ...n,
141
+ ...r,
142
+ "errors"
143
+ ], a;
144
+ return a = new Proxy(e, {
145
+ set(e, n, r) {
146
+ let a = e[n];
147
+ return e[n] = r, i.includes(n) && a !== r && (v(e, n, r), t()), !0;
148
+ },
149
+ get(e, t) {
150
+ let n = e[t];
151
+ return typeof n == "function" ? (e.__boundMethods__ ||= /* @__PURE__ */ new Map(), e.__boundMethods__.has(t) || e.__boundMethods__.set(t, n.bind(a)), e.__boundMethods__.get(t)) : n;
152
+ }
153
+ }), a;
154
+ }
155
+ //#endregion
156
+ //#region src/core/engine.ts
157
+ var b = class {
158
+ static render(e, t) {
159
+ let n = new DOMParser().parseFromString(`<div>${e}</div>`, "text/html").body.firstElementChild;
160
+ return n ? (this.processNode(n, t), n) : document.createElement("div");
161
+ }
162
+ static processNode(e, t) {
163
+ if (e.nodeType === Node.TEXT_NODE) {
164
+ e.textContent = this.interpolate(e.textContent || "", t);
165
+ return;
166
+ }
167
+ if (e.nodeType !== Node.ELEMENT_NODE) return;
168
+ let n = e, r = n.tagName.toLowerCase();
169
+ if (r === "for") {
170
+ let e = (n.getAttribute("each")?.trim() || "").replace(/^\{/, "").replace(/\}$/, "").match(/(?:\(\s*([a-zA-Z_$]\w*)\s*,\s*([a-zA-Z_$]\w*)\s*\)|([a-zA-Z_$]\w*))\s+in\s+(.+)/);
171
+ if (e) {
172
+ let r = e[1] || e[3], i = e[2], a = e[4], o = this.evaluateExpression(a, t), s = document.createDocumentFragment();
173
+ Array.isArray(o) && o.forEach((e, a) => {
174
+ let o = Object.create(t);
175
+ o[r] = e, i && (o[i] = a);
176
+ let c = n.cloneNode(!0);
177
+ for (Array.from(c.childNodes).forEach((e) => this.processNode(e, o)); c.firstChild;) s.appendChild(c.firstChild);
178
+ }), n.parentNode?.replaceChild(s, n);
179
+ }
180
+ return;
181
+ }
182
+ if (r === "if") {
183
+ let e = (n.getAttribute("condition")?.trim() || "").replace(/^\{/, "").replace(/\}$/, ""), r = !1;
184
+ try {
185
+ r = !!Function("ctx", `with(ctx) { return ${e} }`)(t);
186
+ } catch (t) {
187
+ console.error(`JunoEngine condition error: ${e}`, t);
188
+ }
189
+ let i = document.createDocumentFragment(), a = Array.from(n.childNodes), o = a.findIndex((e) => e.tagName?.toLowerCase() === "else");
190
+ (r ? o === -1 ? a : a.slice(0, o) : o === -1 ? [] : Array.from(a[o].childNodes)).forEach((e) => {
191
+ let n = e.cloneNode(!0);
192
+ this.processNode(n, t), i.appendChild(n);
193
+ }), n.parentNode?.replaceChild(i, n);
194
+ return;
195
+ }
196
+ let i = Array.from(n.attributes), a = r.includes("-");
197
+ i.forEach((e) => {
198
+ let r = /^\{[^{}]+\}$/.test(e.value);
199
+ if (a && r) {
200
+ let r = e.value.slice(1, -1), i = this.evaluateExpression(r, t), a = e.name.replace(/-([a-z])/g, (e) => e[1].toUpperCase());
201
+ n[a] = i;
202
+ } else {
203
+ let r = this.interpolate(e.value, t);
204
+ r !== e.value && n.setAttribute(e.name, r);
205
+ }
206
+ }), Array.from(n.childNodes).forEach((e) => this.processNode(e, t));
207
+ }
208
+ static evaluateExpression(e, t) {
209
+ let n = e.trim().split("|").map((e) => e.trim()), r = n[0], i = n[1], a = t.__transforms__ || {}, o;
210
+ try {
211
+ o = /^[\w.]+$/.test(r) ? r.split(".").reduce((e, t) => e?.[t], t) : Function("ctx", `with(ctx) { return ${r} }`)(t);
212
+ } catch {
213
+ return;
214
+ }
215
+ return i && a[i] && (o = a[i](o)), o;
216
+ }
217
+ static interpolate(e, t) {
218
+ return e.replace(/\{((?:[^{}]|\{[^{}]*\})*)\}/g, (e, n) => {
219
+ let r = this.evaluateExpression(n, t);
220
+ return r === void 0 ? "" : String(r);
221
+ });
222
+ }
356
223
  };
357
- h(x, "_instance");
358
- let N = x;
359
- async function ct(i) {
360
- const t = Reflect.getMetadata("nf:config", i);
361
- if (!t || !t.tag)
362
- throw new Error("Missing @Component decorator or tag!");
363
- customElements.define(
364
- t.tag,
365
- class extends HTMLElement {
366
- constructor() {
367
- super();
368
- h(this, "instance");
369
- h(this, "proxy");
370
- h(this, "target");
371
- h(this, "routeUnsubscribe");
372
- this.instance = new i(), (Reflect.getMetadata("nf:host-properties", i.prototype) || []).forEach((r) => {
373
- this.instance[r] = this;
374
- }), (Reflect.getMetadata("nf:inputs", i.prototype) || []).forEach((r) => {
375
- let o = this.hasOwnProperty(r) ? this[r] : void 0;
376
- Object.defineProperty(this, r, {
377
- get: () => this.proxy[r],
378
- set: (a) => {
379
- this.proxy[r] = a, this.update();
380
- }
381
- }), o !== void 0 && (this.instance[r] = o);
382
- }), this.instance.errors || (this.instance.errors = {}), this.instance.isValid || (this.instance.isValid = () => {
383
- this.proxy.errors = {};
384
- let r = !0;
385
- const o = Reflect.getMetadata("nf:schema", i), a = Reflect.getMetadata("nf:refine", i) || [], c = Reflect.getMetadata("nf:validates", i.prototype) || [], l = [];
386
- if (o && typeof o.parse == "function") {
387
- const f = o.parse(this.proxy);
388
- f instanceof Promise ? l.push(f.then((p) => {
389
- p.success || (r = !1, this.proxy.errors = { ...this.proxy.errors, ...p.errors });
390
- })) : f.success || (r = !1, this.proxy.errors = { ...this.proxy.errors, ...f.errors });
391
- }
392
- for (const f of c) {
393
- const p = this.proxy[f.key], u = f.predicate(p);
394
- u instanceof Promise ? l.push(
395
- u.then((d) => {
396
- d || (r = !1, this.proxy.errors = { ...this.proxy.errors, [f.key]: f.message });
397
- })
398
- ) : u || (r = !1, this.proxy.errors = { ...this.proxy.errors, [f.key]: f.message });
399
- }
400
- for (const f of a) {
401
- const p = f.validate(this.proxy);
402
- if (p instanceof Promise)
403
- l.push(
404
- p.then((u) => {
405
- if (!u) {
406
- r = !1;
407
- const d = f.fields[f.fields.length - 1];
408
- this.proxy.errors = { ...this.proxy.errors, [d]: f.message };
409
- }
410
- })
411
- );
412
- else if (!p) {
413
- r = !1;
414
- const u = f.fields[f.fields.length - 1];
415
- this.proxy.errors = { ...this.proxy.errors, [u]: f.message };
416
- }
417
- }
418
- return l.length > 0 ? Promise.all(l).then(() => r) : r;
419
- }), q(this.instance), this.proxy = U(this.instance, () => this.update()), t.shadow ? this.target = this.shadowRoot || this.attachShadow({ mode: "open" }) : this.target = this;
420
- const n = (r, o) => {
421
- let a = r.target;
422
- for (; a && a !== this.parentElement; ) {
423
- const c = a.getAttribute(o);
424
- if (c) {
425
- const l = c.match(/^(\w+)(?:\((.*)\))?$/);
426
- if (l) {
427
- const [f, p, u] = l, d = this.proxy[p];
428
- if (typeof d == "function") {
429
- const m = Reflect.getMetadata("nf:intercept", this.instance, p);
430
- if (m) {
431
- const g = m(this.proxy);
432
- if (g instanceof Promise) {
433
- g.then((y) => {
434
- y === !1 ? (r.stopImmediatePropagation(), r.stopPropagation()) : this.executeMethod(d, r, u);
435
- });
436
- return;
437
- } else if (g === !1) {
438
- r.stopImmediatePropagation(), r.stopPropagation();
439
- return;
440
- }
441
- }
442
- this.executeMethod(d, r, u);
443
- return;
444
- }
445
- }
446
- }
447
- if (a === this) break;
448
- a = a.parentElement;
449
- }
450
- };
451
- this.target.addEventListener("click", (r) => n(r, "@click")), this.target.addEventListener("input", (r) => n(r, "@input"));
452
- }
453
- static get observedAttributes() {
454
- return Reflect.getMetadata("nf:inputs", i.prototype) || [];
455
- }
456
- attributeChangedCallback(s, n, r) {
457
- r && /^\{[^{}]+\}$/.test(r) || n !== r && (this.proxy ? (this.proxy[s] = r, this.update()) : this.instance && (this.instance[s] = r));
458
- }
459
- executeMethod(s, n, r) {
460
- if (r !== void 0) {
461
- const o = r.split(",").map((a) => (a = a.trim(), a === "e" || a === "$event" ? n : a === "true" ? !0 : a === "false" ? !1 : !isNaN(Number(a)) && a !== "" ? Number(a) : a.startsWith("'") && a.endsWith("'") || a.startsWith('"') && a.endsWith('"') ? a.slice(1, -1) : a));
462
- s.apply(this.proxy, o);
463
- } else
464
- s.call(this.proxy, n);
465
- }
466
- async connectedCallback() {
467
- const s = Reflect.getMetadata("nf:canActivate", i);
468
- if (s)
469
- try {
470
- const o = await s();
471
- if (o === !1) return;
472
- if (typeof o == "string") {
473
- N.instance.navigate(o);
474
- return;
475
- }
476
- } catch (o) {
477
- console.error("Guard evaluation failed:", o);
478
- return;
479
- }
480
- if (this.instance.canActivate)
481
- try {
482
- const o = await this.instance.canActivate.call(this.proxy);
483
- if (o === !1) return;
484
- if (typeof o == "string") {
485
- N.instance.navigate(o);
486
- return;
487
- }
488
- } catch (o) {
489
- console.error("Lifecycle canActivate hook failed:", o);
490
- return;
491
- }
492
- if (t.templateUrl) {
493
- const o = await fetch(t.templateUrl);
494
- this.instance.template = await o.text();
495
- }
496
- const n = Reflect.getMetadata("nf:params", i.prototype) || [];
497
- if (n.length > 0) {
498
- const o = N.instance;
499
- this.routeUnsubscribe = o.onRouteMatch((a, c) => {
500
- n.forEach((l) => {
501
- c[l.paramName] !== void 0 && this.proxy[l.key] !== c[l.paramName] && (this.proxy[l.key] = c[l.paramName]);
502
- });
503
- });
504
- }
505
- (Reflect.getMetadata("nf:injects", i.prototype) || []).forEach((o) => {
506
- let a = this.parentElement;
507
- for (; a; ) {
508
- if (a.instance) {
509
- const l = (Reflect.getMetadata("nf:provides", a.instance.constructor) || []).find((f) => f.key === o.key);
510
- if (l) {
511
- this.proxy[o.property] = a.proxy[l.property];
512
- break;
513
- }
514
- }
515
- a = a.parentElement || a.getRootNode().host;
516
- }
517
- }), this.instance.onInit && await this.instance.onInit.call(this.proxy), this.update(), this.instance.onRender && this.instance.onRender.call(this.proxy, this);
518
- }
519
- disconnectedCallback() {
520
- this.routeUnsubscribe && this.routeUnsubscribe(), this.instance.onDestroy && this.instance.onDestroy();
521
- }
522
- update() {
523
- const s = this.instance.template || "<div>No template</div>", n = Reflect.getMetadata("nf:transforms", this.instance) || [], r = {};
524
- for (const c of n)
525
- typeof this.proxy[c] == "function" && (r[c] = this.proxy[c]);
526
- const o = Object.create(this.proxy);
527
- o.__transforms__ = r;
528
- const a = V.render(s, o);
529
- F(this.target, a);
530
- }
531
- }
532
- );
533
- }
534
- const M = class M {
535
- constructor() {
536
- // ── State ─────────────────────────────────────────────────
537
- h(this, "middlewares", []);
538
- }
539
- static get instance() {
540
- return M._instance || (M._instance = new M()), M._instance;
541
- }
542
- // ── Public API ────────────────────────────────────────────
543
- /** Register an error-handling middleware. Returns an unsubscribe function. */
544
- addMiddleware(t) {
545
- return this.middlewares.push(t), () => {
546
- this.middlewares = this.middlewares.filter((e) => e !== t);
547
- };
548
- }
549
- /**
550
- * Run the middleware chain. The first middleware that returns `true`
551
- * stops propagation. If no middleware handles it, logs to console.
552
- */
553
- handle(t) {
554
- for (const e of this.middlewares)
555
- if (e(t) === !0) return;
556
- console.error("[JunoJS ErrorHandler] Unhandled error:", t.message, t);
557
- }
558
- /** Convenience: create a JunoJSError from an HTTP Response. */
559
- static fromResponse(t, e) {
560
- return {
561
- status: t.status,
562
- message: `HTTP ${t.status}: ${t.statusText}`,
563
- url: e,
564
- original: t
565
- };
566
- }
567
- /** Convenience: create a JunoJSError from a caught exception. */
568
- static fromException(t) {
569
- return t instanceof Error ? { message: t.message, original: t } : { message: String(t), original: t };
570
- }
224
+ //#endregion
225
+ //#region src/core/dom.ts
226
+ function x(e, t) {
227
+ let n;
228
+ n = typeof t == "string" ? new DOMParser().parseFromString(`<body>${t}</body>`, "text/html").body : t;
229
+ let r = e instanceof ShadowRoot ? e : document, i = r.activeElement, a = i && i.id ? `#${i.id}` : null, o = i ? i.selectionStart : null, s = i ? i.selectionEnd : null;
230
+ if (S(e, n, e), a) {
231
+ let t = e.querySelector(a);
232
+ t && t !== r.activeElement && (t.focus(), o !== null && s !== null && t.setSelectionRange(o, s));
233
+ }
234
+ }
235
+ function S(e, t, n) {
236
+ let r = Array.from(e.childNodes), i = Array.from(t.childNodes), a = Math.max(r.length, i.length);
237
+ for (let t = 0; t < a; t++) {
238
+ let a = r[t], o = i[t];
239
+ if (!a) {
240
+ e.appendChild(o);
241
+ continue;
242
+ }
243
+ if (!o) {
244
+ e.removeChild(a);
245
+ continue;
246
+ }
247
+ if (a.nodeType !== o.nodeType || a.tagName !== o.tagName) {
248
+ e.replaceChild(o, a);
249
+ continue;
250
+ }
251
+ if (a.nodeType === Node.TEXT_NODE) {
252
+ a.textContent !== o.textContent && (a.textContent = o.textContent);
253
+ continue;
254
+ }
255
+ if (a.nodeType === Node.ELEMENT_NODE) {
256
+ let e = a, t = o, r = e.getAttributeNames(), i = t.getAttributeNames();
257
+ for (let n of r) t.hasAttribute(n) || e.removeAttribute(n);
258
+ for (let n of i) {
259
+ let r = t.getAttribute(n);
260
+ e.getAttribute(n) !== r && e.setAttribute(n, r);
261
+ let i = n.replace(/-([a-z])/g, (e) => e[1].toUpperCase());
262
+ e.tagName.includes("-") && t[i] !== void 0 && e[i] !== t[i] && (e[i] = t[i]);
263
+ }
264
+ if (e instanceof HTMLInputElement || e instanceof HTMLTextAreaElement) {
265
+ let n = t.value || t.getAttribute("value") || "";
266
+ e.value !== n && (e.value = n);
267
+ }
268
+ (!e.tagName.includes("-") || e === n) && S(e, t, n);
269
+ }
270
+ }
271
+ }
272
+ //#endregion
273
+ //#region src/common/router/router.service.ts
274
+ var C = class e {
275
+ static _instance;
276
+ routes = [];
277
+ listeners = [];
278
+ lastTab = null;
279
+ lastParams = {};
280
+ static get instance() {
281
+ return e._instance ||= new e(), e._instance;
282
+ }
283
+ constructor() {
284
+ typeof window < "u" && (window.addEventListener("popstate", () => this.handleLocationChange()), window.addEventListener("hashchange", () => this.handleLocationChange()));
285
+ }
286
+ register(e) {
287
+ this.routes = e;
288
+ }
289
+ navigate(e, t = !0) {
290
+ if (typeof window > "u") return;
291
+ let n = e.startsWith("/") ? e : `/${e}`;
292
+ window.location.pathname !== n && (window.history.pushState({}, "", n), t && this.handleLocationChange());
293
+ }
294
+ onRouteMatch(e) {
295
+ return this.listeners.push(e), this.lastTab === null ? this.handleLocationChange() : e(this.lastTab, this.lastParams), () => {
296
+ this.listeners = this.listeners.filter((t) => t !== e);
297
+ };
298
+ }
299
+ init() {
300
+ this.handleLocationChange();
301
+ }
302
+ async handleLocationChange() {
303
+ if (typeof window > "u") return;
304
+ let e = window.location.pathname, t, n = {};
305
+ for (let r of this.routes) {
306
+ if (r.path === e || `/${r.tab}` === e) {
307
+ t = r;
308
+ break;
309
+ }
310
+ if (r.path.includes("/:")) {
311
+ let i = r.path.split("/"), a = e.split("/");
312
+ if (i.length === a.length) {
313
+ let e = !0, o = {};
314
+ for (let t = 0; t < i.length; t++) if (i[t].startsWith(":")) o[i[t].substring(1)] = a[t];
315
+ else if (i[t] !== a[t]) {
316
+ e = !1;
317
+ break;
318
+ }
319
+ if (e) {
320
+ t = r, n = o;
321
+ break;
322
+ }
323
+ }
324
+ }
325
+ }
326
+ if (t) {
327
+ if (t.canActivate) try {
328
+ let e = await t.canActivate();
329
+ if (e === !1) return;
330
+ if (typeof e == "string") {
331
+ this.navigate(e);
332
+ return;
333
+ }
334
+ } catch (e) {
335
+ console.error(`Route guard error on ${t.path}:`, e);
336
+ return;
337
+ }
338
+ t.title && (document.title = t.title), this.notify(t.tab, n);
339
+ } else if (e === "/" || e === "") {
340
+ let e = this.routes[0];
341
+ e && this.notify(e.tab, {});
342
+ }
343
+ }
344
+ notify(e, t) {
345
+ this.lastTab = e, this.lastParams = t, this.listeners.forEach((n) => n(e, t));
346
+ }
347
+ get currentPath() {
348
+ return typeof window < "u" ? window.location.pathname : "/";
349
+ }
571
350
  };
572
- // ── Singleton ─────────────────────────────────────────────
573
- h(M, "_instance");
574
- let S = M;
575
- class lt {
576
- constructor() {
577
- h(this, "_initialValues", {});
578
- h(this, "_touched", {});
579
- queueMicrotask(() => this._captureInitialValues());
580
- }
581
- // ─── Public API ───────────────────────────────────────────
582
- /** Returns true if every validated field passes all its rules. */
583
- isValid() {
584
- const t = this.getErrors();
585
- return Object.keys(t).length === 0;
586
- }
587
- /** Returns a map of field → error messages (only fields with errors). */
588
- getErrors() {
589
- const t = Reflect.getMetadata("nf:validators", this) || /* @__PURE__ */ new Map(), e = {};
590
- return t.forEach((s, n) => {
591
- const r = this[n], o = [];
592
- for (const a of s)
593
- a.validate(r, this) || o.push(a.message);
594
- o.length > 0 && (e[n] = o);
595
- }), e;
596
- }
597
- /** Resets all fields to their initial values and clears touched state. */
598
- reset() {
599
- for (const [t, e] of Object.entries(this._initialValues))
600
- this[t] = e;
601
- this._touched = {};
602
- }
603
- /** True if any field differs from its initial value. */
604
- get dirty() {
605
- for (const [t, e] of Object.entries(this._initialValues))
606
- if (this[t] !== e) return !0;
607
- return !1;
608
- }
609
- /** Per-field touched tracking. */
610
- get touched() {
611
- return { ...this._touched };
612
- }
613
- /** Mark a field as touched (e.g. on blur). */
614
- markTouched(t) {
615
- this._touched[t] = !0;
616
- }
617
- // ─── Internals ────────────────────────────────────────────
618
- _captureInitialValues() {
619
- (Reflect.getMetadata("nf:validators", this) || /* @__PURE__ */ new Map()).forEach((e, s) => {
620
- this._initialValues[s] = this[s];
621
- });
622
- }
623
- }
624
- function A(i, t, e) {
625
- const s = Reflect.getMetadata("nf:validators", i) || /* @__PURE__ */ new Map(), n = s.get(t) || [];
626
- n.push(e), s.set(t, n), Reflect.defineMetadata("nf:validators", s, i);
627
- }
628
- function ft(i = "This field is required") {
629
- return (t, e) => {
630
- A(t, e, {
631
- name: "required",
632
- message: i,
633
- validate: (s) => s != null && String(s).trim().length > 0
634
- });
635
- };
636
- }
637
- function dt(i = "Invalid email address") {
638
- return (t, e) => {
639
- A(t, e, {
640
- name: "email",
641
- message: i,
642
- validate: (s) => s ? /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(s)) : !0
643
- });
644
- };
645
- }
646
- function ut(i, t) {
647
- return (e, s) => {
648
- A(e, s, {
649
- name: "match",
650
- message: t || `Must match ${i}`,
651
- validate: (n, r) => n === r[i]
652
- });
653
- };
654
- }
655
- function ht(i, t = "Invalid format") {
656
- return (e, s) => {
657
- A(e, s, {
658
- name: "pattern",
659
- message: t,
660
- validate: (n) => n ? i.test(String(n)) : !0
661
- });
662
- };
663
- }
664
- class b {
665
- constructor() {
666
- h(this, "rules", []);
667
- h(this, "IS_REQUIRED", !1);
668
- }
669
- required(t = "Required") {
670
- return this.IS_REQUIRED = !0, this.rules.push((e) => !e && e !== 0 && e !== !1 ? t : void 0), this;
671
- }
672
- email(t = "Invalid email") {
673
- return this.rules.push((e) => {
674
- if (e)
675
- return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(e)) ? void 0 : t;
676
- }), this;
677
- }
678
- min(t, e) {
679
- return this.rules.push((s) => {
680
- if (s)
681
- return String(s).length < t ? e || `Min length ${t}` : void 0;
682
- }), this;
683
- }
684
- max(t, e) {
685
- return this.rules.push((s) => {
686
- if (s)
687
- return String(s).length > t ? e || `Max length ${t}` : void 0;
688
- }), this;
689
- }
690
- validate(t, e) {
691
- for (const s of this.rules) {
692
- const n = s(t, e);
693
- if (n) return n;
694
- }
695
- }
696
- }
697
- class H {
698
- constructor() {
699
- h(this, "fields", {});
700
- h(this, "refines", []);
701
- }
702
- string() {
703
- return new b();
704
- }
705
- number() {
706
- return new b();
707
- }
708
- boolean() {
709
- return new b();
710
- }
711
- shape(t) {
712
- return this.fields = t, this;
713
- }
714
- refine(t, e) {
715
- return this.refines.push({ validate: t, ...e }), this;
716
- }
717
- async parse(t) {
718
- const e = {};
719
- let s = !0;
720
- for (const [n, r] of Object.entries(this.fields)) {
721
- const o = r.validate(t[n], t);
722
- o && (e[n] = o, s = !1);
723
- }
724
- for (const n of this.refines) {
725
- const r = n.validate(t);
726
- (r instanceof Promise ? await r : r) || (e[n.path] = n.message, s = !1);
727
- }
728
- return { success: s, errors: s ? void 0 : e };
729
- }
730
- }
731
- const pt = {
732
- string: () => new b(),
733
- number: () => new b(),
734
- boolean: () => new b(),
735
- object: (i) => new H().shape(i)
736
- };
737
- class mt {
738
- constructor() {
739
- h(this, "requestInterceptors", []);
740
- h(this, "responseInterceptors", []);
741
- h(this, "errorHandler", null);
742
- }
743
- /** Plug in the global ErrorHandler for automatic error routing. */
744
- setErrorHandler(t) {
745
- this.errorHandler = t;
746
- }
747
- // ── Interceptors ──────────────────────────────────────────
748
- addRequestInterceptor(t) {
749
- this.requestInterceptors.push(t);
750
- }
751
- addResponseInterceptor(t) {
752
- this.responseInterceptors.push(t);
753
- }
754
- // ── HTTP Methods ──────────────────────────────────────────
755
- async get(t, e) {
756
- return this.request("GET", t, void 0, e);
757
- }
758
- async post(t, e, s) {
759
- return this.request("POST", t, e, s);
760
- }
761
- async put(t, e, s) {
762
- return this.request("PUT", t, e, s);
763
- }
764
- async delete(t, e) {
765
- return this.request("DELETE", t, void 0, e);
766
- }
767
- async patch(t, e, s) {
768
- return this.request("PATCH", t, e, s);
769
- }
770
- // ── Core ──────────────────────────────────────────────────
771
- async request(t, e, s, n) {
772
- let r = e;
773
- if (n != null && n.params) {
774
- const f = new URLSearchParams(n.params).toString();
775
- r += (e.includes("?") ? "&" : "?") + f;
776
- }
777
- const o = {
778
- "Content-Type": "application/json",
779
- ...(n == null ? void 0 : n.headers) || {}
780
- }, a = { method: t, headers: o };
781
- s !== void 0 && (a.body = JSON.stringify(s));
782
- const c = new AbortController();
783
- let l;
784
- n != null && n.signal && n.signal.addEventListener("abort", () => c.abort()), n != null && n.timeout && n.timeout > 0 && (l = setTimeout(() => c.abort(), n.timeout)), a.signal = c.signal;
785
- for (const f of this.requestInterceptors) {
786
- const p = f(r, a);
787
- p && ([r] = p, Object.assign(a, p[1]));
788
- }
789
- try {
790
- let f = await fetch(r, a);
791
- for (const u of this.responseInterceptors) {
792
- const d = u(f);
793
- d && (f = d);
794
- }
795
- if (!f.ok)
796
- throw this.errorHandler && this.errorHandler.handle(
797
- S.fromResponse(f, r)
798
- ), new Error(`HTTP ${f.status}: ${f.statusText}`);
799
- return (f.headers.get("content-type") || "").includes("application/json") ? await f.json() : await f.text();
800
- } finally {
801
- l !== void 0 && clearTimeout(l);
802
- }
803
- }
804
- }
805
- const R = class R {
806
- constructor() {
807
- // ── State ─────────────────────────────────────────────────
808
- h(this, "dictionaries", /* @__PURE__ */ new Map());
809
- h(this, "_locale", "en");
810
- h(this, "_onLocaleChange", []);
811
- }
812
- static get instance() {
813
- return R._instance || (R._instance = new R()), R._instance;
814
- }
815
- /** Current active locale. */
816
- get locale() {
817
- return this._locale;
818
- }
819
- // ── Public API ────────────────────────────────────────────
820
- /** Register translations for a locale. Merges with any existing entries. */
821
- addTranslations(t, e) {
822
- const s = this.dictionaries.get(t) || {};
823
- this.dictionaries.set(t, { ...s, ...e });
824
- }
825
- /** Switch the active locale. */
826
- setLocale(t) {
827
- this.dictionaries.has(t) || console.warn(`[i18n] No translations registered for locale "${t}".`), this._locale = t;
828
- for (const e of this._onLocaleChange) e();
829
- }
830
- /** Subscribe to locale changes. Returns an unsubscribe function. */
831
- onLocaleChange(t) {
832
- return this._onLocaleChange.push(t), () => {
833
- this._onLocaleChange = this._onLocaleChange.filter((e) => e !== t);
834
- };
835
- }
836
- /**
837
- * Translate a key with optional parameter interpolation.
838
- * Params replace `{{paramName}}` placeholders in the translation string.
839
- *
840
- * t('greeting', { name: 'Ada' }) // "Hello, Ada!"
841
- */
842
- t(t, e) {
843
- const s = this.dictionaries.get(this._locale);
844
- let n = s == null ? void 0 : s[t];
845
- if (n === void 0)
846
- return t;
847
- if (e)
848
- for (const [r, o] of Object.entries(e))
849
- n = n.replace(
850
- new RegExp(`\\{\\{${r}\\}\\}`, "g"),
851
- String(o)
852
- );
853
- return n;
854
- }
855
- /** List all registered locales. */
856
- get availableLocales() {
857
- return [...this.dictionaries.keys()];
858
- }
351
+ //#endregion
352
+ //#region src/core/bootstrap.ts
353
+ async function w(e) {
354
+ let t = Reflect.getMetadata("nf:config", e);
355
+ if (!t || !t.tag) throw Error("Missing @Component decorator or tag!");
356
+ customElements.define(t.tag, class extends HTMLElement {
357
+ instance;
358
+ proxy;
359
+ target;
360
+ routeUnsubscribe;
361
+ static get observedAttributes() {
362
+ return Reflect.getMetadata("nf:inputs", e.prototype) || [];
363
+ }
364
+ attributeChangedCallback(e, t, n) {
365
+ n && /^\{[^{}]+\}$/.test(n) || t !== n && (this.proxy ? this.proxy[e] = n : this.instance && (this.instance[e] = n, this.update()));
366
+ }
367
+ constructor() {
368
+ super(), this.instance = new e(), (Reflect.getMetadata("nf:host-properties", e.prototype) || []).forEach((e) => {
369
+ this.instance[e] = this;
370
+ }), (Reflect.getMetadata("nf:inputs", e.prototype) || []).forEach((e) => {
371
+ let t = this.hasOwnProperty(e) ? this[e] : void 0;
372
+ Object.defineProperty(this, e, {
373
+ get: () => this.proxy[e],
374
+ set: (t) => {
375
+ this.proxy?.[e] !== t && (this.proxy ? this.proxy[e] = t : (this.instance[e] = t, this.update()));
376
+ }
377
+ }), t !== void 0 && (this.instance[e] = t);
378
+ }), this.instance.errors || (this.instance.errors = {}), this.instance.isValid || (this.instance.isValid = () => {
379
+ this.proxy.errors = {};
380
+ let t = !0, n = Reflect.getMetadata("nf:schema", e), r = Reflect.getMetadata("nf:refine", e) || [], i = Reflect.getMetadata("nf:validates", e.prototype) || [], a = [];
381
+ if (n && typeof n.parse == "function") {
382
+ let e = n.parse(this.proxy);
383
+ e instanceof Promise ? a.push(e.then((e) => {
384
+ e.success || (t = !1, this.proxy.errors = {
385
+ ...this.proxy.errors,
386
+ ...e.errors
387
+ });
388
+ })) : e.success || (t = !1, this.proxy.errors = {
389
+ ...this.proxy.errors,
390
+ ...e.errors
391
+ });
392
+ }
393
+ for (let e of i) {
394
+ let n = this.proxy[e.key], r = e.predicate(n);
395
+ r instanceof Promise ? a.push(r.then((n) => {
396
+ n || (t = !1, this.proxy.errors = {
397
+ ...this.proxy.errors,
398
+ [e.key]: e.message
399
+ });
400
+ })) : r || (t = !1, this.proxy.errors = {
401
+ ...this.proxy.errors,
402
+ [e.key]: e.message
403
+ });
404
+ }
405
+ for (let e of r) {
406
+ let n = e.validate(this.proxy);
407
+ if (n instanceof Promise) a.push(n.then((n) => {
408
+ if (!n) {
409
+ t = !1;
410
+ let n = e.fields[e.fields.length - 1];
411
+ this.proxy.errors = {
412
+ ...this.proxy.errors,
413
+ [n]: e.message
414
+ };
415
+ }
416
+ }));
417
+ else if (!n) {
418
+ t = !1;
419
+ let n = e.fields[e.fields.length - 1];
420
+ this.proxy.errors = {
421
+ ...this.proxy.errors,
422
+ [n]: e.message
423
+ };
424
+ }
425
+ }
426
+ return a.length > 0 ? Promise.all(a).then(() => t) : t;
427
+ }), _(this.instance), this.proxy = y(this.instance, () => this.update()), t.shadow ? this.target = this.shadowRoot || this.attachShadow({ mode: "open" }) : this.target = this;
428
+ let n = (e, t) => {
429
+ let n = e.target;
430
+ for (; n && n !== this.parentElement;) {
431
+ let r = n.getAttribute(t);
432
+ if (r) {
433
+ let t = r.match(/^(\w+)(?:\((.*)\))?$/);
434
+ if (t) {
435
+ let [n, r, i] = t, a = this.proxy[r];
436
+ if (typeof a == "function") {
437
+ let t = Reflect.getMetadata("nf:intercept", this.instance, r);
438
+ if (t) {
439
+ let n = t(this.proxy);
440
+ if (n instanceof Promise) {
441
+ n.then((t) => {
442
+ t === !1 ? (e.stopImmediatePropagation(), e.stopPropagation()) : this.executeMethod(a, e, i);
443
+ });
444
+ return;
445
+ } else if (n === !1) {
446
+ e.stopImmediatePropagation(), e.stopPropagation();
447
+ return;
448
+ }
449
+ }
450
+ this.executeMethod(a, e, i);
451
+ return;
452
+ }
453
+ }
454
+ }
455
+ if (n === this) break;
456
+ n = n.parentElement;
457
+ }
458
+ };
459
+ this.target.addEventListener("click", (e) => n(e, "@click")), this.target.addEventListener("input", (e) => n(e, "@input"));
460
+ }
461
+ executeMethod(e, t, n) {
462
+ if (n !== void 0) {
463
+ let r = n.split(",").map((e) => (e = e.trim(), e === "e" || e === "$event" ? t : e === "true" ? !0 : e === "false" ? !1 : !isNaN(Number(e)) && e !== "" ? Number(e) : e.startsWith("'") && e.endsWith("'") || e.startsWith("\"") && e.endsWith("\"") ? e.slice(1, -1) : e));
464
+ e.apply(this.proxy, r);
465
+ } else e.call(this.proxy, t);
466
+ }
467
+ async connectedCallback() {
468
+ let n = Reflect.getMetadata("nf:canActivate", e);
469
+ if (n) try {
470
+ let e = await n();
471
+ if (e === !1) return;
472
+ if (typeof e == "string") {
473
+ C.instance.navigate(e);
474
+ return;
475
+ }
476
+ } catch (e) {
477
+ console.error("Guard evaluation failed:", e);
478
+ return;
479
+ }
480
+ if (this.instance.canActivate) try {
481
+ let e = await this.instance.canActivate.call(this.proxy);
482
+ if (e === !1) return;
483
+ if (typeof e == "string") {
484
+ C.instance.navigate(e);
485
+ return;
486
+ }
487
+ } catch (e) {
488
+ console.error("Lifecycle canActivate hook failed:", e);
489
+ return;
490
+ }
491
+ if (t.templateUrl) try {
492
+ let e = await fetch(t.templateUrl);
493
+ if (!e.ok) throw Error(`Failed to fetch template: ${e.status} ${e.statusText}`);
494
+ let n = e.headers.get("content-type"), r = await e.text();
495
+ n?.includes("text/html") && r.includes(`<${t.tag}`) ? (console.error(`Recursive template detected for ${t.tag}. Check if ${t.templateUrl} exists!`), this.instance.template = `<div style="color:red; padding: 20px; border: 1px solid red;">Recursive template detected for &lt;${t.tag}&gt;! Check URL: ${t.templateUrl}</div>`) : this.instance.template = r;
496
+ } catch (e) {
497
+ console.error(`Juno ERROR: Failed to load template from ${t.templateUrl}`, e), this.instance.template = `<div style="color:red; padding: 10px; border: 1px solid red;">Error loading template from ${t.templateUrl}: ${e.message || e}</div>`;
498
+ }
499
+ let r = Reflect.getMetadata("nf:params", e.prototype) || [];
500
+ r.length > 0 && (this.routeUnsubscribe = C.instance.onRouteMatch((e, t) => {
501
+ r.forEach((e) => {
502
+ t[e.paramName] !== void 0 && this.proxy[e.key] !== t[e.paramName] && (this.proxy[e.key] = t[e.paramName]);
503
+ });
504
+ })), (Reflect.getMetadata("nf:injects", e.prototype) || []).forEach((e) => {
505
+ let t = this.parentElement;
506
+ for (; t;) {
507
+ if (t.instance) {
508
+ let n = (Reflect.getMetadata("nf:provides", t.instance.constructor) || []).find((t) => t.key === e.key);
509
+ if (n) {
510
+ this.proxy[e.property] = t.proxy[n.property];
511
+ break;
512
+ }
513
+ }
514
+ t = t.parentElement || t.getRootNode().host;
515
+ }
516
+ }), this.instance.onInit && await this.instance.onInit.call(this.proxy), this.update(), this.instance.onRender && this.instance.onRender.call(this.proxy, this);
517
+ }
518
+ disconnectedCallback() {
519
+ this.routeUnsubscribe && this.routeUnsubscribe(), this.instance.onDestroy && this.instance.onDestroy();
520
+ }
521
+ update() {
522
+ let e = this.instance.template || "<div>No template</div>", t = Reflect.getMetadata("nf:transforms", this.instance) || [], n = {};
523
+ for (let e of t) typeof this.proxy[e] == "function" && (n[e] = this.proxy[e]);
524
+ let r = Object.create(this.proxy);
525
+ r.__transforms__ = n;
526
+ let i = b.render(e, r);
527
+ x(this.target, i);
528
+ }
529
+ });
530
+ }
531
+ //#endregion
532
+ //#region src/core/error-handler.ts
533
+ var T = class e {
534
+ static _instance;
535
+ static get instance() {
536
+ return e._instance ||= new e(), e._instance;
537
+ }
538
+ middlewares = [];
539
+ addMiddleware(e) {
540
+ return this.middlewares.push(e), () => {
541
+ this.middlewares = this.middlewares.filter((t) => t !== e);
542
+ };
543
+ }
544
+ handle(e) {
545
+ for (let t of this.middlewares) if (t(e) === !0) return;
546
+ console.error("[JunoJS ErrorHandler] Unhandled error:", e.message, e);
547
+ }
548
+ static fromResponse(e, t) {
549
+ return {
550
+ status: e.status,
551
+ message: `HTTP ${e.status}: ${e.statusText}`,
552
+ url: t,
553
+ original: e
554
+ };
555
+ }
556
+ static fromException(e) {
557
+ return e instanceof Error ? {
558
+ message: e.message,
559
+ original: e
560
+ } : {
561
+ message: String(e),
562
+ original: e
563
+ };
564
+ }
565
+ }, E = class {
566
+ _initialValues = {};
567
+ _touched = {};
568
+ constructor() {
569
+ queueMicrotask(() => this._captureInitialValues());
570
+ }
571
+ isValid() {
572
+ let e = this.getErrors();
573
+ return Object.keys(e).length === 0;
574
+ }
575
+ getErrors() {
576
+ let e = Reflect.getMetadata("nf:validators", this) || /* @__PURE__ */ new Map(), t = {};
577
+ return e.forEach((e, n) => {
578
+ let r = this[n], i = [];
579
+ for (let t of e) t.validate(r, this) || i.push(t.message);
580
+ i.length > 0 && (t[n] = i);
581
+ }), t;
582
+ }
583
+ reset() {
584
+ for (let [e, t] of Object.entries(this._initialValues)) this[e] = t;
585
+ this._touched = {};
586
+ }
587
+ get dirty() {
588
+ for (let [e, t] of Object.entries(this._initialValues)) if (this[e] !== t) return !0;
589
+ return !1;
590
+ }
591
+ get touched() {
592
+ return { ...this._touched };
593
+ }
594
+ markTouched(e) {
595
+ this._touched[e] = !0;
596
+ }
597
+ _captureInitialValues() {
598
+ (Reflect.getMetadata("nf:validators", this) || /* @__PURE__ */ new Map()).forEach((e, t) => {
599
+ this._initialValues[t] = this[t];
600
+ });
601
+ }
859
602
  };
860
- // ── Singleton ─────────────────────────────────────────────
861
- h(R, "_instance");
862
- let $ = R;
863
- export {
864
- B as Action,
865
- it as CanActivate,
866
- z as Component,
867
- dt as Email,
868
- S as ErrorHandler,
869
- lt as FormModel,
870
- H as FormSchema,
871
- rt as HostElement,
872
- mt as HttpClient,
873
- $ as I18nService,
874
- tt as Inject,
875
- Z as Input,
876
- nt as Intercept,
877
- V as JunoEngine,
878
- ut as Match,
879
- G as Param,
880
- ht as Pattern,
881
- ot as Persist,
882
- Y as Provide,
883
- et as Refine,
884
- ft as Required,
885
- N as RouterService,
886
- at as Schema,
887
- b as SchemaField,
888
- K as State,
889
- X as Transform,
890
- Q as Use,
891
- st as Validate,
892
- ct as bootstrap,
893
- U as createReactiveProxy,
894
- pt as s
603
+ //#endregion
604
+ //#region src/common/forms/validators.ts
605
+ function D(e, t, n) {
606
+ let r = Reflect.getMetadata("nf:validators", e) || /* @__PURE__ */ new Map(), i = r.get(t) || [];
607
+ i.push(n), r.set(t, i), Reflect.defineMetadata("nf:validators", r, e);
608
+ }
609
+ function O(e = "This field is required") {
610
+ return (t, n) => {
611
+ D(t, n, {
612
+ name: "required",
613
+ message: e,
614
+ validate: (e) => e != null && String(e).trim().length > 0
615
+ });
616
+ };
617
+ }
618
+ function k(e = "Invalid email address") {
619
+ return (t, n) => {
620
+ D(t, n, {
621
+ name: "email",
622
+ message: e,
623
+ validate: (e) => e ? /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(e)) : !0
624
+ });
625
+ };
626
+ }
627
+ function A(e, t) {
628
+ return (n, r) => {
629
+ D(n, r, {
630
+ name: "match",
631
+ message: t || `Must match ${e}`,
632
+ validate: (t, n) => t === n[e]
633
+ });
634
+ };
635
+ }
636
+ function j(e, t = "Invalid format") {
637
+ return (n, r) => {
638
+ D(n, r, {
639
+ name: "pattern",
640
+ message: t,
641
+ validate: (t) => t ? e.test(String(t)) : !0
642
+ });
643
+ };
644
+ }
645
+ //#endregion
646
+ //#region src/common/forms/schema.ts
647
+ var M = class {
648
+ rules = [];
649
+ IS_REQUIRED = !1;
650
+ required(e = "Required") {
651
+ return this.IS_REQUIRED = !0, this.rules.push((t) => !t && t !== 0 && t !== !1 ? e : void 0), this;
652
+ }
653
+ email(e = "Invalid email") {
654
+ return this.rules.push((t) => {
655
+ if (t) return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(t)) ? void 0 : e;
656
+ }), this;
657
+ }
658
+ min(e, t) {
659
+ return this.rules.push((n) => {
660
+ if (n) return String(n).length < e ? t || `Min length ${e}` : void 0;
661
+ }), this;
662
+ }
663
+ max(e, t) {
664
+ return this.rules.push((n) => {
665
+ if (n) return String(n).length > e ? t || `Max length ${e}` : void 0;
666
+ }), this;
667
+ }
668
+ validate(e, t) {
669
+ for (let n of this.rules) {
670
+ let r = n(e, t);
671
+ if (r) return r;
672
+ }
673
+ }
674
+ }, N = class {
675
+ fields = {};
676
+ refines = [];
677
+ string() {
678
+ return new M();
679
+ }
680
+ number() {
681
+ return new M();
682
+ }
683
+ boolean() {
684
+ return new M();
685
+ }
686
+ shape(e) {
687
+ return this.fields = e, this;
688
+ }
689
+ refine(e, t) {
690
+ return this.refines.push({
691
+ validate: e,
692
+ ...t
693
+ }), this;
694
+ }
695
+ async parse(e) {
696
+ let t = {}, n = !0;
697
+ for (let [r, i] of Object.entries(this.fields)) {
698
+ let a = i.validate(e[r], e);
699
+ a && (t[r] = a, n = !1);
700
+ }
701
+ for (let r of this.refines) {
702
+ let i = r.validate(e);
703
+ (i instanceof Promise ? await i : i) || (t[r.path] = r.message, n = !1);
704
+ }
705
+ return {
706
+ success: n,
707
+ errors: n ? void 0 : t
708
+ };
709
+ }
710
+ }, P = {
711
+ string: () => new M(),
712
+ number: () => new M(),
713
+ boolean: () => new M(),
714
+ object: (e) => new N().shape(e)
715
+ }, F = class {
716
+ requestInterceptors = [];
717
+ responseInterceptors = [];
718
+ errorHandler = null;
719
+ setErrorHandler(e) {
720
+ this.errorHandler = e;
721
+ }
722
+ addRequestInterceptor(e) {
723
+ this.requestInterceptors.push(e);
724
+ }
725
+ addResponseInterceptor(e) {
726
+ this.responseInterceptors.push(e);
727
+ }
728
+ async get(e, t) {
729
+ return this.request("GET", e, void 0, t);
730
+ }
731
+ async post(e, t, n) {
732
+ return this.request("POST", e, t, n);
733
+ }
734
+ async put(e, t, n) {
735
+ return this.request("PUT", e, t, n);
736
+ }
737
+ async delete(e, t) {
738
+ return this.request("DELETE", e, void 0, t);
739
+ }
740
+ async patch(e, t, n) {
741
+ return this.request("PATCH", e, t, n);
742
+ }
743
+ async request(e, t, n, r) {
744
+ let i = t;
745
+ if (r?.params) {
746
+ let e = new URLSearchParams(r.params).toString();
747
+ i += (t.includes("?") ? "&" : "?") + e;
748
+ }
749
+ let a = {
750
+ method: e,
751
+ headers: {
752
+ "Content-Type": "application/json",
753
+ ...r?.headers || {}
754
+ }
755
+ };
756
+ n !== void 0 && (a.body = JSON.stringify(n));
757
+ let o = new AbortController(), s;
758
+ r?.signal && r.signal.addEventListener("abort", () => o.abort()), r?.timeout && r.timeout > 0 && (s = setTimeout(() => o.abort(), r.timeout)), a.signal = o.signal;
759
+ for (let e of this.requestInterceptors) {
760
+ let t = e(i, a);
761
+ t && ([i] = t, Object.assign(a, t[1]));
762
+ }
763
+ try {
764
+ let e = await fetch(i, a);
765
+ for (let t of this.responseInterceptors) {
766
+ let n = t(e);
767
+ n && (e = n);
768
+ }
769
+ if (!e.ok) throw this.errorHandler && this.errorHandler.handle(T.fromResponse(e, i)), Error(`HTTP ${e.status}: ${e.statusText}`);
770
+ return (e.headers.get("content-type") || "").includes("application/json") ? await e.json() : await e.text();
771
+ } finally {
772
+ s !== void 0 && clearTimeout(s);
773
+ }
774
+ }
775
+ }, I = class e {
776
+ static _instance;
777
+ static get instance() {
778
+ return e._instance ||= new e(), e._instance;
779
+ }
780
+ dictionaries = /* @__PURE__ */ new Map();
781
+ _locale = "en";
782
+ _onLocaleChange = [];
783
+ get locale() {
784
+ return this._locale;
785
+ }
786
+ addTranslations(e, t) {
787
+ let n = this.dictionaries.get(e) || {};
788
+ this.dictionaries.set(e, {
789
+ ...n,
790
+ ...t
791
+ });
792
+ }
793
+ setLocale(e) {
794
+ this.dictionaries.has(e) || console.warn(`[i18n] No translations registered for locale "${e}".`), this._locale = e;
795
+ for (let e of this._onLocaleChange) e();
796
+ }
797
+ onLocaleChange(e) {
798
+ return this._onLocaleChange.push(e), () => {
799
+ this._onLocaleChange = this._onLocaleChange.filter((t) => t !== e);
800
+ };
801
+ }
802
+ t(e, t) {
803
+ let n = this.dictionaries.get(this._locale)?.[e];
804
+ if (n === void 0) return e;
805
+ if (t) for (let [e, r] of Object.entries(t)) n = n.replace(RegExp(`\\{\\{${e}\\}\\}`, "g"), String(r));
806
+ return n;
807
+ }
808
+ get availableLocales() {
809
+ return [...this.dictionaries.keys()];
810
+ }
895
811
  };
896
- //# sourceMappingURL=index.js.map
812
+ //#endregion
813
+ export { o as Action, f as CanActivate, e as Component, k as Email, T as ErrorHandler, E as FormModel, N as FormSchema, p as HostElement, F as HttpClient, I as I18nService, c as Inject, n as Input, d as Intercept, b as JunoEngine, A as Match, r as Param, j as Pattern, h as Persist, s as Provide, l as Refine, O as Required, C as RouterService, m as Schema, M as SchemaField, t as State, a as Transform, i as Use, u as Validate, w as bootstrap, y as createReactiveProxy, P as s };
814
+
815
+ //# sourceMappingURL=index.js.map