Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: wait for content layer sync before starting dev server #12818

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/mighty-pugs-retire.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Fixes race condition where dev server would attempt to load collections before the content had loaded
5 changes: 2 additions & 3 deletions packages/astro/e2e/actions-blog.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ test.afterAll(async () => {

test.afterEach(async ({ astro }) => {
// Force database reset between tests
await astro.editFile('./db/seed.ts', (original) => original);
await astro.editFile('./db/seed.ts', (original) => original, false);
});

test.describe('Astro Actions - Blog', () => {
test('Like action', async ({ page, astro }) => {
await page.goto(astro.resolveUrl('/blog/first-post/'));

const likeButton = page.getByLabel('Like');
await waitForHydrate(page, likeButton);
await new Promise(resolve => setTimeout(resolve, 500))
await expect(likeButton, 'like button starts with 10 likes').toContainText('10');
await likeButton.click();
await expect(likeButton, 'like button should increment likes').toContainText('11');
Expand All @@ -34,7 +34,6 @@ test.describe('Astro Actions - Blog', () => {

const likeButton = page.getByLabel('get-request');
const likeCount = page.getByLabel('Like');

await expect(likeCount, 'like button starts with 10 likes').toContainText('10');
await likeButton.click();
await expect(likeCount, 'like button should increment likes').toContainText('11');
Expand Down
4 changes: 2 additions & 2 deletions packages/astro/e2e/actions-react-19.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ test.beforeAll(async ({ astro }) => {

test.afterEach(async ({ astro }) => {
// Force database reset between tests
await astro.editFile('./db/seed.ts', (original) => original);
await astro.editFile('./db/seed.ts', (original) => original, false);
});

test.afterAll(async () => {
Expand All @@ -21,9 +21,9 @@ test.afterAll(async () => {
test.describe('Astro Actions - React 19', () => {
test('Like action - client pending state', async ({ page, astro }) => {
await page.goto(astro.resolveUrl('/blog/first-post/'));

const likeButton = page.getByLabel('likes-client');
await waitForHydrate(page, likeButton);
await new Promise(resolve => setTimeout(resolve, 500))

await expect(likeButton).toBeVisible();
await likeButton.click();
Expand Down
4 changes: 2 additions & 2 deletions packages/astro/src/content/content-layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,11 +173,11 @@ export class ContentLayer {
shouldClear = true;
}

if (currentConfigDigest && previousConfigDigest !== currentConfigDigest) {
if (previousConfigDigest && previousConfigDigest !== currentConfigDigest) {
logger.info('Content config changed');
shouldClear = true;
}
if (process.env.ASTRO_VERSION && previousAstroVersion !== process.env.ASTRO_VERSION) {
if (previousAstroVersion && previousAstroVersion !== process.env.ASTRO_VERSION) {
logger.info('Astro version changed');
shouldClear = true;
}
Expand Down
44 changes: 23 additions & 21 deletions packages/astro/src/core/dev/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,27 +84,6 @@ export default async function dev(inlineConfig: AstroInlineConfig): Promise<DevS
}
}

// Start listening to the port
const devServerAddressInfo = await startContainer(restart.container);
logger.info(
'SKIP_FORMAT',
msg.serverStart({
startupTime: performance.now() - devStart,
resolvedUrls: restart.container.viteServer.resolvedUrls || { local: [], network: [] },
host: restart.container.settings.config.server.host,
base: restart.container.settings.config.base,
}),
);

if (isPrerelease) {
logger.warn('SKIP_FORMAT', msg.prerelease({ currentVersion }));
}
if (restart.container.viteServer.config.server?.fs?.strict === false) {
logger.warn('SKIP_FORMAT', msg.fsStrictWarning());
}

await attachContentServerListeners(restart.container);

let store: MutableDataStore | undefined;
try {
const dataStoreFile = getDataStoreFile(restart.container.settings, true);
Expand All @@ -117,6 +96,7 @@ export default async function dev(inlineConfig: AstroInlineConfig): Promise<DevS
if (!store) {
store = new MutableDataStore();
}
await attachContentServerListeners(restart.container);

const config = globalContentConfigObserver.get();
if (config.status === 'error') {
Expand All @@ -131,8 +111,30 @@ export default async function dev(inlineConfig: AstroInlineConfig): Promise<DevS
});
contentLayer.watchContentConfig();
await contentLayer.sync();
} else {
logger.warn('content', 'Content config not loaded');
}

// Start listening to the port
const devServerAddressInfo = await startContainer(restart.container);
logger.info(
'SKIP_FORMAT',
msg.serverStart({
startupTime: performance.now() - devStart,
resolvedUrls: restart.container.viteServer.resolvedUrls || { local: [], network: [] },
host: restart.container.settings.config.server.host,
base: restart.container.settings.config.base,
}),
);

if (isPrerelease) {
logger.warn('SKIP_FORMAT', msg.prerelease({ currentVersion }));
}
if (restart.container.viteServer.config.server?.fs?.strict === false) {
logger.warn('SKIP_FORMAT', msg.fsStrictWarning());
}


logger.info(null, green('watching for file changes...'));

return {
Expand Down
5 changes: 3 additions & 2 deletions packages/astro/test/test-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ export async function loadFixture(inlineConfig) {
devServer = await dev(mergeConfig(inlineConfig, extraInlineConfig));
config.server.host = parseAddressToHost(devServer.address.address); // update host
config.server.port = devServer.address.port; // update port
await new Promise(resolve => setTimeout(resolve, 100))
return devServer;
},
onNextDataStoreChange: (timeout = 5000) => {
Expand Down Expand Up @@ -284,7 +285,7 @@ export async function loadFixture(inlineConfig) {
app.manifest = manifest;
return app;
},
editFile: async (filePath, newContentsOrCallback) => {
editFile: async (filePath, newContentsOrCallback, waitForNextWrite = true) => {
const fileUrl = new URL(filePath.replace(/^\//, ''), config.root);
const contents = await fs.promises.readFile(fileUrl, 'utf-8');
const reset = () => {
Expand All @@ -299,7 +300,7 @@ export async function loadFixture(inlineConfig) {
typeof newContentsOrCallback === 'function'
? newContentsOrCallback(contents)
: newContentsOrCallback;
const nextChange = devServer ? onNextChange() : Promise.resolve();
const nextChange = devServer && waitForNextWrite ? onNextChange() : Promise.resolve();
await fs.promises.writeFile(fileUrl, newContents);
await nextChange;
return reset;
Expand Down
Loading