@scayle/storefront-product-listing 2.0.0 → 2.0.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/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # @scayle/storefront-product-listing
2
2
 
3
+ ## 2.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Resolved an issue where the `appliedFilter` in `useAppliedFilters` was updated on every route change even if the query didn't change.
8
+
9
+ This caused unnecessary updates in places where there is a reactive dependency on the `appliedFilter`.
10
+ The `appliedFilter` is now only updated when the query actually changes.
11
+
3
12
  ## 2.0.0
4
13
 
5
14
  ### Major Changes
@@ -9,14 +18,14 @@
9
18
  **Before**
10
19
 
11
20
  ```ts
12
- import { defaultSortingOptions } from "#storefront-product-listing";
21
+ import { defaultSortingOptions } from '#storefront-product-listing'
13
22
  const { sortLinks } = useProductListSort(useRoute(), {
14
23
  sortingOptions: defaultSortingOptions,
15
- });
24
+ })
16
25
  ```
17
26
 
18
27
  ```ts
19
- const { sortLinks } = useProductListSort(useRoute());
28
+ const { sortLinks } = useProductListSort(useRoute())
20
29
  ```
21
30
 
22
31
  (Both before approaches are equivalent.)
@@ -24,19 +33,19 @@
24
33
  **After**
25
34
 
26
35
  ```ts
27
- import { SORT_PRICE_ASC, SORT_PRICE_DESC } from "#storefront-product-listing";
36
+ import { SORT_PRICE_ASC, SORT_PRICE_DESC } from '#storefront-product-listing'
28
37
  const { sortLinks } = useProductListSort(useRoute(), {
29
38
  sortingOptions: [
30
39
  {
31
40
  ...SORT_PRICE_ASC,
32
- label: "Price Ascending",
41
+ label: 'Price Ascending',
33
42
  },
34
43
  {
35
44
  ...SORT_PRICE_DESC,
36
- label: "Price Descending",
45
+ label: 'Price Descending',
37
46
  },
38
47
  ],
39
- });
48
+ })
40
49
  ```
41
50
 
42
51
  - **BREAKING**: `useProductListingSeoData` now expects `isDefaultSortSelected` to be passed as the final parameter. This removes the internal dependency on `useProductListSort`. It is typed as `MaybeRefOrGetter<Boolean>` to support reactive usage.
@@ -44,12 +53,12 @@
44
53
  **Before**
45
54
 
46
55
  ```ts
47
- const route = useRoute();
56
+ const route = useRoute()
48
57
  const { title, robots, canonicalLink, categoryBreadcrumbSchema } =
49
58
  useProductListingSeoData(breadcrumbs, route, {
50
59
  baseUrl: baseUrl,
51
60
  fullPath: fullPath,
52
- });
61
+ })
53
62
  ```
54
63
 
55
64
  **After**
@@ -221,7 +230,7 @@
221
230
  They can be used as follows:
222
231
 
223
232
  ```ts
224
- import { filtersFactory } from "@scayle/storefront-product-listing";
233
+ import { filtersFactory } from '@scayle/storefront-product-listing'
225
234
  ```
226
235
 
227
236
  - Upgrade the `storefront-core` and `storefront-nuxt` packages to version 8 and update your implementation to reflect the changes in RPC composables:
package/dist/index.d.mts CHANGED
@@ -1,7 +1,6 @@
1
1
  export * from '../dist/runtime/types/sort.js';
2
- import { BreadcrumbItem } from '@scayle/storefront-nuxt';
2
+ import { BreadcrumbItem, FilterItemWithValues } from '@scayle/storefront-nuxt';
3
3
  import { Factory } from 'fishery';
4
- import { FilterItemWithValues } from '@scayle/storefront-api';
5
4
 
6
5
  type RangeTuple = [start: number, end: number];
7
6
 
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  export * from '../dist/runtime/types/sort.js';
2
2
  import { Factory } from 'fishery';
3
- import { FilterTypes } from '@scayle/storefront-api';
3
+ import { FilterTypes } from '@scayle/storefront-nuxt';
4
4
 
