summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.changeset/modern-bulldogs-burn.md5
-rw-r--r--packages/astro/e2e/fixtures/pass-js/src/components/React.tsx12
-rw-r--r--packages/astro/e2e/fixtures/pass-js/src/pages/index.astro10
-rw-r--r--packages/astro/e2e/pass-js.test.js24
-rw-r--r--packages/astro/src/runtime/server/serialize.ts4
5 files changed, 50 insertions, 5 deletions
diff --git a/.changeset/modern-bulldogs-burn.md b/.changeset/modern-bulldogs-burn.md
new file mode 100644
index 000000000..76c3fd8a4
--- /dev/null
+++ b/.changeset/modern-bulldogs-burn.md
@@ -0,0 +1,5 @@
+---
+'astro': patch
+---
+
+Fixes hydration of maps/sets
diff --git a/packages/astro/e2e/fixtures/pass-js/src/components/React.tsx b/packages/astro/e2e/fixtures/pass-js/src/components/React.tsx
index 7302c5443..02023fc9d 100644
--- a/packages/astro/e2e/fixtures/pass-js/src/components/React.tsx
+++ b/packages/astro/e2e/fixtures/pass-js/src/components/React.tsx
@@ -4,12 +4,15 @@ import { useState } from 'react';
interface Props {
obj: BigNestedObject;
num: bigint;
+ arr: any[];
+ map: Map<string, string>;
+ set: Set<string>;
}
const isNode = typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]';
/** a counter written in React */
-export default function Component({ obj, num, arr }: Props) {
+export default function Component({ obj, num, arr, map, set }: Props) {
// We are testing hydration, so don't return anything in the server.
if(isNode) {
return <div></div>
@@ -24,6 +27,13 @@ export default function Component({ obj, num, arr }: Props) {
<span id="bigint-value">{num.toString()}</span>
<span id="arr-type">{Object.prototype.toString.call(arr)}</span>
<span id="arr-value">{arr.join(',')}</span>
+ <span id="map-type">{Object.prototype.toString.call(map)}</span>
+ <ul id="map-items">{Array.from(map).map(([key, value]) => (
+ <li>{key}: {value}</li>
+ ))}
+ </ul>
+ <span id="set-type">{Object.prototype.toString.call(set)}</span>
+ <span id="set-value">{Array.from(set).join(',')}</span>
</div>
);
}
diff --git a/packages/astro/e2e/fixtures/pass-js/src/pages/index.astro b/packages/astro/e2e/fixtures/pass-js/src/pages/index.astro
index dc029b6fb..be40948d8 100644
--- a/packages/astro/e2e/fixtures/pass-js/src/pages/index.astro
+++ b/packages/astro/e2e/fixtures/pass-js/src/pages/index.astro
@@ -12,6 +12,14 @@ const obj: BigNestedObject = {
}
}
};
+
+const map = new Map<string,string>();
+map.set('test1', 'test2');
+map.set('test3', 'test4');
+
+const set = new Set<string>();
+set.add('test1');
+set.add('test2');
---
<html lang="en">
@@ -22,7 +30,7 @@ const obj: BigNestedObject = {
</head>
<body>
<main>
- <Component client:load obj={obj} num={11n} arr={[0, "foo"]} />
+ <Component client:load obj={obj} num={11n} arr={[0, "foo"]} map={map} set={set} />
</main>
</body>
</html>
diff --git a/packages/astro/e2e/pass-js.test.js b/packages/astro/e2e/pass-js.test.js
index 51c4d83de..c3e86888a 100644
--- a/packages/astro/e2e/pass-js.test.js
+++ b/packages/astro/e2e/pass-js.test.js
@@ -1,7 +1,9 @@
import { expect } from '@playwright/test';
import { testFactory } from './test-utils.js';
-const test = testFactory({ root: './fixtures/pass-js/' });
+const test = testFactory({
+ root: './fixtures/pass-js/'
+});
let devServer;
@@ -53,4 +55,24 @@ test.describe('Passing JS into client components', () => {
await expect(arrValue, 'is visible').toBeVisible();
await expect(arrValue).toHaveText('0,foo');
});
+
+ test('Maps and Sets', async ({ page }) => {
+ await page.goto('/');
+
+ const mapType = page.locator('#map-type');
+ await expect(mapType, 'is visible').toBeVisible();
+ await expect(mapType).toHaveText('[object Map]');
+
+ const mapValues = page.locator('#map-items li');
+ expect(await mapValues.count()).toEqual(2);
+
+ const texts = await mapValues.allTextContents();
+ expect(texts).toEqual(['test1: test2', 'test3: test4']);
+
+ const setType = page.locator('#set-type');
+ await expect(setType, 'is visible').toBeVisible();
+
+ const setValue = page.locator('#set-value');
+ await expect(setValue).toHaveText('test1,test2');
+ });
});
diff --git a/packages/astro/src/runtime/server/serialize.ts b/packages/astro/src/runtime/server/serialize.ts
index 59ce96d8d..21996a932 100644
--- a/packages/astro/src/runtime/server/serialize.ts
+++ b/packages/astro/src/runtime/server/serialize.ts
@@ -33,10 +33,10 @@ function convertToSerializedForm(value: any): [ValueOf<typeof PROP_TYPE>, any] {
return [PROP_TYPE.RegExp, (value as RegExp).source];
}
case '[object Map]': {
- return [PROP_TYPE.Map, Array.from(value as Map<any, any>)];
+ return [PROP_TYPE.Map, JSON.stringify(serializeArray(Array.from(value as Map<any, any>)))];
}
case '[object Set]': {
- return [PROP_TYPE.Set, Array.from(value as Set<any>)];
+ return [PROP_TYPE.Set, JSON.stringify(serializeArray(Array.from(value as Set<any>)))];
}
case '[object BigInt]': {
return [PROP_TYPE.BigInt, (value as bigint).toString()];