Skip to content

Commit 442334f

Browse files
committed
make mount/render optional, error if missing
1 parent 08d2350 commit 442334f

File tree

7 files changed

+51
-6
lines changed

7 files changed

+51
-6
lines changed

packages/svelte/messages/client-errors/errors.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@
6060

6161
> The `%rune%` rune is only available inside `.svelte` and `.svelte.js/ts` files
6262
63+
## snippet_missing_mount
64+
65+
> Snippets created with `createRawSnippet(...)` and used on the client must specify a `mount` function
66+
6367
## state_prototype_fixed
6468

6569
> Cannot set prototype of `$state` object
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
## lifecycle_function_unavailable
22

33
> `%name%(...)` is not available on the server
4+
5+
## snippet_missing_render
6+
7+
> Snippets created with `createRawSnippet(...)` and used on the server must specify a `render` function

packages/svelte/src/internal/client/dom/blocks/snippet.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
} from '../../runtime.js';
1010
import { hydrate_next, hydrate_node, hydrating } from '../hydration.js';
1111
import { assign_nodes } from '../template.js';
12+
import * as e from '../../errors.js';
1213

1314
/**
1415
* @template {(node: TemplateNode, ...args: any[]) => void} SnippetFn
@@ -67,13 +68,17 @@ export function wrap_snippet(component, fn) {
6768
* Create a snippet imperatively using mount, hydrate and render functions.
6869
* @template {unknown[]} Params
6970
* @param {{
70-
* mount: (...params: Getters<Params>) => Element,
71+
* mount?: (...params: Getters<Params>) => Element,
7172
* hydrate?: (element: Element, ...params: Getters<Params>) => void,
72-
* render: (...params: Params) => string
73+
* render?: (...params: Params) => string
7374
* }} options
7475
* @returns {import('svelte').Snippet<Params>}
7576
*/
7677
export function createRawSnippet({ mount, hydrate }) {
78+
if (mount === undefined) {
79+
e.snippet_missing_mount();
80+
}
81+
7782
return add_snippet_symbol(
7883
(/** @type {TemplateNode} */ anchor, /** @type {Getters<Params>} */ ...params) => {
7984
/** @type {Element} */

packages/svelte/src/internal/client/errors.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,22 @@ export function rune_outside_svelte(rune) {
262262
}
263263
}
264264

265+
/**
266+
* Snippets created with `createRawSnippet(...)` and used on the client must specify a `mount` function
267+
* @returns {never}
268+
*/
269+
export function snippet_missing_mount() {
270+
if (DEV) {
271+
const error = new Error(`snippet_missing_mount\nSnippets created with \`createRawSnippet(...)\` and used on the client must specify a \`mount\` function`);
272+
273+
error.name = 'Svelte error';
274+
throw error;
275+
} else {
276+
// TODO print a link to the documentation
277+
throw new Error("snippet_missing_mount");
278+
}
279+
}
280+
265281
/**
266282
* Cannot set prototype of `$state` object
267283
* @returns {never}

packages/svelte/src/internal/server/errors.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,17 @@
88
export function lifecycle_function_unavailable(name) {
99
const error = new Error(`lifecycle_function_unavailable\n\`${name}(...)\` is not available on the server`);
1010

11+
error.name = 'Svelte error';
12+
throw error;
13+
}
14+
15+
/**
16+
* Snippets created with `createRawSnippet(...)` and used on the server must specify a `render` function
17+
* @returns {never}
18+
*/
19+
export function snippet_missing_render() {
20+
const error = new Error(`snippet_missing_render\nSnippets created with \`createRawSnippet(...)\` and used on the server must specify a \`render\` function`);
21+
1122
error.name = 'Svelte error';
1223
throw error;
1324
}

packages/svelte/src/internal/server/index.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { DEV } from 'esm-env';
1414
import { current_component, pop, push } from './context.js';
1515
import { EMPTY_COMMENT, BLOCK_CLOSE, BLOCK_OPEN } from './hydration.js';
1616
import { add_snippet_symbol, validate_store } from '../shared/validate.js';
17+
import * as e from './errors.js';
1718

1819
// https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
1920
// https://infra.spec.whatwg.org/#noncharacter
@@ -158,12 +159,16 @@ export function head(payload, fn) {
158159
/**
159160
* Create a snippet imperatively using mount, hyrdate and render functions.
160161
* @param {{
161-
* mount: (...params: any[]) => Element,
162+
* mount?: (...params: any[]) => Element,
162163
* hydrate?: (element: Element, ...params: any[]) => void,
163-
* render: (...params: any[]) => string
164+
* render?: (...params: any[]) => string
164165
* }} options
165166
*/
166167
export function createRawSnippet({ render }) {
168+
if (render === undefined) {
169+
e.snippet_missing_render();
170+
}
171+
167172
const snippet_fn = (/** @type {Payload} */ payload, /** @type {any[]} */ ...args) => {
168173
payload.out += render(...args);
169174
};

packages/svelte/types/index.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,9 +369,9 @@ declare module 'svelte' {
369369
* Create a snippet imperatively using mount, hydrate and render functions.
370370
* */
371371
export function createRawSnippet<Params extends unknown[]>({ mount, hydrate }: {
372-
mount: (...params: Getters<Params>) => Element;
372+
mount?: (...params: Getters<Params>) => Element;
373373
hydrate?: (element: Element, ...params: Getters<Params>) => void;
374-
render: (...params: Params) => string;
374+
render?: (...params: Params) => string;
375375
}): import("svelte").Snippet<Params>;
376376
/**
377377
* Mounts a component to the given target and returns the exports and potentially the props (if compiled with `accessors: true`) of the component.

0 commit comments

Comments
 (0)