@faststore/core 3.32.0 → 3.33.0

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.
Files changed (86) hide show
  1. package/.next/BUILD_ID +1 -1
  2. package/.next/build-manifest.json +27 -27
  3. package/.next/cache/.tsbuildinfo +1 -1
  4. package/.next/cache/config.json +3 -3
  5. package/.next/cache/webpack/client-production/0.pack +0 -0
  6. package/.next/cache/webpack/client-production/index.pack +0 -0
  7. package/.next/cache/webpack/server-production/0.pack +0 -0
  8. package/.next/cache/webpack/server-production/index.pack +0 -0
  9. package/.next/prerender-manifest.js +1 -1
  10. package/.next/prerender-manifest.json +1 -1
  11. package/.next/react-loadable-manifest.json +3 -3
  12. package/.next/routes-manifest.json +1 -1
  13. package/.next/server/chunks/{2409.js → 1650.js} +2 -2
  14. package/.next/server/chunks/3117.js +2 -2
  15. package/.next/server/chunks/4289.js +3 -3
  16. package/.next/server/chunks/{3080.js → 7819.js} +2 -2
  17. package/.next/server/chunks/9594.js +1 -0
  18. package/.next/server/middleware-build-manifest.js +1 -1
  19. package/.next/server/middleware-react-loadable-manifest.js +1 -1
  20. package/.next/server/pages/404.js +1 -1
  21. package/.next/server/pages/404.js.nft.json +1 -1
  22. package/.next/server/pages/500.js +1 -1
  23. package/.next/server/pages/500.js.nft.json +1 -1
  24. package/.next/server/pages/[...slug].js +1 -1
  25. package/.next/server/pages/[...slug].js.nft.json +1 -1
  26. package/.next/server/pages/[slug]/p.js +1 -1
  27. package/.next/server/pages/[slug]/p.js.nft.json +1 -1
  28. package/.next/server/pages/_app.js +1 -1
  29. package/.next/server/pages/_app.js.nft.json +1 -1
  30. package/.next/server/pages/_document.js.nft.json +1 -1
  31. package/.next/server/pages/_error.js +1 -1
  32. package/.next/server/pages/_error.js.nft.json +1 -1
  33. package/.next/server/pages/account.js +1 -1
  34. package/.next/server/pages/account.js.nft.json +1 -1
  35. package/.next/server/pages/api/graphql.js +1 -1
  36. package/.next/server/pages/api/graphql.js.nft.json +1 -1
  37. package/.next/server/pages/api/health/live.js.nft.json +1 -1
  38. package/.next/server/pages/api/health/ready.js.nft.json +1 -1
  39. package/.next/server/pages/api/preview.js.nft.json +1 -1
  40. package/.next/server/pages/checkout.js +1 -1
  41. package/.next/server/pages/checkout.js.nft.json +1 -1
  42. package/.next/server/pages/en-US/404.html +2 -2
  43. package/.next/server/pages/en-US/500.html +2 -2
  44. package/.next/server/pages/en-US/account.html +2 -2
  45. package/.next/server/pages/en-US/checkout.html +2 -2
  46. package/.next/server/pages/en-US/login.html +2 -2
  47. package/.next/server/pages/en-US/s.html +2 -2
  48. package/.next/server/pages/en-US.html +2 -2
  49. package/.next/server/pages/en-US.json +1 -1
  50. package/.next/server/pages/index.js +1 -1
  51. package/.next/server/pages/index.js.nft.json +1 -1
  52. package/.next/server/pages/login.js +1 -1
  53. package/.next/server/pages/login.js.nft.json +1 -1
  54. package/.next/server/pages/s.js +1 -1
  55. package/.next/server/pages/s.js.nft.json +1 -1
  56. package/.next/server/pages-manifest.json +1 -1
  57. package/.next/static/{gfAtPTIXPKnCvUoAN_678 → a8pMv59FUKRCJcUKLEXkQ}/_buildManifest.js +1 -1
  58. package/.next/static/chunks/{3143.42eed67e0a406af4.js → 3143.1aaec7f4a9e83b8d.js} +1 -1
  59. package/.next/static/chunks/4625-4befc256b42bee75.js +1 -0
  60. package/.next/static/chunks/{6335-204d54a0bbb62580.js → 6335-2bf379c0870c440e.js} +1 -1
  61. package/.next/static/chunks/{CartSidebar.b92033a45cbd5b1e.js → CartSidebar.11e73132b1647eec.js} +1 -1
  62. package/.next/static/chunks/pages/[...slug]-f4fd6c8d7dc53f8f.js +1 -0
  63. package/.next/static/chunks/pages/{_app-ac95c1e9f24267d5.js → _app-e03902a5f8bdaf99.js} +1 -1
  64. package/.next/static/chunks/pages/{s-3d8b314cdd548782.js → s-ffb46af7067b79b1.js} +1 -1
  65. package/.next/static/chunks/{webpack-505ab169c34dcfac.js → webpack-1965210fb17803bd.js} +1 -1
  66. package/.next/trace +122 -121
  67. package/.turbo/turbo-build.log +11 -12
  68. package/.turbo/turbo-test.log +5 -6
  69. package/@generated/gql.ts +8 -0
  70. package/@generated/graphql.ts +62 -0
  71. package/@generated/persisted-documents.json +2 -1
  72. package/CHANGELOG.md +12 -0
  73. package/next-seo.config.ts +3 -0
  74. package/package.json +3 -2
  75. package/src/components/templates/ProductListingPage/ProductListing.tsx +24 -7
  76. package/src/components/templates/ProductListingPage/ProductListingPage.tsx +23 -3
  77. package/src/pages/[...slug].tsx +20 -2
  78. package/src/sdk/product/usePageProductsQuery.ts +36 -11
  79. package/src/sdk/product/useProductGalleryQuery.ts +75 -33
  80. package/src/sdk/product/useShouldFetchFirstPage.ts +60 -0
  81. package/src/sdk/redirects/index.ts +8 -0
  82. package/src/utils/fetchProductGallerySSR.ts +121 -0
  83. package/.next/server/chunks/1168.js +0 -1
  84. package/.next/static/chunks/5018-4af021881b60619a.js +0 -1
  85. package/.next/static/chunks/pages/[...slug]-fdede686dea7b909.js +0 -1
  86. /package/.next/static/{gfAtPTIXPKnCvUoAN_678 → a8pMv59FUKRCJcUKLEXkQ}/_ssgManifest.js +0 -0
