@hybridly/vue 0.7.3 → 0.7.4

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
@@ -182,7 +182,11 @@ const state = {
182
182
  },
183
183
  setContext(context) {
184
184
  utils.debug.adapter("vue:state:context", "Storing context:", context);
185
- state.context.value = vue.unref(context);
185
+ if (vue.unref(context) === state.context.value) {
186
+ vue.triggerRef(state.context);
187
+ } else {
188
+ state.context.value = vue.unref(context);
189
+ }
186
190
  },
187
191
  setViewKey(key) {
188
192
  utils.debug.adapter("vue:state:key", "Storing view key:", key);
@@ -366,7 +370,6 @@ function setupDevtools(app) {
366
370
  });
367
371
  if (event === "after") {
368
372
  setTimeout(() => {
369
- vue.triggerRef(state.context);
370
373
  api.notifyComponentUpdate();
371
374
  }, 100);
372
375
  }
@@ -691,24 +694,27 @@ function toReactive(objectRef) {
691
694
  }
692
695
 
693
696
  function useProperties() {
694
- return vue.readonly(toReactive(vue.computed(() => state.context.value?.view.properties)));
697
+ return vue.readonly(toReactive(vue.computed(() => state.properties.value)));
695
698
  }
696
699
  function useProperty(path) {
697
- return vue.computed(() => dotDiver.getByPath(state.context.value?.view.properties, path));
700
+ return vue.computed(() => dotDiver.getByPath(state.properties.value, path));
698
701
  }
