@hybridly/vue 0.3.1 → 0.4.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.
package/dist/index.cjs CHANGED
@@ -127,7 +127,9 @@ const wrapper = vue.defineComponent({
127
127
  actual?.();
128
128
  vue.nextTick(() => {
129
129
  utils.debug.adapter("vue:render:view", "Calling mounted callbacks.");
130
- onMountedCallbacks.pop()?.();
130
+ while (onMountedCallbacks.length) {
131
+ onMountedCallbacks.shift()?.();
132
+ }
131
133
  });
132
134
  };
133
135
  return vue.h(state.view.value, {
@@ -280,17 +282,15 @@ async function initializeHybridly(options = {}) {
280
282
  if (!element) {
281
283
  throw new Error("Could not find an HTML element to initialize Vue on.");
282
284
  }
283
- if (!payload) {
284
- throw new Error("No payload. Are you using `@hybridly` or the `payload` option?");
285
- }
286
285
  state.setContext(await core.createRouter({
287
286
  axios: resolved.axios,
288
287
  plugins: resolved.plugins,
289
288
  serializer: resolved.serializer,
290
289
  responseErrorModals: resolved.responseErrorModals ?? process.env.NODE_ENV === "development",
290
+ routing: resolved.routing,
291
291
  adapter: {
292
292
  resolveComponent: resolve,
293
- onWaitingForMount: (callback) => {
293
+ executeOnMounted: (callback) => {
294
294
  onMountedCallbacks.push(callback);
295
295
  },
296
296
  onDialogClose: async () => {
@@ -346,21 +346,20 @@ function prepare(options) {
346
346
  const id = options.id ?? "root";
347
347
  const element = document?.getElementById(id) ?? void 0;
348
348
  utils.debug.adapter("vue", `Element "${id}" is:`, element);
349
- const payload = options.payload ?? element?.dataset.payload ? JSON.parse(element.dataset.payload) : void 0;
349
+ const payload = element?.dataset.payload ? JSON.parse(element.dataset.payload) : void 0;
350
+ if (!payload) {
351
+ throw new Error("No payload found. Are you using the `@hybridly` directive?");
352
+ }
350
353
  if (options.cleanup !== false) {
351
354
  delete element.dataset.payload;
352
355
  }
353
356
  utils.debug.adapter("vue", "Resolved:", { isServer, element, payload });
354
357
  const resolve = async (name) => {
355
358
  utils.debug.adapter("vue", "Resolving component", name);
356
- if (options.resolve) {
357
- const component = await options.resolve?.(name);
358
- return component.default ?? component;
359
- }
360
- if (options.components) {
361
- return await resolvePageComponent(name, options);
359
+ if (!options.imported) {
360
+ throw new Error("No component loaded. Did you initialize Hybridly? Does `php artisan hybridly:config` return an error?");
362
361
  }
363
- throw new Error("Either `initializeHybridly#resolve` or `initializeHybridly#pages` should be defined.");
362
+ return await resolveViewComponent(name, options);
364
363
  };
365
364
  if (options.progress !== false) {
366
365
  options.plugins = [
@@ -375,21 +374,13 @@ function prepare(options) {
375
374
  resolve
376
375
  };
377
376
  }
378
- async function resolvePageComponent(name, options) {
379
- const components = options.components;
380
- if (name.includes(":")) {
381
- if (options.domains === false) {
382
- utils.showDomainsDisabledErrorModal(name);
383
- console.warn(`${name} is a domain-based component, but domains are disabled.`);
384
- return;
385
- }
386
- const [domain, page] = name.split(":");
387
- name = `${options.domains}.${domain}.${options.pages}.${page}`;
388
- }
389
- const path = Object.keys(components).sort((a, b) => a.length - b.length).find((path2) => path2.endsWith(`${name.replaceAll(".", "/")}.vue`));
390
- if (!path) {
377
+ async function resolveViewComponent(name, options) {
378
+ const components = options.imported;
379
+ const result = options.components.views.find((view) => name === view.identifier);
380
+ const path = Object.keys(components).sort((a, b) => a.length - b.length).find((path2) => result ? path2.endsWith(result?.path) : false);
381
+ if (!result || !path) {
382
+ console.warn(`Page component [${name}] not found. Available components: `, options.components.views.map(({ identifier }) => identifier));
391
383
  utils.showPageComponentErrorModal(name);
392
- console.warn(`Page component "${name}" could not be found. Available pages:`, Object.keys(components));
393
384
  return;
394
385
  }
395
386
  let component = typeof components[path] === "function" ? await components[path]() : components[path];
@@ -402,6 +393,7 @@ const RouterLink = vue.defineComponent({
402
393
  setup(_, { slots, attrs }) {
403
394
  return (props) => {
404
395
  let data = props.data ?? {};
396
+ const preloads = props.preload ?? false;
405
397
  const url = core.makeUrl(props.href ?? "");
406
398
  const method = props.method?.toUpperCase() ?? "GET";
407
399
  const as = typeof props.as === "object" ? props.as : props.as?.toLowerCase() ?? "a";
@@ -424,6 +416,24 @@ Please specify a more appropriate element using the "as" attribute. For example:
424
416
  ...attrs,
425
417
  ...as === "a" ? { href: url } : {},
426
418
  ...props.disabled ? { disabled: props.disabled } : {},
419
+ onMouseenter: () => {
420
+ if (!preloads) {
421
+ return;
422
+ }
423
+ if (props.external) {
424
+ return;
425
+ }
426
+ if (props.disabled) {
427
+ return;
428
+ }
429
+ if (method !== "GET") {
430
+ return;
431
+ }
432
+ core.router.preload(url, {
433
+ data,
434
+ ...props.options
435
+ });
436
+ },
427
437
  onClick: (event) => {
428
438
  if (props.external) {
429
439
  return;
@@ -480,6 +490,10 @@ Please specify a more appropriate element using the "as" attribute. For example:
480
490
  type: String,
481
491
  required: false,
482
492
  default: void 0
493
+ },
494
+ preload: {
495
+ type: Boolean,
496
+ default: false
483
497
  }
484
498
  }
485
499
  });
@@ -680,7 +694,7 @@ function useForm(options) {
680
694
  hasDirty,
681
695
  submitWithOptions: submit,
682
696
  submit: () => submit(),
683
- hasErrors: vue.computed(() => Object.values(errors.value).length > 0),
697
+ hasErrors: vue.computed(() => Object.values(errors.value ?? {}).length > 0),
684
698
  initial,
685
699
  loaded,
686
700
  progress,
@@ -885,7 +899,6 @@ exports.defineLayout = defineLayout;
885
899
  exports.defineLayoutProperties = defineLayoutProperties;
886
900
  exports.initializeHybridly = initializeHybridly;
887
901
  exports.registerHook = registerHook;
888
- exports.resolvePageComponent = resolvePageComponent;
889
902
  exports.useBackForward = useBackForward;
890
903
  exports.useContext = useContext;
891
904
  exports.useDialog = useDialog;
package/dist/index.d.ts CHANGED
@@ -1,10 +1,9 @@
1
1
  import * as vue from 'vue';
2
2
  import { App, Plugin as Plugin$2, h, PropType, ComputedRef, DeepReadonly } from 'vue';
3
3
  import * as _hybridly_core from '@hybridly/core';
4
- import { ResolveComponent as ResolveComponent$1, RouterContextOptions, Plugin as Plugin$1, HybridPayload as HybridPayload$1, RouterContext, Method as Method$1, HybridRequestOptions as HybridRequestOptions$1, UrlResolvable as UrlResolvable$1, registerHook as registerHook$1 } from '@hybridly/core';
4
+ import { RouterContextOptions, Plugin as Plugin$1, RouterContext, Method as Method$1, HybridRequestOptions as HybridRequestOptions$1, UrlResolvable as UrlResolvable$1, registerHook as registerHook$1 } from '@hybridly/core';
5
5
  export { can, route, router } from '@hybridly/core';
6
6
  import { Axios, AxiosResponse, AxiosProgressEvent } from 'axios';
7
- import { HybridlyConfig } from '@hybridly/config';
8
7
  import { ProgressOptions } from '@hybridly/progress-plugin';
9
8
  import * as _vue_shared from '@vue/shared';
10
9
  import { RequestData } from '@hybridly/utils';
@@ -14,11 +13,6 @@ import { SearchableObject, Path, PathValue } from '@clickbar/dot-diver';
14
13
  * Initializes Hybridly's router and context.
15
14
  */
16
15
  declare function initializeHybridly(options?: InitializeOptions): Promise<any>;
17
- /**
18
- * Resolves a page component.
19
- */
20
- declare function resolvePageComponent(name: string, options: ResolvedInitializeOptions): Promise<any>;
21
- type ResolvedInitializeOptions = InitializeOptions & HybridlyConfig;
22
16
  interface InitializeOptions {
23
17
  /** Callback that gets executed before Vue is mounted. */
24
18
  enhanceVue?: (vue: App<Element>) => any;
@@ -30,8 +24,6 @@ interface InitializeOptions {
30
24
  devtools?: boolean;
31
25
  /** Whether to display response error modals. */
32
26
  responseErrorModals?: boolean;
33
- /** A custom component resolution option. */
34
- resolve?: ResolveComponent$1;
35
27
  /** Custom history state serialization functions. */
36
28
  serializer?: RouterContextOptions['serializer'];
37
29
  /** Progressbar options. */
@@ -42,10 +34,6 @@ interface InitializeOptions {
42
34
  plugins?: Plugin$1[];
43
35
  /** Custom Axios instance. */
44
36
  axios?: Axios;
45
- /** Initial view data. This is automatically set by Laravel, using this option would override the default behavior. */
46
- payload?: HybridPayload$1;
47
- /** A custom collection of pages components. This is automatically determined thanks to `root` and `pages`, using this would override the default behavior. */
48
- components?: Record<string, any>;
49
37
  }
50
38
  interface SetupArguments {
51
39
  /** DOM element to mount Vue on. */
@@ -97,42 +85,21 @@ declare const RouterLink: vue.DefineComponent<{
97
85
  required: false;
98
86
  default: undefined;
99
87
  };
100
- }, (props: Readonly<_vue_shared.LooseRequired<Readonly<vue.ExtractPropTypes<{
101
- href: {
102
- type: StringConstructor;
103
- required: false;
104
- default: undefined;
105
- };
106
- as: {
107
- type: (ObjectConstructor | StringConstructor)[];
108
- default: string;
109
- };
110
- method: {
111
- type: PropType<"delete" | Method$1 | "get" | "post" | "put" | "patch">;
112
- default: string;
113
- };
114
- data: {
115
- type: PropType<RequestData>;
116
- default: () => {};
117
- };
118
- external: {
119
- type: BooleanConstructor;
120
- default: boolean;
121
- };
122
- disabled: {
88
+ preload: {
123
89
  type: BooleanConstructor;
124
90
  default: boolean;
125
91
  };
126
- options: {
127
- type: PropType<Omit<HybridRequestOptions$1, "data" | "url" | "method">>;
128
- default: () => {};
129
- };
130
- text: {
131
- type: StringConstructor;
132
- required: false;
133
- default: undefined;
134
- };
135
- }>> & {}>>) => vue.VNode<vue.RendererNode, vue.RendererElement, {
92
+ }, (props: _vue_shared.LooseRequired<{
93
+ readonly data: RequestData;
94
+ readonly method: "delete" | Method$1 | "get" | "post" | "put" | "patch";
95
+ readonly options: Omit<HybridRequestOptions$1, "data" | "url" | "method">;
96
+ readonly as: string | Record<string, any>;
97
+ readonly external: boolean;
98
+ readonly disabled: boolean;
99
+ readonly preload: boolean;
100
+ readonly text?: string | undefined;
101
+ readonly href?: string | undefined;
102
+ } & {}>) => vue.VNode<vue.RendererNode, vue.RendererElement, {
136
103
  [key: string]: any;
137
104
  }>, unknown, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.VNodeProps & vue.AllowedComponentProps & vue.ComponentCustomProps, Readonly<vue.ExtractPropTypes<{
138
105
  href: {
@@ -169,6 +136,10 @@ declare const RouterLink: vue.DefineComponent<{
169
136
  required: false;
170
137
  default: undefined;
171
138
  };
139
+ preload: {
140
+ type: BooleanConstructor;
141
+ default: boolean;
142
+ };
172
143
  }>>, {
173
144
  data: RequestData;
174
145
  text: string;
@@ -178,7 +149,8 @@ declare const RouterLink: vue.DefineComponent<{
178
149
  as: string | Record<string, any>;
179
150
  external: boolean;
180
151
  disabled: boolean;
181
- }>;
152
+ preload: boolean;
153
+ }, {}>;
182
154
 
183
155
  /** Accesses all current properties. */
184
156
  declare function useProperties<T extends object, Global extends GlobalHybridlyProperties>(): vue.DeepReadonly<vue.UnwrapNestedRefs<T & Global>>;
@@ -261,6 +233,10 @@ interface Hooks extends RequestHooks {
261
233
  * Called when a component has been navigated to.
262
234
  */
263
235
  navigated: (options: NavigationOptions, context: InternalRouterContext) => MaybePromise<any>;
236
+ /**
237
+ * Called when a component has been navigated to and was mounted by the adapter.
238
+ */
239
+ mounted: (context: InternalRouterContext) => MaybePromise<any>;
264
240
  }
265
241
 
266
242
  interface RoutingConfiguration {
@@ -443,6 +419,8 @@ interface InternalRouterContext {
443
419
  routing?: RoutingConfiguration;
444
420
  /** Whether to display response error modals. */
445
421
  responseErrorModals?: boolean;
422
+ /** Cache of preload requests. */
423
+ preloadCache: Map<string, AxiosResponse>;
446
424
  }
447
425
  /** Adapter-specific functions. */
448
426
  interface Adapter {
@@ -455,7 +433,7 @@ interface Adapter {
455
433
  /** Called when a dialog is closed. */
456
434
  onDialogClose?: (context: InternalRouterContext) => void;
457
435
  /** Called when Hybridly is waiting for a component to be mounted. The given callback should be executed after the view component is mounted. */
458
- onWaitingForMount: (callback: Function) => void;
436
+ executeOnMounted: (callback: Function) => void;
459
437
  }
460
438
  interface ResolvedAdapter extends Adapter {
461
439
  updateRoutingConfiguration: (routing?: RoutingConfiguration) => void;
@@ -529,7 +507,7 @@ declare function useForm<T extends SearchableObject, P extends Path<T> & string
529
507
  readonly percentage: number;
530
508
  } | undefined;
531
509
  isDirty: boolean;
532
- errors: vue.UnwrapRef<DeepReadonly<[Errors<T>] extends [vue.Ref<any>] ? vue.Ref<any> & Errors<T> : vue.Ref<vue.UnwrapRef<Errors<T>>>>>;
510
+ errors: DeepReadonly<vue.UnwrapRef<Errors<T>>>;
533
511
  processing: boolean;
534
512
  successful: boolean;
535
513
  failed: boolean;
@@ -817,4 +795,4 @@ declare function useRefinements<Properties extends object, RefinementsKey extend
817
795
  applyFilter: (filter: string, value: any, options?: AvailableHybridRequestOptions) => Promise<_hybridly_core.NavigationResponse | undefined>;
818
796
  };
819
797
 
820
- export { Layout, RouterLink, defineLayout, defineLayoutProperties, initializeHybridly, registerHook, resolvePageComponent, useBackForward, useContext, useDialog, useForm, useHistoryState, usePaginator, useProperties, useProperty, useRefinements };
798
+ export { Layout, RouterLink, defineLayout, defineLayoutProperties, initializeHybridly, registerHook, useBackForward, useContext, useDialog, useForm, useHistoryState, usePaginator, useProperties, useProperty, useRefinements };
package/dist/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { shallowRef, ref, unref, triggerRef, defineComponent, toRaw, h, nextTick, createApp, isRef, reactive, readonly, computed, watch, getCurrentInstance, onUnmounted } from 'vue';
2
2
  import { registerHook as registerHook$1, createRouter, makeUrl, router } from '@hybridly/core';
3
3
  export { can, route, router } from '@hybridly/core';
4
- import { debug, random, showDomainsDisabledErrorModal, showPageComponentErrorModal, merge, clone, unsetPropertyAtPath, setValueAtPath } from '@hybridly/utils';
4
+ import { debug, random, showPageComponentErrorModal, merge, clone, unsetPropertyAtPath, setValueAtPath } from '@hybridly/utils';
5
5
  import { progress } from '@hybridly/progress-plugin';
6
6
  import { setupDevtoolsPlugin } from '@vue/devtools-api';
7
7
  import qs from 'qs';
@@ -119,7 +119,9 @@ const wrapper = defineComponent({
119
119
  actual?.();
120
120
  nextTick(() => {
121
121
  debug.adapter("vue:render:view", "Calling mounted callbacks.");
122
- onMountedCallbacks.pop()?.();
122
+ while (onMountedCallbacks.length) {
123
+ onMountedCallbacks.shift()?.();
124
+ }
123
125
  });
124
126
  };
125
127
  return h(state.view.value, {
@@ -272,17 +274,15 @@ async function initializeHybridly(options = {}) {
272
274
  if (!element) {
273
275
  throw new Error("Could not find an HTML element to initialize Vue on.");
274
276
  }
275
- if (!payload) {
276
- throw new Error("No payload. Are you using `@hybridly` or the `payload` option?");
277
- }
278
277
  state.setContext(await createRouter({
279
278
  axios: resolved.axios,
280
279
  plugins: resolved.plugins,
281
280
  serializer: resolved.serializer,
282
281
  responseErrorModals: resolved.responseErrorModals ?? process.env.NODE_ENV === "development",
282
+ routing: resolved.routing,
283
283
  adapter: {
284
284
  resolveComponent: resolve,
285
- onWaitingForMount: (callback) => {
285
+ executeOnMounted: (callback) => {
286
286
  onMountedCallbacks.push(callback);
287
287
  },
288
288
  onDialogClose: async () => {
@@ -338,21 +338,20 @@ function prepare(options) {
338
338
  const id = options.id ?? "root";
339
339
  const element = document?.getElementById(id) ?? void 0;
340
340
  debug.adapter("vue", `Element "${id}" is:`, element);
341
- const payload = options.payload ?? element?.dataset.payload ? JSON.parse(element.dataset.payload) : void 0;
341
+ const payload = element?.dataset.payload ? JSON.parse(element.dataset.payload) : void 0;
342
+ if (!payload) {
343
+ throw new Error("No payload found. Are you using the `@hybridly` directive?");
344
+ }
342
345
  if (options.cleanup !== false) {
343
346
  delete element.dataset.payload;
344
347
  }
345
348
  debug.adapter("vue", "Resolved:", { isServer, element, payload });
346
349
  const resolve = async (name) => {
347
350
  debug.adapter("vue", "Resolving component", name);
348
- if (options.resolve) {
349
- const component = await options.resolve?.(name);
350
- return component.default ?? component;
351
- }
352
- if (options.components) {
353
- return await resolvePageComponent(name, options);
351
+ if (!options.imported) {
352
+ throw new Error("No component loaded. Did you initialize Hybridly? Does `php artisan hybridly:config` return an error?");
354
353
  }
355
- throw new Error("Either `initializeHybridly#resolve` or `initializeHybridly#pages` should be defined.");
354
+ return await resolveViewComponent(name, options);
356
355
  };
357
356
  if (options.progress !== false) {
358
357
  options.plugins = [
@@ -367,21 +366,13 @@ function prepare(options) {
367
366
  resolve
368
367
  };
369
368
  }
370
- async function resolvePageComponent(name, options) {
371
- const components = options.components;
372
- if (name.includes(":")) {
373
- if (options.domains === false) {
374
- showDomainsDisabledErrorModal(name);
375
- console.warn(`${name} is a domain-based component, but domains are disabled.`);
376
- return;
377
- }
378
- const [domain, page] = name.split(":");
379
- name = `${options.domains}.${domain}.${options.pages}.${page}`;
380
- }
381
- const path = Object.keys(components).sort((a, b) => a.length - b.length).find((path2) => path2.endsWith(`${name.replaceAll(".", "/")}.vue`));
382
- if (!path) {
369
+ async function resolveViewComponent(name, options) {
370
+ const components = options.imported;
371
+ const result = options.components.views.find((view) => name === view.identifier);
372
+ const path = Object.keys(components).sort((a, b) => a.length - b.length).find((path2) => result ? path2.endsWith(result?.path) : false);
373
+ if (!result || !path) {
374
+ console.warn(`Page component [${name}] not found. Available components: `, options.components.views.map(({ identifier }) => identifier));
383
375
  showPageComponentErrorModal(name);
384
- console.warn(`Page component "${name}" could not be found. Available pages:`, Object.keys(components));
385
376
  return;
386
377
  }
387
378
  let component = typeof components[path] === "function" ? await components[path]() : components[path];
@@ -394,6 +385,7 @@ const RouterLink = defineComponent({
394
385
  setup(_, { slots, attrs }) {
395
386
  return (props) => {
396
387
  let data = props.data ?? {};
388
+ const preloads = props.preload ?? false;
397
389
  const url = makeUrl(props.href ?? "");
398
390
  const method = props.method?.toUpperCase() ?? "GET";
399
391
  const as = typeof props.as === "object" ? props.as : props.as?.toLowerCase() ?? "a";
@@ -416,6 +408,24 @@ Please specify a more appropriate element using the "as" attribute. For example:
416
408
  ...attrs,
417
409
  ...as === "a" ? { href: url } : {},
418
410
  ...props.disabled ? { disabled: props.disabled } : {},
411
+ onMouseenter: () => {
412
+ if (!preloads) {
413
+ return;
414
+ }
415
+ if (props.external) {
416
+ return;
417
+ }
418
+ if (props.disabled) {
419
+ return;
420
+ }
421
+ if (method !== "GET") {
422
+ return;
423
+ }
424
+ router.preload(url, {
425
+ data,
426
+ ...props.options
427
+ });
428
+ },
419
429
  onClick: (event) => {
420
430
  if (props.external) {
421
431
  return;
@@ -472,6 +482,10 @@ Please specify a more appropriate element using the "as" attribute. For example:
472
482
  type: String,
473
483
  required: false,
474
484
  default: void 0
485
+ },
486
+ preload: {
487
+ type: Boolean,
488
+ default: false
475
489
  }
476
490
  }
477
491
  });
@@ -672,7 +686,7 @@ function useForm(options) {
672
686
  hasDirty,
673
687
  submitWithOptions: submit,
674
688
  submit: () => submit(),
675
- hasErrors: computed(() => Object.values(errors.value).length > 0),
689
+ hasErrors: computed(() => Object.values(errors.value ?? {}).length > 0),
676
690
  initial,
677
691
  loaded,
678
692
  progress,
@@ -869,4 +883,4 @@ function useRefinements(properties, refinementsKeys, defaultOptions = {}) {
869
883
  };
870
884
  }
871
885
 
872
- export { RouterLink, defineLayout, defineLayoutProperties, initializeHybridly, registerHook, resolvePageComponent, useBackForward, useContext, useDialog, useForm, useHistoryState, usePaginator, useProperties, useProperty, useRefinements };
886
+ export { RouterLink, defineLayout, defineLayoutProperties, initializeHybridly, registerHook, useBackForward, useContext, useDialog, useForm, useHistoryState, usePaginator, useProperties, useProperty, useRefinements };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hybridly/vue",
3
- "version": "0.3.1",
3
+ "version": "0.4.1",
4
4
  "description": "Vue adapter for Hybridly",
5
5
  "keywords": [
6
6
  "hybridly",
@@ -43,18 +43,17 @@
43
43
  "defu": "^6.1.2",
44
44
  "lodash.isequal": "^4.5.0",
45
45
  "nprogress": "^0.2.0",
46
- "qs": "^6.11.1",
47
- "@hybridly/config": "0.3.1",
48
- "@hybridly/core": "0.3.1",
49
- "@hybridly/progress-plugin": "0.3.1",
50
- "@hybridly/utils": "0.3.1"
46
+ "qs": "^6.11.2",
47
+ "@hybridly/core": "0.4.1",
48
+ "@hybridly/progress-plugin": "0.4.1",
49
+ "@hybridly/utils": "0.4.1"
51
50
  },
52
51
  "devDependencies": {
53
- "@types/lodash": "^4.14.194",
52
+ "@types/lodash": "^4.14.195",
54
53
  "@types/lodash.clonedeep": "^4.5.7",
55
54
  "@types/lodash.isequal": "^4.5.6",
56
55
  "@types/nprogress": "^0.2.0",
57
- "vue": "^3.2.47"
56
+ "vue": "^3.3.4"
58
57
  },
59
58
  "scripts": {
60
59
  "build": "unbuild",