@real-router/solid 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +11 -0
  2. package/dist/cjs/index.js +168 -65
  3. package/dist/esm/index.mjs +169 -66
  4. package/dist/types/RouterProvider.d.ts +1 -0
  5. package/dist/types/RouterProvider.d.ts.map +1 -1
  6. package/dist/types/components/Link.d.ts.map +1 -1
  7. package/dist/types/components/RouteView/components.d.ts.map +1 -1
  8. package/dist/types/components/RouteView/helpers.d.ts +2 -4
  9. package/dist/types/components/RouteView/helpers.d.ts.map +1 -1
  10. package/dist/types/components/RouterErrorBoundary.d.ts.map +1 -1
  11. package/dist/types/createSignalFromSource.d.ts.map +1 -1
  12. package/dist/types/createStoreFromSource.d.ts.map +1 -1
  13. package/dist/types/dom-utils/index.d.ts +1 -1
  14. package/dist/types/dom-utils/index.d.ts.map +1 -1
  15. package/dist/types/dom-utils/link-utils.d.ts +2 -1
  16. package/dist/types/dom-utils/link-utils.d.ts.map +1 -1
  17. package/dist/types/dom-utils/route-announcer.d.ts.map +1 -1
  18. package/dist/types/hooks/sharedNodeSource.d.ts +4 -0
  19. package/dist/types/hooks/sharedNodeSource.d.ts.map +1 -0
  20. package/dist/types/hooks/useRouteNode.d.ts.map +1 -1
  21. package/dist/types/hooks/useRouteNodeStore.d.ts.map +1 -1
  22. package/dist/types/hooks/useRouteStore.d.ts.map +1 -1
  23. package/dist/types/hooks/useRouterTransition.d.ts.map +1 -1
  24. package/package.json +7 -7
  25. package/src/RouterProvider.tsx +1 -1
  26. package/src/components/Link.tsx +51 -8
  27. package/src/components/RouteView/RouteView.tsx +13 -13
  28. package/src/components/RouteView/components.tsx +12 -6
  29. package/src/components/RouteView/helpers.tsx +19 -17
  30. package/src/components/RouterErrorBoundary.tsx +4 -6
  31. package/src/createSignalFromSource.ts +9 -1
  32. package/src/createStoreFromSource.ts +1 -3
  33. package/src/hooks/sharedNodeSource.ts +30 -0
  34. package/src/hooks/useRouteNode.tsx +2 -4
  35. package/src/hooks/useRouteNodeStore.tsx +2 -3
  36. package/src/hooks/useRouteStore.tsx +0 -8
  37. package/src/hooks/useRouterTransition.tsx +15 -3
@@ -1,13 +1,15 @@
1
1
  import { createComponent, memo, spread, mergeProps as mergeProps$1, insert, template } from 'solid-js/web';
2
2
  import { createRouteNodeSource, createActiveRouteSource, createErrorSource, createRouteSource, createTransitionSource } from '@real-router/sources';
3
- import { Suspense, createSignal, onCleanup, createContext, useContext, children, mergeProps, splitProps, createMemo, createEffect, onMount, createSelector } from 'solid-js';
3
+ import { Suspense, createSignal, onCleanup, createContext, useContext, children, createMemo, mergeProps, splitProps, createEffect, Show, onMount, createSelector } from 'solid-js';
4
4
  import { getPluginApi } from '@real-router/core/api';
5
5
  import { startsWithSegment, getRouteUtils } from '@real-router/route-utils';
6
6
  import { createStore, reconcile } from 'solid-js/store';
7
7
  import { UNKNOWN_ROUTE, getNavigator } from '@real-router/core';
8
8
 
9
- const MATCH_MARKER = Symbol.for("RouteView.Match");
10
- const NOT_FOUND_MARKER = Symbol.for("RouteView.NotFound");
9
+ // Local (non-global) Symbols — Symbol.for() would expose markers to spoofing
10
+ // via the global Symbol registry. See Gotchas section "RouteView Marker Objects".
11
+ const MATCH_MARKER = Symbol("RouteView.Match");
12
+ const NOT_FOUND_MARKER = Symbol("RouteView.NotFound");
11
13
  function Match(props) {
12
14
  const result = {
13
15
  $$type: MATCH_MARKER,
@@ -18,6 +20,10 @@ function Match(props) {
18
20
  return props.children;
19
21
  }
20
22
  };
23
+
24
+ // Marker object is identified by $$type Symbol in RouteView/helpers.tsx,
25
+ // not rendered as JSX. Cast required because JSX.Element does not include
26
+ // arbitrary marker shapes.
21
27
  return result;
22
28
  }
