@plumile/router 0.1.19 → 0.1.21

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 (62) hide show
  1. package/README.md +110 -180
  2. package/lib/esm/eslint-rules/no-direct-window-location-search.js +3 -3
  3. package/lib/esm/index.d.ts +0 -1
  4. package/lib/esm/index.d.ts.map +1 -1
  5. package/lib/esm/index.js +1 -2
  6. package/lib/esm/routing/Link.d.ts.map +1 -1
  7. package/lib/esm/routing/Link.js +14 -25
  8. package/lib/esm/routing/RouteComponentWrapper.js +2 -2
  9. package/lib/esm/routing/createRouter.d.ts.map +1 -1
  10. package/lib/esm/routing/createRouter.js +82 -108
  11. package/lib/esm/routing/index.d.ts +1 -1
  12. package/lib/esm/routing/index.d.ts.map +1 -1
  13. package/lib/esm/routing/index.js +2 -2
  14. package/lib/esm/routing/useAllQuery.js +1 -1
  15. package/lib/esm/routing/useFilters.js +10 -10
  16. package/lib/esm/routing/useQueryState.d.ts.map +1 -1
  17. package/lib/esm/routing/useQueryState.js +10 -45
  18. package/lib/esm/tools/buildCombinedSearch.d.ts +1 -5
  19. package/lib/esm/tools/buildCombinedSearch.d.ts.map +1 -1
  20. package/lib/esm/tools/buildCombinedSearch.js +6 -15
  21. package/lib/esm/tools.d.ts +2 -6
  22. package/lib/esm/tools.d.ts.map +1 -1
  23. package/lib/esm/tools.js +1 -1
  24. package/lib/esm/type-tests/query-infer.test-d.d.ts.map +1 -1
  25. package/lib/esm/type-tests/query-infer.test-d.js +2 -49
  26. package/lib/esm/type-tests/routes-inference.test-d.d.ts +0 -1
  27. package/lib/esm/type-tests/routes-inference.test-d.js +2 -49
  28. package/lib/esm/types.d.ts +2 -16
  29. package/lib/esm/types.d.ts.map +1 -1
  30. package/lib/esm/types.js +1 -1
  31. package/lib/tsconfig.esm.tsbuildinfo +1 -1
  32. package/lib/types/index.d.ts +0 -1
  33. package/lib/types/index.d.ts.map +1 -1
  34. package/lib/types/routing/Link.d.ts.map +1 -1
  35. package/lib/types/routing/createRouter.d.ts.map +1 -1
  36. package/lib/types/routing/index.d.ts +1 -1
  37. package/lib/types/routing/index.d.ts.map +1 -1
  38. package/lib/types/routing/useQueryState.d.ts.map +1 -1
  39. package/lib/types/tools/buildCombinedSearch.d.ts +1 -5
  40. package/lib/types/tools/buildCombinedSearch.d.ts.map +1 -1
  41. package/lib/types/tools.d.ts +2 -6
  42. package/lib/types/tools.d.ts.map +1 -1
  43. package/lib/types/type-tests/query-infer.test-d.d.ts.map +1 -1
  44. package/lib/types/type-tests/routes-inference.test-d.d.ts +0 -1
  45. package/lib/types/types.d.ts +2 -16
  46. package/lib/types/types.d.ts.map +1 -1
  47. package/package.json +4 -4
  48. package/lib/esm/routing/useTypedQuery.d.ts +0 -2
  49. package/lib/esm/routing/useTypedQuery.d.ts.map +0 -1
  50. package/lib/esm/routing/useTypedQuery.js +0 -36
  51. package/lib/esm/tools/buildSearch.d.ts +0 -6
  52. package/lib/esm/tools/buildSearch.d.ts.map +0 -1
  53. package/lib/esm/tools/buildSearch.js +0 -60
  54. package/lib/esm/tools/query-dsl.d.ts +0 -28
  55. package/lib/esm/tools/query-dsl.d.ts.map +0 -1
  56. package/lib/esm/tools/query-dsl.js +0 -250
  57. package/lib/types/routing/useTypedQuery.d.ts +0 -2
  58. package/lib/types/routing/useTypedQuery.d.ts.map +0 -1
  59. package/lib/types/tools/buildSearch.d.ts +0 -6
  60. package/lib/types/tools/buildSearch.d.ts.map +0 -1
  61. package/lib/types/tools/query-dsl.d.ts +0 -28
  62. package/lib/types/tools/query-dsl.d.ts.map +0 -1
package/README.md CHANGED
@@ -228,175 +228,104 @@ Prepares route data and components for rendering.
228
228
 
229
229
  Type helper for strongly-typed route definitions.
230
230
 
231
- ## Advanced Usage
231
+ ## Unified Query & Filter Model
232
232
 
233
- ### Per-Route Prepared Data & Typed Navigate
233
+ The router now unifies page-like query parameters and structured filters under a single model powered by `@plumile/filter-query`.
234
234
 
235
- Each route created with `r({...})` now preserves:
235
+ Key points:
236
236
 
237
- - Prepared data type (return of `prepare`)
238
- - URL parameter type
239
- - Inferred typed query shape from its `query` schema
237
+ - A route can declare a `querySchema` (filter schema) on its deepest branch.
238
+ - All URL parameters (simple key=value and filter operators like `price.gt=10`) are parsed into a single `filters` object.
239
+ - Equality is implicit: `field=value` maps to internal operator `eq`.
240
+ - The current active schema is exposed as `entry.activeQuerySchema` for tooling.
241
+ - Serialization is centralized via `buildCombinedSearch` (used by both `navigate` and `Link`).
240
242
 
241
- This enables discriminated narrowing using `entry.route?.path` and compile-time validation of `navigate` query objects.
243
+ ### Defining a Schema
242
244
 
