@vuetify/v0 0.0.2-beta.4 → 0.0.3

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 (52) hide show
  1. package/README.md +251 -0
  2. package/dist/browser/index.js +3199 -0
  3. package/dist/components/index.d.ts +7 -0
  4. package/dist/components/index.js +8 -0
  5. package/dist/{components-B5iiovK7.mjs → components-DVuB4lnH.js} +16 -217
  6. package/dist/composables/index.d.ts +7 -0
  7. package/dist/composables/index.js +8 -0
  8. package/dist/composables-yeVk-ULz.js +1270 -0
  9. package/dist/constants/index.d.ts +2 -0
  10. package/dist/constants/index.js +5 -0
  11. package/dist/constants-DiTCgvMU.js +1 -0
  12. package/dist/factories/index.d.ts +2 -0
  13. package/dist/factories/index.js +3 -0
  14. package/dist/{createTrinity-CwGvQ2ng.mjs → factories-BEpawPUw.js} +32 -15
  15. package/dist/globals-DZvNEOB4.js +12 -0
  16. package/dist/htmlElements-SjqYu0am.js +78 -0
  17. package/dist/{index-D4Grk5x1.d.mts → index-BozA2pze.d.ts} +1 -1
  18. package/dist/index-Ckt12ON6.d.ts +75 -0
  19. package/dist/index-D0L_ydyW.d.ts +1396 -0
  20. package/dist/index-DVKeyWc5.d.ts +79 -0
  21. package/dist/index.d.ts +7 -0
  22. package/dist/index.js +11 -0
  23. package/dist/transformers/index.d.ts +2 -0
  24. package/dist/transformers/index.js +4 -0
  25. package/dist/{transformers-BTjuwbOV.mjs → transformers-CWrxLIkw.js} +2 -2
  26. package/dist/types/{index.d.mts → index.d.ts} +1 -1
  27. package/dist/types/index.js +1 -0
  28. package/dist/{useTheme-tY7MoBKr.mjs → useTheme-DCXkw_kv.js} +214 -204
  29. package/dist/utilities/{index.d.mts → index.d.ts} +2 -2
  30. package/dist/utilities/{index.mjs → index.js} +1 -1
  31. package/package.json +20 -35
  32. package/dist/components/index.d.mts +0 -5
  33. package/dist/components/index.mjs +0 -7
  34. package/dist/composables/index.d.mts +0 -5
  35. package/dist/composables/index.mjs +0 -7
  36. package/dist/composables-C6dl5kjP.mjs +0 -614
  37. package/dist/factories/index.d.mts +0 -3
  38. package/dist/factories/index.mjs +0 -4
  39. package/dist/factories-DOLmqhVS.mjs +0 -0
  40. package/dist/index-ChaaTPKp.d.mts +0 -421
  41. package/dist/index-Cya5Y9pB.d.mts +0 -412
  42. package/dist/index-DfahEz6s.d.mts +0 -18
  43. package/dist/index-jG0yrC1F.d.mts +0 -467
  44. package/dist/index-oCBJwhpG.d.mts +0 -43
  45. package/dist/index.d.mts +0 -9
  46. package/dist/index.mjs +0 -9
  47. package/dist/transformers/index.d.mts +0 -2
  48. package/dist/transformers/index.mjs +0 -4
  49. package/dist/types/index.mjs +0 -0
  50. /package/dist/{index-BA3ZFBnL.d.mts → index-LBy5OPMu.d.ts} +0 -0
  51. /package/dist/{index-CZRh0I2w.d.mts → index-tUyghL98.d.ts} +0 -0
  52. /package/dist/{utilities-lZSfrXgw.mjs → utilities-D9rWEgQK.js} +0 -0