23
29
  Match.displayName = "RouteView.Match";
@@ -28,6 +34,8 @@ function NotFound(props) {
28
34
  return props.children;
29
35
  }
30
36
  };
37
+
38
+ // See Match for the marker-pattern rationale.
31
39
  return result;
32
40
  }
33
41
  NotFound.displayName = "RouteView.NotFound";
@@ -67,43 +75,65 @@ function buildRenderList(elements, routeName, nodeName) {
67
75
  notFoundChildren = child.children;
68
76
  continue;
69
77
  }
78
+ if (activeMatchFound) {
79
+ continue;
80
+ }
70
81
  const {
71
82
  segment,
72
83
  exact,
73
84
  fallback
74
85
  } = child;
75
86
  const fullSegmentName = nodeName ? `${nodeName}.${segment}` : segment;
76
- const isActive = !activeMatchFound && isSegmentMatch(routeName, fullSegmentName, exact);
77
- if (isActive) {
78
- activeMatchFound = true;
79
- const matchContent = child.children;
80
- const content = fallback === undefined ? matchContent : createComponent(Suspense, {
81
- fallback: fallback,
82
- children: matchContent
83
- });
84
- rendered.push(content);
87
+ if (!isSegmentMatch(routeName, fullSegmentName, exact)) {
88
+ continue;
85
89
  }
90
+ activeMatchFound = true;
91
+ rendered.push(fallback === undefined ? child.children : createComponent(Suspense, {
92
+ fallback: fallback,
93
+ get children() {
94
+ return child.children;
95
+ }
96
+ }));
86
97
  }
87
98
  if (!activeMatchFound && routeName === UNKNOWN_ROUTE && notFoundChildren !== null) {
88
99
  rendered.push(notFoundChildren);
89
100
  }
90
- return {
91
- rendered,
92
- activeMatchFound
93
- };
101
+ return rendered;
94
102
  }
95
103
 
96
104
  function createSignalFromSource(source) {
97
105
  const [value, setValue] = createSignal(source.getSnapshot());
106
+ const sync = () => source.getSnapshot();
98
107
  const unsubscribe = source.subscribe(() => {
99
- setValue(() => source.getSnapshot());
108
+ setValue(sync);
100
109
  });
110
+
111
+ // Re-read after subscribe: lazy sources reconcile their snapshot in
112
+ // onFirstSubscribe (when reused after disconnect via cache). Listener is not
113
+ // notified for that internal update, so we must sync the signal manually.
114
+ // No-op when snapshot is unchanged (signal equality check).
115
+ setValue(sync);
101
116
  onCleanup(() => {
102
117
  unsubscribe();
103
118
  });
104
119
  return value;
105
120
  }
106
121
 
122
+ const cache$2 = new WeakMap();
123
+ function getOrCreateNodeSource(router, nodeName) {
124
+ let perRouter = cache$2.get(router);
125
+ if (!perRouter) {
126
+ perRouter = new Map();
127
+ cache$2.set(router, perRouter);
128
+ }
129
+ let source = perRouter.get(nodeName);
130
+ if (!source) {
131
+ source = createRouteNodeSource(router, nodeName);
132
+ perRouter.set(nodeName, source);
133
+ }
134
+ return source;
135
+ }
136
+
107
137
  const RouterContext = createContext(null);
108
138
  const RouteContext = createContext(null);
109
139
 
