@wix/headless-stores 0.0.48 → 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.
- package/cjs/dist/services/index.d.ts +1 -1
- package/cjs/dist/services/index.js +1 -1
- package/cjs/dist/services/products-list-search-service.d.ts +64 -5
- package/cjs/dist/services/products-list-search-service.js +71 -7
- package/cjs/dist/services/products-list-service.d.ts +55 -22
- package/cjs/dist/services/products-list-service.js +64 -22
- package/dist/services/index.d.ts +1 -1
- package/dist/services/index.js +1 -1
- package/dist/services/products-list-search-service.d.ts +64 -5
- package/dist/services/products-list-search-service.js +71 -7
- package/dist/services/products-list-service.d.ts +55 -22
- package/dist/services/products-list-service.js +64 -22
- package/package.json +1 -1
|
@@ -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,
|
|
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,
|
|
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
|
|
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(
|
|
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
|
*/
|
|
@@ -164,9 +164,33 @@ function updateUrlWithSearchState(searchState) {
|
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
166
|
/**
|
|
167
|
-
* 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
|
+
* ```
|
|
168
192
|
*/
|
|
169
|
-
export async function
|
|
193
|
+
export async function parseUrlToSearchOptions(url, categoriesList, defaultSearchOptions) {
|
|
170
194
|
const urlObj = new URL(url);
|
|
171
195
|
const searchParams = urlObj.searchParams;
|
|
172
196
|
// Get customizations for product option parsing
|
|
@@ -399,12 +423,52 @@ export async function parseUrlForProductsListSearch(url, categoriesList, default
|
|
|
399
423
|
return { searchOptions, initialSearchState };
|
|
400
424
|
}
|
|
401
425
|
/**
|
|
402
|
-
* 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
|
+
* ```
|
|
403
459
|
*/
|
|
404
|
-
export async function loadProductsListSearchServiceConfig(
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
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
|
+
}
|
|
408
472
|
const { items: customizations = [] } = await customizationsV3
|
|
409
473
|
.queryCustomizations()
|
|
410
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}
|
|
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
|
-
* //
|
|
36
|
-
* const
|
|
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
|
-
* //
|
|
43
|
-
* const
|
|
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
|
-
*
|
|
71
|
-
*
|
|
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
|
-
*
|
|
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(
|
|
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}
|
|
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
|
-
* //
|
|
21
|
-
* const
|
|
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
|
-
* //
|
|
28
|
-
* const
|
|
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
|
-
*
|
|
56
|
-
*
|
|
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
|
-
*
|
|
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(
|
|
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/dist/services/index.d.ts
CHANGED
|
@@ -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,
|
|
7
|
+
export { ProductOption, InventoryStatusType, SortType, ProductChoice, ProductsListSearchService, ProductsListSearchServiceDefinition, ProductsListSearchServiceConfig, loadProductsListSearchServiceConfig, parseUrlToSearchOptions, convertUrlSortToSortType, } from "./products-list-search-service.js";
|
package/dist/services/index.js
CHANGED
|
@@ -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,
|
|
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
|
|
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(
|
|
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
|
*/
|
|
@@ -164,9 +164,33 @@ function updateUrlWithSearchState(searchState) {
|
|
|
164
164
|
}
|
|
165
165
|
}
|
|
166
166
|
/**
|
|
167
|
-
* 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
|
+
* ```
|
|
168
192
|
*/
|
|
169
|
-
export async function
|
|
193
|
+
export async function parseUrlToSearchOptions(url, categoriesList, defaultSearchOptions) {
|
|
170
194
|
const urlObj = new URL(url);
|
|
171
195
|
const searchParams = urlObj.searchParams;
|
|
172
196
|
// Get customizations for product option parsing
|
|
@@ -399,12 +423,52 @@ export async function parseUrlForProductsListSearch(url, categoriesList, default
|
|
|
399
423
|
return { searchOptions, initialSearchState };
|
|
400
424
|
}
|
|
401
425
|
/**
|
|
402
|
-
* 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
|
+
* ```
|
|
403
459
|
*/
|
|
404
|
-
export async function loadProductsListSearchServiceConfig(
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
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
|
+
}
|
|
408
472
|
const { items: customizations = [] } = await customizationsV3
|
|
409
473
|
.queryCustomizations()
|
|
410
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}
|
|
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
|
-
* //
|
|
36
|
-
* const
|
|
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
|
-
* //
|
|
43
|
-
* const
|
|
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
|
-
*
|
|
71
|
-
*
|
|
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
|
-
*
|
|
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(
|
|
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}
|
|
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
|
-
* //
|
|
21
|
-
* const
|
|
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
|
-
* //
|
|
28
|
-
* const
|
|
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
|
-
*
|
|
56
|
-
*
|
|
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
|
-
*
|
|
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(
|
|
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),
|