243
245
  ```ts
244
- import { r, q, createRouter } from '@plumile/router';
246
+ import { r } from '@plumile/router';
247
+ import { defineSchema, numberField, stringField } from '@plumile/filter-query';
245
248
 
246
- const plans = r({
247
- path: '/plans',
248
- query: { page: q.number() } as const,
249
- prepare: ({ query }) => ({ page: query.page }),
250
- });
251
- const user = r<{ userId: string }, { id: string }>({
252
- path: '/users/:id',
253
- prepare: ({ variables }) => ({ userId: variables.id }),
249
+ const productFilters = defineSchema({
250
+ page: numberField(),
251
+ price: numberField(),
252
+ title: stringField(),
254
253
  });
255
- const { context } = createRouter([plans, user] as const);
256
-
257
- const entry = context.get();
258
- if (entry.route?.path === '/plans') {
259
- const prepared = context.getPrepared('/plans');
260
- // prepared?.page inferred as number | undefined
261
- const typed = context.getTypedQuery('/plans');
262
- // typed?.page inferred
263
- }
264
-
265
- // Typed navigate – query validated against the route schema
266
- context.navigate({ pathname: '/plans', query: { page: 2 } });
267
- ```
268
-
269
- APIs:
270
-
271
- - `context.getPrepared(path)` → prepared object for that matched path (if present).
272
- - `context.getTypedQuery(path)` → typed query for path.
273
- - `context.navigate({...})` → enforces schema shape when `pathname` matches a known literal path.
274
-
275
- If a path is dynamic or no schema exists, the untyped fallback remains available.
276
-
277
- ### Typed Query Parameters (DSL)
278
-
279
- The router provides a lightweight schema DSL for parsing, typing, normalizing and serializing query strings.
280
-
281
- #### 1. Define a schema on the deepest route
282
-
283
- ```ts
284
- import { q, r } from '@plumile/router';
285
254
 
286
255
  const routes = [
287
256
  r({
288
- path: '/items',
289
- // Schema: page = number (default 1), tag(s) = array of strings, flag = optional boolean
290
- query: {
291
- page: q.default(q.number(), 1),
292
- tags: q.array(q.string()),
293
- flag: q.optional(q.boolean()),
294
- },
295
- prepare: ({ query }) => {
296
- // query is typed: { page: number; tags: string[]; flag?: boolean }
297
- return { page: query.page };
298
- },
257
+ path: '/products',
258
+ querySchema: productFilters,
259
+ prepare: ({ filters }) => ({ page: filters.page?.eq ?? 1 }),
299
260
  render: () => null,
300
261
  }),
301
262
  ];
302
263
  ```
303
264
 
304
- #### 2. Access parsed & typed queries
265
+ ### Accessing Filters
305
266
 
306
267
  ```tsx
307
- import { useQuery, useTypedQuery } from '@plumile/router';
268
+ import { useFilters } from '@plumile/router';
308
269
 
309
270
  function List() {
310
- const raw = useQuery(); // Record<string, string | string[]>
311
- const typed = useTypedQuery(); // Auto‑inferred from deepest route schema (no generic needed)
312
- const [page, setPage] = useQueryState<number>('page'); // Bidirectional state ↔ URL for one param
313
- return <pre>{JSON.stringify({ raw, typed }, null, 2)}</pre>;
271
+ const [filters, actions] = useFilters();
272
+ // filters.price?.gt, filters.title?.contains, filters.page?.eq
273
+ actions.set('price', 'gt', 10);
274
+ actions.set('page', 'eq', 2); // becomes page=2 in URL
275
+ return null;
314
276
  }
315
277
  ```
316
278
 
317
- Referential stability: both `raw` (from `useQuery()`) and `typed` (from `useTypedQuery()`) are memoized per canonical search string. If the URL search part doesn't change semantically (including key order canonicalization), the hook returns the exact same object reference. You can safely list either in React dependency arrays without extra `useMemo` or a hypothetical `useStableQuery` helper (not needed).
318
-
319
- Type inference:
320
-
321
- - If the matched deepest route has a `query` schema, `useTypedQuery()` returns the inferred `InferQuery<typeof schema>` shape automatically.
322
- - If no schema exists, it returns the raw parsed object (record of string | string[]) so you can still read values safely.
323
- - You can still supply a generic manually (`useTypedQuery<MyShape>()`) in edge cases (e.g. incremental migration) but it is usually unnecessary now.
324
-
325
- #### 3. Programmatic navigation with typed query
326
-
327
- ```tsx
328
- import { useNavigate } from '@plumile/router';
279
+ ### Programmatic Navigation
329
280
 
330
- function Pager({ page }: { page: number }) {
331
- const navigate = useNavigate();
332
- return (
333
- <button
334
- onClick={() => {
335
- navigate({ query: { page: page + 1 } });
336
- }}
337
- >
338
- Next page
339
- </button>
340
- );
341
- }
281
+ ```ts
282
+ context.navigate({ pathname: '/products', filters: { page: { eq: 3 } } });
342
283
  ```
343
284
 
344
- #### 4. Link component with query
285
+ ### Page Normalization
345
286
 
346
- ```tsx
347
- import { Link } from '@plumile/router';
348
-
349
- <Link to="/items" query={{ page: 2, tags: ['a', 'b'], flag: true }}>
350
- Filter
351
- </Link>;
352
- ```
287
+ The router clamps `page.eq < 1` to `1` synchronously and performs a history replace so the back stack is not polluted.
353
288
 
354
- `Link` & `navigate` automatically serialize using the route schema, applying:
289
+ ### Serialization Rules
355
290
 
356
- - Schema key order
357
- - Array repetition (`?tags=a&tags=b`)
358
- - Omission of default values when `omitDefaults` optimization applies internally
291
+ `buildCombinedSearch` produces a leading `?` (or empty string) by:
359
292
 
360
- #### 5. Normalization
293
+ 1. Ordering simple query params (from schema order).
294
+ 2. Appending filter operator segments (`field.operator=value`).
295
+ 3. Using implicit equality (`field=value`).
296
+ 4. Maintaining reference stability (no unnecessary object churn).
361
297
 
362
- Built‑in simple normalization currently clamps `page < 1` to `1` and issues a `replaceState` to avoid polluting history.
298
+ ### Migration Note
363
299
 
364
- #### 6. Serialization utility
300
+ The legacy query DSL (`q.*`, `parseTypedQuery`, `buildSearch`) has been removed. Replace any usage with a filter schema (`defineSchema`) and rely on `useFilters`, `navigate({ filters })`, and/or `buildCombinedSearch`.
365
301
 
366
- ```ts
367
- import { buildSearch, q } from '@plumile/router';
368
-
369
- const schema = {
370
- page: q.default(q.number(), 1),
371
- tag: q.array(q.string()),
372
- } as const;
373
- const search = buildSearch({ page: 1, tag: ['x', 'y'] }, schema, {
374
- omitDefaults: true,
375
- });
376
- // => '?tag=x&tag=y'
377
- ```
302
+ ### Performance & Stability
378
303
 
379
- #### 7. Parsing utility / alias
304
+ Filters cache: repeated navigations with semantically identical search strings reuse the same filter object reference, enabling cheap React renders.
380
305
 
381
- ```ts
382
- import { parseSearch, q } from '@plumile/router';
306
+ ### Example Link
383
307
 
