diff --git a/examples/container-with-vitest/src/components/Card.astro b/examples/container-with-vitest/src/components/Card.astro index 776c823292..a7e49f41c5 100644 --- a/examples/container-with-vitest/src/components/Card.astro +++ b/examples/container-with-vitest/src/components/Card.astro @@ -1,6 +1,7 @@ --- --- +
This is a card diff --git a/examples/container-with-vitest/src/pages/[locale].astro b/examples/container-with-vitest/src/pages/[locale].astro index 55e5c186a6..b76d36d39a 100644 --- a/examples/container-with-vitest/src/pages/[locale].astro +++ b/examples/container-with-vitest/src/pages/[locale].astro @@ -1,22 +1,20 @@ --- export function getStaticPaths() { - return [ - {params: {locale: 'en'}}, - ]; + return [{ params: { locale: 'en' } }]; } -const { locale } = Astro.params +const { locale } = Astro.params; --- - - - - - - Astro - - -

Astro

-

Locale: {locale}

- + + + + + + Astro + + +

Astro

+

Locale: {locale}

+ diff --git a/examples/container-with-vitest/test/ReactWrapper.test.ts b/examples/container-with-vitest/test/ReactWrapper.test.ts index 2f21d85966..91e3dd09d9 100644 --- a/examples/container-with-vitest/test/ReactWrapper.test.ts +++ b/examples/container-with-vitest/test/ReactWrapper.test.ts @@ -7,10 +7,10 @@ test('ReactWrapper with react renderer', async () => { renderers: [ { name: '@astrojs/react', - clientEntrypoint: "@astrojs/react/client.js", - serverEntrypoint: "@astrojs/react/server.js", - } - ] + clientEntrypoint: '@astrojs/react/client.js', + serverEntrypoint: '@astrojs/react/server.js', + }, + ], }); const result = await container.renderToString(ReactWrapper); diff --git a/examples/container-with-vitest/test/[locale].test.ts b/examples/container-with-vitest/test/[locale].test.ts index f58a26c49b..db450df538 100644 --- a/examples/container-with-vitest/test/[locale].test.ts +++ b/examples/container-with-vitest/test/[locale].test.ts @@ -7,7 +7,7 @@ test('Dynamic route', async () => { // @ts-ignore const result = await container.renderToString(Locale, { params: { - "locale": 'en' + locale: 'en', }, request: new Request('http://example.com/en'), }); diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts index b1782f39c3..462a3747e9 100644 --- a/packages/astro/src/@types/astro.ts +++ b/packages/astro/src/@types/astro.ts @@ -819,7 +819,7 @@ export interface AstroUserConfig { checkOrigin?: boolean; }; - + /** * @docs * @name vite @@ -1996,7 +1996,7 @@ export interface AstroUserConfig { * In the event of route collisions, where two routes of equal route priority attempt to build the same URL, Astro will log a warning identifying the conflicting routes. */ globalRoutePriority?: boolean; - + /** * @docs * @name experimental.rewriting diff --git a/packages/astro/src/container/index.ts b/packages/astro/src/container/index.ts index 50277dbf04..82859799be 100644 --- a/packages/astro/src/container/index.ts +++ b/packages/astro/src/container/index.ts @@ -1,4 +1,7 @@ +import { posix } from 'node:path'; import type { + AstroRenderer, + AstroUserConfig, ComponentInstance, MiddlewareHandler, RouteData, @@ -6,19 +9,16 @@ import type { SSRLoadedRenderer, SSRManifest, SSRResult, - AstroUserConfig, - AstroRenderer, } from '../@types/astro.js'; -import { ContainerPipeline } from './pipeline.js'; -import { Logger } from '../core/logger/core.js'; -import { nodeLogDestination } from '../core/logger/node.js'; import { validateConfig } from '../core/config/config.js'; import { ASTRO_CONFIG_DEFAULTS } from '../core/config/schema.js'; -import { RenderContext } from '../core/render-context.js'; -import { posix } from 'node:path'; -import { getParts, getPattern, validateSegment } from '../core/routing/manifest/create.js'; +import { Logger } from '../core/logger/core.js'; +import { nodeLogDestination } from '../core/logger/node.js'; import { removeLeadingForwardSlash } from '../core/path.js'; -import type {AstroComponentFactory} from "../runtime/server/index.js"; +import { RenderContext } from '../core/render-context.js'; +import { getParts, getPattern, validateSegment } from '../core/routing/manifest/create.js'; +import type { AstroComponentFactory } from '../runtime/server/index.js'; +import { ContainerPipeline } from './pipeline.js'; /** * Options to be passed when rendering a route @@ -27,15 +27,15 @@ export type ContainerRenderOptions = { /** * If your component renders slots, that's where you want to fill the slots. * A single slot should have the `default` field: - * + * * ## Examples - * + * * **Default slot** - * + * * ```js * container.renderToString(Component, { slots: { default: "Some value"}}); * ``` - * + * * **Named slots** * * ```js @@ -83,7 +83,7 @@ function createManifest( return { rewritingEnabled: false, - trailingSlash: manifest?.trailingSlash ?? ASTRO_CONFIG_DEFAULTS.trailingSlash , + trailingSlash: manifest?.trailingSlash ?? ASTRO_CONFIG_DEFAULTS.trailingSlash, buildFormat: manifest?.buildFormat ?? ASTRO_CONFIG_DEFAULTS.build.format, compressHTML: manifest?.compressHTML ?? ASTRO_CONFIG_DEFAULTS.compressHTML, assets: manifest?.assets ?? new Set(), @@ -93,7 +93,7 @@ function createManifest( adapterName: '', clientDirectives: manifest?.clientDirectives ?? new Map(), renderers: manifest?.renderers ?? renderers, - base: manifest?.base ?? ASTRO_CONFIG_DEFAULTS.base, + base: manifest?.base ?? ASTRO_CONFIG_DEFAULTS.base, componentMetadata: manifest?.componentMetadata ?? new Map(), inlinedScripts: manifest?.inlinedScripts ?? new Map(), i18n: manifest?.i18n, @@ -102,7 +102,7 @@ function createManifest( }; } -export type AstroContainerUserConfig = Omit +export type AstroContainerUserConfig = Omit; /** * Options that are used for the entire lifecycle of the current instance of the container. @@ -110,13 +110,13 @@ export type AstroContainerUserConfig = Omit { - const { - streaming = false, - renderers = [], - } = containerOptions; - const loadedRenderers = await Promise.all( + const { streaming = false, renderers = [] } = containerOptions; + const loadedRenderers = await Promise.all( renderers.map(async (renderer) => { const mod = await import(renderer.serverEntrypoint); if (typeof mod.default !== 'undefined') { @@ -255,13 +252,15 @@ export class experimental_AstroContainer { }) ); const finalRenderers = loadedRenderers.filter((r): r is SSRLoadedRenderer => Boolean(r)); - + return new experimental_AstroContainer({ streaming, renderers: finalRenderers }); } // NOTE: we keep this private via TS instead via `#` so it's still available on the surface, so we can play with it. - // @ematipico: I plan to use it for a possible integration that could help people - private static async createFromManifest(manifest: SSRManifest): Promise { + // @ematipico: I plan to use it for a possible integration that could help people + private static async createFromManifest( + manifest: SSRManifest + ): Promise { const config = await validateConfig(ASTRO_CONFIG_DEFAULTS, process.cwd(), 'container'); const container = new experimental_AstroContainer({ manifest, @@ -269,7 +268,7 @@ export class experimental_AstroContainer { container.#withManifest = true; return container; } - + #insertRoute({ path, componentInstance, @@ -278,13 +277,12 @@ export class experimental_AstroContainer { }: { path: string; componentInstance: ComponentInstance; - route?: string, + route?: string; params?: Record; type?: RouteType; }): RouteData { const pathUrl = new URL(path, 'https://example.com'); - const routeData: RouteData = this.#createRoute(pathUrl, - params, type); + const routeData: RouteData = this.#createRoute(pathUrl, params, type); this.#pipeline.manifest.routes.push({ routeData, file: '', @@ -299,19 +297,19 @@ export class experimental_AstroContainer { /** * @description * It renders a component and returns the result as a string. - * + * * ## Example - * + * * ```js * import Card from "../src/components/Card.astro"; - * + * * const container = await AstroContainer.create(); * const result = await container.renderToString(Card); - * + * * console.log(result); // it's a string * ``` - * - * + * + * * @param {AstroComponentFactory} component The instance of the component. * @param {ContainerRenderOptions=} options Possible options to pass when rendering the component. */ @@ -349,7 +347,10 @@ export class experimental_AstroContainer { const { routeType = 'page', slots } = options; const request = options?.request ?? new Request('https://example.com/'); const url = new URL(request.url); - const componentInstance = routeType === "endpoint" ? component as unknown as ComponentInstance : this.#wrapComponent(component, options.params); + const componentInstance = + routeType === 'endpoint' + ? (component as unknown as ComponentInstance) + : this.#wrapComponent(component, options.params); const routeData = this.#insertRoute({ path: request.url, componentInstance, @@ -387,7 +388,11 @@ export class experimental_AstroContainer { return ''; }, params: Object.keys(params), - pattern: getPattern(segments, ASTRO_CONFIG_DEFAULTS.base, ASTRO_CONFIG_DEFAULTS.trailingSlash), + pattern: getPattern( + segments, + ASTRO_CONFIG_DEFAULTS.base, + ASTRO_CONFIG_DEFAULTS.trailingSlash + ), prerender: false, segments, type, @@ -402,15 +407,18 @@ export class experimental_AstroContainer { * @param params * @private */ - #wrapComponent(componentFactory: AstroComponentFactory, params?: Record): ComponentInstance { + #wrapComponent( + componentFactory: AstroComponentFactory, + params?: Record + ): ComponentInstance { if (params) { return { default: componentFactory, getStaticPaths() { return [{ params }]; - } - } + }, + }; } - return ({ default: componentFactory }) + return { default: componentFactory }; } } diff --git a/packages/astro/src/container/pipeline.ts b/packages/astro/src/container/pipeline.ts index 5e76fad21d..d48d13e420 100644 --- a/packages/astro/src/container/pipeline.ts +++ b/packages/astro/src/container/pipeline.ts @@ -1,4 +1,3 @@ -import { type HeadElements, Pipeline } from '../core/base-pipeline.js'; import type { ComponentInstance, RewritePayload, @@ -6,13 +5,14 @@ import type { SSRElement, SSRResult, } from '../@types/astro.js'; +import { type HeadElements, Pipeline } from '../core/base-pipeline.js'; +import type { SinglePageBuiltModule } from '../core/build/types.js'; +import { RouteNotFound } from '../core/errors/errors-data.js'; +import { AstroError } from '../core/errors/index.js'; import { createModuleScriptElement, createStylesheetElementSet, } from '../core/render/ssr-element.js'; -import { AstroError } from '../core/errors/index.js'; -import { RouteNotFound } from '../core/errors/errors-data.js'; -import type { SinglePageBuiltModule } from '../core/build/types.js'; export class ContainerPipeline extends Pipeline { /** @@ -110,6 +110,5 @@ export class ContainerPipeline extends Pipeline { // At the moment it's not used by the container via any public API // @ts-expect-error It needs to be implemented. - async getComponentByRoute(_routeData: RouteData): Promise { - } + async getComponentByRoute(_routeData: RouteData): Promise {} } diff --git a/packages/astro/test/container.test.js b/packages/astro/test/container.test.js index ab64efa9ff..228844e702 100644 --- a/packages/astro/test/container.test.js +++ b/packages/astro/test/container.test.js @@ -1,4 +1,6 @@ +import assert from 'node:assert/strict'; import { describe, it } from 'node:test'; +import { experimental_AstroContainer } from '../dist/container/index.js'; import { Fragment, createComponent, @@ -8,8 +10,6 @@ import { renderHead, renderSlot, } from '../dist/runtime/server/index.js'; -import { experimental_AstroContainer } from '../dist/container/index.js'; -import assert from 'node:assert/strict'; const BaseLayout = createComponent((result, _props, slots) => { return render` @@ -54,7 +54,7 @@ describe('Container', () => { assert.match(response, /hello world/); }); - + it('Renders a slot', async () => { const Page = createComponent( (result, _props, slots) => {