routerino 2.3.4 → 2.5.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/routerino.js CHANGED
@@ -1,93 +1,138 @@
1
- import { jsx as g, jsxs as q, Fragment as F } from "react/jsx-runtime";
2
- import { useState as I, useEffect as O, createContext as _, Component as V, useContext as G } from "react";
1
+ import { jsx as m, jsxs as q, Fragment as V } from "react/jsx-runtime";
2
+ import { useState as M, useEffect as _, useMemo as X, createContext as Z, Component as J, useContext as Q } from "react";
3
3
  import t from "prop-types";
4
- const K = [480, 800, 1200, 1920], Z = "(max-width: 480px) 100vw, (max-width: 800px) 800px, (max-width: 1200px) 1200px, 1920px";
5
- function J(r, e = "") {
6
- const i = r.toLowerCase(), n = e.toLowerCase();
7
- return !!(i.includes("hero") || i.includes("banner") || n.includes("hero") || n.includes("banner") || n.includes("h-screen") || n.includes("h-full"));
4
+ const Y = [480, 800, 1200, 1920], ee = "(max-width: 480px) 100vw, (max-width: 800px) 800px, (max-width: 1200px) 1200px, 1920px", H = /* @__PURE__ */ new Map();
5
+ function te(i, e = "") {
6
+ const c = i.toLowerCase(), n = e.toLowerCase();
7
+ return !!(c.includes("hero") || c.includes("banner") || n.includes("hero") || n.includes("banner") || n.includes("h-screen") || n.includes("h-full"));
8
8
  }
9
- function H(r, e, i = null) {
10
- const n = r.replace(/\.(jpe?g|png|webp)$/i, ""), h = i ? `.${i}` : r.match(/\.(jpe?g|png|webp)$/i)?.[0] || ".jpg";
11
- return e.map((l) => `${n}-${l}w${h} ${l}w`).join(", ");
9
+ function O(i, e, c = null) {
10
+ const n = i.replace(/\.(jpe?g|png|webp)$/i, ""), f = c ? `.${c}` : i.match(/\.(jpe?g|png|webp)$/i)?.[0] || ".jpg";
11
+ return e.map((l) => `${n}-${l}w${f} ${l}w`).join(", ");
12
12
  }
13
- function B(r) {
13
+ function oe(i) {
14
14
  const {
15
15
  src: e = "",
16
- alt: i = "",
16
+ alt: c = "",
17
17
  priority: n,
18
- widths: h = K,
19
- sizes: l = Z,
20
- className: p = "",
21
- style: L = {},
22
- loading: $,
23
- decoding: E = "async",
24
- fetchpriority: v,
25
- ...x
26
- } = r || {};
27
- if (typeof window < "u" && (window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1"))
28
- return /* @__PURE__ */ g(
18
+ widths: f = Y,
19
+ sizes: l = ee,
20
+ className: u = "",
21
+ style: F = {},
22
+ width: v,
23
+ height: $,
24
+ loading: A,
25
+ decoding: j = "async",
26
+ fetchpriority: d,
27
+ ...k
28
+ } = i || {}, U = typeof window > "u", S = !U && typeof document < "u" && typeof HTMLElement < "u" && document.createElement("div") instanceof HTMLElement, x = S && (window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1"), W = n ?? te(e, u), a = A || (W ? "eager" : "lazy"), P = d || (W ? "high" : void 0), [E, C] = M(null);
29
+ _(() => {
30
+ if (!S || x || !e) return;
31
+ const r = new window.Image();
32
+ r.onload = () => {
33
+ C({
34
+ width: r.naturalWidth,
35
+ height: r.naturalHeight
36
+ });
37
+ }, r.src = e;
38
+ }, [e, S, x]);
39
+ const s = X(() => E ? f.filter((r) => E.width >= r) : f, [E, f]), [B, D] = M(null);
40
+ _(() => {
41
+ if (!S || x) return;
42
+ let r = !1;
43
+ return (async () => {
44
+ const y = e.replace(/\.(jpe?g|png|webp)$/i, ""), T = e.match(/\.(jpe?g|png|webp)$/i)?.[0] || ".jpg", R = [];
45
+ for (const L of s) {
46
+ const I = `${y}-${L}w${T}`;
47
+ if (H.has(I)) {
48
+ H.get(I) && R.push(L);
49
+ continue;
50
+ }
51
+ try {
52
+ const K = await fetch(I, { method: "HEAD" });
53
+ H.set(I, K.ok), K.ok && R.push(L);
54
+ } catch {
55
+ H.set(I, !1);
56
+ }
57
+ }
58
+ r || D(
59
+ R.length > 0 ? R : s
60
+ );
61
+ })(), () => {
62
+ r = !0;
63
+ };
64
+ }, [e, s, S, x]);
65
+ const z = B ?? s, b = {};
66
+ v != null && (b.width = v), $ != null && (b.height = $), E && v == null && $ == null && (b.width = E.width, b.height = E.height);
67
+ const o = {
68
+ maxWidth: "100%",
69
+ height: "auto",
70
+ ...F
71
+ };
72
+ if (x)
73
+ return /* @__PURE__ */ m(
29
74
  "img",
30
75
  {
31
76
  src: e,
32
- alt: i,
33
- loading: $ || "lazy",
34
- decoding: E,
35
- fetchPriority: v,
36
- className: p,
37
- style: L,
38
- ...x
77
+ alt: c,
78
+ loading: a,
79
+ decoding: j,
80
+ fetchPriority: P,
81
+ className: u,
82
+ style: o,
83
+ ...b,
84
+ ...k
39
85
  }
40
86
  );
41
- const [T, D] = I(null), S = e && typeof window < "u";
42
- O(() => {
43
- if (!S) return;
44
- const y = new B();
45
- y.onload = () => {
46
- D({
47
- width: y.naturalWidth,
48
- height: y.naturalHeight
49
- });
50
- }, y.src = e;
51
- }, [e, S]);
52
- const b = T ? h.filter((y) => T.width >= y) : h, [c, k] = I(b);
53
- O(() => {
54
- (async () => {
55
- if (typeof window > "u") {
56
- k(b);
57
- return;
58
- }
59
- const U = e.replace(/\.(jpe?g|png|webp)$/i, ""), o = e.match(/\.(jpe?g|png|webp)$/i)?.[0] || ".jpg", a = [];
60
- for (const w of b) {
61
- const f = `${U}-${w}w${o}`;
62
- try {
63
- (await fetch(f, { method: "HEAD" })).ok && a.push(w);
64
- } catch {
87
+ if (U)
88
+ return /* @__PURE__ */ q("picture", { "data-routerino-image": "true", "data-original-src": e, children: [
89
+ /* @__PURE__ */ m(
90
+ "source",
91
+ {
92
+ srcSet: O(e, f, "webp"),
93
+ type: "image/webp",
94
+ sizes: l
65
95
  }
66
- }
67
- a.length === 0 && b.length > 0 && a.push(Math.min(...b)), k(a);
68
- })();
69
- }, [e, b]);
70
- const P = n ?? J(e, p), W = $ || (P ? "eager" : "lazy"), s = v || (P ? "high" : void 0), j = H(e, c, "webp"), A = H(e, c);
96
+ ),
97
+ /* @__PURE__ */ m(
98
+ "img",
99
+ {
100
+ src: e,
101
+ alt: c,
102
+ srcSet: O(e, f),
103
+ sizes: l,
104
+ loading: a,
105
+ decoding: "async",
106
+ fetchPriority: P,
107
+ className: u,
108
+ style: o,
109
+ ...b,
110
+ ...k
111
+ }
112
+ )
113
+ ] });
114
+ const p = O(e, z, "webp"), g = O(e, z);
71
115
  return /* @__PURE__ */ q("picture", { "data-routerino-image": "true", "data-original-src": e, children: [
72
- /* @__PURE__ */ g("source", { srcSet: j, type: "image/webp", sizes: l }),
73
- /* @__PURE__ */ g(
116
+ /* @__PURE__ */ m("source", { srcSet: p, type: "image/webp", sizes: l }),
117
+ /* @__PURE__ */ m(
74
118
  "img",
75
119
  {
76
120
  src: e,
77
- alt: i,
78
- srcSet: A,
121
+ alt: c,
122
+ srcSet: g,
79
123
  sizes: l,
80
- loading: W,
81
- decoding: E,
82
- fetchPriority: s,
83
- className: p,
84
- style: L,
85
- ...x
124
+ loading: a,
125
+ decoding: j,
126
+ fetchPriority: P,
127
+ className: u,
128
+ style: o,
129
+ ...b,
130
+ ...k
86
131
  }
87
132
  )
88
133
  ] });
89
134
  }
90
- B.propTypes = {
135
+ oe.propTypes = {
91
136
  /** Image source URL (required) */
92
137
  src: t.string.isRequired,
93
138
  /** Alt text for accessibility (required) */
@@ -102,6 +147,10 @@ B.propTypes = {
102
147
  className: t.string,
103
148
  /** Inline styles */
104
149
  style: t.object,
150
+ /** Explicit width for CLS prevention */
151
+ width: t.number,
152
+ /** Explicit height for CLS prevention */
153
+ height: t.number,
105
154
  /** Loading behavior (auto-set based on priority) */
106
155
  loading: t.oneOf(["lazy", "eager"]),
107
156
  /** Decode timing */
@@ -109,54 +158,121 @@ B.propTypes = {
109
158
  /** Fetch priority (auto-set based on priority) */
110
159
  fetchpriority: t.oneOf(["high", "low", "auto"])
111
160
  };
112
- const z = _(null);
113
- function oe() {
114
- const r = G(z);
115
- if (!r)
161
+ const ne = [
162
+ ".pdf",
163
+ ".doc",
164
+ ".docx",
165
+ ".xls",
166
+ ".xlsx",
167
+ ".ppt",
168
+ ".pptx",
169
+ ".odt",
170
+ ".ods",
171
+ ".odp",
172
+ ".rtf",
173
+ ".csv",
174
+ ".txt",
175
+ ".md",
176
+ ".png",
177
+ ".jpg",
178
+ ".jpeg",
179
+ ".gif",
180
+ ".svg",
181
+ ".webp",
182
+ ".avif",
183
+ ".ico",
184
+ ".bmp",
185
+ ".tiff",
186
+ ".tif",
187
+ ".mp4",
188
+ ".webm",
189
+ ".ogv",
190
+ ".mov",
191
+ ".avi",
192
+ ".mkv",
193
+ ".flv",
194
+ ".mp3",
195
+ ".wav",
196
+ ".ogg",
197
+ ".flac",
198
+ ".aac",
199
+ ".m4a",
200
+ ".wma",
201
+ ".woff",
202
+ ".woff2",
203
+ ".ttf",
204
+ ".eot",
205
+ ".zip",
206
+ ".tar",
207
+ ".gz",
208
+ ".bz2",
209
+ ".7z",
210
+ ".rar",
211
+ ".xz",
212
+ ".zst",
213
+ ".epub",
214
+ ".mobi",
215
+ ".json",
216
+ ".xml",
217
+ ".yml",
218
+ ".yaml",
219
+ ".css",
220
+ ".js",
221
+ ".map",
222
+ ".wasm"
223
+ ], N = Z(null);
224
+ function ue() {
225
+ const i = Q(N);
226
+ if (!i)
116
227
  throw new Error(
117
228
  "useRouterino must be used within a Routerino router. Make sure your component is rendered inside a <Routerino> component."
118
229
  );
119
- return r;
230
+ return i;
120
231
  }
121
- function u({ tag: r = "meta", soft: e = !1, ...i }) {
122
- const n = Object.keys(i);
123
- if (n.length < 1)
232
+ function h({
233
+ tag: i = "meta",
234
+ soft: e = !1,
235
+ innerHTML: c,
236
+ ...n
237
+ }) {
238
+ const f = Object.keys(n);
239
+ if (f.length < 1)
124
240
  return console.error(
125
- `[Routerino] updateHeadTag() received no attributes to set for ${r} tag`
241
+ `[Routerino] updateHeadTag() received no attributes to set for ${i} tag`
126
242
  );
127
- let h = null;
128
- for (let l = 0; l < n.length && (n[l] !== "content" && (h = document.querySelector(
129
- `${r}[${n[l]}='${i[n[l]]}']`
130
- )), !h); l++)
243
+ let l = null;
244
+ for (let u = 0; u < f.length && (f[u] !== "content" && (l = document.querySelector(
245
+ `${i}[${f[u]}='${n[f[u]]}']`
246
+ )), !l); u++)
131
247
  ;
132
- h && e || (h || (h = document.createElement(r)), n.forEach((l) => h.setAttribute(l, i[l])), document.querySelector("head").appendChild(h));
248
+ l && e || (l || (l = document.createElement(i)), f.forEach((u) => l.setAttribute(u, n[u])), c !== void 0 && (l.innerHTML = c), document.querySelector("head").appendChild(l));
133
249
  }
134
- function N({ routePattern: r, currentRoute: e }) {
135
- let i = {}, n = r.split("/"), h = e.split("/");
136
- return n.forEach((l, p) => {
137
- l.startsWith(":") && (i[l.slice(1)] = h[p]);
138
- }), i;
250
+ function re({ routePattern: i, currentRoute: e }) {
251
+ let c = {}, n = i.split("/"), f = e.split("/");
252
+ return n.forEach((l, u) => {
253
+ l.startsWith(":") && (c[l.slice(1)] = f[u]);
254
+ }), c;
139
255
  }
140
- class M extends V {
256
+ class G extends J {
141
257
  constructor(e) {
142
258
  super(e), this.state = { hasError: !1 };
143
259
  }
144
260
  static getDerivedStateFromError() {
145
261
  return { hasError: !0 };
146
262
  }
147
- componentDidCatch(e, i) {
263
+ componentDidCatch(e, c) {
148
264
  this.props.debug && (console.group(
149
265
  "%c[Routerino]%c Error Boundary Caught an Error",
150
266
  "color: #ff6b6b; font-weight: bold",
151
267
  "",
152
268
  e
153
- ), console.error("[Routerino] Component Stack:", i.componentStack), this.props.routePath && console.error("[Routerino] Failed Route:", this.props.routePath), console.error("[Routerino] Error occurred at:", (/* @__PURE__ */ new Date()).toISOString()), console.groupEnd()), document.title = this.props.errorTitleString, this.props.usePrerenderTags && u({ name: "prerender-status-code", content: "500" });
269
+ ), console.error("[Routerino] Component Stack:", c.componentStack), this.props.routePath && console.error("[Routerino] Failed Route:", this.props.routePath), console.error("[Routerino] Error occurred at:", (/* @__PURE__ */ new Date()).toISOString()), console.groupEnd()), document.title = this.props.errorTitleString, this.props.usePrerenderTags && h({ name: "prerender-status-code", content: "500" });
154
270
  }
155
271
  render() {
156
272
  return this.state.hasError ? this.props.fallback : this.props.children;
157
273
  }
158
274
  }
159
- M.propTypes = {
275
+ G.propTypes = {
160
276
  /** The child components to render when there's no error */
161
277
  children: t.node,
162
278
  /** The fallback UI to display when an error is caught */
@@ -170,66 +286,67 @@ M.propTypes = {
170
286
  /** Whether to log debug messages to console (optional) */
171
287
  debug: t.bool
172
288
  };
173
- function Q({
174
- routes: r = [
289
+ function ie({
290
+ routes: i = [
175
291
  {
176
292
  path: "/",
177
- element: /* @__PURE__ */ g("p", { children: "This is the default route. Pass an array of routes to the Routerino component in order to configure your own pages. Each route is a dictionary with at least `path` and `element` defined." }),
293
+ element: /* @__PURE__ */ m("p", { children: "This is the default route. Pass an array of routes to the Routerino component in order to configure your own pages. Each route is a dictionary with at least `path` and `element` defined." }),
178
294
  title: "Routerino default route example",
179
295
  description: "The default route example description.",
180
296
  tags: [{ property: "og:locale", content: "en_US" }]
181
297
  }
182
298
  ],
183
- notFoundTemplate: e = /* @__PURE__ */ q(F, { children: [
184
- /* @__PURE__ */ g("p", { children: "No page found for this URL. [404]" }),
185
- /* @__PURE__ */ g("p", { children: /* @__PURE__ */ g("a", { href: "/", children: "Home" }) })
299
+ notFoundTemplate: e = /* @__PURE__ */ q(V, { children: [
300
+ /* @__PURE__ */ m("p", { children: "No page found for this URL. [404]" }),
301
+ /* @__PURE__ */ m("p", { children: /* @__PURE__ */ m("a", { href: "/", children: "Home" }) })
186
302
  ] }),
187
- notFoundTitle: i = "Page not found [404]",
188
- errorTemplate: n = /* @__PURE__ */ q(F, { children: [
189
- /* @__PURE__ */ g("p", { children: "Page failed to load. [500]" }),
190
- /* @__PURE__ */ g("p", { children: /* @__PURE__ */ g("a", { href: "/", children: "Home" }) })
303
+ notFoundTitle: c = "Page not found [404]",
304
+ errorTemplate: n = /* @__PURE__ */ q(V, { children: [
305
+ /* @__PURE__ */ m("p", { children: "Page failed to load. [500]" }),
306
+ /* @__PURE__ */ m("p", { children: /* @__PURE__ */ m("a", { href: "/", children: "Home" }) })
191
307
  ] }),
192
- errorTitle: h = "Page error [500]",
308
+ errorTitle: f = "Page error [500]",
193
309
  useTrailingSlash: l = !0,
194
- usePrerenderTags: p = !1,
195
- baseUrl: L = null,
196
- title: $ = "",
197
- separator: E = " | ",
198
- imageUrl: v = null,
199
- touchIconUrl: x = null,
200
- debug: d = !1
310
+ usePrerenderTags: u = !1,
311
+ baseUrl: F = null,
312
+ title: v = "",
313
+ separator: $ = " | ",
314
+ imageUrl: A = null,
315
+ touchIconUrl: j = null,
316
+ debug: d = !1,
317
+ ignorePatterns: k = []
201
318
  }) {
202
- const T = `${h}${E}${$}`, D = `${i}${E}${$}`;
319
+ const U = [f, v].filter(Boolean).join($), S = [c, v].filter(Boolean).join($);
203
320
  try {
204
321
  if (d) {
205
- const o = r.map((w) => w.path), a = o.filter(
206
- (w, f) => o.indexOf(w) !== f
322
+ const o = i.map((g) => g.path), p = o.filter(
323
+ (g, r) => o.indexOf(g) !== r
207
324
  );
208
- a.length > 0 && (console.warn(
325
+ p.length > 0 && (console.warn(
209
326
  "%c[Routerino]%c Duplicate route paths detected:",
210
327
  "color: #f59e0b; font-weight: bold",
211
328
  "",
212
- [...new Set(a)]
329
+ [...new Set(p)]
213
330
  ), console.warn(
214
331
  "%c[Routerino]%c The first matching route will be used",
215
332
  "color: #f59e0b; font-weight: bold",
216
333
  ""
217
334
  ));
218
335
  }
219
- const [S, b] = I(window?.location?.href ?? "/");
220
- O(() => {
336
+ const [x, W] = M(window?.location?.href ?? "/");
337
+ _(() => {
221
338
  if (typeof window > "u" || typeof document > "u")
222
339
  return;
223
- const o = (w) => {
340
+ const o = (g) => {
224
341
  d && console.debug(
225
342
  "%c[Routerino]%c click occurred",
226
343
  "color: #6b7280; font-weight: bold",
227
344
  ""
228
345
  );
229
- let f = w.target;
230
- for (; f.tagName !== "A" && f.parentElement; )
231
- f = f.parentElement;
232
- if (f.tagName !== "A") {
346
+ let r = g.target;
347
+ for (; r.tagName !== "A" && r.parentElement; )
348
+ r = r.parentElement;
349
+ if (r.tagName !== "A") {
233
350
  d && console.debug(
234
351
  "%c[Routerino]%c no anchor tag found during click",
235
352
  "color: #6b7280; font-weight: bold",
@@ -237,8 +354,10 @@ function Q({
237
354
  );
238
355
  return;
239
356
  }
240
- const m = f.getAttribute("href") || f.href;
241
- if (!m) {
357
+ if (g.defaultPrevented || g.button !== 0 || g.ctrlKey || g.metaKey || g.shiftKey || g.altKey || r.getAttribute("target") === "_blank" || r.hasAttribute("download") || r.getAttribute("rel") === "external")
358
+ return;
359
+ const w = r.getAttribute("href") || r.href;
360
+ if (!w) {
242
361
  d && console.debug(
243
362
  "%c[Routerino]%c anchor tag has no href",
244
363
  "color: #6b7280; font-weight: bold",
@@ -246,12 +365,12 @@ function Q({
246
365
  );
247
366
  return;
248
367
  }
249
- if (!/^(https?:\/\/|\/|\.\/|\.\.\/|[^:]+$)/i.test(m)) {
368
+ if (!/^(https?:\/\/|\/|\.\/|\.\.\/|[^:]+$)/i.test(w)) {
250
369
  d && console.debug(
251
370
  "%c[Routerino]%c skipping non-http URL:",
252
371
  "color: #6b7280; font-weight: bold",
253
372
  "",
254
- m
373
+ w
255
374
  );
256
375
  return;
257
376
  }
@@ -259,67 +378,97 @@ function Q({
259
378
  "%c[Routerino]%c click target href:",
260
379
  "color: #6b7280; font-weight: bold",
261
380
  "",
262
- m
381
+ w
263
382
  );
264
- let R;
383
+ let y;
265
384
  try {
266
- R = new URL(m, window.location.href);
267
- } catch (C) {
385
+ y = new URL(w, window.location.href);
386
+ } catch (T) {
268
387
  d && console.debug(
269
388
  "%c[Routerino]%c Invalid URL:",
270
389
  "color: #6b7280; font-weight: bold",
271
390
  "",
272
- m,
273
- C
391
+ w,
392
+ T
274
393
  );
275
394
  return;
276
395
  }
277
- d && console.debug(
396
+ if (d && console.debug(
278
397
  "%c[Routerino]%c targetUrl:",
279
398
  "color: #6b7280; font-weight: bold",
280
399
  "",
281
- R,
400
+ y,
282
401
  "current:",
283
402
  window.location
284
- ), R && window.location.origin === R.origin ? (d && console.debug(
285
- "%c[Routerino]%c target link is same origin, will use push-state transitioning",
286
- "color: #6b7280; font-weight: bold",
287
- ""
288
- ), w.preventDefault(), f.href !== window.location.href && (b(f.href), window.history.pushState({}, "", f.href)), window.scrollTo({
289
- top: 0,
290
- behavior: "auto"
291
- })) : d && console.debug(
403
+ ), y && window.location.origin === y.origin) {
404
+ const T = y.pathname.toLowerCase();
405
+ if (ne.some((R) => T.endsWith(R))) {
406
+ d && console.debug(
407
+ "%c[Routerino]%c skipping file extension link:",
408
+ "color: #6b7280; font-weight: bold",
409
+ "",
410
+ w
411
+ );
412
+ return;
413
+ }
414
+ if (k.length > 0 && k.some(
415
+ (R) => new RegExp(R, "i").test(w)
416
+ )) {
417
+ d && console.debug(
418
+ "%c[Routerino]%c skipping ignored link pattern:",
419
+ "color: #6b7280; font-weight: bold",
420
+ "",
421
+ w
422
+ );
423
+ return;
424
+ }
425
+ if (d && console.debug(
426
+ "%c[Routerino]%c target link is same origin, will use push-state transitioning",
427
+ "color: #6b7280; font-weight: bold",
428
+ ""
429
+ ), g.preventDefault(), r.href !== window.location.href && (W(r.href), window.history.pushState({}, "", r.href)), r.hash) {
430
+ const R = decodeURIComponent(r.hash.slice(1));
431
+ setTimeout(() => {
432
+ const L = document.getElementById(R);
433
+ L ? L.scrollIntoView({ behavior: "auto" }) : window.scrollTo({ top: 0, behavior: "auto" });
434
+ }, 0);
435
+ } else
436
+ window.scrollTo({
437
+ top: 0,
438
+ behavior: "auto"
439
+ });
440
+ } else d && console.debug(
292
441
  "%c[Routerino]%c target link does not share an origin, standard browser link handling applies",
293
442
  "color: #6b7280; font-weight: bold",
294
443
  ""
295
444
  );
296
445
  };
297
446
  document.addEventListener("click", o);
298
- const a = () => {
447
+ const p = () => {
299
448
  d && console.debug(
300
449
  "%c[Routerino]%c route change ->",
301
450
  "color: #6b7280; font-weight: bold",
302
451
  "",
303
452
  window.location.pathname
304
- ), b(window.location.href);
453
+ ), W(window.location.href);
305
454
  };
306
- return window.addEventListener("popstate", a), () => {
307
- document.removeEventListener("click", o), window.removeEventListener("popstate", a);
455
+ return window.addEventListener("popstate", p), () => {
456
+ document.removeEventListener("click", o), window.removeEventListener("popstate", p);
308
457
  };
309
- }, [S]);
310
- let c = window?.location?.pathname ?? "/";
311
- (c === "/index.html" || c === "") && (c = "/");
312
- const k = r.find((o) => o.path === c), P = r.find(
313
- (o) => `${o.path}/` === c || o.path === `${c}/`
314
- ), W = r.find((o) => {
315
- const a = o.path.endsWith("/") ? o.path.slice(0, -1) : o.path, w = c.endsWith("/") ? c.slice(0, -1) : c, f = a.split("/").filter(Boolean), m = w.split("/").filter(Boolean);
316
- return f.length !== m.length ? !1 : f.every((R, C) => R.startsWith(":") ? !0 : R === m[C]);
317
- }), s = k ?? P ?? W;
458
+ }, [x, k]);
459
+ let a = window?.location?.pathname ?? "/";
460
+ (a === "/index.html" || a === "") && (a = "/");
461
+ const P = i.find((o) => o.path === a), E = i.find(
462
+ (o) => `${o.path}/` === a || o.path === `${a}/`
463
+ ), C = i.find((o) => {
464
+ const p = o.path.endsWith("/") ? o.path.slice(0, -1) : o.path, g = a.endsWith("/") ? a.slice(0, -1) : a, r = p.split("/").filter(Boolean), w = g.split("/").filter(Boolean);
465
+ return r.length !== w.length ? !1 : r.every((y, T) => y.startsWith(":") ? !0 : y === w[T]);
466
+ }), s = P ?? E ?? C;
318
467
  if (d && console.debug(
319
468
  "%c[Routerino]%c Route matching:",
320
469
  "color: #6b7280; font-weight: bold",
321
470
  "",
322
- { match: s, exactMatch: k, addSlashMatch: P, paramsMatch: W }
471
+ { match: s, exactMatch: P, addSlashMatch: E, paramsMatch: C }
323
472
  ), !s)
324
473
  return d && (console.group(
325
474
  "%c[Routerino]%c 404 - No matching route",
@@ -329,71 +478,71 @@ function Q({
329
478
  "%c[Routerino]%c Requested path:",
330
479
  "color: #f59e0b; font-weight: bold",
331
480
  "",
332
- c
481
+ a
333
482
  ), console.warn(
334
483
  "%c[Routerino]%c Available routes:",
335
484
  "color: #f59e0b; font-weight: bold",
336
485
  "",
337
- r.map((o) => o.path)
338
- ), console.groupEnd()), document.title = D, p && u({ name: "prerender-status-code", content: "404" }), e;
339
- if (p) {
486
+ i.map((o) => o.path)
487
+ ), console.groupEnd()), document.title = S, u && h({ name: "prerender-status-code", content: "404" }), e;
488
+ if (u) {
340
489
  const o = document.querySelector(
341
490
  'meta[name="prerender-status-code"]'
342
491
  );
343
492
  o && o.remove();
344
- const a = document.querySelector(
493
+ const p = document.querySelector(
345
494
  'meta[name="prerender-header"]'
346
495
  );
347
- a && a.remove();
496
+ p && p.remove();
348
497
  }
349
- const j = l && !c.endsWith("/") && c !== "/", A = !l && c.endsWith("/") && c !== "/", y = j ? `${c}/` : A ? c.slice(0, -1) : c, U = `${L ?? window?.location?.origin ?? ""}${y}`;
350
- if (s.title) {
351
- const o = `${s.title}${E}${$}`;
352
- document.title = o, u({
353
- tag: "link",
354
- rel: "canonical",
355
- href: U
356
- }), s.tags?.find(({ property: a }) => a === "og:title") || u({
498
+ const B = l && !a.endsWith("/") && a !== "/", D = !l && a.endsWith("/") && a !== "/", z = B ? `${a}/` : D ? a.slice(0, -1) : a, b = `${F ?? window?.location?.origin ?? ""}${z}`;
499
+ if (s.title || v) {
500
+ const o = [s.title, v].filter(Boolean).join($);
501
+ document.title = o, s.tags?.find(({ property: p }) => p === "og:title") || h({
357
502
  property: "og:title",
358
503
  content: o
359
- }), s.tags?.find(({ property: a }) => a === "og:url") || u({
360
- property: "og:url",
361
- content: U
362
504
  });
363
505
  }
364
- if (s.description && (u({ name: "description", content: s.description }), s.tags?.find(({ property: o }) => o === "og:description") || u({
506
+ if (h({
507
+ tag: "link",
508
+ rel: "canonical",
509
+ href: b
510
+ }), s.tags?.find(({ property: o }) => o === "og:url") || h({
511
+ property: "og:url",
512
+ content: b
513
+ }), s.description && (h({ name: "description", content: s.description }), s.tags?.find(({ property: o }) => o === "og:description") || h({
365
514
  property: "og:description",
366
515
  content: s.description
367
- })), (v || s.imageUrl) && u({
516
+ })), (A || s.imageUrl) && h({
368
517
  property: "og:image",
369
- content: s.imageUrl ?? v
370
- }), s.tags?.find(({ property: o }) => o === "twitter:card") || u({
518
+ content: s.imageUrl ?? A
519
+ }), s.tags?.find(({ property: o }) => o === "twitter:card") || h({
371
520
  name: "twitter:card",
372
521
  content: "summary_large_image"
373
- }), x && u({
522
+ }), j && h({
374
523
  tag: "link",
375
524
  rel: "apple-touch-icon",
376
- href: x
377
- }), p && (j || A) && (u({ name: "prerender-status-code", content: "301" }), u({
525
+ href: j
526
+ }), u && (B || D) && (h({ name: "prerender-status-code", content: "301" }), h({
378
527
  name: "prerender-header",
379
- content: `Location: ${U}`
380
- })), s.tags && s.tags.length ? (s.tags.find(({ property: o }) => o === "og:type") || u({ property: "og:type", content: "website" }), s.tags.forEach((o) => u(o))) : u({ property: "og:type", content: "website" }), s.element) {
381
- const o = N({
528
+ content: `Location: ${b}`
529
+ })), s.tags && s.tags.length ? (s.tags.find(({ property: o }) => o === "og:type") || h({ property: "og:type", content: "website" }), s.tags.forEach((o) => h(o))) : h({ property: "og:type", content: "website" }), s.element) {
530
+ const o = re({
382
531
  routePattern: s.path,
383
- currentRoute: c
384
- }), a = {
385
- currentRoute: c,
532
+ currentRoute: a
533
+ }), p = {
534
+ currentRoute: a,
386
535
  params: o,
387
536
  routePattern: s.path,
388
- updateHeadTag: u
537
+ updateHeadTag: h
389
538
  };
390
- return /* @__PURE__ */ g(z.Provider, { value: a, children: /* @__PURE__ */ g(
391
- M,
539
+ return /* @__PURE__ */ m(N.Provider, { value: p, children: /* @__PURE__ */ m(
540
+ G,
392
541
  {
393
542
  fallback: n,
394
- errorTitleString: T,
395
- usePrerenderTags: p,
396
- routePath: c,
543
+ errorTitleString: U,
544
+ usePrerenderTags: u,
545
+ routePath: a,
397
546
  debug: d,
398
547
  children: s.element
399
548
  }
@@ -403,9 +552,9 @@ function Q({
403
552
  "%c[Routerino]%c No route found for",
404
553
  "color: #ff6b6b; font-weight: bold",
405
554
  "",
406
- c
407
- ), document.title = D, p && u({ name: "prerender-status-code", content: "404" }), e;
408
- } catch (S) {
555
+ a
556
+ ), document.title = S, u && h({ name: "prerender-status-code", content: "404" }), e;
557
+ } catch (x) {
409
558
  return d && (console.group(
410
559
  "%c[Routerino]%c Fatal Error",
411
560
  "color: #ff6b6b; font-weight: bold",
@@ -418,23 +567,23 @@ function Q({
418
567
  "%c[Routerino]%c Error:",
419
568
  "color: #ff6b6b; font-weight: bold",
420
569
  "",
421
- S
570
+ x
422
571
  ), console.error(
423
572
  "%c[Routerino]%c This typically means an issue with route configuration or router setup",
424
573
  "color: #ff6b6b; font-weight: bold",
425
574
  ""
426
- ), console.groupEnd()), p && u({ name: "prerender-status-code", content: "500" }), document.title = T, n;
575
+ ), console.groupEnd()), u && h({ name: "prerender-status-code", content: "500" }), document.title = U, n;
427
576
  }
428
577
  }
429
- const X = t.exact({
430
- path: (r, e, i) => {
431
- const n = r[e];
578
+ const ce = t.exact({
579
+ path: (i, e, c) => {
580
+ const n = i[e];
432
581
  return n == null ? new Error(
433
- `The prop \`${e}\` is marked as required in \`${i}\`, but its value is \`${n}\`.`
582
+ `The prop \`${e}\` is marked as required in \`${c}\`, but its value is \`${n}\`.`
434
583
  ) : typeof n != "string" ? new Error(
435
- `Invalid prop \`${e}\` of type \`${typeof n}\` supplied to \`${i}\`, expected \`string\`.`
584
+ `Invalid prop \`${e}\` of type \`${typeof n}\` supplied to \`${c}\`, expected \`string\`.`
436
585
  ) : n.startsWith("/") ? null : new Error(
437
- `Invalid prop \`${e}\` value \`${n}\` supplied to \`${i}\`. Route paths must start with a forward slash (/).`
586
+ `Invalid prop \`${e}\` value \`${n}\` supplied to \`${c}\`. Route paths must start with a forward slash (/).`
438
587
  );
439
588
  },
440
589
  element: t.element.isRequired,
@@ -443,8 +592,8 @@ const X = t.exact({
443
592
  tags: t.arrayOf(t.object),
444
593
  imageUrl: t.string
445
594
  });
446
- Q.propTypes = {
447
- routes: t.arrayOf(X),
595
+ ie.propTypes = {
596
+ routes: t.arrayOf(ce),
448
597
  title: t.string,
449
598
  separator: t.string,
450
599
  notFoundTemplate: t.element,
@@ -453,29 +602,30 @@ Q.propTypes = {
453
602
  errorTitle: t.string,
454
603
  useTrailingSlash: t.bool,
455
604
  usePrerenderTags: t.bool,
456
- baseUrl: (r, e, i) => {
457
- const n = r[e];
605
+ baseUrl: (i, e, c) => {
606
+ const n = i[e];
458
607
  if (n != null) {
459
608
  if (typeof n != "string")
460
609
  return new Error(
461
- `Invalid prop \`${e}\` of type \`${typeof n}\` supplied to \`${i}\`, expected \`string\`.`
610
+ `Invalid prop \`${e}\` of type \`${typeof n}\` supplied to \`${c}\`, expected \`string\`.`
462
611
  );
463
612
  if (n.endsWith("/"))
464
613
  return new Error(
465
- `Invalid prop \`${e}\` supplied to \`${i}\`. The baseUrl should not end with a slash. Got: "${n}"`
614
+ `Invalid prop \`${e}\` supplied to \`${c}\`. The baseUrl should not end with a slash. Got: "${n}"`
466
615
  );
467
616
  }
468
617
  return null;
469
618
  },
470
619
  imageUrl: t.string,
471
620
  touchIconUrl: t.string,
472
- debug: t.bool
621
+ debug: t.bool,
622
+ ignorePatterns: t.arrayOf(t.string)
473
623
  };
474
624
  export {
475
- M as ErrorBoundary,
476
- B as Image,
477
- Q as Routerino,
478
- Q as default,
479
- u as updateHeadTag,
480
- oe as useRouterino
625
+ G as ErrorBoundary,
626
+ oe as Image,
627
+ ie as Routerino,
628
+ ie as default,
629
+ h as updateHeadTag,
630
+ ue as useRouterino
481
631
  };