384
- const schema = { flag: q.boolean() } as const;
385
- const typed = parseSearch(schema, '?flag=1'); // { flag: true }
308
+ ```tsx
309
+ <Link to="/products" filters={{ page: { eq: 1 }, price: { gt: 10 } }}>
310
+ Deals
311
+ </Link>
386
312
  ```
387
313
 
388
- #### 8. Performance and stability
314
+ Renders `href="/products?page=1&price.gt=10"`.
389
315
 
390
- There are two coordinated caching layers:
316
+ ### Manual Serialization Example
391
317
 
392
- 1. Raw query cache: A process-wide Map keyed by a canonicalized search string (sorted keys, ordered value emission). Produces a frozen empty object for the empty search and reuses prior parsed objects, yielding stable references for unchanged search state.
393
- 2. Typed query cache: A WeakMap keyed by (schema reference → canonical search signature) that parses once and reuses the typed value. Structural deep-equality canonicalization means semantically equivalent searches (e.g. reordered keys) reuse object identity.
318
+ If you need to build a URL outside of navigation (e.g. constructing a sitemap entry):
394
319
 
395
- Effects:
320
+ ```ts
321
+ import buildCombinedSearch from '@plumile/router/lib/esm/routing/tools/buildCombinedSearch.js'; // or routed re-export
396
322
 
397
- - Stable object identity for both raw and typed queries eliminates needless renders and removes the need for an extra `useStableQuery` hook.
398
- - Safe to put `useQuery()` / `useTypedQuery()` results directly in dependency arrays (`useEffect`, `useMemo`, selectors, etc.).
399
- - Empty query allocations are avoided (shared frozen object).
323
+ const search = buildCombinedSearch({
324
+ filters: { page: { eq: 1 }, price: { gt: 10 } },
325
+ schema: productFilters,
326
+ });
327
+ // search === '?page=1&price.gt=10'
328
+ ```
400
329
 
401
330
  Guideline: If you need to derive lightweight projections (e.g. `const { page } = typed`), you can still destructure; but avoid spreading into a new object if you rely on reference equality downstream.
402
331
 
@@ -420,13 +349,13 @@ Devtools option forms:
420
349
  - `panel` (default: false) mounts an overlay; closed with the close button or page reload.
421
350
  - `shortcut` (default: `Alt+Shift+R`) toggles panel visibility.
422
351
 
423
- The panel displays current path+search, variables, raw query and typed query. It is intentionally framework‑agnostic (no React runtime cost) and uses a shadow root to minimize style collisions.
352
+ The panel displays current path+search, variables, raw query aggregation, active schema, and parsed filters. It is intentionally framework‑agnostic (no React runtime cost) and uses a shadow root to minimize style collisions.
424
353
 
425
354
  ```js
426
355
  window.__PLUMILE_ROUTER__.get(); // current RouteEntry
427
- const unsub = window.__PLUMILE_ROUTER__.subscribe((entry) =>
428
- console.log(entry.typedQuery),
429
- );
356
+ const unsub = window.__PLUMILE_ROUTER__.subscribe((entry) => {
357
+ console.log('filters', entry.filters);
358
+ });
430
359
  ```
431
360
 
432
361
  This lets you introspect parsed queries & variables without adding debug code. Neither global nor panel is present in production unless explicitly forced with `devtools: { global: true, panel: true }` (discouraged).
@@ -455,15 +384,16 @@ type RouteEntry = {
455
384
  route: { match; params; path } | null; // current matched route (or null)
456
385
  preparedMatch: { routes: { prepared; render?; resourcePage? }[]; match }; // internal prepared tree
457
386
  forceRerender: boolean; // indicates forced re-render situations
458
- rawSearch: string; // '?page=2&tag=a'
459
- query: Record<string, string | string[]>; // raw aggregated query params
460
- typedQuery: any; // typed query if schema present
387
+ rawSearch: string; // '?page=2&price.gt=10'
388
+ query: Record<string, string | string[]>; // raw aggregated query params (for legacy/simple access)
389
+ filters: Record<string, any>; // unified parsed filters (implicit eq)
390
+ activeQuerySchema?: any; // active deepest schema (when present)
461
391
  };
462
392
  ```
463
393
 
464
394
  Common console patterns:
465
395
 
466
- 1. Log every navigation with typed query & params:
396
+ 1. Log every navigation with filters & params:
467
397
 
468
398
  ```js
469
399
  const dev = window.__PLUMILE_ROUTER__;
