pull/17338/head
Elliott Johnson 2 weeks ago
parent 66f3255ac9
commit 2be25949ee

@ -1,5 +1,5 @@
/** @import { Component } from 'svelte' */
/** @import { CspInternal, HydratableContext, RenderOutput, SSRContext, SyncRenderOutput } from './types.js' */
/** @import { CspInternal, HydratableContext, RenderOutput, SSRContext, SyncRenderOutput, Sha256Source } from './types.js' */
/** @import { MaybePromise } from '#shared' */
import { async_mode_flag } from '../flags/index.js';
import { abort } from './abort-signal.js';
@ -521,7 +521,7 @@ export class Renderer {
* @template {Record<string, any>} Props
* @param {Component<Props>} component
* @param {{ props?: Omit<Props, '$$slots' | '$$events'>; context?: Map<any, any>; idPrefix?: string; csp?: CspInternal }} options
* @returns {Promise<AccumulatedContent & { hashes: { script: string[] } }>}
* @returns {Promise<AccumulatedContent & { hashes: { script: Sha256Source[] } }>}
*/
static async #render_async(component, options) {
const previous_context = ssr_context;
@ -629,7 +629,7 @@ export class Renderer {
/**
* @param {AccumulatedContent} content
* @param {Renderer} renderer
* @returns {AccumulatedContent & { hashes: { script: string[] } }}
* @returns {AccumulatedContent & { hashes: { script: Sha256Source[] } }}
*/
static #close_render(content, renderer) {
for (const cleanup of renderer.#collect_on_destroy()) {
@ -706,7 +706,7 @@ export class Renderer {
}
export class SSRState {
/** @readonly @type {CspInternal & { script_hashes: string[] }} */
/** @readonly @type {CspInternal & { script_hashes: Sha256Source[] }} */
csp;
/** @readonly @type {'sync' | 'async'} */
@ -723,10 +723,10 @@ export class SSRState {
/**
* @param {'sync' | 'async'} mode
* @param {string} [id_prefix]
* @param {CspInternal} [csp]
* @param {string} id_prefix
* @param {CspInternal} csp
*/
constructor(mode, id_prefix = '', csp = { hash: false }) {
constructor(mode, id_prefix, csp = { hash: false }) {
this.mode = mode;
this.csp = { ...csp, script_hashes: [] };

@ -15,7 +15,7 @@ export interface SSRContext {
element?: Element;
}
export type Csp = { nonce: string } | { hash: true };
export type Csp = { nonce: string } | { hash: boolean };
export type CspInternal = { nonce?: string; hash: boolean };
@ -37,6 +37,8 @@ export interface RenderContext {
hydratable: HydratableContext;
}
export type Sha256Source = `sha256-${string}`;
export interface SyncRenderOutput {
/** HTML that goes into the `<head>` */
head: string;
@ -45,7 +47,7 @@ export interface SyncRenderOutput {
/** HTML that goes somewhere into the `<body>` */
body: string;
hashes: {
script: string[];
script: Sha256Source[];
};
}

@ -1,14 +1,14 @@
/** @import { SvelteComponent } from '../index.js' */
/** @import { Csp } from '#server' */
import { asClassComponent as as_class_component, createClassComponent } from './legacy-client.js';
import { render } from '../internal/server/index.js';
import { async_mode_flag } from '../internal/flags/index.js';
import * as w from '../internal/server/warnings.js';
// By having this as a separate entry point for server environments, we save the client bundle from having to include the server runtime
export { createClassComponent };
/** @typedef {{ head: string, html: string, css: { code: string, map: null }}} LegacyRenderResult */
/** @typedef {{ head: string, html: string, css: { code: string, map: null }; hashes?: { script: `sha256-${string}`[] } }} LegacyRenderResult */
/**
* Takes a Svelte 5 component and returns a Svelte 4 compatible component constructor.
@ -25,10 +25,10 @@ export { createClassComponent };
*/
export function asClassComponent(component) {
const component_constructor = as_class_component(component);
/** @type {(props?: {}, opts?: { $$slots?: {}; context?: Map<any, any>; }) => LegacyRenderResult & PromiseLike<LegacyRenderResult> } */
const _render = (props, { context } = {}) => {
/** @type {(props?: {}, opts?: { $$slots?: {}; context?: Map<any, any>; csp?: Csp }) => LegacyRenderResult & PromiseLike<LegacyRenderResult> } */
const _render = (props, { context, csp } = {}) => {
// @ts-expect-error the typings are off, but this will work if the component is compiled in SSR mode
const result = render(component, { props, context });
const result = render(component, { props, context, csp });
const munged = Object.defineProperties(
/** @type {LegacyRenderResult & PromiseLike<LegacyRenderResult>} */ ({}),
@ -65,7 +65,8 @@ export function asClassComponent(component) {
return onfulfilled({
css: munged.css,
head: result.head,
html: result.body
html: result.body,
hashes: result.hashes
});
}, onrejected);
}

@ -2566,7 +2566,9 @@ declare module 'svelte/server' {
}
]
): RenderOutput;
type Csp = { nonce: string } | { hash: true };
type Csp = { nonce: string } | { hash: boolean };
type Sha256Source = `sha256-${string}`;
interface SyncRenderOutput {
/** HTML that goes into the `<head>` */
@ -2576,7 +2578,7 @@ declare module 'svelte/server' {
/** HTML that goes somewhere into the `<body>` */
body: string;
hashes: {
script: string[];
script: Sha256Source[];
};
}

Loading…
Cancel
Save