@vertz/ui 0.2.11 → 0.2.13

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 (35) hide show
  1. package/README.md +70 -6
  2. package/dist/shared/{chunk-n91rwj2r.js → chunk-2sth83bd.js} +4 -2
  3. package/dist/shared/{chunk-9e92w0wt.js → chunk-83g4h38e.js} +13 -0
  4. package/dist/shared/{chunk-hrd0mft1.js → chunk-8hsz5y4a.js} +102 -37
  5. package/dist/shared/{chunk-q6cpe5k7.js → chunk-c30eg6wn.js} +1 -1
  6. package/dist/shared/{chunk-qacth5ah.js → chunk-c9xxsrat.js} +7 -2
  7. package/dist/shared/{chunk-v3yyf79g.js → chunk-dksg08fq.js} +1 -1
  8. package/dist/shared/{chunk-g4rch80a.js → chunk-h89w580h.js} +7 -0
  9. package/dist/shared/chunk-hw67ckr3.js +1212 -0
  10. package/dist/shared/{chunk-ryb49346.js → chunk-j6qyxfdc.js} +7 -7
  11. package/dist/shared/{chunk-ka5ked7n.js → chunk-mj7b4t40.js} +107 -41
  12. package/dist/shared/{chunk-0xcmwgdb.js → chunk-nn9v1zmk.js} +6 -6
  13. package/dist/src/auth/public.d.ts +303 -0
  14. package/dist/src/auth/public.js +773 -0
  15. package/dist/src/css/public.js +22 -0
  16. package/dist/{form → src/form}/public.js +2 -2
  17. package/dist/{index.d.ts → src/index.d.ts} +220 -15
  18. package/dist/{index.js → src/index.js} +96 -232
  19. package/dist/{internals.d.ts → src/internals.d.ts} +266 -4
  20. package/dist/{internals.js → src/internals.js} +35 -26
  21. package/dist/{jsx-runtime → src/jsx-runtime}/index.d.ts +1 -1
  22. package/dist/{jsx-runtime → src/jsx-runtime}/index.js +1 -1
  23. package/dist/{query → src/query}/public.d.ts +3 -1
  24. package/dist/src/query/public.js +15 -0
  25. package/dist/{router → src/router}/public.d.ts +25 -4
  26. package/dist/{router → src/router}/public.js +9 -9
  27. package/dist/{test → src/test}/index.d.ts +12 -2
  28. package/dist/{test → src/test}/index.js +4 -4
  29. package/package.json +31 -25
  30. package/reactivity.json +67 -0
  31. package/dist/css/public.js +0 -22
  32. package/dist/query/public.js +0 -15
  33. package/dist/shared/chunk-rjjjvmcf.js +0 -528
  34. /package/dist/{css → src/css}/public.d.ts +0 -0
  35. /package/dist/{form → src/form}/public.d.ts +0 -0
@@ -11,9 +11,36 @@ interface Signal<T> {
11
11
  /** Manually notify all subscribers (useful after mutating the value in place). */
12
12
  notify(): void;
13
13
  }
14
+ /**
15
+ * A read-only reactive value derived from other signals.
16
+ */
17
+ interface ReadonlySignal<T> {
18
+ /** Get the current value and subscribe to changes. */
19
+ readonly value: T;
20
+ /** Read the current value without subscribing. */
21
+ peek(): T;
22
+ }
14
23
  /** Dispose function returned by effect(). */
15
24
  type DisposeFn = () => void;
16
25
  /**
26
+ * Internal: any object that owns a `_subscribers` set.
27
+ * Used by subscribers to track their sources for cleanup.
28
+ */
29
+ interface SubscriberSource {
30
+ _subscribers: Set<Subscriber>;
31
+ }
32
+ /** Internal subscriber interface for the reactive graph. */
33
+ interface Subscriber {
34
+ /** Called when a dependency has changed. */
35
+ _notify(): void;
36
+ /** Unique ID for deduplication in batch queue. */
37
+ _id: number;
38
+ /** Whether this is an effect (leaf subscriber) or computed (intermediate). */
39
+ _isEffect: boolean;
40
+ /** Track a source that this subscriber reads from. */
41
+ _addSource(source: SubscriberSource): void;
42
+ }
43
+ /**
17
44
  * A snapshot of context values at a point in time.
18
45
  * Each Provider creates a new scope that inherits from the parent.
19
46
  * Effects capture this scope so that useContext works in async callbacks.
@@ -195,7 +222,7 @@ declare function setAdapter(adapter: RenderAdapter | null): void;
195
222
  * If no animations are running, calls back immediately.
196
223
  * Respects prefers-reduced-motion by skipping the wait.
197
224
  */
