@wix/headless-stores 0.0.47 → 0.0.49

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.
@@ -4,4 +4,4 @@ export { ProductModifiersService, ProductModifiersServiceDefinition, } from "./p
4
4
  export { ProductService, ProductServiceDefinition, loadProductServiceConfig, } from "./product-service.js";
5
5
  export { SelectedVariantService, SelectedVariantServiceDefinition, } from "./selected-variant-service.js";
6
6
  export { ProductListService, ProductsListServiceDefinition, loadProductsListServiceConfig, ProductsListServiceConfig, } from "./products-list-service.js";
7
- export { ProductOption, InventoryStatusType, SortType, ProductChoice, ProductsListSearchService, ProductsListSearchServiceDefinition, ProductsListSearchServiceConfig, loadProductsListSearchServiceConfig, parseUrlForProductsListSearch, convertUrlSortToSortType, } from "./products-list-search-service.js";
7
+ export { ProductOption, InventoryStatusType, SortType, ProductChoice, ProductsListSearchService, ProductsListSearchServiceDefinition, ProductsListSearchServiceConfig, loadProductsListSearchServiceConfig, parseUrlToSearchOptions, convertUrlSortToSortType, } from "./products-list-search-service.js";
@@ -4,4 +4,4 @@ export { ProductModifiersService, ProductModifiersServiceDefinition, } from "./p
4
4
  export { ProductService, ProductServiceDefinition, loadProductServiceConfig, } from "./product-service.js";
5
5
  export { SelectedVariantService, SelectedVariantServiceDefinition, } from "./selected-variant-service.js";
6
6
  export { ProductListService, ProductsListServiceDefinition, loadProductsListServiceConfig, } from "./products-list-service.js";