@@ -471,7 +401,7 @@ if (dev) {
471
401
  const off = dev.subscribe((e) => {
472
402
  console.log('[router]', e.location.pathname + e.location.search, {
473
403
  vars: e.route?.params,
474
- typed: e.typedQuery,
404
+ filters: e.filters,
475
405
  });
476
406
  });
477
407
  // later: off();
@@ -492,7 +422,7 @@ deepest?.prepared; // Prepared data returned by deepest prepare()
492
422
  let last = window.__PLUMILE_ROUTER__?.get().rawSearch;
493
423
  const off = window.__PLUMILE_ROUTER__?.subscribe((e) => {
494
424
  if (e.rawSearch !== last) {
495
- console.log('query changed', last, '=>', e.rawSearch, e.typedQuery);
425
+ console.log('query changed', last, '=>', e.rawSearch, e.filters);
496
426
  last = e.rawSearch;
497
427
  }
498
428
  });
@@ -503,7 +433,7 @@ const off = window.__PLUMILE_ROUTER__?.subscribe((e) => {
503
433
  ```js
504
434
  const { get } = window.__PLUMILE_ROUTER__;
505
435
  const before = performance.now();
506
- for (let i = 0; i < 200; i++) get().typedQuery; // use cache; ensures no GC
436
+ for (let i = 0; i < 200; i++) get().filters; // use cache; ensures no GC
507
437
  console.log('elapsed ms', performance.now() - before);
508
438
  ```
509
439
 
@@ -511,7 +441,7 @@ console.log('elapsed ms', performance.now() - before);
511
441
 
512
442
  ```js
513
443
  const R = window.__PLUMILE_ROUTER__;
514
- R && R.subscribe((e) => console.debug('[typedQuery]', e.typedQuery));
444
+ R && R.subscribe((e) => console.debug('[filters]', e.filters));
515
445
  ```
516
446
 
517
447
  Unsubscribing: every `subscribe` returns a disposer function. Always call it if you set up long‑lived listeners in a debugging session to avoid memory leaks during hot reloads.
@@ -520,39 +450,42 @@ Extending: if you need more (e.g. trigger navigations) you can wrap `createRoute
520
450
 
521
451
  Production: the symbol is not defined; accessing it will yield `undefined`. Never ship logic depending on it; keep usage inside `if (process.env.NODE_ENV !== 'production')` blocks or guarded optional checks.
522
452
 
523
- ### Filter Schema & useFilters (Integration with @plumile/filter-query)
453
+ ### Unified Query Schema & useFilters (Integration with @plumile/filter-query)
524
454
 
525
- The router can parse and serialize structured filter expressions using the `@plumile/filter-query` package. Define a `filterSchema` on the deepest route (same precedence rule as `query`). Each filter key is encoded as `field.operator=value`.
455
+ The router uses a single unified schema (`querySchema`) defined with `@plumile/filter-query` to describe allowed key/operator pairs. Plain `field=value` maps to the implicit equality operator (`eq`). Each filter segment is encoded as `field.operator=value` (with `eq` omitted).
526
456
 
527
457
  ```ts
528
- import { r, q, useFilters } from '@plumile/router';
458
+ import { r, useFilters } from '@plumile/router';
529
459
  import { defineSchema, numberField, stringField } from '@plumile/filter-query';
530
460
 
531
- const filterSchema = defineSchema({
532
- price: numberField(), // operators: gt,gte,lt,lte,eq,neq,between,in,nin
533
- name: stringField(), // operators: contains,sw,ew,eq,neq,in,nin
461
+ const querySchema = defineSchema({
462
+ page: numberField(), // page.eq=2 => ?page=2 (page normalization clamps <1 to 1)
463
+ price: numberField(), // price.gt=10 => ?price.gt=10
464
+ name: stringField(), // name.contains=ultra => ?name.contains=ultra
534
465
  });
535
466
 
536
- const routes = [
467
+ export const routes = [
537
468
  r({
538
469
  path: '/items',
539
- query: { page: q.default(q.number(), 1) },
540
- filterSchema,
541
- render: () => null,
470
+ querySchema,
471
+ render: () => <Items />,
542
472
  }),
543
473
  ];
544
474
 
545
- // Inside a component rendered under /items
546
- const [filters, actions] = useFilters();
547
- actions.set('price', 'gt', 10); // ?page=1&price.gt=10
548
- actions.set('price', 'eq', 15); // ?page=1&price.gt=10&price.eq=15
549
- actions.remove('price', 'gt'); // remove only that operator
550
- actions.clear(); // remove all filter segments
475
+ function Items() {
476
+ const [filters, { set, remove, clear, merge }] = useFilters();
477
+ set('price', 'gt', 10); // => ?price.gt=10
478
+ set('page', 'eq', 2); // => ?page=2
479
+ remove('price', 'gt');
480
+ merge([{ field: 'price', op: 'between', value: [10, 20] }]);
481
+ clear();
482
+ return null;
483
+ }
551
484
  ```
552
485
 
553
- `navigate({ filters })` is also available for programmatic changes alongside query updates. Serialization keeps query parameters first, then filter segments, both deterministically ordered.
486
+ `navigate({ filters })` is available for programmatic updates. Serialization order: schema field keys first, then any extra non‑schema keys (if present). Operators follow deterministic ordering from `@plumile/filter-query`.
554
487
 
555
- Diagnostics (unknown field/operator, invalid values, etc.) are accessible via `useFilterDiagnostics()` for debugging tooling or UI feedback.
488
+ Diagnostics (unknown field/operator, invalid values, etc.) are accessible via `useFilterDiagnostics()`.
556
489
 
557
490
  ### ESLint Rule: no-direct-window-location-search
558
491
 
@@ -600,32 +533,29 @@ const qs = window.location.search;
600
533
  with:
601
534
 
602
535
  ```ts
603
- const query = useQuery(); // or useTypedQuery()
536
+ const query = useQuery(); // raw key=value aggregation (simple); prefer useFilters() for structured access.
604
537
  ```
605
538
 
606
- ### Migration Guide (Phases 15)
539
+ ### Migration Guide (Legacy DSLUnified Filters)
540
+
541
+ 1. Remove legacy imports of `q`, `parseTypedQuery`, `buildSearch`.
542
+ 2. Define a schema with `defineSchema` from `@plumile/filter-query` and attach as `querySchema`.
543
+ 3. Replace (removed) `useTypedQuery()` usages with `useFilters()`.
544
+ 4. Update navigation: `navigate({ filters: { page: { eq: 2 } } })`.
545
+ 5. Update links: `<Link to="/x" filters={{ page: { eq: 2 } }} />`.
546
+ 6. Page defaults / normalization: rely on built-in clamp (`page < 1 -> 1`).
547
+ 7. Remove any type tests referencing the DSL; rely on schema inference.
607
548
 
608
- 1. Phase 1/2: Upgrade — no schema needed. Use `useQuery()` for raw params.
609
- 2. Phase 3: Add `query` schema to your deepest route; adopt `useTypedQuery()` where type safety is desirable.
610
- 3. Phase 4: Replace manual URL building with `navigate({ query })` or `<Link query={...} />`. Remove ad‑hoc serialization logic.
611
- 4. Phase 5: Move lightweight data loading logic that depends on query into `prepare({ query })` (now typed). Rely on built‑in normalization (e.g. page clamp) or add custom normalization inside `prepare` followed by a `navigate({ replace: true, query: normalized })` if needed.
612
- 5. Optional: Use `buildSearch` / `parseSearch` for unit tests & utilities.
549
+ ### Removed APIs
613
550
 
614
- ### Query Descriptor Reference
551
+ The following legacy APIs were removed in favor of the unified filter model:
615
552
 
616
- | Descriptor | Description | Serialize Example |
617
- | -------------------------------- | --------------------------------------------------- | ------------------------------------ |
618
- | `q.string()` | Last occurrence string | `{ q: 'x' } -> ?q=x` |
619
- | `q.number()` | Number (invalid => undefined) | `{ n: 2 } -> ?n=2` |
620
- | `q.boolean()` | Presence / true/false/1/0 | `{ f: true } -> ?f=1` |
621
- | `q.enum('a','b')` | Restricted string | `{ e: 'a' } -> ?e=a` |
622
- | `q.array(inner)` | Repeated key multi-values | `{ tag: ['x','y'] } -> ?tag=x&tag=y` |
623
- | `q.optional(d)` | Marks descriptor optional | omitted if undefined |
624
- | `q.default(d, v)` | Supplies default + omit on serialize (omitDefaults) | default skipped |
625
- | `q.emptyAsUndefined(q.string())` | Maps empty string '' to undefined | omitted |
626
- | `q.custom({ parse, serialize })` | Custom parse/serialize logic | depends |
553
+ - `q.*` descriptor DSL (replaced by `defineSchema` in `@plumile/filter-query`)
554
+ - `parseTypedQuery`
555
+ - `buildSearch` (use `buildCombinedSearch`)
556
+ - `useTypedQuery`
627
557
 
628
- Custom: `q.custom({ parse(values), serialize(value) })` lets you wire bespoke formats. Ensure `serialize` outputs an array of raw string values. Use sparingly to keep schemas readable.
558
+ Use `@plumile/filter-query` for schema definitions and `useFilters` / `buildCombinedSearch` for runtime access & serialization.
629
559
 
630
560
  ### useQueryState Hook
631
561
 
@@ -639,10 +569,10 @@ setPage(page! + 1, { replace: true });
639
569
 
640
570
  Behavior:
641
571
 
642
- - Reads from typedQuery if schema present, else raw query.
643
- - Respects schema defaults (and `defaultValue` override in options) and omits key when value equals default (with `omitIfDefault: true`).
572
+ - Reads from filters (implicit equality) and falls back to raw query key when not covered by schema.
573
+ - Allows `defaultValue` override in options and omits key when value equals default (with `omitIfDefault: true`).
644
574
  - Pass `{ raw: true }` to force raw (string) source for incremental migrations.
645
- - Uses existing navigation serialization (ordering, omit defaults, arrays).
575
+ - Uses unified serialization ordering (schema keys then extras; operators deterministic).
646
576
 
647
577
  Options:
648
578
  `{ defaultValue?, omitIfDefault?: boolean = true, replace?: boolean, raw?: boolean }`
@@ -2,11 +2,11 @@ const rule = {
2
2
  meta: {
3
3
  type: 'suggestion',
4
4
  docs: {
5
- description: 'Discourage direct window.location.search access; use useQuery()/useTypedQuery() instead',
5
+ description: 'Discourage direct window.location.search access; use useQuery()/useFilters() instead',
6
6
  recommended: false,
7
7
  },
8
8
  messages: {
9
- avoid: 'Avoid direct access to window.location.search. Use useQuery() / useTypedQuery() from @plumile/router.',
9
+ avoid: 'Avoid direct access to window.location.search. Use useQuery() / useFilters() from @plumile/router.',
10
10
  },
11
11
  schema: [
12
12
  {
@@ -45,4 +45,4 @@ const rule = {
45
45
  },
46
46
  };
47
47
  export default rule;
48
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm8tZGlyZWN0LXdpbmRvdy1sb2NhdGlvbi1zZWFyY2guanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZXNsaW50LXJ1bGVzL25vLWRpcmVjdC13aW5kb3ctbG9jYXRpb24tc2VhcmNoLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU9BLE1BQU0sSUFBSSxHQUFvQjtJQUM1QixJQUFJLEVBQUU7UUFDSixJQUFJLEVBQUUsWUFBWTtRQUNsQixJQUFJLEVBQUU7WUFDSixXQUFXLEVBQ1QseUZBQXlGO1lBQzNGLFdBQVcsRUFBRSxLQUFLO1NBQ25CO1FBQ0QsUUFBUSxFQUFFO1lBQ1IsS0FBSyxFQUNILHVHQUF1RztTQUMxRztRQUNELE1BQU0sRUFBRTtZQUNOO2dCQUNFLElBQUksRUFBRSxRQUFRO2dCQUNkLFVBQVUsRUFBRTtvQkFDVixZQUFZLEVBQUUsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsRUFBRTtpQkFDM0Q7Z0JBQ0Qsb0JBQW9CLEVBQUUsS0FBSzthQUM1QjtTQUNGO0tBQ0Y7SUFDRCxNQUFNLENBQUMsT0FBTztRQUNaLE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUE2QixDQUFDO1FBQ2pFLE1BQU0sT0FBTyxHQUFHLElBQUksR0FBRyxDQUFDLFNBQVMsRUFBRSxZQUFZLElBQUksRUFBRSxDQUFDLENBQUM7UUFDdkQsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3ZDLE1BQU0sU0FBUyxHQUFHLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUMxQyxPQUFPLFFBQVEsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDaEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPO1lBQ0wsZ0JBQWdCLENBQUMsSUFBSTtnQkFDbkIsSUFBSSxTQUFTO29CQUFFLE9BQU87Z0JBQ3RCLElBQ0UsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEtBQUssWUFBWTtvQkFDbkMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEtBQUssUUFBUTtvQkFDL0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssa0JBQWtCLEVBQ3ZDLENBQUM7b0JBQ0QsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztvQkFDeEIsSUFDRSxHQUFHLENBQUMsUUFBUSxDQUFDLElBQUksS0FBSyxZQUFZO3dCQUNsQyxHQUFHLENBQUMsUUFBUSxDQUFDLElBQUksS0FBSyxVQUFVO3dCQUNoQyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxZQUFZO3dCQUNoQyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxRQUFRLEVBQzVCLENBQUM7d0JBQ0QsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztvQkFDL0MsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztTQUNGLENBQUM7SUFDSixDQUFDO0NBQ0YsQ0FBQztBQUVGLGVBQWUsSUFBSSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gTW92ZWQgZnJvbSBwYWNrYWdlIHJvb3QgZXNsaW50LXJ1bGVzIGRpcmVjdG9yeSBpbnRvIHNyYyB0byBzYXRpc2Z5IFRTIHJvb3REaXJcbmltcG9ydCB0eXBlIHsgUnVsZSB9IGZyb20gJ2VzbGludCc7XG5cbmludGVyZmFjZSBPcHRpb25zU2hhcGUge1xuICBhbGxvd0luRmlsZXM/OiBzdHJpbmdbXTtcbn1cblxuY29uc3QgcnVsZTogUnVsZS5SdWxlTW9kdWxlID0ge1xuICBtZXRhOiB7XG4gICAgdHlwZTogJ3N1Z2dlc3Rpb24nLFxuICAgIGRvY3M6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnRGlzY291cmFnZSBkaXJlY3Qgd2luZG93LmxvY2F0aW9uLnNlYXJjaCBhY2Nlc3M7IHVzZSB1c2VRdWVyeSgpL3VzZVR5cGVkUXVlcnkoKSBpbnN0ZWFkJyxcbiAgICAgIHJlY29tbWVuZGVkOiBmYWxzZSxcbiAgICB9LFxuICAgIG1lc3NhZ2VzOiB7XG4gICAgICBhdm9pZDpcbiAgICAgICAgJ0F2b2lkIGRpcmVjdCBhY2Nlc3MgdG8gd2luZG93LmxvY2F0aW9uLnNlYXJjaC4gVXNlIHVzZVF1ZXJ5KCkgLyB1c2VUeXBlZFF1ZXJ5KCkgZnJvbSBAcGx1bWlsZS9yb3V0ZXIuJyxcbiAgICB9LFxuICAgIHNjaGVtYTogW1xuICAgICAge1xuICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgIGFsbG93SW5GaWxlczogeyB0eXBlOiAnYXJyYXknLCBpdGVtczogeyB0eXBlOiAnc3RyaW5nJyB9IH0sXG4gICAgICAgIH0sXG4gICAgICAgIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgXSxcbiAgfSxcbiAgY3JlYXRlKGNvbnRleHQpIHtcbiAgICBjb25zdCByYXdPcHRpb24gPSBjb250ZXh0Lm9wdGlvbnNbMF0gYXMgT3B0aW9uc1NoYXBlIHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IGFsbG93SW4gPSBuZXcgU2V0KHJhd09wdGlvbj8uYWxsb3dJbkZpbGVzID8/IFtdKTtcbiAgICBjb25zdCBmaWxlbmFtZSA9IGNvbnRleHQuZ2V0RmlsZW5hbWUoKTtcbiAgICBjb25zdCBpc0FsbG93ZWQgPSBbLi4uYWxsb3dJbl0uc29tZSgocGF0KSA9PiB7XG4gICAgICByZXR1cm4gZmlsZW5hbWUuaW5jbHVkZXMocGF0KTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBNZW1iZXJFeHByZXNzaW9uKG5vZGUpIHtcbiAgICAgICAgaWYgKGlzQWxsb3dlZCkgcmV0dXJuO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgbm9kZS5wcm9wZXJ0eS50eXBlID09PSAnSWRlbnRpZmllcicgJiZcbiAgICAgICAgICBub2RlLnByb3BlcnR5Lm5hbWUgPT09ICdzZWFyY2gnICYmXG4gICAgICAgICAgbm9kZS5vYmplY3QudHlwZSA9PT0gJ01lbWJlckV4cHJlc3Npb24nXG4gICAgICAgICkge1xuICAgICAgICAgIGNvbnN0IG9iaiA9IG5vZGUub2JqZWN0O1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIG9iai5wcm9wZXJ0eS50eXBlID09PSAnSWRlbnRpZmllcicgJiZcbiAgICAgICAgICAgIG9iai5wcm9wZXJ0eS5uYW1lID09PSAnbG9jYXRpb24nICYmXG4gICAgICAgICAgICBvYmoub2JqZWN0LnR5cGUgPT09ICdJZGVudGlmaWVyJyAmJlxuICAgICAgICAgICAgb2JqLm9iamVjdC5uYW1lID09PSAnd2luZG93J1xuICAgICAgICAgICkge1xuICAgICAgICAgICAgY29udGV4dC5yZXBvcnQoeyBub2RlLCBtZXNzYWdlSWQ6ICdhdm9pZCcgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LFxuICAgIH07XG4gIH0sXG59O1xuXG5leHBvcnQgZGVmYXVsdCBydWxlO1xuIl19
48
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm8tZGlyZWN0LXdpbmRvdy1sb2NhdGlvbi1zZWFyY2guanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZXNsaW50LXJ1bGVzL25vLWRpcmVjdC13aW5kb3ctbG9jYXRpb24tc2VhcmNoLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU9BLE1BQU0sSUFBSSxHQUFvQjtJQUM1QixJQUFJLEVBQUU7UUFDSixJQUFJLEVBQUUsWUFBWTtRQUNsQixJQUFJLEVBQUU7WUFDSixXQUFXLEVBQ1Qsc0ZBQXNGO1lBQ3hGLFdBQVcsRUFBRSxLQUFLO1NBQ25CO1FBQ0QsUUFBUSxFQUFFO1lBQ1IsS0FBSyxFQUNILG9HQUFvRztTQUN2RztRQUNELE1BQU0sRUFBRTtZQUNOO2dCQUNFLElBQUksRUFBRSxRQUFRO2dCQUNkLFVBQVUsRUFBRTtvQkFDVixZQUFZLEVBQUUsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsRUFBRTtpQkFDM0Q7Z0JBQ0Qsb0JBQW9CLEVBQUUsS0FBSzthQUM1QjtTQUNGO0tBQ0Y7SUFDRCxNQUFNLENBQUMsT0FBTztRQUNaLE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUE2QixDQUFDO1FBQ2pFLE1BQU0sT0FBTyxHQUFHLElBQUksR0FBRyxDQUFDLFNBQVMsRUFBRSxZQUFZLElBQUksRUFBRSxDQUFDLENBQUM7UUFDdkQsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3ZDLE1BQU0sU0FBUyxHQUFHLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUMxQyxPQUFPLFFBQVEsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDaEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPO1lBQ0wsZ0JBQWdCLENBQUMsSUFBSTtnQkFDbkIsSUFBSSxTQUFTO29CQUFFLE9BQU87Z0JBQ3RCLElBQ0UsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEtBQUssWUFBWTtvQkFDbkMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEtBQUssUUFBUTtvQkFDL0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssa0JBQWtCLEVBQ3ZDLENBQUM7b0JBQ0QsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztvQkFDeEIsSUFDRSxHQUFHLENBQUMsUUFBUSxDQUFDLElBQUksS0FBSyxZQUFZO3dCQUNsQyxHQUFHLENBQUMsUUFBUSxDQUFDLElBQUksS0FBSyxVQUFVO3dCQUNoQyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxZQUFZO3dCQUNoQyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxRQUFRLEVBQzVCLENBQUM7d0JBQ0QsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztvQkFDL0MsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztTQUNGLENBQUM7SUFDSixDQUFDO0NBQ0YsQ0FBQztBQUVGLGVBQWUsSUFBSSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gTW92ZWQgZnJvbSBwYWNrYWdlIHJvb3QgZXNsaW50LXJ1bGVzIGRpcmVjdG9yeSBpbnRvIHNyYyB0byBzYXRpc2Z5IFRTIHJvb3REaXJcbmltcG9ydCB0eXBlIHsgUnVsZSB9IGZyb20gJ2VzbGludCc7XG5cbmludGVyZmFjZSBPcHRpb25zU2hhcGUge1xuICBhbGxvd0luRmlsZXM/OiBzdHJpbmdbXTtcbn1cblxuY29uc3QgcnVsZTogUnVsZS5SdWxlTW9kdWxlID0ge1xuICBtZXRhOiB7XG4gICAgdHlwZTogJ3N1Z2dlc3Rpb24nLFxuICAgIGRvY3M6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnRGlzY291cmFnZSBkaXJlY3Qgd2luZG93LmxvY2F0aW9uLnNlYXJjaCBhY2Nlc3M7IHVzZSB1c2VRdWVyeSgpL3VzZUZpbHRlcnMoKSBpbnN0ZWFkJyxcbiAgICAgIHJlY29tbWVuZGVkOiBmYWxzZSxcbiAgICB9LFxuICAgIG1lc3NhZ2VzOiB7XG4gICAgICBhdm9pZDpcbiAgICAgICAgJ0F2b2lkIGRpcmVjdCBhY2Nlc3MgdG8gd2luZG93LmxvY2F0aW9uLnNlYXJjaC4gVXNlIHVzZVF1ZXJ5KCkgLyB1c2VGaWx0ZXJzKCkgZnJvbSBAcGx1bWlsZS9yb3V0ZXIuJyxcbiAgICB9LFxuICAgIHNjaGVtYTogW1xuICAgICAge1xuICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgIGFsbG93SW5GaWxlczogeyB0eXBlOiAnYXJyYXknLCBpdGVtczogeyB0eXBlOiAnc3RyaW5nJyB9IH0sXG4gICAgICAgIH0sXG4gICAgICAgIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgXSxcbiAgfSxcbiAgY3JlYXRlKGNvbnRleHQpIHtcbiAgICBjb25zdCByYXdPcHRpb24gPSBjb250ZXh0Lm9wdGlvbnNbMF0gYXMgT3B0aW9uc1NoYXBlIHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IGFsbG93SW4gPSBuZXcgU2V0KHJhd09wdGlvbj8uYWxsb3dJbkZpbGVzID8/IFtdKTtcbiAgICBjb25zdCBmaWxlbmFtZSA9IGNvbnRleHQuZ2V0RmlsZW5hbWUoKTtcbiAgICBjb25zdCBpc0FsbG93ZWQgPSBbLi4uYWxsb3dJbl0uc29tZSgocGF0KSA9PiB7XG4gICAgICByZXR1cm4gZmlsZW5hbWUuaW5jbHVkZXMocGF0KTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBNZW1iZXJFeHByZXNzaW9uKG5vZGUpIHtcbiAgICAgICAgaWYgKGlzQWxsb3dlZCkgcmV0dXJuO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgbm9kZS5wcm9wZXJ0eS50eXBlID09PSAnSWRlbnRpZmllcicgJiZcbiAgICAgICAgICBub2RlLnByb3BlcnR5Lm5hbWUgPT09ICdzZWFyY2gnICYmXG4gICAgICAgICAgbm9kZS5vYmplY3QudHlwZSA9PT0gJ01lbWJlckV4cHJlc3Npb24nXG4gICAgICAgICkge1xuICAgICAgICAgIGNvbnN0IG9iaiA9IG5vZGUub2JqZWN0O1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIG9iai5wcm9wZXJ0eS50eXBlID09PSAnSWRlbnRpZmllcicgJiZcbiAgICAgICAgICAgIG9iai5wcm9wZXJ0eS5uYW1lID09PSAnbG9jYXRpb24nICYmXG4gICAgICAgICAgICBvYmoub2JqZWN0LnR5cGUgPT09ICdJZGVudGlmaWVyJyAmJlxuICAgICAgICAgICAgb2JqLm9iamVjdC5uYW1lID09PSAnd2luZG93J1xuICAgICAgICAgICkge1xuICAgICAgICAgICAgY29udGV4dC5yZXBvcnQoeyBub2RlLCBtZXNzYWdlSWQ6ICdhdm9pZCcgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LFxuICAgIH07XG4gIH0sXG59O1xuXG5leHBvcnQgZGVmYXVsdCBydWxlO1xuIl19
@@ -4,6 +4,5 @@ export * from './routing/index.js';
4
4
  export * from './builder.js';
5
5
  export * from './ResourcePage.js';
6
6
  export * from './tools.js';
7
- export { q, parseTypedQuery } from './tools/query-dsl.js';
8
7
  export type * from './types.js';
9
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,cAAc,mBAAmB,CAAC;AAGlC,cAAc,oBAAoB,CAAC;AAGnC,cAAc,oBAAoB,CAAC;AAGnC,cAAc,cAAc,CAAC;AAG7B,cAAc,mBAAmB,CAAC;AAGlC,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,CAAC,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAG1D,mBAAmB,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,cAAc,mBAAmB,CAAC;AAGlC,cAAc,oBAAoB,CAAC;AAGnC,cAAc,oBAAoB,CAAC;AAGnC,cAAc,cAAc,CAAC;AAG7B,cAAc,mBAAmB,CAAC;AAGlC,cAAc,YAAY,CAAC;AAG3B,mBAAmB,YAAY,CAAC"}
package/lib/esm/index.js CHANGED
@@ -4,5 +4,4 @@ export * from './routing/index.js';
4
4
  export * from './builder.js';
5
5
  export * from './ResourcePage.js';
6
6
  export * from './tools.js';
7
- export { q, parseTypedQuery } from './tools/query-dsl.js';
8
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsY0FBYyxtQkFBbUIsQ0FBQztBQUdsQyxjQUFjLG9CQUFvQixDQUFDO0FBR25DLGNBQWMsb0JBQW9CLENBQUM7QUFHbkMsY0FBYyxjQUFjLENBQUM7QUFHN0IsY0FBYyxtQkFBbUIsQ0FBQztBQUdsQyxjQUFjLFlBQVksQ0FBQztBQUMzQixPQUFPLEVBQUUsQ0FBQyxFQUFFLGVBQWUsRUFBRSxNQUFNLHNCQUFzQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gRXhwb3J0IGVycm9yIGhhbmRsaW5nIHV0aWxpdGllc1xuZXhwb3J0ICogZnJvbSAnLi9lcnJvcnMvaW5kZXguanMnO1xuXG4vLyBFeHBvcnQgYnJvd3NlciBoaXN0b3J5IG1hbmFnZW1lbnRcbmV4cG9ydCAqIGZyb20gJy4vaGlzdG9yeS9pbmRleC5qcyc7XG5cbi8vIEV4cG9ydCByb3V0aW5nIGNvbXBvbmVudHMgYW5kIHV0aWxpdGllc1xuZXhwb3J0ICogZnJvbSAnLi9yb3V0aW5nL2luZGV4LmpzJztcblxuLy8gRXhwb3J0IHJvdXRlIGJ1aWxkaW5nIHV0aWxpdGllc1xuZXhwb3J0ICogZnJvbSAnLi9idWlsZGVyLmpzJztcblxuLy8gRXhwb3J0IHJlc291cmNlIHBhZ2UgbWFuYWdlbWVudCBmb3IgbGF6eSBsb2FkaW5nXG5leHBvcnQgKiBmcm9tICcuL1Jlc291cmNlUGFnZS5qcyc7XG5cbi8vIEV4cG9ydCB1dGlsaXR5IGZ1bmN0aW9uc1xuZXhwb3J0ICogZnJvbSAnLi90b29scy5qcyc7XG5leHBvcnQgeyBxLCBwYXJzZVR5cGVkUXVlcnkgfSBmcm9tICcuL3Rvb2xzL3F1ZXJ5LWRzbC5qcyc7XG5cbi8vIEV4cG9ydCBhbGwgVHlwZVNjcmlwdCB0eXBlc1xuZXhwb3J0IHR5cGUgKiBmcm9tICcuL3R5cGVzLmpzJztcbiJdfQ==
7
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsY0FBYyxtQkFBbUIsQ0FBQztBQUdsQyxjQUFjLG9CQUFvQixDQUFDO0FBR25DLGNBQWMsb0JBQW9CLENBQUM7QUFHbkMsY0FBYyxjQUFjLENBQUM7QUFHN0IsY0FBYyxtQkFBbUIsQ0FBQztBQUdsQyxjQUFjLFlBQVksQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEV4cG9ydCBlcnJvciBoYW5kbGluZyB1dGlsaXRpZXNcbmV4cG9ydCAqIGZyb20gJy4vZXJyb3JzL2luZGV4LmpzJztcblxuLy8gRXhwb3J0IGJyb3dzZXIgaGlzdG9yeSBtYW5hZ2VtZW50XG5leHBvcnQgKiBmcm9tICcuL2hpc3RvcnkvaW5kZXguanMnO1xuXG4vLyBFeHBvcnQgcm91dGluZyBjb21wb25lbnRzIGFuZCB1dGlsaXRpZXNcbmV4cG9ydCAqIGZyb20gJy4vcm91dGluZy9pbmRleC5qcyc7XG5cbi8vIEV4cG9ydCByb3V0ZSBidWlsZGluZyB1dGlsaXRpZXNcbmV4cG9ydCAqIGZyb20gJy4vYnVpbGRlci5qcyc7XG5cbi8vIEV4cG9ydCByZXNvdXJjZSBwYWdlIG1hbmFnZW1lbnQgZm9yIGxhenkgbG9hZGluZ1xuZXhwb3J0ICogZnJvbSAnLi9SZXNvdXJjZVBhZ2UuanMnO1xuXG4vLyBFeHBvcnQgdXRpbGl0eSBmdW5jdGlvbnNcbmV4cG9ydCAqIGZyb20gJy4vdG9vbHMuanMnO1xuXG4vLyBFeHBvcnQgYWxsIFR5cGVTY3JpcHQgdHlwZXNcbmV4cG9ydCB0eXBlICogZnJvbSAnLi90eXBlcy5qcyc7XG4iXX0=
@@ -1 +1 @@
1
- {"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../../../src/routing/Link.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EACZ,KAAK,yBAAyB,EAE9B,KAAK,SAAS,EAIf,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAa3E,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,cAAc,GAAG,SAAS,EACnC,QAAQ,EAAE,MAAM,GACf,OAAO,CAmBT;AAKD,KAAK,KAAK,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IAE7E,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,QAAQ,EAAE,SAAS,CAAC;IAEpB,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IAErD,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IAErD,WAAW,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IAEzD,MAAM,CAAC,EAAE,yBAAyB,CAAC;IAEnC,EAAE,CAAC,EAAE,eAAe,GAAG,MAAM,CAAC;IAE9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAyBF,QAAA,MAAM,IAAI,0GAyKR,CAAC;AAEH,eAAe,IAAI,CAAC"}
1
+ {"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../../../src/routing/Link.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EACZ,KAAK,yBAAyB,EAE9B,KAAK,SAAS,EAIf,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAa3E,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,cAAc,GAAG,SAAS,EACnC,QAAQ,EAAE,MAAM,GACf,OAAO,CAmBT;AAKD,KAAK,KAAK,CAAC,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IAE7E,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,QAAQ,EAAE,SAAS,CAAC;IAEpB,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IAErD,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IAErD,WAAW,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IAEzD,MAAM,CAAC,EAAE,yBAAyB,CAAC;IAEnC,EAAE,CAAC,EAAE,eAAe,GAAG,MAAM,CAAC;IAE9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAyBF,QAAA,MAAM,IAAI,0GAuJR,CAAC;AAEH,eAAe,IAAI,CAAC"}