198
- declare function onAnimationsComplete(el: HTMLElement, callback: () => void): void;
225
+ declare function onAnimationsComplete(el: Element, callback: () => void): void;
199
226
  /**
200
227
  * Create a reactive attribute binding.
201
228
  * When the value returned by `fn` changes, the attribute is updated.
@@ -429,7 +456,7 @@ type ExtractParams<T extends string> = [ExtractParamsFromSegments<WithoutWildcar
429
456
  } : Record<string, never> : HasWildcard<T> extends true ? { [K in ExtractParamsFromSegments<WithoutWildcard<T>>] : string } & {
430
457
  "*": string;
431
458
  } : { [K in ExtractParamsFromSegments<WithoutWildcard<T>>] : string };
432
- /** Simple schema interface for search param parsing. */
459
+ /** Schema interface for parsing and validating values (search params, path params). */
433
460
  interface SearchParamSchema<T> {
434
461
  parse(data: unknown): {
435
462
  ok: true;
@@ -439,11 +466,14 @@ interface SearchParamSchema<T> {
439
466
  error: unknown;
440
467
  };
441
468
  }
469
+ /** Schema interface for parsing and validating route path params. */
470
+ type ParamSchema<T> = SearchParamSchema<T>;
442
471
  /** A route configuration for a single path. */
443
472
  interface RouteConfig<
444
473
  TPath extends string = string,
445
474
  TLoaderData = unknown,
446
- TSearch = unknown
475
+ TSearch = unknown,
476
+ TParams = unknown
447
477
  > {
448
478
  /** Component factory (lazy for code splitting). */
449
479
  component: () => Node | Promise<{
@@ -456,6 +486,8 @@ interface RouteConfig<
456
486
  }) => Promise<TLoaderData> | TLoaderData;
457
487
  /** Optional error component rendered when loader throws. */
458
488
  errorComponent?: (error: Error) => Node;
489
+ /** Optional path params schema for validation/parsing. */
490
+ params?: ParamSchema<TParams>;
459
491
  /** Optional search params schema for validation/coercion. */
460
492
  searchParams?: SearchParamSchema<TSearch>;
461
493
  /** Nested child routes. */
@@ -476,6 +508,8 @@ interface CompiledRoute {
476
508
  signal: AbortSignal;
477
509
  }) => Promise<unknown> | unknown;
478
510
  errorComponent?: RouteConfig["errorComponent"];
511
+ /** Optional path params schema for validation/parsing. */
512
+ params?: ParamSchema<unknown>;
479
513
  searchParams?: RouteConfig["searchParams"];
480
514
  /** Compiled children. */
481
515
  children?: CompiledRoute[];
