diff --git a/packages/api-prerendering-service/__tests__/render/extractPeLoaderDataFromHtml.test.ts b/packages/api-prerendering-service/__tests__/render/extractPeLoaderDataFromHtml.test.ts index 967a670437..ae5cdb8191 100644 --- a/packages/api-prerendering-service/__tests__/render/extractPeLoaderDataFromHtml.test.ts +++ b/packages/api-prerendering-service/__tests__/render/extractPeLoaderDataFromHtml.test.ts @@ -4,42 +4,14 @@ describe("extractPeLoaderDataFromHtml Tests", () => { it("must detect pe-loader-data-cache tags in given HTML", async () => { const results = extractPeLoaderDataFromHtml(TEST_STRING); + // The value is not decompressed, so it's still a string. expect(results).toEqual([ { key: "GfT8AoRsYT-1238102521", - value: [ - { - description: - "The Falcon 1 was an expendable launch system privately developed and manufactured by SpaceX during 2006-2009. On 28 September 2008, Falcon 1 became the first privately-developed liquid-fuel launch vehicle to go into orbit around the Earth.", - id: "5e9d0d95eda69955f709d1eb", - name: "Falcon 1", - wikipedia: "https://en.wikipedia.org/wiki/Falcon_1" - }, - { - description: - "Falcon 9 is a two-stage rocket designed and manufactured by SpaceX for the reliable and safe transport of satellites and the Dragon spacecraft into orbit.", - id: "5e9d0d95eda69973a809d1ec", - name: "Falcon 9", - wikipedia: "https://en.wikipedia.org/wiki/Falcon_9" - }, - { - description: - "With the ability to lift into orbit over 54 metric tons (119,000 lb)--a mass equivalent to a 737 jetliner loaded with passengers, crew, luggage and fuel--Falcon Heavy can lift more than twice the payload of the next closest operational vehicle, the Delta IV Heavy, at one-third the cost.", - id: "5e9d0d95eda69974db09d1ed", - name: "Falcon Heavy", - wikipedia: "https://en.wikipedia.org/wiki/Falcon_Heavy" - }, - { - description: - "Starship and Super Heavy Rocket represent a fully reusable transportation system designed to service all Earth orbit needs as well as the Moon and Mars. This two-stage vehicle — composed of the Super Heavy rocket (booster) and Starship (ship) — will eventually replace Falcon 9, Falcon Heavy and Dragon.", - id: "5e9d0d96eda699382d09d1ee", - name: "Starship", - wikipedia: "https://en.wikipedia.org/wiki/SpaceX_Starship" - } - ] + value: "pe_NobwRAJgpgzgxgJwJYAcAuSD2A7MAuMAFQAsoACAMQEMAbOHMgRjIHcqYyrsyoAPFKNghUARjXI0qAV2xxiZGAE8YaKAFsyKZADcqqmorLRtUGpgEROQsmq5SAZlThopCKJZGGAyiidQAGkauSNgA5mQATAAMUQBsALTRUQCcAHRkAPLcEQAcZF5Q6OoiUAiRMTkANJS09NzMJXBUauRopGT2SAgqmjp6porxxqbm7mQ0SACOUkgQ8fZSpuPSsvImxEhw4mRomGSheyG7ZJgIIkhonAiYMpZt5ACiVAhtqWCVYLP4YACsUMkQKIQZJ/YSxZIgn72ADsKQgjCgIneYGwzSg32odAYjGRLCQAGtUO4kFRvsQ0GgUDA8AB6GmCVJ4wkWEmpU6hGlMpA0zF1AD6OIAvpVwNB4Mh0FhcAReQxkmQkBwqDsWJh4ioqKFyNc4PioJcxUhQtgxlxLLZsA4nC43B5vL44AEOqcdu03BNRNszQoqPZWgguDAUKdLph7D79BNVErrPcyAARAMHbhBvyIX2XI57U7nNBvD5fAh/AFAkHuKjg5LQgDMVBycIRcGRqJaGNqctxBKJEBJZIpVNp9OwjK7LKobIQHK5PPb2D5yTAwtFsEQqAwOG+AHULvI46IkFHDMcJvZM9hjjmLicTGUfgAWGz65BwHY4DgACkYjGSlRiUXGIgAJTxPEyq2DAHBQNMSC6OI56vpwZA1tCZAAFb6hMJplGYVDQJYeJtJo7AwIIWrdNUiBQCw1Q0FIoShJq5DegspggbK3AABJQFQ2iGE03AnpcainK0xBcCqmyieQviKDhlhhq65AmrwlxbJgJE9KMAbrqiNBkOsmziNUcbxqYaDKgAkgAamQXE8Yo1R6CcJrxG0XR3O09AqPmnwQN8xaAsCoIVhC0J3hAIgNu4zZom2WKcdxvGdsyxKkgQ5KUtSdIMlyY4TlOXYzvFfJ2UlS6QCuEo6d8Xjmd0GwoFYlheFIAhlKVhgAEqYLq+pkG4WiwIIlzKgsNAGP1UBSDAnr+oGwYvHoUoKMoqgaIaxpjMcJEINokmcONZBPC88iXpcJruEqHAsKYensIpZAALKYAw3qPc8MDpCQioqmqGpavpUAbFs5AAMMAEUAEMAAGQwAKWQ9BqMGJHyeGcYtW1tmJYYOp6pc74iC9KilIBTX5HVMANWQ75U6gZMQzD8OsAeelQCY55SLQE0DZIjo1PFZA/gLdTY/Z5OJpqOA+YWvz/IFySxOWlbVjkESAgCCLoh8LbogQtUfQ1yXdr26X9llQ4jilPbjuynKFT4fj+HyBv1agi4ALpAA==" } ]); }); }); -const TEST_STRING = `...
  • Starship

    Starship and Super Heavy Rocket represent a fully reusable transportation system designed to service all Earth orbit needs as well as the Moon and Mars. This two-stage vehicle — composed of the Super Heavy rocket (booster) and Starship (ship) — will eventually replace Falcon 9, Falcon Heavy and Dragon.

    More info at https://en.wikipedia.org/wiki/SpaceX_Starship
  • `; +const TEST_STRING = `...
  • Starship

    Starship and Super Heavy Rocket represent a fully reusable transportation system designed to service all Earth orbit needs as well as the Moon and Mars. This two-stage vehicle — composed of the Super Heavy rocket (booster) and Starship (ship) — will eventually replace Falcon 9, Falcon Heavy and Dragon.

    More info at https://en.wikipedia.org/wiki/SpaceX_Starship
  • `; diff --git a/packages/api-prerendering-service/package.json b/packages/api-prerendering-service/package.json index 6de200a188..4f5b541a93 100644 --- a/packages/api-prerendering-service/package.json +++ b/packages/api-prerendering-service/package.json @@ -24,7 +24,6 @@ "@webiny/handler-client": "0.0.0", "@webiny/plugins": "0.0.0", "@webiny/utils": "0.0.0", - "he": "^1.2.0", "lodash": "^4.17.21", "object-hash": "^3.0.0", "pluralize": "^8.0.0", @@ -41,7 +40,6 @@ "@babel/plugin-proposal-export-default-from": "^7.23.3", "@babel/preset-env": "^7.24.0", "@babel/preset-typescript": "^7.23.3", - "@types/he": "^1.2.3", "@types/object-hash": "^2.2.1", "@types/puppeteer-core": "^5.4.0", "@webiny/cli": "0.0.0", diff --git a/packages/api-prerendering-service/src/render/extractPeLoaderDataFromHtml.ts b/packages/api-prerendering-service/src/render/extractPeLoaderDataFromHtml.ts index 1618e550a2..cff831707b 100644 --- a/packages/api-prerendering-service/src/render/extractPeLoaderDataFromHtml.ts +++ b/packages/api-prerendering-service/src/render/extractPeLoaderDataFromHtml.ts @@ -1,5 +1,4 @@ import { PeLoaderCacheEntry } from "./types"; -import he from "he"; const parsePeLoaderDataCacheTag = (content: string): PeLoaderCacheEntry | null => { const regex = @@ -14,10 +13,7 @@ const parsePeLoaderDataCacheTag = (content: string): PeLoaderCacheEntry | null = const [, key, value] = m; - // JSON in `data-value` is HTML Entities-encoded. So, we need to decode it here first. - const heParsedValue = he.decode(value); - const parsedValue = JSON.parse(heParsedValue); - return { key, value: parsedValue }; + return { key, value }; } return null; diff --git a/packages/app-website/package.json b/packages/app-website/package.json index 347e88c4c2..70ee6d324b 100644 --- a/packages/app-website/package.json +++ b/packages/app-website/package.json @@ -26,6 +26,7 @@ "apollo-link": "^1.2.14", "apollo-link-batch-http": "^1.2.14", "graphql-tag": "^2.12.6", + "lz-string": "^1.5.0", "react": "18.2.0", "react-dom": "18.2.0", "react-helmet": "^6.1.0", diff --git a/packages/app-website/src/Website.tsx b/packages/app-website/src/Website.tsx index 5b917e0845..229798fdff 100644 --- a/packages/app-website/src/Website.tsx +++ b/packages/app-website/src/Website.tsx @@ -18,11 +18,11 @@ export interface WebsiteProps extends AppProps { const PageBuilderProviderHOC: Decorator< GenericComponent<{ children: React.ReactNode }> > = PreviousProvider => { - const websiteLoaderCache = useMemo(() => { - return new WebsiteLoaderCache(); - }, []); - return function PageBuilderProviderHOC({ children }) { + const websiteLoaderCache = useMemo(() => { + return new WebsiteLoaderCache(); + }, []); + return ( {children} diff --git a/packages/app-website/src/utils/WebsiteLoaderCache.ts b/packages/app-website/src/utils/WebsiteLoaderCache.ts index 56d31a0326..bb1a7efcba 100644 --- a/packages/app-website/src/utils/WebsiteLoaderCache.ts +++ b/packages/app-website/src/utils/WebsiteLoaderCache.ts @@ -1,6 +1,6 @@ import type { ILoaderCache } from "@webiny/app-page-builder-elements/hooks/useLoader/ILoaderCache"; import { getPrerenderId, isPrerendering } from "@webiny/app/utils"; -import { PeLoaderHtmlCache } from "~/utils/WebsiteLoaderCache/PeLoaderHtmlCache"; +import { PeLoaderHtmlCache } from "./WebsiteLoaderCache/PeLoaderHtmlCache"; export class WebsiteLoaderCache implements ILoaderCache { private loaderCache: Record = {}; @@ -19,7 +19,12 @@ export class WebsiteLoaderCache implements ILoaderCache { return this.loaderCache[key]; } - write(key: string, value: TData) { + write(key: string, rawValue: TData) { + // We assume it's compressed data if the value is a string. + const value = PeLoaderHtmlCache.isCompressedData(rawValue) + ? PeLoaderHtmlCache.decompressData(rawValue as string) + : rawValue; + this.loaderCache[key] = value; if (isPrerendering()) { diff --git a/packages/app-website/src/utils/WebsiteLoaderCache/PeLoaderHtmlCache.ts b/packages/app-website/src/utils/WebsiteLoaderCache/PeLoaderHtmlCache.ts index 10b3b83a1b..87cbe6d811 100644 --- a/packages/app-website/src/utils/WebsiteLoaderCache/PeLoaderHtmlCache.ts +++ b/packages/app-website/src/utils/WebsiteLoaderCache/PeLoaderHtmlCache.ts @@ -1,3 +1,7 @@ +import lzString from "lz-string"; + +const COMPRESSED_DATA_PREFIX = "pe_"; + export class PeLoaderHtmlCache { static read(key: string) { const htmlElement = document.querySelector(`pe-loader-data-cache[data-key="${key}"]`); @@ -11,16 +15,30 @@ export class PeLoaderHtmlCache { } try { - return JSON.parse(cachedResultElementValue) as TData; + return PeLoaderHtmlCache.decompressData(cachedResultElementValue) as TData; } catch { return null; } } static write(key: string, value: TData) { - const html = `( value )}'>`; document.body.insertAdjacentHTML("beforeend", html); } + + static compressData(data: TData) { + return COMPRESSED_DATA_PREFIX + lzString.compressToBase64(JSON.stringify(data)); + } + + static decompressData(data: string) { + return JSON.parse( + lzString.decompressFromBase64(data.replace(COMPRESSED_DATA_PREFIX, "")) as string + ); + } + + static isCompressedData(data: TData) { + return typeof data === "string" && data.startsWith(COMPRESSED_DATA_PREFIX); + } } diff --git a/yarn.lock b/yarn.lock index 101bb1ad4f..9474c8c091 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12121,13 +12121,6 @@ __metadata: languageName: node linkType: hard -"@types/he@npm:^1.2.3": - version: 1.2.3 - resolution: "@types/he@npm:1.2.3" - checksum: e77851c73dd7b9902d92fe0118a26246a7f3676a3a1c6eb1408305187ef73b57c22550b1435946b983267f961d935554d5d0e1b458416932552f31e763e1aa41 - languageName: node - linkType: hard - "@types/hoist-non-react-statics@npm:^3.3.5": version: 3.3.5 resolution: "@types/hoist-non-react-statics@npm:3.3.5" @@ -14843,7 +14836,6 @@ __metadata: "@babel/preset-typescript": ^7.23.3 "@babel/runtime": ^7.24.0 "@sparticuz/chromium": 123.0.1 - "@types/he": ^1.2.3 "@types/object-hash": ^2.2.1 "@types/puppeteer-core": ^5.4.0 "@webiny/api": 0.0.0 @@ -14856,7 +14848,6 @@ __metadata: "@webiny/plugins": 0.0.0 "@webiny/project-utils": 0.0.0 "@webiny/utils": 0.0.0 - he: ^1.2.0 lodash: ^4.17.21 object-hash: ^3.0.0 pluralize: ^8.0.0 @@ -16722,6 +16713,7 @@ __metadata: apollo-link: ^1.2.14 apollo-link-batch-http: ^1.2.14 graphql-tag: ^2.12.6 + lz-string: ^1.5.0 react: 18.2.0 react-dom: 18.2.0 react-helmet: ^6.1.0