diff --git a/src/compiler/compile/Component.ts b/src/compiler/compile/Component.ts index 49c60ccd6f..07c9a20f2c 100644 --- a/src/compiler/compile/Component.ts +++ b/src/compiler/compile/Component.ts @@ -231,9 +231,6 @@ export default class Component { const banner = `${this.file ? `${this.file} ` : ``}generated by Svelte v${__VERSION__}`; - const legacy_dev_runtime = compile_options.dev && compile_options.version < 3.22; - const dev_runtime = compile_options.dev && compile_options.version >= 3.22; - const program: any = { type: 'Program', body: result.js }; walk(program, { @@ -246,11 +243,11 @@ export default class Component { } else { let name = node.name.slice(1); - if (legacy_dev_runtime) { - if (internal_exports.has(`${name}_dev$legacy`)) { - name += '_dev$legacy'; - } else if (internal_exports.has(`${name}Dev$legacy`)) { - name += 'Dev$legacy'; + if (compile_options.dev) { + if (internal_exports.has(`${name}_dev`)) { + name += '_dev'; + } else if (internal_exports.has(`${name}Dev`)) { + name += 'Dev'; } } @@ -290,7 +287,7 @@ export default class Component { format, name, banner, - compile_options.sveltePath + (dev_runtime ? '/dev' : ''), + compile_options.sveltePath, imported_helpers, referenced_globals, this.imports, @@ -838,7 +835,7 @@ export default class Component { const guard = this.get_unique_name('guard', scope); this.used_names.add(guard.name); - const before = b`const ${guard} = @loop_guard(${timeout})`; + const before = b`const ${guard} = @loop_guard_dev(${timeout})`; const inside = b`${guard}();`; // wrap expression statement with BlockStatement diff --git a/src/compiler/compile/index.ts b/src/compiler/compile/index.ts index 3374626189..7b992eb712 100644 --- a/src/compiler/compile/index.ts +++ b/src/compiler/compile/index.ts @@ -8,7 +8,6 @@ import fuzzymatch from '../utils/fuzzymatch'; import get_name_from_filename from './utils/get_name_from_filename'; const valid_options = [ - 'version', 'format', 'name', 'filename', @@ -68,7 +67,7 @@ function validate_options(options: CompileOptions, warnings: Warning[]) { } export default function compile(source: string, options: CompileOptions = {}) { - options = { generate: 'dom', dev: null, version: 3, ...options }; + options = { generate: 'dom', dev: null, ...options }; const stats = new Stats(); const warnings = []; diff --git a/src/compiler/compile/render_dom/Block.ts b/src/compiler/compile/render_dom/Block.ts index 173fe09a34..e6ce3e2302 100644 --- a/src/compiler/compile/render_dom/Block.ts +++ b/src/compiler/compile/render_dom/Block.ts @@ -229,7 +229,7 @@ export default class Block { } get_contents(key?: any) { - const { dev, version } = this.renderer.options; + const { dev } = this.renderer.options; let k; for (k in this.chunks) this.chunks[k] = this.chunks[k].filter(Boolean); @@ -403,8 +403,8 @@ export default class Block { ? b` const ${block} = ${return_value}; ${ - version < 3.22 && - b`@dispatch_dev$legacy("SvelteRegisterBlock", { + dev && + b`@dispatch_dev("SvelteRegisterBlock", { block: ${block}, id: ${this.name || 'create_fragment'}.name, type: "${this.type}", diff --git a/src/compiler/compile/render_dom/index.ts b/src/compiler/compile/render_dom/index.ts index c83e29a3e8..abd8742f07 100644 --- a/src/compiler/compile/render_dom/index.ts +++ b/src/compiler/compile/render_dom/index.ts @@ -267,7 +267,7 @@ export default function dom(component: Component, options: CompileOptions): { js : b`$$self.$$.on_destroy.push(@subscribe(${name}, #value => $$invalidate(${i}, ${value} = #value)));`; if (component.compile_options.dev) { - return b`@validate_store(${name}, '${name}'); ${insert}`; + return b`@validate_store_dev(${name}, '${name}'); ${insert}`; } return insert; @@ -342,7 +342,7 @@ export default function dom(component: Component, options: CompileOptions): { js }) .map( ({ name }) => b` - ${component.compile_options.dev && b`@validate_store(${name.slice(1)}, '${name.slice(1)}');`} + ${component.compile_options.dev && b`@validate_store_dev(${name.slice(1)}, '${name.slice(1)}');`} $$self.$$.on_destroy.push(@subscribe(${name.slice(1)}, #value => $$invalidate(${ renderer.context_lookup.get(name).index }, ${name} = #value)); @@ -443,7 +443,7 @@ export default function dom(component: Component, options: CompileOptions): { js ${component.slots.size || component.compile_options.dev ? b`let { $$slots = {}, $$scope } = $$props;` : null} ${ component.compile_options.dev && - b`@validate_slots('${component.tag}', $$slots, [${[...component.slots.keys()] + b`@validate_slots_dev('${component.tag}', $$slots, [${[...component.slots.keys()] .map((key) => `'${key}'`) .join(',')}]);` } @@ -562,8 +562,7 @@ export default function dom(component: Component, options: CompileOptions): { js }, ${not_equal}, ${prop_indexes}, ${dirty}); ${ options.dev && - options.version < 3.22 && - b`@dispatch_dev$legacy("SvelteRegisterComponent", { component: this, tagName: "${name.name}", options, id: create_fragment.name });` + b`@dispatch_dev("SvelteRegisterComponent", { component: this, tagName: "${name.name}", options, id: create_fragment.name });` } ${dev_props_check} diff --git a/src/compiler/compile/render_dom/wrappers/EachBlock.ts b/src/compiler/compile/render_dom/wrappers/EachBlock.ts index 5b648f8ec0..e8e265dd72 100644 --- a/src/compiler/compile/render_dom/wrappers/EachBlock.ts +++ b/src/compiler/compile/render_dom/wrappers/EachBlock.ts @@ -172,7 +172,7 @@ export default class EachBlockWrapper extends Wrapper { block.chunks.init.push(b`let ${each_block_value} = ${snippet};`); if (__DEV__) { - block.chunks.init.push(b`@validate_each_argument(${each_block_value});`); + block.chunks.init.push(b`@is_array_like_dev(${each_block_value});`); } renderer.blocks.push(b` @@ -341,9 +341,9 @@ export default class EachBlockWrapper extends Wrapper { ); const validate_each_keys = - __DEV__ && b`@validate_each_keys(#ctx, ${each_block_value}, ${each_context_getter}, ${key_getter});`; + __DEV__ && b`@check_duplicate_keys_dev(#ctx, ${each_block_value}, ${each_context_getter}, ${key_getter});`; - const validate_each_argument = __DEV__ && b`@validate_each_argument(${each_block_value});`; + const validate_each_argument = __DEV__ && b`@is_array_like_dev(${each_block_value});`; block.chunks.init.push( b`const ${key_getter} = (#ctx) => ${this.node.key.manipulate(block)};`, @@ -438,7 +438,7 @@ export default class EachBlockWrapper extends Wrapper { this.updates.push(b` ${!has_update_method && b`const #old_length = ${each_block}.length;`} ${each_block_value} = ${snippet}; - ${__DEV__ && b`@validate_each_argument(${each_block_value});`} + ${__DEV__ && b`@is_array_like_dev(${each_block_value});`} let #i = ${start}, #block; ${for_loop( each_block_value, diff --git a/src/compiler/compile/render_dom/wrappers/Element/index.ts b/src/compiler/compile/render_dom/wrappers/Element/index.ts index c0db934948..3eed0cb650 100644 --- a/src/compiler/compile/render_dom/wrappers/Element/index.ts +++ b/src/compiler/compile/render_dom/wrappers/Element/index.ts @@ -372,9 +372,7 @@ export default class ElementWrapper extends Wrapper { if (renderer.options.dev) { const loc = renderer.locate(this.node.start); block.chunks.hydrate.push( - b`@add_location_dev$legacy(${this.var}, ${renderer.file_var}, ${loc.line - 1}, ${loc.column}, ${ - this.node.start - });` + b`@add_location_dev(${this.var}, ${renderer.file_var}, ${loc.line - 1}, ${loc.column}, ${this.node.start});` ); } } diff --git a/src/compiler/compile/render_ssr/index.ts b/src/compiler/compile/render_ssr/index.ts index f4657324b4..0177e63069 100644 --- a/src/compiler/compile/render_ssr/index.ts +++ b/src/compiler/compile/render_ssr/index.ts @@ -42,7 +42,7 @@ export default function ssr(component: Component, options: CompileOptions): { js if (store && store.hoistable) return null; const assignment = b`${store_name}.subscribe(#v=>{${name}=#v})();`; return component.compile_options.dev - ? b`@validate_store(${store_name}, '${store_name}'); ${assignment}` + ? b`@validate_store_dev(${store_name}, '${store_name}'); ${assignment}` : assignment; }) .filter(Boolean); @@ -50,7 +50,7 @@ export default function ssr(component: Component, options: CompileOptions): { js component.rewrite_props( ({ name }) => b`${ - component.compile_options.dev && b`@validate_store(${name}, '${name}');` + component.compile_options.dev && b`@validate_store_dev(${name}, '${name}');` }${name}.subscribe((#v)=>{$${name}=#v})()` ); diff --git a/src/compiler/interfaces.ts b/src/compiler/interfaces.ts index 2184beb7fb..f60eedcbd7 100644 --- a/src/compiler/interfaces.ts +++ b/src/compiler/interfaces.ts @@ -102,12 +102,8 @@ export interface Warning { export type ModuleFormat = 'esm' | 'cjs'; export interface CompileOptions { - /* bundler */ filename?: string; - version?: number; format?: ModuleFormat; - - /* Component class name */ name?: string; generate?: string | false; diff --git a/src/runtime/easing/index.ts b/src/runtime/easing/index.ts index 6f20064b84..612c8ab082 100644 --- a/src/runtime/easing/index.ts +++ b/src/runtime/easing/index.ts @@ -1,5 +1,3 @@ -import { dev$assert } from 'svelte/internal'; - export const linear = (t: number) => t; export const quadIn = (t: number) => t ** 2; export const quadOut = (t: number) => 1.0 - (1.0 - t) ** 2; @@ -49,10 +47,9 @@ export const circOut = (t: number) => Math.sin(Math.acos(1.0 - t)); export const circInOut = (t: number) => 0.5 * (t >= 0.5 ? 2.0 - Math.sin(Math.acos(1.0 - 2.0 * (1.0 - t))) : Math.sin(Math.acos(1.0 - 2.0 * t))); export const cubicBezier = (x1: number, y1: number, x2: number, y2: number) => { - dev$assert( - x1 >= 0 && x1 <= 1 && x2 >= 0 && x2 <= 1, - `CubicBezier x1 & x2 values must be { 0 < x < 1 }, got { x1 : ${x1}, x2: ${x2} }` - ); + if (!(x1 >= 0 && x1 <= 1 && x2 >= 0 && x2 <= 1)) { + throw new Error(`CubicBezier x1 & x2 values must be { 0 < x < 1 }, got { x1 : ${x1}, x2: ${x2} }`); + } const ax = 1.0 - (x2 = 3.0 * (x2 - x1) - (x1 = 3.0 * x1)) - x1, ay = 1.0 - (y2 = 3.0 * (y2 - y1) - (y1 = 3.0 * y1)) - y1; let i = 0, diff --git a/src/runtime/environment/index.ts b/src/runtime/environment/index.ts index 747a496de3..04e72a1f2b 100644 --- a/src/runtime/environment/index.ts +++ b/src/runtime/environment/index.ts @@ -20,7 +20,7 @@ export const resolved_promise = Promise.resolve(); export let now = /*#__PURE__*/ is_browser ? performance.now.bind(performance) : Date.now.bind(Date); export let raf = /*#__PURE__*/ __TEST__ ? () => {} : is_browser ? requestAnimationFrame : noop; export let framerate = 1000 / 60; -raf((t1) => { +/*#__PURE__*/ raf((t1) => { raf((d) => { const f24 = 1000 / 24, f144 = 1000 / 144; diff --git a/src/runtime/internal/animations.ts b/src/runtime/internal/animations.ts index adc4cc0443..d7322db3a6 100644 --- a/src/runtime/internal/animations.ts +++ b/src/runtime/internal/animations.ts @@ -11,7 +11,7 @@ export interface AnimationConfig { type AnimationFn = (node: Element, { from, to }: { from: DOMRect; to: DOMRect }, params: any) => AnimationConfig; -export const run_animation = Function.prototype.call.bind(function run_animation( +export const run_animation = /*#__PURE__*/ Function.prototype.call.bind(function run_animation( this: HTMLElement, from: DOMRect, fn: AnimationFn, @@ -31,7 +31,7 @@ export const run_animation = Function.prototype.call.bind(function run_animation ); }); -export const fix_position = Function.prototype.call.bind(function fix_position( +export const fix_position = /*#__PURE__*/ Function.prototype.call.bind(function fix_position( this: HTMLElement, { left, top }: DOMRect ) { diff --git a/src/runtime/internal/dev.legacy.ts b/src/runtime/internal/dev.legacy.ts deleted file mode 100644 index 5626e7a45b..0000000000 --- a/src/runtime/internal/dev.legacy.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { custom_event, append, insert, detach, listen, attr } from './dom'; -import { now } from 'svelte/environment'; -let inited; -export function add_location_dev$legacy(element, file, line, column, char) { - element.__svelte_meta = { - loc: { file, line, column, char }, - }; -} -export function dispatch_dev$legacy(type: string, detail?: T) { - if (!inited && `__SVELTE_DEVTOOLS_GLOBAL_HOOK__` in window) { - inited = true; - throw new Error(`You must specify the version`); - } - document.dispatchEvent(custom_event(type, { version: __VERSION__, ...detail })); -} - -export function append_dev$legacy(target: Node, node: Node) { - dispatch_dev$legacy('SvelteDOMInsert', { target, node }); - append(target, node); -} - -export function insert_dev$legacy(target: Node, node: Node, anchor?: Node) { - dispatch_dev$legacy('SvelteDOMInsert', { target, node, anchor }); - insert(target, node, anchor); -} - -export function detach_dev$legacy(node: Node) { - dispatch_dev$legacy('SvelteDOMRemove', { node }); - detach(node); -} - -export function detach_between_dev$legacy(before: Node, after: Node) { - while (before.nextSibling && before.nextSibling !== after) { - detach_dev$legacy(before.nextSibling); - } -} - -export function detach_before_dev$legacy(after: Node) { - while (after.previousSibling) { - detach_dev$legacy(after.previousSibling); - } -} - -export function detach_after_dev$legacy(before: Node) { - while (before.nextSibling) { - detach_dev$legacy(before.nextSibling); - } -} - -export function listen_dev$legacy( - node: Node, - event: string, - handler: EventListenerOrEventListenerObject, - options?: boolean | AddEventListenerOptions | EventListenerOptions, - has_prevent_default?: boolean, - has_stop_propagation?: boolean -) { - const modifiers = options === true ? ['capture'] : options ? Array.from(Object.keys(options)) : []; - if (has_prevent_default) modifiers.push('preventDefault'); - if (has_stop_propagation) modifiers.push('stopPropagation'); - - dispatch_dev$legacy('SvelteDOMAddEventListener', { node, event, handler, modifiers }); - - const dispose = listen(node, event, handler, options); - return () => { - dispatch_dev$legacy('SvelteDOMRemoveEventListener', { node, event, handler, modifiers }); - dispose(); - }; -} - -export function attr_dev$legacy(node: Element, attribute: string, value?: string) { - attr(node, attribute, value); - - if (value == null) dispatch_dev$legacy('SvelteDOMRemoveAttribute', { node, attribute }); - else dispatch_dev$legacy('SvelteDOMSetAttribute', { node, attribute, value }); -} - -export function prop_dev$legacy(node: Element, property: string, value?: any) { - node[property] = value; - - dispatch_dev$legacy('SvelteDOMSetProperty', { node, property, value }); -} - -export function dataset_dev$legacy(node: HTMLElement, property: string, value?: any) { - node.dataset[property] = value; - - dispatch_dev$legacy('SvelteDOMSetDataset', { node, property, value }); -} - -export function set_data_dev$legacy(text, data) { - data = '' + data; - if (text.data === data) return; - - dispatch_dev$legacy('SvelteDOMSetData', { node: text, data }); - text.data = data; -} -export function loop_guard_dev$legacy(timeout) { - const start = now(); - return () => { - if (now() - start > timeout) { - throw new Error(`Infinite loop detected`); - } - }; -} -export function validate_store_dev$legacy(store, name) { - if (store != null && typeof store.subscribe !== 'function') { - throw new Error(`'${name}' is not a store with a 'subscribe' method`); - } -} diff --git a/src/runtime/internal/dev.tools.ts b/src/runtime/internal/dev.tools.ts deleted file mode 100644 index 58d6da9e49..0000000000 --- a/src/runtime/internal/dev.tools.ts +++ /dev/null @@ -1,147 +0,0 @@ -import { SvelteComponent } from './Component'; - -const dev$context = { - block: null, - component: null, -}; -abstract class Dev$ { - self; - parent_block = dev$context.block; - parent_component = dev$context.component; - constructor(self) { - this.self = self; - } - abstract add(type, payload): void; - abstract subscribers: {}[]; - dispatch(type, payload: any) { - this.add(type, payload); - this.subscribers.forEach((subscriber) => { - if (type in subscriber) subscriber[type](payload); - }); - } - subscribe(subscriber) { - this.subscribers.push(subscriber); - return () => { - const index = this.subscribers.indexOf(subscriber); - if (~index) this.subscribers.splice(index, 1); - }; - } -} -class Dev$Component extends Dev$ { - self: SvelteComponent; - block; - add(type, payload) {} -} -class Dev$Block extends Dev$ { - self; - parent_block; - parent_component; - elements: Dev$Element[] = []; -} -class Dev$Element extends Dev$ { - component; - node; - parent; - children = []; - attributes: {}; - eventListeners: {}; - style: {}; - class: {}; - add(type, payload) {} - subscribers: Dev$ElementSubscriber[] = []; - dispatch(type, payload: any) { - this.add(type, payload); - this.subscribers.forEach((subscriber) => { - if (type in subscriber) subscriber[type](payload); - }); - } - subscribe(subscriber) { - this.subscribers.push(subscriber); - return () => { - const index = this.subscribers.indexOf(subscriber); - if (~index) this.subscribers.splice(index, 1); - }; - } -} -interface Dev$ElementSubscriber { - onMount(payload): void; - onUnmount(payload): void; - setAttribute(payload): void; - removeAttribute(payload): void; - addEventListener(payload): void; - removeEventListener(payload): void; - addClass(payload): void; - removeClass(payload): void; - addStyle(payload): void; - removeStyle(payload): void; -} - -const dev$dispatch = - __DEV__ && - !__TEST__ && - typeof window !== 'undefined' && - (function dev$create_hook() { - const subscribers = []; - const rootComponents = []; - const hook = { - version: __VERSION__, - has_subscribers: false, - subscribe(listener) { - this.has_subscribers = true; - subscribers.push(listener); - if (rootComponents.length) rootComponents.forEach((component) => listener.addRootComponent(component)); - else listener.ping(`init-no-components`); - return () => { - const index = subscribers.indexOf(listener); - if (~index) { - subscribers.splice(index, 1); - this.has_subscribers = !!subscribers.length; - return true; - } - return false; - }; - }, - }; - Object.defineProperty(window, `__SVELTE_DEVTOOLS_GLOBAL_HOOK__`, { - enumerable: false, - get() { - return hook; - }, - }); - return function update(target_type, event_type, ...values) { - if (!hook.has_subscribers) return; - subscribers.forEach((listener) => { - if (target_type in listener && event_type in listener[target_type]) { - listener[target_type][event_type](...values); - } - }); - }; - })(); - -export function dev$element(element: Element | Node | EventTarget, event: keyof ElementEventsMap, payload?: any) { - if (__DEV__) { - dev$dispatch(`element`, event, element, payload); - } -} -export function dev$block(event: keyof BlockEventsMap, payload) {} -export function dev$assert(truthy: any, else_throw: string) { - if (__DEV__ && !truthy) { - throw new Error(else_throw); - } -} - -interface ElementEventsMap { - onMount; - onDestroy; - setAttribute; - removeAttribute; - addEventListener; - removeEventListener; - addClass; - removeClass; -} -interface BlockEventsMap { - 'create'; - 'claim'; - 'claim.failed'; -} diff --git a/src/runtime/internal/dev.ts b/src/runtime/internal/dev.ts new file mode 100644 index 0000000000..b03672a762 --- /dev/null +++ b/src/runtime/internal/dev.ts @@ -0,0 +1,158 @@ +import { custom_event, append, insert, detach, listen, attr } from './dom'; +import { now, has_Symbol } from 'svelte/environment'; +import { SvelteComponent } from './Component'; + +export function add_location_dev(element, file, line, column, char) { + element.__svelte_meta = { + loc: { file, line, column, char }, + }; +} +export function dispatch_dev(type: string, detail?: T) { + document.dispatchEvent(custom_event(type, { version: __VERSION__, ...detail })); +} + +export function append_dev(target: Node, node: Node) { + dispatch_dev('SvelteDOMInsert', { target, node }); + append(target, node); +} + +export function insert_dev(target: Node, node: Node, anchor?: Node) { + dispatch_dev('SvelteDOMInsert', { target, node, anchor }); + insert(target, node, anchor); +} + +export function detach_dev(node: Node) { + dispatch_dev('SvelteDOMRemove', { node }); + detach(node); +} + +export function detach_between_dev(before: Node, after: Node) { + while (before.nextSibling && before.nextSibling !== after) { + detach_dev(before.nextSibling); + } +} + +export function detach_before_dev(after: Node) { + while (after.previousSibling) { + detach_dev(after.previousSibling); + } +} + +export function detach_after_dev(before: Node) { + while (before.nextSibling) { + detach_dev(before.nextSibling); + } +} + +export function listen_dev( + node: Node, + event: string, + handler: EventListenerOrEventListenerObject, + options?: boolean | AddEventListenerOptions | EventListenerOptions, + has_prevent_default?: boolean, + has_stop_propagation?: boolean +) { + const modifiers = options === true ? ['capture'] : options ? Array.from(Object.keys(options)) : []; + if (has_prevent_default) modifiers.push('preventDefault'); + if (has_stop_propagation) modifiers.push('stopPropagation'); + + dispatch_dev('SvelteDOMAddEventListener', { node, event, handler, modifiers }); + + const dispose = listen(node, event, handler, options); + return () => { + dispatch_dev('SvelteDOMRemoveEventListener', { node, event, handler, modifiers }); + dispose(); + }; +} + +export function attr_dev(node: Element, attribute: string, value?: string) { + attr(node, attribute, value); + + if (value == null) dispatch_dev('SvelteDOMRemoveAttribute', { node, attribute }); + else dispatch_dev('SvelteDOMSetAttribute', { node, attribute, value }); +} + +export function prop_dev(node: Element, property: string, value?: any) { + node[property] = value; + + dispatch_dev('SvelteDOMSetProperty', { node, property, value }); +} + +export function dataset_dev(node: HTMLElement, property: string, value?: any) { + node.dataset[property] = value; + + dispatch_dev('SvelteDOMSetDataset', { node, property, value }); +} + +export function set_data_dev(text, data) { + data = '' + data; + if (text.data === data) return; + + dispatch_dev('SvelteDOMSetData', { node: text, data }); + text.data = data; +} +export function loop_guard_dev(timeout) { + const start = now(); + return () => { + if (now() - start > timeout) { + throw new Error(`Infinite loop detected`); + } + }; +} +export function validate_store_dev(store, name) { + if (store != null && typeof store.subscribe !== 'function') { + throw new Error( + `Could not subscribe to $${name}. A valid store is an object with a .subscribe method, consider setting ${name} to null if this is expected.` + ); + } +} +export const is_array_like_dev = (arg) => { + if (typeof arg !== 'string' && typeof arg === 'object' && !('length' in arg)) + throw new Error( + `{#each} only iterates over Array-like Objects.${ + has_Symbol && Symbol.iterator in arg + ? ' Consider using a [...spread] to convert this iterable into an Array instead.' + : '' + }` + ); +}; +export const check_duplicate_keys_dev = (ctx, list, get_context, get_key) => { + const keys = new Set(); + for (let i = 0; i < list.length; i++) { + const key = get_key(get_context(ctx, list, i)); + if (keys.has(key)) { + throw new Error(`Cannot have duplicate keys in a keyed each`); + } + keys.add(key); + } +}; + +type Props = Record; +export interface SvelteComponentDev { + $set(props?: Props): void; + $on(event: string, callback: (event: CustomEvent) => void): () => void; + $destroy(): void; + [accessor: string]: any; +} + +export class SvelteComponentDev extends SvelteComponent { + constructor(options: { + target: Element; + anchor?: Element; + props?: Props; + hydrate?: boolean; + intro?: boolean; + $$inline?: boolean; + }) { + if (!options || (!options.target && !options.$$inline)) throw new Error(`'target' is a required option`); + super(); + } + $destroy() { + super.$destroy(); + this.$destroy = () => { + console.warn(`Component was already destroyed`); // eslint-disable-line no-console + }; + } + $capture_state() {} + $inject_state() {} +} diff --git a/src/runtime/internal/dev.utils.ts b/src/runtime/internal/dev.utils.ts deleted file mode 100644 index aef0d3749e..0000000000 --- a/src/runtime/internal/dev.utils.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { SvelteComponent } from './Component'; -import { now, has_Symbol } from 'svelte/environment'; -import { dev$assert } from './dev.tools'; - -export const dev$is_array_like = (arg) => - dev$assert( - typeof arg === 'string' || (typeof arg === 'object' && 'length' in arg), - `{#each} only iterates over Array-like Objects.${ - has_Symbol && Symbol.iterator in arg - ? ' Consider using a [...spread] to convert this iterable into an Array instead.' - : '' - }` - ); - -export const dev$known_slots = (name, slot, keys) => - Object.keys(slot).forEach((key) => dev$assert(keys.includes(key), `<${name}> received an unexpected slot "${key}".`)); - -export const dev$is_valid_store = (store, name) => - dev$assert( - typeof store === 'object' && (store === null || typeof store.subscribe === 'function'), - `Could not subscribe to $${name}. A valid store is an object with a .subscribe method, consider setting ${name} to null if this is expected.` - ); - -export function dev$loop_guard(loopGuardTimeout) { - const start = now(); - return () => dev$assert(now() - start < loopGuardTimeout, `Infinite loop detected`); -} -type Props = Record; -export interface SvelteComponentDev { - $set(props?: Props): void; - $on(event: string, callback: (event: CustomEvent) => void): () => void; - $destroy(): void; - [accessor: string]: any; -} - -export class SvelteComponentDev extends SvelteComponent { - constructor(options: { - target: Element; - anchor?: Element; - props?: Props; - hydrate?: boolean; - intro?: boolean; - $$inline?: boolean; - }) { - if (!options || (!options.target && !options.$$inline)) throw new Error(`'target' is a required option`); - super(); - } - $destroy() { - super.$destroy(); - this.$destroy = () => { - console.warn(`Component was already destroyed`); // eslint-disable-line no-console - }; - } - $capture_state() {} - $inject_state() {} -} diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts index 37512eb37a..42a352c0b6 100644 --- a/src/runtime/internal/dom.ts +++ b/src/runtime/internal/dom.ts @@ -1,18 +1,14 @@ -import { dev$element, dev$block } from './dev.tools'; import { is_cors } from 'svelte/environment'; export function append(target: Node, node: Node) { - dev$element(node, `onMount`, { target }); target.appendChild(node); } export function insert(target: Node, node: Node, anchor?: Node) { - dev$element(node, `onMount`, { target, anchor }); target.insertBefore(node, anchor || null); } export function detach(node: Node) { - dev$element(node, `onDestroy`); node.parentNode.removeChild(node); } @@ -21,14 +17,11 @@ export function destroy_each(iterations, detaching) { if (iterations[i]) iterations[i].d(detaching); } } -const dev$create = (elem: K) => (dev$block(`create`, elem), elem); export function element(name: K) { - if (__DEV__) return dev$create(document.createElement(name)); return document.createElement(name); } export function element_is(name: K, is: string) { - if (__DEV__) return dev$create(document.createElement(name)); return document.createElement(name, { is }); } export function object_without_properties(obj: T, excluded: K) { @@ -39,12 +32,10 @@ export function object_without_properties(obj: T, exclude } export function svg_element(name: K): SVGElement { - if (__DEV__) return dev$create(document.createElementNS('http://www.w3.org/2000/svg', name)); return document.createElementNS('http://www.w3.org/2000/svg', name); } export function text(data: string) { - if (__DEV__) return dev$create(document.createTextNode(data)); return document.createTextNode(data); } @@ -61,15 +52,6 @@ export function listen( handler: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions | EventListenerOptions ) { - if (__DEV__) { - const reference = { event, handler }; - dev$element(node, `addEventListener`, reference); - node.addEventListener(event, handler, options); - return () => { - dev$element(node, `removeEventListener`, reference); - node.removeEventListener(event, handler, options); - }; - } node.addEventListener(event, handler, options); return () => node.removeEventListener(event, handler, options); } @@ -99,10 +81,8 @@ export function self(fn) { export function attr(node: Element, name: string, value?: any) { if (value == null) { - dev$element(node, `removeAttribute`, { name }); node.removeAttribute(name); } else if (node.getAttribute(name) !== value) { - dev$element(node, `setAttribute`, { name, value }); node.setAttribute(name, value); } } @@ -113,13 +93,10 @@ export function set_attributes(node: HTMLElement, attributes: { [x: string]: any let name; for (name in attributes) { if (attributes[name] == null) { - dev$element(node, `removeAttribute`, { name }); node.removeAttribute(name); } else if (name === 'style') { - dev$element(node, `setAttribute`, { name, value: attributes[name] }); node.style.cssText = attributes[name]; } else if (name === '__value' || (descriptors[name] && descriptors[name].set)) { - dev$element(node, `setAttribute`, { name, value: attributes[name] }); node[name] = attributes[name]; } else { attr(node, name, attributes[name]); @@ -136,7 +113,6 @@ export function set_svg_attributes(node: SVGElement, attributes: { [x: string]: export function set_custom_element_data(node, name, value) { if (name in node) { - dev$element(node, `setAttribute`, { name, value }); node[name] = value; } else { attr(node, name, value); @@ -144,7 +120,6 @@ export function set_custom_element_data(node, name, value) { } export function xlink_attr(node: Element, name, value) { - dev$element(node, `setAttribute`, { name, value }); node.setAttributeNS('http://www.w3.org/1999/xlink', name, value); } @@ -178,20 +153,16 @@ export function claim_element(nodes, name, attributes, is_svg) { if (attributes[(a = n.attributes[j]).name]) j++; else n.removeAttribute(a.name); } - dev$block(`claim`, n); return nodes.splice(i, 1)[0]; } - dev$block(`claim.failed`, name); return is_svg ? svg_element(name) : element(name); } export function claim_text(nodes, data) { for (let i = 0, n; i < nodes.length; i += 1) if ((n = nodes[i]).nodeType === 3) { - dev$block(`claim`, n); return (n.data = '' + data), nodes.splice(i, 1)[0]; } - dev$block(`claim.failed`, 'text'); return text(data); } @@ -202,33 +173,28 @@ export function claim_space(nodes) { export function set_data(text, data) { if (text.data !== (data = '' + data)) { text.data = data; - dev$element(text, `setAttribute`, { name: 'data', value: data }); } } export function set_input_value(input, value) { if (value != null || input.value) { input.value = value; - dev$element(input, `setAttribute`, { name: 'value', value }); } } export function set_input_type(input, type) { try { input.type = type; - dev$element(input, `setAttribute`, { name: 'type', value: type }); } catch (e) {} } export function set_style(node, property, value, is_important?) { - dev$element(node, `setAttribute`, { name: 'style', property, value }); node.style.setProperty(property, value, is_important ? 'important' : ''); } export function select_option(select, value) { for (let i = 0, o; i < select.options.length; i += 1) { if ((o = select.options[i]).__value === value) { - dev$element(o, `setAttribute`, { name: 'selected', value: true }); o.selected = true; return; } @@ -237,13 +203,6 @@ export function select_option(select, value) { export function select_options(select, value) { for (let i = 0, o; i < select.options.length; i += 1) { - if (__DEV__) { - dev$element((o = select.options[i]), `setAttribute`, { - name: 'selected', - value: (o = select.options[i]).selected = ~value.indexOf(o.__value), - }); - continue; - } (o = select.options[i]).selected = ~value.indexOf(o.__value); } } @@ -297,7 +256,6 @@ export function add_resize_listener(node: HTMLElement, fn: () => void) { } export function toggle_class(element, name, toggle) { - dev$element(element, toggle ? 'addClass' : 'removeClass', { name }); element.classList[toggle ? 'add' : 'remove'](name); } diff --git a/src/runtime/internal/index.ts b/src/runtime/internal/index.ts index b154e4cd3d..1708bf3f80 100644 --- a/src/runtime/internal/index.ts +++ b/src/runtime/internal/index.ts @@ -1,9 +1,7 @@ export * from './animations'; export * from './await_block'; export * from './Component'; -export * from './dev.legacy'; -export * from './dev.utils'; -export * from './dev.tools'; +export * from './dev'; export * from './dom'; export * from './keyed_each'; export * from './lifecycle'; @@ -16,5 +14,5 @@ export * from './stores'; export * from './transitions'; export * from './utils'; -// todo; create_module.ts line 24; allow compiler to import non internal +// todo: [create_module.ts line 24] allow compiler to import non internal export * from '../environment/index'; diff --git a/src/runtime/internal/keyed_each.ts b/src/runtime/internal/keyed_each.ts index 4fa0c6b515..3c89c01e4b 100644 --- a/src/runtime/internal/keyed_each.ts +++ b/src/runtime/internal/keyed_each.ts @@ -95,14 +95,3 @@ export const update_keyed_each = ( return new_blocks; }; - -export function validate_each_keys(ctx, list, get_context, get_key) { - const keys = new Set(); - for (let i = 0; i < list.length; i++) { - const key = get_key(get_context(ctx, list, i)); - if (keys.has(key)) { - throw new Error(`Cannot have duplicate keys in a keyed each`); - } - keys.add(key); - } -} diff --git a/src/runtime/internal/lifecycle.ts b/src/runtime/internal/lifecycle.ts index 7c400bef6b..591eea5119 100644 --- a/src/runtime/internal/lifecycle.ts +++ b/src/runtime/internal/lifecycle.ts @@ -1,41 +1,42 @@ import { custom_event } from './dom'; -import { SvelteComponentDev } from './dev.utils'; import { SvelteComponent } from './Component'; -import { dev$assert } from './dev.tools'; - +import { SvelteComponentDev } from './dev'; export let current_component: SvelteComponentDev | SvelteComponent | null; export const set_current_component = (component) => (current_component = component); -const dev$on_init_only = (name: string) => - dev$assert(!!current_component, `${name} cannot be called outside of component initialization`); +const on_init_only = (name: string) => { + if (!current_component) { + throw new Error(`${name} cannot be called outside of component initialization`); + } +}; export function get_current_component() { return current_component; } export function beforeUpdate(fn) { - dev$on_init_only(`beforeUpdate`); + on_init_only(`beforeUpdate`); return current_component.$$.before_update.push(fn); } export function onMount(fn) { - dev$on_init_only(`onMount`); + on_init_only(`onMount`); return current_component.$$.on_mount.push(fn); } export function afterUpdate(fn) { - dev$on_init_only(`afterUpdate`); + on_init_only(`afterUpdate`); return current_component.$$.after_update.push(fn); } export function onDestroy(fn) { - dev$on_init_only(`onDestroy`); + on_init_only(`onDestroy`); return current_component.$$.on_destroy.push(fn); } // todo : deprecate export function createEventDispatcher() { - dev$on_init_only(`createEventDispatcher`); + on_init_only(`createEventDispatcher`); const component = current_component; return (type: string, detail?: any) => { const callbacks = component.$$.callbacks[type]; @@ -50,12 +51,12 @@ export function createEventDispatcher() { } export function setContext(key, context) { - dev$on_init_only(`setContext`); + on_init_only(`setContext`); current_component.$$.context.set(key, context); } export function getContext(key) { - dev$on_init_only(`getContext`); + on_init_only(`getContext`); return current_component.$$.context.get(key); } diff --git a/src/runtime/internal/scheduler.ts b/src/runtime/internal/scheduler.ts index 5be0e527b7..5bf98aa8c8 100644 --- a/src/runtime/internal/scheduler.ts +++ b/src/runtime/internal/scheduler.ts @@ -13,8 +13,8 @@ const measure_callbacks = []; const flush_callbacks = []; // todo : remove add_flush_callback -export const add_flush_callback = Array.prototype.push.bind(flush_callbacks); -export const add_measure_callback = Array.prototype.push.bind(measure_callbacks); +export const add_flush_callback = /*#__PURE__*/ Array.prototype.push.bind(flush_callbacks); +export const add_measure_callback = /*#__PURE__*/ Array.prototype.push.bind(measure_callbacks); const seen_render_callbacks = new Set(); export const add_render_callback = (fn) => { diff --git a/src/runtime/internal/style_manager.ts b/src/runtime/internal/style_manager.ts index 14affaa408..7ab324b94e 100644 --- a/src/runtime/internal/style_manager.ts +++ b/src/runtime/internal/style_manager.ts @@ -7,7 +7,7 @@ const document_uid = new Map(); const document_stylesheets = new Map(); const current_rules = new Set(); -export const animate_css = Function.prototype.call.bind(function animate_css( +export const animate_css = /*#__PURE__*/ Function.prototype.call.bind(function animate_css( this: HTMLElement, css: (t: number) => string, duration: number, diff --git a/src/runtime/internal/transitions.ts b/src/runtime/internal/transitions.ts index 64104ecf70..4098b723bc 100644 --- a/src/runtime/internal/transitions.ts +++ b/src/runtime/internal/transitions.ts @@ -48,7 +48,6 @@ export const group_transition_out = (fn) => { transition_group = transition_group.p; }; -/* todo: deprecate */ const swap = (fn, rx) => fn.length === 1 ? (rx & tx.intro ? fn : (t) => fn(1 - t)) : rx & tx.intro ? (t) => fn(t, 1 - t) : (t) => fn(1 - t, t); @@ -69,7 +68,7 @@ export enum tx { bidirectional_outro = 6, animation = 8, } -export const run_transition = Function.prototype.call.bind(function transition( +export const run_transition = /*#__PURE__*/ Function.prototype.call.bind(function transition( this: HTMLElement, fn: TransitionFn, rx: tx, @@ -94,7 +93,7 @@ export const run_transition = Function.prototype.call.bind(function transition( add_measure_callback(() => { if (null === (config = fn(this, params))) return noop; return (t) => { - if (false === running) return void (running = false); + if (false === running) return; if ('then' in config) return void config.then(stop); let { delay = 0, duration = 300, easing, tick, css, strategy = 'reverse' }: TransitionConfig = @@ -160,7 +159,7 @@ export const run_transition = Function.prototype.call.bind(function transition( }); const running_bidi: Map = new Map(); -export const run_bidirectional_transition = Function.prototype.call.bind(function bidirectional( +export const run_bidirectional_transition = /*#__PURE__*/ Function.prototype.call.bind(function bidirectional( this: HTMLElement, fn: TransitionFn, rx: tx.intro | tx.outro, diff --git a/src/runtime/motion/index.ts b/src/runtime/motion/index.ts index 57267c4a63..3bea3d8c0a 100644 --- a/src/runtime/motion/index.ts +++ b/src/runtime/motion/index.ts @@ -73,7 +73,7 @@ export function spring( }; return obj; } -export function tween( +export function tweened( value: T, { delay: default_delay = 0,