@@ -489,6 +523,8 @@ interface MatchedRoute {
489
523
  interface RouteMatch {
490
524
  /** All params extracted from the full URL path. */
491
525
  params: Record<string, string>;
526
+ /** Parsed params via schema (set when route has a params schema and parse succeeds). */
527
+ parsedParams?: Record<string, unknown>;
492
528
  /** The leaf route config that matched. */
493
529
  route: CompiledRoute;
494
530
  /** The chain of matched routes from root to leaf (for nested layouts). */
@@ -585,4 +621,230 @@ declare function domEffect(fn: () => void): DisposeFn;
585
621
  * Returns a dispose function to stop the effect.
586
622
  */
587
623
  declare function lifecycleEffect(fn: () => void): DisposeFn;
588
- export { stopSignalCollection, startSignalCollection, setContextScope, setAdapter, runCleanups, resolveComponent, removeNode, pushScope, popScope, onCleanup, onAnimationsComplete, matchRoute, matchPath, lifecycleEffect, isRenderNode, insertBefore, getContextScope, getAdapter, executeLoaders, domEffect, deserializeProps, deriveKey, createDOMAdapter, compileTheme, clearChildren, _tryOnCleanup, __text, __staticText, __show, __on, __list, __insert, __exitChildren, __enterChildren, __element, __conditional, __classList, __child, __attr, __append, SPACING_SCALE, SIZE_KEYWORDS, SHADOW_SCALE, RenderText, RenderNode, RenderElement, RenderAdapter, RENDER_NODE_BRAND, RADIUS_SCALE, PropertyMapping, PSEUDO_PREFIXES, PSEUDO_MAP, PROPERTY_MAP, MemoryCache, MatchResult, LINE_HEIGHT_SCALE, KEYWORD_MAP, HEIGHT_AXIS_PROPERTIES, FONT_WEIGHT_SCALE, FONT_SIZE_SCALE, DISPLAY_MAP, CSS_COLOR_KEYWORDS, CSSDeclarationEntry, CONTENT_MAP, COLOR_NAMESPACES, ALIGNMENT_MAP };
624
+ /**
625
+ * QueryResultIndex tracks ordered arrays of entity IDs for list queries.
626
+ * Used to maintain list query results and invalidate on entity removal.
627
+ */
628
+ declare class QueryResultIndex {
629
+ private _indices;
630
+ /**
631
+ * Set the result IDs for a query key.
632
+ */
633
+ set(queryKey: string, ids: string[]): void;
634
+ /**
635
+ * Get the result IDs for a query key.
636
+ */
637
+ get(queryKey: string): string[] | undefined;
638
+ /**
639
+ * Remove an entity ID from all indices (called after entity delete).
640
+ */
641
+ removeEntity(entityId: string): void;
642
+ /**
643
+ * Clear a specific query's index (for revalidation).
644
+ */
645
+ clear(queryKey: string): void;
646
+ /**
647
+ * Snapshot all indices containing the given entity ID.
648
+ * Returns a Map of queryKey → full ID array (copy) for rollback support.
649
+ */
650
+ snapshotEntity(entityId: string): Map<string, string[]>;
651
+ /**
652
+ * Get all query keys (for serialization).
653
+ */
654
+ keys(): string[];
655
+ }
656
+ /**
657
+ * Serialized format for EntityStore - used for SSR transfer and hydration.
658
+ */
659
+ interface SerializedStore {
660
+ /** Entity data keyed by type → id → entity */
661
+ entities: Record<string, Record<string, unknown>>;
662
+ /** Query result indices (optional) */
663
+ queries?: Record<string, {
664
+ ids: string[];
665
+ nextCursor?: string | null;
666
+ }>;
667
+ }
668
+ /**
669
+ * Options for EntityStore constructor.
670
+ */
671
+ interface EntityStoreOptions {
672
+ /** Initial data to hydrate from (SSR). */
673
+ initialData?: SerializedStore;
674
+ }
675
+ /**
676
+ * EntityStore - Normalized, signal-backed entity cache for @vertz/ui.
677
+ *
678
+ * Stores entities by type and ID, with signal-per-entity reactivity.
679
+ * Supports field-level merge, SSR hydration, optimistic layers, and query result indices.
680
+ */
681
+ declare class EntityStore {
682
+ private _entities;
683
+ private _typeListeners;
684
+ private _queryIndices;
685
+ /** Public accessor for query indices — used by optimistic handlers and tests. */
686
+ get queryIndices(): QueryResultIndex;
687
+ constructor(options?: EntityStoreOptions);
688
+ /**
689
+ * Read a single entity. Returns a signal that updates on merge.
690
+ * Returns the same signal instance on repeated calls (identity stability).
691
+ */
692
+ get<T>(type: string, id: string): ReadonlySignal<T | undefined>;
693
+ /**
694
+ * Read multiple entities by IDs. Returns a computed signal of the array.
695
+ * Returns a NEW computed signal each call (not cached).
696
+ */
697
+ getMany<T>(type: string, ids: string[]): ReadonlySignal<(T | undefined)[]>;
698
+ /**
699
+ * Merge one or more entities into the store.
700
+ * Field-level merge with shallow diff - only updates signals if data changed.
701
+ * Uses batch() to coalesce multiple updates into single reactive flush.
702
+ * Uses untrack() to prevent circular re-triggering when called from effects.
703
+ */
704
+ merge<T extends {
705
+ id: string;
706
+ }>(type: string, data: T | T[]): void;
707
+ /**
708
+ * Remove an entity from the store.
709
+ * Triggers type change listeners and removes from query indices.
710
+ */
711
+ remove(type: string, id: string): void;
712
+ /**
713
+ * Subscribe to type-level changes (create/delete, not field updates).
714
+ * Returns an unsubscribe function.
715
+ */
716
+ onTypeChange(type: string, callback: () => void): () => void;
717
+ /**
718
+ * Check if an entity exists in the store.
719
+ */
720
+ has(type: string, id: string): boolean;
721
+ /**
722
+ * Get count of entities for a type.
723
+ */
724
+ size(type: string): number;
725
+ /**
726
+ * Serialize the store for SSR transfer.
727
+ * Serializes base values only — optimistic layers are transient.
728
+ */
729
+ dehydrate(): SerializedStore;
730
+ /**
731
+ * Hydrate from serialized data. Merges into existing store (doesn't replace).
732
+ */
733
+ hydrate(data: SerializedStore): void;
734
+ /**
735
+ * Apply an optimistic layer to an entity.
736
+ * The layer is stacked on top of base, recomputing the visible signal value.
737
+ */
738
+ applyLayer(type: string, id: string, mutationId: string, patch: Record<string, unknown>): void;
739
+ /**
740
+ * Increment the reference count for an entity.
741
+ * Clears orphanedAt timestamp. No-op if entity doesn't exist.
742
+ */
743
+ addRef(type: string, id: string): void;
744
+ /**
745
+ * Decrement the reference count for an entity.
746
+ * Sets orphanedAt when refCount reaches 0. No-op if entity doesn't exist.
747
+ */
748
+ removeRef(type: string, id: string): void;
749
+ /**
750
+ * Evict orphaned entities (refCount=0) that have been unreferenced
751
+ * for longer than maxAge ms. Entities with pending layers are preserved.
752
+ * Default maxAge: 5 minutes.
753
+ */
754
+ evictOrphans(maxAge?: number): number;
755
+ /**
756
+ * Inspect the internal state of an entity — for debugging and testing.
757
+ * Returns base, layers, visible (computed) state, refCount, and orphanedAt.
758
+ */
759
+ inspect(type: string, id: string): {
760
+ base: Record<string, unknown>;
761
+ layers: Map<string, Record<string, unknown>>;
762
+ visible: unknown;
763
+ refCount: number;
764
+ orphanedAt: number | null;
765
+ } | undefined;
766
+ /**
767
+ * Rollback an optimistic layer (mutation failed).
768
+ * Removes the layer and recomputes visible from base + remaining layers.
769
+ */
770
+ rollbackLayer(type: string, id: string, mutationId: string): void;
771
+ /**
772
+ * Optimistically remove an entity (for delete mutations).
773
+ * Removes the entity from the store and query indices.
774
+ * Caller should snapshot entity + indices beforehand for rollback.
775
+ */
776
+ removeOptimistic(type: string, id: string, _mutationId: string): void;
777
+ /**
778
+ * Restore an entity after a failed optimistic delete.
779
+ * Re-merges the entity and restores query index positions.
780
+ */
781
+ restoreOptimistic(type: string, _id: string, _mutationId: string, entitySnapshot: unknown, indexSnapshot: Map<string, string[]>): void;
782
+ /**
783
+ * Commit an optimistic layer after server confirms the mutation.
784
+ * Sets base to server data, removes the layer, recomputes visible.
785
+ */
786
+ commitLayer(type: string, id: string, mutationId: string, serverData: Record<string, unknown>): void;
787
+ /**
788
+ * Merge a single (already normalized) entity into the store.
789
+ */
790
+ private _mergeOne;
791
+ /**
792
+ * Recompute the visible signal value from base + all layers.
793
+ */
794
+ private _recomputeVisible;
795
+ private _getOrCreateTypeMap;
796
+ private _getOrCreateListeners;
797
+ private _notifyTypeChange;
798
+ }
799
+ /** Envelope metadata for list queries (pagination info without entity data). */
800
+ interface QueryEnvelope {
801
+ total?: number;
802
+ limit?: number;
803
+ nextCursor?: string | null;
804
+ hasNextPage?: boolean;
805
+ [key: string]: unknown;
806
+ }
807
+ /**
808
+ * Stores list query envelope metadata per query key.
809
+ * Decoupled from entity data — entities live in EntityStore,
810
+ * envelopes live here. Allows list query reconstruction from
811
+ * EntityStore data + envelope metadata.
812
+ */
813
+ declare class QueryEnvelopeStore {
814
+ private _envelopes;
815
+ get(queryKey: string): QueryEnvelope | undefined;
816
+ set(queryKey: string, envelope: QueryEnvelope): void;
817
+ clear(): void;
818
+ }
819
+ /** Entry registered by query() during SSR for renderToHTML() to await. */
820
+ interface SSRQueryEntry {
821
+ promise: Promise<unknown>;
822
+ timeout: number;
823
+ resolve: (data: unknown) => void;
824
+ key: string;
825
+ resolved?: boolean;
826
+ }
827
+ interface SSRRenderContext {
828
+ url: string;
829
+ adapter: RenderAdapter;
830
+ subscriber: Subscriber | null;
831
+ readValueCb: ((value: unknown) => void) | null;
832
+ cleanupStack: DisposeFn[][];
833
+ batchDepth: number;
834
+ pendingEffects: Map<number, Subscriber>;
835
+ contextScope: ContextScope | null;
836
+ entityStore: EntityStore;
837
+ envelopeStore: QueryEnvelopeStore;
838
+ queryCache: MemoryCache<unknown>;
839
+ inflight: Map<string, Promise<unknown>>;
840
+ /** SSR queries registered for awaiting before final render. */
841
+ queries: SSRQueryEntry[];
842
+ /** Errors collected during SSR rendering. */
843
+ errors: unknown[];
844
+ /** Global per-query timeout override (ms). */
845
+ globalSSRTimeout?: number;
846
+ }
847
+ type SSRContextResolver = () => SSRRenderContext | undefined;
848
+ declare function registerSSRResolver(resolver: SSRContextResolver | null): void;
849
+ declare function getSSRContext(): SSRRenderContext | undefined;
850
+ export { stopSignalCollection, startSignalCollection, setContextScope, setAdapter, runCleanups, resolveComponent, removeNode, registerSSRResolver, pushScope, popScope, onCleanup, onAnimationsComplete, matchRoute, matchPath, lifecycleEffect, isRenderNode, insertBefore, getSSRContext, getContextScope, getAdapter, executeLoaders, domEffect, deserializeProps, deriveKey, createDOMAdapter, compileTheme, clearChildren, _tryOnCleanup, __text, __staticText, __show, __on, __list, __insert, __exitChildren, __enterChildren, __element, __conditional, __classList, __child, __attr, __append, SSRRenderContext, SSRQueryEntry, SPACING_SCALE, SIZE_KEYWORDS, SHADOW_SCALE, RenderText, RenderNode, RenderElement, RenderAdapter, RENDER_NODE_BRAND, RADIUS_SCALE, QueryEnvelopeStore, PropertyMapping, PSEUDO_PREFIXES, PSEUDO_MAP, PROPERTY_MAP, MemoryCache, MatchResult, LINE_HEIGHT_SCALE, KEYWORD_MAP, HEIGHT_AXIS_PROPERTIES, FONT_WEIGHT_SCALE, FONT_SIZE_SCALE, EntityStore, DISPLAY_MAP, CSS_COLOR_KEYWORDS, CSSDeclarationEntry, CONTENT_MAP, COLOR_NAMESPACES, ALIGNMENT_MAP };
@@ -2,23 +2,25 @@ import {
2
2
  deserializeProps,
3
3
  onAnimationsComplete,
4
4
  resolveComponent
5
- } from "./shared/chunk-n91rwj2r.js";
5
+ } from "../shared/chunk-2sth83bd.js";
6
6
  import {
7
7
  __attr,
8
8
  __classList,
9
9
  __on,
10
10
  __show
11
- } from "./shared/chunk-v3yyf79g.js";
11
+ } from "../shared/chunk-dksg08fq.js";
12
12
  import {
13
13
  executeLoaders,
14
14
  matchPath,
15
15
  matchRoute
16
- } from "./shared/chunk-9e92w0wt.js";
16
+ } from "../shared/chunk-83g4h38e.js";
17
17
  import {
18
+ EntityStore,
18
19
  MemoryCache,
20
+ QueryEnvelopeStore,
19
21
  deriveKey
20
- } from "./shared/chunk-rjjjvmcf.js";
21
- import"./shared/chunk-jrtrk5z4.js";
22
+ } from "../shared/chunk-hw67ckr3.js";
23
+ import"../shared/chunk-jrtrk5z4.js";
22
24
  import {
23
25
  ALIGNMENT_MAP,
24
26
  COLOR_NAMESPACES,
@@ -38,7 +40,7 @@ import {
38
40
  SIZE_KEYWORDS,
39
41
  SPACING_SCALE,
40
42
  compileTheme
41
- } from "./shared/chunk-qacth5ah.js";
43
+ } from "../shared/chunk-c9xxsrat.js";
42
44
  import {
43
45
  __append,
44
46
  __child,
@@ -51,30 +53,47 @@ import {
51
53
  claimComment,
52
54
  claimText,
53
55
  getIsHydrating
54
- } from "./shared/chunk-ryb49346.js";
56
+ } from "../shared/chunk-j6qyxfdc.js";
57
+ import"../shared/chunk-prj7nm08.js";
55
58
  import {
56
59
  RENDER_NODE_BRAND,
57
60
  createDOMAdapter,
58
61
  getAdapter,
59
62
  isRenderNode,
60
63
  setAdapter
61
- } from "./shared/chunk-g4rch80a.js";
64
+ } from "../shared/chunk-h89w580h.js";
62
65
  import {
63
66
  _tryOnCleanup,
64
67
  domEffect,
65
68
  getContextScope,
69
+ getSSRContext,
66
70
  lifecycleEffect,
67
71
  onCleanup,
68
72
  popScope,
69
73
  pushScope,
74
+ registerSSRResolver,
70
75
  runCleanups,
71
76
  setContextScope,
72
77
  signal,
73
78
  startSignalCollection,
74
79
  stopSignalCollection
75
- } from "./shared/chunk-hrd0mft1.js";
76
- import"./shared/chunk-prj7nm08.js";
80
+ } from "../shared/chunk-8hsz5y4a.js";
77
81
  // src/dom/conditional.ts
