chore: explicit reexports (#10970)

* explicit re-exports

* explicit re-exports

* regenerate types
pull/10974/head
Rich Harris 5 months ago committed by GitHub
parent 8a758d86ee
commit d49e2aeb15
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -137,7 +137,9 @@
"knip": {
"entry": [
"src/*/index.js",
"src/*/public.d.ts"
"src/index-client.ts",
"src/index-server.ts",
"src/index.d.ts"
],
"project": [
"src/**"

@ -1,13 +0,0 @@
/**
* Pushes all `items` into `array` using `push`, therefore mutating the array.
* We do this for memory and perf reasons, and because `array.push(...items)` would
* run into a "max call stack size exceeded" error with too many items (~65k).
* @template T
* @param {T[]} array
* @param {T[]} items
*/
export function push_array(array, items) {
for (let i = 0; i < items.length; i++) {
array.push(items[i]);
}
}

@ -275,7 +275,7 @@ export function client_component(source, analysis, options) {
const setter = b.set(key, [
b.stmt(b.call(b.id(name), b.id('$$value'))),
b.stmt(b.call('$.flushSync'))
b.stmt(b.call('$.flush_sync'))
]);
if (analysis.runes && binding.initial) {

@ -412,7 +412,7 @@ export function merge_with_preprocessor_map(result, options, source_name) {
* @param {string} from
* @param {string} to
*/
export function get_relative_path(from, to) {
function get_relative_path(from, to) {
// Don't use node's utils here to ensure the compiler is usable in a browser environment
const from_parts = from.split(/[/\\]/);
const to_parts = to.split(/[/\\]/);

@ -95,7 +95,6 @@ export const DOMBooleanAttributes = [
];
export const namespace_svg = 'http://www.w3.org/2000/svg';
export const namespace_html = 'http://www.w3.org/1999/xhtml';
// while `input` is also an interactive element, it is never moved by the browser, so we don't need to check for it
export const interactive_elements = new Set([

@ -1,4 +1,4 @@
import { current_component_context, untrack } from './internal/client/runtime.js';
import { current_component_context, flush_sync, untrack } from './internal/client/runtime.js';
import { is_array } from './internal/client/utils.js';
import { user_effect } from './internal/client/index.js';
@ -167,19 +167,24 @@ function init_update_callbacks(context) {
return (context.u ??= { a: [], b: [], m: [] });
}
// TODO bring implementations in here
// (except probably untrack — do we want to expose that, if there's also a rune?)
/**
* Synchronously flushes any pending state changes and those that result from it.
* @param {() => void} [fn]
* @returns {void}
*/
export function flushSync(fn) {
flush_sync(fn);
}
export { unstate } from './internal/client/proxy.js';
export { hydrate, mount, unmount } from './internal/client/render.js';
export {
flushSync,
mount,
hydrate,
tick,
unmount,
untrack,
unstate,
createRoot,
hasContext,
getContext,
getAllContexts,
setContext
} from './internal/client/index.js';
hasContext,
setContext,
tick,
untrack
} from './internal/client/runtime.js';

@ -11,8 +11,7 @@ export {
setContext,
tick,
unmount,
untrack,
createRoot
untrack
} from './index-client.js';
/** @returns {void} */

@ -9,7 +9,7 @@ const boundaries = {};
const chrome_pattern = /at (?:.+ \()?(.+):(\d+):(\d+)\)?$/;
const firefox_pattern = /@(.+):(\d+):(\d+)$/;
export function get_stack() {
function get_stack() {
const stack = new Error().stack;
if (!stack) return null;

@ -1,7 +1,7 @@
import { is_promise } from '../../../common.js';
import {
current_component_context,
flushSync,
flush_sync,
set_current_component_context,
set_current_effect,
set_current_reaction
@ -48,7 +48,7 @@ export function await_block(anchor, get_input, pending_fn, then_fn, catch_fn) {
// without this, the DOM does not update until two ticks after the promise,
// resolves which is unexpected behaviour (and somewhat irksome to test)
flushSync();
flush_sync();
return e;
}

@ -273,7 +273,7 @@ function split_srcset(srcset) {
* @param {string | undefined | null} srcset
* @returns {boolean}
*/
export function srcset_url_equal(element, srcset) {
function srcset_url_equal(element, srcset) {
var element_urls = split_srcset(element.srcset);
var urls = split_srcset(srcset ?? '');

@ -1,7 +1,7 @@
import { createClassComponent } from '../../../../legacy/legacy-client.js';
import { destroy_effect, render_effect } from '../../reactivity/effects.js';
import { append } from '../template.js';
import { define_property } from '../../utils.js';
import { define_property, object_keys } from '../../utils.js';
/**
* @typedef {Object} CustomElementPropDefinition
@ -145,7 +145,7 @@ if (typeof HTMLElement === 'function') {
// Reflect component props as attributes
this.$$me = render_effect(() => {
this.$$r = true;
for (const key of Object.keys(this.$$c)) {
for (const key of object_keys(this.$$c)) {
if (!this.$$p_d[key]?.reflect) continue;
this.$$d[key] = this.$$c[key];
const attribute_value = get_custom_element_value(
@ -205,7 +205,7 @@ if (typeof HTMLElement === 'function') {
*/
$$g_p(attribute_name) {
return (
Object.keys(this.$$p_d).find(
object_keys(this.$$p_d).find(
(key) =>
this.$$p_d[key].attribute === attribute_name ||
(!this.$$p_d[key].attribute && key.toLowerCase() === attribute_name)
@ -290,12 +290,12 @@ export function create_custom_element(
this.$$p_d = props_definition;
}
static get observedAttributes() {
return Object.keys(props_definition).map((key) =>
return object_keys(props_definition).map((key) =>
(props_definition[key].attribute || key).toLowerCase()
);
}
};
Object.keys(props_definition).forEach((prop) => {
object_keys(props_definition).forEach((prop) => {
define_property(Class.prototype, prop, {
get() {
return this.$$c && prop in this.$$c ? this.$$c[prop] : this.$$d[prop];

@ -22,18 +22,6 @@ function process_raf_task() {
run_all(tasks);
}
/**
* @param {() => void} fn
* @returns {void}
*/
export function schedule_raf_task(fn) {
if (!is_raf_queued) {
is_raf_queued = true;
requestAnimationFrame(process_raf_task);
}
current_raf_tasks.push(fn);
}
/**
* Synchronously run any queued tasks.
*/

@ -1,7 +1,106 @@
export { add_owner, mark_module_start, mark_module_end } from './dev/ownership.js';
export { await_block as await } from './dom/blocks/await.js';
export { if_block as if } from './dom/blocks/if.js';
export { key_block as key } from './dom/blocks/key.js';
export { css_props } from './dom/blocks/css-props.js';
export { each_keyed, each_indexed } from './dom/blocks/each.js';
export { html } from './dom/blocks/html.js';
export { snippet } from './dom/blocks/snippet.js';
export { component } from './dom/blocks/svelte-component.js';
export { element } from './dom/blocks/svelte-element.js';
export { head } from './dom/blocks/svelte-head.js';
export { action } from './dom/elements/actions.js';
export {
remove_input_attr_defaults,
set_attribute,
set_attributes,
set_custom_element_data,
set_dynamic_element_attributes,
set_xlink_attribute
} from './dom/elements/attributes.js';
export { set_class, set_svg_class, toggle_class } from './dom/elements/class.js';
export { event, delegate } from './dom/elements/events.js';
export { autofocus, remove_textarea_child } from './dom/elements/misc.js';
export { set_style } from './dom/elements/style.js';
export { animation, transition } from './dom/elements/transitions.js';
export { bind_checked, bind_files, bind_group, bind_value } from './dom/elements/bindings/input.js';
export {
bind_buffered,
bind_current_time,
bind_ended,
bind_muted,
bind_paused,
bind_playback_rate,
bind_played,
bind_ready_state,
bind_seekable,
bind_seeking,
bind_volume
} from './dom/elements/bindings/media.js';
export { bind_online } from './dom/elements/bindings/navigator.js';
export { bind_prop } from './dom/elements/bindings/props.js';
export { bind_select_value, init_select, select_option } from './dom/elements/bindings/select.js';
export { bind_element_size, bind_resize_observer } from './dom/elements/bindings/size.js';
export { bind_this } from './dom/elements/bindings/this.js';
export { bind_content_editable, bind_property } from './dom/elements/bindings/universal.js';
export { bind_window_scroll, bind_window_size } from './dom/elements/bindings/window.js';
export {
once,
preventDefault,
self,
stopImmediatePropagation,
stopPropagation,
trusted
} from './dom/legacy/event-modifiers.js';
export { init } from './dom/legacy/lifecycle.js';
export {
add_legacy_event_listener,
bubble_event,
reactive_import,
update_legacy_props
} from './dom/legacy/misc.js';
export {
append,
comment,
svg_template,
svg_template_with_script,
template,
template_with_script,
text
} from './dom/template.js';
export { derived, derived_safe_equal } from './reactivity/deriveds.js';
export {
effect_active,
effect_root,
legacy_pre_effect,
legacy_pre_effect_reset,
render_effect,
user_effect,
user_pre_effect
} from './reactivity/effects.js';
export { mutable_source, mutate, source, set } from './reactivity/sources.js';
export {
prop,
rest_props,
spread_props,
update_pre_prop,
update_prop
} from './reactivity/props.js';
export {
invalidate_store,
mutate_store,
store_get,
store_set,
store_unsub,
unsubscribe_on_destroy,
update_pre_store,
update_store
} from './reactivity/store.js';
export { append_styles, sanitize_slots, set_text, slot, stringify } from './render.js';
export {
get,
invalidate_inner_signals,
flushSync,
flush_sync,
tick,
untrack,
update,
@ -20,45 +119,17 @@ export {
setContext,
hasContext
} from './runtime.js';
export * from './dev/ownership.js';
export { await_block as await } from './dom/blocks/await.js';
export { if_block as if } from './dom/blocks/if.js';
export { key_block as key } from './dom/blocks/key.js';
export * from './dom/blocks/css-props.js';
export * from './dom/blocks/each.js';
export * from './dom/blocks/html.js';
export * from './dom/blocks/snippet.js';
export * from './dom/blocks/svelte-component.js';
export * from './dom/blocks/svelte-element.js';
export * from './dom/blocks/svelte-head.js';
export * from './dom/elements/actions.js';
export * from './dom/elements/attributes.js';
export * from './dom/elements/class.js';
export * from './dom/elements/events.js';
export * from './dom/elements/misc.js';
export * from './dom/elements/style.js';
export * from './dom/elements/transitions.js';
export * from './dom/elements/bindings/input.js';
export * from './dom/elements/bindings/media.js';
export * from './dom/elements/bindings/navigator.js';
export * from './dom/elements/bindings/props.js';
export * from './dom/elements/bindings/select.js';
export * from './dom/elements/bindings/size.js';
export * from './dom/elements/bindings/this.js';
export * from './dom/elements/bindings/universal.js';
export * from './dom/elements/bindings/window.js';
export * from './dom/legacy/event-modifiers.js';
export * from './dom/legacy/lifecycle.js';
export * from './dom/legacy/misc.js';
export * from './dom/template.js';
export * from './reactivity/deriveds.js';
export * from './reactivity/effects.js';
export * from './reactivity/sources.js';
export * from './reactivity/equality.js';
export * from './reactivity/props.js';
export * from './reactivity/store.js';
export * from './render.js';
export * from './validate.js';
export {
add_snippet_symbol,
validate_component,
validate_dynamic_component,
validate_dynamic_element_tag,
validate_each_keys,
validate_prop_bindings,
validate_snippet,
validate_store,
validate_void_dynamic_element
} from './validate.js';
export { raf } from './timing.js';
export { proxy, unstate } from './proxy.js';
export { create_custom_element } from './dom/elements/custom-element.js';

@ -9,7 +9,7 @@ import { get_descriptor, is_function } from '../utils.js';
import { mutable_source, set } from './sources.js';
import { derived } from './deriveds.js';
import { get, inspect_fn, is_signals_recorded, untrack } from '../runtime.js';
import { safe_equals, safe_not_equal } from './equality.js';
import { safe_equals } from './equality.js';
/**
* @param {((value?: number) => number)} fn

@ -6,7 +6,7 @@ import {
current_effect,
current_untracked_writes,
current_untracking,
flushSync,
flush_sync,
get,
is_batching_effect,
is_runes,
@ -62,16 +62,6 @@ export function mutable_source(initial_value) {
return s;
}
/**
* @template V
* @param {import('#client').Source<V>} signal
* @param {V} value
* @returns {void}
*/
export function set_sync(signal, value) {
flushSync(() => set(signal, value));
}
/**
* @template V
* @param {import('#client').Value<V>} source

@ -81,16 +81,6 @@ export function stringify(value) {
return typeof value === 'string' ? value : value == null ? '' : value + '';
}
// TODO 5.0 remove this
/**
* @deprecated Use `mount` or `hydrate` instead
*/
export function createRoot() {
throw new Error(
'`createRoot` has been removed. Use `mount` or `hydrate` instead. See the updated docs for more info: https://svelte-5-preview.vercel.app/docs/breaking-changes#components-are-no-longer-classes'
);
}
/**
* Mounts a component to the given target and returns the exports and potentially the props (if compiled with `accessors: true`) of the component
*

@ -628,15 +628,6 @@ export function flush_local_render_effects(effect) {
flush_queued_effects(render_effects);
}
/**
* Synchronously flushes any pending state changes and those that result from it.
* @param {() => void} [fn]
* @returns {void}
*/
export function flushSync(fn) {
flush_sync(fn);
}
/**
* Internal version of `flushSync` with the option to not flush previous effects.
* Returns the result of the passed function, if given.
@ -683,9 +674,9 @@ export function flush_sync(fn, flush_previous = true) {
*/
export async function tick() {
await Promise.resolve();
// By calling flushSync we guarantee that any pending state changes are applied after one tick.
// By calling flush_sync we guarantee that any pending state changes are applied after one tick.
// TODO look into whether we can make flushing subsequent updates synchronously in the future.
flushSync();
flush_sync();
}
/**

@ -17,7 +17,6 @@ export var get_prototype_of = Object.getPrototypeOf;
var map_prototype = Map.prototype;
var map_set_method = map_prototype.set;
var map_get_method = map_prototype.get;
var map_delete_method = map_prototype.delete;
/**
* @template K
@ -30,16 +29,6 @@ export function map_set(map, key, value) {
map_set_method.call(map, key, value);
}
/**
* @template K
* @template V
* @param {Map<K, V>} map
* @param {K} key
*/
export function map_delete(map, key) {
map_delete_method.call(map, key);
}
/**
* @template K
* @template V

@ -1,5 +1,6 @@
import { proxy } from '../internal/client/proxy.js';
import { hydrate, mount, unmount } from '../internal/client/render.js';
import { define_property } from '../internal/client/utils.js';
import * as $ from '../internal/client/index.js';
/**
* Takes the same options as a Svelte 4 component and the component function and returns a Svelte 4 compatible component.
@ -69,8 +70,8 @@ class Svelte4Component {
// Using proxy state here isn't completely mirroring the Svelte 4 behavior, because mutations to a property
// cause fine-grained updates to only the places where that property is used, and not the entire property.
// Reactive statements and actions (the things where this matters) are handling this properly regardless, so it should be fine in practise.
const props = $.proxy({ ...(options.props || {}), $$events: this.#events }, false);
this.#instance = (options.hydrate ? $.hydrate : $.mount)(options.component, {
const props = proxy({ ...(options.props || {}), $$events: this.#events }, false);
this.#instance = (options.hydrate ? hydrate : mount)(options.component, {
target: options.target,
props,
context: options.context,
@ -96,7 +97,7 @@ class Svelte4Component {
Object.assign(props, next);
};
this.#instance.$destroy = () => {
$.unmount(this.#instance);
unmount(this.#instance);
};
}

@ -3,6 +3,7 @@ import { setImmediate } from 'node:timers/promises';
import glob from 'tiny-glob/sync.js';
import * as $ from 'svelte/internal/client';
import { createClassComponent } from 'svelte/legacy';
import { flushSync } from 'svelte';
import { render } from 'svelte/server';
import { afterAll, assert, beforeAll } from 'vitest';
import { compile_directory } from '../helpers.js';
@ -283,7 +284,7 @@ async function run_test_variant(
}
if (config.html) {
$.flushSync();
flushSync();
assert_html_equal_with_options(target.innerHTML, config.html, {
preserveComments:
config.withoutNormalizeHtml === 'only-strip-comments' ? false : undefined,
@ -293,7 +294,7 @@ async function run_test_variant(
try {
if (config.test) {
$.flushSync();
flushSync();
await config.test({
// @ts-expect-error TS doesn't get it
assert: {

@ -1,4 +1,5 @@
import { describe, assert, it } from 'vitest';
import { flushSync } from '../../src/index-client';
import * as $ from '../../src/internal/client/runtime';
import {
effect,
@ -47,8 +48,8 @@ describe('signals', () => {
});
return () => {
$.flushSync(() => set(count, 1));
$.flushSync(() => set(count, 2));
flushSync(() => set(count, 1));
flushSync(() => set(count, 2));
assert.deepEqual(log, ['0:0', '1:2', '2:4']);
};
@ -68,8 +69,8 @@ describe('signals', () => {
});
return () => {
$.flushSync(() => set(count, 1));
$.flushSync(() => set(count, 2));
flushSync(() => set(count, 1));
flushSync(() => set(count, 2));
assert.deepEqual(log, ['A:0:0', 'B:0', 'A:1:2', 'B:2', 'A:2:4', 'B:4']);
};
@ -89,8 +90,8 @@ describe('signals', () => {
});
return () => {
$.flushSync(() => set(count, 1));
$.flushSync(() => set(count, 2));
flushSync(() => set(count, 1));
flushSync(() => set(count, 2));
assert.deepEqual(log, ['A:0', 'B:0:0', 'A:2', 'B:1:2', 'A:4', 'B:2:4']);
};
@ -107,8 +108,8 @@ describe('signals', () => {
});
return () => {
$.flushSync(() => set(count, 1));
$.flushSync(() => set(count, 2));
flushSync(() => set(count, 1));
flushSync(() => set(count, 2));
assert.deepEqual(log, [0, 2, 4]);
};
@ -126,8 +127,8 @@ describe('signals', () => {
});
return () => {
$.flushSync(() => set(count, 1));
$.flushSync(() => set(count, 2));
flushSync(() => set(count, 1));
flushSync(() => set(count, 2));
assert.deepEqual(log, [0, 4, 8]);
};
@ -158,18 +159,18 @@ describe('signals', () => {
});
return () => {
$.flushSync();
flushSync();
let i = 2;
while (--i) {
res.length = 0;
set(B, 1);
set(A, 1 + i * 2);
$.flushSync();
flushSync();
set(A, 2 + i * 2);
set(B, 2);
$.flushSync();
flushSync();
assert.equal(res.length, 4);
assert.deepEqual(res, [3198, 1601, 3195, 1598]);
@ -191,13 +192,13 @@ describe('signals', () => {
});
return () => {
$.flushSync(() => set(count, 1));
flushSync(() => set(count, 1));
// Ensure we're not leaking consumers
assert.deepEqual(count.reactions?.length, 1);
$.flushSync(() => set(count, 2));
flushSync(() => set(count, 2));
// Ensure we're not leaking consumers
assert.deepEqual(count.reactions?.length, 1);
$.flushSync(() => set(count, 3));
flushSync(() => set(count, 3));
// Ensure we're not leaking consumers
assert.deepEqual(count.reactions?.length, 1);
assert.deepEqual(log, [0, 1, 2, 3]);
@ -220,11 +221,11 @@ describe('signals', () => {
$.get(c);
$.flushSync(() => set(a, 1));
flushSync(() => set(a, 1));
$.get(c);
$.flushSync(() => set(b, 1));
flushSync(() => set(b, 1));
$.get(c);
@ -255,11 +256,11 @@ describe('signals', () => {
});
return () => {
$.flushSync(() => set(count, 1));
$.flushSync(() => set(count, 2));
$.flushSync(() => set(count, 3));
$.flushSync(() => set(count, 4));
$.flushSync(() => set(count, 0));
flushSync(() => set(count, 1));
flushSync(() => set(count, 2));
flushSync(() => set(count, 3));
flushSync(() => set(count, 4));
flushSync(() => set(count, 0));
// Ensure we're not leaking consumers
assert.deepEqual(count.reactions?.length, 1);
assert.deepEqual(log, [0, 2, 'limit', 0]);
@ -285,7 +286,7 @@ describe('signals', () => {
});
return () => {
$.flushSync();
flushSync();
assert.deepEqual(log, [[], []]);
};
});
@ -307,7 +308,7 @@ describe('signals', () => {
});
return () => {
$.flushSync();
flushSync();
assert.deepEqual(log, [[{}], [{}]]);
};
});
@ -324,7 +325,7 @@ describe('signals', () => {
return () => {
let errored = false;
try {
$.flushSync();
flushSync();
} catch (e: any) {
assert.include(e.message, 'ERR_SVELTE_TOO_MANY_UPDATES');
errored = true;
@ -345,7 +346,7 @@ describe('signals', () => {
return () => {
let errored = false;
try {
$.flushSync();
flushSync();
} catch (e: any) {
assert.include(e.message, 'ERR_SVELTE_TOO_MANY_UPDATES');
errored = true;
@ -370,8 +371,8 @@ describe('signals', () => {
});
return () => {
$.flushSync(() => set(count, 1));
$.flushSync(() => set(count, 2));
flushSync(() => set(count, 1));
flushSync(() => set(count, 2));
assert.equal(teardown, 1);
};
});

@ -287,12 +287,13 @@ declare module 'svelte' {
* @deprecated Use `$effect` instead see https://svelte-5-preview.vercel.app/docs/deprecations#beforeupdate-and-afterupdate
* */
export function afterUpdate(fn: () => void): void;
/**
* Synchronously flushes any pending state changes and those that result from it.
* */
export function flushSync(fn?: (() => void) | undefined): void;
/** Anything except a function */
type NotFunction<T> = T extends Function ? never : T;
/**
* @deprecated Use `mount` or `hydrate` instead
*/
export function createRoot(): void;
export function unstate<T>(value: T): T;
/**
* Mounts a component to the given target and returns the exports and potentially the props (if compiled with `accessors: true`) of the component
*
@ -320,10 +321,6 @@ declare module 'svelte' {
* Unmounts a component that was previously mounted using `mount` or `hydrate`.
* */
export function unmount(component: Record<string, any>): void;
/**
* Synchronously flushes any pending state changes and those that result from it.
* */
export function flushSync(fn?: (() => void) | undefined): void;
/**
* Returns a promise that resolves once any pending state changes have been applied.
* */
@ -366,7 +363,6 @@ declare module 'svelte' {
* https://svelte.dev/docs/svelte#getallcontexts
* */
export function getAllContexts<T extends Map<any, any> = Map<any, any>>(): T;
export function unstate<T>(value: T): T;
}
declare module 'svelte/action' {

Loading…
Cancel
Save