@vertz/ui 0.2.0 → 0.2.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 (35) hide show
  1. package/README.md +339 -857
  2. package/dist/css/public.d.ts +24 -27
  3. package/dist/css/public.js +5 -1
  4. package/dist/form/public.d.ts +94 -38
  5. package/dist/form/public.js +5 -3
  6. package/dist/index.d.ts +696 -167
  7. package/dist/index.js +461 -84
  8. package/dist/internals.d.ts +192 -23
  9. package/dist/internals.js +151 -102
  10. package/dist/jsx-runtime/index.d.ts +44 -17
  11. package/dist/jsx-runtime/index.js +26 -7
  12. package/dist/query/public.d.ts +62 -7
  13. package/dist/query/public.js +12 -4
  14. package/dist/router/public.d.ts +186 -26
  15. package/dist/router/public.js +22 -7
  16. package/dist/shared/{chunk-f1ynwam4.js → chunk-0p5f7gmg.js} +155 -32
  17. package/dist/shared/{chunk-j8vzvne3.js → chunk-9e92w0wt.js} +4 -1
  18. package/dist/shared/{chunk-xd9d7q5p.js → chunk-cq7xg4xe.js} +59 -10
  19. package/dist/shared/chunk-g4rch80a.js +33 -0
  20. package/dist/shared/{chunk-pgymxpn1.js → chunk-hrd0mft1.js} +136 -34
  21. package/dist/shared/chunk-nmjyj8p9.js +290 -0
  22. package/dist/shared/chunk-pp3a6xbn.js +483 -0
  23. package/dist/shared/chunk-prj7nm08.js +67 -0
  24. package/dist/shared/chunk-q6cpe5k7.js +230 -0
  25. package/dist/shared/chunk-ryb49346.js +374 -0
  26. package/dist/shared/chunk-v3yyf79g.js +48 -0
  27. package/dist/shared/chunk-vx0kzack.js +103 -0
  28. package/dist/shared/chunk-wv6kkj1w.js +464 -0
  29. package/dist/test/index.d.ts +67 -6
  30. package/dist/test/index.js +4 -3
  31. package/package.json +13 -8
  32. package/dist/shared/chunk-bp3v6s9j.js +0 -62
  33. package/dist/shared/chunk-d8h2eh8d.js +0 -141
  34. package/dist/shared/chunk-tsdpgmks.js +0 -98
  35. package/dist/shared/chunk-zbbvx05f.js +0 -202
@@ -1,11 +1,76 @@
1
1
  // src/component/context.ts
2
2
  var currentScope = null;
3
+ function isSignalLike(value) {
4
+ return value != null && typeof value === "object" && "peek" in value && typeof value.peek === "function";
5
+ }
6
+ function wrapSignalProps(value) {
7
+ if (value == null || typeof value !== "object" || Array.isArray(value)) {
8
+ return value;
9
+ }
10
+ const source = value;
11
+ const keys = Object.keys(source);
12
+ let hasSignal = false;
13
+ for (const key of keys) {
14
+ if (isSignalLike(source[key])) {
15
+ hasSignal = true;
16
+ break;
17
+ }
18
+ }
19
+ if (!hasSignal)
20
+ return value;
21
+ const wrapped = {};
22
+ for (const key of keys) {
23
+ const propValue = source[key];
24
+ if (isSignalLike(propValue)) {
25
+ Object.defineProperty(wrapped, key, {
26
+ get() {
27
+ return propValue.value;
28
+ },
29
+ enumerable: true,
30
+ configurable: true
31
+ });
32
+ } else {
33
+ wrapped[key] = propValue;
34
+ }
35
+ }
36
+ return wrapped;
37
+ }
3
38
  function asKey(ctx) {
4
39
  return ctx;
5
40
  }
