chore: use JSDoc type imports in more files (#12239)

* chore: use JSDoc type imports in more files

* Location_1 -> Location

* merge

* fix

* oops

---------

Co-authored-by: Rich Harris <rich.harris@vercel.com>
pull/12262/head
Damian Stasik 1 year ago committed by GitHub
parent bcf23cafce
commit 84325bf89b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1,3 +1,4 @@
/** @import { FlipParams, AnimationConfig } from './public.js' */
import { cubicOut } from '../easing/index.js'; import { cubicOut } from '../easing/index.js';
/** /**
@ -7,8 +8,8 @@ import { cubicOut } from '../easing/index.js';
* https://svelte.dev/docs/svelte-animate#flip * https://svelte.dev/docs/svelte-animate#flip
* @param {Element} node * @param {Element} node
* @param {{ from: DOMRect; to: DOMRect }} fromTo * @param {{ from: DOMRect; to: DOMRect }} fromTo
* @param {import('./public.js').FlipParams} params * @param {FlipParams} params
* @returns {import('./public.js').AnimationConfig} * @returns {AnimationConfig}
*/ */
export function flip(node, { from, to }, params = {}) { export function flip(node, { from, to }, params = {}) {
const style = getComputedStyle(node); const style = getComputedStyle(node);

@ -1,3 +1,5 @@
/** @import { LegacyRoot } from './types/legacy-nodes.js' */
/** @import { CompileOptions, CompileResult, ValidatedCompileOptions, ModuleCompileOptions, Root } from '#compiler' */
import { walk as zimmerframe_walk } from 'zimmerframe'; import { walk as zimmerframe_walk } from 'zimmerframe';
import { convert } from './legacy.js'; import { convert } from './legacy.js';
import { parse as parse_acorn } from './phases/1-parse/acorn.js'; import { parse as parse_acorn } from './phases/1-parse/acorn.js';
@ -14,8 +16,8 @@ export { default as preprocess } from './preprocess/index.js';
* *
* https://svelte.dev/docs/svelte-compiler#svelte-compile * https://svelte.dev/docs/svelte-compiler#svelte-compile
* @param {string} source The component source code * @param {string} source The component source code
* @param {import('#compiler').CompileOptions} options The compiler options * @param {CompileOptions} options The compiler options
* @returns {import('#compiler').CompileResult} * @returns {CompileResult}
*/ */
export function compile(source, options) { export function compile(source, options) {
const validated = validate_component_options(options, ''); const validated = validate_component_options(options, '');
@ -25,7 +27,7 @@ export function compile(source, options) {
const { customElement: customElementOptions, ...parsed_options } = parsed.options || {}; const { customElement: customElementOptions, ...parsed_options } = parsed.options || {};
/** @type {import('#compiler').ValidatedCompileOptions} */ /** @type {ValidatedCompileOptions} */
const combined_options = { const combined_options = {
...validated, ...validated,
...parsed_options, ...parsed_options,
@ -52,8 +54,8 @@ export function compile(source, options) {
* *
* https://svelte.dev/docs/svelte-compiler#svelte-compile * https://svelte.dev/docs/svelte-compiler#svelte-compile
* @param {string} source The component source code * @param {string} source The component source code
* @param {import('#compiler').ModuleCompileOptions} options * @param {ModuleCompileOptions} options
* @returns {import('#compiler').CompileResult} * @returns {CompileResult}
*/ */
export function compileModule(source, options) { export function compileModule(source, options) {
const validated = validate_module_options(options, ''); const validated = validate_module_options(options, '');
@ -73,7 +75,7 @@ export function compileModule(source, options) {
* @overload * @overload
* @param {string} source * @param {string} source
* @param {{ filename?: string; modern: true }} options * @param {{ filename?: string; modern: true }} options
* @returns {import('#compiler').Root} * @returns {Root}
*/ */
/** /**
@ -86,7 +88,7 @@ export function compileModule(source, options) {
* @overload * @overload
* @param {string} source * @param {string} source
* @param {{ filename?: string; modern?: false }} [options] * @param {{ filename?: string; modern?: false }} [options]
* @returns {import('./types/legacy-nodes.js').LegacyRoot} * @returns {LegacyRoot}
*/ */
/** /**
@ -98,7 +100,7 @@ export function compileModule(source, options) {
* https://svelte.dev/docs/svelte-compiler#svelte-parse * https://svelte.dev/docs/svelte-compiler#svelte-parse
* @param {string} source * @param {string} source
* @param {{ filename?: string; rootDir?: string; modern?: boolean }} [options] * @param {{ filename?: string; rootDir?: string; modern?: boolean }} [options]
* @returns {import('#compiler').Root | import('./types/legacy-nodes.js').LegacyRoot} * @returns {Root | LegacyRoot}
*/ */
export function parse(source, { filename, rootDir, modern } = {}) { export function parse(source, { filename, rootDir, modern } = {}) {
state.reset(source, { filename, rootDir }); // TODO it's weird to require filename/rootDir here. reconsider the API state.reset(source, { filename, rootDir }); // TODO it's weird to require filename/rootDir here. reconsider the API
@ -109,7 +111,7 @@ export function parse(source, { filename, rootDir, modern } = {}) {
/** /**
* @param {string} source * @param {string} source
* @param {import('#compiler').Root} ast * @param {Root} ast
* @param {boolean | undefined} modern * @param {boolean | undefined} modern
*/ */
function to_public_ast(source, ast, modern) { function to_public_ast(source, ast, modern) {

@ -1,3 +1,9 @@
/** @import { VariableDeclarator, Node, Identifier } from 'estree' */
/** @import { SvelteNode } from '../types/template.js' */
/** @import { Visitors } from 'zimmerframe' */
/** @import { ComponentAnalysis } from '../phases/types.js' */
/** @import { Scope } from '../phases/scope.js' */
/** @import * as Compiler from '#compiler' */
import MagicString from 'magic-string'; import MagicString from 'magic-string';
import { walk } from 'zimmerframe'; import { walk } from 'zimmerframe';
import { parse } from '../phases/1-parse/index.js'; import { parse } from '../phases/1-parse/index.js';
@ -24,7 +30,7 @@ export function migrate(source) {
const { customElement: customElementOptions, ...parsed_options } = parsed.options || {}; const { customElement: customElementOptions, ...parsed_options } = parsed.options || {};
/** @type {import('#compiler').ValidatedCompileOptions} */ /** @type {Compiler.ValidatedCompileOptions} */
const combined_options = { const combined_options = {
...validate_component_options({}, ''), ...validate_component_options({}, ''),
...parsed_options, ...parsed_options,
@ -160,9 +166,9 @@ export function migrate(source) {
/** /**
* @typedef {{ * @typedef {{
* scope: import('../phases/scope.js').Scope; * scope: Scope;
* str: MagicString; * str: MagicString;
* analysis: import('../phases/types.js').ComponentAnalysis; * analysis: ComponentAnalysis;
* indent: string; * indent: string;
* props: Array<{ local: string; exported: string; init: string; bindable: boolean; slot_name?: string; optional: boolean; type: string; comment?: string }>; * props: Array<{ local: string; exported: string; init: string; bindable: boolean; slot_name?: string; optional: boolean; type: string; comment?: string }>;
* props_insertion_point: number; * props_insertion_point: number;
@ -175,7 +181,7 @@ export function migrate(source) {
* }} State * }} State
*/ */
/** @type {import('zimmerframe').Visitors<import('../types/template.js').SvelteNode, State>} */ /** @type {Visitors<SvelteNode, State>} */
const instance_script = { const instance_script = {
_(node, { state, next }) { _(node, { state, next }) {
// @ts-expect-error // @ts-expect-error
@ -281,9 +287,7 @@ const instance_script = {
// } // }
} }
const binding = /** @type {import('#compiler').Binding} */ ( const binding = /** @type {Compiler.Binding} */ (state.scope.get(declarator.id.name));
state.scope.get(declarator.id.name)
);
if ( if (
state.analysis.uses_props && state.analysis.uses_props &&
@ -429,7 +433,7 @@ const instance_script = {
} }
}; };
/** @type {import('zimmerframe').Visitors<import('../types/template.js').SvelteNode, State>} */ /** @type {Visitors<SvelteNode, State>} */
const template = { const template = {
Identifier(node, { state, path }) { Identifier(node, { state, path }) {
handle_identifier(node, state, path); handle_identifier(node, state, path);
@ -543,15 +547,15 @@ const template = {
}; };
/** /**
* @param {import('estree').VariableDeclarator} declarator * @param {VariableDeclarator} declarator
* @param {MagicString} str * @param {MagicString} str
* @param {import('#compiler').SvelteNode[]} path * @param {Compiler.SvelteNode[]} path
*/ */
function extract_type_and_comment(declarator, str, path) { function extract_type_and_comment(declarator, str, path) {
const parent = path.at(-1); const parent = path.at(-1);
// Try to find jsdoc above the declaration // Try to find jsdoc above the declaration
let comment_node = /** @type {import('estree').Node} */ (parent)?.leadingComments?.at(-1); let comment_node = /** @type {Node} */ (parent)?.leadingComments?.at(-1);
if (comment_node?.type !== 'Block') comment_node = undefined; if (comment_node?.type !== 'Block') comment_node = undefined;
const comment_start = /** @type {any} */ (comment_node)?.start; const comment_start = /** @type {any} */ (comment_node)?.start;
@ -590,11 +594,11 @@ function extract_type_and_comment(declarator, str, path) {
} }
/** /**
* @param {import('#compiler').RegularElement | import('#compiler').SvelteElement | import('#compiler').SvelteWindow | import('#compiler').SvelteDocument | import('#compiler').SvelteBody} element * @param {Compiler.RegularElement | Compiler.SvelteElement | Compiler.SvelteWindow | Compiler.SvelteDocument | Compiler.SvelteBody} element
* @param {State} state * @param {State} state
*/ */
function handle_events(element, state) { function handle_events(element, state) {
/** @type {Map<string, import('#compiler').OnDirective[]>} */ /** @type {Map<string, Compiler.OnDirective[]>} */
const handlers = new Map(); const handlers = new Map();
for (const attribute of element.attributes) { for (const attribute of element.attributes) {
if (attribute.type !== 'OnDirective') continue; if (attribute.type !== 'OnDirective') continue;
@ -805,7 +809,7 @@ function get_indent(state, ...nodes) {
} }
/** /**
* @param {import('#compiler').OnDirective} last * @param {Compiler.OnDirective} last
* @param {State} state * @param {State} state
*/ */
function generate_event_name(last, state) { function generate_event_name(last, state) {
@ -821,7 +825,7 @@ function generate_event_name(last, state) {
} }
/** /**
* @param {import('estree').Identifier} node * @param {Identifier} node
* @param {State} state * @param {State} state
* @param {any[]} path * @param {any[]} path
*/ */

@ -1,3 +1,4 @@
/** @import { TemplateNode, Fragment, Root, SvelteOptionsRaw } from '#compiler' */
// @ts-expect-error acorn type definitions are borked in the release we use // @ts-expect-error acorn type definitions are borked in the release we use
import { isIdentifierStart, isIdentifierChar } from 'acorn'; import { isIdentifierStart, isIdentifierChar } from 'acorn';
import fragment from './state/fragment.js'; import fragment from './state/fragment.js';
@ -26,13 +27,13 @@ export class Parser {
/** Whether we're parsing in TypeScript mode */ /** Whether we're parsing in TypeScript mode */
ts = false; ts = false;
/** @type {import('#compiler').TemplateNode[]} */ /** @type {TemplateNode[]} */
stack = []; stack = [];
/** @type {import('#compiler').Fragment[]} */ /** @type {Fragment[]} */
fragments = []; fragments = [];
/** @type {import('#compiler').Root} */ /** @type {Root} */
root; root;
/** @type {Record<string, boolean>} */ /** @type {Record<string, boolean>} */
@ -120,9 +121,7 @@ export class Parser {
(thing) => thing.type === 'SvelteOptions' (thing) => thing.type === 'SvelteOptions'
); );
if (options_index !== -1) { if (options_index !== -1) {
const options = /** @type {import('#compiler').SvelteOptionsRaw} */ ( const options = /** @type {SvelteOptionsRaw} */ (this.root.fragment.nodes[options_index]);
this.root.fragment.nodes[options_index]
);
this.root.fragment.nodes.splice(options_index, 1); this.root.fragment.nodes.splice(options_index, 1);
this.root.options = read_options(options); this.root.options = read_options(options);
// We need this for the old AST format // We need this for the old AST format
@ -289,7 +288,7 @@ export class Parser {
/** /**
* @param {string} template * @param {string} template
* @returns {import('#compiler').Root} * @returns {Root}
*/ */
export function parse(template) { export function parse(template) {
const parser = new Parser(template); const parser = new Parser(template);

@ -1,3 +1,6 @@
/** @import { Location } from 'locate-character' */
/** @import { Pattern } from 'estree' */
/** @import { Parser } from '../index.js' */
// @ts-expect-error acorn type definitions are borked in the release we use // @ts-expect-error acorn type definitions are borked in the release we use
import { isIdentifierStart } from 'acorn'; import { isIdentifierStart } from 'acorn';
import full_char_code_at from '../utils/full_char_code_at.js'; import full_char_code_at from '../utils/full_char_code_at.js';
@ -13,8 +16,8 @@ import * as e from '../../../errors.js';
import { locator } from '../../../state.js'; import { locator } from '../../../state.js';
/** /**
* @param {import('../index.js').Parser} parser * @param {Parser} parser
* @returns {import('estree').Pattern} * @returns {Pattern}
*/ */
export default function read_pattern(parser) { export default function read_pattern(parser) {
const start = parser.index; const start = parser.index;
@ -30,8 +33,8 @@ export default function read_pattern(parser) {
name, name,
start, start,
loc: { loc: {
start: /** @type {import('locate-character').Location} */ (locator(start)), start: /** @type {Location} */ (locator(start)),
end: /** @type {import('locate-character').Location} */ (locator(parser.index)) end: /** @type {Location} */ (locator(parser.index))
}, },
end: parser.index, end: parser.index,
typeAnnotation: annotation typeAnnotation: annotation
@ -95,7 +98,7 @@ export default function read_pattern(parser) {
} }
/** /**
* @param {import('../index.js').Parser} parser * @param {Parser} parser
* @returns {any} * @returns {any}
*/ */
function read_type_annotation(parser) { function read_type_annotation(parser) {

@ -1,14 +1,16 @@
/** @import { ObjectExpression } from 'estree' */
/** @import { SvelteOptionsRaw, Root, SvelteOptions } from '#compiler' */
import { namespace_mathml, namespace_svg } from '../../../../constants.js'; import { namespace_mathml, namespace_svg } from '../../../../constants.js';
import * as e from '../../../errors.js'; import * as e from '../../../errors.js';
const regex_valid_tag_name = /^[a-zA-Z][a-zA-Z0-9]*-[a-zA-Z0-9-]+$/; const regex_valid_tag_name = /^[a-zA-Z][a-zA-Z0-9]*-[a-zA-Z0-9-]+$/;
/** /**
* @param {import('#compiler').SvelteOptionsRaw} node * @param {SvelteOptionsRaw} node
* @returns {import('#compiler').Root['options']} * @returns {Root['options']}
*/ */
export default function read_options(node) { export default function read_options(node) {
/** @type {import('#compiler').SvelteOptions} */ /** @type {SvelteOptions} */
const component_options = { const component_options = {
start: node.start, start: node.start,
end: node.end, end: node.end,
@ -37,7 +39,7 @@ export default function read_options(node) {
break; // eslint doesn't know this is unnecessary break; // eslint doesn't know this is unnecessary
} }
case 'customElement': { case 'customElement': {
/** @type {import('#compiler').SvelteOptions['customElement']} */ /** @type {SvelteOptions['customElement']} */
const ce = { tag: '' }; const ce = { tag: '' };
const { value } = attribute; const { value } = attribute;
@ -86,8 +88,7 @@ export default function read_options(node) {
e.svelte_options_invalid_customelement_props(attribute); e.svelte_options_invalid_customelement_props(attribute);
} }
ce.props = {}; ce.props = {};
for (const property of /** @type {import('estree').ObjectExpression} */ (props) for (const property of /** @type {ObjectExpression} */ (props).properties) {
.properties) {
if ( if (
property.type !== 'Property' || property.type !== 'Property' ||
property.computed || property.computed ||

@ -1,3 +1,6 @@
/** @import { Program } from 'estree' */
/** @import { Attribute, SpreadAttribute, Directive, Script } from '#compiler' */
/** @import { Parser } from '../index.js' */
import * as acorn from '../acorn.js'; import * as acorn from '../acorn.js';
import { regex_not_newline_characters } from '../../patterns.js'; import { regex_not_newline_characters } from '../../patterns.js';
import * as e from '../../../errors.js'; import * as e from '../../../errors.js';
@ -29,10 +32,10 @@ function get_context(attributes) {
} }
/** /**
* @param {import('../index.js').Parser} parser * @param {Parser} parser
* @param {number} start * @param {number} start
* @param {Array<import('#compiler').Attribute | import('#compiler').SpreadAttribute | import('#compiler').Directive>} attributes * @param {Array<Attribute | SpreadAttribute | Directive>} attributes
* @returns {import('#compiler').Script} * @returns {Script}
*/ */
export function read_script(parser, start, attributes) { export function read_script(parser, start, attributes) {
const script_start = parser.index; const script_start = parser.index;
@ -45,7 +48,7 @@ export function read_script(parser, start, attributes) {
parser.template.slice(0, script_start).replace(regex_not_newline_characters, ' ') + data; parser.template.slice(0, script_start).replace(regex_not_newline_characters, ' ') + data;
parser.read(regex_starts_with_closing_script_tag); parser.read(regex_starts_with_closing_script_tag);
/** @type {import('estree').Program} */ /** @type {Program} */
let ast; let ast;
try { try {

@ -1,3 +1,5 @@
/** @import { Attribute, SpreadAttribute, Directive, Css } from '#compiler' */
/** @import { Parser } from '../index.js' */
import * as e from '../../../errors.js'; import * as e from '../../../errors.js';
const REGEX_MATCHER = /^[~^$*|]?=/; const REGEX_MATCHER = /^[~^$*|]?=/;
@ -14,10 +16,10 @@ const REGEX_COMMENT_CLOSE = /\*\//;
const REGEX_HTML_COMMENT_CLOSE = /-->/; const REGEX_HTML_COMMENT_CLOSE = /-->/;
/** /**
* @param {import('../index.js').Parser} parser * @param {Parser} parser
* @param {number} start * @param {number} start
* @param {Array<import('#compiler').Attribute | import('#compiler').SpreadAttribute | import('#compiler').Directive>} attributes * @param {Array<Attribute | SpreadAttribute | Directive>} attributes
* @returns {import('#compiler').Css.StyleSheet} * @returns {Css.StyleSheet}
*/ */
export default function read_style(parser, start, attributes) { export default function read_style(parser, start, attributes) {
const content_start = parser.index; const content_start = parser.index;
@ -42,12 +44,12 @@ export default function read_style(parser, start, attributes) {
} }
/** /**
* @param {import('../index.js').Parser} parser * @param {Parser} parser
* @param {string} close * @param {string} close
* @returns {any[]} * @returns {any[]}
*/ */
function read_body(parser, close) { function read_body(parser, close) {
/** @type {Array<import('#compiler').Css.Rule | import('#compiler').Css.Atrule>} */ /** @type {Array<Css.Rule | Css.Atrule>} */
const children = []; const children = [];
while (parser.index < parser.template.length) { while (parser.index < parser.template.length) {
@ -68,8 +70,8 @@ function read_body(parser, close) {
} }
/** /**
* @param {import('../index.js').Parser} parser * @param {Parser} parser
* @returns {import('#compiler').Css.Atrule} * @returns {Css.Atrule}
*/ */
function read_at_rule(parser) { function read_at_rule(parser) {
const start = parser.index; const start = parser.index;
@ -79,7 +81,7 @@ function read_at_rule(parser) {
const prelude = read_value(parser); const prelude = read_value(parser);
/** @type {import('#compiler').Css.Block | null} */ /** @type {Css.Block | null} */
let block = null; let block = null;
if (parser.match('{')) { if (parser.match('{')) {
@ -101,8 +103,8 @@ function read_at_rule(parser) {
} }
/** /**
* @param {import('../index.js').Parser} parser * @param {Parser} parser
* @returns {import('#compiler').Css.Rule} * @returns {Css.Rule}
*/ */
function read_rule(parser) { function read_rule(parser) {
const start = parser.index; const start = parser.index;
@ -122,12 +124,12 @@ function read_rule(parser) {
} }
/** /**
* @param {import('../index.js').Parser} parser * @param {Parser} parser
* @param {boolean} [inside_pseudo_class] * @param {boolean} [inside_pseudo_class]
* @returns {import('#compiler').Css.SelectorList} * @returns {Css.SelectorList}
*/ */
function read_selector_list(parser, inside_pseudo_class = false) { function read_selector_list(parser, inside_pseudo_class = false) {
/** @type {import('#compiler').Css.ComplexSelector[]} */ /** @type {Css.ComplexSelector[]} */
const children = []; const children = [];
allow_comment_or_whitespace(parser); allow_comment_or_whitespace(parser);
@ -158,20 +160,20 @@ function read_selector_list(parser, inside_pseudo_class = false) {
} }
/** /**
* @param {import('../index.js').Parser} parser * @param {Parser} parser
* @param {boolean} [inside_pseudo_class] * @param {boolean} [inside_pseudo_class]
* @returns {import('#compiler').Css.ComplexSelector} * @returns {Css.ComplexSelector}
*/ */
function read_selector(parser, inside_pseudo_class = false) { function read_selector(parser, inside_pseudo_class = false) {
const list_start = parser.index; const list_start = parser.index;
/** @type {import('#compiler').Css.RelativeSelector[]} */ /** @type {Css.RelativeSelector[]} */
const children = []; const children = [];
/** /**
* @param {import('#compiler').Css.Combinator | null} combinator * @param {Css.Combinator | null} combinator
* @param {number} start * @param {number} start
* @returns {import('#compiler').Css.RelativeSelector} * @returns {Css.RelativeSelector}
*/ */
function create_selector(combinator, start) { function create_selector(combinator, start) {
return { return {
@ -188,7 +190,7 @@ function read_selector(parser, inside_pseudo_class = false) {
}; };
} }
/** @type {import('#compiler').Css.RelativeSelector} */ /** @type {Css.RelativeSelector} */
let relative_selector = create_selector(null, parser.index); let relative_selector = create_selector(null, parser.index);
while (parser.index < parser.template.length) { while (parser.index < parser.template.length) {
@ -245,7 +247,7 @@ function read_selector(parser, inside_pseudo_class = false) {
} else if (parser.eat(':')) { } else if (parser.eat(':')) {
const name = read_identifier(parser); const name = read_identifier(parser);
/** @type {null | import('#compiler').Css.SelectorList} */ /** @type {null | Css.SelectorList} */
let args = null; let args = null;
if (parser.eat('(')) { if (parser.eat('(')) {
@ -373,8 +375,8 @@ function read_selector(parser, inside_pseudo_class = false) {
} }
/** /**
* @param {import('../index.js').Parser} parser * @param {Parser} parser
* @returns {import('#compiler').Css.Combinator | null} * @returns {Css.Combinator | null}
*/ */
function read_combinator(parser) { function read_combinator(parser) {
const start = parser.index; const start = parser.index;
@ -408,15 +410,15 @@ function read_combinator(parser) {
} }
/** /**
* @param {import('../index.js').Parser} parser * @param {Parser} parser
* @returns {import('#compiler').Css.Block} * @returns {Css.Block}
*/ */
function read_block(parser) { function read_block(parser) {
const start = parser.index; const start = parser.index;
parser.eat('{', true); parser.eat('{', true);
/** @type {Array<import('#compiler').Css.Declaration | import('#compiler').Css.Rule | import('#compiler').Css.Atrule>} */ /** @type {Array<Css.Declaration | Css.Rule | Css.Atrule>} */
const children = []; const children = [];
while (parser.index < parser.template.length) { while (parser.index < parser.template.length) {
@ -442,8 +444,8 @@ function read_block(parser) {
/** /**
* Reads a declaration, rule or at-rule * Reads a declaration, rule or at-rule
* *
* @param {import('../index.js').Parser} parser * @param {Parser} parser
* @returns {import('#compiler').Css.Declaration | import('#compiler').Css.Rule | import('#compiler').Css.Atrule} * @returns {Css.Declaration | Css.Rule | Css.Atrule}
*/ */
function read_block_item(parser) { function read_block_item(parser) {
if (parser.match('@')) { if (parser.match('@')) {
@ -461,8 +463,8 @@ function read_block_item(parser) {
} }
/** /**
* @param {import('../index.js').Parser} parser * @param {Parser} parser
* @returns {import('#compiler').Css.Declaration} * @returns {Css.Declaration}
*/ */
function read_declaration(parser) { function read_declaration(parser) {
const start = parser.index; const start = parser.index;
@ -495,7 +497,7 @@ function read_declaration(parser) {
} }
/** /**
* @param {import('../index.js').Parser} parser * @param {Parser} parser
* @returns {string} * @returns {string}
*/ */
function read_value(parser) { function read_value(parser) {
@ -537,7 +539,7 @@ function read_value(parser) {
/** /**
* Read a property that may or may not be quoted, e.g. * Read a property that may or may not be quoted, e.g.
* `foo` or `'foo bar'` or `"foo bar"` * `foo` or `'foo bar'` or `"foo bar"`
* @param {import('../index.js').Parser} parser * @param {Parser} parser
*/ */
function read_attribute_value(parser) { function read_attribute_value(parser) {
let value = ''; let value = '';
@ -569,7 +571,7 @@ function read_attribute_value(parser) {
/** /**
* https://www.w3.org/TR/CSS21/syndata.html#value-def-identifier * https://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
* @param {import('../index.js').Parser} parser * @param {Parser} parser
*/ */
function read_identifier(parser) { function read_identifier(parser) {
const start = parser.index; const start = parser.index;
@ -608,7 +610,7 @@ function read_identifier(parser) {
return identifier; return identifier;
} }
/** @param {import('../index.js').Parser} parser */ /** @param {Parser} parser */
function allow_comment_or_whitespace(parser) { function allow_comment_or_whitespace(parser) {
parser.allow_whitespace(); parser.allow_whitespace();
while (parser.match('/*') || parser.match('<!--')) { while (parser.match('/*') || parser.match('<!--')) {

@ -1,9 +1,11 @@
/** @import { Context, Visitors } from 'zimmerframe' */
/** @import { FunctionExpression, FunctionDeclaration } from 'estree' */
import { walk } from 'zimmerframe'; import { walk } from 'zimmerframe';
import * as b from '../../utils/builders.js'; import * as b from '../../utils/builders.js';
/** /**
* @param {import('estree').FunctionExpression | import('estree').FunctionDeclaration} node * @param {FunctionExpression | FunctionDeclaration} node
* @param {import('zimmerframe').Context<any, any>} context * @param {Context<any, any>} context
*/ */
function remove_this_param(node, context) { function remove_this_param(node, context) {
if (node.params[0]?.type === 'Identifier' && node.params[0].name === 'this') { if (node.params[0]?.type === 'Identifier' && node.params[0].name === 'this') {
@ -12,7 +14,7 @@ function remove_this_param(node, context) {
return context.next(); return context.next();
} }
/** @type {import('zimmerframe').Visitors<any, null>} */ /** @type {Visitors<any, null>} */
const visitors = { const visitors = {
ImportDeclaration(node) { ImportDeclaration(node) {
if (node.importKind === 'type') return b.empty; if (node.importKind === 'type') return b.empty;

@ -1,3 +1,5 @@
/** @import { Parser } from '../index.js' */
/** @import * as Compiler from '#compiler' */
import { is_void } from '../utils/names.js'; import { is_void } from '../utils/names.js';
import read_expression from '../read/expression.js'; import read_expression from '../read/expression.js';
import { read_script } from '../read/script.js'; import { read_script } from '../read/script.js';
@ -14,7 +16,7 @@ const valid_tag_name = /^\!?[a-zA-Z]{1,}:?[a-zA-Z0-9\-]*/;
/** Invalid attribute characters if the attribute is not surrounded by quotes */ /** Invalid attribute characters if the attribute is not surrounded by quotes */
const regex_starts_with_invalid_attr_value = /^(\/>|[\s"'=<>`])/; const regex_starts_with_invalid_attr_value = /^(\/>|[\s"'=<>`])/;
/** @type {Map<string, import('#compiler').ElementLike['type']>} */ /** @type {Map<string, Compiler.ElementLike['type']>} */
const root_only_meta_tags = new Map([ const root_only_meta_tags = new Map([
['svelte:head', 'SvelteHead'], ['svelte:head', 'SvelteHead'],
['svelte:options', 'SvelteOptions'], ['svelte:options', 'SvelteOptions'],
@ -23,7 +25,7 @@ const root_only_meta_tags = new Map([
['svelte:body', 'SvelteBody'] ['svelte:body', 'SvelteBody']
]); ]);
/** @type {Map<string, import('#compiler').ElementLike['type']>} */ /** @type {Map<string, Compiler.ElementLike['type']>} */
const meta_tags = new Map([ const meta_tags = new Map([
...root_only_meta_tags, ...root_only_meta_tags,
['svelte:element', 'SvelteElement'], ['svelte:element', 'SvelteElement'],
@ -39,7 +41,7 @@ const COMPONENT = /^svelte:component(?=[\s/>])/;
const SLOT = /^svelte:fragment(?=[\s/>])/; const SLOT = /^svelte:fragment(?=[\s/>])/;
const ELEMENT = /^svelte:element(?=[\s/>])/; const ELEMENT = /^svelte:element(?=[\s/>])/;
/** @param {import('#compiler').TemplateNode[]} stack */ /** @param {Compiler.TemplateNode[]} stack */
function parent_is_head(stack) { function parent_is_head(stack) {
let i = stack.length; let i = stack.length;
while (i--) { while (i--) {
@ -50,14 +52,14 @@ function parent_is_head(stack) {
return false; return false;
} }
/** @param {import('#compiler').TemplateNode[]} stack */ /** @param {Compiler.TemplateNode[]} stack */
function parent_is_shadowroot_template(stack) { function parent_is_shadowroot_template(stack) {
// https://developer.chrome.com/docs/css-ui/declarative-shadow-dom#building_a_declarative_shadow_root // https://developer.chrome.com/docs/css-ui/declarative-shadow-dom#building_a_declarative_shadow_root
let i = stack.length; let i = stack.length;
while (i--) { while (i--) {
if ( if (
stack[i].type === 'RegularElement' && stack[i].type === 'RegularElement' &&
/** @type {import('#compiler').RegularElement} */ (stack[i]).attributes.some( /** @type {Compiler.RegularElement} */ (stack[i]).attributes.some(
(a) => a.type === 'Attribute' && a.name === 'shadowrootmode' (a) => a.type === 'Attribute' && a.name === 'shadowrootmode'
) )
) { ) {
@ -71,7 +73,7 @@ const regex_closing_textarea_tag = /^<\/textarea(\s[^>]*)?>/i;
const regex_closing_comment = /-->/; const regex_closing_comment = /-->/;
const regex_capital_letter = /[A-Z]/; const regex_capital_letter = /[A-Z]/;
/** @param {import('../index.js').Parser} parser */ /** @param {Parser} parser */
export default function element(parser) { export default function element(parser) {
const start = parser.index++; const start = parser.index++;
@ -81,7 +83,7 @@ export default function element(parser) {
const data = parser.read_until(regex_closing_comment); const data = parser.read_until(regex_closing_comment);
parser.eat('-->', true); parser.eat('-->', true);
/** @type {ReturnType<typeof parser.append<import('#compiler').Comment>>} */ /** @type {ReturnType<typeof parser.append<Compiler.Comment>>} */
parser.append({ parser.append({
type: 'Comment', type: 'Comment',
start, start,
@ -100,10 +102,10 @@ export default function element(parser) {
if (is_closing_tag) { if (is_closing_tag) {
if ( if (
['svelte:options', 'svelte:window', 'svelte:body', 'svelte:document'].includes(name) && ['svelte:options', 'svelte:window', 'svelte:body', 'svelte:document'].includes(name) &&
/** @type {import('#compiler').ElementLike} */ (parent).fragment.nodes.length /** @type {Compiler.ElementLike} */ (parent).fragment.nodes.length
) { ) {
e.svelte_meta_invalid_content( e.svelte_meta_invalid_content(
/** @type {import('#compiler').ElementLike} */ (parent).fragment.nodes[0].start, /** @type {Compiler.ElementLike} */ (parent).fragment.nodes[0].start,
name name
); );
} }
@ -131,7 +133,7 @@ export default function element(parser) {
? 'SlotElement' ? 'SlotElement'
: 'RegularElement'; : 'RegularElement';
/** @type {import('#compiler').ElementLike} */ /** @type {Compiler.ElementLike} */
const element = const element =
type === 'RegularElement' type === 'RegularElement'
? { ? {
@ -149,7 +151,7 @@ export default function element(parser) {
}, },
parent: null parent: null
} }
: /** @type {import('#compiler').ElementLike} */ ({ : /** @type {Compiler.ElementLike} */ ({
type, type,
start, start,
end: -1, end: -1,
@ -172,7 +174,7 @@ export default function element(parser) {
parser.eat('>', true); parser.eat('>', true);
// close any elements that don't have their own closing tags, e.g. <div><p></div> // close any elements that don't have their own closing tags, e.g. <div><p></div>
while (/** @type {import('#compiler').RegularElement} */ (parent).name !== name) { while (/** @type {Compiler.RegularElement} */ (parent).name !== name) {
if (parent.type !== 'RegularElement') { if (parent.type !== 'RegularElement') {
if (parser.last_auto_closed_tag && parser.last_auto_closed_tag.tag === name) { if (parser.last_auto_closed_tag && parser.last_auto_closed_tag.tag === name) {
e.element_invalid_closing_tag_autoclosed(start, name, parser.last_auto_closed_tag.reason); e.element_invalid_closing_tag_autoclosed(start, name, parser.last_auto_closed_tag.reason);
@ -238,9 +240,7 @@ export default function element(parser) {
e.svelte_component_missing_this(start); e.svelte_component_missing_this(start);
} }
const definition = /** @type {import('#compiler').Attribute} */ ( const definition = /** @type {Compiler.Attribute} */ (element.attributes.splice(index, 1)[0]);
element.attributes.splice(index, 1)[0]
);
if ( if (
definition.value === true || definition.value === true ||
definition.value.length !== 1 || definition.value.length !== 1 ||
@ -261,9 +261,7 @@ export default function element(parser) {
e.svelte_element_missing_this(start); e.svelte_element_missing_this(start);
} }
const definition = /** @type {import('#compiler').Attribute} */ ( const definition = /** @type {Compiler.Attribute} */ (element.attributes.splice(index, 1)[0]);
element.attributes.splice(index, 1)[0]
);
if (definition.value === true) { if (definition.value === true) {
e.svelte_element_missing_this(definition); e.svelte_element_missing_this(definition);
@ -296,7 +294,7 @@ export default function element(parser) {
if (is_top_level_script_or_style) { if (is_top_level_script_or_style) {
parser.eat('>', true); parser.eat('>', true);
/** @type {import('#compiler').Comment | null} */ /** @type {Compiler.Comment | null} */
let prev_comment = null; let prev_comment = null;
for (let i = current.fragment.nodes.length - 1; i >= 0; i--) { for (let i = current.fragment.nodes.length - 1; i >= 0; i--) {
const node = current.fragment.nodes[i]; const node = current.fragment.nodes[i];
@ -363,7 +361,7 @@ export default function element(parser) {
const data = parser.read_until(new RegExp(`</${name}>`)); const data = parser.read_until(new RegExp(`</${name}>`));
const end = parser.index; const end = parser.index;
/** @type {import('#compiler').Text} */ /** @type {Compiler.Text} */
const node = { const node = {
start, start,
end, end,
@ -384,7 +382,7 @@ export default function element(parser) {
const regex_whitespace_or_slash_or_closing_tag = /(\s|\/|>)/; const regex_whitespace_or_slash_or_closing_tag = /(\s|\/|>)/;
/** @param {import('../index.js').Parser} parser */ /** @param {Parser} parser */
function read_tag_name(parser) { function read_tag_name(parser) {
const start = parser.index; const start = parser.index;
@ -441,8 +439,8 @@ const regex_starts_with_quote_characters = /^["']/;
const regex_attribute_value = /^(?:"([^"]*)"|'([^'])*'|([^>\s]+))/; const regex_attribute_value = /^(?:"([^"]*)"|'([^'])*'|([^>\s]+))/;
/** /**
* @param {import('../index.js').Parser} parser * @param {Parser} parser
* @returns {import('#compiler').Attribute | null} * @returns {Compiler.Attribute | null}
*/ */
function read_static_attribute(parser) { function read_static_attribute(parser) {
const start = parser.index; const start = parser.index;
@ -450,7 +448,7 @@ function read_static_attribute(parser) {
const name = parser.read_until(regex_token_ending_character); const name = parser.read_until(regex_token_ending_character);
if (!name) return null; if (!name) return null;
/** @type {true | Array<import('#compiler').Text | import('#compiler').ExpressionTag>} */ /** @type {true | Array<Compiler.Text | Compiler.ExpressionTag>} */
let value = true; let value = true;
if (parser.eat('=')) { if (parser.eat('=')) {
@ -487,8 +485,8 @@ function read_static_attribute(parser) {
} }
/** /**
* @param {import('../index.js').Parser} parser * @param {Parser} parser
* @returns {import('#compiler').Attribute | import('#compiler').SpreadAttribute | import('#compiler').Directive | null} * @returns {Compiler.Attribute | Compiler.SpreadAttribute | Compiler.Directive | null}
*/ */
function read_attribute(parser) { function read_attribute(parser) {
const start = parser.index; const start = parser.index;
@ -502,7 +500,7 @@ function read_attribute(parser) {
parser.allow_whitespace(); parser.allow_whitespace();
parser.eat('}', true); parser.eat('}', true);
/** @type {import('#compiler').SpreadAttribute} */ /** @type {Compiler.SpreadAttribute} */
const spread = { const spread = {
type: 'SpreadAttribute', type: 'SpreadAttribute',
start, start,
@ -527,7 +525,7 @@ function read_attribute(parser) {
parser.allow_whitespace(); parser.allow_whitespace();
parser.eat('}', true); parser.eat('}', true);
/** @type {import('#compiler').ExpressionTag} */ /** @type {Compiler.ExpressionTag} */
const expression = { const expression = {
type: 'ExpressionTag', type: 'ExpressionTag',
start: value_start, start: value_start,
@ -559,7 +557,7 @@ function read_attribute(parser) {
const colon_index = name.indexOf(':'); const colon_index = name.indexOf(':');
const type = colon_index !== -1 && get_directive_type(name.slice(0, colon_index)); const type = colon_index !== -1 && get_directive_type(name.slice(0, colon_index));
/** @type {true | Array<import('#compiler').Text | import('#compiler').ExpressionTag>} */ /** @type {true | Array<Compiler.Text | Compiler.ExpressionTag>} */
let value = true; let value = true;
if (parser.eat('=')) { if (parser.eat('=')) {
parser.allow_whitespace(); parser.allow_whitespace();
@ -604,7 +602,7 @@ function read_attribute(parser) {
} }
} }
/** @type {import('#compiler').Directive} */ /** @type {Compiler.Directive} */
// @ts-expect-error TODO can't figure out this error // @ts-expect-error TODO can't figure out this error
const directive = { const directive = {
start, start,
@ -663,7 +661,7 @@ function get_directive_type(name) {
} }
/** /**
* @param {import('../index.js').Parser} parser * @param {Parser} parser
*/ */
function read_attribute_value(parser) { function read_attribute_value(parser) {
const quote_mark = parser.eat("'") ? "'" : parser.eat('"') ? '"' : null; const quote_mark = parser.eat("'") ? "'" : parser.eat('"') ? '"' : null;
@ -714,13 +712,13 @@ function read_attribute_value(parser) {
} }
/** /**
* @param {import('../index.js').Parser} parser * @param {Parser} parser
* @param {() => boolean} done * @param {() => boolean} done
* @param {string} location * @param {string} location
* @returns {any[]} * @returns {any[]}
*/ */
function read_sequence(parser, done, location) { function read_sequence(parser, done, location) {
/** @type {import('#compiler').Text} */ /** @type {Compiler.Text} */
let current_chunk = { let current_chunk = {
start: parser.index, start: parser.index,
end: -1, end: -1,
@ -730,7 +728,7 @@ function read_sequence(parser, done, location) {
parent: null parent: null
}; };
/** @type {Array<import('#compiler').Text | import('#compiler').ExpressionTag>} */ /** @type {Array<Compiler.Text | Compiler.ExpressionTag>} */
const chunks = []; const chunks = [];
/** @param {number} end */ /** @param {number} end */
@ -768,7 +766,7 @@ function read_sequence(parser, done, location) {
parser.allow_whitespace(); parser.allow_whitespace();
parser.eat('}', true); parser.eat('}', true);
/** @type {import('#compiler').ExpressionTag} */ /** @type {Compiler.ExpressionTag} */
const chunk = { const chunk = {
type: 'ExpressionTag', type: 'ExpressionTag',
start: index, start: index,

@ -1,8 +1,9 @@
/** @import { Parser } from '../index.js' */
import element from './element.js'; import element from './element.js';
import tag from './tag.js'; import tag from './tag.js';
import text from './text.js'; import text from './text.js';
/** @param {import('../index.js').Parser} parser */ /** @param {Parser} parser */
export default function fragment(parser) { export default function fragment(parser) {
if (parser.match('<')) { if (parser.match('<')) {
return element; return element;

@ -1,6 +1,8 @@
/** @import { Text } from '#compiler' */
/** @import { Parser } from '../index.js' */
import { decode_character_references } from '../utils/html.js'; import { decode_character_references } from '../utils/html.js';
/** @param {import('../index.js').Parser} parser */ /** @param {Parser} parser */
export default function text(parser) { export default function text(parser) {
const start = parser.index; const start = parser.index;
@ -10,7 +12,7 @@ export default function text(parser) {
data += parser.template[parser.index++]; data += parser.template[parser.index++];
} }
/** @type {ReturnType<typeof parser.append<import('#compiler').Text>>} */ /** @type {ReturnType<typeof parser.append<Text>>} */
parser.append({ parser.append({
type: 'Text', type: 'Text',
start, start,

@ -1,6 +1,7 @@
/** @import { Fragment } from '#compiler' */
/** /**
* @param {any} transparent * @param {any} transparent
* @returns {import('#compiler').Fragment} * @returns {Fragment}
*/ */
export function create_fragment(transparent = false) { export function create_fragment(transparent = false) {
return { return {

@ -1,3 +1,7 @@
/** @import { Visitors } from 'zimmerframe' */
/** @import { AnalysisState } from './types.js' */
/** @import { Attribute, SvelteNode, TemplateNode, RegularElement, SvelteElement } from '#compiler' */
/** @import { ARIARoleDefinitionKey, ARIARoleRelationConcept, ARIAProperty, ARIAPropertyDefinition, ARIARoleDefinition } from 'aria-query' */
import { roles as roles_map, aria, elementRoles } from 'aria-query'; import { roles as roles_map, aria, elementRoles } from 'aria-query';
// @ts-expect-error package doesn't provide typings // @ts-expect-error package doesn't provide typings
import { AXObjects, AXObjectRoles, elementAXObjects } from 'axobject-query'; import { AXObjects, AXObjectRoles, elementAXObjects } from 'axobject-query';
@ -43,21 +47,21 @@ const interactive_roles = non_abstract_roles.filter(
); );
/** /**
* @param {import('aria-query').ARIARoleDefinitionKey} role * @param {ARIARoleDefinitionKey} role
*/ */
function is_non_interactive_roles(role) { function is_non_interactive_roles(role) {
return non_interactive_roles.includes(role); return non_interactive_roles.includes(role);
} }
/** /**
* @param {import('aria-query').ARIARoleDefinitionKey} role * @param {ARIARoleDefinitionKey} role
*/ */
function is_interactive_roles(role) { function is_interactive_roles(role) {
return interactive_roles.includes(role); return interactive_roles.includes(role);
} }
/** /**
* @param {import('aria-query').ARIARoleDefinitionKey} role * @param {ARIARoleDefinitionKey} role
*/ */
function is_abstract_role(role) { function is_abstract_role(role) {
return abstract_roles.includes(role); return abstract_roles.includes(role);
@ -66,7 +70,7 @@ function is_abstract_role(role) {
const presentation_roles = ['presentation', 'none']; const presentation_roles = ['presentation', 'none'];
/** /**
* @param {import('aria-query').ARIARoleDefinitionKey} role * @param {ARIARoleDefinitionKey} role
*/ */
function is_presentation_role(role) { function is_presentation_role(role) {
return presentation_roles.includes(role); return presentation_roles.includes(role);
@ -74,7 +78,7 @@ function is_presentation_role(role) {
/** /**
* @param {string} tag_name * @param {string} tag_name
* @param {Map<string, import('#compiler').Attribute>} attribute_map * @param {Map<string, Attribute>} attribute_map
*/ */
function is_hidden_from_screen_reader(tag_name, attribute_map) { function is_hidden_from_screen_reader(tag_name, attribute_map) {
if (tag_name === 'input') { if (tag_name === 'input') {
@ -92,7 +96,7 @@ function is_hidden_from_screen_reader(tag_name, attribute_map) {
} }
/** /**
* @param {Map<string, import('#compiler').Attribute>} attribute_map * @param {Map<string, Attribute>} attribute_map
*/ */
function has_disabled_attribute(attribute_map) { function has_disabled_attribute(attribute_map) {
const disabled_attr_value = get_static_value(attribute_map.get('disabled')); const disabled_attr_value = get_static_value(attribute_map.get('disabled'));
@ -111,7 +115,7 @@ function has_disabled_attribute(attribute_map) {
} }
/** /**
* @type {import('aria-query').ARIARoleRelationConcept[]} * @type {ARIARoleRelationConcept[]}
*/ */
const non_interactive_element_role_schemas = []; const non_interactive_element_role_schemas = [];
elementRoles.entries().forEach(([schema, roles]) => { elementRoles.entries().forEach(([schema, roles]) => {
@ -121,7 +125,7 @@ elementRoles.entries().forEach(([schema, roles]) => {
}); });
/** /**
* @type {import('aria-query').ARIARoleRelationConcept[]} * @type {ARIARoleRelationConcept[]}
*/ */
const interactive_element_role_schemas = []; const interactive_element_role_schemas = [];
elementRoles.entries().forEach(([schema, roles]) => { elementRoles.entries().forEach(([schema, roles]) => {
@ -137,7 +141,7 @@ const non_interactive_ax_objects = [...AXObjects.keys()].filter((name) =>
); );
/** /**
* @type {import('aria-query').ARIARoleRelationConcept[]} * @type {ARIARoleRelationConcept[]}
*/ */
const interactive_element_ax_object_schemas = []; const interactive_element_ax_object_schemas = [];
elementAXObjects.entries().forEach( elementAXObjects.entries().forEach(
@ -152,7 +156,7 @@ elementAXObjects.entries().forEach(
); );
/** /**
* @type {import('aria-query').ARIARoleRelationConcept[]} * @type {ARIARoleRelationConcept[]}
*/ */
const non_interactive_element_ax_object_schemas = []; const non_interactive_element_ax_object_schemas = [];
elementAXObjects.entries().forEach( elementAXObjects.entries().forEach(
@ -167,9 +171,9 @@ elementAXObjects.entries().forEach(
); );
/** /**
* @param {import('aria-query').ARIARoleRelationConcept} schema * @param {ARIARoleRelationConcept} schema
* @param {string} tag_name * @param {string} tag_name
* @param {Map<string, import('#compiler').Attribute>} attribute_map * @param {Map<string, Attribute>} attribute_map
*/ */
function match_schema(schema, tag_name, attribute_map) { function match_schema(schema, tag_name, attribute_map) {
if (schema.name !== tag_name) return false; if (schema.name !== tag_name) return false;
@ -192,7 +196,7 @@ const ElementInteractivity = /** @type {const} */ ({
/** /**
* @param {string} tag_name * @param {string} tag_name
* @param {Map<string, import('#compiler').Attribute>} attribute_map * @param {Map<string, Attribute>} attribute_map
* @returns {ElementInteractivity[keyof ElementInteractivity]} * @returns {ElementInteractivity[keyof ElementInteractivity]}
*/ */
function element_interactivity(tag_name, attribute_map) { function element_interactivity(tag_name, attribute_map) {
@ -228,7 +232,7 @@ function element_interactivity(tag_name, attribute_map) {
/** /**
* @param {string} tag_name * @param {string} tag_name
* @param {Map<string, import('#compiler').Attribute>} attribute_map * @param {Map<string, Attribute>} attribute_map
* @returns {boolean} * @returns {boolean}
*/ */
function is_interactive_element(tag_name, attribute_map) { function is_interactive_element(tag_name, attribute_map) {
@ -237,7 +241,7 @@ function is_interactive_element(tag_name, attribute_map) {
/** /**
* @param {string} tag_name * @param {string} tag_name
* @param {Map<string, import('#compiler').Attribute>} attribute_map * @param {Map<string, Attribute>} attribute_map
* @returns {boolean} * @returns {boolean}
*/ */
function is_non_interactive_element(tag_name, attribute_map) { function is_non_interactive_element(tag_name, attribute_map) {
@ -246,7 +250,7 @@ function is_non_interactive_element(tag_name, attribute_map) {
/** /**
* @param {string} tag_name * @param {string} tag_name
* @param {Map<string, import('#compiler').Attribute>} attribute_map * @param {Map<string, Attribute>} attribute_map
* @returns {boolean} * @returns {boolean}
*/ */
function is_static_element(tag_name, attribute_map) { function is_static_element(tag_name, attribute_map) {
@ -254,9 +258,9 @@ function is_static_element(tag_name, attribute_map) {
} }
/** /**
* @param {import('aria-query').ARIARoleDefinitionKey} role * @param {ARIARoleDefinitionKey} role
* @param {string} tag_name * @param {string} tag_name
* @param {Map<string, import('#compiler').Attribute>} attribute_map * @param {Map<string, Attribute>} attribute_map
*/ */
function is_semantic_role_element(role, tag_name, attribute_map) { function is_semantic_role_element(role, tag_name, attribute_map) {
for (const [schema, ax_object] of elementAXObjects.entries()) { for (const [schema, ax_object] of elementAXObjects.entries()) {
@ -540,7 +544,7 @@ const a11y_non_interactive_element_to_interactive_role_exceptions = {
const combobox_if_list = ['email', 'search', 'tel', 'text', 'url']; const combobox_if_list = ['email', 'search', 'tel', 'text', 'url'];
/** @param {Map<string, import('#compiler').Attribute>} attribute_map */ /** @param {Map<string, Attribute>} attribute_map */
function input_implicit_role(attribute_map) { function input_implicit_role(attribute_map) {
const type_attribute = attribute_map.get('type'); const type_attribute = attribute_map.get('type');
if (!type_attribute) return; if (!type_attribute) return;
@ -553,7 +557,7 @@ function input_implicit_role(attribute_map) {
return input_type_to_implicit_role.get(type); return input_type_to_implicit_role.get(type);
} }
/** @param {Map<string, import('#compiler').Attribute>} attribute_map */ /** @param {Map<string, Attribute>} attribute_map */
function menuitem_implicit_role(attribute_map) { function menuitem_implicit_role(attribute_map) {
const type_attribute = attribute_map.get('type'); const type_attribute = attribute_map.get('type');
if (!type_attribute) return; if (!type_attribute) return;
@ -564,7 +568,7 @@ function menuitem_implicit_role(attribute_map) {
/** /**
* @param {string} name * @param {string} name
* @param {Map<string, import('#compiler').Attribute>} attribute_map * @param {Map<string, Attribute>} attribute_map
*/ */
function get_implicit_role(name, attribute_map) { function get_implicit_role(name, attribute_map) {
if (name === 'menuitem') { if (name === 'menuitem') {
@ -579,7 +583,7 @@ function get_implicit_role(name, attribute_map) {
const invisible_elements = ['meta', 'html', 'script', 'style']; const invisible_elements = ['meta', 'html', 'script', 'style'];
/** /**
* @param {import('#compiler').SvelteNode | null} parent * @param {SvelteNode | null} parent
* @param {string[]} elements * @param {string[]} elements
*/ */
function is_parent(parent, elements) { function is_parent(parent, elements) {
@ -588,15 +592,15 @@ function is_parent(parent, elements) {
if (parent.type === 'RegularElement') { if (parent.type === 'RegularElement') {
return elements.includes(parent.name); return elements.includes(parent.name);
} }
parent = /** @type {import('#compiler').TemplateNode} */ (parent).parent; parent = /** @type {TemplateNode} */ (parent).parent;
} }
return false; return false;
} }
/** /**
* @param {import('#compiler').Attribute} attribute * @param {Attribute} attribute
* @param {import('aria-query').ARIAProperty} name * @param {ARIAProperty} name
* @param {import('aria-query').ARIAPropertyDefinition} schema * @param {ARIAPropertyDefinition} schema
* @param {string | true | null} value * @param {string | true | null} value
*/ */
function validate_aria_attribute_value(attribute, name, schema, value) { function validate_aria_attribute_value(attribute, name, schema, value) {
@ -644,7 +648,7 @@ function validate_aria_attribute_value(attribute, name, schema, value) {
} }
/** /**
* @param {import('#compiler').RegularElement |import('#compiler').SvelteElement} node * @param {RegularElement |SvelteElement} node
* @param {string[]} attributes * @param {string[]} attributes
* @param {string} name * @param {string} name
*/ */
@ -660,7 +664,7 @@ function warn_missing_attribute(node, attributes, name = node.name) {
} }
/** /**
* @param {import('#compiler').Attribute | undefined} attribute * @param {Attribute | undefined} attribute
*/ */
function get_static_value(attribute) { function get_static_value(attribute) {
if (!attribute) return null; if (!attribute) return null;
@ -670,7 +674,7 @@ function get_static_value(attribute) {
} }
/** /**
* @param {import('#compiler').Attribute | undefined} attribute * @param {Attribute | undefined} attribute
*/ */
function get_static_text_value(attribute) { function get_static_text_value(attribute) {
const value = get_static_value(attribute); const value = get_static_value(attribute);
@ -679,20 +683,20 @@ function get_static_text_value(attribute) {
} }
/** /**
* @param {import('#compiler').RegularElement | import('#compiler').SvelteElement} node * @param {RegularElement | SvelteElement} node
* @param {import('./types.js').AnalysisState} state * @param {AnalysisState} state
*/ */
function check_element(node, state) { function check_element(node, state) {
// foreign namespace means elements can have completely different meanings, therefore we don't check them // foreign namespace means elements can have completely different meanings, therefore we don't check them
if (state.options.namespace === 'foreign') return; if (state.options.namespace === 'foreign') return;
/** @type {Map<string, import('#compiler').Attribute>} */ /** @type {Map<string, Attribute>} */
const attribute_map = new Map(); const attribute_map = new Map();
/** @type {Set<string>} */ /** @type {Set<string>} */
const handlers = new Set(); const handlers = new Set();
/** @type {import('#compiler').Attribute[]} */ /** @type {Attribute[]} */
const attributes = []; const attributes = [];
const is_dynamic_element = node.type === 'SvelteElement'; const is_dynamic_element = node.type === 'SvelteElement';
@ -748,14 +752,9 @@ function check_element(node, state) {
// aria-proptypes // aria-proptypes
let value = get_static_value(attribute); let value = get_static_value(attribute);
const schema = aria.get(/** @type {import('aria-query').ARIAProperty} */ (name)); const schema = aria.get(/** @type {ARIAProperty} */ (name));
if (schema !== undefined) { if (schema !== undefined) {
validate_aria_attribute_value( validate_aria_attribute_value(attribute, /** @type {ARIAProperty} */ (name), schema, value);
attribute,
/** @type {import('aria-query').ARIAProperty} */ (name),
schema,
value
);
} }
// aria-activedescendant-has-tabindex // aria-activedescendant-has-tabindex
@ -779,8 +778,7 @@ function check_element(node, state) {
const value = get_static_value(attribute); const value = get_static_value(attribute);
if (typeof value === 'string') { if (typeof value === 'string') {
for (const c_r of value.split(regex_whitespaces)) { for (const c_r of value.split(regex_whitespaces)) {
const current_role = const current_role = /** @type {ARIARoleDefinitionKey} current_role */ (c_r);
/** @type {import('aria-query').ARIARoleDefinitionKey} current_role */ (c_r);
if (current_role && is_abstract_role(current_role)) { if (current_role && is_abstract_role(current_role)) {
w.a11y_no_abstract_role(attribute, current_role); w.a11y_no_abstract_role(attribute, current_role);
@ -899,9 +897,7 @@ function check_element(node, state) {
} }
const role = attribute_map.get('role'); const role = attribute_map.get('role');
const role_static_value = /** @type {import('aria-query').ARIARoleDefinitionKey} */ ( const role_static_value = /** @type {ARIARoleDefinitionKey} */ (get_static_text_value(role));
get_static_text_value(role)
);
// click-events-have-key-events // click-events-have-key-events
if (handlers.has('click')) { if (handlers.has('click')) {
@ -922,7 +918,7 @@ function check_element(node, state) {
} }
} }
const role_value = /** @type {import('aria-query').ARIARoleDefinitionKey} */ ( const role_value = /** @type {ARIARoleDefinitionKey} */ (
role ? role_static_value : get_implicit_role(node.name, attribute_map) role ? role_static_value : get_implicit_role(node.name, attribute_map)
); );
@ -941,15 +937,11 @@ function check_element(node, state) {
// role-supports-aria-props // role-supports-aria-props
if (typeof role_value === 'string' && roles_map.has(role_value)) { if (typeof role_value === 'string' && roles_map.has(role_value)) {
const { props } = /** @type {import('aria-query').ARIARoleDefinition} */ ( const { props } = /** @type {ARIARoleDefinition} */ (roles_map.get(role_value));
roles_map.get(role_value)
);
const invalid_aria_props = aria.keys().filter((attribute) => !(attribute in props)); const invalid_aria_props = aria.keys().filter((attribute) => !(attribute in props));
const is_implicit = role_value && role === undefined; const is_implicit = role_value && role === undefined;
for (const attr of attributes) { for (const attr of attributes) {
if ( if (invalid_aria_props.includes(/** @type {ARIAProperty} */ (attr.name))) {
invalid_aria_props.includes(/** @type {import('aria-query').ARIAProperty} */ (attr.name))
) {
if (is_implicit) { if (is_implicit) {
w.a11y_role_supports_aria_props_implicit(attr, attr.name, role_value, node.name); w.a11y_role_supports_aria_props_implicit(attr, attr.name, role_value, node.name);
} else { } else {
@ -1075,7 +1067,7 @@ function check_element(node, state) {
} }
if (node.name === 'label') { if (node.name === 'label') {
/** @param {import('#compiler').TemplateNode} node */ /** @param {TemplateNode} node */
const has_input_child = (node) => { const has_input_child = (node) => {
let has = false; let has = false;
walk( walk(
@ -1112,7 +1104,7 @@ function check_element(node, state) {
return; return;
} }
let has_caption = false; let has_caption = false;
const track = /** @type {import('#compiler').RegularElement | undefined} */ ( const track = /** @type {RegularElement | undefined} */ (
node.fragment.nodes.find((i) => i.type === 'RegularElement' && i.name === 'track') node.fragment.nodes.find((i) => i.type === 'RegularElement' && i.name === 'track')
); );
if (track) { if (track) {
@ -1164,7 +1156,7 @@ function check_element(node, state) {
} }
/** /**
* @type {import('zimmerframe').Visitors<import('#compiler').SvelteNode, import('./types.js').AnalysisState>} * @type {Visitors<SvelteNode, AnalysisState>}
*/ */
export const a11y_validators = { export const a11y_validators = {
RegularElement(node, context) { RegularElement(node, context) {

@ -1,19 +1,22 @@
/** @import { ComponentAnalysis } from '../../types.js' */
/** @import { Css } from '#compiler' */
/** @import { Visitors } from 'zimmerframe' */
import { walk } from 'zimmerframe'; import { walk } from 'zimmerframe';
import * as e from '../../../errors.js'; import * as e from '../../../errors.js';
import { is_keyframes_node } from '../../css.js'; import { is_keyframes_node } from '../../css.js';
import { merge } from '../../visitors.js'; import { merge } from '../../visitors.js';
/** /**
* @typedef {import('zimmerframe').Visitors< * @typedef {Visitors<
* import('#compiler').Css.Node, * Css.Node,
* { * {
* keyframes: string[]; * keyframes: string[];
* rule: import('#compiler').Css.Rule | null; * rule: Css.Rule | null;
* } * }
* >} Visitors * >} CssVisitors
*/ */
/** @param {import('#compiler').Css.RelativeSelector} relative_selector */ /** @param {Css.RelativeSelector} relative_selector */
function is_global(relative_selector) { function is_global(relative_selector) {
const first = relative_selector.selectors[0]; const first = relative_selector.selectors[0];
@ -27,7 +30,7 @@ function is_global(relative_selector) {
); );
} }
/** @type {Visitors} */ /** @type {CssVisitors} */
const analysis_visitors = { const analysis_visitors = {
Atrule(node, context) { Atrule(node, context) {
if (is_keyframes_node(node)) { if (is_keyframes_node(node)) {
@ -102,7 +105,7 @@ const analysis_visitors = {
} }
}; };
/** @type {Visitors} */ /** @type {CssVisitors} */
const validation_visitors = { const validation_visitors = {
Rule(node, context) { Rule(node, context) {
if (node.metadata.is_global_block) { if (node.metadata.is_global_block) {
@ -178,7 +181,7 @@ const validation_visitors = {
} }
}, },
NestingSelector(node, context) { NestingSelector(node, context) {
const rule = /** @type {import('#compiler').Css.Rule} */ (context.state.rule); const rule = /** @type {Css.Rule} */ (context.state.rule);
if (!rule.metadata.parent_rule) { if (!rule.metadata.parent_rule) {
e.css_nesting_selector_invalid_placement(node); e.css_nesting_selector_invalid_placement(node);
} }
@ -188,8 +191,8 @@ const validation_visitors = {
const css_visitors = merge(analysis_visitors, validation_visitors); const css_visitors = merge(analysis_visitors, validation_visitors);
/** /**
* @param {import('#compiler').Css.StyleSheet} stylesheet * @param {Css.StyleSheet} stylesheet
* @param {import('../../types.js').ComponentAnalysis} analysis * @param {ComponentAnalysis} analysis
*/ */
export function analyze_css(stylesheet, analysis) { export function analyze_css(stylesheet, analysis) {
walk(stylesheet, { keyframes: analysis.css.keyframes, rule: null }, css_visitors); walk(stylesheet, { keyframes: analysis.css.keyframes, rule: null }, css_visitors);

@ -1,11 +1,13 @@
/** @import { Visitors } from 'zimmerframe' */
/** @import * as Compiler from '#compiler' */
import { walk } from 'zimmerframe'; import { walk } from 'zimmerframe';
import { get_possible_values } from './utils.js'; import { get_possible_values } from './utils.js';
import { regex_ends_with_whitespace, regex_starts_with_whitespace } from '../../patterns.js'; import { regex_ends_with_whitespace, regex_starts_with_whitespace } from '../../patterns.js';
/** /**
* @typedef {{ * @typedef {{
* stylesheet: import('#compiler').Css.StyleSheet; * stylesheet: Compiler.Css.StyleSheet;
* element: import('#compiler').RegularElement | import('#compiler').SvelteElement; * element: Compiler.RegularElement | Compiler.SvelteElement;
* }} State * }} State
*/ */
/** @typedef {NODE_PROBABLY_EXISTS | NODE_DEFINITELY_EXISTS} NodeExistsValue */ /** @typedef {NODE_PROBABLY_EXISTS | NODE_DEFINITELY_EXISTS} NodeExistsValue */
@ -18,7 +20,7 @@ const whitelist_attribute_selector = new Map([
['dialog', ['open']] ['dialog', ['open']]
]); ]);
/** @type {import('#compiler').Css.Combinator} */ /** @type {Compiler.Css.Combinator} */
const descendant_combinator = { const descendant_combinator = {
type: 'Combinator', type: 'Combinator',
name: ' ', name: ' ',
@ -26,7 +28,7 @@ const descendant_combinator = {
end: -1 end: -1
}; };
/** @type {import('#compiler').Css.RelativeSelector} */ /** @type {Compiler.Css.RelativeSelector} */
const nesting_selector = { const nesting_selector = {
type: 'RelativeSelector', type: 'RelativeSelector',
start: -1, start: -1,
@ -49,14 +51,14 @@ const nesting_selector = {
/** /**
* *
* @param {import('#compiler').Css.StyleSheet} stylesheet * @param {Compiler.Css.StyleSheet} stylesheet
* @param {import('#compiler').RegularElement | import('#compiler').SvelteElement} element * @param {Compiler.RegularElement | Compiler.SvelteElement} element
*/ */
export function prune(stylesheet, element) { export function prune(stylesheet, element) {
walk(stylesheet, { stylesheet, element }, visitors); walk(stylesheet, { stylesheet, element }, visitors);
} }
/** @type {import('zimmerframe').Visitors<import('#compiler').Css.Node, State>} */ /** @type {Visitors<Compiler.Css.Node, State>} */
const visitors = { const visitors = {
Rule(node, context) { Rule(node, context) {
if (node.metadata.is_global_block) { if (node.metadata.is_global_block) {
@ -87,7 +89,7 @@ const visitors = {
if ( if (
apply_selector( apply_selector(
selectors, selectors,
/** @type {import('#compiler').Css.Rule} */ (node.metadata.rule), /** @type {Compiler.Css.Rule} */ (node.metadata.rule),
context.state.element, context.state.element,
context.state.stylesheet context.state.stylesheet
) )
@ -104,7 +106,7 @@ const visitors = {
/** /**
* Discard trailing `:global(...)` selectors, these are unused for scoping purposes * Discard trailing `:global(...)` selectors, these are unused for scoping purposes
* @param {import('#compiler').Css.ComplexSelector} node * @param {Compiler.Css.ComplexSelector} node
*/ */
function truncate(node) { function truncate(node) {
const i = node.children.findLastIndex(({ metadata }) => { const i = node.children.findLastIndex(({ metadata }) => {
@ -115,10 +117,10 @@ function truncate(node) {
} }
/** /**
* @param {import('#compiler').Css.RelativeSelector[]} relative_selectors * @param {Compiler.Css.RelativeSelector[]} relative_selectors
* @param {import('#compiler').Css.Rule} rule * @param {Compiler.Css.Rule} rule
* @param {import('#compiler').RegularElement | import('#compiler').SvelteElement} element * @param {Compiler.RegularElement | Compiler.SvelteElement} element
* @param {import('#compiler').Css.StyleSheet} stylesheet * @param {Compiler.Css.StyleSheet} stylesheet
* @returns {boolean} * @returns {boolean}
*/ */
function apply_selector(relative_selectors, rule, element, stylesheet) { function apply_selector(relative_selectors, rule, element, stylesheet) {
@ -144,7 +146,7 @@ function apply_selector(relative_selectors, rule, element, stylesheet) {
switch (name) { switch (name) {
case ' ': case ' ':
case '>': { case '>': {
let parent = /** @type {import('#compiler').TemplateNode | null} */ (element.parent); let parent = /** @type {Compiler.TemplateNode | null} */ (element.parent);
let parent_matched = false; let parent_matched = false;
let crossed_component_boundary = false; let crossed_component_boundary = false;
@ -167,7 +169,7 @@ function apply_selector(relative_selectors, rule, element, stylesheet) {
if (name === '>') return parent_matched; if (name === '>') return parent_matched;
} }
parent = /** @type {import('#compiler').TemplateNode | null} */ (parent.parent); parent = /** @type {Compiler.TemplateNode | null} */ (parent.parent);
} }
return parent_matched || parent_selectors.every((selector) => is_global(selector, rule)); return parent_matched || parent_selectors.every((selector) => is_global(selector, rule));
@ -218,8 +220,8 @@ function apply_selector(relative_selectors, rule, element, stylesheet) {
/** /**
* Mark both the compound selector and the node it selects as encapsulated, * Mark both the compound selector and the node it selects as encapsulated,
* for transformation in a later step * for transformation in a later step
* @param {import('#compiler').Css.RelativeSelector} relative_selector * @param {Compiler.Css.RelativeSelector} relative_selector
* @param {import('#compiler').RegularElement | import('#compiler').SvelteElement} element * @param {Compiler.RegularElement | Compiler.SvelteElement} element
*/ */
function mark(relative_selector, element) { function mark(relative_selector, element) {
relative_selector.metadata.scoped = true; relative_selector.metadata.scoped = true;
@ -231,8 +233,8 @@ function mark(relative_selector, element) {
* it's a `:global(...)` or unscopeable selector, or * it's a `:global(...)` or unscopeable selector, or
* is an `:is(...)` or `:where(...)` selector that contains * is an `:is(...)` or `:where(...)` selector that contains
* a global selector * a global selector
* @param {import('#compiler').Css.RelativeSelector} selector * @param {Compiler.Css.RelativeSelector} selector
* @param {import('#compiler').Css.Rule} rule * @param {Compiler.Css.Rule} rule
*/ */
function is_global(selector, rule) { function is_global(selector, rule) {
if (selector.metadata.is_global || selector.metadata.is_global_like) { if (selector.metadata.is_global || selector.metadata.is_global_like) {
@ -240,7 +242,7 @@ function is_global(selector, rule) {
} }
for (const s of selector.selectors) { for (const s of selector.selectors) {
/** @type {import('#compiler').Css.SelectorList | null} */ /** @type {Compiler.Css.SelectorList | null} */
let selector_list = null; let selector_list = null;
let owner = rule; let owner = rule;
@ -251,7 +253,7 @@ function is_global(selector, rule) {
} }
if (s.type === 'NestingSelector') { if (s.type === 'NestingSelector') {
owner = /** @type {import('#compiler').Css.Rule} */ (rule.metadata.parent_rule); owner = /** @type {Compiler.Css.Rule} */ (rule.metadata.parent_rule);
selector_list = owner.prelude; selector_list = owner.prelude;
} }
@ -274,10 +276,10 @@ const regex_backslash_and_following_character = /\\(.)/g;
/** /**
* Ensure that `element` satisfies each simple selector in `relative_selector` * Ensure that `element` satisfies each simple selector in `relative_selector`
* *
* @param {import('#compiler').Css.RelativeSelector} relative_selector * @param {Compiler.Css.RelativeSelector} relative_selector
* @param {import('#compiler').Css.Rule} rule * @param {Compiler.Css.Rule} rule
* @param {import('#compiler').RegularElement | import('#compiler').SvelteElement} element * @param {Compiler.RegularElement | Compiler.SvelteElement} element
* @param {import('#compiler').Css.StyleSheet} stylesheet * @param {Compiler.Css.StyleSheet} stylesheet
* @returns {boolean} * @returns {boolean}
*/ */
function relative_selector_might_apply_to_node(relative_selector, rule, element, stylesheet) { function relative_selector_might_apply_to_node(relative_selector, rule, element, stylesheet) {
@ -293,7 +295,7 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element,
} }
if (name === 'global' && relative_selector.selectors.length === 1) { if (name === 'global' && relative_selector.selectors.length === 1) {
const args = /** @type {import('#compiler').Css.SelectorList} */ (selector.args); const args = /** @type {Compiler.Css.SelectorList} */ (selector.args);
const complex_selector = args.children[0]; const complex_selector = args.children[0];
return apply_selector(complex_selector.children, rule, element, stylesheet); return apply_selector(complex_selector.children, rule, element, stylesheet);
} }
@ -373,7 +375,7 @@ function relative_selector_might_apply_to_node(relative_selector, rule, element,
case 'NestingSelector': { case 'NestingSelector': {
let matched = false; let matched = false;
const parent = /** @type {import('#compiler').Css.Rule} */ (rule.metadata.parent_rule); const parent = /** @type {Compiler.Css.Rule} */ (rule.metadata.parent_rule);
for (const complex_selector of parent.prelude.children) { for (const complex_selector of parent.prelude.children) {
if (apply_selector(truncate(complex_selector), parent, element, stylesheet)) { if (apply_selector(truncate(complex_selector), parent, element, stylesheet)) {
@ -425,7 +427,7 @@ function test_attribute(operator, expected_value, case_insensitive, value) {
} }
/** /**
* @param {import('#compiler').RegularElement | import('#compiler').SvelteElement} node * @param {Compiler.RegularElement | Compiler.SvelteElement} node
* @param {string} name * @param {string} name
* @param {string | null} expected_value * @param {string | null} expected_value
* @param {string | null} operator * @param {string | null} operator
@ -535,11 +537,11 @@ function unquote(str) {
} }
/** /**
* @param {import('#compiler').RegularElement | import('#compiler').SvelteElement} node * @param {Compiler.RegularElement | Compiler.SvelteElement} node
* @returns {import('#compiler').RegularElement | import('#compiler').SvelteElement | null} * @returns {Compiler.RegularElement | Compiler.SvelteElement | null}
*/ */
function get_element_parent(node) { function get_element_parent(node) {
/** @type {import('#compiler').SvelteNode | null} */ /** @type {Compiler.SvelteNode | null} */
let parent = node; let parent = node;
while ( while (
// @ts-expect-error TODO figure out a more elegant solution // @ts-expect-error TODO figure out a more elegant solution
@ -569,11 +571,11 @@ function get_element_parent(node) {
* <h1>Heading 1</h1> * <h1>Heading 1</h1>
* <h2>Heading 2</h2> * <h2>Heading 2</h2>
* ``` * ```
* @param {import('#compiler').SvelteNode} node * @param {Compiler.SvelteNode} node
* @returns {import('#compiler').SvelteNode} * @returns {Compiler.SvelteNode}
*/ */
function find_previous_sibling(node) { function find_previous_sibling(node) {
/** @type {import('#compiler').SvelteNode} */ /** @type {Compiler.SvelteNode} */
let current_node = node; let current_node = node;
while ( while (
@ -602,15 +604,15 @@ function find_previous_sibling(node) {
} }
/** /**
* @param {import('#compiler').SvelteNode} node * @param {Compiler.SvelteNode} node
* @param {boolean} adjacent_only * @param {boolean} adjacent_only
* @returns {Map<import('#compiler').RegularElement | import('#compiler').SvelteElement | import('#compiler').SlotElement | import('#compiler').RenderTag, NodeExistsValue>} * @returns {Map<Compiler.RegularElement | Compiler.SvelteElement | Compiler.SlotElement | Compiler.RenderTag, NodeExistsValue>}
*/ */
function get_possible_element_siblings(node, adjacent_only) { function get_possible_element_siblings(node, adjacent_only) {
/** @type {Map<import('#compiler').RegularElement | import('#compiler').SvelteElement | import('#compiler').SlotElement | import('#compiler').RenderTag, NodeExistsValue>} */ /** @type {Map<Compiler.RegularElement | Compiler.SvelteElement | Compiler.SlotElement | Compiler.RenderTag, NodeExistsValue>} */
const result = new Map(); const result = new Map();
/** @type {import('#compiler').SvelteNode} */ /** @type {Compiler.SvelteNode} */
let prev = node; let prev = node;
while ((prev = find_previous_sibling(prev))) { while ((prev = find_previous_sibling(prev))) {
if (prev.type === 'RegularElement') { if (prev.type === 'RegularElement') {
@ -642,7 +644,7 @@ function get_possible_element_siblings(node, adjacent_only) {
} }
if (!prev || !adjacent_only) { if (!prev || !adjacent_only) {
/** @type {import('#compiler').SvelteNode | null} */ /** @type {Compiler.SvelteNode | null} */
let parent = node; let parent = node;
while ( while (
@ -669,12 +671,12 @@ function get_possible_element_siblings(node, adjacent_only) {
} }
/** /**
* @param {import('#compiler').EachBlock | import('#compiler').IfBlock | import('#compiler').AwaitBlock} relative_selector * @param {Compiler.EachBlock | Compiler.IfBlock | Compiler.AwaitBlock} relative_selector
* @param {boolean} adjacent_only * @param {boolean} adjacent_only
* @returns {Map<import('#compiler').RegularElement, NodeExistsValue>} * @returns {Map<Compiler.RegularElement, NodeExistsValue>}
*/ */
function get_possible_last_child(relative_selector, adjacent_only) { function get_possible_last_child(relative_selector, adjacent_only) {
/** @typedef {Map<import('#compiler').RegularElement, NodeExistsValue>} NodeMap */ /** @typedef {Map<Compiler.RegularElement, NodeExistsValue>} NodeMap */
/** @type {NodeMap} */ /** @type {NodeMap} */
const result = new Map(); const result = new Map();
@ -776,7 +778,7 @@ function higher_existence(exist1, exist2) {
return exist1 > exist2 ? exist1 : exist2; return exist1 > exist2 ? exist1 : exist2;
} }
/** @param {Map<import('#compiler').RegularElement, NodeExistsValue>} result */ /** @param {Map<Compiler.RegularElement, NodeExistsValue>} result */
function mark_as_probably(result) { function mark_as_probably(result) {
for (const key of result.keys()) { for (const key of result.keys()) {
result.set(key, NODE_PROBABLY_EXISTS); result.set(key, NODE_PROBABLY_EXISTS);
@ -784,11 +786,11 @@ function mark_as_probably(result) {
} }
/** /**
* @param {import('#compiler').SvelteNode[]} children * @param {Compiler.SvelteNode[]} children
* @param {boolean} adjacent_only * @param {boolean} adjacent_only
*/ */
function loop_child(children, adjacent_only) { function loop_child(children, adjacent_only) {
/** @type {Map<import('#compiler').RegularElement, NodeExistsValue>} */ /** @type {Map<Compiler.RegularElement, NodeExistsValue>} */
const result = new Map(); const result = new Map();
for (let i = children.length - 1; i >= 0; i--) { for (let i = children.length - 1; i >= 0; i--) {
const child = children[i]; const child = children[i];

@ -1,15 +1,17 @@
/** @import { Visitors } from 'zimmerframe' */
/** @import { Css } from '#compiler' */
import { walk } from 'zimmerframe'; import { walk } from 'zimmerframe';
import * as w from '../../../warnings.js'; import * as w from '../../../warnings.js';
import { is_keyframes_node } from '../../css.js'; import { is_keyframes_node } from '../../css.js';
/** /**
* @param {import('#compiler').Css.StyleSheet} stylesheet * @param {Css.StyleSheet} stylesheet
*/ */
export function warn_unused(stylesheet) { export function warn_unused(stylesheet) {
walk(stylesheet, { stylesheet }, visitors); walk(stylesheet, { stylesheet }, visitors);
} }
/** @type {import('zimmerframe').Visitors<import('#compiler').Css.Node, { stylesheet: import('#compiler').Css.StyleSheet }>} */ /** @type {Visitors<Css.Node, { stylesheet: Css.StyleSheet }>} */
const visitors = { const visitors = {
Atrule(node, context) { Atrule(node, context) {
if (!is_keyframes_node(node)) { if (!is_keyframes_node(node)) {

@ -1,7 +1,9 @@
/** @import { Text, ExpressionTag } from '#compiler' */
/** @import { Node } from 'estree' */
const UNKNOWN = {}; const UNKNOWN = {};
/** /**
* @param {import('estree').Node} node * @param {Node} node
* @param {Set<any>} set * @param {Set<any>} set
*/ */
function gather_possible_values(node, set) { function gather_possible_values(node, set) {
@ -16,7 +18,7 @@ function gather_possible_values(node, set) {
} }
/** /**
* @param {import('#compiler').Text | import('#compiler').ExpressionTag} chunk * @param {Text | ExpressionTag} chunk
* @returns {Set<string> | null} * @returns {Set<string> | null}
*/ */
export function get_possible_values(chunk) { export function get_possible_values(chunk) {

@ -1,3 +1,7 @@
/** @import * as ESTree from 'estree' */
/** @import { ValidatedCompileOptions, SvelteNode, ValidatedModuleCompileOptions } from '#compiler' */
/** @import { ComponentAnalysis, Analysis } from '../../types' */
/** @import { Visitors, ComponentClientTransformState, ClientTransformState } from './types' */
import { walk } from 'zimmerframe'; import { walk } from 'zimmerframe';
import * as b from '../../../utils/builders.js'; import * as b from '../../../utils/builders.js';
import { set_scope } from '../../scope.js'; import { set_scope } from '../../scope.js';
@ -12,8 +16,8 @@ import { filename } from '../../../state.js';
/** /**
* This function ensures visitor sets don't accidentally clobber each other * This function ensures visitor sets don't accidentally clobber each other
* @param {...import('./types').Visitors} array * @param {...Visitors} array
* @returns {import('./types').Visitors} * @returns {Visitors}
*/ */
function combine_visitors(...array) { function combine_visitors(...array) {
/** @type {Record<string, any>} */ /** @type {Record<string, any>} */
@ -35,12 +39,12 @@ function combine_visitors(...array) {
/** /**
* @param {string} source * @param {string} source
* @param {import('../../types').ComponentAnalysis} analysis * @param {ComponentAnalysis} analysis
* @param {import('#compiler').ValidatedCompileOptions} options * @param {ValidatedCompileOptions} options
* @returns {import('estree').Program} * @returns {ESTree.Program}
*/ */
export function client_component(source, analysis, options) { export function client_component(source, analysis, options) {
/** @type {import('./types').ComponentClientTransformState} */ /** @type {ComponentClientTransformState} */
const state = { const state = {
analysis, analysis,
options, options,
@ -72,9 +76,9 @@ export function client_component(source, analysis, options) {
locations: /** @type {any} */ (null) locations: /** @type {any} */ (null)
}; };
const module = /** @type {import('estree').Program} */ ( const module = /** @type {ESTree.Program} */ (
walk( walk(
/** @type {import('#compiler').SvelteNode} */ (analysis.module.ast), /** @type {SvelteNode} */ (analysis.module.ast),
state, state,
combine_visitors( combine_visitors(
set_scope(analysis.module.scopes), set_scope(analysis.module.scopes),
@ -87,9 +91,9 @@ export function client_component(source, analysis, options) {
); );
const instance_state = { ...state, scope: analysis.instance.scope }; const instance_state = { ...state, scope: analysis.instance.scope };
const instance = /** @type {import('estree').Program} */ ( const instance = /** @type {ESTree.Program} */ (
walk( walk(
/** @type {import('#compiler').SvelteNode} */ (analysis.instance.ast), /** @type {SvelteNode} */ (analysis.instance.ast),
instance_state, instance_state,
combine_visitors( combine_visitors(
set_scope(analysis.instance.scopes), set_scope(analysis.instance.scopes),
@ -114,9 +118,9 @@ export function client_component(source, analysis, options) {
) )
); );
const template = /** @type {import('estree').Program} */ ( const template = /** @type {ESTree.Program} */ (
walk( walk(
/** @type {import('#compiler').SvelteNode} */ (analysis.template.ast), /** @type {SvelteNode} */ (analysis.template.ast),
{ ...state, scope: analysis.instance.scope }, { ...state, scope: analysis.instance.scope },
combine_visitors( combine_visitors(
set_scope(analysis.template.scopes), set_scope(analysis.template.scopes),
@ -138,10 +142,10 @@ export function client_component(source, analysis, options) {
} }
} }
/** @type {import('estree').Statement[]} */ /** @type {ESTree.Statement[]} */
const store_setup = []; const store_setup = [];
/** @type {import('estree').VariableDeclaration[]} */ /** @type {ESTree.VariableDeclaration[]} */
const legacy_reactive_declarations = []; const legacy_reactive_declarations = [];
for (const [name, binding] of analysis.instance.scope.declarations) { for (const [name, binding] of analysis.instance.scope.declarations) {
@ -193,14 +197,14 @@ export function client_component(source, analysis, options) {
/** /**
* Used to store the group nodes * Used to store the group nodes
* @type {import('estree').VariableDeclaration[]} * @type {ESTree.VariableDeclaration[]}
*/ */
const group_binding_declarations = []; const group_binding_declarations = [];
for (const group of analysis.binding_groups.values()) { for (const group of analysis.binding_groups.values()) {
group_binding_declarations.push(b.const(group.name, b.array([]))); group_binding_declarations.push(b.const(group.name, b.array([])));
} }
/** @type {Array<import('estree').Property | import('estree').SpreadElement>} */ /** @type {Array<ESTree.Property | ESTree.SpreadElement>} */
const component_returned_object = analysis.exports.map(({ name, alias }) => { const component_returned_object = analysis.exports.map(({ name, alias }) => {
const expression = serialize_get_binding(b.id(name), instance_state); const expression = serialize_get_binding(b.id(name), instance_state);
@ -218,7 +222,7 @@ export function client_component(source, analysis, options) {
if (analysis.runes && options.dev) { if (analysis.runes && options.dev) {
const exports = analysis.exports.map(({ name, alias }) => b.literal(alias ?? name)); const exports = analysis.exports.map(({ name, alias }) => b.literal(alias ?? name));
/** @type {import('estree').Literal[]} */ /** @type {ESTree.Literal[]} */
const bindable = []; const bindable = [];
for (const [name, binding] of properties) { for (const [name, binding] of properties) {
if (binding.kind === 'bindable_prop') { if (binding.kind === 'bindable_prop') {
@ -254,7 +258,7 @@ export function client_component(source, analysis, options) {
setter.value.params[0] = { setter.value.params[0] = {
type: 'AssignmentPattern', type: 'AssignmentPattern',
left: b.id('$$value'), left: b.id('$$value'),
right: /** @type {import('estree').Expression} */ (binding.initial) right: /** @type {ESTree.Expression} */ (binding.initial)
}; };
} }
@ -290,9 +294,9 @@ export function client_component(source, analysis, options) {
...legacy_reactive_declarations, ...legacy_reactive_declarations,
...group_binding_declarations, ...group_binding_declarations,
...analysis.top_level_snippets, ...analysis.top_level_snippets,
.../** @type {import('estree').Statement[]} */ (instance.body), .../** @type {ESTree.Statement[]} */ (instance.body),
analysis.runes || !analysis.needs_context ? b.empty : b.stmt(b.call('$.init')), analysis.runes || !analysis.needs_context ? b.empty : b.stmt(b.call('$.init')),
.../** @type {import('estree').Statement[]} */ (template.body) .../** @type {ESTree.Statement[]} */ (template.body)
]); ]);
if (!analysis.runes) { if (!analysis.runes) {
@ -480,7 +484,7 @@ export function client_component(source, analysis, options) {
if (analysis.custom_element) { if (analysis.custom_element) {
const ce = analysis.custom_element; const ce = analysis.custom_element;
/** @type {import('estree').Property[]} */ /** @type {ESTree.Property[]} */
const props_str = []; const props_str = [];
for (const [name, binding] of properties) { for (const [name, binding] of properties) {
@ -495,7 +499,7 @@ export function client_component(source, analysis, options) {
} }
const value = b.object( const value = b.object(
/** @type {import('estree').Property[]} */ ( /** @type {ESTree.Property[]} */ (
[ [
prop_def.attribute ? b.init('attribute', b.literal(prop_def.attribute)) : undefined, prop_def.attribute ? b.init('attribute', b.literal(prop_def.attribute)) : undefined,
prop_def.reflect ? b.init('reflect', b.literal(true)) : undefined, prop_def.reflect ? b.init('reflect', b.literal(true)) : undefined,
@ -539,12 +543,12 @@ export function client_component(source, analysis, options) {
} }
/** /**
* @param {import('../../types').Analysis} analysis * @param {Analysis} analysis
* @param {import('#compiler').ValidatedModuleCompileOptions} options * @param {ValidatedModuleCompileOptions} options
* @returns {import('estree').Program} * @returns {ESTree.Program}
*/ */
export function client_module(analysis, options) { export function client_module(analysis, options) {
/** @type {import('./types').ClientTransformState} */ /** @type {ClientTransformState} */
const state = { const state = {
analysis, analysis,
options, options,
@ -556,9 +560,9 @@ export function client_module(analysis, options) {
in_constructor: false in_constructor: false
}; };
const module = /** @type {import('estree').Program} */ ( const module = /** @type {ESTree.Program} */ (
walk( walk(
/** @type {import('#compiler').SvelteNode} */ (analysis.module.ast), /** @type {SvelteNode} */ (analysis.module.ast),
state, state,
combine_visitors( combine_visitors(
set_scope(analysis.module.scopes), set_scope(analysis.module.scopes),

@ -1,3 +1,7 @@
/** @import { Binding, ReactiveStatement } from '#compiler' */
/** @import { ComponentVisitors } from '../types.js' */
/** @import { Scope } from '../../../scope.js' */
/** @import { VariableDeclarator, Expression, Identifier, Statement } from 'estree' */
import { is_hoistable_function } from '../../utils.js'; import { is_hoistable_function } from '../../utils.js';
import * as b from '../../../../utils/builders.js'; import * as b from '../../../../utils/builders.js';
import { extract_paths } from '../../../../utils/ast.js'; import { extract_paths } from '../../../../utils/ast.js';
@ -5,9 +9,9 @@ import { get_prop_source, serialize_get_binding } from '../utils.js';
/** /**
* Creates the output for a state declaration. * Creates the output for a state declaration.
* @param {import('estree').VariableDeclarator} declarator * @param {VariableDeclarator} declarator
* @param {import('../../../scope.js').Scope} scope * @param {Scope} scope
* @param {import('estree').Expression} value * @param {Expression} value
*/ */
function create_state_declarators(declarator, scope, value) { function create_state_declarators(declarator, scope, value) {
if (declarator.id.type === 'Identifier') { if (declarator.id.type === 'Identifier') {
@ -20,7 +24,7 @@ function create_state_declarators(declarator, scope, value) {
b.declarator(b.id(tmp), value), b.declarator(b.id(tmp), value),
...paths.map((path) => { ...paths.map((path) => {
const value = path.expression?.(b.id(tmp)); const value = path.expression?.(b.id(tmp));
const binding = scope.get(/** @type {import('estree').Identifier} */ (path.node).name); const binding = scope.get(/** @type {Identifier} */ (path.node).name);
return b.declarator( return b.declarator(
path.node, path.node,
binding?.kind === 'state' ? b.call('$.mutable_source', value) : value binding?.kind === 'state' ? b.call('$.mutable_source', value) : value
@ -29,16 +33,14 @@ function create_state_declarators(declarator, scope, value) {
]; ];
} }
/** @type {import('../types.js').ComponentVisitors} */ /** @type {ComponentVisitors} */
export const javascript_visitors_legacy = { export const javascript_visitors_legacy = {
VariableDeclaration(node, { state, visit }) { VariableDeclaration(node, { state, visit }) {
/** @type {import('estree').VariableDeclarator[]} */ /** @type {VariableDeclarator[]} */
const declarations = []; const declarations = [];
for (const declarator of node.declarations) { for (const declarator of node.declarations) {
const bindings = /** @type {import('#compiler').Binding[]} */ ( const bindings = /** @type {Binding[]} */ (state.scope.get_bindings(declarator));
state.scope.get_bindings(declarator)
);
const has_state = bindings.some((binding) => binding.kind === 'state'); const has_state = bindings.some((binding) => binding.kind === 'state');
const has_props = bindings.some((binding) => binding.kind === 'bindable_prop'); const has_props = bindings.some((binding) => binding.kind === 'bindable_prop');
@ -47,15 +49,11 @@ export const javascript_visitors_legacy = {
if (init != null && is_hoistable_function(init)) { if (init != null && is_hoistable_function(init)) {
const hoistable_function = visit(init); const hoistable_function = visit(init);
state.hoisted.push( state.hoisted.push(
b.declaration( b.declaration('const', declarator.id, /** @type {Expression} */ (hoistable_function))
'const',
declarator.id,
/** @type {import('estree').Expression} */ (hoistable_function)
)
); );
continue; continue;
} }
declarations.push(/** @type {import('estree').VariableDeclarator} */ (visit(declarator))); declarations.push(/** @type {VariableDeclarator} */ (visit(declarator)));
continue; continue;
} }
@ -68,14 +66,12 @@ export const javascript_visitors_legacy = {
declarations.push( declarations.push(
b.declarator( b.declarator(
b.id(tmp), b.id(tmp),
/** @type {import('estree').Expression} */ ( /** @type {Expression} */ (visit(/** @type {Expression} */ (declarator.init)))
visit(/** @type {import('estree').Expression} */ (declarator.init))
)
) )
); );
for (const path of paths) { for (const path of paths) {
const name = /** @type {import('estree').Identifier} */ (path.node).name; const name = /** @type {Identifier} */ (path.node).name;
const binding = /** @type {import('#compiler').Binding} */ (state.scope.get(name)); const binding = /** @type {Binding} */ (state.scope.get(name));
const value = path.expression?.(b.id(tmp)); const value = path.expression?.(b.id(tmp));
declarations.push( declarations.push(
b.declarator( b.declarator(
@ -89,9 +85,7 @@ export const javascript_visitors_legacy = {
continue; continue;
} }
const binding = /** @type {import('#compiler').Binding} */ ( const binding = /** @type {Binding} */ (state.scope.get(declarator.id.name));
state.scope.get(declarator.id.name)
);
declarations.push( declarations.push(
b.declarator( b.declarator(
@ -100,7 +94,7 @@ export const javascript_visitors_legacy = {
binding, binding,
state, state,
binding.prop_alias ?? declarator.id.name, binding.prop_alias ?? declarator.id.name,
declarator.init && /** @type {import('estree').Expression} */ (visit(declarator.init)) declarator.init && /** @type {Expression} */ (visit(declarator.init))
) )
) )
); );
@ -112,7 +106,7 @@ export const javascript_visitors_legacy = {
...create_state_declarators( ...create_state_declarators(
declarator, declarator,
state.scope, state.scope,
/** @type {import('estree').Expression} */ (declarator.init && visit(declarator.init)) /** @type {Expression} */ (declarator.init && visit(declarator.init))
) )
); );
} }
@ -135,7 +129,7 @@ export const javascript_visitors_legacy = {
const state = context.state; const state = context.state;
// To recreate Svelte 4 behaviour, we track the dependencies // To recreate Svelte 4 behaviour, we track the dependencies
// the compiler can 'see', but we untrack the effect itself // the compiler can 'see', but we untrack the effect itself
const reactive_stmt = /** @type {import('#compiler').ReactiveStatement} */ ( const reactive_stmt = /** @type {ReactiveStatement} */ (
state.analysis.reactive_statements.get(node) state.analysis.reactive_statements.get(node)
); );
@ -143,7 +137,7 @@ export const javascript_visitors_legacy = {
const { dependencies } = reactive_stmt; const { dependencies } = reactive_stmt;
let serialized_body = /** @type {import('estree').Statement} */ (context.visit(node.body)); let serialized_body = /** @type {Statement} */ (context.visit(node.body));
if (serialized_body.type !== 'BlockStatement') { if (serialized_body.type !== 'BlockStatement') {
serialized_body = b.block([serialized_body]); serialized_body = b.block([serialized_body]);
@ -151,7 +145,7 @@ export const javascript_visitors_legacy = {
const body = serialized_body.body; const body = serialized_body.body;
/** @type {import('estree').Expression[]} */ /** @type {Expression[]} */
const sequence = []; const sequence = [];
for (const binding of dependencies) { for (const binding of dependencies) {
if (binding.kind === 'normal') continue; if (binding.kind === 'normal') continue;

@ -1,7 +1,9 @@
/** @import { FunctionDeclaration } from 'estree' */
/** @import { ComponentVisitors } from '../types.js' */
import * as b from '../../../../utils/builders.js'; import * as b from '../../../../utils/builders.js';
import { function_visitor, serialize_hoistable_params } from '../utils.js'; import { function_visitor, serialize_hoistable_params } from '../utils.js';
/** @type {import('../types.js').ComponentVisitors} */ /** @type {ComponentVisitors} */
export const javascript_visitors = { export const javascript_visitors = {
FunctionExpression: function_visitor, FunctionExpression: function_visitor,
ArrowFunctionExpression: function_visitor, ArrowFunctionExpression: function_visitor,
@ -14,7 +16,7 @@ export const javascript_visitors = {
const params = serialize_hoistable_params(node, context); const params = serialize_hoistable_params(node, context);
context.state.hoisted.push( context.state.hoisted.push(
/** @type {import('estree').FunctionDeclaration} */ ({ /** @type {FunctionDeclaration} */ ({
...node, ...node,
id: node.id !== null ? context.visit(node.id, state) : null, id: node.id !== null ? context.visit(node.id, state) : null,
params, params,

@ -1,3 +1,6 @@
/** @import { Visitors } from 'zimmerframe' */
/** @import { ValidatedCompileOptions, Css } from '#compiler' */
/** @import { ComponentAnalysis } from '../../types.js' */
import MagicString from 'magic-string'; import MagicString from 'magic-string';
import { walk } from 'zimmerframe'; import { walk } from 'zimmerframe';
import { is_keyframes_node, regex_css_name_boundary, remove_css_prefix } from '../../css.js'; import { is_keyframes_node, regex_css_name_boundary, remove_css_prefix } from '../../css.js';
@ -19,8 +22,8 @@ import { merge_with_preprocessor_map } from '../../../utils/mapped_code.js';
/** /**
* *
* @param {string} source * @param {string} source
* @param {import('../../types.js').ComponentAnalysis} analysis * @param {ComponentAnalysis} analysis
* @param {import('#compiler').ValidatedCompileOptions} options * @param {ValidatedCompileOptions} options
*/ */
export function render_stylesheet(source, analysis, options) { export function render_stylesheet(source, analysis, options) {
const code = new MagicString(source); const code = new MagicString(source);
@ -37,9 +40,9 @@ export function render_stylesheet(source, analysis, options) {
} }
}; };
const ast = /** @type {import('#compiler').Css.StyleSheet} */ (analysis.css.ast); const ast = /** @type {Css.StyleSheet} */ (analysis.css.ast);
walk(/** @type {import('#compiler').Css.Node} */ (ast), state, visitors); walk(/** @type {Css.Node} */ (ast), state, visitors);
code.remove(0, ast.content.start); code.remove(0, ast.content.start);
code.remove(/** @type {number} */ (ast.content.end), source.length); code.remove(/** @type {number} */ (ast.content.end), source.length);
@ -64,7 +67,7 @@ export function render_stylesheet(source, analysis, options) {
return css; return css;
} }
/** @type {import('zimmerframe').Visitors<import('#compiler').Css.Node, State>} */ /** @type {Visitors<Css.Node, State>} */
const visitors = { const visitors = {
_: (node, context) => { _: (node, context) => {
context.state.code.addSourcemapLocation(node.start); context.state.code.addSourcemapLocation(node.start);
@ -196,7 +199,7 @@ const visitors = {
if (parent?.type === 'Rule') { if (parent?.type === 'Rule') {
specificity = { bumped: false }; specificity = { bumped: false };
/** @type {import('#compiler').Css.Rule | null} */ /** @type {Css.Rule | null} */
let rule = parent.metadata.parent_rule; let rule = parent.metadata.parent_rule;
while (rule) { while (rule) {
@ -213,7 +216,7 @@ const visitors = {
ComplexSelector(node, context) { ComplexSelector(node, context) {
const before_bumped = context.state.specificity.bumped; const before_bumped = context.state.specificity.bumped;
/** @param {import('#compiler').Css.SimpleSelector} selector */ /** @param {Css.SimpleSelector} selector */
function remove_global_pseudo_class(selector) { function remove_global_pseudo_class(selector) {
context.state.code context.state.code
.remove(selector.start, selector.start + ':global('.length) .remove(selector.start, selector.start + ':global('.length)
@ -293,7 +296,7 @@ const visitors = {
} }
}; };
/** @param {import('#compiler').Css.Rule} rule */ /** @param {Css.Rule} rule */
function is_empty(rule) { function is_empty(rule) {
if (rule.metadata.is_global_block) { if (rule.metadata.is_global_block) {
return rule.block.children.length === 0; return rule.block.children.length === 0;
@ -316,7 +319,7 @@ function is_empty(rule) {
return true; return true;
} }
/** @param {import('#compiler').Css.Rule} rule */ /** @param {Css.Rule} rule */
function is_used(rule) { function is_used(rule) {
for (const selector of rule.prelude.children) { for (const selector of rule.prelude.children) {
if (selector.metadata.used) return true; if (selector.metadata.used) return true;
@ -335,7 +338,7 @@ function is_used(rule) {
/** /**
* *
* @param {import('#compiler').Css.Rule} node * @param {Css.Rule} node
* @param {MagicString} code * @param {MagicString} code
*/ */
function escape_comment_close(node, code) { function escape_comment_close(node, code) {

@ -1,3 +1,5 @@
/** @import { ValidatedCompileOptions, CompileResult, ValidatedModuleCompileOptions } from '#compiler' */
/** @import { ComponentAnalysis, Analysis } from '../types' */
import { print } from 'esrap'; import { print } from 'esrap';
import { VERSION } from '../../../version.js'; import { VERSION } from '../../../version.js';
import { server_component, server_module } from './server/transform-server.js'; import { server_component, server_module } from './server/transform-server.js';
@ -7,10 +9,10 @@ import { merge_with_preprocessor_map, get_source_name } from '../../utils/mapped
import * as state from '../../state.js'; import * as state from '../../state.js';
/** /**
* @param {import('../types').ComponentAnalysis} analysis * @param {ComponentAnalysis} analysis
* @param {string} source * @param {string} source
* @param {import('#compiler').ValidatedCompileOptions} options * @param {ValidatedCompileOptions} options
* @returns {import('#compiler').CompileResult} * @returns {CompileResult}
*/ */
export function transform_component(analysis, source, options) { export function transform_component(analysis, source, options) {
if (options.generate === false) { if (options.generate === false) {
@ -55,10 +57,10 @@ export function transform_component(analysis, source, options) {
} }
/** /**
* @param {import('../types').Analysis} analysis * @param {Analysis} analysis
* @param {string} source * @param {string} source
* @param {import('#compiler').ValidatedModuleCompileOptions} options * @param {ValidatedModuleCompileOptions} options
* @returns {import('#compiler').CompileResult} * @returns {CompileResult}
*/ */
export function transform_module(analysis, source, options) { export function transform_module(analysis, source, options) {
if (options.generate === false) { if (options.generate === false) {

@ -1,3 +1,7 @@
/** @import { Context } from 'zimmerframe' */
/** @import { TransformState } from './types.js' */
/** @import * as Compiler from '#compiler' */
/** @import { Node, Expression, CallExpression } from 'estree' */
import { import {
regex_ends_with_whitespaces, regex_ends_with_whitespaces,
regex_not_whitespace, regex_not_whitespace,
@ -12,7 +16,7 @@ import is_reference from 'is-reference';
import { set_scope } from '../scope.js'; import { set_scope } from '../scope.js';
/** /**
* @param {import('estree').Node} node * @param {Node} node
* @returns {boolean} * @returns {boolean}
*/ */
export function is_hoistable_function(node) { export function is_hoistable_function(node) {
@ -28,20 +32,20 @@ export function is_hoistable_function(node) {
/** /**
* Match Svelte 4 behaviour by sorting ConstTag nodes in topological order * Match Svelte 4 behaviour by sorting ConstTag nodes in topological order
* @param {import("#compiler").SvelteNode[]} nodes * @param {Compiler.SvelteNode[]} nodes
* @param {import('./types.js').TransformState} state * @param {TransformState} state
*/ */
function sort_const_tags(nodes, state) { function sort_const_tags(nodes, state) {
/** /**
* @typedef {{ * @typedef {{
* node: import('#compiler').ConstTag; * node: Compiler.ConstTag;
* deps: Set<import('#compiler').Binding>; * deps: Set<Compiler.Binding>;
* }} Tag * }} Tag
*/ */
const other = []; const other = [];
/** @type {Map<import('#compiler').Binding, Tag>} */ /** @type {Map<Compiler.Binding, Tag>} */
const tags = new Map(); const tags = new Map();
const { _ } = set_scope(state.scopes); const { _ } = set_scope(state.scopes);
@ -51,16 +55,16 @@ function sort_const_tags(nodes, state) {
const declaration = node.declaration.declarations[0]; const declaration = node.declaration.declarations[0];
const bindings = extract_identifiers(declaration.id).map((id) => { const bindings = extract_identifiers(declaration.id).map((id) => {
return /** @type {import('#compiler').Binding} */ (state.scope.get(id.name)); return /** @type {Compiler.Binding} */ (state.scope.get(id.name));
}); });
/** @type {Set<import('#compiler').Binding>} */ /** @type {Set<Compiler.Binding>} */
const deps = new Set(); const deps = new Set();
walk(declaration.init, state, { walk(declaration.init, state, {
_, _,
Identifier(node, context) { Identifier(node, context) {
const parent = /** @type {import('estree').Expression} */ (context.path.at(-1)); const parent = /** @type {Expression} */ (context.path.at(-1));
if (is_reference(node, parent)) { if (is_reference(node, parent)) {
const binding = context.state.scope.get(node.name); const binding = context.state.scope.get(node.name);
@ -81,7 +85,7 @@ function sort_const_tags(nodes, state) {
return nodes; return nodes;
} }
/** @type {Array<[import('#compiler').Binding, import('#compiler').Binding]>} */ /** @type {Array<[Compiler.Binding, Compiler.Binding]>} */
const edges = []; const edges = [];
for (const [id, tag] of tags) { for (const [id, tag] of tags) {
@ -98,7 +102,7 @@ function sort_const_tags(nodes, state) {
e.const_tag_cycle(tag.node, cycle.map((binding) => binding.node.name).join(' → ')); e.const_tag_cycle(tag.node, cycle.map((binding) => binding.node.name).join(' → '));
} }
/** @type {import('#compiler').ConstTag[]} */ /** @type {Compiler.ConstTag[]} */
const sorted = []; const sorted = [];
/** @param {Tag} tag */ /** @param {Tag} tag */
@ -129,11 +133,11 @@ function sort_const_tags(nodes, state) {
* unless it's whitespace-only, in which case collapse to a single whitespace for all cases * unless it's whitespace-only, in which case collapse to a single whitespace for all cases
* except when it's children of certain elements where we know ignore whitespace (like td/option/head), * except when it's children of certain elements where we know ignore whitespace (like td/option/head),
* in which case we remove it entirely * in which case we remove it entirely
* @param {import('#compiler').SvelteNode} parent * @param {Compiler.SvelteNode} parent
* @param {import('#compiler').SvelteNode[]} nodes * @param {Compiler.SvelteNode[]} nodes
* @param {import('#compiler').SvelteNode[]} path * @param {Compiler.SvelteNode[]} path
* @param {import('#compiler').Namespace} namespace * @param {Compiler.Namespace} namespace
* @param {import('./types.js').TransformState} state * @param {TransformState} state
* @param {boolean} preserve_whitespace * @param {boolean} preserve_whitespace
* @param {boolean} preserve_comments * @param {boolean} preserve_comments
*/ */
@ -153,10 +157,10 @@ export function clean_nodes(
nodes = sort_const_tags(nodes, state); nodes = sort_const_tags(nodes, state);
} }
/** @type {import('#compiler').SvelteNode[]} */ /** @type {Compiler.SvelteNode[]} */
const hoisted = []; const hoisted = [];
/** @type {import('#compiler').SvelteNode[]} */ /** @type {Compiler.SvelteNode[]} */
const regular = []; const regular = [];
for (const node of nodes) { for (const node of nodes) {
@ -220,7 +224,7 @@ export function clean_nodes(
parent.name === 'colgroup' || parent.name === 'colgroup' ||
parent.name === 'datalist')); parent.name === 'datalist'));
/** @type {import('#compiler').SvelteNode[]} */ /** @type {Compiler.SvelteNode[]} */
const trimmed = []; const trimmed = [];
// Replace any whitespace between a text and non-text node with a single spaceand keep whitespace // Replace any whitespace between a text and non-text node with a single spaceand keep whitespace
@ -262,9 +266,9 @@ export function clean_nodes(
/** /**
* Infers the namespace for the children of a node that should be used when creating the `$.template(...)`. * Infers the namespace for the children of a node that should be used when creating the `$.template(...)`.
* @param {import('#compiler').Namespace} namespace * @param {Compiler.Namespace} namespace
* @param {import('#compiler').SvelteNode} parent * @param {Compiler.SvelteNode} parent
* @param {import('#compiler').SvelteNode[]} nodes * @param {Compiler.SvelteNode[]} nodes
*/ */
export function infer_namespace(namespace, parent, nodes) { export function infer_namespace(namespace, parent, nodes) {
if (namespace !== 'foreign') { if (namespace !== 'foreign') {
@ -303,12 +307,12 @@ export function infer_namespace(namespace, parent, nodes) {
* Heuristic: Keep current namespace, unless we find a regular element, * Heuristic: Keep current namespace, unless we find a regular element,
* in which case we always want html, or we only find svg nodes, * in which case we always want html, or we only find svg nodes,
* in which case we assume svg. * in which case we assume svg.
* @param {import('#compiler').SvelteNode[]} nodes * @param {Compiler.SvelteNode[]} nodes
* @param {import('#compiler').Namespace | 'keep' | 'maybe_html'} namespace * @param {Compiler.Namespace | 'keep' | 'maybe_html'} namespace
*/ */
function check_nodes_for_namespace(nodes, namespace) { function check_nodes_for_namespace(nodes, namespace) {
/** /**
* @param {import('#compiler').SvelteElement | import('#compiler').RegularElement} node} * @param {Compiler.SvelteElement | Compiler.RegularElement} node}
* @param {{stop: () => void}} context * @param {{stop: () => void}} context
*/ */
const RegularElement = (node, { stop }) => { const RegularElement = (node, { stop }) => {
@ -357,9 +361,9 @@ function check_nodes_for_namespace(nodes, namespace) {
/** /**
* Determines the namespace the children of this node are in. * Determines the namespace the children of this node are in.
* @param {import('#compiler').RegularElement | import('#compiler').SvelteElement} node * @param {Compiler.RegularElement | Compiler.SvelteElement} node
* @param {import('#compiler').Namespace} namespace * @param {Compiler.Namespace} namespace
* @returns {import('#compiler').Namespace} * @returns {Compiler.Namespace}
*/ */
export function determine_namespace_for_children(node, namespace) { export function determine_namespace_for_children(node, namespace) {
if (namespace === 'foreign') { if (namespace === 'foreign') {
@ -378,9 +382,9 @@ export function determine_namespace_for_children(node, namespace) {
} }
/** /**
* @template {import('./types.js').TransformState} T * @template {TransformState} T
* @param {import('estree').CallExpression} node * @param {CallExpression} node
* @param {import('zimmerframe').Context<any, T>} context * @param {Context<any, T>} context
*/ */
export function transform_inspect_rune(node, context) { export function transform_inspect_rune(node, context) {
const { state, visit } = context; const { state, visit } = context;
@ -389,12 +393,11 @@ export function transform_inspect_rune(node, context) {
if (!state.options.dev) return b.unary('void', b.literal(0)); if (!state.options.dev) return b.unary('void', b.literal(0));
if (node.callee.type === 'MemberExpression') { if (node.callee.type === 'MemberExpression') {
const raw_inspect_args = /** @type {import('estree').CallExpression} */ (node.callee.object) const raw_inspect_args = /** @type {CallExpression} */ (node.callee.object).arguments;
.arguments;
const inspect_args = const inspect_args =
/** @type {Array<import('estree').Expression>} */ /** @type {Array<Expression>} */
(raw_inspect_args.map((arg) => visit(arg))); (raw_inspect_args.map((arg) => visit(arg)));
const with_arg = /** @type {import('estree').Expression} */ (visit(node.arguments[0])); const with_arg = /** @type {Expression} */ (visit(node.arguments[0]));
return b.call( return b.call(
'$.inspect', '$.inspect',
@ -402,9 +405,7 @@ export function transform_inspect_rune(node, context) {
with_arg with_arg
); );
} else { } else {
const arg = node.arguments.map( const arg = node.arguments.map((arg) => /** @type {Expression} */ (visit(arg)));
(arg) => /** @type {import('estree').Expression} */ (visit(arg))
);
return b.call('$.inspect', as_fn ? b.thunk(b.array(arg)) : b.array(arg)); return b.call('$.inspect', as_fn ? b.thunk(b.array(arg)) : b.array(arg));
} }
} }

@ -1,3 +1,4 @@
/** @import { Css } from '#compiler' */
const regex_css_browser_prefix = /^-((webkit)|(moz)|(o)|(ms))-/; const regex_css_browser_prefix = /^-((webkit)|(moz)|(o)|(ms))-/;
export const regex_css_name_boundary = /^[\s,;}]$/; export const regex_css_name_boundary = /^[\s,;}]$/;
@ -9,5 +10,5 @@ export function remove_css_prefix(name) {
return name.replace(regex_css_browser_prefix, ''); return name.replace(regex_css_browser_prefix, '');
} }
/** @param {import('#compiler').Css.Atrule} node */ /** @param {Css.Atrule} node */
export const is_keyframes_node = (node) => remove_css_prefix(node.name) === 'keyframes'; export const is_keyframes_node = (node) => remove_css_prefix(node.name) === 'keyframes';

@ -1,3 +1,4 @@
/** @import * as Compiler from '#compiler' */
/** /**
* All nodes that can appear elsewhere than the top level, have attributes and can contain children * All nodes that can appear elsewhere than the top level, have attributes and can contain children
*/ */
@ -13,15 +14,15 @@ const element_nodes = [
/** /**
* Returns true for all nodes that can appear elsewhere than the top level, have attributes and can contain children * Returns true for all nodes that can appear elsewhere than the top level, have attributes and can contain children
* @param {import('#compiler').SvelteNode} node * @param {Compiler.SvelteNode} node
* @returns {node is import('#compiler').Component | import('#compiler').RegularElement | import('#compiler').SlotElement | import('#compiler').SvelteComponent | import('#compiler').SvelteElement | import('#compiler').SvelteFragment | import('#compiler').SvelteSelf} * @returns {node is Compiler.Component | Compiler.RegularElement | Compiler.SlotElement | Compiler.SvelteComponent | Compiler.SvelteElement | Compiler.SvelteFragment | Compiler.SvelteSelf}
*/ */
export function is_element_node(node) { export function is_element_node(node) {
return element_nodes.includes(node.type); return element_nodes.includes(node.type);
} }
/** /**
* @param {import('#compiler').RegularElement | import('#compiler').SvelteElement} node * @param {Compiler.RegularElement | Compiler.SvelteElement} node
* @returns {boolean} * @returns {boolean}
*/ */
export function is_custom_element_node(node) { export function is_custom_element_node(node) {
@ -32,8 +33,8 @@ export function is_custom_element_node(node) {
* @param {string} name * @param {string} name
* @param {number} start * @param {number} start
* @param {number} end * @param {number} end
* @param {true | Array<import('#compiler').Text | import('#compiler').ExpressionTag>} value * @param {true | Array<Compiler.Text | Compiler.ExpressionTag>} value
* @returns {import('#compiler').Attribute} * @returns {Compiler.Attribute}
*/ */
export function create_attribute(name, start, end, value) { export function create_attribute(name, start, end, value) {
return { return {

@ -1,3 +1,4 @@
/** @import { Visitors, Context } from 'zimmerframe' */
const overrides = { const overrides = {
visit() { visit() {
throw new Error('Cannot call visit() during analysis'); throw new Error('Cannot call visit() during analysis');
@ -10,7 +11,7 @@ const overrides = {
/** /**
* @template {{ type: string }} T * @template {{ type: string }} T
* @template U * @template U
* @param {...import('zimmerframe').Visitors<T, U>} tasks * @param {...Visitors<T, U>} tasks
* @returns * @returns
*/ */
export function merge(...tasks) { export function merge(...tasks) {
@ -24,7 +25,7 @@ export function merge(...tasks) {
} }
} }
/** @type {import('zimmerframe').Visitors<T, U>} */ /** @type {Visitors<T, U>} */
// @ts-expect-error // @ts-expect-error
const combined = {}; const combined = {};
@ -33,7 +34,7 @@ export function merge(...tasks) {
/** /**
* @param {T} node * @param {T} node
* @param {import('zimmerframe').Context<T, U>} context * @param {Context<T, U>} context
*/ */
function visitor(node, context) { function visitor(node, context) {
/** /**

@ -1,3 +1,4 @@
/** @import { Processed } from './public.js' */
import { decode as decode_mappings } from '@jridgewell/sourcemap-codec'; import { decode as decode_mappings } from '@jridgewell/sourcemap-codec';
/** /**
@ -80,7 +81,7 @@ function decoded_sourcemap_from_generator(generator) {
} }
/** /**
* @param {import('./public.js').Processed} processed * @param {Processed} processed
*/ */
export function decode_map(processed) { export function decode_map(processed) {
let decoded_map = typeof processed.map === 'string' ? JSON.parse(processed.map) : processed.map; let decoded_map = typeof processed.map === 'string' ? JSON.parse(processed.map) : processed.map;

@ -1,3 +1,6 @@
/** @import { Processed, Preprocessor, MarkupPreprocessor, PreprocessorGroup } from './public.js' */
/** @import { SourceUpdate, Source } from './private.js' */
/** @import { DecodedSourceMap, RawSourceMap } from '@ampproject/remapping' */
import { getLocator } from 'locate-character'; import { getLocator } from 'locate-character';
import { import {
MappedCode, MappedCode,
@ -26,7 +29,7 @@ class PreprocessResult {
/** /**
* @default [] * @default []
* @type {Array<import('@ampproject/remapping').DecodedSourceMap | import('@ampproject/remapping').RawSourceMap>} * @type {Array<DecodedSourceMap | RawSourceMap>}
*/ */
sourcemap_list = []; sourcemap_list = [];
@ -59,7 +62,7 @@ class PreprocessResult {
} }
/** /**
* @param {import('./private.js').SourceUpdate} opts * @param {SourceUpdate} opts
*/ */
update_source({ string: source, map, dependencies }) { update_source({ string: source, map, dependencies }) {
if (source != null) { if (source != null) {
@ -75,7 +78,7 @@ class PreprocessResult {
} }
/** /**
* @returns {import('./public.js').Processed} * @returns {Processed}
*/ */
to_processed() { to_processed() {
// Combine all the source maps for each preprocessor function into one // Combine all the source maps for each preprocessor function into one
@ -96,7 +99,7 @@ class PreprocessResult {
} }
/** /**
* Convert preprocessor output for the tag content into MappedCode * Convert preprocessor output for the tag content into MappedCode
* @param {import('./public.js').Processed} processed * @param {Processed} processed
* @param {{ line: number; column: number; }} location * @param {{ line: number; column: number; }} location
* @param {string} file_basename * @param {string} file_basename
* @returns {MappedCode} * @returns {MappedCode}
@ -105,7 +108,7 @@ function processed_content_to_code(processed, location, file_basename) {
// Convert the preprocessed code and its sourcemap to a MappedCode // Convert the preprocessed code and its sourcemap to a MappedCode
/** /**
* @type {import('@ampproject/remapping').DecodedSourceMap | undefined} * @type {DecodedSourceMap | undefined}
*/ */
let decoded_map = undefined; let decoded_map = undefined;
if (processed.map) { if (processed.map) {
@ -124,11 +127,11 @@ function processed_content_to_code(processed, location, file_basename) {
/** /**
* Given the whole tag including content, return a `MappedCode` * Given the whole tag including content, return a `MappedCode`
* representing the tag content replaced with `processed`. * representing the tag content replaced with `processed`.
* @param {import('./public.js').Processed} processed * @param {Processed} processed
* @param {'style' | 'script'} tag_name * @param {'style' | 'script'} tag_name
* @param {string} original_attributes * @param {string} original_attributes
* @param {string} generated_attributes * @param {string} generated_attributes
* @param {import('./private.js').Source} source * @param {Source} source
* @returns {MappedCode} * @returns {MappedCode}
*/ */
function processed_tag_to_code( function processed_tag_to_code(
@ -157,7 +160,7 @@ function processed_tag_to_code(
if (original_tag_open.length !== tag_open.length) { if (original_tag_open.length !== tag_open.length) {
// Generate a source map for the open tag // Generate a source map for the open tag
/** @type {import('@ampproject/remapping').DecodedSourceMap['mappings']} */ /** @type {DecodedSourceMap['mappings']} */
const mappings = [ const mappings = [
[ [
// start of tag // start of tag
@ -183,7 +186,7 @@ function processed_tag_to_code(
original_tag_open.length - original_tag_open.lastIndexOf('\n') - 1 original_tag_open.length - original_tag_open.lastIndexOf('\n') - 1
]); ]);
/** @type {import('@ampproject/remapping').DecodedSourceMap} */ /** @type {DecodedSourceMap} */
const map = { const map = {
version: 3, version: 3,
names: [], names: [],
@ -255,9 +258,9 @@ const regex_script_tags =
/** /**
* Calculate the updates required to process all instances of the specified tag. * Calculate the updates required to process all instances of the specified tag.
* @param {'style' | 'script'} tag_name * @param {'style' | 'script'} tag_name
* @param {import('./public.js').Preprocessor} preprocessor * @param {Preprocessor} preprocessor
* @param {import('./private.js').Source} source * @param {Source} source
* @returns {Promise<import('./private.js').SourceUpdate>} * @returns {Promise<SourceUpdate>}
*/ */
async function process_tag(tag_name, preprocessor, source) { async function process_tag(tag_name, preprocessor, source) {
const { filename, source: markup } = source; const { filename, source: markup } = source;
@ -299,8 +302,8 @@ async function process_tag(tag_name, preprocessor, source) {
} }
/** /**
* @param {import('./public.js').MarkupPreprocessor} process * @param {MarkupPreprocessor} process
* @param {import('./private.js').Source} source * @param {Source} source
*/ */
async function process_markup(process, source) { async function process_markup(process, source) {
const processed = await process({ const processed = await process({
@ -329,9 +332,9 @@ async function process_markup(process, source) {
* *
* https://svelte.dev/docs/svelte-compiler#svelte-preprocess * https://svelte.dev/docs/svelte-compiler#svelte-preprocess
* @param {string} source * @param {string} source
* @param {import('./public.js').PreprocessorGroup | import('./public.js').PreprocessorGroup[]} preprocessor * @param {PreprocessorGroup | PreprocessorGroup[]} preprocessor
* @param {{ filename?: string }} [options] * @param {{ filename?: string }} [options]
* @returns {Promise<import('./public.js').Processed>} * @returns {Promise<Processed>}
*/ */
export default async function preprocess(source, preprocessor, options) { export default async function preprocess(source, preprocessor, options) {
/** /**

@ -1,10 +1,11 @@
/** @import { Source, Replacement } from './private.js' */
import { MappedCode } from '../utils/mapped_code.js'; import { MappedCode } from '../utils/mapped_code.js';
/** /**
* @param {string} code_slice * @param {string} code_slice
* @param {number} offset * @param {number} offset
* @param {import('./private.js').Source} opts * @param {Source} opts
* @returns {import('./private.js').Source} * @returns {Source}
*/ */
export function slice_source(code_slice, offset, { file_basename, filename, get_location }) { export function slice_source(code_slice, offset, { file_basename, filename, get_location }) {
return { return {
@ -22,7 +23,7 @@ export function slice_source(code_slice, offset, { file_basename, filename, get_
*/ */
function calculate_replacements(re, get_replacement, source) { function calculate_replacements(re, get_replacement, source) {
/** /**
* @type {Array<Promise<import('./private.js').Replacement>>} * @type {Array<Promise<Replacement>>}
*/ */
const replacements = []; const replacements = [];
source.replace(re, (...match) => { source.replace(re, (...match) => {
@ -39,8 +40,8 @@ function calculate_replacements(re, get_replacement, source) {
} }
/** /**
* @param {import('./private.js').Replacement[]} replacements * @param {Replacement[]} replacements
* @param {import('./private.js').Source} source * @param {Source} source
* @returns {MappedCode} * @returns {MappedCode}
*/ */
function perform_replacements(replacements, source) { function perform_replacements(replacements, source) {
@ -62,7 +63,7 @@ function perform_replacements(replacements, source) {
/** /**
* @param {RegExp} regex * @param {RegExp} regex
* @param {(...match: any[]) => Promise<MappedCode>} get_replacement * @param {(...match: any[]) => Promise<MappedCode>} get_replacement
* @param {import('./private.js').Source} location * @param {Source} location
* @returns {Promise<MappedCode>} * @returns {Promise<MappedCode>}
*/ */
export async function replace_in_code(regex, get_replacement, location) { export async function replace_in_code(regex, get_replacement, location) {

@ -1,8 +1,10 @@
/** @import { SvelteNode } from './types' */
/** @import { Warning } from '#compiler' */
import { getLocator } from 'locate-character'; import { getLocator } from 'locate-character';
/** @typedef {{ start?: number, end?: number }} NodeLike */ /** @typedef {{ start?: number, end?: number }} NodeLike */
/** @type {import('#compiler').Warning[]} */ /** @type {Warning[]} */
export let warnings = []; export let warnings = [];
/** /**
@ -24,7 +26,7 @@ export let ignore_stack = [];
* For each node the list of warnings that should be ignored for that node. * For each node the list of warnings that should be ignored for that node.
* Exists in addition to `ignore_stack` because not all warnings are emitted * Exists in addition to `ignore_stack` because not all warnings are emitted
* while the stack is being built. * while the stack is being built.
* @type {Map<import("./types").SvelteNode | NodeLike, Set<string>[]>} * @type {Map<SvelteNode | NodeLike, Set<string>[]>}
*/ */
export let ignore_map = new Map(); export let ignore_map = new Map();

@ -1,16 +1,16 @@
/** @import { Attribute, Text, ExpressionTag, SvelteNode } from '#compiler' */
/** @import * as ESTree from 'estree' */
import { walk } from 'zimmerframe'; import { walk } from 'zimmerframe';
import * as b from '../utils/builders.js'; import * as b from '../utils/builders.js';
/** /**
* Gets the left-most identifier of a member expression or identifier. * Gets the left-most identifier of a member expression or identifier.
* @param {import('estree').MemberExpression | import('estree').Identifier} expression * @param {ESTree.MemberExpression | ESTree.Identifier} expression
* @returns {import('estree').Identifier | null} * @returns {ESTree.Identifier | null}
*/ */
export function object(expression) { export function object(expression) {
while (expression.type === 'MemberExpression') { while (expression.type === 'MemberExpression') {
expression = /** @type {import('estree').MemberExpression | import('estree').Identifier} */ ( expression = /** @type {ESTree.MemberExpression | ESTree.Identifier} */ (expression.object);
expression.object
);
} }
if (expression.type !== 'Identifier') { if (expression.type !== 'Identifier') {
@ -22,8 +22,8 @@ export function object(expression) {
/** /**
* Returns true if the attribute contains a single static text node. * Returns true if the attribute contains a single static text node.
* @param {import('#compiler').Attribute} attribute * @param {Attribute} attribute
* @returns {attribute is import('#compiler').Attribute & { value: [import('#compiler').Text] }} * @returns {attribute is Attribute & { value: [Text] }}
*/ */
export function is_text_attribute(attribute) { export function is_text_attribute(attribute) {
return ( return (
@ -33,8 +33,8 @@ export function is_text_attribute(attribute) {
/** /**
* Returns true if the attribute contains a single expression node. * Returns true if the attribute contains a single expression node.
* @param {import('#compiler').Attribute} attribute * @param {Attribute} attribute
* @returns {attribute is import('#compiler').Attribute & { value: [import('#compiler').ExpressionTag] }} * @returns {attribute is Attribute & { value: [ExpressionTag] }}
*/ */
export function is_expression_attribute(attribute) { export function is_expression_attribute(attribute) {
return ( return (
@ -46,8 +46,8 @@ export function is_expression_attribute(attribute) {
/** /**
* Returns true if the attribute starts with `on` and contains a single expression node. * Returns true if the attribute starts with `on` and contains a single expression node.
* @param {import('#compiler').Attribute} attribute * @param {Attribute} attribute
* @returns {attribute is import('#compiler').Attribute & { value: [import('#compiler').ExpressionTag] }} * @returns {attribute is Attribute & { value: [ExpressionTag] }}
*/ */
export function is_event_attribute(attribute) { export function is_event_attribute(attribute) {
return is_expression_attribute(attribute) && attribute.name.startsWith('on'); return is_expression_attribute(attribute) && attribute.name.startsWith('on');
@ -55,9 +55,9 @@ export function is_event_attribute(attribute) {
/** /**
* Extracts all identifiers from a pattern. * Extracts all identifiers from a pattern.
* @param {import('estree').Pattern} param * @param {ESTree.Pattern} param
* @param {import('estree').Identifier[]} [nodes] * @param {ESTree.Identifier[]} [nodes]
* @returns {import('estree').Identifier[]} * @returns {ESTree.Identifier[]}
*/ */
export function extract_identifiers(param, nodes = []) { export function extract_identifiers(param, nodes = []) {
switch (param.type) { switch (param.type) {
@ -97,11 +97,11 @@ export function extract_identifiers(param, nodes = []) {
/** /**
* Extracts all identifiers and a stringified keypath from an expression. * Extracts all identifiers and a stringified keypath from an expression.
* @param {import('estree').Expression} expr * @param {ESTree.Expression} expr
* @returns {[keypath: string, ids: import('estree').Identifier[]]} * @returns {[keypath: string, ids: ESTree.Identifier[]]}
*/ */
export function extract_all_identifiers_from_expression(expr) { export function extract_all_identifiers_from_expression(expr) {
/** @type {import('estree').Identifier[]} */ /** @type {ESTree.Identifier[]} */
let nodes = []; let nodes = [];
/** @type {string[]} */ /** @type {string[]} */
let keypath = []; let keypath = [];
@ -143,8 +143,8 @@ export function extract_all_identifiers_from_expression(expr) {
/** /**
* Extracts all leaf identifiers from a destructuring expression. * Extracts all leaf identifiers from a destructuring expression.
* @param {import('estree').Identifier | import('estree').ObjectExpression | import('estree').ArrayExpression} node * @param {ESTree.Identifier | ESTree.ObjectExpression | ESTree.ArrayExpression} node
* @param {import('estree').Identifier[]} [nodes] * @param {ESTree.Identifier[]} [nodes]
* @returns * @returns
*/ */
export function extract_identifiers_from_destructuring(node, nodes = []) { export function extract_identifiers_from_destructuring(node, nodes = []) {
@ -181,33 +181,33 @@ export function extract_identifiers_from_destructuring(node, nodes = []) {
* or assignment expression. For example, given `const { foo: { bar: baz } } = quux`, * or assignment expression. For example, given `const { foo: { bar: baz } } = quux`,
* the path of `baz` is `foo.bar` * the path of `baz` is `foo.bar`
* @typedef {Object} DestructuredAssignment * @typedef {Object} DestructuredAssignment
* @property {import('estree').Identifier | import('estree').MemberExpression} node The node the destructuring path end in. Can be a member expression only for assignment expressions * @property {ESTree.Identifier | ESTree.MemberExpression} node The node the destructuring path end in. Can be a member expression only for assignment expressions
* @property {boolean} is_rest `true` if this is a `...rest` destructuring * @property {boolean} is_rest `true` if this is a `...rest` destructuring
* @property {boolean} has_default_value `true` if this has a fallback value like `const { foo = 'bar } = ..` * @property {boolean} has_default_value `true` if this has a fallback value like `const { foo = 'bar } = ..`
* @property {(expression: import('estree').Expression) => import('estree').Identifier | import('estree').MemberExpression | import('estree').CallExpression | import('estree').AwaitExpression} expression Returns an expression which walks the path starting at the given expression. * @property {(expression: ESTree.Expression) => ESTree.Identifier | ESTree.MemberExpression | ESTree.CallExpression | ESTree.AwaitExpression} expression Returns an expression which walks the path starting at the given expression.
* This will be a call expression if a rest element or default is involved e.g. `const { foo: { bar: baz = 42 }, ...rest } = quux` since we can't represent `baz` or `rest` purely as a path * This will be a call expression if a rest element or default is involved e.g. `const { foo: { bar: baz = 42 }, ...rest } = quux` since we can't represent `baz` or `rest` purely as a path
* Will be an await expression in case of an async default value (`const { foo = await bar } = ...`) * Will be an await expression in case of an async default value (`const { foo = await bar } = ...`)
* @property {(expression: import('estree').Expression) => import('estree').Identifier | import('estree').MemberExpression | import('estree').CallExpression | import('estree').AwaitExpression} update_expression Like `expression` but without default values. * @property {(expression: ESTree.Expression) => ESTree.Identifier | ESTree.MemberExpression | ESTree.CallExpression | ESTree.AwaitExpression} update_expression Like `expression` but without default values.
*/ */
/** /**
* Extracts all destructured assignments from a pattern. * Extracts all destructured assignments from a pattern.
* @param {import('estree').Node} param * @param {ESTree.Node} param
* @returns {DestructuredAssignment[]} * @returns {DestructuredAssignment[]}
*/ */
export function extract_paths(param) { export function extract_paths(param) {
return _extract_paths( return _extract_paths(
[], [],
param, param,
(node) => /** @type {import('estree').Identifier | import('estree').MemberExpression} */ (node), (node) => /** @type {ESTree.Identifier | ESTree.MemberExpression} */ (node),
(node) => /** @type {import('estree').Identifier | import('estree').MemberExpression} */ (node), (node) => /** @type {ESTree.Identifier | ESTree.MemberExpression} */ (node),
false false
); );
} }
/** /**
* @param {DestructuredAssignment[]} assignments * @param {DestructuredAssignment[]} assignments
* @param {import('estree').Node} param * @param {ESTree.Node} param
* @param {DestructuredAssignment['expression']} expression * @param {DestructuredAssignment['expression']} expression
* @param {DestructuredAssignment['update_expression']} update_expression * @param {DestructuredAssignment['update_expression']} update_expression
* @param {boolean} has_default_value * @param {boolean} has_default_value
@ -231,7 +231,7 @@ function _extract_paths(assignments = [], param, expression, update_expression,
if (prop.type === 'RestElement') { if (prop.type === 'RestElement') {
/** @type {DestructuredAssignment['expression']} */ /** @type {DestructuredAssignment['expression']} */
const rest_expression = (object) => { const rest_expression = (object) => {
/** @type {import('estree').Expression[]} */ /** @type {ESTree.Expression[]} */
const props = []; const props = [];
for (const p of param.properties) { for (const p of param.properties) {
if (p.type === 'Property' && p.key.type !== 'PrivateIdentifier') { if (p.type === 'Property' && p.key.type !== 'PrivateIdentifier') {
@ -351,7 +351,7 @@ function _extract_paths(assignments = [], param, expression, update_expression,
* Like `path.at(x)`, but skips over `TSNonNullExpression` and `TSAsExpression` nodes and eases assertions a bit * Like `path.at(x)`, but skips over `TSNonNullExpression` and `TSAsExpression` nodes and eases assertions a bit
* by removing the `| undefined` from the resulting type. * by removing the `| undefined` from the resulting type.
* *
* @template {import('#compiler').SvelteNode} T * @template {SvelteNode} T
* @param {T[]} path * @param {T[]} path
* @param {number} at * @param {number} at
*/ */
@ -369,7 +369,7 @@ export function get_parent(path, at) {
* or a logical expression that only contains simple expressions. Used to determine whether * or a logical expression that only contains simple expressions. Used to determine whether
* something needs to be treated as though accessing it could have side-effects (i.e. * something needs to be treated as though accessing it could have side-effects (i.e.
* reading signals prematurely) * reading signals prematurely)
* @param {import('estree').Expression} node * @param {ESTree.Expression} node
* @returns {boolean} * @returns {boolean}
*/ */
export function is_simple_expression(node) { export function is_simple_expression(node) {
@ -398,8 +398,8 @@ export function is_simple_expression(node) {
} }
/** /**
* @template {import('estree').SimpleCallExpression | import('estree').MemberExpression} T * @template {ESTree.SimpleCallExpression | ESTree.MemberExpression} T
* @param {import('estree').ChainExpression & { expression : T } | T} node * @param {ESTree.ChainExpression & { expression : T } | T} node
* @returns {T} * @returns {T}
*/ */
export function unwrap_optional(node) { export function unwrap_optional(node) {
@ -407,7 +407,7 @@ export function unwrap_optional(node) {
} }
/** /**
* @param {import('estree').Expression | import('estree').Pattern} expression * @param {ESTree.Expression | ESTree.Pattern} expression
* @returns {boolean} * @returns {boolean}
*/ */
export function is_expression_async(expression) { export function is_expression_async(expression) {

@ -1,35 +1,36 @@
/** @import * as ESTree from 'estree' */
import { regex_is_valid_identifier } from '../phases/patterns.js'; import { regex_is_valid_identifier } from '../phases/patterns.js';
import { sanitize_template_string } from './sanitize_template_string.js'; import { sanitize_template_string } from './sanitize_template_string.js';
/** /**
* @param {Array<import('estree').Expression | import('estree').SpreadElement | null>} elements * @param {Array<ESTree.Expression | ESTree.SpreadElement | null>} elements
* @returns {import('estree').ArrayExpression} * @returns {ESTree.ArrayExpression}
*/ */
export function array(elements = []) { export function array(elements = []) {
return { type: 'ArrayExpression', elements }; return { type: 'ArrayExpression', elements };
} }
/** /**
* @param {Array<import('estree').Pattern | null>} elements * @param {Array<ESTree.Pattern | null>} elements
* @returns {import('estree').ArrayPattern} * @returns {ESTree.ArrayPattern}
*/ */
export function array_pattern(elements) { export function array_pattern(elements) {
return { type: 'ArrayPattern', elements }; return { type: 'ArrayPattern', elements };
} }
/** /**
* @param {import('estree').Pattern} left * @param {ESTree.Pattern} left
* @param {import('estree').Expression} right * @param {ESTree.Expression} right
* @returns {import('estree').AssignmentPattern} * @returns {ESTree.AssignmentPattern}
*/ */
export function assignment_pattern(left, right) { export function assignment_pattern(left, right) {
return { type: 'AssignmentPattern', left, right }; return { type: 'AssignmentPattern', left, right };
} }
/** /**
* @param {Array<import('estree').Pattern>} params * @param {Array<ESTree.Pattern>} params
* @param {import('estree').BlockStatement | import('estree').Expression} body * @param {ESTree.BlockStatement | ESTree.Expression} body
* @returns {import('estree').ArrowFunctionExpression} * @returns {ESTree.ArrowFunctionExpression}
*/ */
export function arrow(params, body) { export function arrow(params, body) {
return { return {
@ -44,10 +45,10 @@ export function arrow(params, body) {
} }
/** /**
* @param {import('estree').AssignmentOperator} operator * @param {ESTree.AssignmentOperator} operator
* @param {import('estree').Pattern} left * @param {ESTree.Pattern} left
* @param {import('estree').Expression} right * @param {ESTree.Expression} right
* @returns {import('estree').AssignmentExpression} * @returns {ESTree.AssignmentExpression}
*/ */
export function assignment(operator, left, right) { export function assignment(operator, left, right) {
return { type: 'AssignmentExpression', operator, left, right }; return { type: 'AssignmentExpression', operator, left, right };
@ -55,34 +56,34 @@ export function assignment(operator, left, right) {
/** /**
* @template T * @template T
* @param {T & import('estree').BaseFunction} func * @param {T & ESTree.BaseFunction} func
* @returns {T & import('estree').BaseFunction} * @returns {T & ESTree.BaseFunction}
*/ */
export function async(func) { export function async(func) {
return { ...func, async: true }; return { ...func, async: true };
} }
/** /**
* @param {import('estree').Expression} argument * @param {ESTree.Expression} argument
* @returns {import('estree').AwaitExpression} * @returns {ESTree.AwaitExpression}
*/ */
function await_builder(argument) { function await_builder(argument) {
return { type: 'AwaitExpression', argument }; return { type: 'AwaitExpression', argument };
} }
/** /**
* @param {import('estree').BinaryOperator} operator * @param {ESTree.BinaryOperator} operator
* @param {import('estree').Expression} left * @param {ESTree.Expression} left
* @param {import('estree').Expression} right * @param {ESTree.Expression} right
* @returns {import('estree').BinaryExpression} * @returns {ESTree.BinaryExpression}
*/ */
export function binary(operator, left, right) { export function binary(operator, left, right) {
return { type: 'BinaryExpression', operator, left, right }; return { type: 'BinaryExpression', operator, left, right };
} }
/** /**
* @param {import('estree').Statement[]} body * @param {ESTree.Statement[]} body
* @returns {import('estree').BlockStatement} * @returns {ESTree.BlockStatement}
*/ */
export function block(body) { export function block(body) {
return { type: 'BlockStatement', body }; return { type: 'BlockStatement', body };
@ -90,17 +91,17 @@ export function block(body) {
/** /**
* @param {string} name * @param {string} name
* @param {import('estree').Statement} body * @param {ESTree.Statement} body
* @returns {import('estree').LabeledStatement} * @returns {ESTree.LabeledStatement}
*/ */
export function labeled(name, body) { export function labeled(name, body) {
return { type: 'LabeledStatement', label: id(name), body }; return { type: 'LabeledStatement', label: id(name), body };
} }
/** /**
* @param {string | import('estree').Expression} callee * @param {string | ESTree.Expression} callee
* @param {...(import('estree').Expression | import('estree').SpreadElement | false | undefined)} args * @param {...(ESTree.Expression | ESTree.SpreadElement | false | undefined)} args
* @returns {import('estree').CallExpression} * @returns {ESTree.CallExpression}
*/ */
export function call(callee, ...args) { export function call(callee, ...args) {
if (typeof callee === 'string') callee = id(callee); if (typeof callee === 'string') callee = id(callee);
@ -124,20 +125,18 @@ export function call(callee, ...args) {
return { return {
type: 'CallExpression', type: 'CallExpression',
callee, callee,
arguments: /** @type {Array<import('estree').Expression | import('estree').SpreadElement>} */ ( arguments: /** @type {Array<ESTree.Expression | ESTree.SpreadElement>} */ (args),
args
),
optional: false optional: false
}; };
} }
/** /**
* @param {string | import('estree').Expression} callee * @param {string | ESTree.Expression} callee
* @param {...import('estree').Expression} args * @param {...ESTree.Expression} args
* @returns {import('estree').ChainExpression} * @returns {ESTree.ChainExpression}
*/ */
export function maybe_call(callee, ...args) { export function maybe_call(callee, ...args) {
const expression = /** @type {import('estree').SimpleCallExpression} */ (call(callee, ...args)); const expression = /** @type {ESTree.SimpleCallExpression} */ (call(callee, ...args));
expression.optional = true; expression.optional = true;
return { return {
@ -147,29 +146,29 @@ export function maybe_call(callee, ...args) {
} }
/** /**
* @param {import('estree').UnaryOperator} operator * @param {ESTree.UnaryOperator} operator
* @param {import('estree').Expression} argument * @param {ESTree.Expression} argument
* @returns {import('estree').UnaryExpression} * @returns {ESTree.UnaryExpression}
*/ */
export function unary(operator, argument) { export function unary(operator, argument) {
return { type: 'UnaryExpression', argument, operator, prefix: true }; return { type: 'UnaryExpression', argument, operator, prefix: true };
} }
/** /**
* @param {import('estree').Expression} test * @param {ESTree.Expression} test
* @param {import('estree').Expression} consequent * @param {ESTree.Expression} consequent
* @param {import('estree').Expression} alternate * @param {ESTree.Expression} alternate
* @returns {import('estree').ConditionalExpression} * @returns {ESTree.ConditionalExpression}
*/ */
export function conditional(test, consequent, alternate) { export function conditional(test, consequent, alternate) {
return { type: 'ConditionalExpression', test, consequent, alternate }; return { type: 'ConditionalExpression', test, consequent, alternate };
} }
/** /**
* @param {import('estree').LogicalOperator} operator * @param {ESTree.LogicalOperator} operator
* @param {import('estree').Expression} left * @param {ESTree.Expression} left
* @param {import('estree').Expression} right * @param {ESTree.Expression} right
* @returns {import('estree').LogicalExpression} * @returns {ESTree.LogicalExpression}
*/ */
export function logical(operator, left, right) { export function logical(operator, left, right) {
return { type: 'LogicalExpression', operator, left, right }; return { type: 'LogicalExpression', operator, left, right };
@ -177,9 +176,9 @@ export function logical(operator, left, right) {
/** /**
* @param {'const' | 'let' | 'var'} kind * @param {'const' | 'let' | 'var'} kind
* @param {string | import('estree').Pattern} pattern * @param {string | ESTree.Pattern} pattern
* @param {import('estree').Expression} [init] * @param {ESTree.Expression} [init]
* @returns {import('estree').VariableDeclaration} * @returns {ESTree.VariableDeclaration}
*/ */
export function declaration(kind, pattern, init) { export function declaration(kind, pattern, init) {
if (typeof pattern === 'string') pattern = id(pattern); if (typeof pattern === 'string') pattern = id(pattern);
@ -192,32 +191,32 @@ export function declaration(kind, pattern, init) {
} }
/** /**
* @param {import('estree').Pattern} id * @param {ESTree.Pattern} id
* @param {import('estree').Expression} [init] * @param {ESTree.Expression} [init]
* @returns {import('estree').VariableDeclarator} * @returns {ESTree.VariableDeclarator}
*/ */
export function declarator(id, init) { export function declarator(id, init) {
return { type: 'VariableDeclarator', id, init }; return { type: 'VariableDeclarator', id, init };
} }
/** @type {import('estree').EmptyStatement} */ /** @type {ESTree.EmptyStatement} */
export const empty = { export const empty = {
type: 'EmptyStatement' type: 'EmptyStatement'
}; };
/** /**
* @param {import('estree').Expression | import('estree').MaybeNamedClassDeclaration | import('estree').MaybeNamedFunctionDeclaration} declaration * @param {ESTree.Expression | ESTree.MaybeNamedClassDeclaration | ESTree.MaybeNamedFunctionDeclaration} declaration
* @returns {import('estree').ExportDefaultDeclaration} * @returns {ESTree.ExportDefaultDeclaration}
*/ */
export function export_default(declaration) { export function export_default(declaration) {
return { type: 'ExportDefaultDeclaration', declaration }; return { type: 'ExportDefaultDeclaration', declaration };
} }
/** /**
* @param {import('estree').Identifier} id * @param {ESTree.Identifier} id
* @param {import('estree').Pattern[]} params * @param {ESTree.Pattern[]} params
* @param {import('estree').BlockStatement} body * @param {ESTree.BlockStatement} body
* @returns {import('estree').FunctionDeclaration} * @returns {ESTree.FunctionDeclaration}
*/ */
export function function_declaration(id, params, body) { export function function_declaration(id, params, body) {
return { return {
@ -233,8 +232,8 @@ export function function_declaration(id, params, body) {
/** /**
* @param {string} name * @param {string} name
* @param {import('estree').Statement[]} body * @param {ESTree.Statement[]} body
* @returns {import('estree').Property & { value: import('estree').FunctionExpression}}} * @returns {ESTree.Property & { value: ESTree.FunctionExpression}}}
*/ */
export function get(name, body) { export function get(name, body) {
return prop('get', key(name), function_builder(null, [], block(body))); return prop('get', key(name), function_builder(null, [], block(body)));
@ -242,7 +241,7 @@ export function get(name, body) {
/** /**
* @param {string} name * @param {string} name
* @returns {import('estree').Identifier} * @returns {ESTree.Identifier}
*/ */
export function id(name) { export function id(name) {
return { type: 'Identifier', name }; return { type: 'Identifier', name };
@ -250,7 +249,7 @@ export function id(name) {
/** /**
* @param {string} name * @param {string} name
* @returns {import('estree').PrivateIdentifier} * @returns {ESTree.PrivateIdentifier}
*/ */
export function private_id(name) { export function private_id(name) {
return { type: 'PrivateIdentifier', name }; return { type: 'PrivateIdentifier', name };
@ -258,7 +257,7 @@ export function private_id(name) {
/** /**
* @param {string} local * @param {string} local
* @returns {import('estree').ImportNamespaceSpecifier} * @returns {ESTree.ImportNamespaceSpecifier}
*/ */
function import_namespace(local) { function import_namespace(local) {
return { return {
@ -269,8 +268,8 @@ function import_namespace(local) {
/** /**
* @param {string} name * @param {string} name
* @param {import('estree').Expression} value * @param {ESTree.Expression} value
* @returns {import('estree').Property} * @returns {ESTree.Property}
*/ */
export function init(name, value) { export function init(name, value) {
return prop('init', key(name), value); return prop('init', key(name), value);
@ -278,7 +277,7 @@ export function init(name, value) {
/** /**
* @param {string | boolean | null | number | RegExp} value * @param {string | boolean | null | number | RegExp} value
* @returns {import('estree').Literal} * @returns {ESTree.Literal}
*/ */
export function literal(value) { export function literal(value) {
// @ts-expect-error we don't want to muck around with bigint here // @ts-expect-error we don't want to muck around with bigint here
@ -286,11 +285,11 @@ export function literal(value) {
} }
/** /**
* @param {import('estree').Expression | import('estree').Super} object * @param {ESTree.Expression | ESTree.Super} object
* @param {import('estree').Expression | import('estree').PrivateIdentifier} property * @param {ESTree.Expression | ESTree.PrivateIdentifier} property
* @param {boolean} computed * @param {boolean} computed
* @param {boolean} optional * @param {boolean} optional
* @returns {import('estree').MemberExpression} * @returns {ESTree.MemberExpression}
*/ */
export function member(object, property, computed = false, optional = false) { export function member(object, property, computed = false, optional = false) {
return { type: 'MemberExpression', object, property, computed, optional }; return { type: 'MemberExpression', object, property, computed, optional };
@ -298,12 +297,12 @@ export function member(object, property, computed = false, optional = false) {
/** /**
* @param {string} path * @param {string} path
* @returns {import('estree').Identifier | import('estree').MemberExpression} * @returns {ESTree.Identifier | ESTree.MemberExpression}
*/ */
export function member_id(path) { export function member_id(path) {
const parts = path.split('.'); const parts = path.split('.');
/** @type {import('estree').Identifier | import('estree').MemberExpression} */ /** @type {ESTree.Identifier | ESTree.MemberExpression} */
let expression = id(parts[0]); let expression = id(parts[0]);
for (let i = 1; i < parts.length; i += 1) { for (let i = 1; i < parts.length; i += 1) {
@ -313,39 +312,39 @@ export function member_id(path) {
} }
/** /**
* @param {Array<import('estree').Property | import('estree').SpreadElement>} properties * @param {Array<ESTree.Property | ESTree.SpreadElement>} properties
* @returns {import('estree').ObjectExpression} * @returns {ESTree.ObjectExpression}
*/ */
export function object(properties) { export function object(properties) {
return { type: 'ObjectExpression', properties }; return { type: 'ObjectExpression', properties };
} }
/** /**
* @param {Array<import('estree').RestElement | import('estree').AssignmentProperty>} properties * @param {Array<ESTree.RestElement | ESTree.AssignmentProperty>} properties
* @returns {import('estree').ObjectPattern} * @returns {ESTree.ObjectPattern}
*/ */
export function object_pattern(properties) { export function object_pattern(properties) {
return { type: 'ObjectPattern', properties }; return { type: 'ObjectPattern', properties };
} }
/** /**
* @template {import('estree').Expression} Value * @template {ESTree.Expression} Value
* @param {'init' | 'get' | 'set'} kind * @param {'init' | 'get' | 'set'} kind
* @param {import('estree').Expression} key * @param {ESTree.Expression} key
* @param {Value} value * @param {Value} value
* @param {boolean} computed * @param {boolean} computed
* @returns {import('estree').Property & { value: Value }} * @returns {ESTree.Property & { value: Value }}
*/ */
export function prop(kind, key, value, computed = false) { export function prop(kind, key, value, computed = false) {
return { type: 'Property', kind, key, value, method: false, shorthand: false, computed }; return { type: 'Property', kind, key, value, method: false, shorthand: false, computed };
} }
/** /**
* @param {import('estree').Expression | import('estree').PrivateIdentifier} key * @param {ESTree.Expression | ESTree.PrivateIdentifier} key
* @param {import('estree').Expression | null | undefined} value * @param {ESTree.Expression | null | undefined} value
* @param {boolean} computed * @param {boolean} computed
* @param {boolean} is_static * @param {boolean} is_static
* @returns {import('estree').PropertyDefinition} * @returns {ESTree.PropertyDefinition}
*/ */
export function prop_def(key, value, computed = false, is_static = false) { export function prop_def(key, value, computed = false, is_static = false) {
return { type: 'PropertyDefinition', key, value, computed, static: is_static }; return { type: 'PropertyDefinition', key, value, computed, static: is_static };
@ -354,7 +353,7 @@ export function prop_def(key, value, computed = false, is_static = false) {
/** /**
* @param {string} cooked * @param {string} cooked
* @param {boolean} tail * @param {boolean} tail
* @returns {import('estree').TemplateElement} * @returns {ESTree.TemplateElement}
*/ */
export function quasi(cooked, tail = false) { export function quasi(cooked, tail = false) {
const raw = sanitize_template_string(cooked); const raw = sanitize_template_string(cooked);
@ -362,16 +361,16 @@ export function quasi(cooked, tail = false) {
} }
/** /**
* @param {import('estree').Pattern} argument * @param {ESTree.Pattern} argument
* @returns {import('estree').RestElement} * @returns {ESTree.RestElement}
*/ */
export function rest(argument) { export function rest(argument) {
return { type: 'RestElement', argument }; return { type: 'RestElement', argument };
} }
/** /**
* @param {import('estree').Expression[]} expressions * @param {ESTree.Expression[]} expressions
* @returns {import('estree').SequenceExpression} * @returns {ESTree.SequenceExpression}
*/ */
export function sequence(expressions) { export function sequence(expressions) {
return { type: 'SequenceExpression', expressions }; return { type: 'SequenceExpression', expressions };
@ -379,42 +378,42 @@ export function sequence(expressions) {
/** /**
* @param {string} name * @param {string} name
* @param {import('estree').Statement[]} body * @param {ESTree.Statement[]} body
* @returns {import('estree').Property & { value: import('estree').FunctionExpression}} * @returns {ESTree.Property & { value: ESTree.FunctionExpression}}
*/ */
export function set(name, body) { export function set(name, body) {
return prop('set', key(name), function_builder(null, [id('$$value')], block(body))); return prop('set', key(name), function_builder(null, [id('$$value')], block(body)));
} }
/** /**
* @param {import('estree').Expression} argument * @param {ESTree.Expression} argument
* @returns {import('estree').SpreadElement} * @returns {ESTree.SpreadElement}
*/ */
export function spread(argument) { export function spread(argument) {
return { type: 'SpreadElement', argument }; return { type: 'SpreadElement', argument };
} }
/** /**
* @param {import('estree').Expression} expression * @param {ESTree.Expression} expression
* @returns {import('estree').ExpressionStatement} * @returns {ESTree.ExpressionStatement}
*/ */
export function stmt(expression) { export function stmt(expression) {
return { type: 'ExpressionStatement', expression }; return { type: 'ExpressionStatement', expression };
} }
/** /**
* @param {import('estree').TemplateElement[]} elements * @param {ESTree.TemplateElement[]} elements
* @param {import('estree').Expression[]} expressions * @param {ESTree.Expression[]} expressions
* @returns {import('estree').TemplateLiteral} * @returns {ESTree.TemplateLiteral}
*/ */
export function template(elements, expressions) { export function template(elements, expressions) {
return { type: 'TemplateLiteral', quasis: elements, expressions }; return { type: 'TemplateLiteral', quasis: elements, expressions };
} }
/** /**
* @param {import('estree').Expression | import('estree').BlockStatement} expression * @param {ESTree.Expression | ESTree.BlockStatement} expression
* @param {boolean} [async] * @param {boolean} [async]
* @returns {import('estree').Expression} * @returns {ESTree.Expression}
*/ */
export function thunk(expression, async = false) { export function thunk(expression, async = false) {
if ( if (
@ -434,9 +433,9 @@ export function thunk(expression, async = false) {
/** /**
* *
* @param {string | import('estree').Expression} expression * @param {string | ESTree.Expression} expression
* @param {...import('estree').Expression} args * @param {...ESTree.Expression} args
* @returns {import('estree').NewExpression} * @returns {ESTree.NewExpression}
*/ */
function new_builder(expression, ...args) { function new_builder(expression, ...args) {
if (typeof expression === 'string') expression = id(expression); if (typeof expression === 'string') expression = id(expression);
@ -449,19 +448,19 @@ function new_builder(expression, ...args) {
} }
/** /**
* @param {import('estree').UpdateOperator} operator * @param {ESTree.UpdateOperator} operator
* @param {import('estree').Expression} argument * @param {ESTree.Expression} argument
* @param {boolean} prefix * @param {boolean} prefix
* @returns {import('estree').UpdateExpression} * @returns {ESTree.UpdateExpression}
*/ */
export function update(operator, argument, prefix = false) { export function update(operator, argument, prefix = false) {
return { type: 'UpdateExpression', operator, argument, prefix }; return { type: 'UpdateExpression', operator, argument, prefix };
} }
/** /**
* @param {import('estree').Expression} test * @param {ESTree.Expression} test
* @param {import('estree').Statement} body * @param {ESTree.Statement} body
* @returns {import('estree').DoWhileStatement} * @returns {ESTree.DoWhileStatement}
*/ */
export function do_while(test, body) { export function do_while(test, body) {
return { type: 'DoWhileStatement', test, body }; return { type: 'DoWhileStatement', test, body };
@ -471,38 +470,38 @@ const true_instance = literal(true);
const false_instance = literal(false); const false_instance = literal(false);
const null_instane = literal(null); const null_instane = literal(null);
/** @type {import('estree').DebuggerStatement} */ /** @type {ESTree.DebuggerStatement} */
const debugger_builder = { const debugger_builder = {
type: 'DebuggerStatement' type: 'DebuggerStatement'
}; };
/** @type {import('estree').ThisExpression} */ /** @type {ESTree.ThisExpression} */
const this_instance = { const this_instance = {
type: 'ThisExpression' type: 'ThisExpression'
}; };
/** /**
* @param {string | import('estree').Pattern} pattern * @param {string | ESTree.Pattern} pattern
* @param { import('estree').Expression} [init] * @param { ESTree.Expression} [init]
* @returns {import('estree').VariableDeclaration} * @returns {ESTree.VariableDeclaration}
*/ */
function let_builder(pattern, init) { function let_builder(pattern, init) {
return declaration('let', pattern, init); return declaration('let', pattern, init);
} }
/** /**
* @param {string | import('estree').Pattern} pattern * @param {string | ESTree.Pattern} pattern
* @param { import('estree').Expression} init * @param { ESTree.Expression} init
* @returns {import('estree').VariableDeclaration} * @returns {ESTree.VariableDeclaration}
*/ */
function const_builder(pattern, init) { function const_builder(pattern, init) {
return declaration('const', pattern, init); return declaration('const', pattern, init);
} }
/** /**
* @param {string | import('estree').Pattern} pattern * @param {string | ESTree.Pattern} pattern
* @param { import('estree').Expression} [init] * @param { ESTree.Expression} [init]
* @returns {import('estree').VariableDeclaration} * @returns {ESTree.VariableDeclaration}
*/ */
function var_builder(pattern, init) { function var_builder(pattern, init) {
return declaration('var', pattern, init); return declaration('var', pattern, init);
@ -510,11 +509,11 @@ function var_builder(pattern, init) {
/** /**
* *
* @param {import('estree').VariableDeclaration | import('estree').Expression | null} init * @param {ESTree.VariableDeclaration | ESTree.Expression | null} init
* @param {import('estree').Expression} test * @param {ESTree.Expression} test
* @param {import('estree').Expression} update * @param {ESTree.Expression} update
* @param {import('estree').Statement} body * @param {ESTree.Statement} body
* @returns {import('estree').ForStatement} * @returns {ESTree.ForStatement}
*/ */
function for_builder(init, test, update, body) { function for_builder(init, test, update, body) {
return { type: 'ForStatement', init, test, update, body }; return { type: 'ForStatement', init, test, update, body };
@ -523,12 +522,12 @@ function for_builder(init, test, update, body) {
/** /**
* *
* @param {'constructor' | 'method' | 'get' | 'set'} kind * @param {'constructor' | 'method' | 'get' | 'set'} kind
* @param {import('estree').Expression | import('estree').PrivateIdentifier} key * @param {ESTree.Expression | ESTree.PrivateIdentifier} key
* @param {import('estree').Pattern[]} params * @param {ESTree.Pattern[]} params
* @param {import('estree').Statement[]} body * @param {ESTree.Statement[]} body
* @param {boolean} computed * @param {boolean} computed
* @param {boolean} is_static * @param {boolean} is_static
* @returns {import('estree').MethodDefinition} * @returns {ESTree.MethodDefinition}
*/ */
export function method(kind, key, params, body, computed = false, is_static = false) { export function method(kind, key, params, body, computed = false, is_static = false) {
return { return {
@ -543,10 +542,10 @@ export function method(kind, key, params, body, computed = false, is_static = fa
/** /**
* *
* @param {import('estree').Identifier | null} id * @param {ESTree.Identifier | null} id
* @param {import('estree').Pattern[]} params * @param {ESTree.Pattern[]} params
* @param {import('estree').BlockStatement} body * @param {ESTree.BlockStatement} body
* @returns {import('estree').FunctionExpression} * @returns {ESTree.FunctionExpression}
*/ */
function function_builder(id, params, body) { function function_builder(id, params, body) {
return { return {
@ -561,10 +560,10 @@ function function_builder(id, params, body) {
} }
/** /**
* @param {import('estree').Expression} test * @param {ESTree.Expression} test
* @param {import('estree').Statement} consequent * @param {ESTree.Statement} consequent
* @param {import('estree').Statement} [alternate] * @param {ESTree.Statement} [alternate]
* @returns {import('estree').IfStatement} * @returns {ESTree.IfStatement}
*/ */
function if_builder(test, consequent, alternate) { function if_builder(test, consequent, alternate) {
return { type: 'IfStatement', test, consequent, alternate }; return { type: 'IfStatement', test, consequent, alternate };
@ -573,7 +572,7 @@ function if_builder(test, consequent, alternate) {
/** /**
* @param {string} as * @param {string} as
* @param {string} source * @param {string} source
* @returns {import('estree').ImportDeclaration} * @returns {ESTree.ImportDeclaration}
*/ */
export function import_all(as, source) { export function import_all(as, source) {
return { return {
@ -586,7 +585,7 @@ export function import_all(as, source) {
/** /**
* @param {Array<[string, string]>} parts * @param {Array<[string, string]>} parts
* @param {string} source * @param {string} source
* @returns {import('estree').ImportDeclaration} * @returns {ESTree.ImportDeclaration}
*/ */
export function imports(parts, source) { export function imports(parts, source) {
return { return {
@ -601,8 +600,8 @@ export function imports(parts, source) {
} }
/** /**
* @param {import('estree').Expression | null} argument * @param {ESTree.Expression | null} argument
* @returns {import('estree').ReturnStatement} * @returns {ESTree.ReturnStatement}
*/ */
function return_builder(argument = null) { function return_builder(argument = null) {
return { type: 'ReturnStatement', argument }; return { type: 'ReturnStatement', argument };
@ -610,7 +609,7 @@ function return_builder(argument = null) {
/** /**
* @param {string} str * @param {string} str
* @returns {import('estree').ThrowStatement} * @returns {ESTree.ThrowStatement}
*/ */
export function throw_error(str) { export function throw_error(str) {
return { return {
@ -637,7 +636,7 @@ export {
/** /**
* @param {string} name * @param {string} name
* @returns {import('estree').Expression} * @returns {ESTree.Expression}
*/ */
export function key(name) { export function key(name) {
return regex_is_valid_identifier.test(name) ? id(name) : literal(name); return regex_is_valid_identifier.test(name) ? id(name) : literal(name);

@ -1,3 +1,8 @@
/** @import { ValidatedCompileOptions } from '#compiler' */
/** @import { Processed } from '../preprocess/public.js' */
/** @import { SourceMap } from 'magic-string' */
/** @import { Source } from '../preprocess/private.js' */
/** @import { DecodedSourceMap, SourceMapSegment, RawSourceMap } from '@ampproject/remapping' */
import remapping from '@ampproject/remapping'; import remapping from '@ampproject/remapping';
import { push_array } from './push_array.js'; import { push_array } from './push_array.js';
@ -10,7 +15,7 @@ function last_line_length(s) {
// mutate map in-place // mutate map in-place
/** /**
* @param {import('@ampproject/remapping').DecodedSourceMap} map * @param {DecodedSourceMap} map
* @param {{ line: number; column: number; }} offset * @param {{ line: number; column: number; }} offset
* @param {number} source_index * @param {number} source_index
*/ */
@ -74,13 +79,13 @@ export class MappedCode {
string = /** @type {any} */ (undefined); string = /** @type {any} */ (undefined);
/** /**
* @type {import('@ampproject/remapping').DecodedSourceMap} * @type {DecodedSourceMap}
*/ */
map = /** @type {any} */ (undefined); map = /** @type {any} */ (undefined);
/** /**
* @param {string} string * @param {string} string
* @param {import('@ampproject/remapping').DecodedSourceMap | null} map * @param {DecodedSourceMap | null} map
*/ */
constructor(string = '', map = null) { constructor(string = '', map = null) {
this.string = string; this.string = string;
@ -171,7 +176,7 @@ export class MappedCode {
// combine last line + first line // combine last line + first line
push_array( push_array(
m1.mappings[m1.mappings.length - 1], m1.mappings[m1.mappings.length - 1],
/** @type {import('@ampproject/remapping').SourceMapSegment[]} */ (m2.mappings.shift()) /** @type {SourceMapSegment[]} */ (m2.mappings.shift())
); );
// append other lines // append other lines
push_array(m1.mappings, m2.mappings); push_array(m1.mappings, m2.mappings);
@ -181,7 +186,7 @@ export class MappedCode {
/** /**
* @static * @static
* @param {string} string * @param {string} string
* @param {import('@ampproject/remapping').DecodedSourceMap} [map] * @param {DecodedSourceMap} [map]
* @returns {MappedCode} * @returns {MappedCode}
*/ */
static from_processed(string, map) { static from_processed(string, map) {
@ -205,7 +210,7 @@ export class MappedCode {
/** /**
* @static * @static
* @param {import('../preprocess/private.js').Source} opts * @param {Source} opts
* @returns {MappedCode} * @returns {MappedCode}
*/ */
static from_source({ source, file_basename, get_location }) { static from_source({ source, file_basename, get_location }) {
@ -216,7 +221,7 @@ export class MappedCode {
if (!offset) offset = { line: 0, column: 0 }; if (!offset) offset = { line: 0, column: 0 };
/** /**
* @type {import('@ampproject/remapping').DecodedSourceMap} * @type {DecodedSourceMap}
*/ */
const map = { version: 3, names: [], sources: [file_basename], mappings: [] }; const map = { version: 3, names: [], sources: [file_basename], mappings: [] };
if (source == '') return new MappedCode(source, map); if (source == '') return new MappedCode(source, map);
@ -255,7 +260,7 @@ const b64dec =
/** /**
* @param {string} filename Basename of the input file * @param {string} filename Basename of the input file
* @param {Array<import('@ampproject/remapping').DecodedSourceMap | import('@ampproject/remapping').RawSourceMap>} sourcemap_list * @param {Array<DecodedSourceMap | RawSourceMap>} sourcemap_list
*/ */
export function combine_sourcemaps(filename, sourcemap_list) { export function combine_sourcemaps(filename, sourcemap_list) {
if (sourcemap_list.length == 0) return null; if (sourcemap_list.length == 0) return null;
@ -296,9 +301,9 @@ export function combine_sourcemaps(filename, sourcemap_list) {
/** /**
* @param {string} filename * @param {string} filename
* @param {import('magic-string').SourceMap} svelte_map * @param {SourceMap} svelte_map
* @param {string | import('@ampproject/remapping').DecodedSourceMap | import('@ampproject/remapping').RawSourceMap} preprocessor_map_input * @param {string | DecodedSourceMap | RawSourceMap} preprocessor_map_input
* @returns {import('magic-string').SourceMap} * @returns {SourceMap}
*/ */
function apply_preprocessor_sourcemap(filename, svelte_map, preprocessor_map_input) { function apply_preprocessor_sourcemap(filename, svelte_map, preprocessor_map_input) {
if (!svelte_map || !preprocessor_map_input) return svelte_map; if (!svelte_map || !preprocessor_map_input) return svelte_map;
@ -323,13 +328,13 @@ function apply_preprocessor_sourcemap(filename, svelte_map, preprocessor_map_inp
} }
} }
}); });
return /** @type {import('magic-string').SourceMap} */ (result_map); return /** @type {SourceMap} */ (result_map);
} }
const regex_data_uri = /data:(?:application|text)\/json;(?:charset[:=]\S+?;)?base64,(\S*)/; const regex_data_uri = /data:(?:application|text)\/json;(?:charset[:=]\S+?;)?base64,(\S*)/;
// parse attached sourcemap in processed.code // parse attached sourcemap in processed.code
/** /**
* @param {import('../preprocess/public.js').Processed} processed * @param {Processed} processed
* @param {'script' | 'style'} tag_name * @param {'script' | 'style'} tag_name
* @returns {void} * @returns {void}
*/ */
@ -382,8 +387,8 @@ export function parse_attached_sourcemap(processed, tag_name) {
} }
/** /**
* @param {{ code: string, map: import('magic-string').SourceMap}} result * @param {{ code: string, map: SourceMap}} result
* @param {import('#compiler').ValidatedCompileOptions} options * @param {ValidatedCompileOptions} options
* @param {string} source_name * @param {string} source_name
*/ */
export function merge_with_preprocessor_map(result, options, source_name) { export function merge_with_preprocessor_map(result, options, source_name) {

@ -1,3 +1,4 @@
/** @import { ModuleCompileOptions, ValidatedModuleCompileOptions, CompileOptions, ValidatedCompileOptions } from '#compiler' */
import * as e from './errors.js'; import * as e from './errors.js';
import * as w from './warnings.js'; import * as w from './warnings.js';
@ -32,14 +33,14 @@ const common = {
}; };
export const validate_module_options = export const validate_module_options =
/** @type {Validator<import('#compiler').ModuleCompileOptions, import('#compiler').ValidatedModuleCompileOptions>} */ ( /** @type {Validator<ModuleCompileOptions, ValidatedModuleCompileOptions>} */ (
object({ object({
...common ...common
}) })
); );
export const validate_component_options = export const validate_component_options =
/** @type {Validator<import('#compiler').CompileOptions, import('#compiler').ValidatedCompileOptions>} */ ( /** @type {Validator<CompileOptions, ValidatedCompileOptions>} */ (
object({ object({
...common, ...common,

@ -1,10 +1,11 @@
/** @import { SourceLocation } from '../../../compiler/phases/3-transform/client/types.js' */
import { HYDRATION_END, HYDRATION_START } from '../../../constants.js'; import { HYDRATION_END, HYDRATION_START } from '../../../constants.js';
import { hydrating } from '../dom/hydration.js'; import { hydrating } from '../dom/hydration.js';
/** /**
* @param {any} fn * @param {any} fn
* @param {string} filename * @param {string} filename
* @param {import('../../../compiler/phases/3-transform/client/types.js').SourceLocation[]} locations * @param {SourceLocation[]} locations
* @returns {any} * @returns {any}
*/ */
export function add_locations(fn, filename, locations) { export function add_locations(fn, filename, locations) {
@ -21,7 +22,7 @@ export function add_locations(fn, filename, locations) {
/** /**
* @param {Element} element * @param {Element} element
* @param {string} filename * @param {string} filename
* @param {import('../../../compiler/phases/3-transform/client/types.js').SourceLocation} location * @param {SourceLocation} location
*/ */
function assign_location(element, filename, location) { function assign_location(element, filename, location) {
// @ts-expect-error // @ts-expect-error
@ -37,7 +38,7 @@ function assign_location(element, filename, location) {
/** /**
* @param {Node | null} node * @param {Node | null} node
* @param {string} filename * @param {string} filename
* @param {import('../../../compiler/phases/3-transform/client/types.js').SourceLocation[]} locations * @param {SourceLocation[]} locations
*/ */
function assign_locations(node, filename, locations) { function assign_locations(node, filename, locations) {
var i = 0; var i = 0;

@ -1,3 +1,4 @@
/** @import { Source, Effect } from '#client' */
import { block, branch, destroy_effect } from '../reactivity/effects.js'; import { block, branch, destroy_effect } from '../reactivity/effects.js';
import { set_should_intro } from '../render.js'; import { set_should_intro } from '../render.js';
import { get } from '../runtime.js'; import { get } from '../runtime.js';
@ -5,7 +6,7 @@ import { check_target } from './legacy.js';
/** /**
* @template {(anchor: Comment, props: any) => any} Component * @template {(anchor: Comment, props: any) => any} Component
* @param {import("#client").Source<Component>} source * @param {Source<Component>} source
*/ */
export function hmr(source) { export function hmr(source) {
/** /**
@ -15,7 +16,7 @@ export function hmr(source) {
return function (anchor, props) { return function (anchor, props) {
let instance = {}; let instance = {};
/** @type {import("#client").Effect} */ /** @type {Effect} */
let effect; let effect;
block(anchor, 0, () => { block(anchor, 0, () => {

@ -1,3 +1,4 @@
/** @import { ProxyMetadata } from '#client' */
/** @typedef {{ file: string, line: number, column: number }} Location */ /** @typedef {{ file: string, line: number, column: number }} Location */
import { STATE_SYMBOL } from '../constants.js'; import { STATE_SYMBOL } from '../constants.js';
@ -134,8 +135,8 @@ export function add_owner_effect(get_object, Component) {
} }
/** /**
* @param {import('#client').ProxyMetadata<any> | null} from * @param {ProxyMetadata<any> | null} from
* @param {import('#client').ProxyMetadata<any>} to * @param {ProxyMetadata<any>} to
*/ */
export function widen_ownership(from, to) { export function widen_ownership(from, to) {
if (to.owners === null) { if (to.owners === null) {
@ -162,7 +163,7 @@ export function widen_ownership(from, to) {
* @param {Set<any>} seen * @param {Set<any>} seen
*/ */
function add_owner_to_object(object, owner, seen) { function add_owner_to_object(object, owner, seen) {
const metadata = /** @type {import('#client').ProxyMetadata} */ (object?.[STATE_SYMBOL]); const metadata = /** @type {ProxyMetadata} */ (object?.[STATE_SYMBOL]);
if (metadata) { if (metadata) {
// this is a state proxy, add owner directly, if not globally shared // this is a state proxy, add owner directly, if not globally shared
@ -199,7 +200,7 @@ function add_owner_to_object(object, owner, seen) {
} }
/** /**
* @param {import('#client').ProxyMetadata} metadata * @param {ProxyMetadata} metadata
* @param {Function} component * @param {Function} component
* @returns {boolean} * @returns {boolean}
*/ */
@ -215,18 +216,18 @@ function has_owner(metadata, component) {
} }
/** /**
* @param {import('#client').ProxyMetadata} metadata * @param {ProxyMetadata} metadata
* @returns {any} * @returns {any}
*/ */
function get_owner(metadata) { function get_owner(metadata) {
return ( return (
metadata?.owners?.values().next().value ?? metadata?.owners?.values().next().value ??
get_owner(/** @type {import('#client').ProxyMetadata} */ (metadata.parent)) get_owner(/** @type {ProxyMetadata} */ (metadata.parent))
); );
} }
/** /**
* @param {import('#client').ProxyMetadata} metadata * @param {ProxyMetadata} metadata
*/ */
export function check_ownership(metadata) { export function check_ownership(metadata) {
const component = get_component(); const component = get_component();

@ -1,3 +1,4 @@
/** @import { Dom, Effect } from '#client' */
import { UNINITIALIZED } from '../../../../constants.js'; import { UNINITIALIZED } from '../../../../constants.js';
import { block, branch, pause_effect } from '../../reactivity/effects.js'; import { block, branch, pause_effect } from '../../reactivity/effects.js';
import { safe_not_equal } from '../../reactivity/equality.js'; import { safe_not_equal } from '../../reactivity/equality.js';
@ -6,14 +7,14 @@ import { safe_not_equal } from '../../reactivity/equality.js';
* @template V * @template V
* @param {Comment} anchor * @param {Comment} anchor
* @param {() => V} get_key * @param {() => V} get_key
* @param {(anchor: Node) => import('#client').Dom | void} render_fn * @param {(anchor: Node) => Dom | void} render_fn
* @returns {void} * @returns {void}
*/ */
export function key_block(anchor, get_key, render_fn) { export function key_block(anchor, get_key, render_fn) {
/** @type {V | typeof UNINITIALIZED} */ /** @type {V | typeof UNINITIALIZED} */
let key = UNINITIALIZED; let key = UNINITIALIZED;
/** @type {import('#client').Effect} */ /** @type {Effect} */
let effect; let effect;
block(anchor, 0, () => { block(anchor, 0, () => {

@ -1,3 +1,4 @@
/** @import { TemplateNode, Dom, Effect } from '#client' */
import { DEV } from 'esm-env'; import { DEV } from 'esm-env';
import { block, branch, pause_effect } from '../../reactivity/effects.js'; import { block, branch, pause_effect } from '../../reactivity/effects.js';
import { empty } from '../operations.js'; import { empty } from '../operations.js';
@ -5,16 +6,16 @@ import { empty } from '../operations.js';
/** /**
* @template P * @template P
* @template {(props: P) => void} C * @template {(props: P) => void} C
* @param {import('#client').TemplateNode} anchor * @param {TemplateNode} anchor
* @param {() => C} get_component * @param {() => C} get_component
* @param {(anchor: import('#client').TemplateNode, component: C) => import('#client').Dom | void} render_fn * @param {(anchor: TemplateNode, component: C) => Dom | void} render_fn
* @returns {void} * @returns {void}
*/ */
export function component(anchor, get_component, render_fn) { export function component(anchor, get_component, render_fn) {
/** @type {C} */ /** @type {C} */
let component; let component;
/** @type {import('#client').Effect | null} */ /** @type {Effect | null} */
let effect; let effect;
var component_anchor = anchor; var component_anchor = anchor;

@ -1,10 +1,11 @@
/** @import { ActionPayload } from '#client' */
import { effect, render_effect } from '../../reactivity/effects.js'; import { effect, render_effect } from '../../reactivity/effects.js';
import { deep_read_state, untrack } from '../../runtime.js'; import { deep_read_state, untrack } from '../../runtime.js';
/** /**
* @template P * @template P
* @param {Element} dom * @param {Element} dom
* @param {(dom: Element, value?: P) => import('#client').ActionPayload<P>} action * @param {(dom: Element, value?: P) => ActionPayload<P>} action
* @param {() => P} [get_value] * @param {() => P} [get_value]
* @returns {void} * @returns {void}
*/ */

@ -1,3 +1,4 @@
/** @import { ComponentContextLegacy } from '#client' */
import { run, run_all } from '../../../shared/utils.js'; import { run, run_all } from '../../../shared/utils.js';
import { user_pre_effect, user_effect } from '../../reactivity/effects.js'; import { user_pre_effect, user_effect } from '../../reactivity/effects.js';
import { current_component_context, deep_read_state, get, untrack } from '../../runtime.js'; import { current_component_context, deep_read_state, get, untrack } from '../../runtime.js';
@ -6,9 +7,7 @@ import { current_component_context, deep_read_state, get, untrack } from '../../
* Legacy-mode only: Call `onMount` callbacks and set up `beforeUpdate`/`afterUpdate` effects * Legacy-mode only: Call `onMount` callbacks and set up `beforeUpdate`/`afterUpdate` effects
*/ */
export function init() { export function init() {
const context = /** @type {import('#client').ComponentContextLegacy} */ ( const context = /** @type {ComponentContextLegacy} */ (current_component_context);
current_component_context
);
const callbacks = context.l.u; const callbacks = context.l.u;
if (!callbacks) return; if (!callbacks) return;
@ -45,7 +44,7 @@ export function init() {
/** /**
* Invoke the getter of all signals associated with a component * Invoke the getter of all signals associated with a component
* so they can be registered to the effect this function is called in. * so they can be registered to the effect this function is called in.
* @param {import('#client').ComponentContextLegacy} context * @param {ComponentContextLegacy} context
*/ */
function observe_all(context) { function observe_all(context) {
if (context.l.s) { if (context.l.s) {

@ -1,3 +1,4 @@
/** @import { TaskCallback, Task, TaskEntry } from '#client' */
import { raf } from './timing.js'; import { raf } from './timing.js';
// TODO move this into timing.js where it probably belongs // TODO move this into timing.js where it probably belongs
@ -22,11 +23,11 @@ function run_tasks(now) {
/** /**
* Creates a new task that runs on each raf frame * Creates a new task that runs on each raf frame
* until it returns a falsy value or is aborted * until it returns a falsy value or is aborted
* @param {import('#client').TaskCallback} callback * @param {TaskCallback} callback
* @returns {import('#client').Task} * @returns {Task}
*/ */
export function loop(callback) { export function loop(callback) {
/** @type {import('#client').TaskEntry} */ /** @type {TaskEntry} */
let task; let task;
if (raf.tasks.size === 0) { if (raf.tasks.size === 0) {

@ -1,4 +1,5 @@
/** @type {import('#client').Equals} */ /** @import { Equals } from '#client' */
/** @type {Equals} */
export function equals(value) { export function equals(value) {
return value === this.v; return value === this.v;
} }
@ -14,7 +15,7 @@ export function safe_not_equal(a, b) {
: a !== b || (a !== null && typeof a === 'object') || typeof a === 'function'; : a !== b || (a !== null && typeof a === 'object') || typeof a === 'function';
} }
/** @type {import('#client').Equals} */ /** @type {Equals} */
export function safe_equals(value) { export function safe_equals(value) {
return !safe_not_equal(value, this.v); return !safe_not_equal(value, this.v);
} }

@ -1,3 +1,4 @@
/** @import { Source } from './types.js' */
import { DEV } from 'esm-env'; import { DEV } from 'esm-env';
import { import {
PROPS_IS_IMMUTABLE, PROPS_IS_IMMUTABLE,
@ -88,7 +89,7 @@ export function rest_props(props, exclude, name) {
/** /**
* The proxy handler for legacy $$restProps and $$props * The proxy handler for legacy $$restProps and $$props
* @type {ProxyHandler<{ props: Record<string | symbol, unknown>, exclude: Array<string | symbol>, special: Record<string | symbol, (v?: unknown) => unknown>, version: import('./types.js').Source<number> }>}} * @type {ProxyHandler<{ props: Record<string | symbol, unknown>, exclude: Array<string | symbol>, special: Record<string | symbol, (v?: unknown) => unknown>, version: Source<number> }>}}
*/ */
const legacy_rest_props_handler = { const legacy_rest_props_handler = {
get(target, key) { get(target, key) {

@ -1,3 +1,5 @@
/** @import { StoreReferencesContainer, Source } from '#client' */
/** @import { Store } from '#shared' */
import { subscribe_to_store } from '../../../store/utils.js'; import { subscribe_to_store } from '../../../store/utils.js';
import { noop } from '../../shared/utils.js'; import { noop } from '../../shared/utils.js';
import { UNINITIALIZED } from '../../../constants.js'; import { UNINITIALIZED } from '../../../constants.js';
@ -10,13 +12,13 @@ import { mutable_source, set } from './sources.js';
* signal that will be updated when the store is. The store references container is needed to * signal that will be updated when the store is. The store references container is needed to
* track reassignments to stores and to track the correct component context. * track reassignments to stores and to track the correct component context.
* @template V * @template V
* @param {import('#shared').Store<V> | null | undefined} store * @param {Store<V> | null | undefined} store
* @param {string} store_name * @param {string} store_name
* @param {import('#client').StoreReferencesContainer} stores * @param {StoreReferencesContainer} stores
* @returns {V} * @returns {V}
*/ */
export function store_get(store, store_name, stores) { export function store_get(store, store_name, stores) {
/** @type {import('#client').StoreReferencesContainer[''] | undefined} */ /** @type {StoreReferencesContainer[''] | undefined} */
let entry = stores[store_name]; let entry = stores[store_name];
const is_new = entry === undefined; const is_new = entry === undefined;
@ -46,12 +48,12 @@ export function store_get(store, store_name, stores) {
* Unsubscribe from a store if it's not the same as the one in the store references container. * Unsubscribe from a store if it's not the same as the one in the store references container.
* We need this in addition to `store_get` because someone could unsubscribe from a store but * We need this in addition to `store_get` because someone could unsubscribe from a store but
* then never subscribe to the new one (if any), causing the subscription to stay open wrongfully. * then never subscribe to the new one (if any), causing the subscription to stay open wrongfully.
* @param {import('#shared').Store<any> | null | undefined} store * @param {Store<any> | null | undefined} store
* @param {string} store_name * @param {string} store_name
* @param {import('#client').StoreReferencesContainer} stores * @param {StoreReferencesContainer} stores
*/ */
export function store_unsub(store, store_name, stores) { export function store_unsub(store, store_name, stores) {
/** @type {import('#client').StoreReferencesContainer[''] | undefined} */ /** @type {StoreReferencesContainer[''] | undefined} */
let entry = stores[store_name]; let entry = stores[store_name];
if (entry && entry.store !== store) { if (entry && entry.store !== store) {
@ -65,8 +67,8 @@ export function store_unsub(store, store_name, stores) {
/** /**
* @template V * @template V
* @param {import('#shared').Store<V> | null | undefined} store * @param {Store<V> | null | undefined} store
* @param {import('#client').Source<V>} source * @param {Source<V>} source
*/ */
function connect_store_to_signal(store, source) { function connect_store_to_signal(store, source) {
if (store == null) { if (store == null) {
@ -80,7 +82,7 @@ function connect_store_to_signal(store, source) {
/** /**
* Sets the new value of a store and returns that value. * Sets the new value of a store and returns that value.
* @template V * @template V
* @param {import('#shared').Store<V>} store * @param {Store<V>} store
* @param {V} value * @param {V} value
* @returns {V} * @returns {V}
*/ */
@ -90,7 +92,7 @@ export function store_set(store, value) {
} }
/** /**
* @param {import('#client').StoreReferencesContainer} stores * @param {StoreReferencesContainer} stores
* @param {string} store_name * @param {string} store_name
*/ */
export function invalidate_store(stores, store_name) { export function invalidate_store(stores, store_name) {
@ -102,7 +104,7 @@ export function invalidate_store(stores, store_name) {
/** /**
* Unsubscribes from all auto-subscribed stores on destroy * Unsubscribes from all auto-subscribed stores on destroy
* @param {import('#client').StoreReferencesContainer} stores * @param {StoreReferencesContainer} stores
*/ */
export function unsubscribe_on_destroy(stores) { export function unsubscribe_on_destroy(stores) {
on_destroy(() => { on_destroy(() => {
@ -116,7 +118,7 @@ export function unsubscribe_on_destroy(stores) {
/** /**
* Updates a store with a new value. * Updates a store with a new value.
* @param {import('#shared').Store<V>} store the store to update * @param {Store<V>} store the store to update
* @param {any} expression the expression that mutates the store * @param {any} expression the expression that mutates the store
* @param {V} new_value the new store value * @param {V} new_value the new store value
* @template V * @template V
@ -127,7 +129,7 @@ export function mutate_store(store, expression, new_value) {
} }
/** /**
* @param {import('#shared').Store<number>} store * @param {Store<number>} store
* @param {number} store_value * @param {number} store_value
* @param {1 | -1} [d] * @param {1 | -1} [d]
* @returns {number} * @returns {number}
@ -138,7 +140,7 @@ export function update_store(store, store_value, d = 1) {
} }
/** /**
* @param {import('#shared').Store<number>} store * @param {Store<number>} store
* @param {number} store_value * @param {number} store_value
* @param {1 | -1} [d] * @param {1 | -1} [d]
* @returns {number} * @returns {number}

@ -1,3 +1,4 @@
/** @import { Raf } from '#client' */
import { noop } from '../shared/utils.js'; import { noop } from '../shared/utils.js';
const is_client = typeof window !== 'undefined'; const is_client = typeof window !== 'undefined';
@ -6,7 +7,7 @@ const request_animation_frame = is_client ? requestAnimationFrame : noop;
const now = is_client ? () => performance.now() : () => Date.now(); const now = is_client ? () => performance.now() : () => Date.now();
/** @type {import('#client').Raf} */ /** @type {Raf} */
export const raf = { export const raf = {
tick: /** @param {any} _ */ (_) => request_animation_frame(_), tick: /** @param {any} _ */ (_) => request_animation_frame(_),
now: () => now(), now: () => now(),

@ -1,8 +1,9 @@
/** @import { Component } from '#server' */
import { DEV } from 'esm-env'; import { DEV } from 'esm-env';
import { on_destroy } from './index.js'; import { on_destroy } from './index.js';
import * as e from '../shared/errors.js'; import * as e from '../shared/errors.js';
/** @type {import('#server').Component | null} */ /** @type {Component | null} */
export var current_component = null; export var current_component = null;
/** /**
@ -65,7 +66,7 @@ export function push(fn) {
} }
export function pop() { export function pop() {
var component = /** @type {import('#server').Component} */ (current_component); var component = /** @type {Component} */ (current_component);
var ondestroy = component.d; var ondestroy = component.d;
@ -77,7 +78,7 @@ export function pop() {
} }
/** /**
* @param {import('#server').Component} component_context * @param {Component} component_context
* @returns {Map<unknown, unknown> | null} * @returns {Map<unknown, unknown> | null}
*/ */
function get_parent_context(component_context) { function get_parent_context(component_context) {

@ -1,3 +1,4 @@
/** @import { ComponentConstructorOptions, ComponentType, SvelteComponent, Component } from 'svelte' */
import { proxy } from '../internal/client/proxy.js'; import { proxy } from '../internal/client/proxy.js';
import { user_pre_effect } from '../internal/client/reactivity/effects.js'; import { user_pre_effect } from '../internal/client/reactivity/effects.js';
import { hydrate, mount, unmount } from '../internal/client/render.js'; import { hydrate, mount, unmount } from '../internal/client/render.js';
@ -13,13 +14,13 @@ import { define_property } from '../internal/client/utils.js';
* @template {Record<string, any>} Events * @template {Record<string, any>} Events
* @template {Record<string, any>} Slots * @template {Record<string, any>} Slots
* *
* @param {import('svelte').ComponentConstructorOptions<Props> & { * @param {ComponentConstructorOptions<Props> & {
* component: import('svelte').ComponentType<import('svelte').SvelteComponent<Props, Events, Slots>> | import('svelte').Component<Props>; * component: ComponentType<SvelteComponent<Props, Events, Slots>> | Component<Props>;
* immutable?: boolean; * immutable?: boolean;
* hydrate?: boolean; * hydrate?: boolean;
* recover?: boolean; * recover?: boolean;
* }} options * }} options
* @returns {import('svelte').SvelteComponent<Props, Events, Slots> & Exports} * @returns {SvelteComponent<Props, Events, Slots> & Exports}
*/ */
export function createClassComponent(options) { export function createClassComponent(options) {
// @ts-expect-error $$prop_def etc are not actually defined // @ts-expect-error $$prop_def etc are not actually defined
@ -36,8 +37,8 @@ export function createClassComponent(options) {
* @template {Record<string, any>} Events * @template {Record<string, any>} Events
* @template {Record<string, any>} Slots * @template {Record<string, any>} Slots
* *
* @param {import('svelte').SvelteComponent<Props, Events, Slots> | import('svelte').Component<Props>} component * @param {SvelteComponent<Props, Events, Slots> | Component<Props>} component
* @returns {import('svelte').ComponentType<import('svelte').SvelteComponent<Props, Events, Slots> & Exports>} * @returns {ComponentType<SvelteComponent<Props, Events, Slots> & Exports>}
*/ */
export function asClassComponent(component) { export function asClassComponent(component) {
// @ts-expect-error $$prop_def etc are not actually defined // @ts-expect-error $$prop_def etc are not actually defined
@ -60,7 +61,7 @@ class Svelte4Component {
#instance; #instance;
/** /**
* @param {import('svelte').ComponentConstructorOptions & { * @param {ComponentConstructorOptions & {
* component: any; * component: any;
* immutable?: boolean; * immutable?: boolean;
* hydrate?: boolean; * hydrate?: boolean;

@ -1,3 +1,4 @@
/** @import { SvelteComponent } from '../index.js' */
import { asClassComponent as as_class_component, createClassComponent } from './legacy-client.js'; import { asClassComponent as as_class_component, createClassComponent } from './legacy-client.js';
import { render } from '../internal/server/index.js'; import { render } from '../internal/server/index.js';
@ -15,8 +16,8 @@ export { createClassComponent };
* @template {Record<string, any>} Events * @template {Record<string, any>} Events
* @template {Record<string, any>} Slots * @template {Record<string, any>} Slots
* *
* @param {import('../index.js').SvelteComponent<Props, Events, Slots>} component * @param {SvelteComponent<Props, Events, Slots>} component
* @returns {typeof import('../index.js').SvelteComponent<Props, Events, Slots> & Exports} * @returns {typeof SvelteComponent<Props, Events, Slots> & Exports}
*/ */
export function asClassComponent(component) { export function asClassComponent(component) {
const component_constructor = as_class_component(component); const component_constructor = as_class_component(component);

@ -1,3 +1,6 @@
/** @import { Task } from '../internal/client/types' */
/** @import { Tweened } from './public' */
/** @import { TweenedOptions } from './private' */
import { writable } from '../store/index.js'; import { writable } from '../store/index.js';
import { raf } from '../internal/client/timing.js'; import { raf } from '../internal/client/timing.js';
import { loop } from '../internal/client/loop.js'; import { loop } from '../internal/client/loop.js';
@ -76,17 +79,17 @@ function get_interpolator(a, b) {
* https://svelte.dev/docs/svelte-motion#tweened * https://svelte.dev/docs/svelte-motion#tweened
* @template T * @template T
* @param {T} [value] * @param {T} [value]
* @param {import('./private').TweenedOptions<T>} [defaults] * @param {TweenedOptions<T>} [defaults]
* @returns {import('./public').Tweened<T>} * @returns {Tweened<T>}
*/ */
export function tweened(value, defaults = {}) { export function tweened(value, defaults = {}) {
const store = writable(value); const store = writable(value);
/** @type {import('../internal/client/types').Task} */ /** @type {Task} */
let task; let task;
let target_value = value; let target_value = value;
/** /**
* @param {T} new_value * @param {T} new_value
* @param {import('./private').TweenedOptions<T>} [opts] * @param {TweenedOptions<T>} [opts]
*/ */
function set(new_value, opts) { function set(new_value, opts) {
target_value = new_value; target_value = new_value;
@ -96,7 +99,7 @@ export function tweened(value, defaults = {}) {
return Promise.resolve(); return Promise.resolve();
} }
/** @type {import('../internal/client/types').Task | null} */ /** @type {Task | null} */
let previous_task = task; let previous_task = task;
let started = false; let started = false;

@ -1,9 +1,11 @@
/** @import { Readable, StartStopNotifier, Subscriber, Unsubscriber, Updater, Writable } from './public' */
/** @import { Invalidator, Stores, StoresValues, SubscribeInvalidateTuple } from './private' */
import { noop, run_all } from '../internal/shared/utils.js'; import { noop, run_all } from '../internal/shared/utils.js';
import { safe_not_equal } from '../internal/client/reactivity/equality.js'; import { safe_not_equal } from '../internal/client/reactivity/equality.js';
import { subscribe_to_store } from './utils.js'; import { subscribe_to_store } from './utils.js';
/** /**
* @type {Array<import('./private').SubscribeInvalidateTuple<any> | any>} * @type {Array<SubscribeInvalidateTuple<any> | any>}
*/ */
const subscriber_queue = []; const subscriber_queue = [];
@ -13,8 +15,8 @@ const subscriber_queue = [];
* https://svelte.dev/docs/svelte-store#readable * https://svelte.dev/docs/svelte-store#readable
* @template T * @template T
* @param {T} [value] initial value * @param {T} [value] initial value
* @param {import('./public').StartStopNotifier<T>} [start] * @param {StartStopNotifier<T>} [start]
* @returns {import('./public').Readable<T>} * @returns {Readable<T>}
*/ */
export function readable(value, start) { export function readable(value, start) {
return { return {
@ -28,14 +30,14 @@ export function readable(value, start) {
* https://svelte.dev/docs/svelte-store#writable * https://svelte.dev/docs/svelte-store#writable
* @template T * @template T
* @param {T} [value] initial value * @param {T} [value] initial value
* @param {import('./public').StartStopNotifier<T>} [start] * @param {StartStopNotifier<T>} [start]
* @returns {import('./public').Writable<T>} * @returns {Writable<T>}
*/ */
export function writable(value, start = noop) { export function writable(value, start = noop) {
/** @type {import('./public').Unsubscriber | null} */ /** @type {Unsubscriber | null} */
let stop = null; let stop = null;
/** @type {Set<import('./private').SubscribeInvalidateTuple<T>>} */ /** @type {Set<SubscribeInvalidateTuple<T>>} */
const subscribers = new Set(); const subscribers = new Set();
/** /**
@ -63,7 +65,7 @@ export function writable(value, start = noop) {
} }
/** /**
* @param {import('./public').Updater<T>} fn * @param {Updater<T>} fn
* @returns {void} * @returns {void}
*/ */
function update(fn) { function update(fn) {
@ -71,12 +73,12 @@ export function writable(value, start = noop) {
} }
/** /**
* @param {import('./public').Subscriber<T>} run * @param {Subscriber<T>} run
* @param {import('./private').Invalidator<T>} [invalidate] * @param {Invalidator<T>} [invalidate]
* @returns {import('./public').Unsubscriber} * @returns {Unsubscriber}
*/ */
function subscribe(run, invalidate = noop) { function subscribe(run, invalidate = noop) {
/** @type {import('./private').SubscribeInvalidateTuple<T>} */ /** @type {SubscribeInvalidateTuple<T>} */
const subscriber = [run, invalidate]; const subscriber = [run, invalidate];
subscribers.add(subscriber); subscribers.add(subscriber);
if (subscribers.size === 1) { if (subscribers.size === 1) {
@ -99,38 +101,38 @@ export function writable(value, start = noop) {
* applying an aggregation function over its input values. * applying an aggregation function over its input values.
* *
* https://svelte.dev/docs/svelte-store#derived * https://svelte.dev/docs/svelte-store#derived
* @template {import('./private.js').Stores} S * @template {Stores} S
* @template T * @template T
* @overload * @overload
* @param {S} stores * @param {S} stores
* @param {(values: import('./private.js').StoresValues<S>, set: (value: T) => void, update: (fn: import('./public.js').Updater<T>) => void) => import('./public.js').Unsubscriber | void} fn * @param {(values: StoresValues<S>, set: (value: T) => void, update: (fn: Updater<T>) => void) => Unsubscriber | void} fn
* @param {T} [initial_value] * @param {T} [initial_value]
* @returns {import('./public.js').Readable<T>} * @returns {Readable<T>}
*/ */
/** /**
* Derived value store by synchronizing one or more readable stores and * Derived value store by synchronizing one or more readable stores and
* applying an aggregation function over its input values. * applying an aggregation function over its input values.
* *
* https://svelte.dev/docs/svelte-store#derived * https://svelte.dev/docs/svelte-store#derived
* @template {import('./private.js').Stores} S * @template {Stores} S
* @template T * @template T
* @overload * @overload
* @param {S} stores * @param {S} stores
* @param {(values: import('./private.js').StoresValues<S>) => T} fn * @param {(values: StoresValues<S>) => T} fn
* @param {T} [initial_value] * @param {T} [initial_value]
* @returns {import('./public.js').Readable<T>} * @returns {Readable<T>}
*/ */
/** /**
* @template {import('./private.js').Stores} S * @template {Stores} S
* @template T * @template T
* @param {S} stores * @param {S} stores
* @param {Function} fn * @param {Function} fn
* @param {T} [initial_value] * @param {T} [initial_value]
* @returns {import('./public.js').Readable<T>} * @returns {Readable<T>}
*/ */
export function derived(stores, fn, initial_value) { export function derived(stores, fn, initial_value) {
const single = !Array.isArray(stores); const single = !Array.isArray(stores);
/** @type {Array<import('./public').Readable<any>>} */ /** @type {Array<Readable<any>>} */
const stores_array = single ? [stores] : stores; const stores_array = single ? [stores] : stores;
if (!stores_array.every(Boolean)) { if (!stores_array.every(Boolean)) {
throw new Error('derived() expects stores as input, got a falsy value'); throw new Error('derived() expects stores as input, got a falsy value');
@ -187,8 +189,8 @@ export function derived(stores, fn, initial_value) {
* *
* https://svelte.dev/docs/svelte-store#readonly * https://svelte.dev/docs/svelte-store#readonly
* @template T * @template T
* @param {import('./public').Readable<T>} store - store to make readonly * @param {Readable<T>} store - store to make readonly
* @returns {import('./public').Readable<T>} * @returns {Readable<T>}
*/ */
export function readonly(store) { export function readonly(store) {
return { return {
@ -202,7 +204,7 @@ export function readonly(store) {
* *
* https://svelte.dev/docs/svelte-store#get * https://svelte.dev/docs/svelte-store#get
* @template T * @template T
* @param {import('../store/public').Readable<T>} store * @param {Readable<T>} store
* @returns {T} * @returns {T}
*/ */
export function get(store) { export function get(store) {

@ -1,17 +1,16 @@
import { Readable, Subscriber } from './public.js'; import { Readable, Subscriber } from './public.js';
/** Cleanup logic callback. */ /** Cleanup logic callback. */
export type Invalidator<T> = (value?: T) => void; type Invalidator<T> = (value?: T) => void;
/** Pair of subscriber and invalidator. */ /** Pair of subscriber and invalidator. */
export type SubscribeInvalidateTuple<T> = [Subscriber<T>, Invalidator<T>]; type SubscribeInvalidateTuple<T> = [Subscriber<T>, Invalidator<T>];
/** One or more `Readable`s. */ /** One or more `Readable`s. */
export type Stores = type Stores = Readable<any> | [Readable<any>, ...Array<Readable<any>>] | Array<Readable<any>>;
| Readable<any>
| [Readable<any>, ...Array<Readable<any>>]
| Array<Readable<any>>;
/** One or more values from `Readable` stores. */ /** One or more values from `Readable` stores. */
export type StoresValues<T> = type StoresValues<T> =
T extends Readable<infer U> ? U : { [K in keyof T]: T[K] extends Readable<infer U> ? U : never }; T extends Readable<infer U> ? U : { [K in keyof T]: T[K] extends Readable<infer U> ? U : never };
export { Invalidator, SubscribeInvalidateTuple, Stores, StoresValues };

@ -1,13 +1,13 @@
import type { Invalidator } from './private.js'; import type { Invalidator } from './private.js';
/** Callback to inform of a value updates. */ /** Callback to inform of a value updates. */
export type Subscriber<T> = (value: T) => void; type Subscriber<T> = (value: T) => void;
/** Unsubscribes from value updates. */ /** Unsubscribes from value updates. */
export type Unsubscriber = () => void; type Unsubscriber = () => void;
/** Callback to update a value. */ /** Callback to update a value. */
export type Updater<T> = (value: T) => T; type Updater<T> = (value: T) => T;
/** /**
* Start and stop notification callbacks. * Start and stop notification callbacks.
@ -18,13 +18,13 @@ export type Updater<T> = (value: T) => T;
* @returns {void | (() => void)} Optionally, a cleanup function that is called when the last remaining * @returns {void | (() => void)} Optionally, a cleanup function that is called when the last remaining
* subscriber unsubscribes. * subscriber unsubscribes.
*/ */
export type StartStopNotifier<T> = ( type StartStopNotifier<T> = (
set: (value: T) => void, set: (value: T) => void,
update: (fn: Updater<T>) => void update: (fn: Updater<T>) => void
) => void | (() => void); ) => void | (() => void);
/** Readable interface for subscribing. */ /** Readable interface for subscribing. */
export interface Readable<T> { interface Readable<T> {
/** /**
* Subscribe on value changes. * Subscribe on value changes.
* @param run subscription callback * @param run subscription callback
@ -34,7 +34,7 @@ export interface Readable<T> {
} }
/** Writable interface for both updating and subscribing. */ /** Writable interface for both updating and subscribing. */
export interface Writable<T> extends Readable<T> { interface Writable<T> extends Readable<T> {
/** /**
* Set value and inform subscribers. * Set value and inform subscribers.
* @param value to set * @param value to set
@ -48,4 +48,6 @@ export interface Writable<T> extends Readable<T> {
update(this: void, updater: Updater<T>): void; update(this: void, updater: Updater<T>): void;
} }
export { Readable, StartStopNotifier, Subscriber, Unsubscriber, Updater, Writable };
export * from './index.js'; export * from './index.js';

@ -1,8 +1,9 @@
/** @import { Readable } from './public' */
import { noop } from '../internal/shared/utils.js'; import { noop } from '../internal/shared/utils.js';
/** /**
* @template T * @template T
* @param {import('./public').Readable<T> | null | undefined} store * @param {Readable<T> | null | undefined} store
* @param {(value: T) => void} run * @param {(value: T) => void} run
* @param {(value: T) => void} [invalidate] * @param {(value: T) => void} [invalidate]
* @returns {() => void} * @returns {() => void}

@ -1,3 +1,4 @@
/** @import { BlurParams, CrossfadeParams, DrawParams, FadeParams, FlyParams, ScaleParams, SlideParams, TransitionConfig } from './public' */
/** @param {number} x */ /** @param {number} x */
const linear = (x) => x; const linear = (x) => x;
@ -29,8 +30,8 @@ function split_css_unit(value) {
* *
* https://svelte.dev/docs/svelte-transition#blur * https://svelte.dev/docs/svelte-transition#blur
* @param {Element} node * @param {Element} node
* @param {import('./public').BlurParams} [params] * @param {BlurParams} [params]
* @returns {import('./public').TransitionConfig} * @returns {TransitionConfig}
*/ */
export function blur( export function blur(
node, node,
@ -54,8 +55,8 @@ export function blur(
* *
* https://svelte.dev/docs/svelte-transition#fade * https://svelte.dev/docs/svelte-transition#fade
* @param {Element} node * @param {Element} node
* @param {import('./public').FadeParams} [params] * @param {FadeParams} [params]
* @returns {import('./public').TransitionConfig} * @returns {TransitionConfig}
*/ */
export function fade(node, { delay = 0, duration = 400, easing = linear } = {}) { export function fade(node, { delay = 0, duration = 400, easing = linear } = {}) {
const o = +getComputedStyle(node).opacity; const o = +getComputedStyle(node).opacity;
@ -72,8 +73,8 @@ export function fade(node, { delay = 0, duration = 400, easing = linear } = {})
* *
* https://svelte.dev/docs/svelte-transition#fly * https://svelte.dev/docs/svelte-transition#fly
* @param {Element} node * @param {Element} node
* @param {import('./public').FlyParams} [params] * @param {FlyParams} [params]
* @returns {import('./public').TransitionConfig} * @returns {TransitionConfig}
*/ */
export function fly( export function fly(
node, node,
@ -100,8 +101,8 @@ export function fly(
* *
* https://svelte.dev/docs/svelte-transition#slide * https://svelte.dev/docs/svelte-transition#slide
* @param {Element} node * @param {Element} node
* @param {import('./public').SlideParams} [params] * @param {SlideParams} [params]
* @returns {import('./public').TransitionConfig} * @returns {TransitionConfig}
*/ */
export function slide(node, { delay = 0, duration = 400, easing = cubic_out, axis = 'y' } = {}) { export function slide(node, { delay = 0, duration = 400, easing = cubic_out, axis = 'y' } = {}) {
const style = getComputedStyle(node); const style = getComputedStyle(node);
@ -144,8 +145,8 @@ export function slide(node, { delay = 0, duration = 400, easing = cubic_out, axi
* *
* https://svelte.dev/docs/svelte-transition#scale * https://svelte.dev/docs/svelte-transition#scale
* @param {Element} node * @param {Element} node
* @param {import('./public').ScaleParams} [params] * @param {ScaleParams} [params]
* @returns {import('./public').TransitionConfig} * @returns {TransitionConfig}
*/ */
export function scale( export function scale(
node, node,
@ -172,8 +173,8 @@ export function scale(
* *
* https://svelte.dev/docs/svelte-transition#draw * https://svelte.dev/docs/svelte-transition#draw
* @param {SVGElement & { getTotalLength(): number }} node * @param {SVGElement & { getTotalLength(): number }} node
* @param {import('./public').DrawParams} [params] * @param {DrawParams} [params]
* @returns {import('./public').TransitionConfig} * @returns {TransitionConfig}
*/ */
export function draw(node, { delay = 0, speed, duration, easing = cubic_in_out } = {}) { export function draw(node, { delay = 0, speed, duration, easing = cubic_in_out } = {}) {
let len = node.getTotalLength(); let len = node.getTotalLength();
@ -218,10 +219,10 @@ function assign(tar, src) {
* The `crossfade` function creates a pair of [transitions](https://svelte.dev/docs#template-syntax-element-directives-transition-fn) called `send` and `receive`. When an element is 'sent', it looks for a corresponding element being 'received', and generates a transition that transforms the element to its counterpart's position and fades it out. When an element is 'received', the reverse happens. If there is no counterpart, the `fallback` transition is used. * The `crossfade` function creates a pair of [transitions](https://svelte.dev/docs#template-syntax-element-directives-transition-fn) called `send` and `receive`. When an element is 'sent', it looks for a corresponding element being 'received', and generates a transition that transforms the element to its counterpart's position and fades it out. When an element is 'received', the reverse happens. If there is no counterpart, the `fallback` transition is used.
* *
* https://svelte.dev/docs/svelte-transition#crossfade * https://svelte.dev/docs/svelte-transition#crossfade
* @param {import('./public').CrossfadeParams & { * @param {CrossfadeParams & {
* fallback?: (node: Element, params: import('./public').CrossfadeParams, intro: boolean) => import('./public').TransitionConfig; * fallback?: (node: Element, params: CrossfadeParams, intro: boolean) => TransitionConfig;
* }} params * }} params
* @returns {[(node: any, params: import('./public').CrossfadeParams & { key: any; }) => () => import('./public').TransitionConfig, (node: any, params: import('./public').CrossfadeParams & { key: any; }) => () => import('./public').TransitionConfig]} * @returns {[(node: any, params: CrossfadeParams & { key: any; }) => () => TransitionConfig, (node: any, params: CrossfadeParams & { key: any; }) => () => TransitionConfig]}
*/ */
export function crossfade({ fallback, ...defaults }) { export function crossfade({ fallback, ...defaults }) {
/** @type {Map<any, Element>} */ /** @type {Map<any, Element>} */
@ -232,8 +233,8 @@ export function crossfade({ fallback, ...defaults }) {
/** /**
* @param {Element} from_node * @param {Element} from_node
* @param {Element} node * @param {Element} node
* @param {import('./public').CrossfadeParams} params * @param {CrossfadeParams} params
* @returns {import('./public').TransitionConfig} * @returns {TransitionConfig}
*/ */
function crossfade(from_node, node, params) { function crossfade(from_node, node, params) {
const { const {
@ -269,7 +270,7 @@ export function crossfade({ fallback, ...defaults }) {
* @param {Map<any, Element>} items * @param {Map<any, Element>} items
* @param {Map<any, Element>} counterparts * @param {Map<any, Element>} counterparts
* @param {boolean} intro * @param {boolean} intro
* @returns {(node: any, params: import('./public').CrossfadeParams & { key: any; }) => () => import('./public').TransitionConfig} * @returns {(node: any, params: CrossfadeParams & { key: any; }) => () => TransitionConfig}
*/ */
function transition(items, counterparts, intro) { function transition(items, counterparts, intro) {
// @ts-expect-error TODO improve typings (are the public types wrong?) // @ts-expect-error TODO improve typings (are the public types wrong?)

@ -1,6 +1,6 @@
export type EasingFunction = (t: number) => number; type EasingFunction = (t: number) => number;
export interface TransitionConfig { interface TransitionConfig {
delay?: number; delay?: number;
duration?: number; duration?: number;
easing?: EasingFunction; easing?: EasingFunction;
@ -8,7 +8,7 @@ export interface TransitionConfig {
tick?: (t: number, u: number) => void; tick?: (t: number, u: number) => void;
} }
export interface BlurParams { interface BlurParams {
delay?: number; delay?: number;
duration?: number; duration?: number;
easing?: EasingFunction; easing?: EasingFunction;
@ -16,13 +16,13 @@ export interface BlurParams {
opacity?: number; opacity?: number;
} }
export interface FadeParams { interface FadeParams {
delay?: number; delay?: number;
duration?: number; duration?: number;
easing?: EasingFunction; easing?: EasingFunction;
} }
export interface FlyParams { interface FlyParams {
delay?: number; delay?: number;
duration?: number; duration?: number;
easing?: EasingFunction; easing?: EasingFunction;
@ -31,14 +31,14 @@ export interface FlyParams {
opacity?: number; opacity?: number;
} }
export interface SlideParams { interface SlideParams {
delay?: number; delay?: number;
duration?: number; duration?: number;
easing?: EasingFunction; easing?: EasingFunction;
axis?: 'x' | 'y'; axis?: 'x' | 'y';
} }
export interface ScaleParams { interface ScaleParams {
delay?: number; delay?: number;
duration?: number; duration?: number;
easing?: EasingFunction; easing?: EasingFunction;
@ -46,17 +46,29 @@ export interface ScaleParams {
opacity?: number; opacity?: number;
} }
export interface DrawParams { interface DrawParams {
delay?: number; delay?: number;
speed?: number; speed?: number;
duration?: number | ((len: number) => number); duration?: number | ((len: number) => number);
easing?: EasingFunction; easing?: EasingFunction;
} }
export interface CrossfadeParams { interface CrossfadeParams {
delay?: number; delay?: number;
duration?: number | ((len: number) => number); duration?: number | ((len: number) => number);
easing?: EasingFunction; easing?: EasingFunction;
} }
export {
EasingFunction,
TransitionConfig,
BlurParams,
FadeParams,
FlyParams,
SlideParams,
ScaleParams,
DrawParams,
CrossfadeParams
};
export * from './index.js'; export * from './index.js';

@ -1,3 +1,4 @@
/** @import { CompileOptions } from '#compiler' */
import * as fs from 'node:fs'; import * as fs from 'node:fs';
import * as path from 'node:path'; import * as path from 'node:path';
import glob from 'tiny-glob/sync.js'; import glob from 'tiny-glob/sync.js';
@ -53,7 +54,7 @@ export function create_deferred() {
* *
* @param {string} cwd * @param {string} cwd
* @param {'client' | 'server'} generate * @param {'client' | 'server'} generate
* @param {Partial<import('#compiler').CompileOptions>} compileOptions * @param {Partial<CompileOptions>} compileOptions
* @param {boolean} [output_map] * @param {boolean} [output_map]
* @param {any} [preprocessor] * @param {any} [preprocessor]
*/ */

@ -1,3 +1,5 @@
/** @import { assert } from 'vitest' */
/** @import { CompileOptions, Warning } from '#compiler' */
/** /**
* @param {any} a * @param {any} a
* @param {any} b * @param {any} b
@ -118,9 +120,9 @@ function normalize_children(node) {
* html?: string; * html?: string;
* ssrHtml?: string; * ssrHtml?: string;
* props?: Props; * props?: Props;
* compileOptions?: Partial<import('#compiler').CompileOptions>; * compileOptions?: Partial<CompileOptions>;
* test?: (args: { * test?: (args: {
* assert: typeof import('vitest').assert & { * assert: typeof assert & {
* htmlEqual(a: string, b: string, description?: string): void; * htmlEqual(a: string, b: string, description?: string): void;
* htmlEqualWithOptions( * htmlEqualWithOptions(
* a: string, * a: string,
@ -129,7 +131,7 @@ function normalize_children(node) {
* description?: string * description?: string
* ): void; * ): void;
* }; * };
* compileOptions: import('#compiler').CompileOptions; * compileOptions: CompileOptions;
* component: Props & { * component: Props & {
* [key: string]: any; * [key: string]: any;
* }; * };
@ -150,7 +152,7 @@ function normalize_children(node) {
* accessors?: boolean; * accessors?: boolean;
* immutable?: boolean; * immutable?: boolean;
* dev?: boolean; * dev?: boolean;
* warnings?: import('#compiler').Warning[]; * warnings?: Warning[];
*}} args *}} args
*/ */
export function test(args) { export function test(args) {

@ -1,3 +1,4 @@
/** @import { Location } from 'locate-character' */
import * as assert from 'node:assert'; import * as assert from 'node:assert';
import * as path from 'node:path'; import * as path from 'node:path';
import { getLocator } from 'locate-character'; import { getLocator } from 'locate-character';
@ -15,7 +16,7 @@ export function assert_mapped({ code, filename, input, input_code, preprocessed
if (filename === undefined) filename = 'input.svelte'; if (filename === undefined) filename = 'input.svelte';
if (input_code === undefined) input_code = code; if (input_code === undefined) input_code = code;
const source_loc = /** @type {import('locate-character').Location} */ (locate_input(input_code)); const source_loc = /** @type {Location} */ (locate_input(input_code));
assert.notEqual(source_loc, undefined, `failed to locate "${input_code}" in "${filename}"`); assert.notEqual(source_loc, undefined, `failed to locate "${input_code}" in "${filename}"`);
const transformed_loc = preprocessed.locate_1(code); const transformed_loc = preprocessed.locate_1(code);

@ -1,3 +1,4 @@
/** @import { PreprocessorGroup, Preprocessor } from '../../../../src/compiler/public' */
import * as path from 'node:path'; import * as path from 'node:path';
import MagicString from 'magic-string'; import MagicString from 'magic-string';
import { test } from '../../test'; import { test } from '../../test';
@ -10,10 +11,10 @@ let comment_multi = true;
* @param {'script' | 'style'} tag_name * @param {'script' | 'style'} tag_name
* @param {string} search * @param {string} search
* @param {string} replace * @param {string} replace
* @returns {import('../../../../src/compiler/public').PreprocessorGroup} * @returns {PreprocessorGroup}
*/ */
function get_processor(tag_name, search, replace) { function get_processor(tag_name, search, replace) {
/** @type {import('../../../../src/compiler/public').Preprocessor} */ /** @type {Preprocessor} */
const preprocessor = ({ content, filename = '' }) => { const preprocessor = ({ content, filename = '' }) => {
let code = content.slice(); let code = content.slice();
const ms = new MagicString(code); const ms = new MagicString(code);

@ -1,3 +1,4 @@
/** @import { Location } from 'locate-character' */
import MagicString from 'magic-string'; import MagicString from 'magic-string';
import { TraceMap, originalPositionFor } from '@jridgewell/trace-mapping'; import { TraceMap, originalPositionFor } from '@jridgewell/trace-mapping';
import { test } from '../../test'; import { test } from '../../test';
@ -54,10 +55,7 @@ export default test({
['--done-replace-twice: green', '--replace-me-twice', 10, 2] ['--done-replace-twice: green', '--replace-me-twice', 10, 2]
]).forEach(([content, name, line, column]) => { ]).forEach(([content, name, line, column]) => {
assert.deepEqual( assert.deepEqual(
originalPositionFor( originalPositionFor(map, /** @type {Location} */ (locate(content))),
map,
/** @type {import('locate-character').Location_1} */ (locate(content))
),
{ {
source: sourcefile, source: sourcefile,
name, name,

@ -952,6 +952,29 @@ declare module 'svelte/compiler' {
inside_rest?: boolean; inside_rest?: boolean;
} | null; } | null;
} }
/**
* The preprocess function provides convenient hooks for arbitrarily transforming component source code.
* For example, it can be used to convert a <style lang="sass"> block into vanilla CSS.
*
* https://svelte.dev/docs/svelte-compiler#svelte-preprocess
* */
function preprocess(source: string, preprocessor: PreprocessorGroup | PreprocessorGroup[], options?: {
filename?: string;
} | undefined): Promise<Processed>;
/**
* The current version, as set in package.json.
*
* https://svelte.dev/docs/svelte-compiler#svelte-version
* */
const VERSION: string;
/**
* Does a best-effort migration of Svelte code towards using runes, event attributes and render tags.
* May throw an error if the code is too complex to migrate automatically.
*
* */
function migrate(source: string): {
code: string;
};
interface BaseNode_1 { interface BaseNode_1 {
type: string; type: string;
start: number; start: number;
@ -1191,29 +1214,6 @@ declare module 'svelte/compiler' {
| LegacyAttributeShorthand | LegacyAttributeShorthand
| LegacyCssNode | LegacyCssNode
| Text; | Text;
/**
* The preprocess function provides convenient hooks for arbitrarily transforming component source code.
* For example, it can be used to convert a <style lang="sass"> block into vanilla CSS.
*
* https://svelte.dev/docs/svelte-compiler#svelte-preprocess
* */
function preprocess(source: string, preprocessor: PreprocessorGroup | PreprocessorGroup[], options?: {
filename?: string;
} | undefined): Promise<Processed>;
/**
* The current version, as set in package.json.
*
* https://svelte.dev/docs/svelte-compiler#svelte-version
* */
const VERSION: string;
/**
* Does a best-effort migration of Svelte code towards using runes, event attributes and render tags.
* May throw an error if the code is too complex to migrate automatically.
*
* */
function migrate(source: string): {
code: string;
};
class Scope { class Scope {
constructor(root: ScopeRoot, parent: Scope | null, porous: boolean); constructor(root: ScopeRoot, parent: Scope | null, porous: boolean);
@ -2030,25 +2030,26 @@ declare module 'svelte/easing' {
} }
declare module 'svelte/legacy' { declare module 'svelte/legacy' {
import type { ComponentConstructorOptions, SvelteComponent, ComponentType, Component } from 'svelte';
/** /**
* Takes the same options as a Svelte 4 component and the component function and returns a Svelte 4 compatible component. * Takes the same options as a Svelte 4 component and the component function and returns a Svelte 4 compatible component.
* *
* @deprecated Use this only as a temporary solution to migrate your imperative component code to Svelte 5. * @deprecated Use this only as a temporary solution to migrate your imperative component code to Svelte 5.
* *
* */ * */
function createClassComponent<Props extends Record<string, any>, Exports extends Record<string, any>, Events extends Record<string, any>, Slots extends Record<string, any>>(options: import("svelte").ComponentConstructorOptions<Props> & { function createClassComponent<Props extends Record<string, any>, Exports extends Record<string, any>, Events extends Record<string, any>, Slots extends Record<string, any>>(options: ComponentConstructorOptions<Props> & {
component: import("svelte").ComponentType<import("svelte").SvelteComponent<Props, Events, Slots>> | import("svelte").Component<Props>; component: ComponentType<SvelteComponent<Props, Events, Slots>> | Component<Props>;
immutable?: boolean; immutable?: boolean;
hydrate?: boolean; hydrate?: boolean;
recover?: boolean; recover?: boolean;
}): import("svelte").SvelteComponent<Props, Events, Slots> & Exports; }): SvelteComponent<Props, Events, Slots> & Exports;
/** /**
* Takes the component function and returns a Svelte 4 compatible component constructor. * Takes the component function and returns a Svelte 4 compatible component constructor.
* *
* @deprecated Use this only as a temporary solution to migrate your imperative component code to Svelte 5. * @deprecated Use this only as a temporary solution to migrate your imperative component code to Svelte 5.
* *
* */ * */
function asClassComponent<Props extends Record<string, any>, Exports extends Record<string, any>, Events extends Record<string, any>, Slots extends Record<string, any>>(component: import("svelte").SvelteComponent<Props, Events, Slots> | import("svelte").Component<Props>): import("svelte").ComponentType<import("svelte").SvelteComponent<Props, Events, Slots> & Exports>; function asClassComponent<Props extends Record<string, any>, Exports extends Record<string, any>, Events extends Record<string, any>, Slots extends Record<string, any>>(component: SvelteComponent<Props, Events, Slots> | Component<Props>): ComponentType<SvelteComponent<Props, Events, Slots> & Exports>;
/** /**
* Runs the given function once immediately on the server, and works like `$effect.pre` on the client. * Runs the given function once immediately on the server, and works like `$effect.pre` on the client.
* *
@ -2252,10 +2253,7 @@ declare module 'svelte/store' {
type Invalidator<T> = (value?: T) => void; type Invalidator<T> = (value?: T) => void;
/** One or more `Readable`s. */ /** One or more `Readable`s. */
type Stores = type Stores = Readable<any> | [Readable<any>, ...Array<Readable<any>>] | Array<Readable<any>>;
| Readable<any>
| [Readable<any>, ...Array<Readable<any>>]
| Array<Readable<any>>;
/** One or more values from `Readable` stores. */ /** One or more values from `Readable` stores. */
type StoresValues<T> = type StoresValues<T> =
@ -2302,7 +2300,7 @@ declare module 'svelte/store' {
* */ * */
function get<T>(store: Readable<T>): T; function get<T>(store: Readable<T>): T;
export { Subscriber, Unsubscriber, Updater, StartStopNotifier, Readable, Writable, readable, writable, derived, readonly, get }; export { Readable, StartStopNotifier, Subscriber, Unsubscriber, Updater, Writable, readable, writable, derived, readonly, get };
} }
declare module 'svelte/transition' { declare module 'svelte/transition' {

Loading…
Cancel
Save