@epoch32/visage 1.0.0 → 1.1.1

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 (137) hide show
  1. package/dist/api/client.d.ts +5 -0
  2. package/dist/api/file-router.d.ts +29 -0
  3. package/dist/api/handler.d.ts +15 -0
  4. package/dist/api/index.d.ts +12 -0
  5. package/dist/{src/api → api}/index.js +87 -2
  6. package/dist/api/middleware.d.ts +11 -0
  7. package/dist/api/pragma.d.ts +21 -0
  8. package/dist/api/procedure.d.ts +66 -0
  9. package/dist/api/types.d.ts +181 -0
  10. package/dist/charts/Area.d.ts +18 -0
  11. package/dist/charts/Axis.d.ts +21 -0
  12. package/dist/charts/Bar.d.ts +10 -0
  13. package/dist/charts/CartesianGrid.d.ts +10 -0
  14. package/dist/charts/Chart.d.ts +16 -0
  15. package/dist/charts/Cursor.d.ts +8 -0
  16. package/dist/charts/Legend.d.ts +9 -0
  17. package/dist/charts/Line.d.ts +18 -0
  18. package/dist/charts/Pie.d.ts +12 -0
  19. package/dist/charts/Tooltip.d.ts +12 -0
  20. package/dist/charts/context.d.ts +20 -0
  21. package/dist/charts/index.d.ts +14 -0
  22. package/dist/{src/charts → charts}/index.js +87 -2
  23. package/dist/charts/path.d.ts +27 -0
  24. package/dist/charts/scale.d.ts +23 -0
  25. package/dist/charts/types.d.ts +43 -0
  26. package/dist/devtools/DomTab.d.ts +6 -0
  27. package/dist/devtools/GraphInspector.d.ts +11 -0
  28. package/dist/devtools/GraphTab.d.ts +10 -0
  29. package/dist/devtools/QueryTab.d.ts +10 -0
  30. package/dist/devtools/RpcTab.d.ts +10 -0
  31. package/dist/devtools/SignalsTab.d.ts +10 -0
  32. package/dist/devtools/component.d.ts +2 -0
  33. package/dist/devtools/highlighter.d.ts +2 -0
  34. package/dist/devtools/hub.d.ts +41 -0
  35. package/dist/devtools/index.d.ts +9 -0
  36. package/dist/{src/devtools → devtools}/index.js +87 -2
  37. package/dist/devtools/styles.d.ts +1 -0
  38. package/dist/devtools/types.d.ts +44 -0
  39. package/dist/dom/async.d.ts +41 -0
  40. package/dist/dom/control-flow.d.ts +53 -0
  41. package/dist/dom/index.d.ts +3 -0
  42. package/dist/{src/dom → dom}/index.js +87 -2
  43. package/dist/dom/lazy.d.ts +30 -0
  44. package/dist/dom/render.d.ts +23 -0
  45. package/dist/dom/resource.d.ts +34 -0
  46. package/dist/form/form.d.ts +41 -0
  47. package/dist/form/index.d.ts +2 -0
  48. package/dist/{src/form → form}/index.js +87 -2
  49. package/dist/form/schema.d.ts +96 -0
  50. package/dist/index.d.ts +15 -0
  51. package/dist/{src/index.js → index.js} +87 -2
  52. package/dist/jsx-dev-runtime/index.d.ts +1 -0
  53. package/dist/jsx-runtime/index.d.ts +8 -0
  54. package/dist/{src/jsx-runtime → jsx-runtime}/index.js +87 -2
  55. package/dist/jsx-runtime/jsx.d.ts +278 -0
  56. package/dist/query/create-mutation.d.ts +3 -0
  57. package/dist/query/create-query.d.ts +4 -0
  58. package/dist/query/focus-manager.d.ts +14 -0
  59. package/dist/query/index.d.ts +9 -0
  60. package/dist/{src/query → query}/index.js +87 -2
  61. package/dist/query/mutation-cache.d.ts +24 -0
  62. package/dist/query/online-manager.d.ts +14 -0
  63. package/dist/query/query-cache.d.ts +69 -0
  64. package/dist/query/query-client.d.ts +46 -0
  65. package/dist/query/types.d.ts +131 -0
  66. package/dist/query/utils.d.ts +16 -0
  67. package/dist/router/index.d.ts +1 -0
  68. package/dist/{src/router → router}/index.js +87 -2
  69. package/dist/router/router.d.ts +91 -0
  70. package/dist/rpc/client.d.ts +2 -0
  71. package/dist/rpc/error.d.ts +16 -0
  72. package/dist/rpc/index.d.ts +7 -0
  73. package/dist/{src/rpc → rpc}/index.js +87 -2
  74. package/dist/rpc/procedure.d.ts +8 -0
  75. package/dist/rpc/router.d.ts +19 -0
  76. package/dist/rpc/server.d.ts +3 -0
  77. package/dist/rpc/types.d.ts +200 -0
  78. package/dist/server/hydrate.d.ts +5 -0
  79. package/dist/server/index.d.ts +3 -0
  80. package/dist/{src/server → server}/index.js +87 -2
  81. package/dist/server/render-to-stream.d.ts +9 -0
  82. package/dist/server/render-to-string.d.ts +6 -0
  83. package/dist/signals/computed.d.ts +61 -0
  84. package/dist/signals/context.d.ts +44 -0
  85. package/dist/signals/effect.d.ts +56 -0
  86. package/dist/signals/index.d.ts +8 -0
  87. package/dist/{src/signals → signals}/index.js +87 -2
  88. package/dist/signals/scope.d.ts +61 -0
  89. package/dist/signals/signal.d.ts +40 -0
  90. package/dist/signals/store.d.ts +45 -0
  91. package/dist/signals/system.d.ts +56 -0
  92. package/dist/signals/types.d.ts +58 -0
  93. package/dist/style/component.d.ts +49 -0
  94. package/dist/style/create-style.d.ts +63 -0
  95. package/dist/style/cx.d.ts +18 -0
  96. package/dist/style/hash.d.ts +8 -0
  97. package/dist/style/index.d.ts +8 -0
  98. package/dist/{src/style → style}/index.js +87 -2
  99. package/dist/style/layout.d.ts +129 -0
  100. package/dist/style/manager.d.ts +31 -0
  101. package/dist/style/parser.d.ts +12 -0
  102. package/dist/style/scale.d.ts +82 -0
  103. package/dist/template/index.d.ts +1 -0
  104. package/dist/{src/template → template}/index.js +87 -2
  105. package/dist/template/template.d.ts +8 -0
  106. package/dist/ui/accordion.d.ts +81 -0
  107. package/dist/ui/command-dialog.d.ts +10 -0
  108. package/dist/ui/command.d.ts +103 -0
  109. package/dist/ui/data-table.d.ts +38 -0
  110. package/dist/ui/dialog.d.ts +102 -0
  111. package/dist/ui/dropdown-menu.d.ts +92 -0
  112. package/dist/ui/icon.d.ts +18 -0
  113. package/dist/ui/index.d.ts +14 -0
  114. package/dist/{src/ui → ui}/index.js +87 -2
  115. package/dist/ui/layout.d.ts +1 -0
  116. package/dist/ui/popover.d.ts +68 -0
  117. package/dist/ui/switch.d.ts +31 -0
  118. package/dist/ui/tabs.d.ts +71 -0
  119. package/dist/ui/toast.d.ts +91 -0
  120. package/dist/ui/tooltip.d.ts +64 -0
  121. package/dist/ui/utils.d.ts +21 -0
  122. package/dist/virtual/index.d.ts +2 -0
  123. package/dist/{src/virtual → virtual}/index.js +87 -2
  124. package/dist/virtual/virtual-list.d.ts +21 -0
  125. package/dist/virtual/virtualizer.d.ts +31 -0
  126. package/dist/vite/hmr.d.ts +7 -0
  127. package/dist/vite/index.d.ts +3 -0
  128. package/dist/{src/vite → vite}/index.js +4 -0
  129. package/dist/vite/lucide.d.ts +27 -0
  130. package/dist/vite/plugin.d.ts +3 -0
  131. package/dist/vite/rpc-middleware.d.ts +5 -0
  132. package/dist/vite/types.d.ts +59 -0
  133. package/package.json +40 -40
  134. package/src/signals/index.ts +1 -0
  135. package/src/signals/signal.ts +110 -2
  136. package/src/signals/types.ts +9 -0
  137. package/src/vite/plugin.ts +4 -0