@@ -1,23 +1,23 @@
1
1
 
2
- > @faststore/core@3.31.0 prebuild /home/runner/work/faststore/faststore/packages/core
2
+ > @faststore/core@3.32.1 prebuild /home/runner/work/faststore/faststore/packages/core
3
3
  > na run partytown && na run generate
4
4
 
5
5
 
6
- > @faststore/core@3.31.0 partytown /home/runner/work/faststore/faststore/packages/core
6
+ > @faststore/core@3.32.1 partytown /home/runner/work/faststore/faststore/packages/core
7
7
  > partytown copylib ./public/~partytown
8
8
 
9
9
  Partytown lib copied to: /home/runner/work/faststore/faststore/packages/core/public/~partytown
10
10
 
11
- > @faststore/core@3.31.0 generate /home/runner/work/faststore/faststore/packages/core
11
+ > @faststore/core@3.32.1 generate /home/runner/work/faststore/faststore/packages/core
12
12
  > na run generate:schema && na run generate:codegen && na run format:generated
13
13
 
14
14
 
15
- > @faststore/core@3.31.0 generate:schema /home/runner/work/faststore/faststore/packages/core
15
+ > @faststore/core@3.32.1 generate:schema /home/runner/work/faststore/faststore/packages/core
16
16
  > tsx src/server/generator/generateGraphQLSchemaFile.ts
17
17
 
18
18
  Schema GraphQL file generated successfully
19
19
 
20
- > @faststore/core@3.31.0 generate:codegen /home/runner/work/faststore/faststore/packages/core
20
+ > @faststore/core@3.32.1 generate:codegen /home/runner/work/faststore/faststore/packages/core
21
21
  > graphql-codegen
22
22
 
23
23
  [STARTED] Parse Configuration
@@ -37,11 +37,11 @@ Running lifecycle hook "afterStart" scripts...
37
37
  [CLI] Loading Documents
38
38
  [CLI] Generating output
39
39
 
40
- > @faststore/core@3.31.0 format:generated /home/runner/work/faststore/faststore/packages/core
40
+ > @faststore/core@3.32.1 format:generated /home/runner/work/faststore/faststore/packages/core
41
41
  > prettier --write "@generated/**/*.{ts,js,tsx,jsx,json}" --loglevel error
42
42
 
43
43
 
44
- > @faststore/core@3.31.0 build /home/runner/work/faststore/faststore/packages/core
44
+ > @faststore/core@3.32.1 build /home/runner/work/faststore/faststore/packages/core
45
45
  > next build
46
46
 
47
47
  ⚠ No build cache found. Please configure build caching for faster rebuilds. Read more: https://nextjs.org/docs/messages/no-cache
@@ -62,7 +62,6 @@ https://nextjs.org/telemetry
62
62
  Warning: Dynamic Content not found for the page: home. Refer to the Dynamic Content documentation at https://developers.vtex.com/docs/guides/faststore/dynamic-content-overview for mapping the page and the corresponding data-fetching function.
63
63
 
64
64
  Generating static pages (3/7)
65
65
 
66
66
  Generating static pages (5/7)
67
- CustomModalFooterSection not found. Add a new component for this section or remove it from the CMS
68
67
 
69
68
  ✓ Generating static pages (7/7)
70
69
  Finalizing page optimization ...
71
70
  Collecting build traces ...
@@ -71,7 +70,7 @@ Route (pages) Size First Load JS
71
70
  ┌ ● / 3.86 kB 124 kB
72
71
  ├ └ css/b1806cbafd0c1f81.css 3.06 kB
73
72
  ├ /_app 0 B 92.3 kB
