@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.
@@ -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, k as ct, l as it, b as bt, n as wt } from "./template-compiler-DbHgEJzb.js";
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], k = !!d[2];
53
- if (k && l !== a.length - 1)
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(k ? "__SPLAT__" : "([^/]+)");
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 kt() {
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 Pt(t) {
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
- kt();
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, k, L, j;
298
+ let l, u, d, A, P, L, j;
299
299
  const _ = /* @__PURE__ */ new Set(), B = 10;
300
- let P = 0;
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) || P >= B ? (I(`Redirect loop detected: ${p}`), !1) : n;
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) || P >= B ? (I(`Redirect loop detected: ${p}`), !1) : n;
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, P = 0, _.clear();
432
+ R = !0, k = 0, _.clear();
433
433
  try {
434
434
  await N(s, c);
435
435
  } finally {
436
- R = !1, P = 0, _.clear();
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
- P++;
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
- P++;
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), k = (e) => f(e, !1), L = (e) => f(e, !0), j = () => window.history.back();
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 (P++, P > B) {
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
- k = async (e) => (P = 0, _.clear(), c(e)), L = async (e) => (P = 0, _.clear(), c(e)), j = () => {
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: k,
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: Pt,
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((k) => typeof k == "string" ? { tag: k, props: {}, children: [] } : k);
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 || ""), k = tt(a.style || "");
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 && (k.value = N), q !== null && f.removeAttribute("class"), N !== null && f.removeAttribute("style");
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
- }), P = T(() => ({
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(P.value).filter((h) => P.value[h]).join(" ")
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
- () => k && k.value || a.style || ""
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
- Pt as resolveRouteComponent,
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';
@@ -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>;