6
- function createContext(defaultValue) {
41
+ var REGISTRY_KEY = "__VERTZ_CTX_REG__";
42
+ var contextRegistry = globalThis[REGISTRY_KEY] ?? (() => {
43
+ const m = new Map;
44
+ globalThis[REGISTRY_KEY] = m;
45
+ return m;
46
+ })();
47
+ function createContext(defaultValue, __stableId) {
48
+ if (__stableId) {
49
+ const existing = contextRegistry.get(__stableId);
50
+ if (existing)
51
+ return existing;
52
+ }
7
53
  const ctx = {
8
- Provider(value, fn) {
54
+ Provider(valueOrProps, fn) {
55
+ if (fn !== undefined) {
56
+ const value2 = wrapSignalProps(valueOrProps);
57
+ const parentScope2 = currentScope;
58
+ const scope2 = parentScope2 ? new Map(parentScope2) : new Map;
59
+ scope2.set(asKey(ctx), value2);
60
+ ctx._stack.push(value2);
61
+ const prevScope2 = currentScope;
62
+ currentScope = scope2;
63
+ try {
64
+ fn();
65
+ } finally {
66
+ ctx._stack.pop();
67
+ currentScope = prevScope2;
68
+ }
69
+ return;
70
+ }
71
+ const props = valueOrProps;
72
+ const { value: rawValue, children } = props;
73
+ const value = wrapSignalProps(rawValue);
9
74
  const parentScope = currentScope;
10
75
  const scope = parentScope ? new Map(parentScope) : new Map;
11
76
  scope.set(asKey(ctx), value);
@@ -13,7 +78,11 @@ function createContext(defaultValue) {
13
78
  const prevScope = currentScope;
14
79
  currentScope = scope;
15
80
  try {
16
- fn();
81
+ const result = typeof children === "function" ? children() : children;
82
+ if (typeof process !== "undefined" && true && Array.isArray(result)) {
83
+ throw new Error("Context.Provider JSX children must have a single root element. " + "Wrap multiple children in a fragment: <><Child1 /><Child2 /></>");
84
+ }
85
+ return result;
17
86
  } finally {
18
87
  ctx._stack.pop();
19
88
  currentScope = prevScope;
@@ -22,6 +91,9 @@ function createContext(defaultValue) {
22
91
  _default: defaultValue,
23
92
  _stack: []
24
93
  };
94
+ if (__stableId) {
95
+ contextRegistry.set(__stableId, ctx);
96
+ }
25
97
  return ctx;
26
98
  }
27
99
  function useContext(ctx) {
@@ -46,7 +118,7 @@ function setContextScope(scope) {
46
118
  // src/runtime/disposal.ts
47
119
  class DisposalScopeError extends Error {
48
120
  constructor() {
49
- super("onCleanup() must be called within a disposal scope (e.g., inside effect(), watch(), onMount(), or a pushScope()/popScope() block). " + "Called outside a scope, the cleanup callback would be silently discarded.");
121
+ super("onCleanup() must be called within a disposal scope (e.g., inside domEffect(), lifecycleEffect(), onMount(), or a pushScope()/popScope() block). " + "Called outside a scope, the cleanup callback would be silently discarded.");
50
122
  this.name = "DisposalScopeError";
51
123
  }
52
124
  }
@@ -79,6 +151,35 @@ function runCleanups(cleanups) {
79
151
  cleanups.length = 0;
80
152
  }
81
153
 
154
+ // src/runtime/tracking.ts
155
+ var currentSubscriber = null;
156
+ var readValueCallback = null;
157
+ function getSubscriber() {
158
+ return currentSubscriber;
159
+ }
160
+ function setSubscriber(sub) {
161
+ const prev = currentSubscriber;
162
+ currentSubscriber = sub;
163
+ return prev;
164
+ }
165
+ function getReadValueCallback() {
166
+ return readValueCallback;
167
+ }
168
+ function setReadValueCallback(cb) {
169
+ const prev = readValueCallback;
170
+ readValueCallback = cb;
171
+ return prev;
172
+ }
173
+ function untrack(fn) {
174
+ const prev = currentSubscriber;
175
+ currentSubscriber = null;
176
+ try {
177
+ return fn();
178
+ } finally {
179
+ currentSubscriber = prev;
180
+ }
181
+ }
182
+
82
183
  // src/runtime/scheduler.ts
83
184
  var batchDepth = 0;
84
185
  var pendingEffects = new Map;
@@ -114,36 +215,18 @@ function batch(fn) {
114
215
  }
115
216
  }
116
217
 
117
- // src/runtime/tracking.ts
118
- var currentSubscriber = null;
119
- var readValueCallback = null;
120
- function getSubscriber() {
121
- return currentSubscriber;
122
- }
123
- function setSubscriber(sub) {
124
- const prev = currentSubscriber;
125
- currentSubscriber = sub;
126
- return prev;
218
+ // src/runtime/signal.ts
219
+ function isSSR() {
220
+ const check = typeof globalThis !== "undefined" && globalThis.__VERTZ_IS_SSR__;
221
+ return typeof check === "function" ? check() : false;
127
222
  }
128
- function getReadValueCallback() {
129
- return readValueCallback;
223
+ var signalCollectorStack = [];
224
+ function startSignalCollection() {
225
+ signalCollectorStack.push([]);
130
226
  }
131
- function setReadValueCallback(cb) {
132
- const prev = readValueCallback;
133
- readValueCallback = cb;
134
- return prev;
135
- }
136
- function untrack(fn) {
137
- const prev = currentSubscriber;
138
- currentSubscriber = null;
139
- try {
140
- return fn();
141
- } finally {
142
- currentSubscriber = prev;
143
- }
227
+ function stopSignalCollection() {
228
+ return signalCollectorStack.pop() ?? [];
144
229
  }
145
-
146
- // src/runtime/signal.ts
147
230
  var nextId = 0;
148
231
 
149
232
  class SignalImpl {
@@ -185,7 +268,12 @@ class SignalImpl {
185
268
  }
186
269
  }
187
270
  function signal(initial) {
188
- return new SignalImpl(initial);
271
+ const s = new SignalImpl(initial);
272
+ const collector = signalCollectorStack[signalCollectorStack.length - 1];
273
+ if (collector) {
274
+ collector.push(s);
275
+ }
276
+ return s;
189
277
  }
190
278
  class ComputedImpl {
191
279
  _id;
@@ -297,7 +385,21 @@ class EffectImpl {
297
385
  this._contextScope = null;
298
386
  }
299
387
  }
300
- function effect(fn) {
388
+ function domEffect(fn) {
389
+ if (isSSR()) {
390
+ fn();
391
+ return () => {};
392
+ }
393
+ const eff = new EffectImpl(fn);
394
+ eff._run();
395
+ const dispose = () => eff._dispose();
396
+ _tryOnCleanup(dispose);
397
+ return dispose;
398
+ }
399
+ function lifecycleEffect(fn) {
400
+ if (isSSR()) {
401
+ return () => {};
402
+ }
301
403
  const eff = new EffectImpl(fn);
302
404
  eff._run();
303
405
  const dispose = () => eff._dispose();
@@ -305,4 +407,4 @@ function effect(fn) {
305
407
  return dispose;
306
408
  }
307
409
 
308
- export { createContext, useContext, DisposalScopeError, onCleanup, _tryOnCleanup, pushScope, popScope, runCleanups, batch, setReadValueCallback, untrack, signal, computed, effect };
410
+ export { createContext, useContext, getContextScope, setContextScope, DisposalScopeError, onCleanup, _tryOnCleanup, pushScope, popScope, runCleanups, setReadValueCallback, untrack, batch, startSignalCollection, stopSignalCollection, signal, computed, domEffect, lifecycleEffect };
@@ -0,0 +1,290 @@
1
+ import {
2
+ __classList,
3
+ __on
4
+ } from "./chunk-v3yyf79g.js";
5
+ import {
6
+ __append,
7
+ __element,
8
+ __enterChildren,
9
+ __exitChildren,
10
+ __staticText,
11
+ getIsHydrating
12
+ } from "./chunk-ryb49346.js";
13
+ import {
14
+ _tryOnCleanup,
15
+ createContext,
16
+ domEffect,
17
+ popScope,
18
+ pushScope,
19
+ runCleanups,
20
+ signal,
21
+ untrack,
22
+ useContext
23
+ } from "./chunk-hrd0mft1.js";
24
+
25
+ // src/router/link.ts
26
+ function createLink(currentPath, navigate, factoryOptions) {
27
+ return function Link({
28
+ href,
29
+ children,
30
+ activeClass,
31
+ className,
32
+ prefetch
33
+ }) {
34
+ const handleClick = (event) => {
35
+ const mouseEvent = event;
36
+ if (mouseEvent.ctrlKey || mouseEvent.metaKey || mouseEvent.shiftKey || mouseEvent.altKey) {
37
+ return;
38
+ }
39
+ mouseEvent.preventDefault();
40
+ navigate(href);
41
+ };
42
+ const props = { href };
43
+ if (className) {
44
+ props.class = className;
45
+ }
46
+ const el = __element("a", props);
47
+ __on(el, "click", handleClick);
48
+ __enterChildren(el);
49
+ if (typeof children === "function") {
50
+ const result = children();
51
+ if (typeof result === "string") {
52
+ __append(el, __staticText(result));
53
+ } else {
54
+ __append(el, result);
55
+ }
56
+ } else {
57
+ __append(el, __staticText(children));
58
+ }
59
+ __exitChildren();
60
+ if (activeClass) {
61
+ __classList(el, {
62
+ [activeClass]: () => currentPath.value === href
63
+ });
64
+ }
65
+ if (prefetch === "hover" && factoryOptions?.onPrefetch) {
66
+ let prefetched = false;
67
+ const triggerPrefetch = () => {
68
+ if (prefetched)
69
+ return;
70
+ prefetched = true;
71
+ factoryOptions.onPrefetch?.(href);
72
+ };
73
+ __on(el, "mouseenter", triggerPrefetch);
74
+ __on(el, "focus", triggerPrefetch);
75
+ }
76
+ return el;
77
+ };
78
+ }
79
+
80
+ // src/router/router-context.ts
81
+ var RouterContext = createContext();
82
+ function useRouter() {
83
+ const router = useContext(RouterContext);
84
+ if (!router) {
85
+ throw new Error("useRouter() must be called within RouterContext.Provider");
86
+ }
87
+ return router;
88
+ }
89
+ function useParams() {
90
+ const router = useContext(RouterContext);
91
+ if (!router) {
92
+ throw new Error("useParams() must be called within RouterContext.Provider");
93
+ }
94
+ return router.current?.params ?? {};
95
+ }
96
+
97
+ // src/router/outlet.ts
98
+ var OutletContext = createContext();
99
+ function Outlet() {
100
+ const ctx = useContext(OutletContext);
101
+ if (!ctx) {
102
+ return document.createComment("outlet:empty");
103
+ }
104
+ const container = __element("div");
105
+ let childCleanups = [];
106
+ let renderGen = 0;
107
+ let isFirstHydrationRender = getIsHydrating();
108
+ __enterChildren(container);
109
+ const dispose = domEffect(() => {
110
+ const factory = ctx.childComponent;
111
+ untrack(() => {
112
+ runCleanups(childCleanups);
113
+ if (isFirstHydrationRender) {
114
+ isFirstHydrationRender = false;
115
+ } else {
116
+ while (container.firstChild) {
117
+ container.removeChild(container.firstChild);
118
+ }
119
+ }
120
+ const gen = ++renderGen;
121
+ childCleanups = pushScope();
122
+ if (factory) {
123
+ const result = factory();
124
+ if (result instanceof Promise) {
125
+ const router = ctx.router;
126
+ popScope();
127
+ result.then((mod) => {
128
+ if (gen !== renderGen)
129
+ return;
130
+ childCleanups = pushScope();
131
+ RouterContext.Provider(router, () => {
132
+ const node = mod.default();
133
+ __append(container, node);
134
+ });
135
+ popScope();
136
+ });
137
+ } else {
138
+ __append(container, result);
139
+ popScope();
140
+ }
141
+ } else {
142
+ popScope();
143
+ }
144
+ });
145
+ });
146
+ __exitChildren();
147
+ _tryOnCleanup(() => {
148
+ runCleanups(childCleanups);
149
+ dispose();
150
+ });
151
+ return container;
152
+ }
153
+
154
+ // src/router/router-view.ts
155
+ function hasViewTransition(doc) {
156
+ return "startViewTransition" in doc;
157
+ }
158
+ function withTransition(fn) {
159
+ if (typeof document !== "undefined" && hasViewTransition(document)) {
160
+ document.startViewTransition(fn);
161
+ } else {
162
+ fn();
163
+ }
164
+ }
165
+ function RouterView({ router, fallback }) {
166
+ const container = __element("div");
167
+ let isFirstHydrationRender = getIsHydrating();
168
+ let renderGen = 0;
169
+ let pageCleanups = [];
170
+ let prevLevels = [];
171
+ __enterChildren(container);
172
+ const dispose = domEffect(() => {
173
+ const match = router.current.value;
174
+ untrack(() => {
175
+ const gen = ++renderGen;
176
+ const newMatched = match?.matched ?? [];
177
+ const minLen = Math.min(prevLevels.length, newMatched.length);
178
+ let divergeAt = 0;
179
+ for (divergeAt = 0;divergeAt < minLen; divergeAt++) {
180
+ if (prevLevels[divergeAt].route !== newMatched[divergeAt].route)
181
+ break;
182
+ }
183
+ if (prevLevels.length > 0 && divergeAt === prevLevels.length && divergeAt === newMatched.length) {
184
+ return;
185
+ }
186
+ if (divergeAt > 0 && newMatched.length > 0) {
187
+ const newLevels = buildLevels(newMatched);
188
+ const newChildFactory = buildInsideOutFactory(newMatched, newLevels, divergeAt, router);
189
+ const parentLevel = prevLevels[divergeAt - 1];
190
+ if (parentLevel.childSignal) {
191
+ parentLevel.childSignal.value = newChildFactory;
192
+ }
193
+ prevLevels = [...prevLevels.slice(0, divergeAt), ...newLevels.slice(divergeAt)];
194
+ return;
195
+ }
196
+ runCleanups(pageCleanups);
197
+ const doRender = () => {
198
+ if (!isFirstHydrationRender) {
199
+ while (container.firstChild) {
200
+ container.removeChild(container.firstChild);
201
+ }
202
+ }
203
+ isFirstHydrationRender = false;
204
+ pageCleanups = pushScope();
205
+ if (!match) {
206
+ prevLevels = [];
207
+ if (fallback) {
208
+ container.appendChild(fallback());
209
+ }
210
+ popScope();
211
+ return;
212
+ }
213
+ const levels = buildLevels(newMatched);
214
+ const rootFactory = buildInsideOutFactory(newMatched, levels, 0, router);
215
+ RouterContext.Provider(router, () => {
216
+ const result = rootFactory();
217
+ if (result instanceof Promise) {
218
+ result.then((mod) => {
219
+ if (gen !== renderGen)
220
+ return;
221
+ RouterContext.Provider(router, () => {
222
+ const node = mod.default();
223
+ container.appendChild(node);
224
+ });
225
+ });
226
+ } else {
227
+ __append(container, result);
228
+ }
229
+ });
230
+ prevLevels = levels;
231
+ popScope();
232
+ };
233
+ if (isFirstHydrationRender) {
234
+ doRender();
235
+ } else {
236
+ withTransition(doRender);
237
+ }
238
+ });
239
+ });
240
+ __exitChildren();
241
+ _tryOnCleanup(() => {
242
+ runCleanups(pageCleanups);
243
+ dispose();
244
+ });
245
+ return container;
246
+ }
247
+ function buildLevels(matched) {
248
+ return matched.map((m, i) => ({
249
+ childSignal: i < matched.length - 1 ? signal(undefined) : undefined,
250
+ route: m.route
251
+ }));
252
+ }
253
+ function buildInsideOutFactory(matched, levels, startAt, router) {
254
+ let factory = matched[matched.length - 1].route.component;
255
+ for (let i = matched.length - 2;i >= startAt; i--) {
256
+ const level = levels[i];
257
+ const childFactory = factory;
258
+ level.childSignal.value = childFactory;
259
+ const parentRoute = level.route;
260
+ const cs = level.childSignal;
261
+ factory = () => {
262
+ let result;
263
+ OutletContext.Provider({ childComponent: cs, router }, () => {
264
+ result = parentRoute.component();
265
+ });
266
+ return result;
267
+ };
268
+ }
269
+ return factory;
270
+ }
271
+
272
+ // src/router/search-params.ts
273
+ function parseSearchParams(urlParams, schema) {
274
+ const raw = {};
275
+ for (const [key, value] of urlParams.entries()) {
276
+ raw[key] = value;
277
+ }
278
+ if (schema) {
279
+ const result = schema.parse(raw);
280
+ if (result.ok)
281
+ return result.data;
282
+ return raw;
283
+ }
284
+ return raw;
285
+ }
286
+ function useSearchParams(searchSignal) {
287
+ return searchSignal.value;
288
+ }
289
+
290
+ export { createLink, RouterContext, useRouter, useParams, OutletContext, Outlet, RouterView, parseSearchParams, useSearchParams };