74
- ├ ● /[...slug] 2.14 kB 132 kB
73
+ ├ ● /[...slug] 2.34 kB 133 kB
75
74
  ├ ● /[slug]/p 35.5 kB 156 kB
76
75
  ├ ├ css/a3ca6a9b63f657be.css 5.75 kB
77
76
  ├ ├ css/62a5153ac7061286.css 6.11 kB
@@ -85,12 +84,12 @@ Route (pages) Size First Load JS
85
84
  ├ λ /api/preview 0 B 92.3 kB
86
85
  ├ ● /checkout 694 B 121 kB
87
86
  ├ ● /login 1.59 kB 122 kB
88
- └ ● /s 3.18 kB 133 kB
87
+ └ ● /s 3.18 kB 134 kB
89
88
  + First Load JS shared by all 95.8 kB
90
89
  ├ chunks/framework-807b0f81cbc129f0.js 45.4 kB
91
90
  ├ chunks/main-5569625b3fdd6741.js 33.1 kB
92
- ├ chunks/pages/_app-ac95c1e9f24267d5.js 10.3 kB
93
- ├ chunks/webpack-505ab169c34dcfac.js 3.58 kB
91
+ ├ chunks/pages/_app-e03902a5f8bdaf99.js 10.3 kB
92
+ ├ chunks/webpack-1965210fb17803bd.js 3.58 kB
94
93
  └ css/0a57ee6c7a57788c.css 3.49 kB
95
94
 
96
95
  λ (Server) server-side renders at runtime (uses getInitialProps or getServerSideProps)
@@ -1,15 +1,14 @@
1
1
 
2
- > @faststore/core@3.31.0 test /home/runner/work/faststore/faststore/packages/core
2
+ > @faststore/core@3.32.1 test /home/runner/work/faststore/faststore/packages/core
3
3
  > jest
4
4
 
5
- PASS test/server/cms/global.test.ts (23.995 s)
6
- PASS test/utils/multipleTemplates.test.ts (24.181 s)
5
+ PASS test/utils/multipleTemplates.test.ts (24.455 s)
6
+ PASS test/server/cms/global.test.ts (24.572 s)
7
7
  PASS test/server/cms/index.test.ts
8
- PASS test/server/index.test.ts (28.653 s)
9
- A worker process has failed to exit gracefully and has been force exited. This is likely caused by tests leaking due to improper teardown. Try running with --detectOpenHandles to find leaks. Active timers can also cause this, ensure that .unref() was called on them.
8
+ PASS test/server/index.test.ts (29.791 s)
10
9
 
11
10
  Test Suites: 4 passed, 4 total
12
11
  Tests: 22 passed, 22 total
13
12
  Snapshots: 0 total
14
- Time: 30.014 s
13
+ Time: 31.107 s
15
14
  Ran all test suites.
package/@generated/gql.ts CHANGED
@@ -60,6 +60,8 @@ const documents = {
60
60
  types.ValidateSessionDocument,
61
61
  '\n query ClientShippingSimulationQuery(\n $postalCode: String!\n $country: String!\n $items: [IShippingItem!]!\n ) {\n ...ClientShippingSimulation\n shipping(items: $items, postalCode: $postalCode, country: $country) {\n logisticsInfo {\n slas {\n carrier\n price\n availableDeliveryWindows {\n startDateUtc\n endDateUtc\n price\n listPrice\n }\n shippingEstimate\n localizedEstimates\n deliveryChannel\n }\n }\n address {\n city\n neighborhood\n state\n }\n }\n }\n':
62
62
  types.ClientShippingSimulationQueryDocument,
63
+ '\n query ServerManyProductsQuery(\n $first: Int!\n $after: String\n $sort: StoreSort!\n $term: String!\n $selectedFacets: [IStoreSelectedFacet!]!\n $sponsoredCount: Int\n ) {\n ...ClientManyProducts\n search(\n first: $first\n after: $after\n sort: $sort\n term: $term\n selectedFacets: $selectedFacets\n sponsoredCount: $sponsoredCount\n ) {\n products {\n pageInfo {\n totalCount\n }\n edges {\n node {\n ...ProductSummary_product\n }\n }\n }\n metadata {\n ...SearchEvent_metadata\n }\n }\n }\n':
64
+ types.ServerManyProductsQueryDocument,
63
65
  }
64
66
 