82
+ function normalizeNode(branchResult) {
83
+ if (branchResult == null || typeof branchResult === "boolean") {
84
+ return getAdapter().createComment("empty");
85
+ }
86
+ if (isRenderNode(branchResult)) {
87
+ if (branchResult.nodeType === 11) {
88
+ const wrap = getAdapter().createElement("span");
89
+ wrap.style.display = "contents";
90
+ wrap.appendChild(branchResult);
91
+ return wrap;
92
+ }
93
+ return branchResult;
94
+ }
95
+ return getAdapter().createTextNode(String(branchResult));
96
+ }
78
97
  function __conditional(condFn, trueFn, falseFn) {
79
98
  if (getIsHydrating()) {
80
99
  return hydrateConditional(condFn, trueFn, falseFn);
@@ -110,14 +129,7 @@ function hydrateConditional(condFn, trueFn, falseFn) {
110
129
  const branchResult = show ? trueFn() : falseFn();
111
130
  popScope();
112
131
  branchCleanups = scope;
113
- let newNode;
114
- if (branchResult == null || typeof branchResult === "boolean") {
115
- newNode = getAdapter().createComment("empty");
116
- } else if (isRenderNode(branchResult)) {
117
- newNode = branchResult;
118
- } else {
119
- newNode = getAdapter().createTextNode(String(branchResult));
120
- }
132
+ const newNode = normalizeNode(branchResult);
121
133
  if (currentNode?.parentNode) {
122
134
  currentNode.parentNode.replaceChild(newNode, currentNode);
123
135
  } else if (anchor.parentNode) {
@@ -148,14 +160,7 @@ function csrConditional(condFn, trueFn, falseFn) {
148
160
  const branchResult = show ? trueFn() : falseFn();
149
161
  popScope();
150
162
  branchCleanups = scope;
151
- let newNode;
152
- if (branchResult == null || typeof branchResult === "boolean") {
153
- newNode = getAdapter().createComment("empty");
154
- } else if (isRenderNode(branchResult)) {
155
- newNode = branchResult;
156
- } else {
157
- newNode = getAdapter().createTextNode(String(branchResult));
158
- }
163
+ const newNode = normalizeNode(branchResult);
159
164
  if (currentNode?.parentNode) {
160
165
  currentNode.parentNode.replaceChild(newNode, currentNode);
161
166
  } else if (anchor.parentNode) {
@@ -311,6 +316,7 @@ export {
311
316
  runCleanups,
312
317
  resolveComponent,
313
318
  removeNode,
319
+ registerSSRResolver,
314
320
  pushScope,
315
321
  popScope,
316
322
  onCleanup,
@@ -320,6 +326,7 @@ export {
320
326
  lifecycleEffect,
321
327
  isRenderNode,
322
328
  insertBefore,
329
+ getSSRContext,
323
330
  getContextScope,
324
331
  getAdapter,
325
332
  executeLoaders,
@@ -349,6 +356,7 @@ export {
349
356
  SHADOW_SCALE,
350
357
  RENDER_NODE_BRAND,
351
358
  RADIUS_SCALE,
359
+ QueryEnvelopeStore,
352
360
  PSEUDO_PREFIXES,
353
361
  PSEUDO_MAP,
354
362
  PROPERTY_MAP,
@@ -358,6 +366,7 @@ export {
358
366
  HEIGHT_AXIS_PROPERTIES,
359
367
  FONT_WEIGHT_SCALE,
360
368
  FONT_SIZE_SCALE,
369
+ EntityStore,
361
370
  DISPLAY_MAP,
362
371
  CSS_COLOR_KEYWORDS,
363
372
  CONTENT_MAP,
@@ -3,7 +3,7 @@
3
3
  * to understand intrinsic element types and component types.
4
4
  */
5
5
  declare namespace JSX {
6
- type Element = HTMLElement | SVGElement;
6
+ type Element = HTMLElement | SVGElement | DocumentFragment;
7
7
  type JSXComponent = (props: Record<string, unknown>) => Element;
8
8
  interface HTMLAttributes {
9
9
  [key: string]: unknown;
@@ -2,7 +2,7 @@ import {
2
2
  SVG_NS,
3
3
  isSVGTag,
4
4
  normalizeSVGAttr
5
- } from "../shared/chunk-prj7nm08.js";
5
+ } from "../../shared/chunk-prj7nm08.js";
6
6
 
7
7
  // src/jsx-runtime/index.ts
8
8
  function applyChildren(parent, children) {
@@ -10,7 +10,7 @@ interface CacheStore<T = unknown> {
10
10
  delete(key: string): void;
11
11
  clear?(): void;
12
12
  }
13
- import { QueryDescriptor } from "@vertz/fetch";
13
+ import { EntityQueryMeta, QueryDescriptor } from "@vertz/fetch";
14
14
  /**
15
15
  * A read-only reactive value derived from other signals.
16
16
  */
@@ -56,6 +56,8 @@ interface QueryOptions<T> {
56
56
  * when the function returns `false`).
57
57
  */
58
58
  refetchInterval?: number | false | ((data: T | undefined, iteration: number) => number | false);
59
+ /** @internal Entity metadata for entity-backed queries. Set by descriptor overload. */
60
+ _entityMeta?: EntityQueryMeta;
59
61
  }
60
62
  /** The reactive object returned by query(). */
61
63
  interface QueryResult<
@@ -0,0 +1,15 @@
1
+ import {
2
+ query,
3
+ queryMatch
4
+ } from "../../shared/chunk-hw67ckr3.js";
5
+ import"../../shared/chunk-jrtrk5z4.js";
6
+ import"../../shared/chunk-h89w580h.js";
7
+ import"../../shared/chunk-8hsz5y4a.js";
8
+
9
+ // src/query/public.ts
10
+ import { isQueryDescriptor } from "@vertz/fetch";
11
+ export {
12
+ queryMatch,
13
+ query,
14
+ isQueryDescriptor
15
+ };
@@ -44,7 +44,7 @@ type PathWithParams<T extends string> = T extends `${infer Before}*` ? `${PathWi
44
44
  * ```
45
45
  */
46
46
  type RoutePaths<TRouteMap extends Record<string, unknown>> = { [K in keyof TRouteMap & string] : PathWithParams<K> }[keyof TRouteMap & string];
47
- /** Simple schema interface for search param parsing. */
47
+ /** Schema interface for parsing and validating values (search params, path params). */
48
48
  interface SearchParamSchema<T> {
49
49
  parse(data: unknown): {
50
50
  ok: true;
@@ -54,11 +54,14 @@ interface SearchParamSchema<T> {
54
54
  error: unknown;
55
55
  };
56
56
  }
57
+ /** Schema interface for parsing and validating route path params. */
58
+ type ParamSchema<T> = SearchParamSchema<T>;
57
59
  /** A route configuration for a single path. */
58
60
  interface RouteConfig<
59
61
  TPath extends string = string,
60
62
  TLoaderData = unknown,
61
- TSearch = unknown
63
+ TSearch = unknown,
64
+ TParams = unknown
62
65
  > {
63
66
  /** Component factory (lazy for code splitting). */
64
67
  component: () => Node | Promise<{
@@ -71,6 +74,8 @@ interface RouteConfig<
71
74
  }) => Promise<TLoaderData> | TLoaderData;
72
75
  /** Optional error component rendered when loader throws. */
73
76
  errorComponent?: (error: Error) => Node;
77
+ /** Optional path params schema for validation/parsing. */
78
+ params?: ParamSchema<TParams>;
74
79
  /** Optional search params schema for validation/coercion. */
75
80
  searchParams?: SearchParamSchema<TSearch>;
76
81
  /** Nested child routes. */
@@ -101,6 +106,7 @@ interface RouteConfigLike {
101
106
  signal: AbortSignal;
102
107
  }): unknown;
103
108
  errorComponent?: (error: Error) => Node;
109
+ params?: ParamSchema<unknown>;
104
110
  searchParams?: SearchParamSchema<unknown>;
105
111
  children?: Record<string, RouteConfigLike>;
106
112
  }
@@ -131,6 +137,8 @@ interface CompiledRoute {
131
137
  signal: AbortSignal;
132
138
  }) => Promise<unknown> | unknown;
133
139
  errorComponent?: RouteConfig["errorComponent"];
140
+ /** Optional path params schema for validation/parsing. */
141
+ params?: ParamSchema<unknown>;
134
142
  searchParams?: RouteConfig["searchParams"];
135
143
  /** Compiled children. */
136
144
  children?: CompiledRoute[];
@@ -144,6 +152,8 @@ interface MatchedRoute {
144
152
  interface RouteMatch {
145
153
  /** All params extracted from the full URL path. */
146
154
  params: Record<string, string>;
155
+ /** Parsed params via schema (set when route has a params schema and parse succeeds). */
156
+ parsedParams?: Record<string, unknown>;
147
157
  /** The leaf route config that matched. */
148
158
  route: CompiledRoute;
149
159
  /** The chain of matched routes from root to leaf (for nested layouts). */
@@ -304,7 +314,7 @@ type TypedRouter<T extends Record<string, RouteConfigLike> = RouteDefinitionMap>
304
314
  * Create a router instance.
305
315
  *
306
316
  * @param routes - Compiled route list from defineRoutes()
307
- * @param initialUrl - The initial URL to match (optional; auto-detects from window.location or __SSR_URL__)
317
+ * @param initialUrl - The initial URL to match (optional; auto-detects from window.location or SSR context)
308
318
  * @returns Router instance with reactive state and navigation methods
309
319
  */
310
320
  declare function createRouter<T extends Record<string, RouteConfigLike> = RouteDefinitionMap>(routes: TypedRoutes<T>, initialUrl?: string, options?: RouterOptions): Router<T>;
@@ -351,7 +361,18 @@ declare const OutletContext: Context<OutletContextValue>;
351
361
  declare function Outlet(): Node;
352
362
  declare const RouterContext: Context<Router>;
353
363
  declare function useRouter<T extends Record<string, RouteConfigLike> = RouteDefinitionMap>(): UnwrapSignals<Router<T>>;
364
+ /**
365
+ * Read route params from the current matched route.
366
+ *
367
+ * Overload 1: `useParams<'/tasks/:id'>()` — returns `{ id: string }` (backward compat).
368
+ * Overload 2: `useParams<{ id: number }>()` — returns parsed type assertion
369
+ * (reads `parsedParams` when a route has a `params` schema).
370
+ *
371
+ * At runtime, both overloads prefer `parsedParams` (schema-parsed) when available,
372
+ * falling back to raw `params` (string values).
373
+ */
354
374
  declare function useParams<TPath extends string = string>(): ExtractParams<TPath>;
375
+ declare function useParams<T extends Record<string, unknown>>(): T;
355
376
  interface RouterViewProps {
356
377
  router: Router;
357
378
  fallback?: () => Node;
@@ -384,4 +405,4 @@ declare function parseSearchParams<T = Record<string, string>>(urlParams: URLSea
384
405
  * @returns The current search params value
385
406
  */
386
407
  declare function useSearchParams<T>(searchSignal: ReadonlySignal<T>): T;
387
- export { useSearchParams, useRouter, useParams, parseSearchParams, defineRoutes, createRouter, createLink, TypedRoutes, TypedRouter, SearchParamSchema, RouterViewProps, RouterView, RouterContext, Router, RoutePaths, RouteMatch, RouteDefinitionMap, RouteConfig, PathWithParams, OutletContextValue, OutletContext, Outlet, NavigateOptions, MatchedRoute, LoaderData, LinkProps, InferRouteMap, ExtractParams, CompiledRoute };
408
+ export { useSearchParams, useRouter, useParams, parseSearchParams, defineRoutes, createRouter, createLink, TypedRoutes, TypedRouter, SearchParamSchema, RouterViewProps, RouterView, RouterContext, Router, RoutePaths, RouteMatch, RouteDefinitionMap, RouteConfig, PathWithParams, ParamSchema, OutletContextValue, OutletContext, Outlet, NavigateOptions, MatchedRoute, LoaderData, LinkProps, InferRouteMap, ExtractParams, CompiledRoute };
@@ -8,19 +8,19 @@ import {
8
8
  useParams,
9
9
  useRouter,
10
10
  useSearchParams
11
- } from "../shared/chunk-0xcmwgdb.js";
12
- import"../shared/chunk-v3yyf79g.js";
11
+ } from "../../shared/chunk-nn9v1zmk.js";
12
+ import"../../shared/chunk-dksg08fq.js";
13
13
  import {
14
14
  createRouter
15
- } from "../shared/chunk-ka5ked7n.js";
15
+ } from "../../shared/chunk-mj7b4t40.js";
16
16
  import {
17
17
  defineRoutes
18
- } from "../shared/chunk-9e92w0wt.js";
19
- import"../shared/chunk-jrtrk5z4.js";
20
- import"../shared/chunk-ryb49346.js";
21
- import"../shared/chunk-g4rch80a.js";
22
- import"../shared/chunk-hrd0mft1.js";
23
- import"../shared/chunk-prj7nm08.js";
18
+ } from "../../shared/chunk-83g4h38e.js";
19
+ import"../../shared/chunk-jrtrk5z4.js";
20
+ import"../../shared/chunk-j6qyxfdc.js";
21
+ import"../../shared/chunk-prj7nm08.js";
22
+ import"../../shared/chunk-h89w580h.js";
23
+ import"../../shared/chunk-8hsz5y4a.js";
24
24
  export {
25
25
  useSearchParams,
26
26
  useRouter,