druxt 0.25.0-dev.20260927110413 → 0.25.0-dev.20260927224155

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/druxt.esm.js CHANGED
@@ -400,7 +400,7 @@ class DruxtClient {
400
400
  }
401
401
 
402
402
  var name = "druxt";
403
- var version = "0.25.0-dev.20260927110413";
403
+ var version = "0.25.0-dev.20260927224155";
404
404
  var description = "The Fully Decoupled Drupal Framework for Nuxt.js.";
405
405
  var keywords = [
406
406
  "cms",
@@ -459,7 +459,7 @@ var dependencies = {
459
459
  };
460
460
  var devDependencies = {
461
461
  "@storybook/addon-docs": "^6.5.16",
462
- "druxt-test-utils": "1.0.0-dev.20260927110413"
462
+ "druxt-test-utils": "1.0.0-dev.20260927224155"
463
463
  };
464
464
  var peerDependencies = {
465
465
  axios: "0.28.0",
@@ -636,16 +636,45 @@ const dehydrateResources = ({ commit, queryObject, resources, prefix }) => {
636
636
  return { id: data.id, type: data.type };
637
637
  });
638
638
  };
639
+ const collectionHash = (query) => {
640
+ if (!query)
641
+ return "_default";
642
+ const queryObject = getDrupalJsonApiParams(query).getQueryObject();
643
+ return md5(JSON.stringify({ ...queryObject, fields: {}, include: [] }));
644
+ };
645
+ const flush = (tree, key, keys, leaf) => {
646
+ const byKey = tree[key];
647
+ if (!byKey)
648
+ return;
649
+ if (!keys.length && leaf === void 0)
650
+ return Vue.delete(tree, key);
651
+ for (const k of keys.length ? keys : Object.keys(byKey)) {
652
+ if (!byKey[k])
653
+ continue;
654
+ if (leaf !== void 0)
655
+ Vue.delete(byKey[k], leaf);
656
+ else
657
+ Vue.delete(byKey, k);
658
+ }
659
+ };
639
660
  const DruxtStore = ({ store }) => {
640
661
  if (typeof store === "undefined") {
641
662
  throw new TypeError("Vuex store not found.");
642
663
  }
643
664
  const namespace = "druxt";
644
665
  const inFlight = new Map();
666
+ const generation = { value: 0 };
667
+ const flushInFlight = () => {
668
+ inFlight.clear();
669
+ generation.value += 1;
670
+ };
645
671
  const share = (key, request) => {
646
672
  if (!inFlight.has(key)) {
647
- const clear = () => inFlight.delete(key);
648
673
  const promise = request();
674
+ const clear = () => {
675
+ if (inFlight.get(key) === promise)
676
+ inFlight.delete(key);
677
+ };
649
678
  inFlight.set(key, promise);
650
679
  promise.then(clear, clear);
651
680
  }
@@ -700,31 +729,23 @@ const DruxtStore = ({ store }) => {
700
729
  resource = merge(state.resources[type][id][prefix] || {}, resource, { arrayMerge: (dst, src) => src });
701
730
  Vue.set(state.resources[type][id], prefix, resource);
702
731
  },
703
- flushCollection(state, { type, hash, prefix }) {
732
+ flushCollection(state, { type, hash, query, prefix } = {}) {
733
+ flushInFlight();
704
734
  if (!type)
705
- Vue.set(state, "collections", {});
706
- else if (type && !hash && !prefix)
707
- Vue.set(state.collections, type, {});
708
- else if (type && hash && !prefix)
709
- Vue.set(state.collections[type], hash, {});
710
- else if (type && hash && prefix)
711
- Vue.set(state.collections[type][hash], prefix, {});
735
+ return Vue.set(state, "collections", {});
736
+ const key = hash !== void 0 ? hash : query !== void 0 ? collectionHash(query) : void 0;
737
+ flush(state.collections, type, key !== void 0 ? [key] : [], prefix);
712
738
  },
713
- flushResource(state, { type, id, prefix }) {
739
+ flushResource(state, { type, id, prefix } = {}) {
740
+ flushInFlight();
714
741
  if (!type)
715
- Vue.set(state, "resources", {});
716
- else if (type && !id && !prefix)
717
- Vue.set(state.resources, type, {});
718
- else if (type && id && !prefix)
719
- Vue.set(state.resources[type], id, {});
720
- else if (type && id && prefix)
721
- Vue.set(state.resources[type][id], prefix, {});
742
+ return Vue.set(state, "resources", {});
743
+ flush(state.resources, type, id !== void 0 ? [id] : [], prefix);
722
744
  }
723
745
  },
724
746
  actions: {
725
747
  async getCollection({ commit, state }, { type, query, prefix, bypassCache = false }) {
726
- const queryObject = getDrupalJsonApiParams(query).getQueryObject();
727
- const hash = query ? md5(JSON.stringify({ ...queryObject, fields: {}, include: [] })) : "_default";
748
+ const hash = collectionHash(query);
728
749
  if (!bypassCache && ((state.collections[type] || {})[hash] || {})[prefix]) {
729
750
  const cached = state.collections[type][hash][prefix];
730
751
  const hydrate = (o) => (((state.resources[o.type] || {})[o.id] || {})[prefix] || {}).data;
@@ -738,10 +759,12 @@ const DruxtStore = ({ store }) => {
738
759
  };
739
760
  }
740
761
  }
741
- const key = JSON.stringify(["collection", prefix, type, hash, queryObject]);
762
+ const key = JSON.stringify(["collection", prefix, type, hash, getDrupalJsonApiParams(query).getQueryObject()]);
742
763
  return share(key, async () => {
764
+ const since = generation.value;
743
765
  const collection = await this.$druxt.getCollection(type, query, prefix);
744
- commit("addCollection", { collection: { ...collection }, type, hash, prefix });
766
+ if (since === generation.value)
767
+ commit("addCollection", { collection: { ...collection }, type, hash, prefix });
745
768
  return collection;
746
769
  });
747
770
  },
@@ -755,7 +778,7 @@ const DruxtStore = ({ store }) => {
755
778
  queryObject.fields[type] = Array.from(new Set([...fields2, ...includes])).filter((s) => s).join(",");
756
779
  }
757
780
  let included = [];
758
- if (queryObject.include && storedResource) {
781
+ if (queryObject.include && storedResource && !bypassCache) {
759
782
  const resources = await Promise.all(queryObject.include.split(",").filter((s) => Object.keys(storedResource.data.relationships || {}).includes(s)).map((key) => {
760
783
  let { data } = storedResource.data.relationships[key];
761
784
  data = Array.isArray(data) ? data : [data];
@@ -779,7 +802,7 @@ const DruxtStore = ({ store }) => {
779
802
  }
780
803
  const isFull = typeof (queryObject.fields || {})[type] !== "string";
781
804
  let fields = isFull ? true : (queryObject.fields || {})[type];
782
- if (storedResource && !isFull && fields) {
805
+ if (storedResource && !isFull && fields && !bypassCache) {
783
806
  const queryFields = fields.split(",");
784
807
  const resourceFields = [
785
808
  ...Object.keys(((storedResource || {}).data || {}).attributes || {}),
@@ -790,18 +813,22 @@ const DruxtStore = ({ store }) => {
790
813
  queryObject.fields[type] = (missingFields || []).join(",") || void 0;
791
814
  }
792
815
  let resource;
816
+ const since = generation.value;
793
817
  if (bypassCache || !storedResource || fields) {
794
818
  try {
795
819
  const key = JSON.stringify(["resource", prefix, type, id, queryObject]);
796
820
  resource = await share(key, async () => {
821
+ const started = generation.value;
797
822
  const response = await this.$druxt.getResource(type, id, getDrupalJsonApiParams(queryObject), prefix);
798
- commit("addResource", { prefix, resource: { ...response } });
823
+ if (started === generation.value)
824
+ commit("addResource", { prefix, resource: { ...response } });
799
825
  return response;
800
826
  });
801
827
  } catch (e) {
802
828
  }
803
829
  }
804
- const result = { ...((state.resources[type] || {})[id] || {})[prefix] };
830
+ const stored = ((state.resources[type] || {})[id] || {})[prefix];
831
+ const result = { ...since === generation.value && stored ? stored : resource || stored };
805
832
  if (queryObject.include && ((resource || {}).included || (storedResource || {}).included)) {
806
833
  included = [
807
834
  ...(resource || {}).included || [],
package/dist/druxt.ssr.js CHANGED
@@ -413,7 +413,7 @@ class DruxtClient {
413
413
  }
414
414
 
415
415
  var name = "druxt";
416
- var version = "0.25.0-dev.20260927110413";
416
+ var version = "0.25.0-dev.20260927224155";
417
417
  var description = "The Fully Decoupled Drupal Framework for Nuxt.js.";
418
418
  var keywords = [
419
419
  "cms",
@@ -472,7 +472,7 @@ var dependencies = {
472
472
  };
473
473
  var devDependencies = {
474
474
  "@storybook/addon-docs": "^6.5.16",
475
- "druxt-test-utils": "1.0.0-dev.20260927110413"
475
+ "druxt-test-utils": "1.0.0-dev.20260927224155"
476
476
  };
477
477
  var peerDependencies = {
478
478
  axios: "0.28.0",
@@ -649,16 +649,45 @@ const dehydrateResources = ({ commit, queryObject, resources, prefix }) => {
649
649
  return { id: data.id, type: data.type };
650
650
  });
651
651
  };
652
+ const collectionHash = (query) => {
653
+ if (!query)
654
+ return "_default";
655
+ const queryObject = getDrupalJsonApiParams(query).getQueryObject();
656
+ return md5__default["default"](JSON.stringify({ ...queryObject, fields: {}, include: [] }));
657
+ };
658
+ const flush = (tree, key, keys, leaf) => {
659
+ const byKey = tree[key];
660
+ if (!byKey)
661
+ return;
662
+ if (!keys.length && leaf === void 0)
663
+ return Vue__default["default"].delete(tree, key);
664
+ for (const k of keys.length ? keys : Object.keys(byKey)) {
665
+ if (!byKey[k])
666
+ continue;
667
+ if (leaf !== void 0)
668
+ Vue__default["default"].delete(byKey[k], leaf);
669
+ else
670
+ Vue__default["default"].delete(byKey, k);
671
+ }
672
+ };
652
673
  const DruxtStore = ({ store }) => {
653
674
  if (typeof store === "undefined") {
654
675
  throw new TypeError("Vuex store not found.");
655
676
  }
656
677
  const namespace = "druxt";
657
678
  const inFlight = new Map();
679
+ const generation = { value: 0 };
680
+ const flushInFlight = () => {
681
+ inFlight.clear();
682
+ generation.value += 1;
683
+ };
658
684
  const share = (key, request) => {
659
685
  if (!inFlight.has(key)) {
660
- const clear = () => inFlight.delete(key);
661
686
  const promise = request();
687
+ const clear = () => {
688
+ if (inFlight.get(key) === promise)
689
+ inFlight.delete(key);
690
+ };
662
691
  inFlight.set(key, promise);
663
692
  promise.then(clear, clear);
664
693
  }
@@ -713,31 +742,23 @@ const DruxtStore = ({ store }) => {
713
742
  resource = merge__default["default"](state.resources[type][id][prefix] || {}, resource, { arrayMerge: (dst, src) => src });
714
743
  Vue__default["default"].set(state.resources[type][id], prefix, resource);
715
744
  },
716
- flushCollection(state, { type, hash, prefix }) {
745
+ flushCollection(state, { type, hash, query, prefix } = {}) {
746
+ flushInFlight();
717
747
  if (!type)
718
- Vue__default["default"].set(state, "collections", {});
719
- else if (type && !hash && !prefix)
720
- Vue__default["default"].set(state.collections, type, {});
721
- else if (type && hash && !prefix)
722
- Vue__default["default"].set(state.collections[type], hash, {});
723
- else if (type && hash && prefix)
724
- Vue__default["default"].set(state.collections[type][hash], prefix, {});
748
+ return Vue__default["default"].set(state, "collections", {});
749
+ const key = hash !== void 0 ? hash : query !== void 0 ? collectionHash(query) : void 0;
750
+ flush(state.collections, type, key !== void 0 ? [key] : [], prefix);
725
751
  },
726
- flushResource(state, { type, id, prefix }) {
752
+ flushResource(state, { type, id, prefix } = {}) {
753
+ flushInFlight();
727
754
  if (!type)
728
- Vue__default["default"].set(state, "resources", {});
729
- else if (type && !id && !prefix)
730
- Vue__default["default"].set(state.resources, type, {});
731
- else if (type && id && !prefix)
732
- Vue__default["default"].set(state.resources[type], id, {});
733
- else if (type && id && prefix)
734
- Vue__default["default"].set(state.resources[type][id], prefix, {});
755
+ return Vue__default["default"].set(state, "resources", {});
756
+ flush(state.resources, type, id !== void 0 ? [id] : [], prefix);
735
757
  }
736
758
  },
737
759
  actions: {
738
760
  async getCollection({ commit, state }, { type, query, prefix, bypassCache = false }) {
739
- const queryObject = getDrupalJsonApiParams(query).getQueryObject();
740
- const hash = query ? md5__default["default"](JSON.stringify({ ...queryObject, fields: {}, include: [] })) : "_default";
761
+ const hash = collectionHash(query);
741
762
  if (!bypassCache && ((state.collections[type] || {})[hash] || {})[prefix]) {
742
763
  const cached = state.collections[type][hash][prefix];
743
764
  const hydrate = (o) => (((state.resources[o.type] || {})[o.id] || {})[prefix] || {}).data;
@@ -751,10 +772,12 @@ const DruxtStore = ({ store }) => {
751
772
  };
752
773
  }
753
774
  }
754
- const key = JSON.stringify(["collection", prefix, type, hash, queryObject]);
775
+ const key = JSON.stringify(["collection", prefix, type, hash, getDrupalJsonApiParams(query).getQueryObject()]);
755
776
  return share(key, async () => {
777
+ const since = generation.value;
756
778
  const collection = await this.$druxt.getCollection(type, query, prefix);
757
- commit("addCollection", { collection: { ...collection }, type, hash, prefix });
779
+ if (since === generation.value)
780
+ commit("addCollection", { collection: { ...collection }, type, hash, prefix });
758
781
  return collection;
759
782
  });
760
783
  },
@@ -768,7 +791,7 @@ const DruxtStore = ({ store }) => {
768
791
  queryObject.fields[type] = Array.from(new Set([...fields2, ...includes])).filter((s) => s).join(",");
769
792
  }
770
793
  let included = [];
771
- if (queryObject.include && storedResource) {
794
+ if (queryObject.include && storedResource && !bypassCache) {
772
795
  const resources = await Promise.all(queryObject.include.split(",").filter((s) => Object.keys(storedResource.data.relationships || {}).includes(s)).map((key) => {
773
796
  let { data } = storedResource.data.relationships[key];
774
797
  data = Array.isArray(data) ? data : [data];
@@ -792,7 +815,7 @@ const DruxtStore = ({ store }) => {
792
815
  }
793
816
  const isFull = typeof (queryObject.fields || {})[type] !== "string";
794
817
  let fields = isFull ? true : (queryObject.fields || {})[type];
795
- if (storedResource && !isFull && fields) {
818
+ if (storedResource && !isFull && fields && !bypassCache) {
796
819
  const queryFields = fields.split(",");
797
820
  const resourceFields = [
798
821
  ...Object.keys(((storedResource || {}).data || {}).attributes || {}),
@@ -803,18 +826,22 @@ const DruxtStore = ({ store }) => {
803
826
  queryObject.fields[type] = (missingFields || []).join(",") || void 0;
804
827
  }
805
828
  let resource;
829
+ const since = generation.value;
806
830
  if (bypassCache || !storedResource || fields) {
807
831
  try {
808
832
  const key = JSON.stringify(["resource", prefix, type, id, queryObject]);
809
833
  resource = await share(key, async () => {
834
+ const started = generation.value;
810
835
  const response = await this.$druxt.getResource(type, id, getDrupalJsonApiParams(queryObject), prefix);
811
- commit("addResource", { prefix, resource: { ...response } });
836
+ if (started === generation.value)
837
+ commit("addResource", { prefix, resource: { ...response } });
812
838
  return response;
813
839
  });
814
840
  } catch (e) {
815
841
  }
816
842
  }
817
- const result = { ...((state.resources[type] || {})[id] || {})[prefix] };
843
+ const stored = ((state.resources[type] || {})[id] || {})[prefix];
844
+ const result = { ...since === generation.value && stored ? stored : resource || stored };
818
845
  if (queryObject.include && ((resource || {}).included || (storedResource || {}).included)) {
819
846
  included = [
820
847
  ...(resource || {}).included || [],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "druxt",
3
- "version": "0.25.0-dev.20260927110413",
3
+ "version": "0.25.0-dev.20260927224155",
4
4
  "description": "The Fully Decoupled Drupal Framework for Nuxt.js.",
5
5
  "keywords": [
6
6
  "cms",
@@ -59,7 +59,7 @@
59
59
  },
60
60
  "devDependencies": {
61
61
  "@storybook/addon-docs": "^6.5.16",
62
- "druxt-test-utils": "1.0.0-dev.20260927110413"
62
+ "druxt-test-utils": "1.0.0-dev.20260927224155"
63
63
  },
64
64
  "peerDependencies": {
65
65
  "axios": "0.28.0",