@@ -0,0 +1,1270 @@
1
+ import { createContext, createPlugin, createTrinity, useContext } from "./factories-BEpawPUw.js";
2
+ import { createTokensContext, useHydration, useLogger, useRegistry, useSelection, useSingle, useTokens } from "./useTheme-DCXkw_kv.js";
3
+ import { isArray, isBoolean, isFunction, isObject } from "./utilities-D9rWEgQK.js";
4
+ import { IN_BROWSER, SUPPORTS_INTERSECTION_OBSERVER, SUPPORTS_MUTATION_OBSERVER, SUPPORTS_OBSERVER } from "./globals-DZvNEOB4.js";
5
+ import { toArray } from "./transformers-CWrxLIkw.js";
6
+ import { computed, getCurrentScope, isRef, onMounted, onScopeDispose, onUnmounted, readonly, ref, shallowRef, toRaw, toRef, toValue, unref, watch } from "vue";
7
+
8
+ //#region src/composables/useEventListener/index.ts
9
+ function useEventListener(target, event, listener, options) {
10
+ const cleanups = [];
11
+ function cleanup() {
12
+ for (const fn of cleanups) fn();
13
+ cleanups.length = 0;
14
+ }
15
+ function register(el, event$1, listener$1, options$1) {
16
+ el.addEventListener(event$1, listener$1, options$1);
17
+ return () => el.removeEventListener(event$1, listener$1, options$1);
18
+ }
19
+ const stopWatcher = watch(() => [
20
+ toValue(target),
21
+ toValue(event),
22
+ unref(listener),
23
+ toValue(options)
24
+ ], ([el, events, listeners, opts]) => {
25
+ cleanup();
26
+ if (!el) return;
27
+ const eventList = toArray(events);
28
+ const listenerList = toArray(listeners);
29
+ for (const event$1 of eventList) for (const listenerFn of listenerList) cleanups.push(register(el, event$1, listenerFn, opts));
30
+ }, {
31
+ immediate: true,
32
+ flush: "post"
33
+ });
34
+ function stop() {
35
+ stopWatcher();
36
+ cleanup();
37
+ }
38
+ onScopeDispose(stop, true);
39
+ return stop;
40
+ }
41
+ /**
42
+ * Convenience function for attaching event listeners to the window object.
43
+ * This function provides a simplified API by pre-binding the window target,
44
+ * making it easier to handle window-specific events with automatic cleanup.
45
+ *
46
+ * @param event Event name(s) to listen for from WindowEventMap.
47
+ * @param listener Event handler function(s) with proper window event typing.
48
+ * @param options Optional event listener configuration.
49
+ * @returns Function to manually remove all attached listeners.
50
+ */
51
+ function useWindowEventListener(event, listener, options) {
52
+ return useEventListener(window, event, listener, options);
53
+ }
54
+ /**
55
+ * Convenience function for attaching event listeners to the document object.
56
+ * This function provides a simplified API by pre-binding the document target,
57
+ * making it easier to handle document-specific events with automatic cleanup.
58
+ *
59
+ * @param event Event name(s) to listen for from DocumentEventMap.
60
+ * @param listener Event handler function(s) with proper document event typing.
61
+ * @param options Optional event listener configuration.
62
+ * @returns Function to manually remove all attached listeners.
63
+ */
64
+ function useDocumentEventListener(event, listener, options) {
65
+ return useEventListener(document, event, listener, options);
66
+ }
67
+
68
+ //#endregion
69
+ //#region src/composables/useGroup/index.ts
70
+ /**
71
+ * Creates a group selection context for managing collections of items where multiple selections can be made.
72
+ * This function extends the selection functionality with group selection capabilities.
73
+ *
74
+ * @param options Optional configuration for group selection behavior.
75
+ * @template Z The type of items managed by the group selection.
76
+ * @template E The type of the group selection context.
77
+ * @returns The group selection context object.
78
+ */
79
+ function useGroup(options) {
80
+ const registry = useSelection(options);
81
+ const selectedIndexes = computed(() => {
82
+ return new Set(Array.from(registry.selectedItems.value).map((item) => item?.index));
83
+ });
84
+ function select(ids) {
85
+ for (const id of toArray(ids)) registry.select(id);
86
+ }
87
+ function unselect(ids) {
88
+ for (const id of toArray(ids)) registry.unselect(id);
89
+ }
90
+ function toggle(ids) {
91
+ for (const id of toArray(ids)) registry.toggle(id);
92
+ }
93
+ return {
94
+ ...registry,
95
+ select,
96
+ unselect,
97
+ toggle,
98
+ selectedIndexes
99
+ };
100
+ }
101
+ /**
102
+ * Creates a group selection registry context with full injection/provision control.
103
+ * Returns the complete trinity for advanced usage scenarios.
104
+ *
105
+ * @param namespace The namespace for the group selection registry context
106
+ * @param options Optional configuration for group selection behavior.
107
+ * @template Z The structure of the registry group selection items.
108
+ * @template E The available methods for the group's context.
109
+ * @returns A tuple containing the inject function, provide function, and the group selection context.
110
+ */
111
+ function createGroupContext(namespace, options) {
112
+ const [useGroupContext, _provideGroupContext] = createContext(namespace);
113
+ const context = useGroup(options);
114
+ function provideGroupContext(_context = context, app) {
115
+ return _provideGroupContext(_context, app);
116
+ }
117
+ return createTrinity(useGroupContext, provideGroupContext, context);
118
+ }
119
+
120
+ //#endregion
121
+ //#region src/composables/useFeatures/index.ts
122
+ /**
123
+ *
124
+ * @param namespace The namespace for the feature context
125
+ * @param options Configure initial features to register
126
+ * @template Z The type of feature ticket
127
+ * @template E The type of feature context
128
+ * @returns A context trinity for the features context
129
+ *
130
+ * @see https://0.vuetifyjs.com/composables/plugins/create-features
131
+ */
132
+ function createFeatures(namespace = "v0:features", options = {}) {
133
+ const [useFeaturesContext, _provideFeaturesContext] = createContext(namespace);
134
+ const tokens = useTokens(options.features, { flat: true });
135
+ const registry = useGroup();
136
+ for (const [id, { value }] of tokens.entries()) register({
137
+ id,
138
+ value
139
+ });
140
+ function variation(id, fallback = null) {
141
+ const ticket = registry.get(id);
142
+ if (!ticket) return fallback;
143
+ return isObject(ticket.value) ? ticket.value.$variation ?? fallback : fallback;
144
+ }
145
+ function register(registration = {}) {
146
+ const item = {
147
+ value: false,
148
+ ...registration
149
+ };
150
+ const ticket = registry.register(item);
151
+ if (isBoolean(ticket.value) || isObject(ticket.value) && isBoolean(ticket.value.$value) && ticket.value.$value === true) registry.select(ticket.id);
152
+ return ticket;
153
+ }
154
+ const context = {
155
+ ...registry,
156
+ variation,
157
+ register
158
+ };
159
+ function provideFeaturesContext(_context = context, app) {
160
+ return _provideFeaturesContext(_context, app);
161
+ }
162
+ return createTrinity(useFeaturesContext, provideFeaturesContext, context);
163
+ }
164
+ /**
165
+ * Simple hook to access the theme context.
166
+ *
167
+ * @returns The features context containing current theme state and utilities.
168
+ *
169
+ * @see https://0.vuetifyjs.com/composables/plugins/create-features
170
+ */
171
+ function useFeatures() {
172
+ return useContext("v0:features");
173
+ }
174
+ /**
175
+ * Creates a Vue plugin for feature management with variation support.
176
+ *
177
+ * @param options Configuration for initial features to register.
178
+ * @template Z The type of feature ticket.
179
+ * @template E The type of feature context.
180
+ * @returns A Vue plugin object with install method.
181
+ *
182
+ * @see https://0.vuetifyjs.com/composables/plugins/create-features
183
+ */
184
+ function createFeaturesPlugin(options = {}) {
185
+ const [, provideFeaturesContext, context] = createFeatures("v0:features", options);
186
+ return createPlugin({
187
+ namespace: "v0:features",
188
+ provide: (app) => {
189
+ provideFeaturesContext(context, app);
190
+ }
191
+ });
192
+ }
193
+
194
+ //#endregion
195
+ //#region src/composables/useFilter/index.ts
196
+ function defaultFilter(query, item, keys, mode = "some") {
197
+ const queries = Array.isArray(query) ? query.map((q) => String(q).toLowerCase()) : [String(query).toLowerCase()];
198
+ function match(value, q) {
199
+ return String(value).toLowerCase().includes(q);
200
+ }
201
+ const stringValues = (typeof item === "object" && item !== null ? keys?.length ? keys.map((k) => item[k]) : Object.values(item) : [item]).map((v) => String(v).toLowerCase());
202
+ if (mode === "some") return stringValues.some((val) => match(val, queries[0]));
203
+ if (mode === "every") return stringValues.every((val) => match(val, queries[0]));
204
+ if (mode === "union") return queries.some((q) => stringValues.some((val) => match(val, q)));
205
+ if (mode === "intersection") return queries.every((q) => stringValues.some((val) => match(val, q)));
206
+ return false;
207
+ }
208
+ function toRefOrGetter(value) {
209
+ return isRef(value) ? value : typeof value === "function" ? toRef(value) : toRef(() => value);
210
+ }
211
+ /**
212
+ * Creates a reactive filter for arrays based on query matching with configurable search modes.
213
+ * Supports 'some' (any field matches), 'every' (all fields match), 'union' (any query matches),
214
+ * and 'intersection' (all queries match) filtering strategies.
215
+ *
216
+ * @param query Filter query to match against items.
217
+ * @param items Collection of items to filter.
218
+ * @param options Optional configuration for the filter behavior.
219
+ * @template Z The type of the items being filtered.
220
+ * @returns A computed reference to the filtered items based on the query and options.
221
+ */
222
+ function useFilter(query, items, options = {}) {
223
+ const { customFilter, keys, mode = "some" } = options;
224
+ const filterFunction = customFilter ?? ((q, i) => defaultFilter(q, i, keys, mode));
225
+ const itemsRef = isRef(items) ? items : toRef(() => items);
226
+ const queryRef = toRefOrGetter(query);
227
+ return { items: computed(() => {
228
+ const q = toValue(queryRef);
229
+ const queries = (Array.isArray(q) ? q : [q]).filter((q$1) => String(q$1).trim());
230
+ if (queries.length === 0) return itemsRef.value;
231
+ const queryParam = queries.length === 1 ? queries[0] : queries;
232
+ return itemsRef.value.filter((item) => filterFunction(queryParam, item));
233
+ }) };
234
+ }
235
+
236
+ //#endregion
237
+ //#region src/composables/useForm/index.ts
238
+ function useForm(options) {
239
+ const registry = useRegistry(options);
240
+ const validateOn = options?.validateOn || "submit";
241
+ function parse(value) {
242
+ return value.toLowerCase().split(/\s+/);
243
+ }
244
+ function validatesOn(event) {
245
+ return parse(validateOn).includes(event);
246
+ }
247
+ const isValidating = computed(() => {
248
+ for (const ticket of registry.collection.values()) if (ticket.isValidating.value) return true;
249
+ return false;
250
+ });
251
+ const isValid = computed(() => {
252
+ let hasFields = false;
253
+ for (const ticket of registry.values()) {
254
+ hasFields = true;
255
+ if (ticket.isValid.value === false) return false;
256
+ if (ticket.isValid.value === null) return null;
257
+ }
258
+ return hasFields ? true : null;
259
+ });
260
+ function reset() {
261
+ for (const ticket of registry.values()) ticket.reset();
262
+ }
263
+ async function submit() {
264
+ return validate(registry.keys());
265
+ }
266
+ async function validate(id) {
267
+ const validating = toArray(id);
268
+ if (validatesOn("submit")) return (await Promise.all(validating.map(async (id$1) => await registry.get(id$1)?.validate() ?? true))).every(Boolean);
269
+ return validating.map((id$1) => registry.get(id$1)).filter(Boolean).every((ticket) => ticket.isValid.value === true);
270
+ }
271
+ function register(registration) {
272
+ const model = shallowRef(registration.value == null ? "" : toValue(registration.value));
273
+ const rules = registration.rules || [];
274
+ const errors = shallowRef([]);
275
+ const isValidating$1 = shallowRef(false);
276
+ const initialValue = model.value;
277
+ const triggers = registration.validateOn || validateOn;
278
+ const isPristine = shallowRef(true);
279
+ const isValid$1 = shallowRef(null);
280
+ function _validatesOn(event) {
281
+ return parse(triggers).includes(event);
282
+ }
283
+ function _reset() {
284
+ model.value = initialValue;
285
+ errors.value = [];
286
+ isPristine.value = true;
287
+ isValid$1.value = null;
288
+ }
289
+ async function validate$1(silent = false) {
290
+ if (rules.length === 0) return true;
291
+ isValidating$1.value = true;
292
+ try {
293
+ const errorMessages = (await Promise.all(rules.map((rule) => rule(model.value)))).filter((result) => typeof result === "string");
294
+ if (!silent) {
295
+ errors.value = errorMessages;
296
+ isValid$1.value = errorMessages.length === 0;
297
+ isPristine.value = toValue(model) === initialValue;
298
+ }
299
+ return errorMessages.length === 0;
300
+ } finally {
301
+ isValidating$1.value = false;
302
+ }
303
+ }
304
+ const item = {
305
+ ...registration,
306
+ rules,
307
+ errors,
308
+ disabled: registration.disabled || false,
309
+ validateOn: triggers,
310
+ isValidating: isValidating$1,
311
+ isPristine,
312
+ isValid: isValid$1,
313
+ reset: _reset,
314
+ validate: validate$1
315
+ };
316
+ const ticket = registry.register(item);
317
+ Object.defineProperty(ticket, "value", {
318
+ get() {
319
+ return model.value;
320
+ },
321
+ set(val) {
322
+ model.value = val;
323
+ isPristine.value = val === initialValue;
324
+ isValid$1.value = null;
325
+ if (_validatesOn("change")) validate$1();
326
+ },
327
+ enumerable: true,
328
+ configurable: true
329
+ });
330
+ return ticket;
331
+ }
332
+ return {
333
+ ...registry,
334
+ register,
335
+ reset,
336
+ submit,
337
+ validateOn,
338
+ isValid,
339
+ isValidating
340
+ };
341
+ }
342
+
343
+ //#endregion
344
+ //#region src/composables/useIntersectionObserver/index.ts
345
+ /**
346
+ * Composable for observing element intersection with viewport or ancestor
347
+ *
348
+ * @param target - Element ref to observe
349
+ * @param callback - Callback fired on intersection change
350
+ * @param options - Observer options
351
+ * @returns Observer controls and intersection state
352
+ *
353
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver
354
+ */
355
+ function useIntersectionObserver(target, callback, options = {}) {
356
+ const { isHydrated } = useHydration();
357
+ const observer = shallowRef();
358
+ const isPaused = shallowRef(false);
359
+ const isIntersecting = shallowRef(false);
360
+ watch([isHydrated, target], ([hydrated, el]) => {
361
+ cleanup();
362
+ if (!hydrated || !SUPPORTS_INTERSECTION_OBSERVER || !el) return;
363
+ observer.value = new IntersectionObserver((entries) => {
364
+ const transformedEntries = entries.map((entry) => ({
365
+ boundingClientRect: entry.boundingClientRect,
366
+ intersectionRatio: entry.intersectionRatio,
367
+ intersectionRect: entry.intersectionRect,
368
+ isIntersecting: entry.isIntersecting,
369
+ rootBounds: entry.rootBounds,
370
+ target: entry.target,
371
+ time: entry.time
372
+ }));
373
+ const latestEntry = transformedEntries.at(-1);
374
+ if (latestEntry) isIntersecting.value = latestEntry.isIntersecting;
375
+ callback(transformedEntries);
376
+ }, {
377
+ root: options.root || null,
378
+ rootMargin: options.rootMargin || "0px",
379
+ threshold: options.threshold || 0
380
+ });
381
+ observer.value.observe(el);
382
+ if (options.immediate) {
383
+ const syntheticEntry = {
384
+ boundingClientRect: el.getBoundingClientRect(),
385
+ intersectionRatio: 0,
386
+ intersectionRect: new DOMRect(0, 0, 0, 0),
387
+ isIntersecting: false,
388
+ rootBounds: null,
389
+ target: el,
390
+ time: performance.now()
391
+ };
392
+ callback([syntheticEntry]);
393
+ }
394
+ });
395
+ function setup() {
396
+ if (!isHydrated.value || !SUPPORTS_INTERSECTION_OBSERVER || !target.value || isPaused.value) return;
397
+ observer.value = new IntersectionObserver((entries) => {
398
+ const transformedEntries = entries.map((entry) => ({
399
+ boundingClientRect: entry.boundingClientRect,
400
+ intersectionRatio: entry.intersectionRatio,
401
+ intersectionRect: entry.intersectionRect,
402
+ isIntersecting: entry.isIntersecting,
403
+ rootBounds: entry.rootBounds,
404
+ target: entry.target,
405
+ time: entry.time
406
+ }));
407
+ const latestEntry = transformedEntries.at(-1);
408
+ if (latestEntry) isIntersecting.value = latestEntry.isIntersecting;
409
+ callback(transformedEntries);
410
+ }, {
411
+ root: options.root || null,
412
+ rootMargin: options.rootMargin || "0px",
413
+ threshold: options.threshold || 0
414
+ });
415
+ observer.value.observe(target.value);
416
+ if (options.immediate) {
417
+ const syntheticEntry = {
418
+ boundingClientRect: target.value.getBoundingClientRect(),
419
+ intersectionRatio: 0,
420
+ intersectionRect: new DOMRect(0, 0, 0, 0),
421
+ isIntersecting: false,
422
+ rootBounds: null,
423
+ target: target.value,
424
+ time: performance.now()
425
+ };
426
+ callback([syntheticEntry]);
427
+ }
428
+ }
429
+ function cleanup() {
430
+ if (observer.value) {
431
+ observer.value.disconnect();
432
+ observer.value = void 0;
433
+ }
434
+ }
435
+ function pause() {
436
+ isPaused.value = true;
437
+ observer.value?.disconnect();
438
+ }
439
+ function resume() {
440
+ isPaused.value = false;
441
+ setup();
442
+ }
443
+ function stop() {
444
+ cleanup();
445
+ }
446
+ onUnmounted(stop);
447
+ return {
448
+ isIntersecting: readonly(isIntersecting),
449
+ isPaused: readonly(isPaused),
450
+ pause,
451
+ resume,
452
+ stop
453
+ };
454
+ }
455
+ /**
456
+ * Convenience composable for simple intersection detection
457
+ *
458
+ * @param target - Element ref to observe
459
+ * @param options - Observer options
460
+ * @returns Reactive intersection state
461
+ */
462
+ function useElementIntersection(target, options = {}) {
463
+ const isIntersecting = shallowRef(false);
464
+ const intersectionRatio = shallowRef(0);
465
+ useIntersectionObserver(target, (entries) => {
466
+ const entry = entries.at(-1);
467
+ if (entry) {
468
+ isIntersecting.value = entry.isIntersecting;
469
+ intersectionRatio.value = entry.intersectionRatio;
470
+ }
471
+ }, {
472
+ immediate: true,
473
+ ...options
474
+ });
475
+ return {
476
+ isIntersecting: readonly(isIntersecting),
477
+ intersectionRatio: readonly(intersectionRatio)
478
+ };
479
+ }
480
+
481
+ //#endregion
482
+ //#region src/composables/useKeydown/index.ts
483
+ /**
484
+ * Sets up global keyboard event listeners for specified key handlers with automatic cleanup.
485
+ * This composable automatically starts listening when mounted and cleans up when the scope
486
+ * is disposed, providing a clean way to handle global keyboard interactions.
487
+ *
488
+ * @param handlers A single handler or array of handlers to register for keydown events.
489
+ * @returns Object with methods to manually start and stop listening for keydown events.
490
+ */
491
+ function useKeydown(handlers) {
492
+ const keyHandlers = Array.isArray(handlers) ? handlers : [handlers];
493
+ function onKeydown(event) {
494
+ const handler = keyHandlers.find((h$1) => h$1.key === event.key);
495
+ if (handler) {
496
+ if (handler.preventDefault) event.preventDefault();
497
+ if (handler.stopPropagation) event.stopPropagation();
498
+ handler.handler(event);
499
+ }
500
+ }
501
+ function startListening() {
502
+ document.addEventListener("keydown", onKeydown);
503
+ }
504
+ function stopListening() {
505
+ document.removeEventListener("keydown", onKeydown);
506
+ }
507
+ if (getCurrentScope()) onMounted(startListening);
508
+ onScopeDispose(stopListening, true);
509
+ return {
510
+ startListening,
511
+ stopListening
512
+ };
513
+ }
514
+
515
+ //#endregion
516
+ //#region src/composables/useLocale/adapters/v0.ts
517
+ /**
518
+ * Vuetify0.x locale adapter implementation
519
+ *
520
+ * This adapter provides translation and number formatting
521
+ * capabilities using the Intl API and supports both
522
+ * numbered and named variables in translation strings.
523
+ */
524
+ var Vuetify0LocaleAdapter = class {
525
+ t(message, ...params) {
526
+ let resolvedMessage = message;
527
+ if (params.length > 0 && typeof params[0] === "object" && params[0] !== null && !Array.isArray(params[0])) {
528
+ const variables = params[0];
529
+ resolvedMessage = resolvedMessage.replace(/{([a-zA-Z][a-zA-Z0-9_]*)}/g, (match, name) => {
530
+ return variables[name] === void 0 ? match : String(variables[name]);
531
+ });
532
+ params = params.slice(1);
533
+ }
534
+ resolvedMessage = resolvedMessage.replace(/\{(\d+)\}/g, (match, index) => {
535
+ const idx = Number.parseInt(index, 10);
536
+ if (params[idx] !== void 0) return String(params[idx]);
537
+ return match;
538
+ });
539
+ return resolvedMessage;
540
+ }
541
+ n(value, locale, ...params) {
542
+ if (!IN_BROWSER || !locale) return value.toString();
543
+ const options = params[0];
544
+ return new Intl.NumberFormat(String(locale), options).format(value);
545
+ }
546
+ };
547
+
548
+ //#endregion
549
+ //#region src/composables/useLocale/index.ts
550
+ /**
551
+ * Creates a locale registry for managing internationalization with translations and number formatting.
552
+ * Supports message resolution with token references and locale-specific number formatting.
553
+ *
554
+ * @param namespace The namespace for the locale context.
555
+ * @param options Configuration including adapter and messages.
556
+ * @template Z The type of the locale context.
557
+ * @template E The type of the locale items managed by the registry.
558
+ * @returns An array containing the inject function, provide function, and the locale context.
559
+ */
560
+ function createLocale(namespace = "v0:locale", options = {}) {
561
+ const { adapter = new Vuetify0LocaleAdapter(), messages = {} } = options;
562
+ const [useLocaleContext, _provideLocaleContext] = createContext(namespace);
563
+ const registry = useSingle();
564
+ for (const id in messages) {
565
+ registry.register({
566
+ value: messages[id],
567
+ id
568
+ });
569
+ if (id === options.default && !registry.selectedId.value) registry.select(id);
570
+ }
571
+ function t(key, ...params) {
572
+ const locale = registry.selectedId.value;
573
+ if (!locale) return key;
574
+ const message = messages[locale]?.[key];
575
+ const template = typeof message === "string" ? resolve(locale, message) : key;
576
+ return adapter.t(template, ...params);
577
+ }
578
+ function n(value, ...params) {
579
+ return adapter.n(value, registry.selectedId.value, ...params);
580
+ }
581
+ function resolve(locale, str) {
582
+ return str.replace(/{([a-zA-Z0-9.-_]+)}/g, (match, linkedKey) => {
583
+ const [linkedLocale, ...rest] = linkedKey.split(".");
584
+ const keyPath = rest.join(".");
585
+ const targetLocale = messages[linkedLocale] ? linkedLocale : locale;
586
+ const targetKey = messages[linkedLocale] ? keyPath : linkedKey;
587
+ const resolved = messages[targetLocale]?.[targetKey];
588
+ return typeof resolved === "string" ? resolve(targetLocale, resolved) : match;
589
+ });
590
+ }
591
+ const context = {
592
+ ...registry,
593
+ t,
594
+ n
595
+ };
596
+ function provideLocaleContext(_context = context, app) {
597
+ return _provideLocaleContext(_context, app);
598
+ }
599
+ return createTrinity(useLocaleContext, provideLocaleContext, context);
600
+ }
601
+ /**
602
+ * Simple hook to access the locale context.
603
+ *
604
+ * @returns The locale context containing translation and formatting functions.
605
+ */
606
+ function useLocale() {
607
+ return useContext("v0:locale");
608
+ }
609
+ /**
610
+ * Creates a Vue plugin for internationalization with locale management and translation support.
611
+ * Integrates with token system for message resolution and provides app-wide locale context.
612
+ *
613
+ * @param options Configuration for adapter, default locale, and messages.
614
+ * @template Z The type of the locale context.
615
+ * @template E The type of the locale items managed by the registry.
616
+ * @template R The type of the token context.
617
+ * @template O The type of the token items managed by the registry.
618
+ * @returns Vue install function for the plugin
619
+ */
620
+ function createLocalePlugin(options = {}) {
621
+ const { adapter = new Vuetify0LocaleAdapter(), messages = {} } = options;
622
+ const [, provideLocaleTokenContext, tokensContext] = createTokensContext("v0:locale:tokens", messages);
623
+ const [, provideLocaleContext, localeContext] = createLocale("v0:locale", {
624
+ adapter,
625
+ messages
626
+ });
627
+ return createPlugin({
628
+ namespace: "v0:locale",
629
+ provide: (app) => {
630
+ provideLocaleContext(localeContext, app);
631
+ provideLocaleTokenContext(tokensContext, app);
632
+ }
633
+ });
634
+ }
635
+
636
+ //#endregion
637
+ //#region src/composables/useMutationObserver/index.ts
638
+ /**
639
+ * Composable for observing DOM mutations
640
+ *
641
+ * @param target - Element ref to observe
642
+ * @param callback - Callback fired on mutation
643
+ * @param options - Observer options
644
+ * @returns Observer controls
645
+ *
646
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
647
+ */
648
+ function useMutationObserver(target, callback, options = {}) {
649
+ const { isHydrated } = useHydration();
650
+ const observer = shallowRef();
651
+ const isPaused = shallowRef(false);
652
+ const observerOptions = {
653
+ childList: options.childList ?? true,
654
+ attributes: options.attributes ?? false,
655
+ characterData: options.characterData ?? false,
656
+ subtree: options.subtree ?? false,
657
+ attributeOldValue: options.attributeOldValue ?? false,
658
+ characterDataOldValue: options.characterDataOldValue ?? false,
659
+ attributeFilter: options.attributeFilter
660
+ };
661
+ watch([isHydrated, target], ([hydrated, el]) => {
662
+ cleanup();
663
+ if (!hydrated || !SUPPORTS_MUTATION_OBSERVER || !el) return;
664
+ observer.value = new MutationObserver((mutations) => {
665
+ const transformedEntries = mutations.map((mutation) => ({
666
+ type: mutation.type,
667
+ target: mutation.target,
668
+ addedNodes: mutation.addedNodes,
669
+ removedNodes: mutation.removedNodes,
670
+ previousSibling: mutation.previousSibling,
671
+ nextSibling: mutation.nextSibling,
672
+ attributeName: mutation.attributeName,
673
+ attributeNamespace: mutation.attributeNamespace,
674
+ oldValue: mutation.oldValue
675
+ }));
676
+ callback(transformedEntries);
677
+ });
678
+ observer.value.observe(el, observerOptions);
679
+ if (options.immediate) {
680
+ const emptyNodeList = {
681
+ length: 0,
682
+ item: () => null,
683
+ forEach: () => {},
684
+ *[Symbol.iterator]() {}
685
+ };
686
+ callback([{
687
+ type: "childList",
688
+ target: el,
689
+ addedNodes: emptyNodeList,
690
+ removedNodes: emptyNodeList,
691
+ previousSibling: null,
692
+ nextSibling: null,
693
+ attributeName: null,
694
+ attributeNamespace: null,
695
+ oldValue: null
696
+ }]);
697
+ }
698
+ }, { immediate: true });
699
+ function setup() {
700
+ if (!isHydrated.value || !SUPPORTS_MUTATION_OBSERVER || !target.value || isPaused.value) return;
701
+ observer.value = new MutationObserver((mutations) => {
702
+ const transformedEntries = mutations.map((mutation) => ({
703
+ type: mutation.type,
704
+ target: mutation.target,
705
+ addedNodes: mutation.addedNodes,
706
+ removedNodes: mutation.removedNodes,
707
+ previousSibling: mutation.previousSibling,
708
+ nextSibling: mutation.nextSibling,
709
+ attributeName: mutation.attributeName,
710
+ attributeNamespace: mutation.attributeNamespace,
711
+ oldValue: mutation.oldValue
712
+ }));
713
+ callback(transformedEntries);
714
+ });
715
+ observer.value.observe(target.value, observerOptions);
716
+ if (options.immediate) {
717
+ const emptyNodeList = {
718
+ length: 0,
719
+ item: () => null,
720
+ forEach: () => {},
721
+ *[Symbol.iterator]() {}
722
+ };
723
+ const syntheticEntry = {
724
+ type: "childList",
725
+ target: target.value,
726
+ addedNodes: emptyNodeList,
727
+ removedNodes: emptyNodeList,
728
+ previousSibling: null,
729
+ nextSibling: null,
730
+ attributeName: null,
731
+ attributeNamespace: null,
732
+ oldValue: null
733
+ };
734
+ callback([syntheticEntry]);
735
+ }
736
+ }
737
+ function cleanup() {
738
+ if (observer.value) {
739
+ observer.value.disconnect();
740
+ observer.value = void 0;
741
+ }
742
+ }
743
+ function pause() {
744
+ isPaused.value = true;
745
+ observer.value?.disconnect();
746
+ }
747
+ function resume() {
748
+ isPaused.value = false;
749
+ setup();
750
+ }
751
+ function stop() {
752
+ cleanup();
753
+ }
754
+ onUnmounted(stop);
755
+ return {
756
+ isPaused: readonly(isPaused),
757
+ pause,
758
+ resume,
759
+ stop
760
+ };
761
+ }
762
+
763
+ //#endregion
764
+ //#region src/composables/usePermissions/adapters/adapter.ts
765
+ var PermissionAdapter = class {};
766
+
767
+ //#endregion
768
+ //#region src/composables/usePermissions/adapters/v0.ts
769
+ var Vuetify0PermissionAdapter = class extends PermissionAdapter {
770
+ constructor() {
771
+ super();
772
+ }
773
+ can(role, action, subject, context, permissions) {
774
+ const access = `${role}.${action}.${subject}`;
775
+ const ticket = permissions.get(access);
776
+ if (!ticket || !ticket.value) return false;
777
+ return isFunction(ticket.value) ? ticket.value(context) : ticket.value;
778
+ }
779
+ };
780
+
781
+ //#endregion
782
+ //#region src/composables/usePermissions/index.ts
783
+ /**
784
+ *
785
+ * @param namespace The namespace for the permissions context
786
+ * @param options Configure initial permissions and adapter
787
+ * @template Z The type of permission ticket
788
+ * @template E The type of permission context
789
+ * @returns A context trinity for the permissions context
790
+ *
791
+ * @see https://0.vuetifyjs.com/composables/plugins/create-permissions
792
+ */
793
+ function createPermissions(namespace = "v0:permissions", options = {}) {
794
+ const { adapter = new Vuetify0PermissionAdapter(), permissions = {} } = options;
795
+ const [usePermissionsContext, _providePermissionsContext] = createContext(namespace);
796
+ const record = {};
797
+ for (const role in permissions) {
798
+ if (!record[role]) record[role] = {};
799
+ for (const [actions, subjects, condition = true] of permissions[role]) for (const action of toArray(actions)) for (const subject of toArray(subjects)) {
800
+ if (!record[role][action]) record[role][action] = {};
801
+ record[role][action][subject] = condition;
802
+ }
803
+ }
804
+ const tokens = useTokens(record);
805
+ function can(id, action, subject, context$1 = {}) {
806
+ return adapter.can(id, action, subject, context$1, tokens);
807
+ }
808
+ const context = {
809
+ ...tokens,
810
+ can
811
+ };
812
+ function providePermissionsContext(_context = context, app) {
813
+ return _providePermissionsContext(_context, app);
814
+ }
815
+ return createTrinity(usePermissionsContext, providePermissionsContext, context);
816
+ }
817
+ /**
818
+ * Simple hook to access the permissions context
819
+ *
820
+ * @returns The permissions context
821
+ * @template Z The type of permission ticket
822
+ *
823
+ * @see https://0.vuetifyjs.com/composables/plugins/use-permissions
824
+ */
825
+ function usePermissions() {
826
+ return useContext("v0:permissions");
827
+ }
828
+ /**
829
+ * Factory function to create a permissions plugin
830
+ *
831
+ * @param options Configuration options for the permissions plugin
832
+ * @template Z The type of permission ticket
833
+ * @template E The type of permission context
834
+ * @returns A Vue plugin object for permissions management
835
+ *
836
+ * @see https://0.vuetifyjs.com/composables/plugins/use-permissions
837
+ */
838
+ function createPermissionsPlugin(options = {}) {
839
+ const [, providePermissionContext, context] = createPermissions("v0:permissions", options);
840
+ return createPlugin({
841
+ namespace: "v0:permissions",
842
+ provide: (app) => {
843
+ providePermissionContext(context, app);
844
+ }
845
+ });
846
+ }
847
+
848
+ //#endregion
849
+ //#region src/composables/useProxyModel/index.ts
850
+ /**
851
+ * Creates a proxy model for two-way binding with a selection context.
852
+ *
853
+ * @param registry SelectionContext | GroupContext | SingleContext | StepContext
854
+ * @template Z The type of items managed by the selection.
855
+ * @template E The type of the selection context.
856
+ * @returns The proxy model for two-way binding with the selection context.
857
+ */
858
+ function useProxyModel(registry, initial, options, _transformIn, _transformOut) {
859
+ const logger = useLogger();
860
+ const internal = (options?.deep ? ref : shallowRef)(initial ? toArray(initial) : []);
861
+ const isModelArray = isArray(initial);
862
+ function transformIn(val) {
863
+ if (isFunction(_transformIn)) return _transformIn(val);
864
+ return toArray(val);
865
+ }
866
+ function transformOut(val) {
867
+ if (isFunction(_transformOut)) return _transformOut(val);
868
+ return isModelArray ? val : val[0];
869
+ }
870
+ const model = computed({
871
+ get() {
872
+ return transformOut(internal.value);
873
+ },
874
+ set(val) {
875
+ internal.value = transformIn(val);
876
+ }
877
+ });
878
+ const watcher = watch(registry.selectedIds, (val, oldVal) => {
879
+ if (toRaw(val).symmetricDifference(toRaw(oldVal)).size === 0) return;
880
+ if (val.size === 0) {
881
+ model.value = [];
882
+ return;
883
+ }
884
+ model.value = Array.from(registry.selectedValues.value);
885
+ });
886
+ watch(model, (val) => {
887
+ const currentIds = new Set(toValue(registry.selectedIds));
888
+ const targetIds = /* @__PURE__ */ new Set();
889
+ for (const value of toArray(val)) {
890
+ const ids = registry.browse(value);
891
+ if (isArray(ids)) for (const single of ids) targetIds.add(single);
892
+ else if (ids) targetIds.add(ids);
893
+ else logger.warn("Unable to find id for value", value);
894
+ }
895
+ watcher.pause();
896
+ if (isModelArray) {
897
+ for (const id of currentIds.difference(targetIds)) registry.selectedIds.delete(id);
898
+ for (const id of targetIds.difference(currentIds)) registry.selectedIds.add(id);
899
+ } else {
900
+ const next = targetIds.values().next().value;
901
+ const last = currentIds.values().next().value;
902
+ registry.selectedIds.delete(last);
903
+ registry.selectedIds.add(next);
904
+ }
905
+ watcher.resume();
906
+ });
907
+ return model;
908
+ }
909
+
910
+ //#endregion
911
+ //#region src/composables/useResizeObserver/index.ts
912
+ /**
913
+ * Composable for observing element resize events
914
+ *
915
+ * @param target - Element ref to observe
916
+ * @param callback - Callback fired on resize
917
+ * @param options - Observer options
918
+ * @returns Observer controls
919
+ *
920
+ * @see https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver
921
+ */
922
+ function useResizeObserver(target, callback, options = {}) {
923
+ const { isHydrated } = useHydration();
924
+ const observer = shallowRef();
925
+ const isPaused = shallowRef(false);
926
+ watch([isHydrated, target], ([hydrated, el]) => {
927
+ cleanup();
928
+ if (!hydrated || !SUPPORTS_OBSERVER || !el) return;
929
+ observer.value = new ResizeObserver((entries) => {
930
+ const transformedEntries = entries.map((entry) => ({
931
+ contentRect: {
932
+ width: entry.contentRect.width,
933
+ height: entry.contentRect.height,
934
+ top: entry.contentRect.top,
935
+ left: entry.contentRect.left
936
+ },
937
+ target: entry.target
938
+ }));
939
+ callback(transformedEntries);
940
+ });
941
+ observer.value.observe(el, { box: options.box || "content-box" });
942
+ if (options.immediate) {
943
+ const rect = el.getBoundingClientRect();
944
+ callback([{
945
+ contentRect: {
946
+ width: rect.width,
947
+ height: rect.height,
948
+ top: rect.top,
949
+ left: rect.left
950
+ },
951
+ target: el
952
+ }]);
953
+ }
954
+ });
955
+ function setup() {
956
+ if (!isHydrated.value || !SUPPORTS_OBSERVER || !target.value || isPaused.value) return;
957
+ observer.value = new ResizeObserver((entries) => {
958
+ const transformedEntries = entries.map((entry) => ({
959
+ contentRect: {
960
+ width: entry.contentRect.width,
961
+ height: entry.contentRect.height,
962
+ top: entry.contentRect.top,
963
+ left: entry.contentRect.left
964
+ },
965
+ target: entry.target
966
+ }));
967
+ callback(transformedEntries);
968
+ });
969
+ observer.value.observe(target.value, { box: options.box || "content-box" });
970
+ if (options.immediate) {
971
+ const rect = target.value.getBoundingClientRect();
972
+ callback([{
973
+ contentRect: {
974
+ width: rect.width,
975
+ height: rect.height,
976
+ top: rect.top,
977
+ left: rect.left
978
+ },
979
+ target: target.value
980
+ }]);
981
+ }
982
+ }
983
+ function cleanup() {
984
+ if (observer.value) {
985
+ observer.value.disconnect();
986
+ observer.value = void 0;
987
+ }
988
+ }
989
+ function pause() {
990
+ isPaused.value = true;
991
+ observer.value?.disconnect();
992
+ }
993
+ function resume() {
994
+ isPaused.value = false;
995
+ setup();
996
+ }
997
+ function stop() {
998
+ cleanup();
999
+ }
1000
+ onUnmounted(stop);
1001
+ return {
1002
+ isPaused: readonly(isPaused),
1003
+ pause,
1004
+ resume,
1005
+ stop
1006
+ };
1007
+ }
1008
+ /**
1009
+ * Convenience composable for tracking element dimensions
1010
+ *
1011
+ * @param target - Element ref to observe
1012
+ * @returns Reactive width and height
1013
+ */
1014
+ function useElementSize(target) {
1015
+ const width = shallowRef(0);
1016
+ const height = shallowRef(0);
1017
+ useResizeObserver(target, (entries) => {
1018
+ const entry = entries[0];
1019
+ if (entry) {
1020
+ width.value = entry.contentRect.width;
1021
+ height.value = entry.contentRect.height;
1022
+ }
1023
+ }, { immediate: true });
1024
+ return {
1025
+ width,
1026
+ height
1027
+ };
1028
+ }
1029
+
1030
+ //#endregion
1031
+ //#region src/composables/useStep/index.ts
1032
+ /**
1033
+ * Creates a step selection context for managing collections where users can navigate through items sequentially.
1034
+ * This function extends the single selection functionality with stepping navigation.
1035
+ *
1036
+ * @param options Optional configuration for step behavior.
1037
+ * @template Z The type of items managed by the step selection.
1038
+ * @template E The type of the step selection context.
1039
+ * @returns The step selection context object.
1040
+ */
1041
+ function useStep(options) {
1042
+ const registry = useSingle(options);
1043
+ function first() {
1044
+ if (registry.size === 0) return;
1045
+ registry.selectedIds.clear();
1046
+ registry.select(registry.lookup(0));
1047
+ }
1048
+ function last() {
1049
+ const size = registry.size;
1050
+ if (size === 0) return;
1051
+ registry.selectedIds.clear();
1052
+ registry.select(registry.lookup(size - 1));
1053
+ }
1054
+ function next() {
1055
+ step(1);
1056
+ }
1057
+ function prev() {
1058
+ step(-1);
1059
+ }
1060
+ function wrapped(length, index) {
1061
+ return (index + length) % length;
1062
+ }
1063
+ function step(count = 1) {
1064
+ const length = registry.size;
1065
+ if (!length) return;
1066
+ const direction = Math.sign(count || 1);
1067
+ let hops = 0;
1068
+ let index = wrapped(length, registry.selectedIndex.value + count);
1069
+ let id = registry.lookup(index);
1070
+ while (id !== void 0 && registry.get(id)?.disabled && hops < length) {
1071
+ index = wrapped(length, index + direction);
1072
+ id = registry.lookup(index);
1073
+ hops++;
1074
+ }
1075
+ if (id === void 0 || hops === length) return;
1076
+ registry.selectedIds.clear();
1077
+ registry.select(id);
1078
+ }
1079
+ return {
1080
+ ...registry,
1081
+ first,
1082
+ last,
1083
+ next,
1084
+ prev,
1085
+ step
1086
+ };
1087
+ }
1088
+ /**
1089
+ * Creates a step selection registry context with full injection/provision control.
1090
+ * Returns the complete trinity for advanced usage scenarios.
1091
+ *
1092
+ * @param namespace The namespace for the step selection registry context
1093
+ * @param options Optional configuration for step selection behavior.
1094
+ * @template Z The structure of the registry step selection items.
1095
+ * @template E The available methods for the step's context.
1096
+ * @returns A tuple containing the inject function, provide function, and the step selection context.
1097
+ */
1098
+ function createStepContext(namespace, options) {
1099
+ const [useStepContext, _provideStepContext] = createContext(namespace);
1100
+ const context = useStep(options);
1101
+ function provideStepContext(_context = context, app) {
1102
+ return _provideStepContext(_context, app);
1103
+ }
1104
+ return createTrinity(useStepContext, provideStepContext, context);
1105
+ }
1106
+
1107
+ //#endregion
1108
+ //#region src/composables/useStorage/adapters/memory.ts
1109
+ /**
1110
+ * In-memory storage adapter that implements the StorageAdapter interface.
1111
+ * This adapter provides temporary storage that persists only for the current
1112
+ * session and is useful for testing or when persistent storage is not available.
1113
+ */
1114
+ var MemoryAdapter = class {
1115
+ store = /* @__PURE__ */ new Map();
1116
+ get length() {
1117
+ return this.store.size;
1118
+ }
1119
+ getItem(key) {
1120
+ return this.store.get(key) ?? null;
1121
+ }
1122
+ setItem(key, value) {
1123
+ this.store.set(key, value);
1124
+ }
1125
+ removeItem(key) {
1126
+ this.store.delete(key);
1127
+ }
1128
+ key(index) {
1129
+ return String(Array.from(this.store.keys())[index] ?? "");
1130
+ }
1131
+ };
1132
+
1133
+ //#endregion
1134
+ //#region src/composables/useStorage/index.ts
1135
+ const [useStorageContext, provideStorageContext] = createContext("v0:storage");
1136
+ /**
1137
+ * Creates a reactive storage system with automatic persistence and cross-adapter support.
1138
+ * This function provides a consistent interface for storing and retrieving reactive values
1139
+ * that automatically sync with the underlying storage adapter (localStorage, memory, etc.).
1140
+ *
1141
+ * @param options Optional configuration for storage adapter, prefix, and serialization.
1142
+ * @template E The type of the storage context.
1143
+ * @returns A storage context object with get, set, remove, and clear methods.
1144
+ */
1145
+ function createStorage(options = {}) {
1146
+ const { adapter = IN_BROWSER ? window.localStorage : new MemoryAdapter(), prefix = "v0:", serializer = {
1147
+ read: JSON.parse,
1148
+ write: JSON.stringify
1149
+ } } = options;
1150
+ const cache = /* @__PURE__ */ new Map();
1151
+ function get(key, defaultValue) {
1152
+ const prefixedKey = `${prefix}${key}`;
1153
+ if (cache.has(prefixedKey)) return cache.get(prefixedKey);
1154
+ const storedValue = adapter?.getItem(prefixedKey);
1155
+ let initialValue = defaultValue;
1156
+ if (storedValue) try {
1157
+ initialValue = serializer.read(storedValue);
1158
+ } catch (error) {
1159
+ console.error(`[v0:storage] Failed to parse stored value for key "${prefixedKey}":`, error);
1160
+ }
1161
+ const valueRef = ref(initialValue);
1162
+ watch(valueRef, (newValue) => {
1163
+ if (newValue === void 0 || newValue === null) adapter?.removeItem(prefixedKey);
1164
+ else adapter?.setItem(prefixedKey, serializer.write(newValue));
1165
+ }, { deep: true });
1166
+ cache.set(prefixedKey, valueRef);
1167
+ return valueRef;
1168
+ }
1169
+ function set(key, value) {
1170
+ const valueRef = get(key);
1171
+ valueRef.value = value;
1172
+ }
1173
+ function remove(key) {
1174
+ const prefixedKey = `${prefix}${key}`;
1175
+ adapter?.removeItem(prefixedKey);
1176
+ cache.delete(prefixedKey);
1177
+ }
1178
+ function clear() {
1179
+ for (const key of cache.keys()) adapter?.removeItem(key);
1180
+ cache.clear();
1181
+ }
1182
+ return {
1183
+ get,
1184
+ set,
1185
+ remove,
1186
+ clear
1187
+ };
1188
+ }
1189
+ /**
1190
+ * Simple hook to access the storage context.
1191
+ *
1192
+ * @returns The storage context containing reactive storage methods.
1193
+ */
1194
+ function useStorage() {
1195
+ return useStorageContext();
1196
+ }
1197
+ /**
1198
+ * Creates a Vue plugin for reactive storage capabilities with automatic persistence.
1199
+ * Provides app-wide access to reactive storage that syncs with the configured adapter.
1200
+ *
1201
+ * @param options Optional configuration for the storage system.
1202
+ * @returns A Vue plugin object with install method.
1203
+ */
1204
+ function createStoragePlugin(options = {}) {
1205
+ const context = createStorage(options);
1206
+ return createPlugin({
1207
+ namespace: "v0:storage",
1208
+ provide: (app) => {
1209
+ provideStorageContext(context, app);
1210
+ }
1211
+ });
1212
+ }
1213
+
1214
+ //#endregion
1215
+ //#region src/composables/useTimeline/index.ts
1216
+ /**
1217
+ * Creates a registry with timeline capabilities (undo/redo)
1218
+ *
1219
+ * @param _options Optional configuration for timeline
1220
+ * @template Z The type of ticket to be stored in the timeline
1221
+ * @template E The type of the timeline context
1222
+ * @returns The timeline context object
1223
+ *
1224
+ * @see https://0.vuetifyjs.com/composables/registration/use-timeline
1225
+ */
1226
+ function useTimeline(_options = {}) {
1227
+ const { size = 10,...options } = _options;
1228
+ const registry = useRegistry(options);
1229
+ const undoTimeline = [];
1230
+ const redoTimeline = [];
1231
+ function register(item) {
1232
+ if (registry.size < size) return registry.register({ ...item });
1233
+ const id = registry.lookup(0);
1234
+ const removing = registry.get(id);
1235
+ if (redoTimeline.length === size) redoTimeline.shift();
1236
+ redoTimeline.push(removing);
1237
+ registry.unregister(id);
1238
+ const ticket = registry.register({ ...item });
1239
+ registry.reindex();
1240
+ return ticket;
1241
+ }
1242
+ function redo() {
1243
+ if (undoTimeline.length === 0) return;
1244
+ registry.register(undoTimeline.pop());
1245
+ registry.reindex();
1246
+ }
1247
+ function undo() {
1248
+ const id = registry.lookup(registry.size - 1);
1249
+ if (!id) return;
1250
+ undoTimeline.push(registry.get(id));
1251
+ registry.unregister(id);
1252
+ restore();
1253
+ }
1254
+ function restore() {
1255
+ const value = redoTimeline.pop();
1256
+ const restored = value ? [value, ...registry.values()] : [...registry.values()];
1257
+ registry.clear();
1258
+ registry.onboard(restored);
1259
+ registry.reindex();
1260
+ }
1261
+ return {
1262
+ ...registry,
1263
+ register,
1264
+ undo,
1265
+ redo
1266
+ };
1267
+ }
1268
+
1269
+ //#endregion
1270
+ export { createFeatures, createFeaturesPlugin, createGroupContext, createLocale, createLocalePlugin, createPermissions, createPermissionsPlugin, createStepContext, createStorage, createStoragePlugin, provideStorageContext, useDocumentEventListener, useElementIntersection, useElementSize, useEventListener, useFeatures, useFilter, useForm, useGroup, useIntersectionObserver, useKeydown, useLocale, useMutationObserver, usePermissions, useProxyModel, useResizeObserver, useStep, useStorage, useStorageContext, useTimeline, useWindowEventListener };