@vertz/ui 0.2.10 → 0.2.12
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.
- package/dist/css/public.js +3 -3
- package/dist/form/public.js +2 -2
- package/dist/index.d.ts +18 -3
- package/dist/index.js +200 -12
- package/dist/internals.d.ts +6 -1
- package/dist/internals.js +74 -24
- package/dist/jsx-runtime/index.d.ts +1 -1
- package/dist/query/public.js +2 -2
- package/dist/router/public.js +5 -5
- package/dist/shared/{chunk-0xcmwgdb.js → chunk-18jzqefd.js} +5 -5
- package/dist/shared/{chunk-hrd0mft1.js → chunk-2rs8a26p.js} +10 -4
- package/dist/shared/{chunk-q6cpe5k7.js → chunk-55tgkc7s.js} +1 -1
- package/dist/shared/{chunk-ryb49346.js → chunk-662f9zrb.js} +1 -1
- package/dist/shared/{chunk-hh0dhmb4.js → chunk-9k2z3jfx.js} +2 -2
- package/dist/shared/{chunk-n91rwj2r.js → chunk-bjcpcq5j.js} +4 -2
- package/dist/shared/{chunk-ka5ked7n.js → chunk-g1gf16fz.js} +1 -1
- package/dist/shared/{chunk-qacth5ah.js → chunk-kg898f92.js} +1 -1
- package/dist/shared/{chunk-v3yyf79g.js → chunk-wn4gv1qd.js} +1 -1
- package/dist/test/index.js +2 -2
- package/package.json +3 -3
package/dist/css/public.js
CHANGED
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
globalCss,
|
|
7
7
|
s,
|
|
8
8
|
variants
|
|
9
|
-
} from "../shared/chunk-
|
|
10
|
-
import"../shared/chunk-
|
|
9
|
+
} from "../shared/chunk-kg898f92.js";
|
|
10
|
+
import"../shared/chunk-662f9zrb.js";
|
|
11
11
|
import"../shared/chunk-g4rch80a.js";
|
|
12
|
-
import"../shared/chunk-
|
|
12
|
+
import"../shared/chunk-2rs8a26p.js";
|
|
13
13
|
import"../shared/chunk-prj7nm08.js";
|
|
14
14
|
export {
|
|
15
15
|
variants,
|
package/dist/form/public.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -148,6 +148,20 @@ declare function ErrorBoundary(props: ErrorBoundaryProps): Node;
|
|
|
148
148
|
* ```
|
|
149
149
|
*/
|
|
150
150
|
declare function onMount2(callback: () => (() => void) | void): void;
|
|
151
|
+
interface ListTransitionProps<T> {
|
|
152
|
+
each: T[];
|
|
153
|
+
keyFn: (item: T, index: number) => string | number;
|
|
154
|
+
children: (item: T) => HTMLElement | SVGElement;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* ListTransition component for animated list item enter/exit.
|
|
158
|
+
* New items get `data-presence="enter"`, removed items get `data-presence="exit"`
|
|
159
|
+
* with DOM removal deferred until CSS animation completes.
|
|
160
|
+
*
|
|
161
|
+
* Props are accessed as getters (not destructured) so the compiler-generated
|
|
162
|
+
* reactive getters are tracked by the underlying domEffect.
|
|
163
|
+
*/
|
|
164
|
+
declare function ListTransition<T>(props: ListTransitionProps<T>): Node;
|
|
151
165
|
interface PresenceProps {
|
|
152
166
|
when: boolean;
|
|
153
167
|
children: () => HTMLElement;
|
|
@@ -735,7 +749,7 @@ interface MountHandle {
|
|
|
735
749
|
* @param options - Mount options (theme, styles, onMount, etc.)
|
|
736
750
|
* @returns MountHandle with unmount function and root element
|
|
737
751
|
*/
|
|
738
|
-
declare function mount<AppFn extends () => Element>(app: AppFn, selector: string | HTMLElement, options?: MountOptions): MountHandle;
|
|
752
|
+
declare function mount<AppFn extends () => Element | DocumentFragment>(app: AppFn, selector: string | HTMLElement, options?: MountOptions): MountHandle;
|
|
739
753
|
import { QueryDescriptor as QueryDescriptor2 } from "@vertz/fetch";
|
|
740
754
|
import { isQueryDescriptor } from "@vertz/fetch";
|
|
741
755
|
/**
|
|
@@ -1174,8 +1188,9 @@ declare class DisposalScopeError extends Error {
|
|
|
1174
1188
|
declare function batch(fn: () => void): void;
|
|
1175
1189
|
/**
|
|
1176
1190
|
* Create a reactive signal with an initial value.
|
|
1191
|
+
* Optional key is used by HMR to match signals by name across re-mounts.
|
|
1177
1192
|
*/
|
|
1178
|
-
declare function signal<T>(initial: T): Signal<T>;
|
|
1193
|
+
declare function signal<T>(initial: T, key?: string): Signal<T>;
|
|
1179
1194
|
/**
|
|
1180
1195
|
* Create a computed (derived) reactive value.
|
|
1181
1196
|
* The function is lazily evaluated and cached.
|
|
@@ -1284,4 +1299,4 @@ declare class EntityStore {
|
|
|
1284
1299
|
* ```
|
|
1285
1300
|
*/
|
|
1286
1301
|
declare function createTestStore(data: Record<string, Record<string, unknown>>): EntityStore;
|
|
1287
|
-
export { zoomOut, zoomIn, variants, validate, useSearchParams, useRouter, useParams, useDialogStack, useContext, untrack, slideOutToTop, slideOutToRight, slideOutToLeft, slideOutToBottom, slideInFromTop, slideInFromRight, slideInFromLeft, slideInFromBottom, signal, setAdapter, s, resolveChildren, resetInjectedStyles, ref, queryMatch, query, parseSearchParams, palettes, onMount2 as onMount, mount, keyframes, isRenderNode, isQueryDescriptor, injectCSS, hydrate, globalCss, getInjectedCSS, getAdapter, formDataToObject, form, fadeOut, fadeIn, defineTheme, defineRoutes, css, createTestStore, createRouter, createLink, createFieldState, createDialogStack, createDOMAdapter, createContext, computed, compileTheme, children, batch, accordionUp, accordionDown, __staticText, __exitChildren, __enterChildren, __element, __append, VariantsConfig, VariantProps, VariantFunction, ValidationResult, UnwrapSignals, TypedRoutes, TypedRouter, ThemeProviderProps, ThemeProvider, ThemeInput, Theme, SuspenseProps, Suspense, StyleValue, StyleEntry, Signal, SerializedStore, SearchParamSchema, SdkMethodWithMeta, SdkMethod, RouterViewProps, RouterView, RouterOptions, RouterContext, Router, RoutePaths, RouteMatch, RouteDefinitionMap, RouteConfig, RenderText, RenderNode, RenderElement, RenderAdapter, Ref, ReadonlySignal, RawDeclaration, RENDER_NODE_BRAND, QueryResult, QueryOptions, QueryMatchHandlers, QueryDescriptor2 as QueryDescriptor, PresenceProps, Presence, PathWithParams, OutletContextValue, OutletContext, Outlet, NavigateOptions, MountOptions, MountHandle, MatchedRoute, LoaderData, LinkProps, LinkFactoryOptions, InferRouteMap, GlobalCSSOutput, GlobalCSSInput, FormSchema, FormOptions, FormInstance, FormDataOptions, FieldState, ExtractParams, ErrorBoundaryProps, ErrorBoundary, EntityStoreOptions, EntityStore, DisposeFn, DisposalScopeError, DialogStackContext, DialogStack, DialogHandle, DialogDismissedError, DialogComponent, Context, Computed, ComponentRegistry, ComponentLoader, ComponentFunction, CompiledTheme, CompiledRoute, ColorPalette, ChildrenAccessor, ChildValue, CacheStore, CSSOutput, CSSInput, ANIMATION_EASING, ANIMATION_DURATION };
|
|
1302
|
+
export { zoomOut, zoomIn, variants, validate, useSearchParams, useRouter, useParams, useDialogStack, useContext, untrack, slideOutToTop, slideOutToRight, slideOutToLeft, slideOutToBottom, slideInFromTop, slideInFromRight, slideInFromLeft, slideInFromBottom, signal, setAdapter, s, resolveChildren, resetInjectedStyles, ref, queryMatch, query, parseSearchParams, palettes, onMount2 as onMount, mount, keyframes, isRenderNode, isQueryDescriptor, injectCSS, hydrate, globalCss, getInjectedCSS, getAdapter, formDataToObject, form, fadeOut, fadeIn, defineTheme, defineRoutes, css, createTestStore, createRouter, createLink, createFieldState, createDialogStack, createDOMAdapter, createContext, computed, compileTheme, children, batch, accordionUp, accordionDown, __staticText, __exitChildren, __enterChildren, __element, __append, VariantsConfig, VariantProps, VariantFunction, ValidationResult, UnwrapSignals, TypedRoutes, TypedRouter, ThemeProviderProps, ThemeProvider, ThemeInput, Theme, SuspenseProps, Suspense, StyleValue, StyleEntry, Signal, SerializedStore, SearchParamSchema, SdkMethodWithMeta, SdkMethod, RouterViewProps, RouterView, RouterOptions, RouterContext, Router, RoutePaths, RouteMatch, RouteDefinitionMap, RouteConfig, RenderText, RenderNode, RenderElement, RenderAdapter, Ref, ReadonlySignal, RawDeclaration, RENDER_NODE_BRAND, QueryResult, QueryOptions, QueryMatchHandlers, QueryDescriptor2 as QueryDescriptor, PresenceProps, Presence, PathWithParams, OutletContextValue, OutletContext, Outlet, NavigateOptions, MountOptions, MountHandle, MatchedRoute, LoaderData, ListTransitionProps, ListTransition, LinkProps, LinkFactoryOptions, InferRouteMap, GlobalCSSOutput, GlobalCSSInput, FormSchema, FormOptions, FormInstance, FormDataOptions, FieldState, ExtractParams, ErrorBoundaryProps, ErrorBoundary, EntityStoreOptions, EntityStore, DisposeFn, DisposalScopeError, DialogStackContext, DialogStack, DialogHandle, DialogDismissedError, DialogComponent, Context, Computed, ComponentRegistry, ComponentLoader, ComponentFunction, CompiledTheme, CompiledRoute, ColorPalette, ChildrenAccessor, ChildValue, CacheStore, CSSOutput, CSSInput, ANIMATION_EASING, ANIMATION_DURATION };
|
package/dist/index.js
CHANGED
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
slideOutToTop,
|
|
21
21
|
zoomIn,
|
|
22
22
|
zoomOut
|
|
23
|
-
} from "./shared/chunk-
|
|
23
|
+
} from "./shared/chunk-bjcpcq5j.js";
|
|
24
24
|
import {
|
|
25
25
|
Outlet,
|
|
26
26
|
OutletContext,
|
|
@@ -31,11 +31,11 @@ import {
|
|
|
31
31
|
useParams,
|
|
32
32
|
useRouter,
|
|
33
33
|
useSearchParams
|
|
34
|
-
} from "./shared/chunk-
|
|
35
|
-
import"./shared/chunk-
|
|
34
|
+
} from "./shared/chunk-18jzqefd.js";
|
|
35
|
+
import"./shared/chunk-wn4gv1qd.js";
|
|
36
36
|
import {
|
|
37
37
|
createRouter
|
|
38
|
-
} from "./shared/chunk-
|
|
38
|
+
} from "./shared/chunk-g1gf16fz.js";
|
|
39
39
|
import {
|
|
40
40
|
defineRoutes
|
|
41
41
|
} from "./shared/chunk-9e92w0wt.js";
|
|
@@ -44,11 +44,11 @@ import {
|
|
|
44
44
|
form,
|
|
45
45
|
formDataToObject,
|
|
46
46
|
validate
|
|
47
|
-
} from "./shared/chunk-
|
|
47
|
+
} from "./shared/chunk-55tgkc7s.js";
|
|
48
48
|
import {
|
|
49
49
|
query,
|
|
50
50
|
queryMatch
|
|
51
|
-
} from "./shared/chunk-
|
|
51
|
+
} from "./shared/chunk-9k2z3jfx.js";
|
|
52
52
|
import"./shared/chunk-jrtrk5z4.js";
|
|
53
53
|
import {
|
|
54
54
|
ThemeProvider,
|
|
@@ -63,7 +63,7 @@ import {
|
|
|
63
63
|
resolveChildren,
|
|
64
64
|
s,
|
|
65
65
|
variants
|
|
66
|
-
} from "./shared/chunk-
|
|
66
|
+
} from "./shared/chunk-kg898f92.js";
|
|
67
67
|
import {
|
|
68
68
|
__append,
|
|
69
69
|
__element,
|
|
@@ -72,7 +72,7 @@ import {
|
|
|
72
72
|
__staticText,
|
|
73
73
|
endHydration,
|
|
74
74
|
startHydration
|
|
75
|
-
} from "./shared/chunk-
|
|
75
|
+
} from "./shared/chunk-662f9zrb.js";
|
|
76
76
|
import {
|
|
77
77
|
RENDER_NODE_BRAND,
|
|
78
78
|
createDOMAdapter,
|
|
@@ -95,7 +95,7 @@ import {
|
|
|
95
95
|
signal,
|
|
96
96
|
untrack,
|
|
97
97
|
useContext
|
|
98
|
-
} from "./shared/chunk-
|
|
98
|
+
} from "./shared/chunk-2rs8a26p.js";
|
|
99
99
|
import"./shared/chunk-prj7nm08.js";
|
|
100
100
|
// src/component/error-boundary-context.ts
|
|
101
101
|
var handlerStack = [];
|
|
@@ -174,6 +174,179 @@ function onMount(callback) {
|
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
176
|
}
|
|
177
|
+
// src/dom/list-transition.ts
|
|
178
|
+
function createItemProxy(itemSignal) {
|
|
179
|
+
if (typeof itemSignal.peek() !== "object" || itemSignal.peek() == null) {
|
|
180
|
+
return itemSignal.peek();
|
|
181
|
+
}
|
|
182
|
+
return new Proxy({}, {
|
|
183
|
+
get(_target, prop, receiver) {
|
|
184
|
+
const current = itemSignal.value;
|
|
185
|
+
if (current == null)
|
|
186
|
+
return;
|
|
187
|
+
const value = Reflect.get(current, prop, receiver);
|
|
188
|
+
if (typeof value === "function") {
|
|
189
|
+
return value.bind(current);
|
|
190
|
+
}
|
|
191
|
+
return value;
|
|
192
|
+
},
|
|
193
|
+
has(_target, prop) {
|
|
194
|
+
const current = itemSignal.value;
|
|
195
|
+
if (current == null)
|
|
196
|
+
return false;
|
|
197
|
+
return Reflect.has(current, prop);
|
|
198
|
+
},
|
|
199
|
+
ownKeys() {
|
|
200
|
+
const current = itemSignal.value;
|
|
201
|
+
if (current == null)
|
|
202
|
+
return [];
|
|
203
|
+
return Reflect.ownKeys(current);
|
|
204
|
+
},
|
|
205
|
+
getOwnPropertyDescriptor(_target, prop) {
|
|
206
|
+
const current = itemSignal.value;
|
|
207
|
+
if (current == null)
|
|
208
|
+
return;
|
|
209
|
+
return Reflect.getOwnPropertyDescriptor(current, prop);
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
function listTransition(startMarker, endMarker, items, keyFn, renderFn) {
|
|
214
|
+
const getItems = typeof items === "function" ? items : () => items.value;
|
|
215
|
+
const nodeMap = new Map;
|
|
216
|
+
const scopeMap = new Map;
|
|
217
|
+
const itemSignalMap = new Map;
|
|
218
|
+
const exitingNodes = new Set;
|
|
219
|
+
const exitingKeyMap = new Map;
|
|
220
|
+
const keyGeneration = new Map;
|
|
221
|
+
let isFirstRun = true;
|
|
222
|
+
const outerScope = pushScope();
|
|
223
|
+
try {
|
|
224
|
+
domEffect(() => {
|
|
225
|
+
const newItems = getItems() ?? [];
|
|
226
|
+
const newKeySet = new Set(newItems.map((item, i) => keyFn(item, i)));
|
|
227
|
+
if (isFirstRun) {
|
|
228
|
+
isFirstRun = false;
|
|
229
|
+
for (const [i, item] of newItems.entries()) {
|
|
230
|
+
const key = keyFn(item, i);
|
|
231
|
+
const itemSig = signal(item);
|
|
232
|
+
const proxy = createItemProxy(itemSig);
|
|
233
|
+
const scope = pushScope();
|
|
234
|
+
const node = renderFn(proxy);
|
|
235
|
+
popScope();
|
|
236
|
+
nodeMap.set(key, node);
|
|
237
|
+
scopeMap.set(key, scope);
|
|
238
|
+
itemSignalMap.set(key, itemSig);
|
|
239
|
+
endMarker.parentNode?.insertBefore(node, endMarker);
|
|
240
|
+
}
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
for (const [key, node] of nodeMap) {
|
|
244
|
+
if (!newKeySet.has(key)) {
|
|
245
|
+
const scope = scopeMap.get(key);
|
|
246
|
+
if (scope) {
|
|
247
|
+
runCleanups(scope);
|
|
248
|
+
scopeMap.delete(key);
|
|
249
|
+
}
|
|
250
|
+
nodeMap.delete(key);
|
|
251
|
+
itemSignalMap.delete(key);
|
|
252
|
+
const gen = (keyGeneration.get(key) ?? 0) + 1;
|
|
253
|
+
keyGeneration.set(key, gen);
|
|
254
|
+
exitingNodes.add(node);
|
|
255
|
+
exitingKeyMap.set(key, node);
|
|
256
|
+
node.setAttribute("data-presence", "exit");
|
|
257
|
+
onAnimationsComplete(node, () => {
|
|
258
|
+
if (keyGeneration.get(key) === gen) {
|
|
259
|
+
node.parentNode?.removeChild(node);
|
|
260
|
+
exitingNodes.delete(node);
|
|
261
|
+
exitingKeyMap.delete(key);
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
const desiredNodes = [];
|
|
267
|
+
const enterNodes = [];
|
|
268
|
+
for (const [i, item] of newItems.entries()) {
|
|
269
|
+
const key = keyFn(item, i);
|
|
270
|
+
let node = nodeMap.get(key);
|
|
271
|
+
if (!node) {
|
|
272
|
+
const oldExiting = exitingKeyMap.get(key);
|
|
273
|
+
if (oldExiting) {
|
|
274
|
+
oldExiting.parentNode?.removeChild(oldExiting);
|
|
275
|
+
exitingNodes.delete(oldExiting);
|
|
276
|
+
exitingKeyMap.delete(key);
|
|
277
|
+
}
|
|
278
|
+
const gen = (keyGeneration.get(key) ?? 0) + 1;
|
|
279
|
+
keyGeneration.set(key, gen);
|
|
280
|
+
const itemSig = signal(item);
|
|
281
|
+
const proxy = createItemProxy(itemSig);
|
|
282
|
+
const scope = pushScope();
|
|
283
|
+
node = renderFn(proxy);
|
|
284
|
+
popScope();
|
|
285
|
+
nodeMap.set(key, node);
|
|
286
|
+
scopeMap.set(key, scope);
|
|
287
|
+
itemSignalMap.set(key, itemSig);
|
|
288
|
+
node.setAttribute("data-presence", "enter");
|
|
289
|
+
enterNodes.push({ node, key });
|
|
290
|
+
} else {
|
|
291
|
+
const itemSig = itemSignalMap.get(key);
|
|
292
|
+
if (itemSig) {
|
|
293
|
+
itemSig.value = item;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
desiredNodes.push(node);
|
|
297
|
+
}
|
|
298
|
+
const parent = startMarker.parentNode;
|
|
299
|
+
if (parent) {
|
|
300
|
+
let cursor = startMarker.nextSibling;
|
|
301
|
+
for (const desired of desiredNodes) {
|
|
302
|
+
while (cursor && cursor !== endMarker && exitingNodes.has(cursor)) {
|
|
303
|
+
cursor = cursor.nextSibling;
|
|
304
|
+
}
|
|
305
|
+
if (cursor === desired) {
|
|
306
|
+
cursor = cursor.nextSibling;
|
|
307
|
+
} else {
|
|
308
|
+
parent.insertBefore(desired, cursor);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
for (const { node: enterNode, key } of enterNodes) {
|
|
313
|
+
onAnimationsComplete(enterNode, () => {
|
|
314
|
+
if (nodeMap.get(key) === enterNode) {
|
|
315
|
+
enterNode.removeAttribute("data-presence");
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
} finally {
|
|
321
|
+
popScope();
|
|
322
|
+
}
|
|
323
|
+
const dispose = () => {
|
|
324
|
+
for (const scope of scopeMap.values()) {
|
|
325
|
+
runCleanups(scope);
|
|
326
|
+
}
|
|
327
|
+
scopeMap.clear();
|
|
328
|
+
for (const node of exitingNodes) {
|
|
329
|
+
node.parentNode?.removeChild(node);
|
|
330
|
+
}
|
|
331
|
+
exitingNodes.clear();
|
|
332
|
+
exitingKeyMap.clear();
|
|
333
|
+
runCleanups(outerScope);
|
|
334
|
+
};
|
|
335
|
+
_tryOnCleanup(dispose);
|
|
336
|
+
return dispose;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// src/component/list-transition.ts
|
|
340
|
+
function ListTransition(props) {
|
|
341
|
+
const startMarker = document.createComment("lt-start");
|
|
342
|
+
const endMarker = document.createComment("lt-end");
|
|
343
|
+
const fragment = document.createDocumentFragment();
|
|
344
|
+
fragment.appendChild(startMarker);
|
|
345
|
+
fragment.appendChild(endMarker);
|
|
346
|
+
const dispose = listTransition(startMarker, endMarker, () => props.each, props.keyFn, props.children);
|
|
347
|
+
_tryOnCleanup(dispose);
|
|
348
|
+
return Object.assign(fragment, { dispose });
|
|
349
|
+
}
|
|
177
350
|
// src/component/presence.ts
|
|
178
351
|
function Presence(props) {
|
|
179
352
|
const anchor = document.createComment("presence");
|
|
@@ -293,7 +466,7 @@ function Suspense(props) {
|
|
|
293
466
|
}
|
|
294
467
|
}
|
|
295
468
|
// src/dialog/dialog-stack.ts
|
|
296
|
-
var DialogStackContext = createContext();
|
|
469
|
+
var DialogStackContext = createContext(undefined, "@vertz/ui::DialogStackContext");
|
|
297
470
|
function useDialogStack() {
|
|
298
471
|
const stack = useContext(DialogStackContext);
|
|
299
472
|
if (!stack) {
|
|
@@ -432,6 +605,11 @@ function createDialogStack(container) {
|
|
|
432
605
|
}
|
|
433
606
|
}
|
|
434
607
|
// src/mount.ts
|
|
608
|
+
var MOUNTED_KEY = Symbol.for("vertz:mounted-roots");
|
|
609
|
+
var _global = globalThis;
|
|
610
|
+
if (!_global[MOUNTED_KEY])
|
|
611
|
+
_global[MOUNTED_KEY] = new WeakMap;
|
|
612
|
+
var mountedRoots = _global[MOUNTED_KEY];
|
|
435
613
|
function mount(app, selector, options) {
|
|
436
614
|
if (typeof selector !== "string" && !(selector instanceof HTMLElement)) {
|
|
437
615
|
throw new Error(`mount(): selector must be a string or HTMLElement, got ${typeof selector}`);
|
|
@@ -440,6 +618,9 @@ function mount(app, selector, options) {
|
|
|
440
618
|
if (!root) {
|
|
441
619
|
throw new Error(`mount(): root element "${selector}" not found`);
|
|
442
620
|
}
|
|
621
|
+
const existingHandle = mountedRoots.get(root);
|
|
622
|
+
if (existingHandle)
|
|
623
|
+
return existingHandle;
|
|
443
624
|
if (options?.theme) {
|
|
444
625
|
const { css: css2 } = compileTheme(options.theme);
|
|
445
626
|
injectCSS(css2);
|
|
@@ -457,13 +638,16 @@ function mount(app, selector, options) {
|
|
|
457
638
|
endHydration();
|
|
458
639
|
popScope();
|
|
459
640
|
options?.onMount?.(root);
|
|
460
|
-
|
|
641
|
+
const handle2 = {
|
|
461
642
|
unmount: () => {
|
|
643
|
+
mountedRoots.delete(root);
|
|
462
644
|
runCleanups(scope2);
|
|
463
645
|
root.textContent = "";
|
|
464
646
|
},
|
|
465
647
|
root
|
|
466
648
|
};
|
|
649
|
+
mountedRoots.set(root, handle2);
|
|
650
|
+
return handle2;
|
|
467
651
|
} catch (e) {
|
|
468
652
|
endHydration();
|
|
469
653
|
popScope();
|
|
@@ -479,13 +663,16 @@ function mount(app, selector, options) {
|
|
|
479
663
|
root.appendChild(appElement);
|
|
480
664
|
popScope();
|
|
481
665
|
options?.onMount?.(root);
|
|
482
|
-
|
|
666
|
+
const handle = {
|
|
483
667
|
unmount: () => {
|
|
668
|
+
mountedRoots.delete(root);
|
|
484
669
|
runCleanups(scope);
|
|
485
670
|
root.textContent = "";
|
|
486
671
|
},
|
|
487
672
|
root
|
|
488
673
|
};
|
|
674
|
+
mountedRoots.set(root, handle);
|
|
675
|
+
return handle;
|
|
489
676
|
}
|
|
490
677
|
// src/store/merge.ts
|
|
491
678
|
function shallowMerge(existing, incoming) {
|
|
@@ -773,6 +960,7 @@ export {
|
|
|
773
960
|
Presence,
|
|
774
961
|
OutletContext,
|
|
775
962
|
Outlet,
|
|
963
|
+
ListTransition,
|
|
776
964
|
ErrorBoundary,
|
|
777
965
|
EntityStore,
|
|
778
966
|
DisposalScopeError,
|
package/dist/internals.d.ts
CHANGED
|
@@ -195,7 +195,7 @@ declare function setAdapter(adapter: RenderAdapter | null): void;
|
|
|
195
195
|
* If no animations are running, calls back immediately.
|
|
196
196
|
* Respects prefers-reduced-motion by skipping the wait.
|
|
197
197
|
*/
|
|
198
|
-
declare function onAnimationsComplete(el:
|
|
198
|
+
declare function onAnimationsComplete(el: Element, callback: () => void): void;
|
|
199
199
|
/**
|
|
200
200
|
* Create a reactive attribute binding.
|
|
201
201
|
* When the value returned by `fn` changes, the attribute is updated.
|
|
@@ -340,6 +340,11 @@ declare function clearChildren(container: Node): void;
|
|
|
340
340
|
* Efficiently updates a container's children when the items signal changes.
|
|
341
341
|
* Reuses existing DOM nodes based on key identity — no virtual DOM.
|
|
342
342
|
*
|
|
343
|
+
* Each item is wrapped in a reactive proxy backed by a signal. When the item
|
|
344
|
+
* at an existing key changes (e.g., after refetch), the signal updates and
|
|
345
|
+
* any reactive bindings inside the node (domEffect, __child) re-run
|
|
346
|
+
* automatically — without re-creating the DOM node.
|
|
347
|
+
*
|
|
343
348
|
* Compiler output target for .map() / for-each expressions in JSX.
|
|
344
349
|
*
|
|
345
350
|
* @param container - The parent DOM element
|
package/dist/internals.js
CHANGED
|
@@ -2,13 +2,13 @@ import {
|
|
|
2
2
|
deserializeProps,
|
|
3
3
|
onAnimationsComplete,
|
|
4
4
|
resolveComponent
|
|
5
|
-
} from "./shared/chunk-
|
|
5
|
+
} from "./shared/chunk-bjcpcq5j.js";
|
|
6
6
|
import {
|
|
7
7
|
__attr,
|
|
8
8
|
__classList,
|
|
9
9
|
__on,
|
|
10
10
|
__show
|
|
11
|
-
} from "./shared/chunk-
|
|
11
|
+
} from "./shared/chunk-wn4gv1qd.js";
|
|
12
12
|
import {
|
|
13
13
|
executeLoaders,
|
|
14
14
|
matchPath,
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
import {
|
|
18
18
|
MemoryCache,
|
|
19
19
|
deriveKey
|
|
20
|
-
} from "./shared/chunk-
|
|
20
|
+
} from "./shared/chunk-9k2z3jfx.js";
|
|
21
21
|
import"./shared/chunk-jrtrk5z4.js";
|
|
22
22
|
import {
|
|
23
23
|
ALIGNMENT_MAP,
|
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
SIZE_KEYWORDS,
|
|
39
39
|
SPACING_SCALE,
|
|
40
40
|
compileTheme
|
|
41
|
-
} from "./shared/chunk-
|
|
41
|
+
} from "./shared/chunk-kg898f92.js";
|
|
42
42
|
import {
|
|
43
43
|
__append,
|
|
44
44
|
__child,
|
|
@@ -51,7 +51,7 @@ import {
|
|
|
51
51
|
claimComment,
|
|
52
52
|
claimText,
|
|
53
53
|
getIsHydrating
|
|
54
|
-
} from "./shared/chunk-
|
|
54
|
+
} from "./shared/chunk-662f9zrb.js";
|
|
55
55
|
import {
|
|
56
56
|
RENDER_NODE_BRAND,
|
|
57
57
|
createDOMAdapter,
|
|
@@ -69,11 +69,27 @@ import {
|
|
|
69
69
|
pushScope,
|
|
70
70
|
runCleanups,
|
|
71
71
|
setContextScope,
|
|
72
|
+
signal,
|
|
72
73
|
startSignalCollection,
|
|
73
74
|
stopSignalCollection
|
|
74
|
-
} from "./shared/chunk-
|
|
75
|
+
} from "./shared/chunk-2rs8a26p.js";
|
|
75
76
|
import"./shared/chunk-prj7nm08.js";
|
|
76
77
|
// src/dom/conditional.ts
|
|
78
|
+
function normalizeNode(branchResult) {
|
|
79
|
+
if (branchResult == null || typeof branchResult === "boolean") {
|
|
80
|
+
return getAdapter().createComment("empty");
|
|
81
|
+
}
|
|
82
|
+
if (isRenderNode(branchResult)) {
|
|
83
|
+
if (branchResult.nodeType === 11) {
|
|
84
|
+
const wrap = getAdapter().createElement("span");
|
|
85
|
+
wrap.style.display = "contents";
|
|
86
|
+
wrap.appendChild(branchResult);
|
|
87
|
+
return wrap;
|
|
88
|
+
}
|
|
89
|
+
return branchResult;
|
|
90
|
+
}
|
|
91
|
+
return getAdapter().createTextNode(String(branchResult));
|
|
92
|
+
}
|
|
77
93
|
function __conditional(condFn, trueFn, falseFn) {
|
|
78
94
|
if (getIsHydrating()) {
|
|
79
95
|
return hydrateConditional(condFn, trueFn, falseFn);
|
|
@@ -109,14 +125,7 @@ function hydrateConditional(condFn, trueFn, falseFn) {
|
|
|
109
125
|
const branchResult = show ? trueFn() : falseFn();
|
|
110
126
|
popScope();
|
|
111
127
|
branchCleanups = scope;
|
|
112
|
-
|
|
113
|
-
if (branchResult == null || typeof branchResult === "boolean") {
|
|
114
|
-
newNode = getAdapter().createComment("empty");
|
|
115
|
-
} else if (isRenderNode(branchResult)) {
|
|
116
|
-
newNode = branchResult;
|
|
117
|
-
} else {
|
|
118
|
-
newNode = getAdapter().createTextNode(String(branchResult));
|
|
119
|
-
}
|
|
128
|
+
const newNode = normalizeNode(branchResult);
|
|
120
129
|
if (currentNode?.parentNode) {
|
|
121
130
|
currentNode.parentNode.replaceChild(newNode, currentNode);
|
|
122
131
|
} else if (anchor.parentNode) {
|
|
@@ -147,14 +156,7 @@ function csrConditional(condFn, trueFn, falseFn) {
|
|
|
147
156
|
const branchResult = show ? trueFn() : falseFn();
|
|
148
157
|
popScope();
|
|
149
158
|
branchCleanups = scope;
|
|
150
|
-
|
|
151
|
-
if (branchResult == null || typeof branchResult === "boolean") {
|
|
152
|
-
newNode = getAdapter().createComment("empty");
|
|
153
|
-
} else if (isRenderNode(branchResult)) {
|
|
154
|
-
newNode = branchResult;
|
|
155
|
-
} else {
|
|
156
|
-
newNode = getAdapter().createTextNode(String(branchResult));
|
|
157
|
-
}
|
|
159
|
+
const newNode = normalizeNode(branchResult);
|
|
158
160
|
if (currentNode?.parentNode) {
|
|
159
161
|
currentNode.parentNode.replaceChild(newNode, currentNode);
|
|
160
162
|
} else if (anchor.parentNode) {
|
|
@@ -189,10 +191,46 @@ function clearChildren(container) {
|
|
|
189
191
|
}
|
|
190
192
|
}
|
|
191
193
|
// src/dom/list.ts
|
|
194
|
+
function createItemProxy(itemSignal) {
|
|
195
|
+
if (typeof itemSignal.peek() !== "object" || itemSignal.peek() == null) {
|
|
196
|
+
return itemSignal.peek();
|
|
197
|
+
}
|
|
198
|
+
return new Proxy({}, {
|
|
199
|
+
get(_target, prop, receiver) {
|
|
200
|
+
const current = itemSignal.value;
|
|
201
|
+
if (current == null)
|
|
202
|
+
return;
|
|
203
|
+
const value = Reflect.get(current, prop, receiver);
|
|
204
|
+
if (typeof value === "function") {
|
|
205
|
+
return value.bind(current);
|
|
206
|
+
}
|
|
207
|
+
return value;
|
|
208
|
+
},
|
|
209
|
+
has(_target, prop) {
|
|
210
|
+
const current = itemSignal.value;
|
|
211
|
+
if (current == null)
|
|
212
|
+
return false;
|
|
213
|
+
return Reflect.has(current, prop);
|
|
214
|
+
},
|
|
215
|
+
ownKeys() {
|
|
216
|
+
const current = itemSignal.value;
|
|
217
|
+
if (current == null)
|
|
218
|
+
return [];
|
|
219
|
+
return Reflect.ownKeys(current);
|
|
220
|
+
},
|
|
221
|
+
getOwnPropertyDescriptor(_target, prop) {
|
|
222
|
+
const current = itemSignal.value;
|
|
223
|
+
if (current == null)
|
|
224
|
+
return;
|
|
225
|
+
return Reflect.getOwnPropertyDescriptor(current, prop);
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
}
|
|
192
229
|
function __list(container, items, keyFn, renderFn) {
|
|
193
230
|
const getItems = typeof items === "function" ? items : () => items.value;
|
|
194
231
|
const nodeMap = new Map;
|
|
195
232
|
const scopeMap = new Map;
|
|
233
|
+
const itemSignalMap = new Map;
|
|
196
234
|
const isHydrationRun = getIsHydrating();
|
|
197
235
|
const outerScope = pushScope();
|
|
198
236
|
let isFirstRun = true;
|
|
@@ -202,11 +240,14 @@ function __list(container, items, keyFn, renderFn) {
|
|
|
202
240
|
isFirstRun = false;
|
|
203
241
|
for (const [i, item] of newItems.entries()) {
|
|
204
242
|
const key = keyFn(item, i);
|
|
243
|
+
const itemSig = signal(item);
|
|
244
|
+
const proxy = createItemProxy(itemSig);
|
|
205
245
|
const scope = pushScope();
|
|
206
|
-
const node = renderFn(
|
|
246
|
+
const node = renderFn(proxy);
|
|
207
247
|
popScope();
|
|
208
248
|
nodeMap.set(key, node);
|
|
209
249
|
scopeMap.set(key, scope);
|
|
250
|
+
itemSignalMap.set(key, itemSig);
|
|
210
251
|
}
|
|
211
252
|
return;
|
|
212
253
|
}
|
|
@@ -221,6 +262,7 @@ function __list(container, items, keyFn, renderFn) {
|
|
|
221
262
|
}
|
|
222
263
|
node.parentNode?.removeChild(node);
|
|
223
264
|
nodeMap.delete(key);
|
|
265
|
+
itemSignalMap.delete(key);
|
|
224
266
|
}
|
|
225
267
|
}
|
|
226
268
|
const desiredNodes = [];
|
|
@@ -228,11 +270,19 @@ function __list(container, items, keyFn, renderFn) {
|
|
|
228
270
|
const key = keyFn(item, i);
|
|
229
271
|
let node = nodeMap.get(key);
|
|
230
272
|
if (!node) {
|
|
273
|
+
const itemSig = signal(item);
|
|
274
|
+
const proxy = createItemProxy(itemSig);
|
|
231
275
|
const scope = pushScope();
|
|
232
|
-
node = renderFn(
|
|
276
|
+
node = renderFn(proxy);
|
|
233
277
|
popScope();
|
|
234
278
|
nodeMap.set(key, node);
|
|
235
279
|
scopeMap.set(key, scope);
|
|
280
|
+
itemSignalMap.set(key, itemSig);
|
|
281
|
+
} else {
|
|
282
|
+
const itemSig = itemSignalMap.get(key);
|
|
283
|
+
if (itemSig) {
|
|
284
|
+
itemSig.value = item;
|
|
285
|
+
}
|
|
236
286
|
}
|
|
237
287
|
desiredNodes.push(node);
|
|
238
288
|
}
|
|
@@ -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;
|
package/dist/query/public.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
query,
|
|
3
3
|
queryMatch
|
|
4
|
-
} from "../shared/chunk-
|
|
4
|
+
} from "../shared/chunk-9k2z3jfx.js";
|
|
5
5
|
import"../shared/chunk-jrtrk5z4.js";
|
|
6
6
|
import"../shared/chunk-g4rch80a.js";
|
|
7
|
-
import"../shared/chunk-
|
|
7
|
+
import"../shared/chunk-2rs8a26p.js";
|
|
8
8
|
|
|
9
9
|
// src/query/public.ts
|
|
10
10
|
import { isQueryDescriptor } from "@vertz/fetch";
|
package/dist/router/public.js
CHANGED
|
@@ -8,18 +8,18 @@ import {
|
|
|
8
8
|
useParams,
|
|
9
9
|
useRouter,
|
|
10
10
|
useSearchParams
|
|
11
|
-
} from "../shared/chunk-
|
|
12
|
-
import"../shared/chunk-
|
|
11
|
+
} from "../shared/chunk-18jzqefd.js";
|
|
12
|
+
import"../shared/chunk-wn4gv1qd.js";
|
|
13
13
|
import {
|
|
14
14
|
createRouter
|
|
15
|
-
} from "../shared/chunk-
|
|
15
|
+
} from "../shared/chunk-g1gf16fz.js";
|
|
16
16
|
import {
|
|
17
17
|
defineRoutes
|
|
18
18
|
} from "../shared/chunk-9e92w0wt.js";
|
|
19
19
|
import"../shared/chunk-jrtrk5z4.js";
|
|
20
|
-
import"../shared/chunk-
|
|
20
|
+
import"../shared/chunk-662f9zrb.js";
|
|
21
21
|
import"../shared/chunk-g4rch80a.js";
|
|
22
|
-
import"../shared/chunk-
|
|
22
|
+
import"../shared/chunk-2rs8a26p.js";
|
|
23
23
|
import"../shared/chunk-prj7nm08.js";
|
|
24
24
|
export {
|
|
25
25
|
useSearchParams,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
__classList,
|
|
3
3
|
__on
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-wn4gv1qd.js";
|
|
5
5
|
import {
|
|
6
6
|
__append,
|
|
7
7
|
__element,
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
__exitChildren,
|
|
10
10
|
__staticText,
|
|
11
11
|
getIsHydrating
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-662f9zrb.js";
|
|
13
13
|
import {
|
|
14
14
|
_tryOnCleanup,
|
|
15
15
|
createContext,
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
signal,
|
|
21
21
|
untrack,
|
|
22
22
|
useContext
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-2rs8a26p.js";
|
|
24
24
|
|
|
25
25
|
// src/router/link.ts
|
|
26
26
|
var DANGEROUS_SCHEMES = ["javascript:", "data:", "vbscript:"];
|
|
@@ -90,7 +90,7 @@ function createLink(currentPath, navigate, factoryOptions) {
|
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
// src/router/router-context.ts
|
|
93
|
-
var RouterContext = createContext();
|
|
93
|
+
var RouterContext = createContext(undefined, "@vertz/ui::RouterContext");
|
|
94
94
|
function useRouter() {
|
|
95
95
|
const router = useContext(RouterContext);
|
|
96
96
|
if (!router) {
|
|
@@ -107,7 +107,7 @@ function useParams() {
|
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
// src/router/outlet.ts
|
|
110
|
-
var OutletContext = createContext();
|
|
110
|
+
var OutletContext = createContext(undefined, "@vertz/ui::OutletContext");
|
|
111
111
|
function Outlet() {
|
|
112
112
|
const ctx = useContext(OutletContext);
|
|
113
113
|
if (!ctx) {
|
|
@@ -220,7 +220,11 @@ function isSSR() {
|
|
|
220
220
|
const check = typeof globalThis !== "undefined" && globalThis.__VERTZ_IS_SSR__;
|
|
221
221
|
return typeof check === "function" ? check() : false;
|
|
222
222
|
}
|
|
223
|
-
var
|
|
223
|
+
var COLLECTOR_KEY = Symbol.for("vertz:signal-collector-stack");
|
|
224
|
+
var _global = globalThis;
|
|
225
|
+
if (!_global[COLLECTOR_KEY])
|
|
226
|
+
_global[COLLECTOR_KEY] = [];
|
|
227
|
+
var signalCollectorStack = _global[COLLECTOR_KEY];
|
|
224
228
|
function startSignalCollection() {
|
|
225
229
|
signalCollectorStack.push([]);
|
|
226
230
|
}
|
|
@@ -232,8 +236,10 @@ var nextId = 0;
|
|
|
232
236
|
class SignalImpl {
|
|
233
237
|
_value;
|
|
234
238
|
_subscribers = new Set;
|
|
235
|
-
|
|
239
|
+
_hmrKey;
|
|
240
|
+
constructor(initial, key) {
|
|
236
241
|
this._value = initial;
|
|
242
|
+
this._hmrKey = key;
|
|
237
243
|
}
|
|
238
244
|
get value() {
|
|
239
245
|
const sub = getSubscriber();
|
|
@@ -267,8 +273,8 @@ class SignalImpl {
|
|
|
267
273
|
});
|
|
268
274
|
}
|
|
269
275
|
}
|
|
270
|
-
function signal(initial) {
|
|
271
|
-
const s = new SignalImpl(initial);
|
|
276
|
+
function signal(initial, key) {
|
|
277
|
+
const s = new SignalImpl(initial, key);
|
|
272
278
|
const collector = signalCollectorStack[signalCollectorStack.length - 1];
|
|
273
279
|
if (collector) {
|
|
274
280
|
collector.push(s);
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
setReadValueCallback,
|
|
17
17
|
signal,
|
|
18
18
|
untrack
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-2rs8a26p.js";
|
|
20
20
|
|
|
21
21
|
// src/query/cache.ts
|
|
22
22
|
class MemoryCache {
|
|
@@ -459,7 +459,7 @@ function queryMatch(queryResult, handlers) {
|
|
|
459
459
|
} else {
|
|
460
460
|
branch = "data";
|
|
461
461
|
}
|
|
462
|
-
if (branch === currentBranch
|
|
462
|
+
if (branch === currentBranch) {
|
|
463
463
|
return;
|
|
464
464
|
}
|
|
465
465
|
runCleanups(branchCleanups);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
injectCSS
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-kg898f92.js";
|
|
4
4
|
|
|
5
5
|
// src/dom/animation.ts
|
|
6
6
|
function onAnimationsComplete(el, callback) {
|
|
@@ -8,7 +8,9 @@ function onAnimationsComplete(el, callback) {
|
|
|
8
8
|
callback();
|
|
9
9
|
return;
|
|
10
10
|
}
|
|
11
|
-
el
|
|
11
|
+
if ("offsetHeight" in el) {
|
|
12
|
+
el.offsetHeight;
|
|
13
|
+
}
|
|
12
14
|
if (typeof el.getAnimations === "function") {
|
|
13
15
|
const animations = el.getAnimations();
|
|
14
16
|
if (animations.length > 0) {
|
package/dist/test/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createRouter
|
|
3
|
-
} from "../shared/chunk-
|
|
3
|
+
} from "../shared/chunk-g1gf16fz.js";
|
|
4
4
|
import {
|
|
5
5
|
defineRoutes
|
|
6
6
|
} from "../shared/chunk-9e92w0wt.js";
|
|
7
7
|
import"../shared/chunk-jrtrk5z4.js";
|
|
8
|
-
import"../shared/chunk-
|
|
8
|
+
import"../shared/chunk-2rs8a26p.js";
|
|
9
9
|
|
|
10
10
|
// src/test/interactions.ts
|
|
11
11
|
async function click(el) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vertz/ui",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.12",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Vertz UI framework — signals, components, JSX runtime",
|
|
@@ -63,11 +63,11 @@
|
|
|
63
63
|
"typecheck": "tsc --noEmit"
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
|
-
"@vertz/fetch": "^0.2.
|
|
66
|
+
"@vertz/fetch": "^0.2.11"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
69
|
"@happy-dom/global-registrator": "^20.7.0",
|
|
70
|
-
"@vertz/schema": "^0.2.
|
|
70
|
+
"@vertz/schema": "^0.2.11",
|
|
71
71
|
"bunup": "^0.16.31",
|
|
72
72
|
"happy-dom": "^20.7.0",
|
|
73
73
|
"typescript": "^5.7.0"
|