7
- export { InventoryStatusType, SortType, ProductsListSearchService, ProductsListSearchServiceDefinition, loadProductsListSearchServiceConfig, parseUrlForProductsListSearch, convertUrlSortToSortType, } from "./products-list-search-service.js";
7
+ export { InventoryStatusType, SortType, ProductsListSearchService, ProductsListSearchServiceDefinition, loadProductsListSearchServiceConfig, parseUrlToSearchOptions, convertUrlSortToSortType, } from "./products-list-search-service.js";
@@ -33,7 +33,7 @@ export interface ProductChoice {
33
33
  /**
34
34
  * Initial search state that can be loaded from URL parameters.
35
35
  */
36
- type InitialSearchState = {
36
+ export type InitialSearchState = {
37
37
  sort?: SortType;
38
38
  limit?: number;
39
39
  cursor?: string | null;
@@ -138,16 +138,75 @@ export declare const ProductsListSearchServiceDefinition: string & {
138
138
  */
139
139
  export declare function convertUrlSortToSortType(urlSort: string): SortType | null;
140
140
  /**
141
- * Parse URL and build complete search options with all filters, sort, and pagination
141
+ * Parse URL and build complete search options with all filters, sort, and pagination.
142
+ * This function extracts search parameters, filters, sorting, and pagination from a URL
143
+ * and converts them into the format expected by the Wix Stores API.
144
+ *
145
+ * @param {string} url - The URL to parse search parameters from
146
+ * @param {Category[]} categoriesList - List of available categories for category slug resolution
147
+ * @param {productsV3.V3ProductSearch} [defaultSearchOptions] - Default search options to merge with parsed URL parameters
148
+ * @returns {Promise<{searchOptions: productsV3.V3ProductSearch, initialSearchState: InitialSearchState}>}
149
+ * Object containing both API-ready search options and UI-ready initial state
150
+ *
151
+ * @example
152
+ * ```tsx
153
+ * // Parse URL with filters, sort, and pagination
154
+ * const categories = await loadCategoriesListServiceConfig();
155
+ * const { searchOptions, initialSearchState } = await parseUrlToSearchOptions(
156
+ * 'https://example.com/products?sort=price:desc&Color=red,blue&minPrice=50',
157
+ * categories.categories
158
+ * );
159
+ *
160
+ * // Use searchOptions for API calls
161
+ * const products = await productsV3.searchProducts(searchOptions);
162
+ *
163
+ * // Use initialSearchState for UI initialization
164
+ * const filterState = initialSearchState.productOptions; // { colorId: ['red-id', 'blue-id'] }
165
+ * ```
142
166
  */
143
- export declare function parseUrlForProductsListSearch(url: string, categoriesList: Category[], defaultSearchOptions?: productsV3.V3ProductSearch): Promise<{
167
+ export declare function parseUrlToSearchOptions(url: string, categoriesList: Category[], defaultSearchOptions?: productsV3.V3ProductSearch): Promise<{
144
168
  searchOptions: productsV3.V3ProductSearch;
145
169
  initialSearchState: InitialSearchState;
146
170
  }>;
147
171
  /**
148
- * Load search service configuration from URL
172
+ * Load search service configuration from URL or parsed URL result.
173
+ * This function provides the configuration for the Products List Search service,
174
+ * including customizations and initial search state.
175
+ *
176
+ * @param {string | { searchOptions: productsV3.V3ProductSearch; initialSearchState: InitialSearchState }} input - Either a URL to parse or parsed URL result from parseUrlToSearchOptions
177
+ * @returns {Promise<ProductsListSearchServiceConfig>} Promise that resolves to the search service configuration
178
+ *
179
+ * @example
180
+ * ```tsx
181
+ * // Option 1: Load from URL (will parse filters, sort, pagination from URL params)
182
+ * const searchConfig = await loadProductsListSearchServiceConfig(window.location.href);
183
+ *
184
+ * // Option 2: Custom parsing with defaults
185
+ * const categories = await loadCategoriesListServiceConfig();
186
+ * const parsed = await parseUrlToSearchOptions(
187
+ * window.location.href,
188
+ * categories.categories,
189
+ * {
190
+ * cursorPaging: { limit: 12 },
191
+ * filter: { 'categoryIds': ['123'] },
192
+ * sort: [{ fieldName: 'name' as const, order: 'ASC' as const }]
193
+ * }
194
+ * );
195
+ * const searchConfig = await loadProductsListSearchServiceConfig(parsed);
196
+ *
197
+ * // Option 3: Performance optimization - use parsed result for both services (no duplicate parsing)
198
+ * const categories = await loadCategoriesListServiceConfig();
199
+ * const parsed = await parseUrlToSearchOptions(url, categories.categories);
200
+ * const [productsConfig, searchConfig] = await Promise.all([
201
+ * loadProductsListServiceConfig(parsed),
202
+ * loadProductsListSearchServiceConfig(parsed),
203
+ * ]);
204
+ * ```
149
205
  */
150
- export declare function loadProductsListSearchServiceConfig(url: string): Promise<ProductsListSearchServiceConfig>;
206
+ export declare function loadProductsListSearchServiceConfig(input: string | {
207
+ searchOptions: productsV3.V3ProductSearch;
208
+ initialSearchState: InitialSearchState;
209
+ }): Promise<ProductsListSearchServiceConfig>;
151
210
  /**
152
211
  * Implementation of the Products List Search service
153
212
  */
@@ -141,21 +141,17 @@ function updateUrlWithSearchState(searchState) {
141
141
  }
142
142
  // Handle URL path construction with category
143
143
  let baseUrl = window.location.pathname;
144
- // If categorySlug is provided, update the path
144
+ // If categorySlug is provided, replace the last path segment (which represents the category)
145
145
  if (categorySlug) {
146
- // Find if there's already a /category/ segment in the current path
147
146
  const pathSegments = baseUrl.split("/").filter(Boolean);
148
- const categoryIndex = pathSegments.findIndex((segment) => segment === "category");
149
- if (categoryIndex !== -1) {
150
- // Replace existing category slug
151
- pathSegments[categoryIndex + 1] = categorySlug;
147
+ if (pathSegments.length > 0) {
148
+ // Replace the last segment with the new category slug
149
+ pathSegments[pathSegments.length - 1] = categorySlug;
152
150
  baseUrl = "/" + pathSegments.join("/");
153
151
  }
154
152
  else {
155
- // Append category path to existing base
156
- baseUrl = baseUrl.endsWith("/")
157
- ? `${baseUrl}category/${categorySlug}`
158
- : `${baseUrl}/category/${categorySlug}`;
153
+ // If no segments, just use the category slug
154
+ baseUrl = `/${categorySlug}`;
159
155
  }
160
156
  }
161
157
  // Build the new URL
@@ -168,9 +164,33 @@ function updateUrlWithSearchState(searchState) {
168
164
  }
169
165
  }
170
166
  /**
171
- * Parse URL and build complete search options with all filters, sort, and pagination
167
+ * Parse URL and build complete search options with all filters, sort, and pagination.
168
+ * This function extracts search parameters, filters, sorting, and pagination from a URL
169
+ * and converts them into the format expected by the Wix Stores API.
170
+ *
171
+ * @param {string} url - The URL to parse search parameters from
172
+ * @param {Category[]} categoriesList - List of available categories for category slug resolution
173
+ * @param {productsV3.V3ProductSearch} [defaultSearchOptions] - Default search options to merge with parsed URL parameters
174
+ * @returns {Promise<{searchOptions: productsV3.V3ProductSearch, initialSearchState: InitialSearchState}>}
175
+ * Object containing both API-ready search options and UI-ready initial state
176
+ *
177
+ * @example
178
+ * ```tsx
179
+ * // Parse URL with filters, sort, and pagination
180
+ * const categories = await loadCategoriesListServiceConfig();
181
+ * const { searchOptions, initialSearchState } = await parseUrlToSearchOptions(
182
+ * 'https://example.com/products?sort=price:desc&Color=red,blue&minPrice=50',
183
+ * categories.categories
184
+ * );
185
+ *
186
+ * // Use searchOptions for API calls
187
+ * const products = await productsV3.searchProducts(searchOptions);
188
+ *
189
+ * // Use initialSearchState for UI initialization
190
+ * const filterState = initialSearchState.productOptions; // { colorId: ['red-id', 'blue-id'] }
191
+ * ```
172
192
  */
173
- export async function parseUrlForProductsListSearch(url, categoriesList, defaultSearchOptions) {
193
+ export async function parseUrlToSearchOptions(url, categoriesList, defaultSearchOptions) {
174
194
  const urlObj = new URL(url);
175
195
  const searchParams = urlObj.searchParams;
176
196
  // Get customizations for product option parsing
@@ -403,12 +423,52 @@ export async function parseUrlForProductsListSearch(url, categoriesList, default
403
423
  return { searchOptions, initialSearchState };
404
424
  }
405
425
  /**
406
- * Load search service configuration from URL
426
+ * Load search service configuration from URL or parsed URL result.
427
+ * This function provides the configuration for the Products List Search service,
428
+ * including customizations and initial search state.
429
+ *
430
+ * @param {string | { searchOptions: productsV3.V3ProductSearch; initialSearchState: InitialSearchState }} input - Either a URL to parse or parsed URL result from parseUrlToSearchOptions
431
+ * @returns {Promise<ProductsListSearchServiceConfig>} Promise that resolves to the search service configuration
432
+ *
433
+ * @example
434
+ * ```tsx
435
+ * // Option 1: Load from URL (will parse filters, sort, pagination from URL params)
436
+ * const searchConfig = await loadProductsListSearchServiceConfig(window.location.href);
437
+ *
438
+ * // Option 2: Custom parsing with defaults
439
+ * const categories = await loadCategoriesListServiceConfig();
440
+ * const parsed = await parseUrlToSearchOptions(
441
+ * window.location.href,
442
+ * categories.categories,
443
+ * {
444
+ * cursorPaging: { limit: 12 },
445
+ * filter: { 'categoryIds': ['123'] },
446
+ * sort: [{ fieldName: 'name' as const, order: 'ASC' as const }]
447
+ * }
448
+ * );
449
+ * const searchConfig = await loadProductsListSearchServiceConfig(parsed);
450
+ *
451
+ * // Option 3: Performance optimization - use parsed result for both services (no duplicate parsing)
452
+ * const categories = await loadCategoriesListServiceConfig();
453
+ * const parsed = await parseUrlToSearchOptions(url, categories.categories);
454
+ * const [productsConfig, searchConfig] = await Promise.all([
455
+ * loadProductsListServiceConfig(parsed),
456
+ * loadProductsListSearchServiceConfig(parsed),
457
+ * ]);
458
+ * ```
407
459
  */
408
- export async function loadProductsListSearchServiceConfig(url) {
409
- // Load categories using the categories service
410
- const categoriesListConfig = await loadCategoriesListServiceConfig();
411
- const { initialSearchState } = await parseUrlForProductsListSearch(url, categoriesListConfig.categories);
460
+ export async function loadProductsListSearchServiceConfig(input) {
461
+ let initialSearchState;
462
+ if (typeof input === 'string') {
463
+ // URL input - parse it
464
+ const categoriesListConfig = await loadCategoriesListServiceConfig();
465
+ const { initialSearchState: parsedState } = await parseUrlToSearchOptions(input, categoriesListConfig.categories);
466
+ initialSearchState = parsedState;
467
+ }
468
+ else {
469
+ // Parsed URL result - use initialSearchState directly (no duplicate work)
470
+ initialSearchState = input.initialSearchState;
471
+ }
412
472
  const { items: customizations = [] } = await customizationsV3
413
473
  .queryCustomizations()
414
474
  .find();
@@ -1,5 +1,6 @@
1
1
  import { type Signal } from "@wix/services-definitions/core-services/signals";
2
2
  import { productsV3 } from "@wix/stores";
3
+ import { type InitialSearchState } from "./products-list-search-service.js";
3
4
  export declare const DEFAULT_QUERY_LIMIT = 100;
4
5
  /**
5
6
  * Configuration interface for the Products List service.
@@ -20,27 +21,33 @@ export type ProductsListServiceConfig = {
20
21
  /**
21
22
  * Loads products list service configuration from the Wix Stores API for SSR initialization.
22
23
  * This function is designed to be used during Server-Side Rendering (SSR) to preload
23
- * a list of products based on search criteria.
24
+ * a list of products based on search criteria or URL parameters.
24
25
  *
25
- * @param {productsV3.V3ProductSearch} searchOptions - The search options for querying products
26
+ * @param {string | { searchOptions: productsV3.V3ProductSearch; initialSearchState: InitialSearchState }} input - Either a URL to parse or parsed URL result from parseUrlToSearchOptions
26
27
  * @returns {Promise<ProductsListServiceConfig>} Promise that resolves to the products list configuration
27
28
  *
28
29
  * @example
29
30
  * ```astro
30
31
  * ---
31
32
  * // Astro page example - pages/products.astro
32
- * import { loadProductsListServiceConfig } from '@wix/stores/services';
33
+ * import { loadProductsListServiceConfig, parseUrlToSearchOptions, loadCategoriesListServiceConfig } from '@wix/stores/services';
33
34
  * import { ProductList } from '@wix/stores/components';
34
35
  *
35
- * // Define search options
36
- * const searchOptions = {
37
- * cursorPaging: { limit: 12 },
38
- * filter: {},
39
- * sort: [{ fieldName: 'name', order: 'ASC' }]
40
- * };
36
+ * // Option 1: Load from URL (will parse filters, sort, pagination from URL params)
37
+ * const productsConfig = await loadProductsListServiceConfig(Astro.url.href);
41
38
  *
42
- * // Load products data during SSR
43
- * const productsConfig = await loadProductsListServiceConfig(searchOptions);
39
+ * // Option 2: Custom parsing with defaults
40
+ * const categories = await loadCategoriesListServiceConfig();
41
+ * const parsed = await parseUrlToSearchOptions(
42
+ * Astro.url.href,
43
+ * categories.categories,
44
+ * {
45
+ * cursorPaging: { limit: 12 },
46
+ * filter: {},
47
+ * sort: [{ fieldName: 'name' as const, order: 'ASC' as const }]
48
+ * }
49
+ * );
50
+ * const productsConfig = await loadProductsListServiceConfig(parsed);
44
51
  * ---
45
52
  *
46
53
  * <ProductList.Root productsConfig={productsConfig}>
@@ -59,23 +66,31 @@ export type ProductsListServiceConfig = {
59
66
  * ```tsx
60
67
  * // Next.js page example - pages/products.tsx
61
68
  * import { GetServerSideProps } from 'next';
62
- * import { loadProductsListServiceConfig } from '@wix/stores/services';
69
+ * import { loadProductsListServiceConfig, parseUrlToSearchOptions, loadCategoriesListServiceConfig } from '@wix/stores/services';
63
70
  * import { ProductsList } from '@wix/stores/components';
64
71
  *
65
72
  * interface ProductsPageProps {
66
73
  * productsConfig: Awaited<ReturnType<typeof loadProductsListServiceConfig>>;
67
74
  * }
68
75
  *
69
- * export const getServerSideProps: GetServerSideProps<ProductsPageProps> = async () => {
70
- * const searchOptions = {
71
- * cursorPaging: { limit: 12 },
72
- * filter: {
73
- * 'allCategoriesInfo.categories': { $matchItems: [{ _id: { $in: [category._id] } }] }
74
- * },
75
- * sort: [{ fieldName: 'name' as const, order: 'ASC' as const }]
76
- * };
76
+ * export const getServerSideProps: GetServerSideProps<ProductsPageProps> = async ({ req }) => {
77
+ * // Option 1: Parse from URL
78
+ * const productsConfig = await loadProductsListServiceConfig(`${req.url}`);
77
79
  *
78
- * const productsConfig = await loadProductsListServiceConfig(searchOptions);
80
+ * // Option 2: Custom parsing with filters
81
+ * const categories = await loadCategoriesListServiceConfig();
82
+ * const parsed = await parseUrlToSearchOptions(
83
+ * `${req.url}`,
84
+ * categories.categories,
85
+ * {
86
+ * cursorPaging: { limit: 12 },
87
+ * filter: {
88
+ * 'allCategoriesInfo.categories': { $matchItems: [{ _id: { $in: [category._id] } }] }
89
+ * },
90
+ * sort: [{ fieldName: 'name' as const, order: 'ASC' as const }]
91
+ * }
92
+ * );
93
+ * const productsConfig = await loadProductsListServiceConfig(parsed);
79
94
  *
80
95
  * return {
81
96
  * props: {
@@ -99,8 +114,26 @@ export type ProductsListServiceConfig = {
99
114
  * );
100
115
  * }
101
116
  * ```
117
+ *
118
+ * @example
119
+ * ```tsx
120
+ * // Advanced: Performance optimization when using both services
121
+ * import { parseUrlToSearchOptions, loadProductsListServiceConfig, loadProductsListSearchServiceConfig, loadCategoriesListServiceConfig } from '@wix/stores/services';
122
+ *
123
+ * const categories = await loadCategoriesListServiceConfig();
124
+ * const parsed = await parseUrlToSearchOptions(url, categories.categories);
125
+ *
126
+ * // Both services use the same parsed result (no duplicate URL parsing)
127
+ * const [productsConfig, searchConfig] = await Promise.all([
128
+ * loadProductsListServiceConfig(parsed),
129
+ * loadProductsListSearchServiceConfig(parsed)
130
+ * ]);
131
+ * ```
102
132
  */
103
- export declare function loadProductsListServiceConfig(searchOptions: productsV3.V3ProductSearch): Promise<ProductsListServiceConfig>;
133
+ export declare function loadProductsListServiceConfig(input: string | {
134
+ searchOptions: productsV3.V3ProductSearch;
135
+ initialSearchState: InitialSearchState;
136
+ }): Promise<ProductsListServiceConfig>;
104
137
  /**
105
138
  * Service definition for the Products List service.
106
139
  * This defines the reactive API contract for managing a list of products with search, pagination, and filtering capabilities.
@@ -1,31 +1,39 @@
1
1
  import { defineService, implementService } from "@wix/services-definitions";
2
2
  import { SignalsServiceDefinition, } from "@wix/services-definitions/core-services/signals";
3
3
  import { productsV3, readOnlyVariantsV3 } from "@wix/stores";
4
+ import { loadCategoriesListServiceConfig } from "./categories-list-service.js";
5
+ import { parseUrlToSearchOptions } from "./products-list-search-service.js";
4
6
  export const DEFAULT_QUERY_LIMIT = 100;
5
7
  /**
6
8
  * Loads products list service configuration from the Wix Stores API for SSR initialization.
7
9
  * This function is designed to be used during Server-Side Rendering (SSR) to preload
8
- * a list of products based on search criteria.
10
+ * a list of products based on search criteria or URL parameters.
9
11
  *
10
- * @param {productsV3.V3ProductSearch} searchOptions - The search options for querying products
12
+ * @param {string | { searchOptions: productsV3.V3ProductSearch; initialSearchState: InitialSearchState }} input - Either a URL to parse or parsed URL result from parseUrlToSearchOptions
11
13
  * @returns {Promise<ProductsListServiceConfig>} Promise that resolves to the products list configuration
12
14
  *
13
15
  * @example
14
16
  * ```astro
15
17
  * ---
16
18
  * // Astro page example - pages/products.astro
17
- * import { loadProductsListServiceConfig } from '@wix/stores/services';
19
+ * import { loadProductsListServiceConfig, parseUrlToSearchOptions, loadCategoriesListServiceConfig } from '@wix/stores/services';
18
20
  * import { ProductList } from '@wix/stores/components';
19
21
  *
20
- * // Define search options
21
- * const searchOptions = {
22
- * cursorPaging: { limit: 12 },
23
- * filter: {},
24
- * sort: [{ fieldName: 'name', order: 'ASC' }]
25
- * };
22
+ * // Option 1: Load from URL (will parse filters, sort, pagination from URL params)
23
+ * const productsConfig = await loadProductsListServiceConfig(Astro.url.href);
26
24
  *
27
- * // Load products data during SSR
28
- * const productsConfig = await loadProductsListServiceConfig(searchOptions);
25
+ * // Option 2: Custom parsing with defaults
26
+ * const categories = await loadCategoriesListServiceConfig();
27
+ * const parsed = await parseUrlToSearchOptions(
28
+ * Astro.url.href,
29
+ * categories.categories,
30
+ * {
31
+ * cursorPaging: { limit: 12 },
32
+ * filter: {},
33
+ * sort: [{ fieldName: 'name' as const, order: 'ASC' as const }]
34
+ * }
35
+ * );
36
+ * const productsConfig = await loadProductsListServiceConfig(parsed);
29
37
  * ---
30
38
  *
31
39
  * <ProductList.Root productsConfig={productsConfig}>
@@ -44,23 +52,31 @@ export const DEFAULT_QUERY_LIMIT = 100;
44
52
  * ```tsx
45
53
  * // Next.js page example - pages/products.tsx
46
54
  * import { GetServerSideProps } from 'next';
47
- * import { loadProductsListServiceConfig } from '@wix/stores/services';
55
+ * import { loadProductsListServiceConfig, parseUrlToSearchOptions, loadCategoriesListServiceConfig } from '@wix/stores/services';
48
56
  * import { ProductsList } from '@wix/stores/components';
49
57
  *
50
58
  * interface ProductsPageProps {
51
59
  * productsConfig: Awaited<ReturnType<typeof loadProductsListServiceConfig>>;
52
60
  * }
53
61
  *
54
- * export const getServerSideProps: GetServerSideProps<ProductsPageProps> = async () => {
55
- * const searchOptions = {
56
- * cursorPaging: { limit: 12 },
57
- * filter: {
58
- * 'allCategoriesInfo.categories': { $matchItems: [{ _id: { $in: [category._id] } }] }
59
- * },
60
- * sort: [{ fieldName: 'name' as const, order: 'ASC' as const }]
61
- * };
62
+ * export const getServerSideProps: GetServerSideProps<ProductsPageProps> = async ({ req }) => {
63
+ * // Option 1: Parse from URL
64
+ * const productsConfig = await loadProductsListServiceConfig(`${req.url}`);
62
65
  *
63
- * const productsConfig = await loadProductsListServiceConfig(searchOptions);
66
+ * // Option 2: Custom parsing with filters
67
+ * const categories = await loadCategoriesListServiceConfig();
68
+ * const parsed = await parseUrlToSearchOptions(
69
+ * `${req.url}`,
70
+ * categories.categories,
71
+ * {
72
+ * cursorPaging: { limit: 12 },
73
+ * filter: {
74
+ * 'allCategoriesInfo.categories': { $matchItems: [{ _id: { $in: [category._id] } }] }
75
+ * },
76
+ * sort: [{ fieldName: 'name' as const, order: 'ASC' as const }]
77
+ * }
78
+ * );
79
+ * const productsConfig = await loadProductsListServiceConfig(parsed);
64
80
  *
65
81
  * return {
66
82
  * props: {
@@ -84,8 +100,34 @@ export const DEFAULT_QUERY_LIMIT = 100;
84
100
  * );
85
101
  * }
86
102
  * ```
103
+ *
104
+ * @example
105
+ * ```tsx
106
+ * // Advanced: Performance optimization when using both services
107
+ * import { parseUrlToSearchOptions, loadProductsListServiceConfig, loadProductsListSearchServiceConfig, loadCategoriesListServiceConfig } from '@wix/stores/services';
108
+ *
109
+ * const categories = await loadCategoriesListServiceConfig();
110
+ * const parsed = await parseUrlToSearchOptions(url, categories.categories);
111
+ *
112
+ * // Both services use the same parsed result (no duplicate URL parsing)
113
+ * const [productsConfig, searchConfig] = await Promise.all([
114
+ * loadProductsListServiceConfig(parsed),
115
+ * loadProductsListSearchServiceConfig(parsed)
116
+ * ]);
117
+ * ```
87
118
  */
88
- export async function loadProductsListServiceConfig(searchOptions) {
119
+ export async function loadProductsListServiceConfig(input) {
120
+ let searchOptions;
121
+ if (typeof input === 'string') {
122
+ // URL input - parse it
123
+ const categoriesListConfig = await loadCategoriesListServiceConfig();
124
+ const { searchOptions: parsedOptions } = await parseUrlToSearchOptions(input, categoriesListConfig.categories);
125
+ searchOptions = parsedOptions;
126
+ }
127
+ else {
128
+ // Parsed URL result - use searchOptions directly
129
+ searchOptions = input.searchOptions;
130
+ }
89
131
  const searchWithoutFilter = { ...searchOptions, filter: {} };
90
132
  const [resultWithoutFilter, resultWithFilter] = await Promise.all([
91
133
  fetchProducts(searchWithoutFilter),
@@ -4,4 +4,4 @@ export { ProductModifiersService, ProductModifiersServiceDefinition, } from "./p
4
4
  export { ProductService, ProductServiceDefinition, loadProductServiceConfig, } from "./product-service.js";
5
5
  export { SelectedVariantService, SelectedVariantServiceDefinition, } from "./selected-variant-service.js";
6
6
  export { ProductListService, ProductsListServiceDefinition, loadProductsListServiceConfig, ProductsListServiceConfig, } from "./products-list-service.js";
7
- export { ProductOption, InventoryStatusType, SortType, ProductChoice, ProductsListSearchService, ProductsListSearchServiceDefinition, ProductsListSearchServiceConfig, loadProductsListSearchServiceConfig, parseUrlForProductsListSearch, convertUrlSortToSortType, } from "./products-list-search-service.js";
7
+ export { ProductOption, InventoryStatusType, SortType, ProductChoice, ProductsListSearchService, ProductsListSearchServiceDefinition, ProductsListSearchServiceConfig, loadProductsListSearchServiceConfig, parseUrlToSearchOptions, convertUrlSortToSortType, } from "./products-list-search-service.js";
@@ -4,4 +4,4 @@ export { ProductModifiersService, ProductModifiersServiceDefinition, } from "./p
4
4
  export { ProductService, ProductServiceDefinition, loadProductServiceConfig, } from "./product-service.js";
5
5
  export { SelectedVariantService, SelectedVariantServiceDefinition, } from "./selected-variant-service.js";
6
6
  export { ProductListService, ProductsListServiceDefinition, loadProductsListServiceConfig, } from "./products-list-service.js";
7
- export { InventoryStatusType, SortType, ProductsListSearchService, ProductsListSearchServiceDefinition, loadProductsListSearchServiceConfig, parseUrlForProductsListSearch, convertUrlSortToSortType, } from "./products-list-search-service.js";
7
+ export { InventoryStatusType, SortType, ProductsListSearchService, ProductsListSearchServiceDefinition, loadProductsListSearchServiceConfig, parseUrlToSearchOptions, convertUrlSortToSortType, } from "./products-list-search-service.js";
@@ -33,7 +33,7 @@ export interface ProductChoice {
33
33
  /**
34
34
  * Initial search state that can be loaded from URL parameters.
35
35
  */
36
- type InitialSearchState = {
36
+ export type InitialSearchState = {
37
37
  sort?: SortType;
38
38
  limit?: number;
39
39
  cursor?: string | null;
@@ -138,16 +138,75 @@ export declare const ProductsListSearchServiceDefinition: string & {
138
138
  */
139
139
  export declare function convertUrlSortToSortType(urlSort: string): SortType | null;
140
140
  /**
141
- * Parse URL and build complete search options with all filters, sort, and pagination
141
+ * Parse URL and build complete search options with all filters, sort, and pagination.
142
+ * This function extracts search parameters, filters, sorting, and pagination from a URL
143
+ * and converts them into the format expected by the Wix Stores API.
144
+ *
145
+ * @param {string} url - The URL to parse search parameters from
146
+ * @param {Category[]} categoriesList - List of available categories for category slug resolution
147
+ * @param {productsV3.V3ProductSearch} [defaultSearchOptions] - Default search options to merge with parsed URL parameters
148
+ * @returns {Promise<{searchOptions: productsV3.V3ProductSearch, initialSearchState: InitialSearchState}>}
149
+ * Object containing both API-ready search options and UI-ready initial state
150
+ *
151
+ * @example
152
+ * ```tsx
153
+ * // Parse URL with filters, sort, and pagination
154
+ * const categories = await loadCategoriesListServiceConfig();
155
+ * const { searchOptions, initialSearchState } = await parseUrlToSearchOptions(
156
+ * 'https://example.com/products?sort=price:desc&Color=red,blue&minPrice=50',
157
+ * categories.categories
158
+ * );
159
+ *
160
+ * // Use searchOptions for API calls
161
+ * const products = await productsV3.searchProducts(searchOptions);
162
+ *
163
+ * // Use initialSearchState for UI initialization
164
+ * const filterState = initialSearchState.productOptions; // { colorId: ['red-id', 'blue-id'] }
165
+ * ```
142
166
  */
143
- export declare function parseUrlForProductsListSearch(url: string, categoriesList: Category[], defaultSearchOptions?: productsV3.V3ProductSearch): Promise<{
167
+ export declare function parseUrlToSearchOptions(url: string, categoriesList: Category[], defaultSearchOptions?: productsV3.V3ProductSearch): Promise<{
144
168
  searchOptions: productsV3.V3ProductSearch;
145
169
  initialSearchState: InitialSearchState;
146
170
  }>;
147
171
  /**
148
- * Load search service configuration from URL
172
+ * Load search service configuration from URL or parsed URL result.
173
+ * This function provides the configuration for the Products List Search service,
174
+ * including customizations and initial search state.
175
+ *
176
+ * @param {string | { searchOptions: productsV3.V3ProductSearch; initialSearchState: InitialSearchState }} input - Either a URL to parse or parsed URL result from parseUrlToSearchOptions
177
+ * @returns {Promise<ProductsListSearchServiceConfig>} Promise that resolves to the search service configuration
178
+ *
179
+ * @example
180
+ * ```tsx
181
+ * // Option 1: Load from URL (will parse filters, sort, pagination from URL params)
182
+ * const searchConfig = await loadProductsListSearchServiceConfig(window.location.href);
183
+ *
184
+ * // Option 2: Custom parsing with defaults
185
+ * const categories = await loadCategoriesListServiceConfig();
186
+ * const parsed = await parseUrlToSearchOptions(
187
+ * window.location.href,
188
+ * categories.categories,
189
+ * {
190
+ * cursorPaging: { limit: 12 },
191
+ * filter: { 'categoryIds': ['123'] },
192
+ * sort: [{ fieldName: 'name' as const, order: 'ASC' as const }]
193
+ * }
194
+ * );
195
+ * const searchConfig = await loadProductsListSearchServiceConfig(parsed);
196
+ *
197
+ * // Option 3: Performance optimization - use parsed result for both services (no duplicate parsing)
198
+ * const categories = await loadCategoriesListServiceConfig();
199
+ * const parsed = await parseUrlToSearchOptions(url, categories.categories);
200
+ * const [productsConfig, searchConfig] = await Promise.all([
201
+ * loadProductsListServiceConfig(parsed),
202
+ * loadProductsListSearchServiceConfig(parsed),
203
+ * ]);
204
+ * ```
149
205
  */
150
- export declare function loadProductsListSearchServiceConfig(url: string): Promise<ProductsListSearchServiceConfig>;
206
+ export declare function loadProductsListSearchServiceConfig(input: string | {
207
+ searchOptions: productsV3.V3ProductSearch;
208
+ initialSearchState: InitialSearchState;
209
+ }): Promise<ProductsListSearchServiceConfig>;
151
210
  /**
152
211
  * Implementation of the Products List Search service
153
212
  */
@@ -141,21 +141,17 @@ function updateUrlWithSearchState(searchState) {
141
141
  }
142
142
  // Handle URL path construction with category
143
143
  let baseUrl = window.location.pathname;
144
- // If categorySlug is provided, update the path
144
+ // If categorySlug is provided, replace the last path segment (which represents the category)
145
145
  if (categorySlug) {
146
- // Find if there's already a /category/ segment in the current path
147
146
  const pathSegments = baseUrl.split("/").filter(Boolean);
148
- const categoryIndex = pathSegments.findIndex((segment) => segment === "category");
149
- if (categoryIndex !== -1) {
150
- // Replace existing category slug
151
- pathSegments[categoryIndex + 1] = categorySlug;
147
+ if (pathSegments.length > 0) {
148
+ // Replace the last segment with the new category slug
149
+ pathSegments[pathSegments.length - 1] = categorySlug;
152
150
  baseUrl = "/" + pathSegments.join("/");
153
151
  }
154
152
  else {
155
- // Append category path to existing base
156
- baseUrl = baseUrl.endsWith("/")
157
- ? `${baseUrl}category/${categorySlug}`
158
- : `${baseUrl}/category/${categorySlug}`;
153
+ // If no segments, just use the category slug
154
+ baseUrl = `/${categorySlug}`;
159
155
  }
160
156
  }
161
157
  // Build the new URL
@@ -168,9 +164,33 @@ function updateUrlWithSearchState(searchState) {
168
164
  }
169
165
  }
170
166
  /**
171
- * Parse URL and build complete search options with all filters, sort, and pagination
167
+ * Parse URL and build complete search options with all filters, sort, and pagination.
168
+ * This function extracts search parameters, filters, sorting, and pagination from a URL
169
+ * and converts them into the format expected by the Wix Stores API.
170
+ *
171
+ * @param {string} url - The URL to parse search parameters from
172
+ * @param {Category[]} categoriesList - List of available categories for category slug resolution
173
+ * @param {productsV3.V3ProductSearch} [defaultSearchOptions] - Default search options to merge with parsed URL parameters
174
+ * @returns {Promise<{searchOptions: productsV3.V3ProductSearch, initialSearchState: InitialSearchState}>}
175
+ * Object containing both API-ready search options and UI-ready initial state
176
+ *
177
+ * @example
178
+ * ```tsx
179
+ * // Parse URL with filters, sort, and pagination
180
+ * const categories = await loadCategoriesListServiceConfig();
181
+ * const { searchOptions, initialSearchState } = await parseUrlToSearchOptions(
182
+ * 'https://example.com/products?sort=price:desc&Color=red,blue&minPrice=50',
183
+ * categories.categories
184
+ * );
185
+ *
186
+ * // Use searchOptions for API calls
187
+ * const products = await productsV3.searchProducts(searchOptions);
188
+ *
189
+ * // Use initialSearchState for UI initialization
190
+ * const filterState = initialSearchState.productOptions; // { colorId: ['red-id', 'blue-id'] }
191
+ * ```
172
192
  */
173
- export async function parseUrlForProductsListSearch(url, categoriesList, defaultSearchOptions) {
193
+ export async function parseUrlToSearchOptions(url, categoriesList, defaultSearchOptions) {
174
194
  const urlObj = new URL(url);
175
195
  const searchParams = urlObj.searchParams;
176
196
  // Get customizations for product option parsing
@@ -403,12 +423,52 @@ export async function parseUrlForProductsListSearch(url, categoriesList, default
403
423
  return { searchOptions, initialSearchState };
404
424
  }
405
425
  /**
406
- * Load search service configuration from URL
426
+ * Load search service configuration from URL or parsed URL result.
427
+ * This function provides the configuration for the Products List Search service,
428
+ * including customizations and initial search state.
429
+ *
430
+ * @param {string | { searchOptions: productsV3.V3ProductSearch; initialSearchState: InitialSearchState }} input - Either a URL to parse or parsed URL result from parseUrlToSearchOptions
431
+ * @returns {Promise<ProductsListSearchServiceConfig>} Promise that resolves to the search service configuration
432
+ *
433
+ * @example
434
+ * ```tsx
435
+ * // Option 1: Load from URL (will parse filters, sort, pagination from URL params)
436
+ * const searchConfig = await loadProductsListSearchServiceConfig(window.location.href);
437
+ *
438
+ * // Option 2: Custom parsing with defaults
439
+ * const categories = await loadCategoriesListServiceConfig();
440
+ * const parsed = await parseUrlToSearchOptions(
441
+ * window.location.href,
442
+ * categories.categories,
443
+ * {
444
+ * cursorPaging: { limit: 12 },
445
+ * filter: { 'categoryIds': ['123'] },
446
+ * sort: [{ fieldName: 'name' as const, order: 'ASC' as const }]
447
+ * }
448
+ * );
449
+ * const searchConfig = await loadProductsListSearchServiceConfig(parsed);
450
+ *
451
+ * // Option 3: Performance optimization - use parsed result for both services (no duplicate parsing)
452
+ * const categories = await loadCategoriesListServiceConfig();
453
+ * const parsed = await parseUrlToSearchOptions(url, categories.categories);
454
+ * const [productsConfig, searchConfig] = await Promise.all([
455
+ * loadProductsListServiceConfig(parsed),
456
+ * loadProductsListSearchServiceConfig(parsed),
457
+ * ]);
458
+ * ```
407
459
  */
408
- export async function loadProductsListSearchServiceConfig(url) {
409
- // Load categories using the categories service
410
- const categoriesListConfig = await loadCategoriesListServiceConfig();
411
- const { initialSearchState } = await parseUrlForProductsListSearch(url, categoriesListConfig.categories);
460
+ export async function loadProductsListSearchServiceConfig(input) {
461
+ let initialSearchState;
462
+ if (typeof input === 'string') {
463
+ // URL input - parse it
464
+ const categoriesListConfig = await loadCategoriesListServiceConfig();
465
+ const { initialSearchState: parsedState } = await parseUrlToSearchOptions(input, categoriesListConfig.categories);
466
+ initialSearchState = parsedState;
467
+ }
468
+ else {
469
+ // Parsed URL result - use initialSearchState directly (no duplicate work)
470
+ initialSearchState = input.initialSearchState;
471
+ }
412
472
  const { items: customizations = [] } = await customizationsV3
413
473
  .queryCustomizations()
414
474
  .find();
@@ -1,5 +1,6 @@
1
1
  import { type Signal } from "@wix/services-definitions/core-services/signals";
2
2
  import { productsV3 } from "@wix/stores";
3
+ import { type InitialSearchState } from "./products-list-search-service.js";
3
4
  export declare const DEFAULT_QUERY_LIMIT = 100;
4
5
  /**
5
6
  * Configuration interface for the Products List service.
@@ -20,27 +21,33 @@ export type ProductsListServiceConfig = {
20
21
  /**
21
22
  * Loads products list service configuration from the Wix Stores API for SSR initialization.
22
23
  * This function is designed to be used during Server-Side Rendering (SSR) to preload
23
- * a list of products based on search criteria.
24
+ * a list of products based on search criteria or URL parameters.
24
25
  *
25
- * @param {productsV3.V3ProductSearch} searchOptions - The search options for querying products
26
+ * @param {string | { searchOptions: productsV3.V3ProductSearch; initialSearchState: InitialSearchState }} input - Either a URL to parse or parsed URL result from parseUrlToSearchOptions
26
27
  * @returns {Promise<ProductsListServiceConfig>} Promise that resolves to the products list configuration
27
28
  *
28
29
  * @example
29
30
  * ```astro
30
31
  * ---
31
32
  * // Astro page example - pages/products.astro
32
- * import { loadProductsListServiceConfig } from '@wix/stores/services';
33
+ * import { loadProductsListServiceConfig, parseUrlToSearchOptions, loadCategoriesListServiceConfig } from '@wix/stores/services';
33
34
  * import { ProductList } from '@wix/stores/components';
34
35
  *
35
- * // Define search options
36
- * const searchOptions = {
37
- * cursorPaging: { limit: 12 },
38
- * filter: {},
39
- * sort: [{ fieldName: 'name', order: 'ASC' }]
40
- * };
36
+ * // Option 1: Load from URL (will parse filters, sort, pagination from URL params)
37
+ * const productsConfig = await loadProductsListServiceConfig(Astro.url.href);
41
38
  *
42
- * // Load products data during SSR
43
- * const productsConfig = await loadProductsListServiceConfig(searchOptions);
39
+ * // Option 2: Custom parsing with defaults
40
+ * const categories = await loadCategoriesListServiceConfig();
41
+ * const parsed = await parseUrlToSearchOptions(
42
+ * Astro.url.href,
43
+ * categories.categories,
44
+ * {
45
+ * cursorPaging: { limit: 12 },
46
+ * filter: {},
47
+ * sort: [{ fieldName: 'name' as const, order: 'ASC' as const }]
48
+ * }
49
+ * );
50
+ * const productsConfig = await loadProductsListServiceConfig(parsed);
44
51
  * ---
45
52
  *
46
53
  * <ProductList.Root productsConfig={productsConfig}>
@@ -59,23 +66,31 @@ export type ProductsListServiceConfig = {
59
66
  * ```tsx
60
67
  * // Next.js page example - pages/products.tsx
61
68
  * import { GetServerSideProps } from 'next';
62
- * import { loadProductsListServiceConfig } from '@wix/stores/services';
69
+ * import { loadProductsListServiceConfig, parseUrlToSearchOptions, loadCategoriesListServiceConfig } from '@wix/stores/services';
63
70
  * import { ProductsList } from '@wix/stores/components';
64
71
  *
65
72
  * interface ProductsPageProps {
66
73
  * productsConfig: Awaited<ReturnType<typeof loadProductsListServiceConfig>>;
67
74
  * }
68
75
  *
69
- * export const getServerSideProps: GetServerSideProps<ProductsPageProps> = async () => {
70
- * const searchOptions = {
71
- * cursorPaging: { limit: 12 },
72
- * filter: {
73
- * 'allCategoriesInfo.categories': { $matchItems: [{ _id: { $in: [category._id] } }] }
74
- * },
75
- * sort: [{ fieldName: 'name' as const, order: 'ASC' as const }]
76
- * };
76
+ * export const getServerSideProps: GetServerSideProps<ProductsPageProps> = async ({ req }) => {
77
+ * // Option 1: Parse from URL
78
+ * const productsConfig = await loadProductsListServiceConfig(`${req.url}`);
77
79
  *
78
- * const productsConfig = await loadProductsListServiceConfig(searchOptions);
80
+ * // Option 2: Custom parsing with filters
81
+ * const categories = await loadCategoriesListServiceConfig();
82
+ * const parsed = await parseUrlToSearchOptions(
83
+ * `${req.url}`,
84
+ * categories.categories,
85
+ * {
86
+ * cursorPaging: { limit: 12 },
87
+ * filter: {
88
+ * 'allCategoriesInfo.categories': { $matchItems: [{ _id: { $in: [category._id] } }] }
89
+ * },
90
+ * sort: [{ fieldName: 'name' as const, order: 'ASC' as const }]
91
+ * }
92
+ * );
93
+ * const productsConfig = await loadProductsListServiceConfig(parsed);
79
94
  *
80
95
  * return {
81
96
  * props: {
@@ -99,8 +114,26 @@ export type ProductsListServiceConfig = {
99
114
  * );
100
115
  * }
101
116
  * ```
117
+ *
118
+ * @example
119
+ * ```tsx
120
+ * // Advanced: Performance optimization when using both services
121
+ * import { parseUrlToSearchOptions, loadProductsListServiceConfig, loadProductsListSearchServiceConfig, loadCategoriesListServiceConfig } from '@wix/stores/services';
122
+ *
123
+ * const categories = await loadCategoriesListServiceConfig();
124
+ * const parsed = await parseUrlToSearchOptions(url, categories.categories);
125
+ *
126
+ * // Both services use the same parsed result (no duplicate URL parsing)
127
+ * const [productsConfig, searchConfig] = await Promise.all([
128
+ * loadProductsListServiceConfig(parsed),
129
+ * loadProductsListSearchServiceConfig(parsed)
130
+ * ]);
131
+ * ```
102
132
  */
103
- export declare function loadProductsListServiceConfig(searchOptions: productsV3.V3ProductSearch): Promise<ProductsListServiceConfig>;
133
+ export declare function loadProductsListServiceConfig(input: string | {
134
+ searchOptions: productsV3.V3ProductSearch;
135
+ initialSearchState: InitialSearchState;
136
+ }): Promise<ProductsListServiceConfig>;
104
137
  /**
105
138
  * Service definition for the Products List service.
106
139
  * This defines the reactive API contract for managing a list of products with search, pagination, and filtering capabilities.
@@ -1,31 +1,39 @@
1
1
  import { defineService, implementService } from "@wix/services-definitions";
2
2
  import { SignalsServiceDefinition, } from "@wix/services-definitions/core-services/signals";
3
3
  import { productsV3, readOnlyVariantsV3 } from "@wix/stores";
4
+ import { loadCategoriesListServiceConfig } from "./categories-list-service.js";
5
+ import { parseUrlToSearchOptions } from "./products-list-search-service.js";
4
6
  export const DEFAULT_QUERY_LIMIT = 100;
5
7
  /**
6
8
  * Loads products list service configuration from the Wix Stores API for SSR initialization.
7
9
  * This function is designed to be used during Server-Side Rendering (SSR) to preload
8
- * a list of products based on search criteria.
10
+ * a list of products based on search criteria or URL parameters.
9
11
  *
10
- * @param {productsV3.V3ProductSearch} searchOptions - The search options for querying products
12
+ * @param {string | { searchOptions: productsV3.V3ProductSearch; initialSearchState: InitialSearchState }} input - Either a URL to parse or parsed URL result from parseUrlToSearchOptions
11
13
  * @returns {Promise<ProductsListServiceConfig>} Promise that resolves to the products list configuration
12
14
  *
13
15
  * @example
14
16
  * ```astro
15
17
  * ---
16
18
  * // Astro page example - pages/products.astro
17
- * import { loadProductsListServiceConfig } from '@wix/stores/services';
19
+ * import { loadProductsListServiceConfig, parseUrlToSearchOptions, loadCategoriesListServiceConfig } from '@wix/stores/services';
18
20
  * import { ProductList } from '@wix/stores/components';
19
21
  *
20
- * // Define search options
21
- * const searchOptions = {
22
- * cursorPaging: { limit: 12 },
23
- * filter: {},
24
- * sort: [{ fieldName: 'name', order: 'ASC' }]
25
- * };
22
+ * // Option 1: Load from URL (will parse filters, sort, pagination from URL params)
23
+ * const productsConfig = await loadProductsListServiceConfig(Astro.url.href);
26
24
  *
27
- * // Load products data during SSR
28
- * const productsConfig = await loadProductsListServiceConfig(searchOptions);
25
+ * // Option 2: Custom parsing with defaults
26
+ * const categories = await loadCategoriesListServiceConfig();
27
+ * const parsed = await parseUrlToSearchOptions(
28
+ * Astro.url.href,
29
+ * categories.categories,
30
+ * {
31
+ * cursorPaging: { limit: 12 },
32
+ * filter: {},
33
+ * sort: [{ fieldName: 'name' as const, order: 'ASC' as const }]
34
+ * }
35
+ * );
36
+ * const productsConfig = await loadProductsListServiceConfig(parsed);
29
37
  * ---
30
38
  *
31
39
  * <ProductList.Root productsConfig={productsConfig}>
@@ -44,23 +52,31 @@ export const DEFAULT_QUERY_LIMIT = 100;
44
52
  * ```tsx
45
53
  * // Next.js page example - pages/products.tsx
46
54
  * import { GetServerSideProps } from 'next';
47
- * import { loadProductsListServiceConfig } from '@wix/stores/services';
55
+ * import { loadProductsListServiceConfig, parseUrlToSearchOptions, loadCategoriesListServiceConfig } from '@wix/stores/services';
48
56
  * import { ProductsList } from '@wix/stores/components';
49
57
  *
50
58
  * interface ProductsPageProps {
51
59
  * productsConfig: Awaited<ReturnType<typeof loadProductsListServiceConfig>>;
52
60
  * }
53
61
  *
54
- * export const getServerSideProps: GetServerSideProps<ProductsPageProps> = async () => {
55
- * const searchOptions = {
56
- * cursorPaging: { limit: 12 },
57
- * filter: {
58
- * 'allCategoriesInfo.categories': { $matchItems: [{ _id: { $in: [category._id] } }] }
59
- * },
60
- * sort: [{ fieldName: 'name' as const, order: 'ASC' as const }]
61
- * };
62
+ * export const getServerSideProps: GetServerSideProps<ProductsPageProps> = async ({ req }) => {
63
+ * // Option 1: Parse from URL
64
+ * const productsConfig = await loadProductsListServiceConfig(`${req.url}`);
62
65
  *
63
- * const productsConfig = await loadProductsListServiceConfig(searchOptions);
66
+ * // Option 2: Custom parsing with filters
67
+ * const categories = await loadCategoriesListServiceConfig();
68
+ * const parsed = await parseUrlToSearchOptions(
69
+ * `${req.url}`,
70
+ * categories.categories,
71
+ * {
72
+ * cursorPaging: { limit: 12 },
73
+ * filter: {
74
+ * 'allCategoriesInfo.categories': { $matchItems: [{ _id: { $in: [category._id] } }] }
75
+ * },
76
+ * sort: [{ fieldName: 'name' as const, order: 'ASC' as const }]
77
+ * }
78
+ * );
79
+ * const productsConfig = await loadProductsListServiceConfig(parsed);
64
80
  *
65
81
  * return {
66
82
  * props: {
@@ -84,8 +100,34 @@ export const DEFAULT_QUERY_LIMIT = 100;
84
100
  * );
85
101
  * }
86
102
  * ```
103
+ *
104
+ * @example
105
+ * ```tsx
106
+ * // Advanced: Performance optimization when using both services
107
+ * import { parseUrlToSearchOptions, loadProductsListServiceConfig, loadProductsListSearchServiceConfig, loadCategoriesListServiceConfig } from '@wix/stores/services';
108
+ *
109
+ * const categories = await loadCategoriesListServiceConfig();
110
+ * const parsed = await parseUrlToSearchOptions(url, categories.categories);
111
+ *
112
+ * // Both services use the same parsed result (no duplicate URL parsing)
113
+ * const [productsConfig, searchConfig] = await Promise.all([
114
+ * loadProductsListServiceConfig(parsed),
115
+ * loadProductsListSearchServiceConfig(parsed)
116
+ * ]);
117
+ * ```
87
118
  */
88
- export async function loadProductsListServiceConfig(searchOptions) {
119
+ export async function loadProductsListServiceConfig(input) {
120
+ let searchOptions;
121
+ if (typeof input === 'string') {
122
+ // URL input - parse it
123
+ const categoriesListConfig = await loadCategoriesListServiceConfig();
124
+ const { searchOptions: parsedOptions } = await parseUrlToSearchOptions(input, categoriesListConfig.categories);
125
+ searchOptions = parsedOptions;
126
+ }
127
+ else {
128
+ // Parsed URL result - use searchOptions directly
129
+ searchOptions = input.searchOptions;
130
+ }
89
131
  const searchWithoutFilter = { ...searchOptions, filter: {} };
90
132
  const [resultWithoutFilter, resultWithFilter] = await Promise.all([
91
133
  fetchProducts(searchWithoutFilter),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/headless-stores",
3
- "version": "0.0.47",
3
+ "version": "0.0.49",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "prebuild": "cd ../media && yarn build && cd ../ecom && yarn build",