65
67
  /**
@@ -206,6 +208,12 @@ export function gql(
206
208
  export function gql(
207
209
  source: '\n query ClientShippingSimulationQuery(\n $postalCode: String!\n $country: String!\n $items: [IShippingItem!]!\n ) {\n ...ClientShippingSimulation\n shipping(items: $items, postalCode: $postalCode, country: $country) {\n logisticsInfo {\n slas {\n carrier\n price\n availableDeliveryWindows {\n startDateUtc\n endDateUtc\n price\n listPrice\n }\n shippingEstimate\n localizedEstimates\n deliveryChannel\n }\n }\n address {\n city\n neighborhood\n state\n }\n }\n }\n'
208
210
  ): typeof import('./graphql').ClientShippingSimulationQueryDocument
211
+ /**
212
+ * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
213
+ */
214
+ export function gql(
215
+ source: '\n query ServerManyProductsQuery(\n $first: Int!\n $after: String\n $sort: StoreSort!\n $term: String!\n $selectedFacets: [IStoreSelectedFacet!]!\n $sponsoredCount: Int\n ) {\n ...ClientManyProducts\n search(\n first: $first\n after: $after\n sort: $sort\n term: $term\n selectedFacets: $selectedFacets\n sponsoredCount: $sponsoredCount\n ) {\n products {\n pageInfo {\n totalCount\n }\n edges {\n node {\n ...ProductSummary_product\n }\n }\n }\n metadata {\n ...SearchEvent_metadata\n }\n }\n }\n'
216
+ ): typeof import('./graphql').ServerManyProductsQueryDocument
209
217
 
210
218
  export function gql(source: string) {
211
219
  return (documents as any)[source] ?? {}
@@ -1848,6 +1848,59 @@ export type ClientShippingSimulationQueryQuery = {
1848
1848
  } | null
1849
1849
  }
1850
1850
 
1851
+ export type ServerManyProductsQueryQueryVariables = Exact<{
1852
+ first: Scalars['Int']['input']
1853
+ after: InputMaybe<Scalars['String']['input']>
1854
+ sort: StoreSort
1855
+ term: Scalars['String']['input']
1856
+ selectedFacets: Array<IStoreSelectedFacet> | IStoreSelectedFacet
1857
+ sponsoredCount: InputMaybe<Scalars['Int']['input']>
1858
+ }>
1859
+
1860
+ export type ServerManyProductsQueryQuery = {
1861
+ search: {
1862
+ products: {
1863
+ pageInfo: { totalCount: number }
1864
+ edges: Array<{
1865
+ node: {
1866
+ slug: string
1867
+ sku: string
1868
+ name: string
1869
+ gtin: string
1870
+ id: string
1871
+ brand: { name: string; brandName: string }
1872
+ isVariantOf: { productGroupID: string; name: string }
1873
+ image: Array<{ url: string; alternateName: string }>
1874
+ offers: {
1875
+ lowPrice: number
1876
+ lowPriceWithTaxes: number
1877
+ offers: Array<{
1878
+ availability: string
1879
+ price: number
1880
+ listPrice: number
1881
+ listPriceWithTaxes: number
1882
+ quantity: number
1883
+ seller: { identifier: string }
1884
+ }>
1885
+ }
1886
+ additionalProperty: Array<{
1887
+ propertyID: string
1888
+ name: string
1889
+ value: any
1890
+ valueReference: any
1891
+ }>
1892
+ advertisement: { adId: string; adResponseId: string } | null
1893
+ }
1894
+ }>
1895
+ }
1896
+ metadata: {
1897
+ isTermMisspelled: boolean
1898
+ logicalOperator: string
1899
+ fuzzy: string | null
1900
+ } | null
1901
+ }
1902
+ }
1903
+
1851
1904
  export class TypedDocumentString<TResult, TVariables>
1852
1905
  extends String
1853
1906
  implements DocumentTypeDecoration<TResult, TVariables>