699
702
  function setProperty(path, value) {
700
- if (!state.context.value?.view.properties) {
703
+ if (!state.properties.value) {
701
704
  return;
702
705
  }
703
- dotDiver.setByPath(state.context.value.view.properties, path, vue.toValue(value));
706
+ dotDiver.setByPath(state.properties.value, path, vue.toValue(value));
707
+ if (state.context.value?.view.properties) {
708
+ dotDiver.setByPath(state.context.value.view.properties, path, vue.toValue(value));
709
+ }
704
710
  }
705
711
 
706
712
  function safeClone(obj) {
707
713
  return utils.clone(vue.toRaw(obj));
708
714
  }
709
715
  function useForm(options) {
710
- const shouldRemember = !!options?.key;
711
- const historyKey = options?.key ?? "form:default";
716
+ const shouldRemember = !!options.key;
717
+ const historyKey = options.key ?? "form:default";
712
718
  const historyData = shouldRemember ? core.router.history.get(historyKey) : void 0;
713
719
  const timeoutIds = {
714
720
  recentlyFailed: void 0,
@@ -730,7 +736,21 @@ function useForm(options) {
730
736
  Reflect.set(initial, key, safeClone(value));
731
737
  });
732
738
  }
733
- function reset(...keys) {
739
+ function resetSubmissionState() {
740
+ successful.value = false;
741
+ failed.value = false;
742
+ recentlyFailed.value = false;
743
+ recentlySuccessful.value = false;
744
+ clearTimeout(timeoutIds.recentlySuccessful);
745
+ clearTimeout(timeoutIds.recentlyFailed);
746
+ progress.value = void 0;
747
+ }
748
+ function reset() {
749
+ resetSubmissionState();
750
+ clearErrors();
751
+ resetFields();
752
+ }
753
+ function resetFields(...keys) {
734
754
  if (keys.length === 0) {
735
755
  keys = Object.keys(fields);
736
756
  }
@@ -747,24 +767,21 @@ function useForm(options) {
747
767
  });
748
768
  }
749
769
  function submit(optionsOverrides) {
750
- const url = typeof options.url === "function" ? options.url() : options.url;
751
- const data = typeof options.transform === "function" ? options.transform?.(fields) : fields;
752
- const preserveState = optionsOverrides?.preserveState ?? options.preserveState;
753
- const hooks = { ...options?.hooks, ...optionsOverrides?.hooks };
770
+ const { fields: _f, key: _k, ...optionsWithoutFields } = options;
771
+ const optionsWithOverrides = optionsOverrides ? utils.merge(optionsWithoutFields, optionsOverrides, { mergePlainObjects: true }) : optionsWithoutFields;
772
+ const url = typeof optionsWithOverrides.url === "function" ? optionsWithOverrides.url() : optionsWithOverrides.url;
773
+ const data = typeof optionsWithOverrides.transform === "function" ? optionsWithOverrides.transform(fields) : fields;
774
+ const preserveState = optionsWithOverrides.preserveState ?? optionsWithOverrides.method !== "GET";
775
+ const hooks = optionsWithOverrides.hooks ?? {};
754
776
  return core.router.navigate({
755
- ...options,
777
+ ...optionsWithOverrides,
756
778
  url: url ?? state.context.value?.url,
757
- method: options.method ?? "POST",
758
- ...optionsOverrides,
779
+ method: optionsWithOverrides.method ?? "POST",
759
780
  data: safeClone(data),
760
- preserveState: preserveState === void 0 && options.method !== "GET" ? true : preserveState,
781
+ preserveState,
761
782
  hooks: {
762
783
  before: (navigation, context) => {
763
- failed.value = false;
764
- successful.value = false;
765
- recentlySuccessful.value = false;
766
- clearTimeout(timeoutIds.recentlySuccessful);
767
- clearTimeout(timeoutIds.recentlyFailed);
784
+ resetSubmissionState();
768
785
  return hooks.before?.(navigation, context);
769
786
  },
770
787
  start: (context) => {
@@ -779,20 +796,20 @@ function useForm(options) {
779
796
  setErrors(incoming);
780
797
  failed.value = true;
781
798
  recentlyFailed.value = true;
782
- timeoutIds.recentlyFailed = setTimeout(() => recentlyFailed.value = false, options?.timeout ?? 5e3);
799
+ timeoutIds.recentlyFailed = setTimeout(() => recentlyFailed.value = false, optionsWithOverrides.timeout ?? 5e3);
783
800
  return hooks.error?.(incoming, context);
784
801
  },
785
802
  success: (payload, context) => {
786
803
  clearErrors();
787
- if (options?.updateInitials) {
804
+ if (optionsWithOverrides.updateInitials) {
788
805
  setInitial(fields);
789
806
  }
790
- if (options?.reset !== false) {
791
- reset();
807
+ if (optionsWithOverrides.reset !== false) {
808
+ resetFields();
792
809
  }
793
810
  successful.value = true;
794
811
  recentlySuccessful.value = true;
795
- timeoutIds.recentlySuccessful = setTimeout(() => recentlySuccessful.value = false, options?.timeout ?? 5e3);
812
+ timeoutIds.recentlySuccessful = setTimeout(() => recentlySuccessful.value = false, optionsWithOverrides.timeout ?? 5e3);
796
813
  return hooks.success?.(payload, context);
797
814
  },
798
815
  after: (context) => {
@@ -839,7 +856,9 @@ function useForm(options) {
839
856
  }
840
857
  }, { deep: true, immediate: true });
841
858
  return vue.reactive({
859
+ resetFields,
842
860
  reset,
861
+ resetSubmissionState,
843
862
  clear,
844
863
  fields,
845
864
  abort,
package/dist/index.d.cts CHANGED
@@ -243,7 +243,9 @@ interface FormOptions<T extends SearchableObject> extends Omit<HybridRequestOpti
243
243
  transform?: (fields: T) => any;
244
244
  }
245
245
  declare function useForm<T extends SearchableObject, P extends Path<T> & string = Path<T> & string>(options: FormOptions<T>): {
246
- reset: (...keys: P[]) => void;
246
+ resetFields: (...keys: P[]) => void;
247
+ reset: () => void;
248
+ resetSubmissionState: () => void;
247
249
  clear: (...keys: P[]) => void;
248
250
  fields: vue.UnwrapRef<T>;
249
251
  abort: () => void;
@@ -252,8 +254,8 @@ declare function useForm<T extends SearchableObject, P extends Path<T> & string
252
254
  clearError: (key: P) => void;
253
255
  setInitial: (newInitial: Partial<T>) => void;
254
256
  hasDirty: (...keys: P[]) => boolean;
255
- submitWith: (optionsOverrides?: Omit<HybridRequestOptions, 'data'>) => Promise<_hybridly_core.NavigationResponse>;
256
- submitWithOptions: (optionsOverrides?: Omit<HybridRequestOptions, 'data'>) => Promise<_hybridly_core.NavigationResponse>;
257
+ submitWith: (optionsOverrides?: Omit<FormOptions<T>, 'fields' | 'key'>) => Promise<_hybridly_core.NavigationResponse>;
258
+ submitWithOptions: (optionsOverrides?: Omit<FormOptions<T>, 'fields' | 'key'>) => Promise<_hybridly_core.NavigationResponse>;
257
259
  submit: () => Promise<_hybridly_core.NavigationResponse>;
258
260
  hasErrors: boolean;
259
261
  initial: vue.UnwrapRef<DeepReadonly<T>>;
package/dist/index.d.mts CHANGED
@@ -243,7 +243,9 @@ interface FormOptions<T extends SearchableObject> extends Omit<HybridRequestOpti
243
243
  transform?: (fields: T) => any;
244
244
  }
245
245
  declare function useForm<T extends SearchableObject, P extends Path<T> & string = Path<T> & string>(options: FormOptions<T>): {
246
- reset: (...keys: P[]) => void;
246
+ resetFields: (...keys: P[]) => void;
247
+ reset: () => void;
248
+ resetSubmissionState: () => void;
247
249
  clear: (...keys: P[]) => void;
248
250
  fields: vue.UnwrapRef<T>;
249
251
  abort: () => void;
@@ -252,8 +254,8 @@ declare function useForm<T extends SearchableObject, P extends Path<T> & string
252
254
  clearError: (key: P) => void;
253
255
  setInitial: (newInitial: Partial<T>) => void;
254
256
  hasDirty: (...keys: P[]) => boolean;
255
- submitWith: (optionsOverrides?: Omit<HybridRequestOptions, 'data'>) => Promise<_hybridly_core.NavigationResponse>;
256
- submitWithOptions: (optionsOverrides?: Omit<HybridRequestOptions, 'data'>) => Promise<_hybridly_core.NavigationResponse>;
257
+ submitWith: (optionsOverrides?: Omit<FormOptions<T>, 'fields' | 'key'>) => Promise<_hybridly_core.NavigationResponse>;
258
+ submitWithOptions: (optionsOverrides?: Omit<FormOptions<T>, 'fields' | 'key'>) => Promise<_hybridly_core.NavigationResponse>;
257
259
  submit: () => Promise<_hybridly_core.NavigationResponse>;
258
260
  hasErrors: boolean;
259
261
  initial: vue.UnwrapRef<DeepReadonly<T>>;
package/dist/index.d.ts CHANGED
@@ -243,7 +243,9 @@ interface FormOptions<T extends SearchableObject> extends Omit<HybridRequestOpti
243
243
  transform?: (fields: T) => any;
244
244
  }
245
245
  declare function useForm<T extends SearchableObject, P extends Path<T> & string = Path<T> & string>(options: FormOptions<T>): {
246
- reset: (...keys: P[]) => void;
246
+ resetFields: (...keys: P[]) => void;
247
+ reset: () => void;
248
+ resetSubmissionState: () => void;
247
249
  clear: (...keys: P[]) => void;
248
250
  fields: vue.UnwrapRef<T>;
249
251
  abort: () => void;
@@ -252,8 +254,8 @@ declare function useForm<T extends SearchableObject, P extends Path<T> & string
252
254
  clearError: (key: P) => void;
253
255
  setInitial: (newInitial: Partial<T>) => void;
254
256
  hasDirty: (...keys: P[]) => boolean;
255
- submitWith: (optionsOverrides?: Omit<HybridRequestOptions, 'data'>) => Promise<_hybridly_core.NavigationResponse>;
256
- submitWithOptions: (optionsOverrides?: Omit<HybridRequestOptions, 'data'>) => Promise<_hybridly_core.NavigationResponse>;
257
+ submitWith: (optionsOverrides?: Omit<FormOptions<T>, 'fields' | 'key'>) => Promise<_hybridly_core.NavigationResponse>;
258
+ submitWithOptions: (optionsOverrides?: Omit<FormOptions<T>, 'fields' | 'key'>) => Promise<_hybridly_core.NavigationResponse>;
257
259
  submit: () => Promise<_hybridly_core.NavigationResponse>;
258
260
  hasErrors: boolean;
259
261
  initial: vue.UnwrapRef<DeepReadonly<T>>;
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { shallowRef, ref, unref, defineComponent, toRaw, h, nextTick, triggerRef, createApp, isRef, reactive, readonly, computed, toValue, watch, getCurrentInstance, onUnmounted } from 'vue';
1
+ import { shallowRef, ref, unref, triggerRef, defineComponent, toRaw, h, nextTick, createApp, isRef, reactive, readonly, computed, toValue, watch, getCurrentInstance, onUnmounted } from 'vue';
2
2
  import { definePlugin, registerHook as registerHook$1, createRouter, makeUrl, router, route } from '@hybridly/core';
3
3
  export { can, route, router } from '@hybridly/core';
4
4
  import { debug, random, showViewComponentErrorModal, merge, clone, unsetPropertyAtPath, setValueAtPath } from '@hybridly/utils';
@@ -175,7 +175,11 @@ const state = {
175
175
  },
176
176
  setContext(context) {
177
177
  debug.adapter("vue:state:context", "Storing context:", context);
178
- state.context.value = unref(context);
178
+ if (unref(context) === state.context.value) {
179
+ triggerRef(state.context);
180
+ } else {
181
+ state.context.value = unref(context);
182
+ }
179
183
  },
180
184
  setViewKey(key) {
181
185
  debug.adapter("vue:state:key", "Storing view key:", key);
@@ -359,7 +363,6 @@ function setupDevtools(app) {
359
363
  });
360
364
  if (event === "after") {
361
365
  setTimeout(() => {
362
- triggerRef(state.context);
363
366
  api.notifyComponentUpdate();
364
367
  }, 100);
365
368
  }
@@ -684,24 +687,27 @@ function toReactive(objectRef) {
684
687
  }
685
688
 
686
689
  function useProperties() {
687
- return readonly(toReactive(computed(() => state.context.value?.view.properties)));
690
+ return readonly(toReactive(computed(() => state.properties.value)));
688
691
  }
689
692
  function useProperty(path) {
690
- return computed(() => getByPath(state.context.value?.view.properties, path));
693
+ return computed(() => getByPath(state.properties.value, path));
691
694
  }
692
695
  function setProperty(path, value) {
693
- if (!state.context.value?.view.properties) {
696
+ if (!state.properties.value) {
694
697
  return;
695
698
  }
696
- setByPath(state.context.value.view.properties, path, toValue(value));
699
+ setByPath(state.properties.value, path, toValue(value));
700
+ if (state.context.value?.view.properties) {
701
+ setByPath(state.context.value.view.properties, path, toValue(value));
702
+ }
697
703
  }
698
704
 
699
705
  function safeClone(obj) {
700
706
  return clone(toRaw(obj));
701
707
  }
702
708
  function useForm(options) {
703
- const shouldRemember = !!options?.key;
704
- const historyKey = options?.key ?? "form:default";
709
+ const shouldRemember = !!options.key;
710
+ const historyKey = options.key ?? "form:default";
705
711
  const historyData = shouldRemember ? router.history.get(historyKey) : void 0;
706
712
  const timeoutIds = {
707
713
  recentlyFailed: void 0,
@@ -723,7 +729,21 @@ function useForm(options) {
723
729
  Reflect.set(initial, key, safeClone(value));
724
730
  });
725
731
  }
726
- function reset(...keys) {
732
+ function resetSubmissionState() {
733
+ successful.value = false;
734
+ failed.value = false;
735
+ recentlyFailed.value = false;
736
+ recentlySuccessful.value = false;
737
+ clearTimeout(timeoutIds.recentlySuccessful);
738
+ clearTimeout(timeoutIds.recentlyFailed);
739
+ progress.value = void 0;
740
+ }
741
+ function reset() {
742
+ resetSubmissionState();
743
+ clearErrors();
744
+ resetFields();
745
+ }
746
+ function resetFields(...keys) {
727
747
  if (keys.length === 0) {
728
748
  keys = Object.keys(fields);
729
749
  }
@@ -740,24 +760,21 @@ function useForm(options) {
740
760
  });
741
761
  }
742
762
  function submit(optionsOverrides) {
743
- const url = typeof options.url === "function" ? options.url() : options.url;
744
- const data = typeof options.transform === "function" ? options.transform?.(fields) : fields;
745
- const preserveState = optionsOverrides?.preserveState ?? options.preserveState;
746
- const hooks = { ...options?.hooks, ...optionsOverrides?.hooks };
763
+ const { fields: _f, key: _k, ...optionsWithoutFields } = options;
764
+ const optionsWithOverrides = optionsOverrides ? merge(optionsWithoutFields, optionsOverrides, { mergePlainObjects: true }) : optionsWithoutFields;
765
+ const url = typeof optionsWithOverrides.url === "function" ? optionsWithOverrides.url() : optionsWithOverrides.url;
766
+ const data = typeof optionsWithOverrides.transform === "function" ? optionsWithOverrides.transform(fields) : fields;
767
+ const preserveState = optionsWithOverrides.preserveState ?? optionsWithOverrides.method !== "GET";
768
+ const hooks = optionsWithOverrides.hooks ?? {};
747
769
  return router.navigate({
748
- ...options,
770
+ ...optionsWithOverrides,
749
771
  url: url ?? state.context.value?.url,
750
- method: options.method ?? "POST",
751
- ...optionsOverrides,
772
+ method: optionsWithOverrides.method ?? "POST",
752
773
  data: safeClone(data),
753
- preserveState: preserveState === void 0 && options.method !== "GET" ? true : preserveState,
774
+ preserveState,
754
775
  hooks: {
755
776
  before: (navigation, context) => {
756
- failed.value = false;
757
- successful.value = false;
758
- recentlySuccessful.value = false;
759
- clearTimeout(timeoutIds.recentlySuccessful);
760
- clearTimeout(timeoutIds.recentlyFailed);
777
+ resetSubmissionState();
761
778
  return hooks.before?.(navigation, context);
762
779
  },
763
780
  start: (context) => {
@@ -772,20 +789,20 @@ function useForm(options) {
772
789
  setErrors(incoming);
773
790
  failed.value = true;
774
791
  recentlyFailed.value = true;
775
- timeoutIds.recentlyFailed = setTimeout(() => recentlyFailed.value = false, options?.timeout ?? 5e3);
792
+ timeoutIds.recentlyFailed = setTimeout(() => recentlyFailed.value = false, optionsWithOverrides.timeout ?? 5e3);
776
793
  return hooks.error?.(incoming, context);
777
794
  },
778
795
  success: (payload, context) => {
779
796
  clearErrors();
780
- if (options?.updateInitials) {
797
+ if (optionsWithOverrides.updateInitials) {
781
798
  setInitial(fields);
782
799
  }
783
- if (options?.reset !== false) {
784
- reset();
800
+ if (optionsWithOverrides.reset !== false) {
801
+ resetFields();
785
802
  }
786
803
  successful.value = true;
787
804
  recentlySuccessful.value = true;
788
- timeoutIds.recentlySuccessful = setTimeout(() => recentlySuccessful.value = false, options?.timeout ?? 5e3);
805
+ timeoutIds.recentlySuccessful = setTimeout(() => recentlySuccessful.value = false, optionsWithOverrides.timeout ?? 5e3);
789
806
  return hooks.success?.(payload, context);
790
807
  },
791
808
  after: (context) => {
@@ -832,7 +849,9 @@ function useForm(options) {
832
849
  }
833
850
  }, { deep: true, immediate: true });
834
851
  return reactive({
852
+ resetFields,
835
853
  reset,
854
+ resetSubmissionState,
836
855
  clear,
837
856
  fields,
838
857
  abort,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hybridly/vue",
3
- "version": "0.7.3",
3
+ "version": "0.7.4",
4
4
  "description": "Vue adapter for Hybridly",
5
5
  "keywords": [
6
6
  "hybridly",
@@ -48,15 +48,16 @@
48
48
  "defu": "^6.1.4",
49
49
  "lodash.isequal": "^4.5.0",
50
50
  "nprogress": "^0.2.0",
51
- "qs": "^6.12.0",
52
- "@hybridly/core": "0.7.3",
53
- "@hybridly/utils": "0.7.3"
51
+ "qs": "^6.12.1",
52
+ "@hybridly/core": "0.7.4",
53
+ "@hybridly/utils": "0.7.4"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@types/lodash": "^4.17.0",
57
57
  "@types/lodash.isequal": "^4.5.8",
58
58
  "@types/nprogress": "^0.2.3",
59
- "vue": "^3.4.21"
59
+ "@vue/test-utils": "^2.4.5",
60
+ "vue": "^3.4.23"
60
61
  },
61
62
  "scripts": {
62
63
  "build": "unbuild",