@@ -848,10 +848,12 @@ class Signal {
848
848
  _value;
849
849
  _subscribers = new Set;
850
850
  _equals;
851
+ _onSet;
851
852
  version = 0;
852
- constructor(initialValue, equals) {
853
+ constructor(initialValue, equals, onSet) {
853
854
  this._value = initialValue;
854
855
  this._equals = equals ?? Object.is;
856
+ this._onSet = onSet;
855
857
  }
856
858
  get() {
857
859
  if (currentSubscriber !== null && currentSubscriber.state !== 3 /* DISPOSED */) {
@@ -876,6 +878,9 @@ class Signal {
876
878
  }
877
879
  this._value = newValue;
878
880
  this.version++;
881
+ if (this._onSet) {
882
+ this._onSet(newValue);
883
+ }
879
884
  batch(() => {
880
885
  this.notify();
881
886
  });
@@ -901,11 +906,91 @@ class Signal {
901
906
  }
902
907
  }
903
908
  }
909
+ function resolveStorage(storageOption) {
910
+ if (storageOption && typeof storageOption === "object") {
911
+ return storageOption;
912
+ }
913
+ if (storageOption === "session") {
914
+ try {
915
+ if (typeof sessionStorage !== "undefined")
916
+ return sessionStorage;
917
+ } catch {}
918
+ try {
919
+ if (typeof window !== "undefined" && window.sessionStorage) {
920
+ return window.sessionStorage;
921
+ }
922
+ } catch {}
923
+ try {
924
+ if (typeof globalThis !== "undefined" && globalThis.sessionStorage) {
925
+ return globalThis.sessionStorage;
926
+ }
927
+ } catch {}
928
+ return null;
929
+ }
930
+ try {
931
+ if (typeof localStorage !== "undefined")
932
+ return localStorage;
933
+ } catch {}
934
+ try {
935
+ if (typeof window !== "undefined" && window.localStorage) {
936
+ return window.localStorage;
937
+ }
938
+ } catch {}
939
+ try {
940
+ if (typeof globalThis !== "undefined" && globalThis.localStorage) {
941
+ return globalThis.localStorage;
942
+ }
943
+ } catch {}
944
+ return null;
945
+ }
904
946
  function signal(initialValue, optionsOrEquals) {
905
947
  const equals = typeof optionsOrEquals === "function" ? optionsOrEquals : optionsOrEquals?.equals;
906
948
  const isInternal = typeof optionsOrEquals === "object" ? optionsOrEquals?.internal : false;
907
949
  const customName = typeof optionsOrEquals === "object" ? optionsOrEquals?.name : undefined;
908
- const s = new Signal(initialValue, equals);
950
+ const persistOption = typeof optionsOrEquals === "object" ? optionsOrEquals?.persist : undefined;
951
+ const persistConfig = persistOption ? typeof persistOption === "string" ? { key: persistOption } : persistOption : undefined;
952
+ let effectiveInitial = initialValue;
953
+ const storage = persistConfig ? resolveStorage(persistConfig.storage) : null;
954
+ const serialize = persistConfig?.serialize ?? JSON.stringify;
955
+ const deserialize = persistConfig?.deserialize ?? JSON.parse;
956
+ if (persistConfig && storage) {
957
+ try {
958
+ const stored = storage.getItem(persistConfig.key);
959
+ if (stored !== null) {
960
+ effectiveInitial = deserialize(stored);
961
+ }
962
+ } catch {}
963
+ }
964
+ let isSyncing = false;
965
+ const onSet = persistConfig && storage ? (val) => {
966
+ if (isSyncing)
967
+ return;
968
+ try {
969
+ storage.setItem(persistConfig.key, serialize(val));
970
+ } catch {}
971
+ } : undefined;
972
+ const s = new Signal(effectiveInitial, equals, onSet);
973
+ if (persistConfig && storage && (persistConfig.syncTabs ?? true) && typeof window !== "undefined" && typeof window.addEventListener === "function") {
974
+ const onStorage = (e) => {
975
+ if (e.key === persistConfig.key) {
976
+ try {
977
+ const nextVal = e.newValue !== null ? deserialize(e.newValue) : initialValue;
978
+ isSyncing = true;
979
+ try {
980
+ s.set(nextVal);
981
+ } finally {
982
+ isSyncing = false;
983
+ }
984
+ } catch {}
985
+ }
986
+ };
987
+ window.addEventListener("storage", onStorage);
988
+ if (currentScope) {
989
+ currentScope.addCleanup(() => {
990
+ window.removeEventListener("storage", onStorage);
991
+ });
992
+ }
993
+ }
909
994
  const accessor = (...args) => {
910
995
  if (args.length === 0) {
911
996
  return s.get();
@@ -0,0 +1,30 @@
1
+ import type { Child } from "./render";
2
+ export type Component<P = any> = (props: P) => Child;
3
+ export type LazyComponent<T extends Component<any>> = T & {
4
+ preload(): Promise<T>;
5
+ };
6
+ /**
7
+ * Lazy load an asynchronous component with automatic `<Suspense>` boundary coordination and preloading.
8
+ *
9
+ * Dynamically imports the component module upon first render or when `.preload()` is invoked.
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * // Dynamic code-split component
14
+ * const HeavyChart = lazy(() => import("./HeavyChart"));
15
+ *
16
+ * // Optional early prefetching
17
+ * HeavyChart.preload();
18
+ *
19
+ * // Render inside Suspense
20
+ * <Suspense fallback={<div>Loading chart...</div>}>
21
+ * <HeavyChart data={chartData()} />
22
+ * </Suspense>
23
+ * ```
24
+ *
25
+ * @param importer - Dynamic import function returning a component or `{ default: Component }`
26
+ * @returns A lazy component with a `.preload()` method
27
+ */
28
+ export declare function lazy<T extends Component<any>>(importer: () => Promise<{
29
+ default: T;
30
+ } | T>): LazyComponent<T>;
@@ -0,0 +1,23 @@
1
+ import { type ReadonlySignal } from "../signals";
2
+ export type ReactiveValue<T> = T | ReadonlySignal<T> | (() => T);
3
+ export type Child = Node | string | number | boolean | null | undefined | ReadonlySignal<any> | (() => any) | Child[];
4
+ /**
5
+ * Check if a property is a reactive getter or signal
6
+ */
7
+ export declare function isReactive<T>(value: unknown): value is ReadonlySignal<T> | (() => T);
8
+ /**
9
+ * Extract current value whether static, signal, or getter
10
+ */
11
+ export declare function resolveValue<T>(val: ReactiveValue<T>): T;
12
+ /**
13
+ * Mount a Visage component or element to a DOM container
14
+ */
15
+ export declare function render(fn: () => Child, container: HTMLElement | DocumentFragment): () => void;
16
+ /**
17
+ * Bind dynamic or static attributes, properties, styles, and events to an Element
18
+ */
19
+ export declare function setAttribute(el: HTMLElement | SVGElement, key: string, value: any): void;
20
+ /**
21
+ * Insert a child node into a parent container with reactive fine-grained updates
22
+ */
23
+ export declare function insertChild(parent: Node, child: Child, before?: Node | null): Node | null;
@@ -0,0 +1,34 @@
1
+ import { type ReadonlySignal } from "../signals";
2
+ import { type ReactiveValue } from "./render";
3
+ export interface SuspenseContextValue {
4
+ registerPromise(p: Promise<any>): void;
5
+ }
6
+ export declare const SuspenseContext: import("..").Context<SuspenseContextValue | null>;
7
+ export interface ResourceActions<T> {
8
+ mutate(value: T): void;
9
+ refetch(): Promise<T>;
10
+ readonly loading: ReadonlySignal<boolean>;
11
+ readonly error: ReadonlySignal<any>;
12
+ }
13
+ export type Resource<T> = ReadonlySignal<T | undefined> & ResourceActions<T>;
14
+ /**
15
+ * Create an asynchronous resource tied to optional source signals and suspense boundaries.
16
+ *
17
+ * Automatically tracks async state, registers pending promises with `<Suspense>`,
18
+ * and supports manual mutation and refetching.
19
+ *
20
+ * @example
21
+ * ```tsx
22
+ * const [userId, setUserId] = createSignal("user-1");
23
+ * const user = createResource(userId, (id) => fetchUser(id));
24
+ *
25
+ * // Read data, loading state, error
26
+ * <div>{() => user()?.name}</div>
27
+ * ```
28
+ *
29
+ * @param sourceOrFetcher - A reactive source signal or direct async fetcher function
30
+ * @param maybeFetcher - Async fetcher taking the resolved source value
31
+ * @returns A reactive Resource accessor with `.loading`, `.error`, `.mutate`, and `.refetch`
32
+ */
33
+ export declare function createResource<T>(fetcher: () => Promise<T>): Resource<T>;
34
+ export declare function createResource<T, S>(source: ReactiveValue<S>, fetcher: (source: S) => Promise<T>): Resource<T>;
@@ -0,0 +1,41 @@
1
+ import { type ReadonlySignal, type WritableSignal } from "../signals";
2
+ import { type SchemaLike } from "./schema";
3
+ export interface FieldState<T> {
4
+ value: WritableSignal<T>;
5
+ error: ReadonlySignal<string | null>;
6
+ touched: WritableSignal<boolean>;
7
+ isDirty: ReadonlySignal<boolean>;
8
+ }
9
+ export type FormFields<T> = {
10
+ [K in keyof T]-?: FieldState<T[K]>;
11
+ };
12
+ export interface FormOptions<T extends Record<string, any> = Record<string, any>> {
13
+ initialValues: T;
14
+ schema?: SchemaLike<any>;
15
+ validateOn?: "change" | "blur" | "submit";
16
+ onSubmit?: (values: T) => void | Promise<void>;
17
+ }
18
+ export interface Form<T> {
19
+ fields: FormFields<T>;
20
+ values: () => T;
21
+ errors: ReadonlySignal<Partial<Record<keyof T, string>>>;
22
+ isValid: ReadonlySignal<boolean>;
23
+ isDirty: ReadonlySignal<boolean>;
24
+ isSubmitting: ReadonlySignal<boolean>;
25
+ submitCount: ReadonlySignal<number>;
26
+ bind: (name: keyof T) => {
27
+ name: string;
28
+ value: WritableSignal<any>;
29
+ onInput: (e: any) => void;
30
+ onBlur: () => void;
31
+ };
32
+ handleSubmit: (e?: Event) => Promise<boolean>;
33
+ reset: (values?: Partial<T>) => void;
34
+ setFieldValue: <K extends keyof T>(name: K, value: T[K]) => void;
35
+ setFieldError: (name: keyof T, error: string | null) => void;
36
+ validate: () => boolean;
37
+ }
38
+ /**
39
+ * Create a fine-grained reactive form with built-in schema validation (ArkType, Zod, Valibot, or native v)
40
+ */
41
+ export declare function createForm<T extends Record<string, any> = Record<string, any>>(options: FormOptions<T>): Form<T>;
@@ -0,0 +1,2 @@
1
+ export { createForm, type FieldState, type Form, type FormFields, type FormOptions } from "./form";
2
+ export { Schema, type SchemaLike, type StandardSchemaV1, type ValidationIssue, type ValidationResult, v, validateWithSchema } from "./schema";
@@ -848,10 +848,12 @@ class Signal {
848
848
  _value;
849
849
  _subscribers = new Set;
850
850
  _equals;
851
+ _onSet;
851
852
  version = 0;
852
- constructor(initialValue, equals) {
853
+ constructor(initialValue, equals, onSet) {
853
854
  this._value = initialValue;
854
855
  this._equals = equals ?? Object.is;
856
+ this._onSet = onSet;
855
857
  }
856
858
  get() {
857
859
  if (currentSubscriber !== null && currentSubscriber.state !== 3 /* DISPOSED */) {
@@ -876,6 +878,9 @@ class Signal {
876
878
  }
877
879
  this._value = newValue;
878
880
  this.version++;
881
+ if (this._onSet) {
882
+ this._onSet(newValue);
883
+ }
879
884
  batch(() => {
880
885
  this.notify();
881
886
  });
@@ -901,11 +906,91 @@ class Signal {
901
906
  }
902
907
  }
903
908
  }
909
+ function resolveStorage(storageOption) {
910
+ if (storageOption && typeof storageOption === "object") {
911
+ return storageOption;
912
+ }
913
+ if (storageOption === "session") {
914
+ try {
915
+ if (typeof sessionStorage !== "undefined")
916
+ return sessionStorage;
917
+ } catch {}
918
+ try {
919
+ if (typeof window !== "undefined" && window.sessionStorage) {
920
+ return window.sessionStorage;
921
+ }
922
+ } catch {}
923
+ try {
924
+ if (typeof globalThis !== "undefined" && globalThis.sessionStorage) {
925
+ return globalThis.sessionStorage;
926
+ }
927
+ } catch {}
928
+ return null;
929
+ }
930
+ try {
931
+ if (typeof localStorage !== "undefined")
932
+ return localStorage;
933
+ } catch {}
934
+ try {
935
+ if (typeof window !== "undefined" && window.localStorage) {
936
+ return window.localStorage;
937
+ }
938
+ } catch {}
939
+ try {
940
+ if (typeof globalThis !== "undefined" && globalThis.localStorage) {
941
+ return globalThis.localStorage;
942
+ }
943
+ } catch {}
944
+ return null;
945
+ }
904
946
  function signal(initialValue, optionsOrEquals) {
905
947
  const equals = typeof optionsOrEquals === "function" ? optionsOrEquals : optionsOrEquals?.equals;
906
948
  const isInternal = typeof optionsOrEquals === "object" ? optionsOrEquals?.internal : false;
907
949
  const customName = typeof optionsOrEquals === "object" ? optionsOrEquals?.name : undefined;
908
- const s = new Signal(initialValue, equals);
950
+ const persistOption = typeof optionsOrEquals === "object" ? optionsOrEquals?.persist : undefined;
951
+ const persistConfig = persistOption ? typeof persistOption === "string" ? { key: persistOption } : persistOption : undefined;
952
+ let effectiveInitial = initialValue;
953
+ const storage = persistConfig ? resolveStorage(persistConfig.storage) : null;
954
+ const serialize = persistConfig?.serialize ?? JSON.stringify;
955
+ const deserialize = persistConfig?.deserialize ?? JSON.parse;
956
+ if (persistConfig && storage) {
957
+ try {
958
+ const stored = storage.getItem(persistConfig.key);
959
+ if (stored !== null) {
960
+ effectiveInitial = deserialize(stored);
961
+ }
962
+ } catch {}
963
+ }
964
+ let isSyncing = false;
965
+ const onSet = persistConfig && storage ? (val) => {
966
+ if (isSyncing)
967
+ return;
968
+ try {
969
+ storage.setItem(persistConfig.key, serialize(val));
970
+ } catch {}
971
+ } : undefined;
972
+ const s = new Signal(effectiveInitial, equals, onSet);
973
+ if (persistConfig && storage && (persistConfig.syncTabs ?? true) && typeof window !== "undefined" && typeof window.addEventListener === "function") {
974
+ const onStorage = (e) => {
975
+ if (e.key === persistConfig.key) {
976
+ try {
977
+ const nextVal = e.newValue !== null ? deserialize(e.newValue) : initialValue;
978
+ isSyncing = true;
979
+ try {
980
+ s.set(nextVal);
981
+ } finally {
982
+ isSyncing = false;
983
+ }
984
+ } catch {}
985
+ }
986
+ };
987
+ window.addEventListener("storage", onStorage);
988
+ if (currentScope) {
989
+ currentScope.addCleanup(() => {
990
+ window.removeEventListener("storage", onStorage);
991
+ });
992
+ }
993
+ }
909
994
  const accessor = (...args) => {
910
995
  if (args.length === 0) {
911
996
  return s.get();
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Built-in lightweight schema validator & Standard Schema v1 (ArkType, Zod, Valibot) support
3
+ */
4
+ export interface ValidationIssue {
5
+ path: string;
6
+ message: string;
7
+ }
8
+ export interface ValidationResult<T> {
9
+ success: boolean;
10
+ data?: T;
11
+ issues?: ValidationIssue[];
12
+ }
13
+ export interface StandardSchemaV1<T = any> {
14
+ "~standard": {
15
+ version: 1;
16
+ vendor: string;
17
+ validate: (value: unknown) => {
18
+ value: T;
19
+ } | {
20
+ issues: ReadonlyArray<{
21
+ path?: ReadonlyArray<string | number>;
22
+ message: string;
23
+ }>;
24
+ };
25
+ };
26
+ }
27
+ export type SchemaLike<T = any> = Schema<T> | StandardSchemaV1<T> | ((value: unknown) => ValidationResult<T> | boolean | string | null | undefined);
28
+ export declare abstract class Schema<T = any> {
29
+ readonly _type: T;
30
+ abstract validate(value: unknown, path?: string): ValidationResult<T>;
31
+ "~standard": {
32
+ version: 1;
33
+ vendor: string;
34
+ validate: (val: unknown) => {
35
+ value: T;
36
+ issues?: undefined;
37
+ } | {
38
+ value?: undefined;
39
+ issues: {
40
+ path: string[];
41
+ message: string;
42
+ }[];
43
+ };
44
+ };
45
+ }
46
+ declare class StringSchema extends Schema<string> {
47
+ private _min?;
48
+ private _max?;
49
+ private _emailMsg?;
50
+ private _regex?;
51
+ private _isOptional;
52
+ min(length: number, message?: string): this;
53
+ max(length: number, message?: string): this;
54
+ email(message?: string): this;
55
+ regex(pattern: RegExp, message?: string): this;
56
+ optional(): Schema<string | undefined>;
57
+ validate(value: unknown, path?: string): ValidationResult<string>;
58
+ }
59
+ declare class NumberSchema extends Schema<number> {
60
+ private _min?;
61
+ private _max?;
62
+ private _integer?;
63
+ private _isOptional;
64
+ min(value: number, message?: string): this;
65
+ max(value: number, message?: string): this;
66
+ integer(message?: string): this;
67
+ optional(): Schema<number | undefined>;
68
+ validate(value: unknown, path?: string): ValidationResult<number>;
69
+ }
70
+ declare class BooleanSchema extends Schema<boolean> {
71
+ validate(value: unknown, _path?: string): ValidationResult<boolean>;
72
+ }
73
+ export type InferSchemaType<S> = S extends Schema<infer T> ? T : S extends StandardSchemaV1<infer T> ? T : S extends (val: any) => ValidationResult<infer T> ? T : any;
74
+ export type InferObjectShape<S extends Record<string, SchemaLike<any>>> = {
75
+ [K in keyof S]: InferSchemaType<S[K]>;
76
+ };
77
+ export declare class ObjectSchema<T extends Record<string, any>> extends Schema<T> {
78
+ shape: {
79
+ [K in keyof T]: SchemaLike<T[K]>;
80
+ };
81
+ constructor(shape: {
82
+ [K in keyof T]: SchemaLike<T[K]>;
83
+ });
84
+ validate(value: unknown, basePath?: string): ValidationResult<T>;
85
+ }
86
+ export declare function validateWithSchema<T>(schema: SchemaLike<T>, value: unknown, path?: string): ValidationResult<T>;
87
+ /**
88
+ * Built-in schema definition library
89
+ */
90
+ export declare const v: {
91
+ string: () => StringSchema;
92
+ number: () => NumberSchema;
93
+ boolean: () => BooleanSchema;
94
+ object: <S extends Record<string, SchemaLike<any>>>(shape: S) => ObjectSchema<{ [K in keyof S]: InferSchemaType<S[K]>; }>;
95
+ };
96
+ export {};
@@ -0,0 +1,15 @@
1
+ export { type ApiClient, type ApiClientOptions, buildFileRouter, createApi, createApiClient, createApiHandler, defineMiddleware, type FileRouteModule, ProcedureBuilder, procedure } from "./api";
2
+ export { type AnyScale, Area, type AreaProps, type BandScale, Bar, type BarProps, CartesianGrid, type CartesianGridProps, Chart, ChartContext, type ChartContextValue, ChartCursor, type ChartCursorProps, ChartLegend, type ChartProps, ChartTooltip, type CurveType, createBandScale, createLinearScale, generateNiceTicks, type HoverState, Legend, type LegendProps, Line, type LinearScale, type LineProps, type Margin, Pie, type PieProps, type Point, pathArc, pathArea, pathLine, type SeriesMeta, useChartContext, XAxis, type XAxisProps, YAxis, type YAxisProps } from "./charts";
3
+ export { connectDevTools, DevToolsHub, type DevToolsOptions, type DevToolsTab, devtoolsHub, highlightElement, type QueryRecord, type RpcRecord, type SignalRecord, VisageDevTools } from "./devtools";
4
+ export { type Child, type Component, createResource, ErrorBoundary, type ErrorBoundaryProps, For, type ForProps, insertChild, isReactive, type LazyComponent, lazy, Portal, type PortalProps, type ReactiveValue, type Resource, type ResourceActions, render, resolveValue, Show, type ShowProps, Suspense, type SuspenseProps, setAttribute } from "./dom";
5
+ export { createForm, type FieldState, type Form, type FormFields, type FormOptions, Schema, type SchemaLike, type StandardSchemaV1, type ValidationIssue, type ValidationResult, v, validateWithSchema } from "./form";
6
+ export type { AnchorAttributes, ButtonAttributes, HTMLAttributes, InputAttributes, JSX, ReactiveProp } from "./jsx-runtime/jsx";
7
+ export { type CreateQueryOptions, createInfiniteQuery, createMutation, createQuery, type DefaultOptions, type FetchStatus, FocusManager, focusManager, hashKey, type InfiniteData, type InfiniteQueryOptions, type InfiniteQueryResult, type MutateOptions, Mutation, MutationCache, type MutationFunction, type MutationOptions, type MutationResult, type MutationStatus, OnlineManager, onlineManager, Query, QueryCache, QueryClient, type QueryClientConfig, QueryClientContext, QueryClientProvider, type QueryFilters, type QueryFunction, type QueryFunctionContext, type QueryKey, type QueryObserver, type QueryOptions, type QueryResult, type QueryState, type QueryStatus, type RefetchOptions, type RetryDelayValue } from "./query";
8
+ export { Link, type LinkProps, type LocationState, type MatchedRoute, Route, type RouteDefinition, type RouteProps, Router, type RouterContextValue, type RouterProps, Routes, type RoutesProps, useLocation, useNavigate, useParams, useSearchParams } from "./router";
9
+ export { type ClientOptions, type ClientRouter, type CORSOptions, createClient, createFetchHandler, createProcedure, createRouter, ERROR_CODE_TO_STATUS, executeProcedure, type FetchHandlerOptions, type MiddlewareFn, mutation, type Procedure, type ProcedureOptions, type ProcedureRecord, type ProcedureType, query, type Router as RPCRouter, RouterImpl, RPCError, type RPCErrorCode, type RPCResponse, STATUS_TO_ERROR_CODE, type SubscriptionCallbacks, type SubscriptionHandle, subscription } from "./rpc";
10
+ export { hydrate, renderChildToString, renderToStream, renderToString, type StreamOptions } from "./server";
11
+ export { batch, type CleanupFn, Computed, type Context, computed, createContext, createEffect, createMemo, createRoot, createSignal, createStore, type Dependency, Effect, effect, getActiveScope, isSignal, mutateStore, onCleanup, type ReadonlySignal, runInScope, Scope, Signal, type Store, type Subscriber, signal, untrack, unwrapStore, useContext, type WritableSignal } from "./signals";
12
+ export { type BaseLayoutProps, Center, type CenterProps, type ClassValue, createStyle, css, cx, DIMENSION_KEYWORDS, em, extractStyleTags, fluid, formatStyleProp, type GlassOptions, Grid, type GridProps, getScopeId, glass, hashString, hasReactiveClass, normalizeClass, px, type RadiusVariant, Row, type RowProps, radius, rem, type ScopeOptions, type ShadowVariant, Spacer, type SpacerProps, Stack, type StackProps, Style, type StyleClasses, StyleManager, type StyleProps, scopeCSS, scopeSelector, shadow, space, styleManager, UNITLESS_PROPERTIES, useStyle } from "./style";
13
+ export { html, template } from "./template";
14
+ export { Accordion, AccordionContent, AccordionItem, type AccordionItemProps, type AccordionMultipleProps, type AccordionProps, type AccordionSingleProps, AccordionTrigger, type ColumnDef, Command, CommandDialog, type CommandDialogProps, CommandEmpty, CommandGroup, type CommandGroupData, CommandInput, type CommandInputProps, CommandItem, type CommandItemData, type CommandItemProps, CommandList, type CommandProps, createControllableSignal, createIcon, createId, createToastManager, DataTable, type DataTableProps, Dialog, DialogClose, DialogContent, type DialogContentProps, DialogDescription, DialogOverlay, DialogPortal, type DialogProps, DialogTitle, DialogTrigger, DropdownMenu, DropdownMenuContent, DropdownMenuItem, type DropdownMenuItemProps, DropdownMenuPortal, type DropdownMenuProps, DropdownMenuSeparator, DropdownMenuTrigger, defaultToastManager, type IconNode, type IconProps, onClickOutside, Popover, PopoverClose, PopoverContent, type PopoverContentProps, PopoverPortal, type PopoverProps, PopoverTrigger, type SortDirection, type SortState, Switch, type SwitchProps, SwitchThumb, type SwitchThumbProps, Tabs, TabsContent, type TabsContentProps, TabsList, type TabsProps, TabsTrigger, Toast, ToastClose, type ToastData, ToastDescription, type ToastManager, type ToastOptions, type ToastProps, ToastProvider, type ToastProviderProps, ToastTitle, type ToastVariant, ToastViewport, type ToastViewportProps, Tooltip, TooltipContent, type TooltipContentProps, TooltipPortal, type TooltipProps, TooltipTrigger, toast, trapFocus, useAccordionContext, useAccordionItemContext, useCommandContext, useDialogContext, useDropdownMenuContext, usePopoverContext, useTabsContext, useToast, useTooltipContext } from "./ui";
15
+ export { createVirtualizer, VirtualGrid, type VirtualGridProps, type VirtualItem, type Virtualizer, type VirtualizerOptions, VirtualList, type VirtualListProps } from "./virtual";
@@ -1112,10 +1112,12 @@ class Signal {
1112
1112
  _value;
1113
1113
  _subscribers = new Set;
1114
1114
  _equals;
1115
+ _onSet;
1115
1116
  version = 0;
1116
- constructor(initialValue, equals) {
1117
+ constructor(initialValue, equals, onSet) {
1117
1118
  this._value = initialValue;
1118
1119
  this._equals = equals ?? Object.is;
1120
+ this._onSet = onSet;
1119
1121
  }
1120
1122
  get() {
1121
1123
  if (currentSubscriber !== null && currentSubscriber.state !== 3 /* DISPOSED */) {
@@ -1140,6 +1142,9 @@ class Signal {
1140
1142
  }
1141
1143
  this._value = newValue;
1142
1144
  this.version++;
1145
+ if (this._onSet) {
1146
+ this._onSet(newValue);
1147
+ }
1143
1148
  batch(() => {
1144
1149
  this.notify();
1145
1150
  });
@@ -1165,11 +1170,91 @@ class Signal {
1165
1170
  }
1166
1171
  }
1167
1172
  }
1173
+ function resolveStorage(storageOption) {
1174
+ if (storageOption && typeof storageOption === "object") {
1175
+ return storageOption;
1176
+ }
1177
+ if (storageOption === "session") {
1178
+ try {
1179
+ if (typeof sessionStorage !== "undefined")
1180
+ return sessionStorage;
1181
+ } catch {}
1182
+ try {
1183
+ if (typeof window !== "undefined" && window.sessionStorage) {
1184
+ return window.sessionStorage;
1185
+ }
1186
+ } catch {}
1187
+ try {
1188
+ if (typeof globalThis !== "undefined" && globalThis.sessionStorage) {
1189
+ return globalThis.sessionStorage;
1190
+ }
1191
+ } catch {}
1192
+ return null;
1193
+ }
1194
+ try {
1195
+ if (typeof localStorage !== "undefined")
1196
+ return localStorage;
1197
+ } catch {}
1198
+ try {
1199
+ if (typeof window !== "undefined" && window.localStorage) {
1200
+ return window.localStorage;
1201
+ }
1202
+ } catch {}
1203
+ try {
1204
+ if (typeof globalThis !== "undefined" && globalThis.localStorage) {
1205
+ return globalThis.localStorage;
1206
+ }
1207
+ } catch {}
1208
+ return null;
1209
+ }
1168
1210
  function signal(initialValue, optionsOrEquals) {
1169
1211
  const equals = typeof optionsOrEquals === "function" ? optionsOrEquals : optionsOrEquals?.equals;
1170
1212
  const isInternal = typeof optionsOrEquals === "object" ? optionsOrEquals?.internal : false;
1171
1213
  const customName = typeof optionsOrEquals === "object" ? optionsOrEquals?.name : undefined;
1172
- const s = new Signal(initialValue, equals);
1214
+ const persistOption = typeof optionsOrEquals === "object" ? optionsOrEquals?.persist : undefined;
1215
+ const persistConfig = persistOption ? typeof persistOption === "string" ? { key: persistOption } : persistOption : undefined;
1216
+ let effectiveInitial = initialValue;
1217
+ const storage = persistConfig ? resolveStorage(persistConfig.storage) : null;
1218
+ const serialize = persistConfig?.serialize ?? JSON.stringify;
1219
+ const deserialize = persistConfig?.deserialize ?? JSON.parse;
1220
+ if (persistConfig && storage) {
1221
+ try {
1222
+ const stored = storage.getItem(persistConfig.key);
1223
+ if (stored !== null) {
1224
+ effectiveInitial = deserialize(stored);
1225
+ }
1226
+ } catch {}
1227
+ }
1228
+ let isSyncing = false;
1229
+ const onSet = persistConfig && storage ? (val) => {
1230
+ if (isSyncing)
1231
+ return;
1232
+ try {
1233
+ storage.setItem(persistConfig.key, serialize(val));
1234
+ } catch {}
1235
+ } : undefined;
1236
+ const s = new Signal(effectiveInitial, equals, onSet);
1237
+ if (persistConfig && storage && (persistConfig.syncTabs ?? true) && typeof window !== "undefined" && typeof window.addEventListener === "function") {
1238
+ const onStorage = (e) => {
1239
+ if (e.key === persistConfig.key) {
1240
+ try {
1241
+ const nextVal = e.newValue !== null ? deserialize(e.newValue) : initialValue;
1242
+ isSyncing = true;
1243
+ try {
1244
+ s.set(nextVal);
1245
+ } finally {
1246
+ isSyncing = false;
1247
+ }
1248
+ } catch {}
1249
+ }
1250
+ };
1251
+ window.addEventListener("storage", onStorage);
1252
+ if (currentScope) {
1253
+ currentScope.addCleanup(() => {
1254
+ window.removeEventListener("storage", onStorage);
1255
+ });
1256
+ }
1257
+ }
1173
1258
  const accessor = (...args) => {
1174
1259
  if (args.length === 0) {
1175
1260
  return s.get();
@@ -0,0 +1 @@
1
+ export { Fragment, type JSX, jsx, jsxDEV, jsxs } from "../jsx-runtime";
@@ -0,0 +1,8 @@
1
+ import { type Child } from "../dom";
2
+ export type { JSX } from "./jsx";
3
+ export declare function Fragment(props: {
4
+ children?: Child;
5
+ }): any;
6
+ export declare function jsx(type: any, props?: Record<string, any>, key?: any): any;
7
+ export declare const jsxs: typeof jsx;
8
+ export declare const jsxDEV: typeof jsx;