@@ -2394,3 +2447,12 @@ export const ClientShippingSimulationQueryDocument = {
2394
2447
  ClientShippingSimulationQueryQuery,
2395
2448
  ClientShippingSimulationQueryQueryVariables
2396
2449
  >
2450
+ export const ServerManyProductsQueryDocument = {
2451
+ __meta__: {
2452
+ operationName: 'ServerManyProductsQuery',
2453
+ operationHash: '4fa4dfd1233e2ed5b0b3f662e8866a901d481a52',
2454
+ },
2455
+ } as unknown as TypedDocumentString<
2456
+ ServerManyProductsQueryQuery,
2457
+ ServerManyProductsQueryQueryVariables
2458
+ >
@@ -10,5 +10,6 @@
10
10
  "47e48eaee91d16a4237eb2c1241bc2ed3e2ad9bb": "fragment ClientSearchSuggestions on Query { search(first: 5, term: $term, selectedFacets: $selectedFacets) { suggestions { terms { value } } } } fragment ProductSummary_product on StoreProduct { additionalProperty { name propertyID value valueReference } advertisement { adId adResponseId } brand { brandName: name } brand { name } gtin image { alternateName url } isVariantOf { name productGroupID } name offers { lowPrice lowPriceWithTaxes offers { availability listPrice listPriceWithTaxes price quantity seller { identifier } } } id: productID sku slug } fragment SearchEvent_metadata on SearchMetadata { fuzzy isTermMisspelled logicalOperator } query ClientSearchSuggestionsQuery($selectedFacets: [IStoreSelectedFacet!], $term: String!) { search(first: 5, term: $term, selectedFacets: $selectedFacets) { metadata { ...SearchEvent_metadata } products { pageInfo { totalCount } } suggestions { products { ...ProductSummary_product } terms { value } } } ...ClientSearchSuggestions }",
11
11
  "e2385b0f11726d0068f96548f57a8dd441c064e3": "fragment ClientTopSearchSuggestions on Query { search(first: 5, term: $term, selectedFacets: $selectedFacets) { suggestions { terms { value } } } } query ClientTopSearchSuggestionsQuery($selectedFacets: [IStoreSelectedFacet!], $term: String!) { search(first: 5, term: $term, selectedFacets: $selectedFacets) { suggestions { terms { value } } } ...ClientTopSearchSuggestions }",
12
12
  "2c6e94b978eb50647873082daebcc5b332154cb1": "mutation ValidateSession($search: String!, $session: IStoreSession!) { validateSession(session: $session, search: $search) { addressType b2b { customerId } channel country currency { code symbol } deliveryMode { deliveryChannel deliveryMethod deliveryWindow { endDate startDate } } geoCoordinates { latitude longitude } locale marketingData { utmCampaign utmMedium utmSource utmiCampaign utmiPage utmiPart } person { email familyName givenName id } postalCode } }",
13
- "c35bad22f67f3eb34fea52bb49efa6b1da6b728d": "fragment ClientShippingSimulation on Query { shipping(items: $items, postalCode: $postalCode, country: $country) { address { city } } } query ClientShippingSimulationQuery($country: String!, $items: [IShippingItem!]!, $postalCode: String!) { shipping(items: $items, postalCode: $postalCode, country: $country) { address { city neighborhood state } logisticsInfo { slas { availableDeliveryWindows { endDateUtc listPrice price startDateUtc } carrier deliveryChannel localizedEstimates price shippingEstimate } } } ...ClientShippingSimulation }"
13
+ "c35bad22f67f3eb34fea52bb49efa6b1da6b728d": "fragment ClientShippingSimulation on Query { shipping(items: $items, postalCode: $postalCode, country: $country) { address { city } } } query ClientShippingSimulationQuery($country: String!, $items: [IShippingItem!]!, $postalCode: String!) { shipping(items: $items, postalCode: $postalCode, country: $country) { address { city neighborhood state } logisticsInfo { slas { availableDeliveryWindows { endDateUtc listPrice price startDateUtc } carrier deliveryChannel localizedEstimates price shippingEstimate } } } ...ClientShippingSimulation }",
14
+ "4fa4dfd1233e2ed5b0b3f662e8866a901d481a52": "fragment ClientManyProducts on Query { search( first: $first after: $after sort: $sort term: $term selectedFacets: $selectedFacets sponsoredCount: $sponsoredCount ) { products { pageInfo { totalCount } } } } fragment ProductSummary_product on StoreProduct { additionalProperty { name propertyID value valueReference } advertisement { adId adResponseId } brand { brandName: name } brand { name } gtin image { alternateName url } isVariantOf { name productGroupID } name offers { lowPrice lowPriceWithTaxes offers { availability listPrice listPriceWithTaxes price quantity seller { identifier } } } id: productID sku slug } fragment SearchEvent_metadata on SearchMetadata { fuzzy isTermMisspelled logicalOperator } query ServerManyProductsQuery($after: String, $first: Int!, $selectedFacets: [IStoreSelectedFacet!]!, $sort: StoreSort!, $sponsoredCount: Int, $term: String!) { search( first: $first after: $after sort: $sort term: $term selectedFacets: $selectedFacets sponsoredCount: $sponsoredCount ) { metadata { ...SearchEvent_metadata } products { edges { node { ...ProductSummary_product } } pageInfo { totalCount } } } ...ClientManyProducts }"
14
15
  }
