From 8d1d59c6045d6875141cb588cd59b456974c3f26 Mon Sep 17 00:00:00 2001 From: Connor Easton Date: Tue, 9 Nov 2021 22:19:33 -0700 Subject: [PATCH 01/12] docs(readme): center title and add href to logo --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 597a2185c3..ea7e28f236 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,15 @@ -![Hydrogen logo](/docs/images/HydrogenLogo.png) +

+ + + +

+ +
📚 [Docs](https://shopify.dev/custom-storefronts/hydrogen) | 🗣 [Discord](https://discord.gg/Hefq6w5c5d) | 💬 [Discussions](https://github.com/Shopify/hydrogen/discussions) | 📝 [Changelog](./packages/hydrogen/CHANGELOG.md) +
+ Hydrogen is a **React-based framework** for building dynamic, **Shopify-powered** custom storefronts. Spin up a Hydrogen app in your browser with our [playground](https://hydrogen.new/) or set up your local environment with the instructions below ⬇️ From e2326b9756f83a2b6522cfb6f974ed034484141b Mon Sep 17 00:00:00 2001 From: Fran Dios Date: Wed, 10 Nov 2021 17:08:03 +0900 Subject: [PATCH 02/12] fix: new lines in wire response --- packages/hydrogen/src/framework/Hydration/Cache.client.ts | 5 ++++- packages/hydrogen/src/framework/Hydration/wire.server.ts | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/hydrogen/src/framework/Hydration/Cache.client.ts b/packages/hydrogen/src/framework/Hydration/Cache.client.ts index 31100efd39..9fc0ab46a0 100644 --- a/packages/hydrogen/src/framework/Hydration/Cache.client.ts +++ b/packages/hydrogen/src/framework/Hydration/Cache.client.ts @@ -136,7 +136,10 @@ function createManifestFromWirePayload(payload: string): WireManifest { return payload.split('\n').reduce((memo, row) => { const [key, ...values] = row.split(':'); - memo[key] = JSON.parse(values.join(':')); + if (key) { + memo[key] = JSON.parse(values.join(':')); + } + return memo; }, {} as Record) as WireManifest; } diff --git a/packages/hydrogen/src/framework/Hydration/wire.server.ts b/packages/hydrogen/src/framework/Hydration/wire.server.ts index 182b53d42d..14674759d9 100644 --- a/packages/hydrogen/src/framework/Hydration/wire.server.ts +++ b/packages/hydrogen/src/framework/Hydration/wire.server.ts @@ -90,7 +90,7 @@ export function generateWireSyntaxFromRenderedHtml(html: string) { return `M${idx + 1}:${JSON.stringify(component)}`; }) .join('\n') + `\nJ0:${JSON.stringify(wireModel)}` - ); + ).trim(); } function isDomNode(item: any) { From 1f45f15a24a96dea6efb598e10cf3c4b6c4ba624 Mon Sep 17 00:00:00 2001 From: Fran Dios Date: Wed, 10 Nov 2021 17:08:56 +0900 Subject: [PATCH 03/12] chore: update changelog --- packages/hydrogen/CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/hydrogen/CHANGELOG.md b/packages/hydrogen/CHANGELOG.md index d8c268222e..85ddc64c5c 100644 --- a/packages/hydrogen/CHANGELOG.md +++ b/packages/hydrogen/CHANGELOG.md @@ -5,7 +5,9 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). - +## Unreleased + +- fix: new lines in hydration request break JSON.parse ## 0.6.3 - 2021-11-10 From 4302cf2ff9cfa2eb08d86baaf9b9c6061cc21977 Mon Sep 17 00:00:00 2001 From: Fran Dios Date: Wed, 10 Nov 2021 17:15:55 +0900 Subject: [PATCH 04/12] test: remove new lines in wire response --- .../hydrogen/src/framework/Hydration/__tests__/wire.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/hydrogen/src/framework/Hydration/__tests__/wire.spec.ts b/packages/hydrogen/src/framework/Hydration/__tests__/wire.spec.ts index d99a336c83..5eb5370682 100644 --- a/packages/hydrogen/src/framework/Hydration/__tests__/wire.spec.ts +++ b/packages/hydrogen/src/framework/Hydration/__tests__/wire.spec.ts @@ -2,7 +2,7 @@ import {generateWireSyntaxFromRenderedHtml} from '../wire.server'; it('renders normal html elements', () => { const input = `

Hello!

`; - const output = `\nJ0:["$","div",null,{"className":"foo","children":["$","p",null,{"id":"bar","children":"Hello!"}]}]`; + const output = `J0:["$","div",null,{"className":"foo","children":["$","p",null,{"id":"bar","children":"Hello!"}]}]`; expect(generateWireSyntaxFromRenderedHtml(input)).toBe(output); }); @@ -98,7 +98,7 @@ J0:["$","div",null,{"className":"foo","children":["\\n ",["$","@1",null,{"sid it('renders Client Components with nested props that have multiple children', () => { const input = `

Bar

Baz
`; - const output = `\nJ0:["$","div",null,{"className":"foo","children":[["$","p",null,{"key":0,"children":"Bar"}],["$","div",null,{"key":1,"children":"Baz"}]]}]`; + const output = `J0:["$","div",null,{"className":"foo","children":[["$","p",null,{"key":0,"children":"Bar"}],["$","div",null,{"key":1,"children":"Baz"}]]}]`; expect(generateWireSyntaxFromRenderedHtml(input)).toBe(output); }); From 79f32c52ad5c5972a22256134248960cc131577d Mon Sep 17 00:00:00 2001 From: Bret Little Date: Wed, 10 Nov 2021 12:19:16 -0500 Subject: [PATCH 05/12] fix(#201): normalize POSIX separators to support windows --- .../vite-plugin-react-server-components-shim.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/hydrogen/src/framework/plugins/vite-plugin-react-server-components-shim.ts b/packages/hydrogen/src/framework/plugins/vite-plugin-react-server-components-shim.ts index 9807d90a64..c8be7eaf8e 100644 --- a/packages/hydrogen/src/framework/plugins/vite-plugin-react-server-components-shim.ts +++ b/packages/hydrogen/src/framework/plugins/vite-plugin-react-server-components-shim.ts @@ -1,4 +1,5 @@ import type {Plugin, ResolvedConfig} from 'vite'; +import {normalizePath} from 'vite'; import path from 'path'; import {proxyClientComponent} from '../server-components'; @@ -77,7 +78,9 @@ export default () => { const hydrogenPath = path.dirname(require.resolve('@shopify/hydrogen')); const importerPath = path.join(hydrogenPath, 'framework', 'Hydration'); - const importerToRootPath = path.relative(importerPath, config.root); + const importerToRootPath = normalizePath( + path.relative(importerPath, config.root) + ); const [importerToRootNested] = importerToRootPath.match(/(\.\.\/)+(\.\.)?/) || []; const userPrefix = path.normalize( @@ -100,10 +103,10 @@ export default () => { ); return code - .replace('__USER_COMPONENTS_PREFIX__', userPrefix) - .replace('__USER_COMPONENTS_GLOB__', userGlob) - .replace('__LIB_COMPONENTS_PREFIX__', libPrefix) - .replace('__LIB_COMPONENTS_GLOB__', libGlob); + .replace('__USER_COMPONENTS_PREFIX__', normalizePath(userPrefix)) + .replace('__USER_COMPONENTS_GLOB__', normalizePath(userGlob)) + .replace('__LIB_COMPONENTS_PREFIX__', normalizePath(libPrefix)) + .replace('__LIB_COMPONENTS_GLOB__', normalizePath(libGlob)); } }, } as Plugin; From 69576610c4ee344870d85bed970840b75c4b5e2b Mon Sep 17 00:00:00 2001 From: Josh Larson Date: Wed, 10 Nov 2021 12:01:53 -0600 Subject: [PATCH 06/12] chore: improve Stackblitz publishing flow (#203) * chore: hoist local flag to root project * chore: publish to stackblitz branch with new release * chore: rename gitignore for stackblitz * chore: use correct path * chore: include `.stackblitzrc` file to ensure dev server starts --- .github/workflows/publish_stackblitz.yml | 21 +++++++++++++++++++ package.json | 2 +- .../scripts/tmp-copy-template-from-dev.js | 2 +- packages/dev/.stackblitzrc | 4 ++++ packages/dev/package.json | 2 +- 5 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/publish_stackblitz.yml create mode 100644 packages/dev/.stackblitzrc diff --git a/.github/workflows/publish_stackblitz.yml b/.github/workflows/publish_stackblitz.yml new file mode 100644 index 0000000000..970509c73a --- /dev/null +++ b/.github/workflows/publish_stackblitz.yml @@ -0,0 +1,21 @@ +name: Publish to Stackblitz + +on: + release: + types: [published] + +jobs: + publish: + runs-on: ubuntu-latest + name: Publish latest release to Stackblitz + steps: + - name: Checkout the code + uses: actions/checkout@v2 + - name: Rename gitignore + run: | + mv packages/dev/_gitignore packages/dev/.gitignore + - name: Push to stackblitz branch + uses: EndBug/add-and-commit@v7.4.0 + with: + push: 'origin stackblitz --force' + diff --git a/package.json b/package.json index 517e4c6206..0285337538 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ }, "scripts": { "dev-lib": "yarn workspace @shopify/hydrogen dev", - "dev-server": "VITE_INSPECT=1 yarn workspace dev dev", + "dev-server": "LOCAL_DEV=true VITE_INSPECT=1 yarn workspace dev dev", "build": "run-s build-lib build-dev build-cli", "build-lib": "yarn workspace @shopify/hydrogen build", "build-cli": "yarn workspace @shopify/hydrogen-cli build", diff --git a/packages/create-hydrogen-app/scripts/tmp-copy-template-from-dev.js b/packages/create-hydrogen-app/scripts/tmp-copy-template-from-dev.js index ef11ce4858..cd50c36805 100644 --- a/packages/create-hydrogen-app/scripts/tmp-copy-template-from-dev.js +++ b/packages/create-hydrogen-app/scripts/tmp-copy-template-from-dev.js @@ -12,7 +12,7 @@ const {copy} = require('./utils'); const devPath = path.resolve(__dirname, '..', '..', 'dev'); const templatePath = path.resolve(__dirname, '..', './template-hydrogen'); -const skipFiles = ['node_modules', 'dist']; +const skipFiles = ['node_modules', 'dist', '.stackblitzrc']; // Remove the symlink and replace it with a folder fs.unlinkSync(templatePath); diff --git a/packages/dev/.stackblitzrc b/packages/dev/.stackblitzrc new file mode 100644 index 0000000000..d98146f4d0 --- /dev/null +++ b/packages/dev/.stackblitzrc @@ -0,0 +1,4 @@ +{ + "installDependencies": true, + "startCommand": "npm run dev" +} diff --git a/packages/dev/package.json b/packages/dev/package.json index 25c0fb830a..86e7408e03 100644 --- a/packages/dev/package.json +++ b/packages/dev/package.json @@ -5,7 +5,7 @@ "license": "MIT", "private": true, "scripts": { - "dev": "LOCAL_DEV=true vite", + "dev": "vite", "lint": "npm-run-all lint:*", "lint:js": "eslint --no-error-on-unmatched-pattern --ext .js,.ts,.jsx,.tsx src", "lint:css": "stylelint ./src/**/*.{css,sass,scss}", From 193a6019759955196af247759fab015009d844e3 Mon Sep 17 00:00:00 2001 From: Bret Little Date: Wed, 10 Nov 2021 13:16:48 -0500 Subject: [PATCH 07/12] fix: add a unit test to validate vite middleware transforms --- ...-react-server-components-shim.spec.ts.snap | 41 +++++++++++++++ ...lugin-react-server-components-shim.spec.ts | 52 +++++++++++++++++++ .../src/framework/plugins/resolver.ts | 3 ++ ...ite-plugin-react-server-components-shim.ts | 3 +- 4 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 packages/hydrogen/src/framework/plugins/__tests__/__snapshots__/vite-plugin-react-server-components-shim.spec.ts.snap create mode 100644 packages/hydrogen/src/framework/plugins/__tests__/vite-plugin-react-server-components-shim.spec.ts create mode 100644 packages/hydrogen/src/framework/plugins/resolver.ts diff --git a/packages/hydrogen/src/framework/plugins/__tests__/__snapshots__/vite-plugin-react-server-components-shim.spec.ts.snap b/packages/hydrogen/src/framework/plugins/__tests__/__snapshots__/vite-plugin-react-server-components-shim.spec.ts.snap new file mode 100644 index 0000000000..4637321d01 --- /dev/null +++ b/packages/hydrogen/src/framework/plugins/__tests__/__snapshots__/vite-plugin-react-server-components-shim.spec.ts.snap @@ -0,0 +1,41 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`transforms client-imports 1`] = ` +"// Transform relative paths to absolute in order +// to match component IDs from ClientMarker. +function normalizeComponentPaths( + componentObject: Record any)>, + prefix: string +) { + return Object.entries(componentObject).reduce((acc, [key, value]) => { + acc[prefix + key.replace(/\\\\.\\\\.\\\\//gm, '')] = value; + return acc; + }, {} as typeof componentObject); +} + +// These strings are replaced in a plugin with real globs +// and paths that depend on the user project structure. +const allClientComponents = { + ...normalizeComponentPaths( + // @ts-ignore + import.meta.glob('../../components/**/*.client.js'), + \`@shopify/\` + ), + ...normalizeComponentPaths( + // @ts-ignore + import.meta.glob('../../../src/**/*.client.[jt]sx'), + \`./\` + ), +}; + +export default function importClientComponent(moduleId: string) { + const modImport = allClientComponents[moduleId]; + + if (!modImport) { + throw new Error(\`Could not find client component \${moduleId}\`); + } + + return modImport(); +} +" +`; diff --git a/packages/hydrogen/src/framework/plugins/__tests__/vite-plugin-react-server-components-shim.spec.ts b/packages/hydrogen/src/framework/plugins/__tests__/vite-plugin-react-server-components-shim.spec.ts new file mode 100644 index 0000000000..99d19e6fcd --- /dev/null +++ b/packages/hydrogen/src/framework/plugins/__tests__/vite-plugin-react-server-components-shim.spec.ts @@ -0,0 +1,52 @@ +import middleware from '../vite-plugin-react-server-components-shim'; +import fs from 'fs'; +import path from 'path'; +import {resolve} from '../resolver'; + +jest.mock('../resolver'); + +(resolve as any).mockImplementation(() => '@shopify/hydrogen'); + +let m: any; + +beforeEach(() => { + m = middleware(); + m.configResolved({ + root: '.', + }); +}); + +it('only transforms client-imports', function () { + expect(m.transform('', '')).toBe(undefined); +}); + +it('transforms client-imports', function () { + const code = fs.readFileSync( + path.resolve(__dirname, '../../Hydration/client-imports.ts'), + 'utf8' + ); + const result = m.transform(code, '/Hydration/client-imports'); + + expect(result).toMatchSnapshot(); +}); + +it('throws an error when non-Server components load Server components', async function () { + await expect(m.resolveId('.server.tsx', '.client.tsx')).rejects.toThrow(); + + await expect(m.resolveId('.server.jsx', '.client.jsx')).rejects.toThrow(); +}); + +it('passes when server components import client components', async function () { + m.resolveId('.client.tsx', '.server.tsx'); + m.resolveId('.client.jsx', '.server.jsx'); +}); + +it('throws an error when client components load hydrogen from the server-only entrypoint', async function () { + await expect( + m.resolveId('@shopify/hydrogen', '.client.tsx') + ).rejects.toThrow(); + + await expect( + m.resolveId('@shopify/hydrogen', '.client.jsx') + ).rejects.toThrow(); +}); diff --git a/packages/hydrogen/src/framework/plugins/resolver.ts b/packages/hydrogen/src/framework/plugins/resolver.ts new file mode 100644 index 0000000000..9540dbf713 --- /dev/null +++ b/packages/hydrogen/src/framework/plugins/resolver.ts @@ -0,0 +1,3 @@ +export function resolve(path: string) { + return require.resolve(path); +} diff --git a/packages/hydrogen/src/framework/plugins/vite-plugin-react-server-components-shim.ts b/packages/hydrogen/src/framework/plugins/vite-plugin-react-server-components-shim.ts index c8be7eaf8e..304bc7f57c 100644 --- a/packages/hydrogen/src/framework/plugins/vite-plugin-react-server-components-shim.ts +++ b/packages/hydrogen/src/framework/plugins/vite-plugin-react-server-components-shim.ts @@ -2,6 +2,7 @@ import type {Plugin, ResolvedConfig} from 'vite'; import {normalizePath} from 'vite'; import path from 'path'; import {proxyClientComponent} from '../server-components'; +import {resolve} from './resolver'; export default () => { let config: ResolvedConfig; @@ -75,7 +76,7 @@ export default () => { */ if (id.includes('/Hydration/client-imports')) { // eslint-disable-next-line node/no-missing-require - const hydrogenPath = path.dirname(require.resolve('@shopify/hydrogen')); + const hydrogenPath = path.dirname(resolve('@shopify/hydrogen')); const importerPath = path.join(hydrogenPath, 'framework', 'Hydration'); const importerToRootPath = normalizePath( From b0a0ce3b83b11e24b13909aa360f66c781aca1e5 Mon Sep 17 00:00:00 2001 From: Josh Larson Date: Wed, 10 Nov 2021 14:31:40 -0600 Subject: [PATCH 08/12] chore: request more repros in bug reports We got StackBlitz. Let's use it to our advantage! 80% of the time when people go to reproduce the bug fix, they will find the true cause of the issue (and sometimes it's not Hydrogen related). --- .github/ISSUE_TEMPLATE/bug_report.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index d535723c41..f004df479d 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -10,7 +10,11 @@ assignees: '' A clear and concise description of what the bug is. **To Reproduce** -Steps to reproduce the behaviour: + +- Provide a link to a [StackBlitz sandbox](https://hydrogen.new) which reproduces the issue +- OR: provide a link to a repository that reproduces the issue + +If you cannot do one of the above, list steps to reproduce the behaviour below: 1. Go to '...' 2. Click on '....' From 6f2e86e85ff7f51c46d8ea6ac2a8bb049b2dbcda Mon Sep 17 00:00:00 2001 From: Bret Little Date: Wed, 10 Nov 2021 13:49:15 -0500 Subject: [PATCH 09/12] chore: update changelog --- packages/hydrogen/CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/hydrogen/CHANGELOG.md b/packages/hydrogen/CHANGELOG.md index d8c268222e..769e91e580 100644 --- a/packages/hydrogen/CHANGELOG.md +++ b/packages/hydrogen/CHANGELOG.md @@ -5,7 +5,9 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). - +## Unreleased + +- fix(#201): normalize POSIX separators to support windows ## 0.6.3 - 2021-11-10 From ade416ff1b31c779b9920c9becdbaff19761aa07 Mon Sep 17 00:00:00 2001 From: "Sahil H. Mobaidin" Date: Wed, 10 Nov 2021 23:32:01 +0200 Subject: [PATCH 10/12] fix(dev): fix scroll to top on app first load --- packages/hydrogen/CHANGELOG.md | 4 ++++ .../src/foundation/Router/ServerStateRouter.client.tsx | 9 ++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/hydrogen/CHANGELOG.md b/packages/hydrogen/CHANGELOG.md index d8c268222e..872153524e 100644 --- a/packages/hydrogen/CHANGELOG.md +++ b/packages/hydrogen/CHANGELOG.md @@ -7,6 +7,10 @@ and adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## 0.6.4 - 2021-11-10 + +- fix: fix scroll to top on app first load + ## 0.6.3 - 2021-11-10 - fix: add trailing slash to user components glob diff --git a/packages/hydrogen/src/foundation/Router/ServerStateRouter.client.tsx b/packages/hydrogen/src/foundation/Router/ServerStateRouter.client.tsx index c22695a6be..ba0f8a6beb 100644 --- a/packages/hydrogen/src/foundation/Router/ServerStateRouter.client.tsx +++ b/packages/hydrogen/src/foundation/Router/ServerStateRouter.client.tsx @@ -9,13 +9,16 @@ import {useServerState} from '../useServerState'; * server state, which in turn fetches the correct server component. */ export function ServerStateRouter() { - const {setServerState, pending} = useServerState() as ServerStateContextValue; + const {setServerState, pending, serverState} = + useServerState() as ServerStateContextValue; const [isNavigating, setIsNavigating] = useState(false); const location = useLocation(); useEffect(() => { - setIsNavigating(true); - setServerState('pathname', location.pathname); + if (serverState.pathname !== location.pathname) { + setIsNavigating(true); + setServerState('pathname', location.pathname); + } }, [location.pathname, setServerState]); useEffect(() => { From 8df3c8f8d400f71fd98861ca956d30acedbc8686 Mon Sep 17 00:00:00 2001 From: Bret Little Date: Wed, 10 Nov 2021 17:12:17 -0500 Subject: [PATCH 11/12] chore: fix changelog --- packages/hydrogen/CHANGELOG.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/hydrogen/CHANGELOG.md b/packages/hydrogen/CHANGELOG.md index 9095e5fdd7..d92ddecafc 100644 --- a/packages/hydrogen/CHANGELOG.md +++ b/packages/hydrogen/CHANGELOG.md @@ -8,10 +8,7 @@ and adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## Unreleased - fix(#201): normalize POSIX separators to support windows - -## 0.6.4 - 2021-11-10 - -- fix: fix scroll to top on app first load +- fix: scroll to top on app first load ## 0.6.3 - 2021-11-10 From 164d3174388db07272ea524a539ef1ade00bdb7a Mon Sep 17 00:00:00 2001 From: Fran Dios Date: Thu, 11 Nov 2021 12:52:06 +0900 Subject: [PATCH 12/12] test: client handles new lines in hydration response --- .../src/framework/Hydration/__tests__/Cache.spec.tsx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/hydrogen/src/framework/Hydration/__tests__/Cache.spec.tsx b/packages/hydrogen/src/framework/Hydration/__tests__/Cache.spec.tsx index e61df0da27..2055f04f06 100644 --- a/packages/hydrogen/src/framework/Hydration/__tests__/Cache.spec.tsx +++ b/packages/hydrogen/src/framework/Hydration/__tests__/Cache.spec.tsx @@ -13,6 +13,15 @@ it('handles DOM elements', async () => { expect(screen.getByText('hello')).toBeInTheDocument(); }); +it('ignores new lines', async () => { + const tuples = [['$', 'div', null, {children: 'hello'}]]; + const payload = `\nJ0:${JSON.stringify(tuples)}\n`; + + render(await convertHydrationResponseToReactComponents(payload)); + + expect(screen.getByText('hello')).toBeInTheDocument(); +}); + it('handles DOM elements with arrays of children', async () => { const tuples = [ [