0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2024-12-16 21:46:22 -05:00

[ci] format

This commit is contained in:
Matthew Phillips 2024-07-17 17:38:27 +00:00 committed by astrobot-houston
parent d495df5361
commit b46a78e1c9
26 changed files with 1602 additions and 1319 deletions

File diff suppressed because it is too large Load diff

View file

@ -1 +1,11 @@
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} {
"name": "",
"short_name": "",
"icons": [
{ "src": "/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" }
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"display": "standalone"
}

View file

@ -1,32 +1,32 @@
@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap"); @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700&display=swap');
@tailwind base; @tailwind base;
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
@layer base { @layer base {
body { body {
@apply font-poppins; @apply font-poppins;
} }
h1, h1,
h2, h2,
h3, h3,
h4, h4,
h5, h5,
h6 { h6 {
@apply font-roboto; @apply font-roboto;
} }
} }
@layer components { @layer components {
.size-selector input:checked + label { .size-selector input:checked + label {
@apply bg-primary text-white; @apply bg-primary text-white;
} }
.color-selector input:checked + label { .color-selector input:checked + label {
@apply ring-2 ring-primary; @apply ring-2 ring-primary;
} }
.input-box { .input-box {
@apply block w-full border border-gray-300 px-4 py-3 text-gray-600 text-sm rounded placeholder-gray-400 focus:border-primary focus:ring-0; @apply block w-full border border-gray-300 px-4 py-3 text-gray-600 text-sm rounded placeholder-gray-400 focus:border-primary focus:ring-0;
} }
} }

View file

@ -5,28 +5,32 @@ const { placeholder } = Astro.props;
let wishlist = 0; let wishlist = 0;
let cart = 0; let cart = 0;
if(!placeholder) { if (!placeholder) {
await new Promise(resolve => setTimeout(resolve, 3000)); await new Promise((resolve) => setTimeout(resolve, 3000));
} }
--- ---
<a href="#" class="text-center text-gray-700 hover:text-primary transition relative"> <a href="#" class="text-center text-gray-700 hover:text-primary transition relative">
<div class="text-2xl"> <div class="text-2xl">
<i class="fa-regular fa-heart"></i> <i class="fa-regular fa-heart"></i>
</div> </div>
<div class="text-xs leading-3">Wishlist</div> <div class="text-xs leading-3">Wishlist</div>
<div <div
class="absolute right-0 -top-1 w-5 h-5 rounded-full flex items-center justify-center bg-primary text-white text-xs">{ wishlist }</div> class="absolute right-0 -top-1 w-5 h-5 rounded-full flex items-center justify-center bg-primary text-white text-xs"
>
{wishlist}
</div>
</a> </a>
<a href="#" class="text-center text-gray-700 hover:text-primary transition relative"> <a href="#" class="text-center text-gray-700 hover:text-primary transition relative">
<div class="text-2xl"> <div class="text-2xl">
<i class="fa-solid fa-bag-shopping"></i> <i class="fa-solid fa-bag-shopping"></i>
</div> </div>
<div class="text-xs leading-3">Cart</div> <div class="text-xs leading-3">Cart</div>
<CartCount client:load count={cart} /> <CartCount client:load count={cart} />
</a> </a>
<a href="#" class="text-center text-gray-700 hover:text-primary transition relative"> <a href="#" class="text-center text-gray-700 hover:text-primary transition relative">
<div class="text-2xl"> <div class="text-2xl">
<i class="fa-regular fa-user"></i> <i class="fa-regular fa-user"></i>
</div> </div>
<div class="text-xs leading-3">Account</div> <div class="text-xs leading-3">Account</div>
</a> </a>

File diff suppressed because it is too large Load diff

View file

@ -2254,7 +2254,7 @@ export interface AstroUserConfig {
* #### Server island fallback content * #### Server island fallback content
* *
* Since your component will not render with the rest of the page, you may want to add generic content (e.g. a loading message) to temporarily show in its place. This content will be displayed when the page first renders but before the island has loaded. * Since your component will not render with the rest of the page, you may want to add generic content (e.g. a loading message) to temporarily show in its place. This content will be displayed when the page first renders but before the island has loaded.
* *
* Add placeholder content as a child of your Astro component with the `slot="fallback:` attribute. When your island content is available, the fallback content will be replaced. * Add placeholder content as a child of your Astro component with the `slot="fallback:` attribute. When your island content is available, the fallback content will be replaced.
* *
* The example below displays a generic avatar as fallback content, then animates into a personalized avatar using view transitions: * The example below displays a generic avatar as fallback content, then animates into a personalized avatar using view transitions:
@ -3377,7 +3377,6 @@ export interface SSRMetadata {
headInTree: boolean; headInTree: boolean;
extraHead: string[]; extraHead: string[];
propagators: Set<AstroComponentInstance>; propagators: Set<AstroComponentInstance>;
} }
/* Preview server stuff */ /* Preview server stuff */

View file

@ -11,6 +11,7 @@ import { appendForwardSlash, removeFileExtension } from '../core/path.js';
import { isServerLikeOutput } from '../core/util.js'; import { isServerLikeOutput } from '../core/util.js';
import { rootRelativePath } from '../core/viteUtils.js'; import { rootRelativePath } from '../core/viteUtils.js';
import type { AstroPluginMetadata } from '../vite-plugin-astro/index.js'; import type { AstroPluginMetadata } from '../vite-plugin-astro/index.js';
import { createDefaultAstroMetadata } from '../vite-plugin-astro/metadata.js';
import { import {
CONTENT_FLAG, CONTENT_FLAG,
CONTENT_RENDER_FLAG, CONTENT_RENDER_FLAG,
@ -30,7 +31,6 @@ import {
getEntryType, getEntryType,
getExtGlob, getExtGlob,
} from './utils.js'; } from './utils.js';
import { createDefaultAstroMetadata } from '../vite-plugin-astro/metadata.js';
interface AstroContentVirtualModPluginParams { interface AstroContentVirtualModPluginParams {
settings: AstroSettings; settings: AstroSettings;

View file

@ -99,11 +99,11 @@ export class AppPipeline extends Pipeline {
} }
async getModuleForRoute(route: RouteData): Promise<SinglePageBuiltModule> { async getModuleForRoute(route: RouteData): Promise<SinglePageBuiltModule> {
for(const defaultRoute of this.defaultRoutes) { for (const defaultRoute of this.defaultRoutes) {
if(route.component === defaultRoute.component) { if (route.component === defaultRoute.component) {
return { return {
page: () => Promise.resolve(defaultRoute.instance), page: () => Promise.resolve(defaultRoute.instance),
renderers: [] renderers: [],
}; };
} }
} }

View file

@ -1,5 +1,5 @@
import type { import type {
ComponentInstance, ComponentInstance,
Locales, Locales,
MiddlewareHandler, MiddlewareHandler,
RouteData, RouteData,
@ -84,7 +84,13 @@ export type SSRManifestI18n = {
export type SerializedSSRManifest = Omit< export type SerializedSSRManifest = Omit<
SSRManifest, SSRManifest,
'middleware' | 'routes' | 'assets' | 'componentMetadata' | 'inlinedScripts' | 'clientDirectives' | 'serverIslandNameMap' | 'middleware'
| 'routes'
| 'assets'
| 'componentMetadata'
| 'inlinedScripts'
| 'clientDirectives'
| 'serverIslandNameMap'
> & { > & {
routes: SerializedRouteInfo[]; routes: SerializedRouteInfo[];
assets: string[]; assets: string[];

View file

@ -272,8 +272,8 @@ export class BuildPipeline extends Pipeline {
return await entry.page(); return await entry.page();
} }
for(const route of this.defaultRoutes) { for (const route of this.defaultRoutes) {
if(route.component === routeData.component) { if (route.component === routeData.component) {
return route.instance; return route.instance;
} }
} }

View file

@ -4,6 +4,7 @@ import type { Plugin as VitePlugin } from 'vite';
import type { AstroAdapter, AstroSettings } from '../../../@types/astro.js'; import type { AstroAdapter, AstroSettings } from '../../../@types/astro.js';
import { isFunctionPerRouteEnabled } from '../../../integrations/hooks.js'; import { isFunctionPerRouteEnabled } from '../../../integrations/hooks.js';
import { routeIsRedirect } from '../../redirects/index.js'; import { routeIsRedirect } from '../../redirects/index.js';
import { VIRTUAL_ISLAND_MAP_ID } from '../../server-islands/vite-plugin-server-islands.js';
import { isServerLikeOutput } from '../../util.js'; import { isServerLikeOutput } from '../../util.js';
import { addRollupInput } from '../add-rollup-input.js'; import { addRollupInput } from '../add-rollup-input.js';
import type { BuildInternals } from '../internal.js'; import type { BuildInternals } from '../internal.js';
@ -13,7 +14,6 @@ import { SSR_MANIFEST_VIRTUAL_MODULE_ID } from './plugin-manifest.js';
import { MIDDLEWARE_MODULE_ID } from './plugin-middleware.js'; import { MIDDLEWARE_MODULE_ID } from './plugin-middleware.js';
import { ASTRO_PAGE_MODULE_ID } from './plugin-pages.js'; import { ASTRO_PAGE_MODULE_ID } from './plugin-pages.js';
import { RENDERERS_MODULE_ID } from './plugin-renderers.js'; import { RENDERERS_MODULE_ID } from './plugin-renderers.js';
import { VIRTUAL_ISLAND_MAP_ID } from '../../server-islands/vite-plugin-server-islands.js';
import { getComponentFromVirtualModulePageName, getVirtualModulePageName } from './util.js'; import { getComponentFromVirtualModulePageName, getVirtualModulePageName } from './util.js';
export const SSR_VIRTUAL_MODULE_ID = '@astrojs-ssr-virtual-entry'; export const SSR_VIRTUAL_MODULE_ID = '@astrojs-ssr-virtual-entry';
@ -250,7 +250,9 @@ function generateSSRCode(settings: AstroSettings, adapter: AstroAdapter, middlew
`import { manifest as defaultManifest } from '${SSR_MANIFEST_VIRTUAL_MODULE_ID}';`, `import { manifest as defaultManifest } from '${SSR_MANIFEST_VIRTUAL_MODULE_ID}';`,
`import * as serverEntrypointModule from '${adapter.serverEntrypoint}';`, `import * as serverEntrypointModule from '${adapter.serverEntrypoint}';`,
edgeMiddleware ? `` : `import { onRequest as middleware } from '${middlewareId}';`, edgeMiddleware ? `` : `import { onRequest as middleware } from '${middlewareId}';`,
settings.config.experimental.serverIslands ? `import { serverIslandMap } from '${VIRTUAL_ISLAND_MAP_ID}';` : '' settings.config.experimental.serverIslands
? `import { serverIslandMap } from '${VIRTUAL_ISLAND_MAP_ID}';`
: '',
]; ];
const contents = [ const contents = [

View file

@ -540,7 +540,10 @@ export const AstroConfigSchema = z.object({
}) })
.strict() .strict()
.optional(), .optional(),
serverIslands: z.boolean().optional().default(ASTRO_CONFIG_DEFAULTS.experimental.serverIslands), serverIslands: z
.boolean()
.optional()
.default(ASTRO_CONFIG_DEFAULTS.experimental.serverIslands),
}) })
.strict( .strict(
`Invalid or outdated experimental feature.\nCheck for incorrect spelling or outdated Astro version.\nSee https://docs.astro.build/en/reference/configuration-reference/#experimental-flags for a list of all current experiments.` `Invalid or outdated experimental feature.\nCheck for incorrect spelling or outdated Astro version.\nSee https://docs.astro.build/en/reference/configuration-reference/#experimental-flags for a list of all current experiments.`

View file

@ -36,8 +36,8 @@ import { vitePluginSSRManifest } from '../vite-plugin-ssr-manifest/index.js';
import type { Logger } from './logger/core.js'; import type { Logger } from './logger/core.js';
import { createViteLogger } from './logger/vite.js'; import { createViteLogger } from './logger/vite.js';
import { vitePluginMiddleware } from './middleware/vite-plugin.js'; import { vitePluginMiddleware } from './middleware/vite-plugin.js';
import { vitePluginServerIslands } from './server-islands/vite-plugin-server-islands.js';
import { joinPaths } from './path.js'; import { joinPaths } from './path.js';
import { vitePluginServerIslands } from './server-islands/vite-plugin-server-islands.js';
import { isObject } from './util.js'; import { isObject } from './util.js';
interface CreateViteOptions { interface CreateViteOptions {

View file

@ -1,7 +1,16 @@
import type { ComponentInstance, ManifestData, SSRManifest, } from "../../@types/astro.js"; import type { ComponentInstance, ManifestData, SSRManifest } from '../../@types/astro.js';
import { DEFAULT_404_COMPONENT } from "../constants.js"; import { DEFAULT_404_COMPONENT } from '../constants.js';
import { ensureServerIslandRoute, createEndpoint as createServerIslandEndpoint, SERVER_ISLAND_ROUTE, SERVER_ISLAND_COMPONENT } from "../server-islands/endpoint.js"; import {
import { ensure404Route, default404Instance, DEFAULT_404_ROUTE } from './astro-designed-error-pages.js'; SERVER_ISLAND_COMPONENT,
SERVER_ISLAND_ROUTE,
createEndpoint as createServerIslandEndpoint,
ensureServerIslandRoute,
} from '../server-islands/endpoint.js';
import {
DEFAULT_404_ROUTE,
default404Instance,
ensure404Route,
} from './astro-designed-error-pages.js';
export function injectDefaultRoutes(manifest: ManifestData) { export function injectDefaultRoutes(manifest: ManifestData) {
ensure404Route(manifest); ensure404Route(manifest);
@ -14,7 +23,7 @@ type DefaultRouteParams = {
matchesComponent(filePath: URL): boolean; matchesComponent(filePath: URL): boolean;
route: string; route: string;
component: string; component: string;
} };
export function createDefaultRoutes(manifest: SSRManifest, root: URL): DefaultRouteParams[] { export function createDefaultRoutes(manifest: SSRManifest, root: URL): DefaultRouteParams[] {
return [ return [
@ -29,6 +38,6 @@ export function createDefaultRoutes(manifest: SSRManifest, root: URL): DefaultRo
matchesComponent: (filePath) => filePath.href === new URL(SERVER_ISLAND_COMPONENT, root).href, matchesComponent: (filePath) => filePath.href === new URL(SERVER_ISLAND_COMPONENT, root).href,
route: SERVER_ISLAND_ROUTE, route: SERVER_ISLAND_ROUTE,
component: SERVER_ISLAND_COMPONENT, component: SERVER_ISLAND_COMPONENT,
} },
]; ];
} }

View file

@ -1,5 +1,15 @@
import { renderComponent, renderTemplate, type AstroComponentFactory, type ComponentSlots } from '../../runtime/server/index.js'; import type {
import type { ComponentInstance, ManifestData, RouteData, SSRManifest } from '../../@types/astro.js'; ComponentInstance,
ManifestData,
RouteData,
SSRManifest,
} from '../../@types/astro.js';
import {
type AstroComponentFactory,
type ComponentSlots,
renderComponent,
renderTemplate,
} from '../../runtime/server/index.js';
import { createSlotValueFromString } from '../../runtime/server/render/slot.js'; import { createSlotValueFromString } from '../../runtime/server/render/slot.js';
export const SERVER_ISLAND_ROUTE = '/_server-islands/[name]'; export const SERVER_ISLAND_ROUTE = '/_server-islands/[name]';
@ -17,7 +27,7 @@ export function ensureServerIslandRoute(manifest: ManifestData) {
params: ['name'], params: ['name'],
segments: [ segments: [
[{ content: '_server-islands', dynamic: false, spread: false }], [{ content: '_server-islands', dynamic: false, spread: false }],
[{ content: 'name', dynamic: true, spread: false }] [{ content: 'name', dynamic: true, spread: false }],
], ],
// eslint-disable-next-line // eslint-disable-next-line
pattern: /^\/_server-islands\/([^/]+?)$/, pattern: /^\/_server-islands\/([^/]+?)$/,
@ -25,7 +35,7 @@ export function ensureServerIslandRoute(manifest: ManifestData) {
isIndex: false, isIndex: false,
fallbackRoutes: [], fallbackRoutes: [],
route: SERVER_ISLAND_ROUTE, route: SERVER_ISLAND_ROUTE,
} };
manifest.routes.push(route); manifest.routes.push(route);
} }
@ -34,7 +44,7 @@ type RenderOptions = {
componentExport: string; componentExport: string;
props: Record<string, any>; props: Record<string, any>;
slots: Record<string, string>; slots: Record<string, string>;
} };
export function createEndpoint(manifest: SSRManifest) { export function createEndpoint(manifest: SSRManifest) {
const page: AstroComponentFactory = async (result) => { const page: AstroComponentFactory = async (result) => {
@ -42,19 +52,19 @@ export function createEndpoint(manifest: SSRManifest) {
const request = result.request; const request = result.request;
const raw = await request.text(); const raw = await request.text();
const data = JSON.parse(raw) as RenderOptions; const data = JSON.parse(raw) as RenderOptions;
if(!params.name) { if (!params.name) {
return new Response(null, { return new Response(null, {
status: 400, status: 400,
statusText: 'Bad request' statusText: 'Bad request',
}); });
} }
const componentId = params.name; const componentId = params.name;
const imp = manifest.serverIslandMap?.get(componentId); const imp = manifest.serverIslandMap?.get(componentId);
if(!imp) { if (!imp) {
return new Response(null, { return new Response(null, {
status: 404, status: 404,
statusText: 'Not found' statusText: 'Not found',
}); });
} }
@ -63,15 +73,15 @@ export function createEndpoint(manifest: SSRManifest) {
const Component = (componentModule as any)[data.componentExport]; const Component = (componentModule as any)[data.componentExport];
const slots: ComponentSlots = {}; const slots: ComponentSlots = {};
for(const prop in data.slots) { for (const prop in data.slots) {
slots[prop] = createSlotValueFromString(data.slots[prop]); slots[prop] = createSlotValueFromString(data.slots[prop]);
} }
return renderTemplate`${renderComponent(result, 'Component', Component, props, slots)}`; return renderTemplate`${renderComponent(result, 'Component', Component, props, slots)}`;
} };
page.isAstroComponentFactory = true; page.isAstroComponentFactory = true;
const instance: ComponentInstance = { const instance: ComponentInstance = {
default: page, default: page,
partial: true, partial: true,
@ -79,4 +89,3 @@ export function createEndpoint(manifest: SSRManifest) {
return instance; return instance;
} }

View file

@ -1,10 +1,10 @@
import type { AstroPluginMetadata } from '../../vite-plugin-astro/index.js';
import type { AstroSettings } from '../../@types/astro.js';
import type { ConfigEnv, ViteDevServer, Plugin as VitePlugin } from 'vite'; import type { ConfigEnv, ViteDevServer, Plugin as VitePlugin } from 'vite';
import type { AstroSettings } from '../../@types/astro.js';
import type { AstroPluginMetadata } from '../../vite-plugin-astro/index.js';
export const VIRTUAL_ISLAND_MAP_ID = '@astro-server-islands'; export const VIRTUAL_ISLAND_MAP_ID = '@astro-server-islands';
export const RESOLVED_VIRTUAL_ISLAND_MAP_ID = '\0' + VIRTUAL_ISLAND_MAP_ID; export const RESOLVED_VIRTUAL_ISLAND_MAP_ID = '\0' + VIRTUAL_ISLAND_MAP_ID;
const serverIslandPlaceholder = '\'$$server-islands$$\''; const serverIslandPlaceholder = "'$$server-islands$$'";
export function vitePluginServerIslands({ settings }: { settings: AstroSettings }): VitePlugin { export function vitePluginServerIslands({ settings }: { settings: AstroSettings }): VitePlugin {
let command: ConfigEnv['command'] = 'serve'; let command: ConfigEnv['command'] = 'serve';
@ -20,29 +20,29 @@ export function vitePluginServerIslands({ settings }: { settings: AstroSettings
viteServer = _server; viteServer = _server;
}, },
resolveId(name) { resolveId(name) {
if(name === VIRTUAL_ISLAND_MAP_ID) { if (name === VIRTUAL_ISLAND_MAP_ID) {
return RESOLVED_VIRTUAL_ISLAND_MAP_ID; return RESOLVED_VIRTUAL_ISLAND_MAP_ID;
} }
}, },
load(id) { load(id) {
if(id === RESOLVED_VIRTUAL_ISLAND_MAP_ID) { if (id === RESOLVED_VIRTUAL_ISLAND_MAP_ID) {
return `export const serverIslandMap = ${serverIslandPlaceholder};`; return `export const serverIslandMap = ${serverIslandPlaceholder};`;
} }
}, },
transform(_code, id) { transform(_code, id) {
if(id.endsWith('.astro')) { if (id.endsWith('.astro')) {
const info = this.getModuleInfo(id); const info = this.getModuleInfo(id);
if(info?.meta) { if (info?.meta) {
const astro = info.meta.astro as AstroPluginMetadata['astro'] | undefined; const astro = info.meta.astro as AstroPluginMetadata['astro'] | undefined;
if(astro?.serverComponents.length) { if (astro?.serverComponents.length) {
for(const comp of astro.serverComponents) { for (const comp of astro.serverComponents) {
if(!settings.serverIslandNameMap.has(comp.resolvedPath)) { if (!settings.serverIslandNameMap.has(comp.resolvedPath)) {
let name = comp.localName; let name = comp.localName;
let idx = 1; let idx = 1;
while(true) { while (true) {
// Name not taken, let's use it. // Name not taken, let's use it.
if(!settings.serverIslandMap.has(name)) { if (!settings.serverIslandMap.has(name)) {
break; break;
} }
// Increment a number onto the name: Avatar -> Avatar1 // Increment a number onto the name: Avatar -> Avatar1
@ -57,12 +57,12 @@ export function vitePluginServerIslands({ settings }: { settings: AstroSettings
}); });
// Build mode // Build mode
if(command === 'build') { if (command === 'build') {
let referenceId = this.emitFile({ let referenceId = this.emitFile({
type: 'chunk', type: 'chunk',
id: comp.specifier, id: comp.specifier,
importer: id, importer: id,
name: comp.localName name: comp.localName,
}); });
referenceIdMap.set(comp.resolvedPath, referenceId); referenceIdMap.set(comp.resolvedPath, referenceId);
@ -74,17 +74,17 @@ export function vitePluginServerIslands({ settings }: { settings: AstroSettings
} }
}, },
renderChunk(code) { renderChunk(code) {
if(code.includes(serverIslandPlaceholder)) { if (code.includes(serverIslandPlaceholder)) {
let mapSource = 'new Map(['; let mapSource = 'new Map([';
for(let [resolvedPath, referenceId] of referenceIdMap) { for (let [resolvedPath, referenceId] of referenceIdMap) {
const fileName = this.getFileName(referenceId); const fileName = this.getFileName(referenceId);
const islandName = settings.serverIslandNameMap.get(resolvedPath)!; const islandName = settings.serverIslandNameMap.get(resolvedPath)!;
mapSource += `\n\t['${islandName}', () => import('./${fileName}')],` mapSource += `\n\t['${islandName}', () => import('./${fileName}')],`;
} }
mapSource += '\n]);'; mapSource += '\n]);';
referenceIdMap.clear(); referenceIdMap.clear();
return code.replace(serverIslandPlaceholder, mapSource); return code.replace(serverIslandPlaceholder, mapSource);
} }
}, },
} };
} }

View file

@ -3,8 +3,8 @@ import * as t from '@babel/types';
import { AstroError } from '../core/errors/errors.js'; import { AstroError } from '../core/errors/errors.js';
import { AstroErrorData } from '../core/errors/index.js'; import { AstroErrorData } from '../core/errors/index.js';
import { resolvePath } from '../core/viteUtils.js'; import { resolvePath } from '../core/viteUtils.js';
import type { PluginMetadata } from '../vite-plugin-astro/types.js';
import { createDefaultAstroMetadata } from '../vite-plugin-astro/metadata.js'; import { createDefaultAstroMetadata } from '../vite-plugin-astro/metadata.js';
import type { PluginMetadata } from '../vite-plugin-astro/types.js';
const ClientOnlyPlaceholder = 'astro-client-only'; const ClientOnlyPlaceholder = 'astro-client-only';

View file

@ -26,7 +26,6 @@ export async function renderEndpoint(
); );
} }
if (handler === undefined) { if (handler === undefined) {
logger.warn( logger.warn(
'router', 'router',
`No API Route handler exists for the method "${method}" for the route "${url.pathname}".\n` + `No API Route handler exists for the method "${method}" for the route "${url.pathname}".\n` +

View file

@ -6,7 +6,11 @@ export type AstroFactoryReturnValue = RenderTemplateResult | Response | HeadAndC
// The callback passed to to $$createComponent // The callback passed to to $$createComponent
export interface AstroComponentFactory { export interface AstroComponentFactory {
(result: SSRResult, props: any, slots: any): AstroFactoryReturnValue | Promise<AstroFactoryReturnValue>; (
result: SSRResult,
props: any,
slots: any
): AstroFactoryReturnValue | Promise<AstroFactoryReturnValue>;
isAstroComponentFactory?: boolean; isAstroComponentFactory?: boolean;
moduleId?: string | undefined; moduleId?: string | undefined;
propagation?: PropagationHint; propagation?: PropagationHint;

View file

@ -27,9 +27,9 @@ import {
} from './common.js'; } from './common.js';
import { componentIsHTMLElement, renderHTMLElement } from './dom.js'; import { componentIsHTMLElement, renderHTMLElement } from './dom.js';
import { maybeRenderHead } from './head.js'; import { maybeRenderHead } from './head.js';
import { containsServerDirective, renderServerIsland } from './server-islands.js';
import { type ComponentSlots, renderSlotToString, renderSlots } from './slot.js'; import { type ComponentSlots, renderSlotToString, renderSlots } from './slot.js';
import { formatList, internalSpreadAttributes, renderElement, voidElementNames } from './util.js'; import { formatList, internalSpreadAttributes, renderElement, voidElementNames } from './util.js';
import { containsServerDirective, renderServerIsland } from './server-islands.js';
const needsHeadRenderingSymbol = Symbol.for('astro.needsHeadRendering'); const needsHeadRenderingSymbol = Symbol.for('astro.needsHeadRendering');
const rendererAliases = new Map([['solid', 'solid-js']]); const rendererAliases = new Map([['solid', 'solid-js']]);
@ -474,10 +474,10 @@ function renderAstroComponent(
props: Record<string | number, any>, props: Record<string | number, any>,
slots: any = {} slots: any = {}
): RenderInstance { ): RenderInstance {
if(containsServerDirective(props)) { if (containsServerDirective(props)) {
return renderServerIsland(result, displayName, props, slots); return renderServerIsland(result, displayName, props, slots);
} }
const instance = createAstroComponentInstance(result, displayName, Component, props, slots); const instance = createAstroComponentInstance(result, displayName, Component, props, slots);
return { return {
async render(destination) { async render(destination) {

View file

@ -1,18 +1,16 @@
import type { import type { SSRResult } from '../../../@types/astro.js';
SSRResult, import { renderChild } from './any.js';
} from '../../../@types/astro.js'; import type { RenderInstance } from './common.js';
import { renderChild } from "./any.js"; import { type ComponentSlots, renderSlotToString } from './slot.js';
import type { RenderInstance } from "./common.js";
import { renderSlotToString, type ComponentSlots } from "./slot.js";
const internalProps = new Set([ const internalProps = new Set([
'server:component-path', 'server:component-path',
'server:component-export', 'server:component-export',
'server:component-directive', 'server:component-directive',
'server:defer' 'server:defer',
]); ]);
export function containsServerDirective(props: Record<string | number, any>,) { export function containsServerDirective(props: Record<string | number, any>) {
return 'server:component-directive' in props; return 'server:component-directive' in props;
} }
@ -20,7 +18,7 @@ export function renderServerIsland(
result: SSRResult, result: SSRResult,
_displayName: string, _displayName: string,
props: Record<string | number, any>, props: Record<string | number, any>,
slots: ComponentSlots, slots: ComponentSlots
): RenderInstance { ): RenderInstance {
return { return {
async render(destination) { async render(destination) {
@ -28,23 +26,23 @@ export function renderServerIsland(
const componentExport = props['server:component-export']; const componentExport = props['server:component-export'];
const componentId = result.serverIslandNameMap.get(componentPath); const componentId = result.serverIslandNameMap.get(componentPath);
if(!componentId) { if (!componentId) {
throw new Error(`Could not find server component name`); throw new Error(`Could not find server component name`);
} }
// Remove internal props // Remove internal props
for(const key of Object.keys(props)) { for (const key of Object.keys(props)) {
if(internalProps.has(key)) { if (internalProps.has(key)) {
delete props[key]; delete props[key];
} }
} }
destination.write('<!--server-island-start-->') destination.write('<!--server-island-start-->');
// Render the slots // Render the slots
const renderedSlots: Record<string, string> = {}; const renderedSlots: Record<string, string> = {};
for(const name in slots) { for (const name in slots) {
if(name !== 'fallback') { if (name !== 'fallback') {
const content = await renderSlotToString(result, slots[name]); const content = await renderSlotToString(result, slots[name]);
renderedSlots[name] = content.toString(); renderedSlots[name] = content.toString();
} else { } else {
@ -83,7 +81,7 @@ if(response.status === 200 && response.headers.get('content-type') === 'text/htm
script.before(frag); script.before(frag);
} }
script.remove(); script.remove();
</script>`) </script>`);
} },
} };
} }

View file

@ -105,7 +105,7 @@ export async function renderSlots(
} }
export function createSlotValueFromString(content: string): ComponentSlotValue { export function createSlotValueFromString(content: string): ComponentSlotValue {
return function() { return function () {
return renderTemplate`${unescapeHTML(content)}`; return renderTemplate`${unescapeHTML(content)}`;
}; };
} }

View file

@ -158,8 +158,8 @@ export class DevPipeline extends Pipeline {
const { loader } = this; const { loader } = this;
// First check built-in routes // First check built-in routes
for(const route of this.defaultRoutes) { for (const route of this.defaultRoutes) {
if(route.matchesComponent(filePath)) { if (route.matchesComponent(filePath)) {
return route.instance; return route.instance;
} }
} }
@ -226,8 +226,8 @@ export class DevPipeline extends Pipeline {
rewriteKnownRoute(route: string, sourceRoute: RouteData): ComponentInstance { rewriteKnownRoute(route: string, sourceRoute: RouteData): ComponentInstance {
if (isServerLikeOutput(this.config) && sourceRoute.prerender) { if (isServerLikeOutput(this.config) && sourceRoute.prerender) {
for(let def of this.defaultRoutes) { for (let def of this.defaultRoutes) {
if(route === def.route) { if (route === def.route) {
return def.instance; return def.instance;
} }
} }

View file

@ -9,8 +9,8 @@ import { AstroError, AstroErrorData } from '../core/errors/index.js';
import { patchOverlay } from '../core/errors/overlay.js'; import { patchOverlay } from '../core/errors/overlay.js';
import type { Logger } from '../core/logger/core.js'; import type { Logger } from '../core/logger/core.js';
import { createViteLoader } from '../core/module-loader/index.js'; import { createViteLoader } from '../core/module-loader/index.js';
import { createRouteManifest } from '../core/routing/index.js';
import { injectDefaultRoutes } from '../core/routing/default.js'; import { injectDefaultRoutes } from '../core/routing/default.js';
import { createRouteManifest } from '../core/routing/index.js';
import { toRoutingStrategy } from '../i18n/utils.js'; import { toRoutingStrategy } from '../i18n/utils.js';
import { baseMiddleware } from './base.js'; import { baseMiddleware } from './base.js';
import { createController } from './controller.js'; import { createController } from './controller.js';
@ -36,7 +36,7 @@ export default function createVitePluginAstroServer({
const loader = createViteLoader(viteServer); const loader = createViteLoader(viteServer);
const manifest = createDevelopmentManifest(settings); const manifest = createDevelopmentManifest(settings);
let manifestData: ManifestData = injectDefaultRoutes( let manifestData: ManifestData = injectDefaultRoutes(
createRouteManifest({ settings, fsMod }, logger), createRouteManifest({ settings, fsMod }, logger)
); );
const pipeline = DevPipeline.create(manifestData, { loader, logger, manifest, settings }); const pipeline = DevPipeline.create(manifestData, { loader, logger, manifest, settings });
const controller = createController({ loader }); const controller = createController({ loader });
@ -46,9 +46,7 @@ export default function createVitePluginAstroServer({
function rebuildManifest(needsManifestRebuild: boolean) { function rebuildManifest(needsManifestRebuild: boolean) {
pipeline.clearRouteCache(); pipeline.clearRouteCache();
if (needsManifestRebuild) { if (needsManifestRebuild) {
manifestData = injectDefaultRoutes( manifestData = injectDefaultRoutes(createRouteManifest({ settings }, logger));
createRouteManifest({ settings }, logger),
);
pipeline.setManifestData(manifestData); pipeline.setManifestData(manifestData);
} }
} }

View file

@ -13,9 +13,9 @@ import { AstroError, AstroErrorData } from '../core/errors/index.js';
import type { Logger } from '../core/logger/core.js'; import type { Logger } from '../core/logger/core.js';
import { isMarkdownFile } from '../core/util.js'; import { isMarkdownFile } from '../core/util.js';
import { shorthash } from '../runtime/server/shorthash.js'; import { shorthash } from '../runtime/server/shorthash.js';
import { createDefaultAstroMetadata } from '../vite-plugin-astro/metadata.js';
import { getFileInfo } from '../vite-plugin-utils/index.js'; import { getFileInfo } from '../vite-plugin-utils/index.js';
import { type MarkdownImagePath, getMarkdownCodeForImages } from './images.js'; import { type MarkdownImagePath, getMarkdownCodeForImages } from './images.js';
import { createDefaultAstroMetadata } from '../vite-plugin-astro/metadata.js';
interface AstroPluginOptions { interface AstroPluginOptions {
settings: AstroSettings; settings: AstroSettings;

View file

@ -1,4 +1,3 @@
import assert from 'node:assert/strict'; import assert from 'node:assert/strict';
import { after, before, describe, it } from 'node:test'; import { after, before, describe, it } from 'node:test';
import * as cheerio from 'cheerio'; import * as cheerio from 'cheerio';
@ -27,22 +26,22 @@ describe('Server islands', () => {
await devServer.stop(); await devServer.stop();
}); });
it('omits the islands HTML', async () => { it('omits the islands HTML', async () => {
const res = await fixture.fetch('/'); const res = await fixture.fetch('/');
assert.equal(res.status, 200); assert.equal(res.status, 200);
const html = await res.text(); const html = await res.text();
const $ = cheerio.load(html); const $ = cheerio.load(html);
const serverIslandEl = $('h2#island'); const serverIslandEl = $('h2#island');
assert.equal(serverIslandEl.length, 0); assert.equal(serverIslandEl.length, 0);
}); });
}); });
describe('prod', () => { describe('prod', () => {
before(async () => { before(async () => {
await fixture.build(); await fixture.build();
}); });
it('omits the islands HTML', async () => { it('omits the islands HTML', async () => {
const app = await fixture.loadTestAdapterApp(); const app = await fixture.loadTestAdapterApp();
const request = new Request('http://example.com/'); const request = new Request('http://example.com/');
const response = await app.render(request); const response = await app.render(request);
@ -54,8 +53,8 @@ describe('Server islands', () => {
const serverIslandScript = $('script[data-island-id]'); const serverIslandScript = $('script[data-island-id]');
assert.equal(serverIslandScript.length, 1, 'has the island script'); assert.equal(serverIslandScript.length, 1, 'has the island script');
}); });
}); });
}); });
describe('Hybrid mode', () => { describe('Hybrid mode', () => {
@ -93,11 +92,11 @@ describe('Server islands', () => {
componentExport: 'default', componentExport: 'default',
props: {}, props: {},
slots: {}, slots: {},
}) }),
}); });
return app.render(request); return app.render(request);
} }
it('Island returns its HTML', async () => { it('Island returns its HTML', async () => {
const response = await fetchIsland(); const response = await fetchIsland();
const html = await response.text(); const html = await response.text();