package/CHANGELOG.md CHANGED
@@ -3,6 +3,18 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [3.33.0](https://github.com/vtex/faststore/compare/v3.32.1...v3.33.0) (2025-03-31)
7
+
8
+ ### Features
9
+
10
+ - loads first page product gallery from Build Time (getStaticProps) + improve number of requests (+) ([#2721](https://github.com/vtex/faststore/issues/2721)) ([9a74405](https://github.com/vtex/faststore/commit/9a74405b53ce31211e2d5a2c61874a535e47d654)), closes [/github.com/vtex/faststore/blob/47fd98ef2e3380bc2b84f5ff7922068d75077d45/packages/core/src/sdk/product/useShouldFetchFirstPage.ts#L3](https://github.com//github.com/vtex/faststore/blob/47fd98ef2e3380bc2b84f5ff7922068d75077d45/packages/core/src/sdk/product/useShouldFetchFirstPage.ts/issues/L3)
11
+
12
+ ## [3.32.1](https://github.com/vtex/faststore/compare/v3.32.0...v3.32.1) (2025-03-28)
13
+
14
+ ### Bug Fixes
15
+
16
+ - call redirect-evaluate only for pages ([#2748](https://github.com/vtex/faststore/issues/2748)) ([cc5bde1](https://github.com/vtex/faststore/commit/cc5bde1334a4eb1924a645a3587c2b66dd51fb84))
17
+
6
18
  # [3.32.0](https://github.com/vtex/faststore/compare/v3.31.0...v3.32.0) (2025-03-27)
7
19
 
8
20
  **Note:** Version bump only for package @faststore/core
@@ -2,6 +2,7 @@ import type { DefaultSeoProps } from 'next-seo'
2
2
  import storeConfig from './discovery.config'
3
3
 
4
4
  const buildTime = new Date().toISOString()
5
+ const buildTimeInMS = Date.now()
5
6
 
6
7
  const config: DefaultSeoProps = {
7
8
  norobots: storeConfig.experimental.noRobots,
@@ -16,3 +17,5 @@ const config: DefaultSeoProps = {
16
17
  }
17
18
 
18
19
  export default config
20
+
21
+ export const generatedBuildTime = buildTimeInMS
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@faststore/core",
3
- "version": "3.32.0",
3
+ "version": "3.33.0",
4
4
  "license": "MIT",
5
5
  "repository": "vtex/faststore",
6
6
  "browserslist": "supports es6-module and not dead",
@@ -67,6 +67,7 @@
67
67
  "css-loader": "^6.7.1",
68
68
  "deepmerge": "^4.3.1",
69
69
  "draftjs-to-html": "^0.9.1",
70
+ "fast-deep-equal": "^3.1.3",
70
71
  "fs-extra": "^10.1.0",
71
72
  "graphql": "^15.6.0",
72
73
  "include-media": "^1.4.10",
@@ -104,5 +105,5 @@
104
105
  "ts-jest": "29.1.1",
105
106
  "typescript": "5.3.2"
106
107
  },
107
- "gitHead": "f4ece9782501b7caf26932199e53fd5019fc127e"
108
+ "gitHead": "e68051d8fca8e35ef16d00b94fbd39f7cb4a4856"
108
109
  }
@@ -1,5 +1,9 @@
1
- import { useSearch } from '@faststore/sdk'
2
- import type { ServerCollectionPageQueryQuery } from '@generated/graphql'
1
+ import { formatSearchState, useSearch } from '@faststore/sdk'
2
+ import type {
3
+ ServerCollectionPageQueryQuery,
4
+ ServerManyProductsQueryQuery,
5
+ ServerManyProductsQueryQueryVariables,
6
+ } from '@generated/graphql'
3
7
  import deepmerge from 'deepmerge'
4
8
  import { ITEMS_PER_PAGE } from 'src/constants'
5
9
 
@@ -11,12 +15,14 @@ import RenderSections, {
11
15
  } from 'src/components/cms/RenderSections'
12
16
  import type { PLPContentType } from 'src/server/cms/plp'
13
17
 
18
+ import { useEffect } from 'react'
14
19
  import PageProvider, { type PLPContext } from 'src/sdk/overrides/PageProvider'
15
20
  import {
16
21
  useCreateUseGalleryPage,
17
22
  UseGalleryPageContext,
18
23
  } from 'src/sdk/product/usePageProductsQuery'
19
24
  import { useProductGalleryQuery } from 'src/sdk/product/useProductGalleryQuery'
25
+ import { useApplySearchState } from 'src/sdk/search/state'
20
26
 
21
27
  const ScrollToTopButton = dynamic(
22
28
  () =>
@@ -27,7 +33,8 @@ const ScrollToTopButton = dynamic(
27
33
  )
28
34
 
29
35
  export type ProductListingPageProps = {
30
- data: ServerCollectionPageQueryQuery
36
+ data: ServerCollectionPageQueryQuery & ServerManyProductsQueryQuery
37
+ serverManyProductsVariables: ServerManyProductsQueryQueryVariables
31
38
  page: PLPContentType
32
39
  globalSections?: Array<{ name: string; data: any }>
33
40
  }
@@ -39,13 +46,19 @@ const overwriteMerge = (_: any[], sourceArray: any[]) => sourceArray
39
46
  export default function ProductListing({
40
47
  page: { sections, settings },
41
48
  data: server,
49
+ serverManyProductsVariables,
42
50
  globalSections,
43
51
  }: ProductListingPageProps) {
44
- const {
45
- state: { sort, term, selectedFacets },
46
- } = useSearch()
52
+ const { state } = useSearch()
53
+ const { sort, term, selectedFacets } = state
54
+
47
55
  const itemsPerPage = settings?.productGallery?.itemsPerPage ?? ITEMS_PER_PAGE
48
56
 
57
+ const applySearchState = useApplySearchState()
58
+ useEffect(() => {
59
+ applySearchState(formatSearchState(state))
60
+ }, [])
61
+
49
62
  const { data: pageProductGalleryData } = useProductGalleryQuery({
50
63
  term,
51
64
  sort,
@@ -53,7 +66,11 @@ export default function ProductListing({
53
66
  itemsPerPage,
54
67
  })
55
68
 
56
- const { pages, useGalleryPage } = useCreateUseGalleryPage()
69
+ const initialPages = { search: server?.search }
70
+ const { pages, useGalleryPage } = useCreateUseGalleryPage({
71
+ initialPages,
72
+ serverManyProductsVariables,
73
+ })
57
74
 
58
75
  const context = {
59
76
  data: {
@@ -8,7 +8,11 @@ import { BreadcrumbJsonLd, NextSeo } from 'next-seo'
8
8
  import { useRouter } from 'next/router'
9
9
  import { useMemo } from 'react'
10
10
 
11
- import type { ServerCollectionPageQueryQuery } from '@generated/graphql'
11
+ import type {
12
+ ServerCollectionPageQueryQuery,
13
+ ServerManyProductsQueryQuery,
14
+ ServerManyProductsQueryQueryVariables,
15
+ } from '@generated/graphql'
12
16
  import { ITEMS_PER_PAGE } from 'src/constants'
13
17
  import { useApplySearchState } from 'src/sdk/search/state'
14
18
 
@@ -18,7 +22,8 @@ import storeConfig from '../../../../discovery.config'
18
22
  import ProductListing from './ProductListing'
19
23
 
20
24
  export type ProductListingPageProps = {
21
- data: ServerCollectionPageQueryQuery
25
+ data: ServerCollectionPageQueryQuery & ServerManyProductsQueryQuery
26
+ serverManyProductsVariables: ServerManyProductsQueryQueryVariables
22
27
  page: PLPContentType
23
28
  globalSections?: Array<{ name: string; data: any }>
24
29
  }
@@ -26,12 +31,24 @@ export type ProductListingPageProps = {
26
31
  type UseSearchParams = {
27
32
  collection: ServerCollectionPageQueryQuery['collection']
28
33
  sort: SearchState['sort']
34
+ serverData?: ServerCollectionPageQueryQuery & ServerManyProductsQueryQuery
29
35
  }
30
36
  const useSearchParams = ({
31
37
  collection,
32
38
  sort,
39
+ serverData,
33
40
  }: UseSearchParams): SearchState => {
34
- const selectedFacets = collection?.meta.selectedFacets
41
+ const selectedFacets = [
42
+ ...collection?.meta.selectedFacets,
43
+ {
44
+ key: 'fuzzy',
45
+ value: serverData?.search?.metadata?.fuzzy ?? 'auto',
46
+ },
47
+ {
48
+ key: 'operator',
49
+ value: serverData?.search?.metadata?.logicalOperator ?? 'and',
50
+ },
51
+ ]
35
52
  const { asPath } = useRouter()
36
53
 
37
54
  const hrefState = useMemo(() => {
@@ -57,6 +74,7 @@ const useSearchParams = ({
57
74
  export default function ProductListingPage({
58
75
  page: plpContentType,
59
76
  data: server,
77
+ serverManyProductsVariables,
60
78
  globalSections,
61
79
  }: ProductListingPageProps) {
62
80
  const { settings } = plpContentType
@@ -66,6 +84,7 @@ export default function ProductListingPage({
66
84
  const searchParams = useSearchParams({
67
85
  collection,
68
86
  sort: settings?.productGallery?.sortBySelection as SearchState['sort'],
87
+ serverData: server,
69
88
  })
70
89
 
71
90
  const {
@@ -117,6 +136,7 @@ export default function ProductListingPage({
117
136
  globalSections={globalSections}
118
137
  page={plpContentType}
119
138
  data={server}
139
+ serverManyProductsVariables={serverManyProductsVariables}
120
140
  />
121
141
  </SearchProvider>
122
142
  )
@@ -6,9 +6,12 @@ import { gql } from '@generated'
6
6
  import type {
7
7
  ServerCollectionPageQueryQuery,
8
8
  ServerCollectionPageQueryQueryVariables,
9
+ ServerManyProductsQueryQuery,
10
+ ServerManyProductsQueryQueryVariables,
9
11
  } from '@generated/graphql'
10
12
  import { execute } from 'src/server'
11
13
 
14
+ import type { SearchState } from '@faststore/sdk'
12
15
  import type { Locator } from '@vtex/client-cms'
13
16
  import dynamic from 'next/dynamic'
14
17
  import {
@@ -27,6 +30,7 @@ import type { PageContentType } from 'src/server/cms'
27
30
  import { injectGlobalSections } from 'src/server/cms/global'
28
31
  import { getPLP, type PLPContentType } from 'src/server/cms/plp'
29
32
  import { getDynamicContent } from 'src/utils/dynamicContent'
33
+ import { fetchServerManyProducts } from 'src/utils/fetchProductGallerySSR'
30
34
 
31
35
  const LandingPage = dynamic(
32
36
  () => import('src/components/templates/LandingPage')
@@ -41,7 +45,8 @@ type Props = BaseProps &
41
45
  | {
42
46
  type: 'plp'
43
47
  page: PLPContentType
44
- data: ServerCollectionPageQueryQuery
48
+ data: ServerCollectionPageQueryQuery & ServerManyProductsQueryQuery
49
+ serverManyProductsVariables: ServerManyProductsQueryQueryVariables
45
50
  }
46
51
  | {
47
52
  type: 'page'
@@ -163,6 +168,15 @@ export const getStaticProps: GetStaticProps<
163
168
  globalSectionsFooterPromise,
164
169
  ])
165
170
 
171
+ const [serverManyProductsData, serverManyProductsVariables] =
172
+ await fetchServerManyProducts({
173
+ itemsPerPage: cmsPage?.settings?.productGallery?.itemsPerPage,
174
+ sort: cmsPage?.settings?.productGallery
175
+ ?.sortBySelection as SearchState['sort'],
176
+ term: '',
177
+ selectedFacets: data?.collection?.meta.selectedFacets,
178
+ })
179
+
166
180
  const notFound = errors.find(isNotFoundError)
167
181
 
168
182
  if (notFound) {
@@ -194,7 +208,11 @@ export const getStaticProps: GetStaticProps<
194
208
 
195
209
  return {
196
210
  props: {
197
- data,
211
+ data: {
212
+ ...data,
213
+ ...serverManyProductsData,
214
+ },
215
+ serverManyProductsVariables,
198
216
  page: cmsPage,
199
217
  globalSections: globalSectionsResult,
200
218
  type: 'plp',
@@ -4,17 +4,20 @@ import type {
4
4
  ClientManyProductsQueryQuery,
5
5
  ClientManyProductsQueryQueryVariables,
6
6
  } from '@generated/graphql'
7
+ import deepEquals from 'fast-deep-equal'
7
8
  import {
8
- useEffect,
9
- useCallback,
10
9
  createContext,
10
+ useCallback,
11
11
  useContext,
12
- useRef,
12
+ useEffect,
13
13
  useMemo,
14
+ useRef,
14
15
  useState,
15
16
  } from 'react'
16
17
  import { useQuery } from 'src/sdk/graphql/useQuery'
18
+ import { generatedBuildTime } from '../../../next-seo.config'
17
19
  import { useLocalizedVariables } from './useLocalizedVariables'
20
+ import { useShouldFetchFirstPage } from './useShouldFetchFirstPage'
18
21
 
19
22
  export const UseGalleryPageContext = createContext<
20
23
  ReturnType<typeof useCreateUseGalleryPage>['useGalleryPage']
@@ -64,14 +67,27 @@ export const query = gql(`
64
67
 
65
68
  const getKey = (object: any) => JSON.stringify(object)
66
69
 
70
+ interface UseCreateUseGalleryPageProps {
71
+ initialPages: ClientManyProductsQueryQuery
72
+ serverManyProductsVariables: ClientManyProductsQueryQueryVariables
73
+ }
74
+
67
75
  /**
68
76
  * Use this hook for managed pages state and creating useGalleryPage hook that will be used for fetching a list of products per pages in PLP or Search
69
77
  */
70
- export const useCreateUseGalleryPage = () => {
71
- const [pages, setPages] = useState<ClientManyProductsQueryQuery[]>([])
78
+ export const useCreateUseGalleryPage = (
79
+ params?: UseCreateUseGalleryPageProps
80
+ ) => {
81
+ const initialPages = params?.initialPages?.search ? [params.initialPages] : []
82
+ const initialVariables = params?.serverManyProductsVariables
83
+ ? [getKey(params.serverManyProductsVariables)]
84
+ : []
85
+
86
+ const [pages, setPages] =
87
+ useState<ClientManyProductsQueryQuery[]>(initialPages)
72
88
  // We create pagesRef as a mirror of the pages state so we don't have to add pages as a dependency of the useGalleryPage hook
73
- const pagesRef = useRef<ClientManyProductsQueryQuery[]>([])
74
- const pagesCache = useRef<string[]>([])
89
+ const pagesRef = useRef<ClientManyProductsQueryQuery[]>(initialPages)
90
+ const pagesCache = useRef<string[]>(initialVariables)
75
91
 
76
92
  const useGalleryPage = useCallback(function useGalleryPage(page: number) {
77
93
  const {
@@ -87,8 +103,17 @@ export const useCreateUseGalleryPage = () => {
87
103
  selectedFacets,
88
104
  })
89
105
 
90
- const hasSameVariables =
91
- pagesCache.current[page] === getKey(localizedVariables)
106
+ const hasSameVariables = deepEquals(
107
+ pagesCache.current[page],
108
+ getKey(localizedVariables)
109
+ )
110
+
111
+ const shouldFetchFirstPage = useShouldFetchFirstPage({
112
+ page,
113
+ generatedBuildTime,
114
+ })
115
+
116
+ const shouldFetch = !hasSameVariables || shouldFetchFirstPage
92
117
 
93
118
  const { data } = useQuery<
94
119
  ClientManyProductsQueryQuery,
@@ -96,10 +121,10 @@ export const useCreateUseGalleryPage = () => {
96
121
  >(query, localizedVariables, {
97
122
  fallbackData: null,
98
123
  suspense: true,
99
- doNotRun: hasSameVariables,
124
+ doNotRun: !shouldFetch,
100
125
  })
101
126
 
102
- const shouldUpdatePages = !hasSameVariables && data !== null
127
+ const shouldUpdatePages = data !== null
103
128
 
104
129
  if (shouldUpdatePages) {
105
130
  pagesCache.current[page] = getKey(localizedVariables)