@jasonshimmy/custom-elements-runtime 2.5.8 → 2.6.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/README.md +41 -40
- package/dist/custom-elements-runtime.cjs.js +3 -3
- package/dist/custom-elements-runtime.es.js +75 -74
- package/dist/custom-elements-runtime.router.cjs.js +1 -1
- package/dist/custom-elements-runtime.router.es.js +27 -27
- package/dist/index.d.ts +2 -1
- package/dist/runtime/hooks.d.ts +59 -0
- package/dist/{template-compiler-DXKQZPJB.cjs → template-compiler-gn2qLc7f.cjs} +9 -9
- package/dist/{template-compiler-DXKQZPJB.cjs.map → template-compiler-gn2qLc7f.cjs.map} +1 -1
- package/dist/{template-compiler-DbHgEJzb.js → template-compiler-xSxUyqRI.js} +157 -130
- package/dist/{template-compiler-DbHgEJzb.js.map → template-compiler-xSxUyqRI.js.map} +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as y, d as I } from "./logger-BvkEbVM4.js";
|
|
2
2
|
import { f as rt, r as tt, c as T } from "./namespace-helpers-DcD_6_K1.js";
|
|
3
|
-
import { c as st, h as F,
|
|
3
|
+
import { c as st, h as F, l as ct, m as it, b as bt, o as wt } from "./template-compiler-xSxUyqRI.js";
|
|
4
4
|
import { createStore as lt } from "./custom-elements-runtime.store.es.js";
|
|
5
5
|
import { match as St } from "./custom-elements-runtime.directives.es.js";
|
|
6
6
|
const ut = {
|
|
@@ -49,12 +49,12 @@ function At(t) {
|
|
|
49
49
|
}
|
|
50
50
|
const d = u.match(/^:([A-Za-z0-9_-]+)(\*)?$/);
|
|
51
51
|
if (d) {
|
|
52
|
-
const A = d[1],
|
|
53
|
-
if (
|
|
52
|
+
const A = d[1], P = !!d[2];
|
|
53
|
+
if (P && l !== a.length - 1)
|
|
54
54
|
return y(
|
|
55
55
|
`Route '${t.path}' contains a splat param ':${A}*' in a non-terminal position; splats must be the last segment. This route will be ignored.`
|
|
56
56
|
), { invalid: !0 };
|
|
57
|
-
i.push(A), o.push(
|
|
57
|
+
i.push(A), o.push(P ? "__SPLAT__" : "([^/]+)");
|
|
58
58
|
continue;
|
|
59
59
|
}
|
|
60
60
|
o.push(Ct(u));
|
|
@@ -103,7 +103,7 @@ let J = {}, U = {};
|
|
|
103
103
|
function xt() {
|
|
104
104
|
J = {}, U = {};
|
|
105
105
|
}
|
|
106
|
-
function
|
|
106
|
+
function Pt() {
|
|
107
107
|
const t = Object.entries(J);
|
|
108
108
|
if (t.length <= pt) return;
|
|
109
109
|
const g = t.sort(
|
|
@@ -115,7 +115,7 @@ function kt() {
|
|
|
115
115
|
for (const [a] of g)
|
|
116
116
|
delete J[a];
|
|
117
117
|
}
|
|
118
|
-
async function
|
|
118
|
+
async function kt(t) {
|
|
119
119
|
if (t.component) return t.component;
|
|
120
120
|
if (t.load) {
|
|
121
121
|
const r = J[t.path];
|
|
@@ -126,7 +126,7 @@ async function Pt(t) {
|
|
|
126
126
|
const g = typeof window > "u";
|
|
127
127
|
try {
|
|
128
128
|
const a = t.load().then((i) => {
|
|
129
|
-
|
|
129
|
+
Pt();
|
|
130
130
|
const o = i.default;
|
|
131
131
|
return J[t.path] = {
|
|
132
132
|
component: o,
|
|
@@ -295,9 +295,9 @@ const E = {
|
|
|
295
295
|
};
|
|
296
296
|
function Tt(t) {
|
|
297
297
|
const { routes: r, base: g = "", initialUrl: a, scrollToFragment: i = !0 } = t, o = Et(g), b = typeof i == "boolean" ? { ...ut, enabled: i } : { ...ut, ...i };
|
|
298
|
-
let l, u, d, A,
|
|
298
|
+
let l, u, d, A, P, L, j;
|
|
299
299
|
const _ = /* @__PURE__ */ new Set(), B = 10;
|
|
300
|
-
let
|
|
300
|
+
let k = 0;
|
|
301
301
|
const X = async (s, c) => {
|
|
302
302
|
const e = et(r, s.path);
|
|
303
303
|
if (!e || !e.beforeEnter) return !0;
|
|
@@ -305,7 +305,7 @@ function Tt(t) {
|
|
|
305
305
|
const n = await e.beforeEnter(s, c);
|
|
306
306
|
if (typeof n == "string") {
|
|
307
307
|
const p = `${s.path}->${n}`;
|
|
308
|
-
return _.has(p) ||
|
|
308
|
+
return _.has(p) || k >= B ? (I(`Redirect loop detected: ${p}`), !1) : n;
|
|
309
309
|
}
|
|
310
310
|
return n !== !1;
|
|
311
311
|
} catch (n) {
|
|
@@ -323,7 +323,7 @@ function Tt(t) {
|
|
|
323
323
|
const n = await e.onEnter(s, c);
|
|
324
324
|
if (typeof n == "string") {
|
|
325
325
|
const p = `${s.path}->${n}`;
|
|
326
|
-
return _.has(p) ||
|
|
326
|
+
return _.has(p) || k >= B ? (I(`Redirect loop detected: ${p}`), !1) : n;
|
|
327
327
|
}
|
|
328
328
|
return n !== !1;
|
|
329
329
|
} catch (n) {
|
|
@@ -429,11 +429,11 @@ function Tt(t) {
|
|
|
429
429
|
y(`Navigation to ${s} blocked - navigation already in progress`);
|
|
430
430
|
return;
|
|
431
431
|
}
|
|
432
|
-
R = !0,
|
|
432
|
+
R = !0, k = 0, _.clear();
|
|
433
433
|
try {
|
|
434
434
|
await N(s, c);
|
|
435
435
|
} finally {
|
|
436
|
-
R = !1,
|
|
436
|
+
R = !1, k = 0, _.clear();
|
|
437
437
|
}
|
|
438
438
|
}, q = (s) => {
|
|
439
439
|
const c = s.indexOf("#"), e = c >= 0 ? s.slice(c + 1) : "", n = c >= 0 ? s.slice(0, c) : s, p = n.indexOf("?"), m = p >= 0 ? n.slice(0, p) : n, w = p >= 0 ? at(n.slice(p)) : {}, S = m.startsWith(o) ? m.slice(o.length) : m;
|
|
@@ -454,7 +454,7 @@ function Tt(t) {
|
|
|
454
454
|
}, w = await X(m, p);
|
|
455
455
|
if (w === !1) return;
|
|
456
456
|
if (typeof w == "string") {
|
|
457
|
-
|
|
457
|
+
k++;
|
|
458
458
|
const $ = `${m.path}->${w}`;
|
|
459
459
|
_.add($), await N(w, !0);
|
|
460
460
|
return;
|
|
@@ -462,7 +462,7 @@ function Tt(t) {
|
|
|
462
462
|
const S = await G(m, p);
|
|
463
463
|
if (S === !1) return;
|
|
464
464
|
if (typeof S == "string") {
|
|
465
|
-
|
|
465
|
+
k++;
|
|
466
466
|
const $ = `${m.path}->${S}`;
|
|
467
467
|
_.add($), await N(S, !0);
|
|
468
468
|
return;
|
|
@@ -544,7 +544,7 @@ function Tt(t) {
|
|
|
544
544
|
await f(n.path, e);
|
|
545
545
|
};
|
|
546
546
|
const c = () => A(!0);
|
|
547
|
-
window.addEventListener("popstate", c),
|
|
547
|
+
window.addEventListener("popstate", c), P = (e) => f(e, !1), L = (e) => f(e, !0), j = () => window.history.back();
|
|
548
548
|
} else {
|
|
549
549
|
l = () => {
|
|
550
550
|
try {
|
|
@@ -568,7 +568,7 @@ function Tt(t) {
|
|
|
568
568
|
await c(e.path);
|
|
569
569
|
};
|
|
570
570
|
const c = async (e) => {
|
|
571
|
-
if (
|
|
571
|
+
if (k++, k > B) {
|
|
572
572
|
I(`SSR redirect depth exceeded for path: ${e}`);
|
|
573
573
|
return;
|
|
574
574
|
}
|
|
@@ -604,19 +604,19 @@ function Tt(t) {
|
|
|
604
604
|
throw I("SSR navigation error:", n), n;
|
|
605
605
|
}
|
|
606
606
|
};
|
|
607
|
-
|
|
607
|
+
P = async (e) => (k = 0, _.clear(), c(e)), L = async (e) => (k = 0, _.clear(), c(e)), j = () => {
|
|
608
608
|
};
|
|
609
609
|
}
|
|
610
610
|
return {
|
|
611
611
|
_cleanupScrollState: Y,
|
|
612
612
|
store: d,
|
|
613
|
-
push:
|
|
613
|
+
push: P,
|
|
614
614
|
replace: L,
|
|
615
615
|
back: j,
|
|
616
616
|
subscribe: d.subscribe,
|
|
617
617
|
matchRoute: (s) => O(s),
|
|
618
618
|
getCurrent: () => d.getState(),
|
|
619
|
-
resolveRouteComponent:
|
|
619
|
+
resolveRouteComponent: kt,
|
|
620
620
|
base: o,
|
|
621
621
|
// Public API: allow components or tests to explicitly request scrolling to
|
|
622
622
|
// a fragment when they know their DOM is ready. Returns true if scrolled.
|
|
@@ -696,7 +696,7 @@ function Ft(t) {
|
|
|
696
696
|
return { tag: u, props: {}, children: [] };
|
|
697
697
|
if (typeof u == "function") {
|
|
698
698
|
const d = u();
|
|
699
|
-
return (d instanceof Promise ? d : Promise.resolve(d)).then((
|
|
699
|
+
return (d instanceof Promise ? d : Promise.resolve(d)).then((P) => typeof P == "string" ? { tag: P, props: {}, children: [] } : P);
|
|
700
700
|
}
|
|
701
701
|
return F`<div>Invalid route component</div>`;
|
|
702
702
|
} catch {
|
|
@@ -731,7 +731,7 @@ function Ft(t) {
|
|
|
731
731
|
} : null;
|
|
732
732
|
let d;
|
|
733
733
|
wt(() => "a,button{display:inline-block;}");
|
|
734
|
-
const A = tt(a.class || ""),
|
|
734
|
+
const A = tt(a.class || ""), P = tt(a.style || "");
|
|
735
735
|
if (!i) {
|
|
736
736
|
let h = null;
|
|
737
737
|
ct((R) => {
|
|
@@ -769,7 +769,7 @@ function Ft(t) {
|
|
|
769
769
|
const f = R?._host;
|
|
770
770
|
if (f instanceof HTMLElement) {
|
|
771
771
|
const q = f.getAttribute("class"), N = f.getAttribute("style");
|
|
772
|
-
q && (A.value = q), N && (
|
|
772
|
+
q && (A.value = q), N && (P.value = N), q !== null && f.removeAttribute("class"), N !== null && f.removeAttribute("style");
|
|
773
773
|
try {
|
|
774
774
|
R?._requestRender?.();
|
|
775
775
|
try {
|
|
@@ -835,19 +835,19 @@ function Ft(t) {
|
|
|
835
835
|
const R = (A && A.value || a.class || "").split(/\s+/).filter(Boolean), f = {};
|
|
836
836
|
for (const q of R) f[q] = !0;
|
|
837
837
|
return f;
|
|
838
|
-
}),
|
|
838
|
+
}), k = T(() => ({
|
|
839
839
|
...B.value,
|
|
840
840
|
[a.activeClass || "active"]: j.value,
|
|
841
841
|
[a.exactActiveClass || "exact-active"]: L.value
|
|
842
842
|
})), X = T(
|
|
843
|
-
() => Object.keys(
|
|
843
|
+
() => Object.keys(k.value).filter((h) => k.value[h]).join(" ")
|
|
844
844
|
), G = T(() => a.tag || "a"), nt = T(() => G.value === "button"), z = T(
|
|
845
845
|
() => L.value ? a.ariaCurrentValue : null
|
|
846
846
|
), M = T(() => !!a.disabled), O = T(() => {
|
|
847
847
|
const h = String(a.to || "");
|
|
848
848
|
return (Z(h) || !!a.external) && G.value === "a";
|
|
849
849
|
}), Y = T(
|
|
850
|
-
() =>
|
|
850
|
+
() => P && P.value || a.style || ""
|
|
851
851
|
), K = (h) => {
|
|
852
852
|
if (h.defaultPrevented || h.button !== 0 || h.metaKey || h.altKey || h.ctrlKey || h.shiftKey)
|
|
853
853
|
return;
|
|
@@ -934,7 +934,7 @@ export {
|
|
|
934
934
|
Lt as matchRouteSSR,
|
|
935
935
|
C as normalizePathForRoute,
|
|
936
936
|
at as parseQuery,
|
|
937
|
-
|
|
937
|
+
kt as resolveRouteComponent,
|
|
938
938
|
$t as safeDecode,
|
|
939
939
|
Rt as serializeQuery,
|
|
940
940
|
Tt as useRouter
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { component } from './runtime/component';
|
|
2
|
-
export { useEmit, useOnConnected, useOnDisconnected, useOnAttributeChanged, useOnError, useStyle, useProps, provide, inject, createComposable, useExpose, useSlots, getCurrentComponentContext, } from './runtime/hooks';
|
|
2
|
+
export { useEmit, useOnConnected, useOnDisconnected, useOnAttributeChanged, useOnError, useStyle, useProps, defineModel, provide, inject, createComposable, useExpose, useSlots, getCurrentComponentContext, } from './runtime/hooks';
|
|
3
|
+
export type { ModelRef } from './runtime/hooks';
|
|
3
4
|
export { ref, computed, watch, watchEffect, isReactiveState, } from './runtime/reactive';
|
|
4
5
|
export { ReactiveState } from './runtime/reactive';
|
|
5
6
|
export { html } from './runtime/template-compiler';
|
package/dist/runtime/hooks.d.ts
CHANGED
|
@@ -252,3 +252,62 @@ export declare function useSlots(): {
|
|
|
252
252
|
getNodes(name?: string): Element[];
|
|
253
253
|
names(): string[];
|
|
254
254
|
};
|
|
255
|
+
/**
|
|
256
|
+
* A writable ref that reads from a component prop and emits `update:<propName>`
|
|
257
|
+
* when its value is set, enabling two-way binding with a parent's `:model` or
|
|
258
|
+
* `:model:<propName>` directive.
|
|
259
|
+
*
|
|
260
|
+
* Also recognised by the vdom `:model` directive as a reactive value so it can
|
|
261
|
+
* be passed directly to native inputs inside the child template.
|
|
262
|
+
*/
|
|
263
|
+
export interface ModelRef<T> {
|
|
264
|
+
/** The current prop value. Reactive — reads trigger re-renders. */
|
|
265
|
+
value: T;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Define a two-way binding model for a component prop, similar to Vue's
|
|
269
|
+
* `defineModel()`. It combines `useProps` + `useEmit` into a single ergonomic
|
|
270
|
+
* API so child components don't need to wire the plumbing manually.
|
|
271
|
+
*
|
|
272
|
+
* The returned `ModelRef` object:
|
|
273
|
+
* - **reads** `.value` → returns the current prop value (reactive)
|
|
274
|
+
* - **writes** `.value = x` → emits `update:<propName>` so the parent's
|
|
275
|
+
* `:model` / `:model:<propName>` directive can update its reactive state
|
|
276
|
+
*
|
|
277
|
+
* The object is also recognised by the vdom `:model` directive, so you can
|
|
278
|
+
* pass it directly to a native input's `:model` binding inside the child
|
|
279
|
+
* template and the two-way sync is wired up automatically.
|
|
280
|
+
*
|
|
281
|
+
* @example
|
|
282
|
+
* ```ts
|
|
283
|
+
* // Default model — maps to the parent's :model="..."
|
|
284
|
+
* component('my-input', () => {
|
|
285
|
+
* const model = defineModel('');
|
|
286
|
+
*
|
|
287
|
+
* return html`
|
|
288
|
+
* <input :model="${model}" />
|
|
289
|
+
* `;
|
|
290
|
+
* });
|
|
291
|
+
*
|
|
292
|
+
* // Named model — maps to the parent's :model:title="..."
|
|
293
|
+
* component('my-field', () => {
|
|
294
|
+
* const title = defineModel('title', '');
|
|
295
|
+
* const count = defineModel('count', 0);
|
|
296
|
+
*
|
|
297
|
+
* return html`
|
|
298
|
+
* <input :model="${title}" />
|
|
299
|
+
* <input type="number" :model="${count}" />
|
|
300
|
+
* `;
|
|
301
|
+
* });
|
|
302
|
+
* ```
|
|
303
|
+
*
|
|
304
|
+
* @param args - Either:
|
|
305
|
+
* - No arguments → `modelValue` prop, no default.
|
|
306
|
+
* - One argument → treated as the **default value** for the `modelValue` prop;
|
|
307
|
+
* type is inferred from the value.
|
|
308
|
+
* - Two arguments → first is the **prop name**, second is the **default value**;
|
|
309
|
+
* type is inferred from the default value.
|
|
310
|
+
*/
|
|
311
|
+
export declare function defineModel<T = unknown>(): ModelRef<T | undefined>;
|
|
312
|
+
export declare function defineModel<T>(defaultValue: T): ModelRef<T>;
|
|
313
|
+
export declare function defineModel<T>(propName: string, defaultValue: T): ModelRef<T>;
|