5
5
  const breadcrumbsFactory = Factory.define(() => [
6
6
  { to: "/de/c/women/clothing/shirts-2045", value: "shirts" },
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@scayle/storefront-product-listing",
3
3
  "configKey": "product-listing",
4
- "version": "2.0.0",
4
+ "version": "2.0.1",
5
5
  "compatibility": {
6
6
  "bridge": false,
7
7
  "nuxt": ">=3.13"
package/dist/module.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { defineNuxtModule, createResolver, addImportsDir } from '@nuxt/kit';
2
2
 
3
3
  const PACKAGE_NAME = "@scayle/storefront-product-listing";
4
- const PACKAGE_VERSION = "2.0.0";
4
+ const PACKAGE_VERSION = "2.0.1";
5
5
  const module = defineNuxtModule({
6
6
  meta: {
7
7
  name: PACKAGE_NAME,
@@ -1,9 +1,11 @@
1
- import { computed } from "vue";
1
+ import { computed, ref, watch } from "vue";
2
2
  import { parseFilterDataFromRoute } from "../utils/filters.js";
3
3
  export function useAppliedFilters(route, { filtersPrefix } = { filtersPrefix: "filters" }) {
4
- const appliedFilter = computed(() => {
5
- return parseFilterDataFromRoute(route, filtersPrefix);
6
- });
4
+ const appliedFilter = ref({ attributes: [] });
5
+ const routeQueryString = computed(() => JSON.stringify(route.query));
6
+ watch(routeQueryString, () => {
7
+ appliedFilter.value = parseFilterDataFromRoute(route.query, filtersPrefix);
8
+ }, { immediate: true });
7
9
  const appliedFiltersCount = computed(() => {
8
10
  let count = 0;
9
11
  count += appliedFilter.value.attributes?.length ?? 0;
@@ -39,7 +41,7 @@ export function useAppliedFilters(route, { filtersPrefix } = { filtersPrefix: "f
39
41
  return appliedFiltersCount.value > 0;
40
42
  });
41
43
  return {
42
- appliedFilter,
44
+ appliedFilter: computed(() => appliedFilter.value),
43
45
  appliedFiltersCount,
44
46
  appliedAttributeValues,
45
47
  appliedBooleanValues,
@@ -1,7 +1,6 @@
1
- import type { FetchFiltersParams } from '@scayle/storefront-nuxt';
1
+ import type { FetchFiltersParams, FilterItemWithValues } from '@scayle/storefront-nuxt';
2
2
  import { useFilters } from '@scayle/storefront-nuxt/composables';
3
3
  import type { ComputedRef, Ref } from 'vue';
4
- import type { FilterItemWithValues } from '@scayle/storefront-api';
5
4
  export type FiltersForListingOptions = Partial<{
6
5
  params: Ref<Omit<FetchFiltersParams, 'category'>>;
7
6
  fetchingOptions: Partial<{
@@ -1,7 +1,6 @@
1
- import type { FetchProductsByCategoryParams, Product } from '@scayle/storefront-nuxt';
1
+ import type { FetchProductsByCategoryParams, Product, Pagination } from '@scayle/storefront-nuxt';
2
2
  import type { Ref, ComputedRef } from 'vue';
3
3
  import { useProducts } from '@scayle/storefront-nuxt/composables';
4
- import type { Pagination } from '@scayle/storefront-api';
5
4
  export type UseProductsForListingReturn = Pick<Awaited<ReturnType<typeof useProducts>>, 'error' | 'status'> & {
6
5
  /** A computed array of products in the specified category. */
7
6
  products: ComputedRef<Product[]>;
@@ -1,9 +1,10 @@
1
1
  import {
2
2
  ErrorResponse,
3
3
  HttpStatusCode,
4
- HttpStatusMessage
4
+ HttpStatusMessage,
5
+ defineRpcHandler
5
6
  } from "@scayle/storefront-nuxt";
6
- export const getAllShopCategoriesForId = async function getAllShopCategoriesForId2({ id, properties }, context) {
7
+ export const getAllShopCategoriesForId = defineRpcHandler(async ({ id, properties }, context) => {
7
8
  if (typeof id !== "number" || isNaN(id)) {
8
9
  return new ErrorResponse(
9
10
  HttpStatusCode.BAD_REQUEST,
@@ -43,4 +44,4 @@ export const getAllShopCategoriesForId = async function getAllShopCategoriesForI
43
44
  // 12 hours
44
45
  })();
45
46
  return result;
46
- };
47
+ });
@@ -2,14 +2,14 @@ import type { LocationQuery, RouteLocationNormalizedLoadedGeneric } from 'vue-ro
2
2
  import type { CategoryFilter, ProductSearchQuery } from '@scayle/storefront-nuxt';
3
3
  import type { RangeTuple } from '../..//index.js';
4
4
  /**
5
- * Parses filter data from a Vue Router route object.
5
+ * Parses filter data from a Vue Router query object.
6
6
  *
7
- * @param route The Vue Router route object.
7
+ * @param query The query object.
8
8
  * @param filtersPrefix The prefix used for filter query parameters.
9
9
  *
10
10
  * @returns An object representing the parsed product search query.
11
11
  */
12
- export declare const parseFilterDataFromRoute: (route: RouteLocationNormalizedLoadedGeneric, filtersPrefix: string) => ProductSearchQuery;
12
+ export declare const parseFilterDataFromRoute: (query: LocationQuery, filtersPrefix: string) => ProductSearchQuery;
13
13
  /**
14
14
  * Creates a new attribute filter query object.
15
15
  *
@@ -1,11 +1,11 @@
1
1
  const getAttributeValues = (value) => {
2
2
  return value.split(",").filter((v) => v !== "").map(Number).filter((v) => !isNaN(v));
3
3
  };
4
- export const parseFilterDataFromRoute = (route, filtersPrefix) => {
5
- const queryKeys = Object.keys(route.query);
4
+ export const parseFilterDataFromRoute = (query, filtersPrefix) => {
5
+ const queryKeys = Object.keys(query);
6
6
  const productSearchQuery = { attributes: [] };
7
7
  queryKeys.forEach((queryKey) => {
8
- const value = route.query[queryKey];
8
+ const value = query[queryKey];
9
9
  if (!queryKey.includes(filtersPrefix)) {
10
10
  return;
11
11
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scayle/storefront-product-listing",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Collection of essential composables and utilities to work with product listing",
5
5
  "author": "SCAYLE Commerce Engine",
6
6
  "license": "MIT",
@@ -33,9 +33,7 @@
33
33
  },
34
34
  "peerDependencies": {
35
35
  "@nuxt/kit": ">=3.13.0",
36
- "@scayle/storefront-core": "^8.0.0",
37
36
  "@scayle/storefront-nuxt": "^8.0.0",
38
- "@vue/test-utils": "^2.4.6",
39
37
  "@vueuse/core": "^12.8.2 || ^13.0.0",
40
38
  "fishery": "^2.2.3",
41
39
  "vue-router": "^4.5.0",
@@ -43,31 +41,29 @@
43
41
  },
44
42
  "devDependencies": {
45
43
  "@arethetypeswrong/cli": "0.18.2",
46
- "@nuxt/kit": "3.16.2",
44
+ "@nuxt/kit": "3.17.7",
47
45
  "@nuxt/module-builder": "1.0.1",
48
- "@nuxt/schema": "3.16.2",
46
+ "@nuxt/schema": "3.17.7",
49
47
  "@nuxt/test-utils": "3.19.2",
50
- "@scayle/eslint-config-storefront": "4.5.12",
51
- "@scayle/storefront-api": "18.9.0",
52
- "@scayle/storefront-nuxt": "8.32.1",
53
- "@types/node": "22.15.34",
48
+ "@types/node": "22.16.4",
54
49
  "@vitest/coverage-v8": "3.2.4",
55
- "@vue/test-utils": "2.4.6",
56
- "@vueuse/core": "13.4.0",
50
+ "@vueuse/core": "13.5.0",
57
51
  "dprint": "0.50.1",
58
52
  "eslint-formatter-gitlab": "6.0.1",
59
- "eslint": "9.30.0",
53
+ "eslint": "9.31.0",
60
54
  "fishery": "2.3.1",
61
55
  "happy-dom": "18.0.1",
62
- "nuxt": "3.16.2",
56
+ "nuxt": "3.17.7",
63
57
  "publint": "0.3.12",
64
58
  "schema-dts": "1.1.5",
65
59
  "typescript": "5.8.3",
66
60
  "unbuild": "3.5.0",
67
61
  "vitest": "3.2.4",
68
62
  "vue-router": "4.5.1",
69
- "vue-tsc": "2.2.10",
70
- "vue": "3.5.17"
63
+ "vue-tsc": "3.0.1",
64
+ "vue": "3.5.17",
65
+ "@scayle/eslint-config-storefront": "4.6.1",
66
+ "@scayle/storefront-nuxt": "8.34.1"
71
67
  },
72
68
  "scripts": {
73
69
  "build": "nuxt-module-build build",