@@ -117,27 +147,24 @@ const useRouter = () => {
117
147
 
118
148
  function useRouteNode(nodeName) {
119
149
  const router = useRouter();
120
- const store = createRouteNodeSource(router, nodeName);
121
- return createSignalFromSource(store);
150
+ return createSignalFromSource(getOrCreateNodeSource(router, nodeName));
122
151
  }
123
152
 
124
153
  function RouteViewRoot(props) {
125
154
  const routeState = useRouteNode(props.nodeName);
126
155
  const resolved = children(() => props.children);
156
+ const elements = createMemo(() => {
157
+ const arr = [];
158
+ collectElements(resolved(), arr);
159
+ return arr;
160
+ });
127
161
  return memo(() => {
128
162
  const state = routeState();
129
163
  if (!state.route) {
130
164
  return null;
131
165
  }
132
- const elements = [];
133
- collectElements(resolved(), elements);
134
- const {
135
- rendered
136
- } = buildRenderList(elements, state.route.name, props.nodeName);
137
- if (rendered.length > 0) {
138
- return rendered;
139
- }
140
- return null;
166
+ const rendered = buildRenderList(elements(), state.route.name, props.nodeName);
167
+ return rendered.length > 0 ? rendered : null;
141
168
  });
142
169
  }
143
170
  RouteViewRoot.displayName = "RouteView";
@@ -163,14 +190,36 @@ const INTERNAL_ROUTE_PREFIX = "@@";
163
190
  const VISUALLY_HIDDEN = "position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);clip-path:inset(50%);white-space:nowrap;border:0";
164
191
  function createRouteAnnouncer(router, options) {
165
192
  const prefix = "Navigated to ";
193
+ const getCustomText = options?.getAnnouncementText;
166
194
  let isInitialNavigation = true;
167
195
  let isReady = false;
168
196
  let isDestroyed = false;
169
197
  let lastAnnouncedText = "";
198
+ let pendingText = null;
170
199
  let clearTimeoutId;
171
200
  const announcer = getOrCreateAnnouncer();
201
+ const doAnnounce = (text, h1) => {
202
+ lastAnnouncedText = text;
203
+ clearTimeout(clearTimeoutId);
204
+ announcer.textContent = text;
205
+ clearTimeoutId = setTimeout(() => {
206
+ announcer.textContent = "";
207
+ lastAnnouncedText = "";
208
+ }, CLEAR_DELAY);
209
+ manageFocus(h1);
210
+ };
211
+
212
+ // Safari-ready delay: announcing before VoiceOver wires up the aria-live region
213
+ // causes the first announcement to be silently dropped. Wait SAFARI_READY_DELAY ms
214
+ // before marking the announcer "ready" — any navigation during that window is
215
+ // buffered in pendingText and flushed once the delay expires.
172
216
  const safariTimeoutId = setTimeout(() => {
173
217
  isReady = true;
218
+ if (pendingText !== null && !isDestroyed) {
219
+ const text = pendingText;
220
+ pendingText = null;
221
+ doAnnounce(text, document.querySelector("h1"));
222
+ }
174
223
  }, SAFARI_READY_DELAY);
175
224
  const unsubscribe = router.subscribe(({
176
225
  route
@@ -179,22 +228,28 @@ function createRouteAnnouncer(router, options) {
179
228
  isInitialNavigation = false;
180
229
  return;
181
230
  }
231
+
232
+ // Double rAF: waits for two paint frames so the incoming route's DOM
233
+ // (including the new <h1>) is fully rendered before resolveText reads it.
234
+ // Single rAF fires before the new route's template has been attached,
235
+ // which would cause resolveText to pick up the OLD h1 or fall back to
236
+ // document.title / route.name prematurely.
182
237
  requestAnimationFrame(() => {
183
238
  requestAnimationFrame(() => {
184
239
  if (isDestroyed) {
185
240
  return;
186
241
  }
187
- const text = resolveText(route, prefix);
188
- if (text && text !== lastAnnouncedText && isReady) {
189
- lastAnnouncedText = text;
190
- clearTimeout(clearTimeoutId);
191
- announcer.textContent = text;
192
- clearTimeoutId = setTimeout(() => {
193
- announcer.textContent = "";
194
- lastAnnouncedText = "";
195
- }, CLEAR_DELAY);
196
- manageFocus();
242
+ const h1 = document.querySelector("h1");
243
+ const text = resolveText(route, prefix, getCustomText, h1);
244
+ if (!text || text === lastAnnouncedText) {
245
+ return;
246
+ }
247
+ if (!isReady) {
248
+ // Defer announcement until Safari-ready window elapses (see safariTimeoutId).
249
+ pendingText = text;
250
+ return;
197
251
  }
252
+ doAnnounce(text, h1);
198
253
  });
199
254
  });
200
255
  });
@@ -224,15 +279,13 @@ function getOrCreateAnnouncer() {
224
279
  function removeAnnouncer() {
225
280
  document.querySelector(`[${ANNOUNCER_ATTR}]`)?.remove();
226
281
  }
227
- function resolveText(route, prefix, getCustomText) {
228
- const h1 = document.querySelector("h1");
282
+ function resolveText(route, prefix, getCustomText, h1) {
229
283
  const h1Text = h1?.textContent.trim() ?? "";
230
284
  const routeName = route.name.startsWith(INTERNAL_ROUTE_PREFIX) ? "" : route.name;
231
285
  const rawText = h1Text || document.title || routeName || globalThis.location.pathname;
232
286
  return `${prefix}${rawText}`;
233
287
  }
234
- function manageFocus() {
235
- const h1 = document.querySelector("h1");
288
+ function manageFocus(h1) {
236
289
  if (!h1) {
237
290
  return;
238
291
  }
@@ -251,7 +304,10 @@ function buildHref(router, routeName, routeParams) {
251
304
  try {
252
305
  const buildUrl = router.buildUrl;
253
306
  if (buildUrl) {
254
- return buildUrl(routeName, routeParams);
307
+ const url = buildUrl(routeName, routeParams);
308
+ if (url !== undefined) {
309
+ return url;
310
+ }
255
311
  }
256
312
  return router.buildPath(routeName, routeParams);
257
313
  } catch {
@@ -259,25 +315,67 @@ function buildHref(router, routeName, routeParams) {
259
315
  return undefined;
260
316
  }
261
317
  }
318
+ function parseTokens(value) {
319
+ return value ? value.match(/\S+/g) ?? [] : [];
320
+ }
262
321
  function buildActiveClassName(isActive, activeClassName, baseClassName) {
263
322
  if (isActive && activeClassName) {
264
- return baseClassName ? `${baseClassName} ${activeClassName}`.trim() : activeClassName;
323
+ const activeTokens = parseTokens(activeClassName);
324
+ if (activeTokens.length === 0) {
325
+ return baseClassName ?? undefined;
326
+ }
327
+ if (!baseClassName) {
328
+ return activeTokens.join(" ");
329
+ }
330
+ const baseTokens = parseTokens(baseClassName);
331
+ const seen = new Set(baseTokens);
332
+ for (const token of activeTokens) {
333
+ if (!seen.has(token)) {
334
+ seen.add(token);
335
+ baseTokens.push(token);
336
+ }
337
+ }
338
+ return baseTokens.join(" ");
265
339
  }
266
340
  return baseClassName ?? undefined;
267
341
  }
268
342
  function applyLinkA11y(element) {
343
+ if (!element) {
344
+ return;
345
+ }
269
346
  if (element instanceof HTMLAnchorElement || element instanceof HTMLButtonElement) {
270
347
  return;
271
348
  }
272
- if (!element.getAttribute("role")) {
349
+ if (!element.hasAttribute("role")) {
273
350
  element.setAttribute("role", "link");
274
351
  }
275
- if (!element.getAttribute("tabindex")) {
352
+ if (!element.hasAttribute("tabindex")) {
276
353
  element.setAttribute("tabindex", "0");
277
354
  }
278
355
  }
279
356
 
280
357
  var _tmpl$ = /*#__PURE__*/template(`<a>`);
358
+ // Slow-path source cache: shared per-router, keyed by routeName + params + flags.
359
+ // Captured slow-path values are stable per Link (props captured at init), so the
360
+ // cache key is guaranteed stable for the lifetime of any consumer.
361
+ const activeSourceCache = new WeakMap();
362
+ function getOrCreateActiveSource(router, routeName, routeParams, activeStrict, ignoreQueryParams) {
363
+ let perRouter = activeSourceCache.get(router);
364
+ if (!perRouter) {
365
+ perRouter = new Map();
366
+ activeSourceCache.set(router, perRouter);
367
+ }
368
+ const key = `${routeName}|${JSON.stringify(routeParams)}|${activeStrict}|${ignoreQueryParams}`;
369
+ let source = perRouter.get(key);
370
+ if (!source) {
371
+ source = createActiveRouteSource(router, routeName, routeParams, {
372
+ strict: activeStrict,
373
+ ignoreQueryParams
374
+ });
375
+ perRouter.set(key, source);
376
+ }
377
+ return source;
378
+ }
281
379
  function Link(props) {
282
380
  const merged = mergeProps({
283
381
  routeParams: EMPTY_PARAMS,
@@ -287,13 +385,13 @@ function Link(props) {
287
385
  ignoreQueryParams: true
288
386
  }, props);
289
387
  const [local, rest] = splitProps(merged, ["routeName", "routeParams", "routeOptions", "activeClassName", "activeStrict", "ignoreQueryParams", "onClick", "target", "class", "children"]);
290
- const router = useRouter();
291
388
  const ctx = useContext(RouterContext);
292
- const useFastPath = ctx?.routeSelector && !local.activeStrict && local.ignoreQueryParams && local.routeParams === EMPTY_PARAMS;
293
- const isActive = useFastPath ? () => ctx.routeSelector(local.routeName) : createSignalFromSource(createActiveRouteSource(router, local.routeName, local.routeParams, {
294
- strict: local.activeStrict,
295
- ignoreQueryParams: local.ignoreQueryParams
296
- }));
389
+ if (!ctx) {
390
+ throw new Error("Link must be used within a RouterProvider");
391
+ }
392
+ const router = ctx.router;
393
+ const useFastPath = !local.activeStrict && local.ignoreQueryParams && local.routeParams === EMPTY_PARAMS;
394
+ const isActive = useFastPath ? () => ctx.routeSelector(local.routeName) : createSignalFromSource(getOrCreateActiveSource(router, local.routeName, local.routeParams, local.activeStrict, local.ignoreQueryParams));
297
395
  const href = createMemo(() => buildHref(router, local.routeName, local.routeParams));
298
396
  const handleClick = evt => {
299
397
  if (local.onClick) {
@@ -325,13 +423,13 @@ function Link(props) {
325
423
  })();
326
424
  }
327
425
 
328
- const cache = new WeakMap();
426
+ const cache$1 = new WeakMap();
329
427
  function useRouterError() {
330
428
  const router = useRouter();
331
- let source = cache.get(router);
429
+ let source = cache$1.get(router);
332
430
  if (!source) {
333
431
  source = createErrorSource(router);
334
- cache.set(router, source);
432
+ cache$1.set(router, source);
335
433
  }
336
434
  return createSignalFromSource(source);
337
435
  }
@@ -350,9 +448,11 @@ function RouterErrorBoundary(props) {
350
448
  return snap.version > dismissedVersion() ? snap.error : null;
351
449
  });
352
450
  const resetError = () => setDismissedVersion(snapshot().version);
353
- return [memo(() => props.children), memo(() => {
354
- const error = visibleError();
355
- return error ? props.fallback(error, resetError) : null;
451
+ return [memo(() => props.children), createComponent(Show, {
452
+ get when() {
453
+ return visibleError();
454
+ },
455
+ children: error => props.fallback(error(), resetError)
356
456
  })];
357
457
  }
358
458
 
@@ -422,7 +522,9 @@ const useRoute = () => {
422
522
  };
423
523
 
424
524
  function createStoreFromSource(source) {
425
- const [state, setState] = createStore(structuredClone(source.getSnapshot()));
525
+ const [state, setState] = createStore({
526
+ ...source.getSnapshot()
527
+ });
426
528
  const unsubscribe = source.subscribe(() => {
427
529
  setState(reconcile(source.getSnapshot()));
428
530
  });
@@ -431,23 +533,24 @@ function createStoreFromSource(source) {
431
533
  }
432
534
 
433
535
  function useRouteStore() {
434
- const ctx = useContext(RouteContext);
435
- if (!ctx) {
436
- throw new Error("useRouteStore must be used within a RouterProvider");
437
- }
438
536
  const router = useRouter();
439
537
  return createStoreFromSource(createRouteSource(router));
440
538
  }
441
539
 
442
540
  function useRouteNodeStore(nodeName) {
443
541
  const router = useRouter();
444
- return createStoreFromSource(createRouteNodeSource(router, nodeName));
542
+ return createStoreFromSource(getOrCreateNodeSource(router, nodeName));
445
543
  }
446
544
 
545
+ const cache = new WeakMap();
447
546
  function useRouterTransition() {
448
547
  const router = useRouter();
449
- const store = createTransitionSource(router);
450
- return createSignalFromSource(store);
548
+ let source = cache.get(router);
549
+ if (!source) {
550
+ source = createTransitionSource(router);
551
+ cache.set(router, source);
552
+ }
553
+ return createSignalFromSource(source);
451
554
  }
452
555
 
453
556
  function isRouteActive(linkRouteName, currentRouteName) {
@@ -4,5 +4,6 @@ export interface RouteProviderProps {
4
4
  router: Router;
5
5
  announceNavigation?: boolean;
6
6
  }
7
+ export declare function isRouteActive(linkRouteName: string, currentRouteName: string): boolean;
7
8
  export declare function RouterProvider(props: ParentProps<RouteProviderProps>): JSX.Element;
8
9
  //# sourceMappingURL=RouterProvider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"RouterProvider.d.ts","sourceRoot":"","sources":["../../src/RouterProvider.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEjD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAYD,wBAAgB,cAAc,CAC5B,KAAK,EAAE,WAAW,CAAC,kBAAkB,CAAC,GACrC,GAAG,CAAC,OAAO,CA+Bb"}
1
+ {"version":3,"file":"RouterProvider.d.ts","sourceRoot":"","sources":["../../src/RouterProvider.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEjD,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,wBAAgB,aAAa,CAC3B,aAAa,EAAE,MAAM,EACrB,gBAAgB,EAAE,MAAM,GACvB,OAAO,CAKT;AAED,wBAAgB,cAAc,CAC5B,KAAK,EAAE,WAAW,CAAC,kBAAkB,CAAC,GACrC,GAAG,CAAC,OAAO,CA+Bb"}
@@ -1 +1 @@
1
- {"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../../../src/components/Link.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAC5C,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAC5B,GAAG,CAAC,OAAO,CAgFb"}
1
+ {"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../../../src/components/Link.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAU,MAAM,mBAAmB,CAAC;AAExD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAsCpC,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,EAC5C,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAC5B,GAAG,CAAC,OAAO,CAuFb"}
@@ -1 +1 @@
1
- {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../../src/components/RouteView/components.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACzD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,eAAO,MAAM,YAAY,eAAgC,CAAC;AAE1D,eAAO,MAAM,gBAAgB,eAAmC,CAAC;AAEjE,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,YAAY,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC;IACvB,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,gBAAgB,CAAC;IAChC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC;CACvB;AAED,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,cAAc,CAAC;AAE3D,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,GAAG,CAAC,OAAO,CAYpD;yBAZe,KAAK;;;AAgBrB,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,GAAG,CAAC,OAAO,CAS1D;yBATe,QAAQ"}
1
+ {"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../../src/components/RouteView/components.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACzD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAIpC,eAAO,MAAM,YAAY,eAA4B,CAAC;AAEtD,eAAO,MAAM,gBAAgB,eAA+B,CAAC;AAE7D,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,YAAY,CAAC;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC;IACvB,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,OAAO,gBAAgB,CAAC;IAChC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC;CACvB;AAED,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,cAAc,CAAC;AAE3D,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,GAAG,CAAC,OAAO,CAepD;yBAfe,KAAK;;;AAmBrB,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,GAAG,CAAC,OAAO,CAU1D;yBAVe,QAAQ"}
@@ -1,8 +1,6 @@
1
1
  import type { RouteViewMarker } from "./components";
2
2
  import type { JSX } from "solid-js";
3
+ export declare function isSegmentMatch(routeName: string, fullSegmentName: string, exact: boolean): boolean;
3
4
  export declare function collectElements(children: unknown, result: RouteViewMarker[]): void;
4
- export declare function buildRenderList(elements: RouteViewMarker[], routeName: string, nodeName: string): {
5
- rendered: JSX.Element[];
6
- activeMatchFound: boolean;
7
- };
5
+ export declare function buildRenderList(elements: RouteViewMarker[], routeName: string, nodeName: string): JSX.Element[];
8
6
  //# sourceMappingURL=helpers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../../src/components/RouteView/helpers.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAGV,eAAe,EAChB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAgCpC,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,OAAO,EACjB,MAAM,EAAE,eAAe,EAAE,GACxB,IAAI,CAgBN;AAED,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,eAAe,EAAE,EAC3B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf;IAAE,QAAQ,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;IAAC,gBAAgB,EAAE,OAAO,CAAA;CAAE,CAuCxD"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../../src/components/RouteView/helpers.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAGV,eAAe,EAChB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,EACvB,KAAK,EAAE,OAAO,GACb,OAAO,CAMT;AAoBD,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,OAAO,EACjB,MAAM,EAAE,eAAe,EAAE,GACxB,IAAI,CAgBN;AAED,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,eAAe,EAAE,EAC3B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,GAAG,CAAC,OAAO,EAAE,CAyCf"}
@@ -1 +1 @@
1
- {"version":3,"file":"RouterErrorBoundary.d.ts","sourceRoot":"","sources":["../../../src/components/RouterErrorBoundary.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,CACjB,KAAK,EAAE,WAAW,EAClB,UAAU,EAAE,MAAM,IAAI,KACnB,GAAG,CAAC,OAAO,CAAC;IACjB,QAAQ,CAAC,OAAO,CAAC,EAAE,CACjB,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,KAAK,GAAG,IAAI,EACrB,SAAS,EAAE,KAAK,GAAG,IAAI,KACpB,IAAI,CAAC;CACX;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,wBAAwB,GAC9B,GAAG,CAAC,OAAO,CA8Bb"}
1
+ {"version":3,"file":"RouterErrorBoundary.d.ts","sourceRoot":"","sources":["../../../src/components/RouterErrorBoundary.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAEpC,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,CACjB,KAAK,EAAE,WAAW,EAClB,UAAU,EAAE,MAAM,IAAI,KACnB,GAAG,CAAC,OAAO,CAAC;IACjB,QAAQ,CAAC,OAAO,CAAC,EAAE,CACjB,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,KAAK,GAAG,IAAI,EACrB,SAAS,EAAE,KAAK,GAAG,IAAI,KACpB,IAAI,CAAC;CACX;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,wBAAwB,GAC9B,GAAG,CAAC,OAAO,CA4Bb"}
@@ -1 +1 @@
1
- {"version":3,"file":"createSignalFromSource.d.ts","sourceRoot":"","sources":["../../src/createSignalFromSource.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,wBAAgB,sBAAsB,CAAC,CAAC,EACtC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,GACtB,QAAQ,CAAC,CAAC,CAAC,CAYb"}
1
+ {"version":3,"file":"createSignalFromSource.d.ts","sourceRoot":"","sources":["../../src/createSignalFromSource.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,wBAAgB,sBAAsB,CAAC,CAAC,EACtC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,GACtB,QAAQ,CAAC,CAAC,CAAC,CAoBb"}
@@ -1 +1 @@
1
- {"version":3,"file":"createStoreFromSource.d.ts","sourceRoot":"","sources":["../../src/createStoreFromSource.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,MAAM,EACpD,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,GACtB,CAAC,CAYH"}
1
+ {"version":3,"file":"createStoreFromSource.d.ts","sourceRoot":"","sources":["../../src/createStoreFromSource.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,MAAM,EACpD,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,GACtB,CAAC,CAUH"}
@@ -1,4 +1,4 @@
1
1
  export { createRouteAnnouncer } from "./route-announcer.js";
2
- export { shouldNavigate, buildHref, buildActiveClassName, applyLinkA11y, } from "./link-utils.js";
2
+ export { shouldNavigate, buildHref, buildActiveClassName, shallowEqual, applyLinkA11y, } from "./link-utils.js";
3
3
  export type { RouteAnnouncerOptions } from "./route-announcer.js";
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dom-utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE5D,OAAO,EACL,cAAc,EACd,SAAS,EACT,oBAAoB,EACpB,aAAa,GACd,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dom-utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE5D,OAAO,EACL,cAAc,EACd,SAAS,EACT,oBAAoB,EACpB,YAAY,EACZ,aAAa,GACd,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC"}
@@ -2,5 +2,6 @@ import type { Router, Params } from "@real-router/core";
2
2
  export declare function shouldNavigate(evt: MouseEvent): boolean;
3
3
  export declare function buildHref(router: Router, routeName: string, routeParams: Params): string | undefined;
4
4
  export declare function buildActiveClassName(isActive: boolean, activeClassName: string | undefined, baseClassName: string | undefined): string | undefined;
5
- export declare function applyLinkA11y(element: HTMLElement): void;
5
+ export declare function shallowEqual(prev: object | undefined, next: object | undefined): boolean;
6
+ export declare function applyLinkA11y(element: HTMLElement | null | undefined): void;
6
7
  //# sourceMappingURL=link-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"link-utils.d.ts","sourceRoot":"","sources":["../../../src/dom-utils/link-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAExD,wBAAgB,cAAc,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAQvD;AAID,wBAAgB,SAAS,CACvB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,MAAM,GAAG,SAAS,CAgBpB;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,OAAO,EACjB,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,aAAa,EAAE,MAAM,GAAG,SAAS,GAChC,MAAM,GAAG,SAAS,CAQpB;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAaxD"}
1
+ {"version":3,"file":"link-utils.d.ts","sourceRoot":"","sources":["../../../src/dom-utils/link-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAExD,wBAAgB,cAAc,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAQvD;AAID,wBAAgB,SAAS,CACvB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,MAAM,GAAG,SAAS,CAoBpB;AAMD,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,OAAO,EACjB,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,aAAa,EAAE,MAAM,GAAG,SAAS,GAChC,MAAM,GAAG,SAAS,CAyBpB;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,IAAI,EAAE,MAAM,GAAG,SAAS,GACvB,OAAO,CAwBT;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAgB3E"}
@@ -1 +1 @@
1
- {"version":3,"file":"route-announcer.d.ts","sourceRoot":"","sources":["../../../src/dom-utils/route-announcer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AASvD,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,CAAC;CAChD;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,qBAAqB,GAC9B;IAAE,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,CAuDzB"}
1
+ {"version":3,"file":"route-announcer.d.ts","sourceRoot":"","sources":["../../../src/dom-utils/route-announcer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AASvD,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mBAAmB,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,CAAC;CAChD;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,qBAAqB,GAC9B;IAAE,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE,CAsFzB"}
@@ -0,0 +1,4 @@
1
+ import type { Router } from "@real-router/core";
2
+ import type { RouteNodeSnapshot, RouterSource } from "@real-router/sources";
3
+ export declare function getOrCreateNodeSource(router: Router, nodeName: string): RouterSource<RouteNodeSnapshot>;
4
+ //# sourceMappingURL=sharedNodeSource.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sharedNodeSource.d.ts","sourceRoot":"","sources":["../../../src/hooks/sharedNodeSource.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAO5E,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,YAAY,CAAC,iBAAiB,CAAC,CAgBjC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useRouteNode.d.ts","sourceRoot":"","sources":["../../../src/hooks/useRouteNode.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC,CAKnE"}
1
+ {"version":3,"file":"useRouteNode.d.ts","sourceRoot":"","sources":["../../../src/hooks/useRouteNode.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC,CAInE"}
@@ -1 +1 @@
1
- {"version":3,"file":"useRouteNodeStore.d.ts","sourceRoot":"","sources":["../../../src/hooks/useRouteNodeStore.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAI9D"}
1
+ {"version":3,"file":"useRouteNodeStore.d.ts","sourceRoot":"","sources":["../../../src/hooks/useRouteNodeStore.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAI9D"}
@@ -1 +1 @@
1
- {"version":3,"file":"useRouteStore.d.ts","sourceRoot":"","sources":["../../../src/hooks/useRouteStore.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,wBAAgB,aAAa,IAAI,UAAU,CAU1C"}
1
+ {"version":3,"file":"useRouteStore.d.ts","sourceRoot":"","sources":["../../../src/hooks/useRouteStore.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,wBAAgB,aAAa,IAAI,UAAU,CAI1C"}
@@ -1 +1 @@
1
- {"version":3,"file":"useRouterTransition.d.ts","sourceRoot":"","sources":["../../../src/hooks/useRouterTransition.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,wBAAgB,mBAAmB,IAAI,QAAQ,CAAC,wBAAwB,CAAC,CAKxE"}
1
+ {"version":3,"file":"useRouterTransition.d.ts","sourceRoot":"","sources":["../../../src/hooks/useRouterTransition.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAEV,wBAAwB,EACzB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAIzC,wBAAgB,mBAAmB,IAAI,QAAQ,CAAC,wBAAwB,CAAC,CAWxE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@real-router/solid",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "type": "commonjs",
5
5
  "description": "Solid.js integration for Real-Router",
6
6
  "main": "./dist/cjs/index.js",
@@ -51,9 +51,9 @@
51
51
  "license": "MIT",
52
52
  "sideEffects": false,
53
53
  "dependencies": {
54
- "@real-router/core": "^0.47.0",
55
- "@real-router/route-utils": "^0.2.0",
56
- "@real-router/sources": "^0.5.0"
54
+ "@real-router/core": "^0.48.0",
55
+ "@real-router/route-utils": "^0.2.1",
56
+ "@real-router/sources": "^0.5.1"
57
57
  },
58
58
  "devDependencies": {
59
59
  "@babel/core": "7.29.0",
@@ -71,19 +71,19 @@
71
71
  "solid-js": "1.9.12",
72
72
  "vite-plugin-solid": "2.11.11",
73
73
  "vitest": "4.1.0",
74
- "@real-router/browser-plugin": "^0.12.0"
74
+ "@real-router/browser-plugin": "^0.12.2"
75
75
  },
76
76
  "peerDependencies": {
77
77
  "solid-js": ">=1.7.0"
78
78
  },
79
79
  "scripts": {
80
- "build": "rimraf dist && tsc -p tsconfig.build.json && rollup -c rollup.config.mjs",
81
80
  "test": "vitest",
82
81
  "test:properties": "vitest run --config vitest.config.properties.mts",
83
82
  "test:stress": "vitest run --config vitest.config.stress.mts",
84
83
  "type-check": "tsc --noEmit",
85
84
  "lint": "eslint --cache --ext .ts,.tsx src/ tests/ --fix --max-warnings 0",
86
85
  "lint:package": "publint",
87
- "lint:types": "attw --pack ."
86
+ "lint:types": "attw --pack .",
87
+ "bundle": "rimraf dist && tsc -p tsconfig.build.json && rollup -c rollup.config.mjs"
88
88
  }
89
89
  }
@@ -14,7 +14,7 @@ export interface RouteProviderProps {
14
14
  announceNavigation?: boolean;
15
15
  }
16
16
 
17
- function isRouteActive(
17
+ export function isRouteActive(
18
18
  linkRouteName: string,
19
19
  currentRouteName: string,
20
20
  ): boolean {