Skip to content

Commit

Permalink
Merge branch 'main' into fix/vue-types-with-multiple-script-blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
Princesseuh authored Nov 8, 2023
2 parents ab1b88a + d979b8f commit b450334
Show file tree
Hide file tree
Showing 33 changed files with 806 additions and 81 deletions.
5 changes: 5 additions & 0 deletions .changeset/eighty-ladybugs-shake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Fixes an error in dev mode on Safari where view transitions prevented navigating to pages with `client:only` components
5 changes: 5 additions & 0 deletions .changeset/rude-eggs-hunt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"astro": patch
---

Add animations, shadows and general styling tweaks to the Dev Overlay to better match the intended design.
5 changes: 5 additions & 0 deletions .changeset/strange-toes-remain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Adds compatibility for shiki languages with the `path` property
7 changes: 7 additions & 0 deletions .changeset/tricky-clocks-end.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@astrojs/vercel': minor
---

The Vercel adapter now streams responses!

This brings better performance to your visitors by showing them content as it is rendered. The browser can also start loading the required stylesheets and scripts much sooner, which ultimately results in faster full page loads.
24 changes: 22 additions & 2 deletions packages/astro/components/Code.astro
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
---
import path from 'node:path';
import fs from 'node:fs';
import { fileURLToPath } from 'node:url';
import type {
BuiltinLanguage,
BuiltinTheme,
Expand Down Expand Up @@ -56,8 +59,25 @@ const {
// shiki -> shikiji compat
if (typeof lang === 'object') {
// `id` renamed to `name
if ((lang as any).id && !lang.name) {
// shikiji does not support `path`
// https://github.com/shikijs/shiki/blob/facb6ff37996129626f8066a5dccb4608e45f649/packages/shiki/src/loader.ts#L98
const langPath = (lang as any).path;
if (langPath) {
// shiki resolves path from within its package directory :shrug:
const astroRoot = fileURLToPath(new URL('../', import.meta.url));
const normalizedPath = path.isAbsolute(langPath) ? langPath : path.resolve(astroRoot, langPath);
try {
const content = fs.readFileSync(normalizedPath, 'utf-8');
const parsed = JSON.parse(content);
Object.assign(lang, parsed);
} catch (e) {
throw new Error(`Unable to find language file at ${normalizedPath}`, {
cause: e,
});
}
}
// `id` renamed to `name` (always override)
if ((lang as any).id) {
lang.name = (lang as any).id;
}
// `grammar` flattened to lang itself
Expand Down
1 change: 1 addition & 0 deletions packages/astro/src/@types/astro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2318,6 +2318,7 @@ export interface DevOverlayPlugin {
name: string;
icon: Icon;
init?(canvas: ShadowRoot, eventTarget: EventTarget): void | Promise<void>;
beforeTogglingOff?(canvas: ShadowRoot): boolean | Promise<boolean>;
}

export type DevOverlayMetadata = Window &
Expand Down
26 changes: 23 additions & 3 deletions packages/astro/src/core/config/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import { markdownConfigDefaults } from '@astrojs/markdown-remark';
import { bundledThemes, type BuiltinTheme } from 'shikiji';
import type { AstroUserConfig, ViteUserConfig } from '../../@types/astro.js';

import fs from 'node:fs';
import type { OutgoingHttpHeaders } from 'node:http';
import path from 'node:path';
import { pathToFileURL } from 'node:url';
import { fileURLToPath, pathToFileURL } from 'node:url';
import { z } from 'zod';
import { appendForwardSlash, prependForwardSlash, removeTrailingForwardSlash } from '../path.js';

Expand Down Expand Up @@ -247,8 +248,27 @@ export const AstroConfigSchema = z.object({
for (const lang of langs) {
// shiki -> shikiji compat
if (typeof lang === 'object') {
// `id` renamed to `name
if ((lang as any).id && !lang.name) {
// shikiji does not support `path`
// https://github.com/shikijs/shiki/blob/facb6ff37996129626f8066a5dccb4608e45f649/packages/shiki/src/loader.ts#L98
const langPath = (lang as any).path;
if (langPath) {
// shiki resolves path from within its package directory :shrug:
const astroRoot = fileURLToPath(new URL('../../../', import.meta.url));
const normalizedPath = path.isAbsolute(langPath)
? langPath
: path.resolve(astroRoot, langPath);
try {
const content = fs.readFileSync(normalizedPath, 'utf-8');
const parsed = JSON.parse(content);
Object.assign(lang, parsed);
} catch (e) {
throw new Error(`Unable to find language file at ${normalizedPath}`, {
cause: e,
});
}
}
// `id` renamed to `name` (always override)
if ((lang as any).id) {
lang.name = (lang as any).id;
}
// `grammar` flattened to lang itself
Expand Down
6 changes: 4 additions & 2 deletions packages/astro/src/core/preview/static-preview-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export default async function createStaticPreviewServer(
null,
msg.serverStart({
startupTime: performance.now() - startServerTime,
resolvedUrls: previewServer.resolvedUrls,
resolvedUrls: previewServer.resolvedUrls ?? { local: [], network: [] },
host: settings.config.server.host,
base: settings.config.base,
})
Expand All @@ -72,7 +72,9 @@ export default async function createStaticPreviewServer(
host: getResolvedHostForHttpServer(settings.config.server.host),
port: settings.config.server.port,
closed,
server: previewServer.httpServer,
// In Vite 5, `httpServer` may be a `Http2SecureServer`, but we know we are only starting a HTTP server
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
server: previewServer.httpServer as http.Server,
stop: async () => {
await new Promise((resolve, reject) => {
previewServer.httpServer.destroy((err) => (err ? reject(err) : resolve(undefined)));
Expand Down
20 changes: 17 additions & 3 deletions packages/astro/src/core/preview/vite-plugin-astro-preview.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import fs from 'node:fs';
import { fileURLToPath } from 'node:url';
import type { Plugin } from 'vite';
import type { Connect, Plugin } from 'vite';
import { version } from 'vite';
import type { AstroSettings } from '../../@types/astro.js';
import { notFoundTemplate, subpathNotUsedTemplate } from '../../template/4xx.js';
import { stripBase } from './util.js';

const HAS_FILE_EXTENSION_REGEXP = /^.*\.[^\\]+$/;
const IS_VITE_5 = version.startsWith('5.');

export function vitePluginAstroPreview(settings: AstroSettings): Plugin {
const { base, outDir, trailingSlash } = settings.config;
Expand Down Expand Up @@ -50,7 +52,7 @@ export function vitePluginAstroPreview(settings: AstroSettings): Plugin {
});

return () => {
server.middlewares.use((req, res) => {
const fourOhFourMiddleware: Connect.NextHandleFunction = (req, res) => {
const errorPagePath = fileURLToPath(outDir + '/404.html');
if (fs.existsSync(errorPagePath)) {
res.statusCode = 404;
Expand All @@ -61,7 +63,19 @@ export function vitePluginAstroPreview(settings: AstroSettings): Plugin {
res.statusCode = 404;
res.end(notFoundTemplate(pathname, 'Not Found'));
}
});
};

// Vite 5 has its own 404 middleware, we replace it with ours instead.
if (IS_VITE_5) {
for (const middleware of server.middlewares.stack) {
// This hardcoded name will not break between Vite versions
if ((middleware.handle as Connect.HandleFunction).name === 'vite404Middleware') {
middleware.handle = fourOhFourMiddleware;
}
}
} else {
server.middlewares.use(fourOhFourMiddleware);
}
};
},
};
Expand Down
4 changes: 2 additions & 2 deletions packages/astro/src/runtime/client/dev-overlay/entrypoint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,13 @@ document.addEventListener('DOMContentLoaded', async () => {
target.querySelector('.notification')?.toggleAttribute('data-active', newState);
});

eventTarget.addEventListener('toggle-plugin', (evt) => {
eventTarget.addEventListener('toggle-plugin', async (evt) => {
let newState = undefined;
if (evt instanceof CustomEvent) {
newState = evt.detail.state ?? true;
}

overlay.togglePluginStatus(plugin, newState);
await overlay.togglePluginStatus(plugin, newState);
});

return plugin;
Expand Down
80 changes: 51 additions & 29 deletions packages/astro/src/runtime/client/dev-overlay/overlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export class AstroDevOverlay extends HTMLElement {
display: flex;
gap: 8px;
align-items: center;
transition: bottom 0.2s ease-in-out;
transition: bottom 0.35s cubic-bezier(0.485, -0.050, 0.285, 1.505);
pointer-events: none;
}
Expand All @@ -72,11 +72,10 @@ export class AstroDevOverlay extends HTMLElement {
height: 56px;
overflow: hidden;
pointer-events: auto;
background: linear-gradient(180deg, #13151A 0%, rgba(19, 21, 26, 0.88) 100%);
box-shadow: 0px 0px 0px 0px #13151A4D;
border: 1px solid #343841;
border-radius: 9999px;
box-shadow: 0px 0px 0px 0px rgba(19, 21, 26, 0.30), 0px 1px 2px 0px rgba(19, 21, 26, 0.29), 0px 4px 4px 0px rgba(19, 21, 26, 0.26), 0px 10px 6px 0px rgba(19, 21, 26, 0.15), 0px 17px 7px 0px rgba(19, 21, 26, 0.04), 0px 26px 7px 0px rgba(19, 21, 26, 0.01);
}
#dev-bar .item {
Expand Down Expand Up @@ -187,16 +186,6 @@ export class AstroDevOverlay extends HTMLElement {
width: 1px;
}
astro-dev-overlay-plugin-canvas {
position: absolute;
top: 0;
left: 0;
}
astro-dev-overlay-plugin-canvas:not([data-active]) {
display: none;
}
#minimize-button {
width: 32px;
height: 32px;
Expand Down Expand Up @@ -263,15 +252,15 @@ export class AstroDevOverlay extends HTMLElement {
}

// Create plugin canvases
this.plugins.forEach((plugin) => {
this.plugins.forEach(async (plugin) => {
if (!this.hasBeenInitialized) {
console.log(`Creating plugin canvas for ${plugin.id}`);
const pluginCanvas = document.createElement('astro-dev-overlay-plugin-canvas');
pluginCanvas.dataset.pluginId = plugin.id;
this.shadowRoot?.append(pluginCanvas);
}

this.togglePluginStatus(plugin, plugin.active);
await this.togglePluginStatus(plugin, plugin.active);
});

// Init plugin lazily - This is safe to do here because only plugins that are not initialized yet will be affected
Expand Down Expand Up @@ -306,7 +295,7 @@ export class AstroDevOverlay extends HTMLElement {
await this.initPlugin(plugin);
}

this.togglePluginStatus(plugin);
await this.togglePluginStatus(plugin);
});
});

Expand Down Expand Up @@ -418,30 +407,52 @@ export class AstroDevOverlay extends HTMLElement {
}

getPluginCanvasById(id: string) {
return this.shadowRoot.querySelector(`astro-dev-overlay-plugin-canvas[data-plugin-id="${id}"]`);
return this.shadowRoot.querySelector<HTMLElement>(
`astro-dev-overlay-plugin-canvas[data-plugin-id="${id}"]`
);
}

togglePluginStatus(plugin: DevOverlayPlugin, status?: boolean) {
plugin.active = status ?? !plugin.active;
/**
* @param plugin The plugin to toggle the status of
* @param newStatus Optionally, force the plugin into a specific state
*/
async togglePluginStatus(plugin: DevOverlayPlugin, newStatus?: boolean) {
const pluginCanvas = this.getPluginCanvasById(plugin.id);
if (!pluginCanvas) return;

if (plugin.active && !newStatus && plugin.beforeTogglingOff) {
const shouldToggleOff = await plugin.beforeTogglingOff(pluginCanvas.shadowRoot!);

// If the plugin returned false, don't toggle it off, maybe the plugin showed a confirmation dialog or similar
if (!shouldToggleOff) return;
}

plugin.active = newStatus ?? !plugin.active;
const target = this.shadowRoot.querySelector(`[data-plugin-id="${plugin.id}"]`);
if (!target) return;
target.classList.toggle('active', plugin.active);
this.getPluginCanvasById(plugin.id)?.toggleAttribute('data-active', plugin.active);

plugin.eventTarget.dispatchEvent(
new CustomEvent('plugin-toggled', {
detail: {
state: plugin.active,
plugin,
},
})
);
pluginCanvas.style.display = plugin.active ? 'block' : 'none';

window.requestAnimationFrame(() => {
pluginCanvas.toggleAttribute('data-active', plugin.active);
plugin.eventTarget.dispatchEvent(
new CustomEvent('plugin-toggled', {
detail: {
state: plugin.active,
plugin,
},
})
);
});

if (import.meta.hot) {
import.meta.hot.send(`${WS_EVENT_NAME}:${plugin.id}:toggled`, { state: plugin.active });
}
}

/**
* @param newStatus Optionally, force the minimize button into a specific state
*/
toggleMinimizeButton(newStatus?: boolean) {
const minimizeButton = this.shadowRoot.querySelector<HTMLDivElement>('#minimize-button');
if (!minimizeButton) return;
Expand Down Expand Up @@ -493,4 +504,15 @@ export class DevOverlayCanvas extends HTMLElement {
super();
this.shadowRoot = this.attachShadow({ mode: 'open' });
}

connectedCallback() {
this.shadowRoot.innerHTML = `
<style>
:host {
position: absolute;
top: 0;
left: 0;
}
</style>`;
}
}
Loading

0 comments on commit b450334

Please sign in to comment.