@testing-library/svelte-core 1.0.0-next.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Ben Monro <ben.monro@gmail.com> (https://github.com/benmonro)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,173 @@
1
+ # @testing-library/svelte-core
2
+
3
+ Do you want to build your own Svelte testing library? You may want to use our
4
+ rendering core, which abstracts away differences in Svelte versions to provide a
5
+ simple API to render Svelte components into the document and clean them up
6
+ afterwards
7
+
8
+ ## Table of Contents
9
+
10
+ - [Example Usage](#example-usage)
11
+ - [API](#api)
12
+ - [`render`](#render)
13
+ - [`setup`](#setup)
14
+ - [`mount`](#mount)
15
+ - [`cleanup`](#cleanup)
16
+ - [`addCleanupTask`](#addcleanuptask)
17
+ - [`removeCleanupTask`](#removecleanuptask)
18
+ - [Utility types](#utility-types)
19
+
20
+ ## Example Usage
21
+
22
+ ```ts
23
+ import { beforeEach } from 'vitest'
24
+ import * as SvelteCore from '@testing-library/svelte-core'
25
+
26
+ import { bindQueries, type Screen } from './bring-your-own-queries.js'
27
+
28
+ beforeEach(() => {
29
+ SvelteCore.cleanup()
30
+ })
31
+
32
+ export interface RenderResult<
33
+ C extends SvelteCore.Component,
34
+ > extends SvelteCore.RenderResult<C> {
35
+ screen: Screen
36
+ }
37
+
38
+ export const render = <C extends SvelteCore.Component>(
39
+ Component: SvelteCore.ComponentImport<C>,
40
+ options: SvelteCore.ComponentOptions<C>
41
+ ): RenderResult<C> => {
42
+ const renderResult = SvelteCore.render(Component, options)
43
+ const screen = bindQueries(baseElement)
44
+
45
+ return { screen, ...renderResult }
46
+ }
47
+ ```
48
+
49
+ ## API
50
+
51
+ ### `render`
52
+
53
+ Set up the document and mount a component into that document.
54
+
55
+ ```ts
56
+ const { baseElement, container, component, unmount, rerender } = render(
57
+ Component,
58
+ componentOptions,
59
+ setupOptions
60
+ )
61
+ ```
62
+
63
+ | Argument | Type | Description |
64
+ | ------------------ | ------------------------------------------------------- | --------------------------------------------- |
65
+ | `Component` | [Svelte component][svelte-component-docs] | An imported Svelte component |
66
+ | `componentOptions` | `Props` or partial [`mount` options][svelte-mount-docs] | Options for how the component will be mounted |
67
+ | `setupOptions` | `{ baseElement?: HTMLElement }` | Optionally override `baseElement` |
68
+
69
+ | Result | Type | Description | Default |
70
+ | ------------- | ------------------------------------------ | ---------------------------------------- | ----------------------------------- |
71
+ | `baseElement` | `HTMLElement` | The base element | `document.body` |
72
+ | `container` | `HTMLElement` | The component's immediate parent element | `<div>` appended to `document.body` |
73
+ | `component` | [component exports][svelte-mount-docs] | The component's exports from `mount` | N/A |
74
+ | `rerender` | `(props: Partial<Props>) => Promise<void>` | Update the component's props | N/A |
75
+ | `unmount` | `() => void` | Unmount the component from the document | N/A |
76
+
77
+ > \[!TIP]
78
+ > Calling `render` is equivalent to calling `setup` followed by `mount`
79
+ >
80
+ > ```ts
81
+ > const { baseElement, container, mountOptions } = setup(
82
+ > componentOptions,
83
+ > setupOptions
84
+ > )
85
+ > const { component, rerender, unmount } = mount(Component, mountOptions)
86
+ > ```
87
+
88
+ [svelte-component-docs]: https://svelte.dev/docs/svelte-components
89
+ [svelte-mount-docs]: https://svelte.dev/docs/svelte/imperative-component-api#mount
90
+
91
+ ### `setup`
92
+
93
+ Validate options and prepare document elements for rendering.
94
+
95
+ ```ts
96
+ const { baseElement, target, mountOptions } = setup(options, renderOptions)
97
+ ```
98
+
99
+ | Argument | Type | Description |
100
+ | ------------------ | ------------------------------------------------------- | --------------------------------------------- |
101
+ | `componentOptions` | `Props` or partial [`mount` options][svelte-mount-docs] | Options for how the component will be mounted |
102
+ | `setupOptions` | `{ baseElement?: HTMLElement }` | Optionally override `baseElement` |
103
+
104
+ | Result | Type | Description | Default |
105
+ | -------------- | ------------------------------------ | ---------------------------------------- | ----------------------------------- |
106
+ | `baseElement` | `HTMLElement` | The base element | `document.body` |
107
+ | `container` | `HTMLElement` | The component's immediate parent element | `<div>` appended to `document.body` |
108
+ | `mountOptions` | [`mount` options][svelte-mount-docs] | Validated options to pass to `mount` | `{ target, props: {} }` |
109
+
110
+ ### `mount`
111
+
112
+ Mount a Svelte component into the document.
113
+
114
+ ```ts
115
+ const { component, unmount, rerender } = mount(Component, options)
116
+ ```
117
+
118
+ | Argument | Type | Description |
119
+ | -------------- | ----------------------------------------- | -------------------------------------------- |
120
+ | `Component` | [Svelte component][svelte-component-docs] | An imported Svelte component |
121
+ | `mountOptions` | [component options][svelte-mount-docs] | Options to pass to Svelte's `mount` function |
122
+
123
+ | Result | Type | Description |
124
+ | ----------- | ------------------------------------------ | --------------------------------------- |
125
+ | `component` | [component exports][svelte-mount-docs] | The component's exports from `mount` |
126
+ | `unmount` | `() => void` | Unmount the component from the document |
127
+ | `rerender` | `(props: Partial<Props>) => Promise<void>` | Update the component's props |
128
+
129
+ ### `cleanup`
130
+
131
+ Cleanup rendered components and added elements. Call this when your tests are
132
+ over.
133
+
134
+ ```ts
135
+ cleanup()
136
+ ```
137
+
138
+ ### `addCleanupTask`
139
+
140
+ Add a custom cleanup task to be called with `cleanup()`
141
+
142
+ ```ts
143
+ addCleanupTask(() => {
144
+ // ...reset something
145
+ })
146
+ ```
147
+
148
+ ### `removeCleanupTask`
149
+
150
+ Remove a cleanup task from `cleanup()`. Useful if a cleanup task can only be run
151
+ once and may be run outside of `cleanup`
152
+
153
+ ```ts
154
+ const customCleanup = () => {
155
+ // ...reset something
156
+ }
157
+
158
+ addCleanupTask(customCleanup)
159
+
160
+ const manuallyCleanupEarly = () => {
161
+ customCleanup()
162
+ removeCleanupTask(customCleanup)
163
+ }
164
+ ```
165
+
166
+ ### Utility types
167
+
168
+ This module exports various utility types from
169
+ `@testing-library/svelte-core/types`. They adapt to whatever Svelte version is
170
+ installed, and can be used to get type signatures for imported components,
171
+ props, exports, etc.
172
+
173
+ See [`./types.d.ts`](./types.d.ts) for the full list of available types.
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@testing-library/svelte-core",
3
+ "version": "1.0.0-next.1",
4
+ "description": "Core rendering and cleanup logic for Svelte testing utilities.",
5
+ "exports": {
6
+ ".": {
7
+ "types": "./dist/index.d.ts",
8
+ "svelte": "./src/index.js",
9
+ "default": "./src/index.js"
10
+ },
11
+ "./types": {
12
+ "types": "./types.d.ts"
13
+ }
14
+ },
15
+ "type": "module",
16
+ "license": "MIT",
17
+ "homepage": "https://github.com/testing-library/svelte-testing-library#readme",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/testing-library/svelte-testing-library.git",
21
+ "directory": "packages/svelte-core"
22
+ },
23
+ "bugs": {
24
+ "url": "https://github.com/testing-library/svelte-testing-library/issues"
25
+ },
26
+ "engines": {
27
+ "node": ">=16"
28
+ },
29
+ "keywords": [
30
+ "testing",
31
+ "svelte",
32
+ "ui",
33
+ "dom",
34
+ "jsdom",
35
+ "unit",
36
+ "integration",
37
+ "functional",
38
+ "end-to-end",
39
+ "e2e"
40
+ ],
41
+ "files": [
42
+ "dist",
43
+ "src",
44
+ "types.d.ts"
45
+ ],
46
+ "peerDependencies": {
47
+ "svelte": "^3 || ^4 || ^5 || ^5.0.0-next.0"
48
+ },
49
+ "publishConfig": {
50
+ "access": "public",
51
+ "provenance": true
52
+ }
53
+ }
package/src/cleanup.js ADDED
@@ -0,0 +1,32 @@
1
+ /** @type {Set<() => void>} */
2
+ const cleanupTasks = new Set()
3
+
4
+ /**
5
+ * Register later cleanup task
6
+ *
7
+ * @param {() => void} onCleanup
8
+ */
9
+ const addCleanupTask = (onCleanup) => {
10
+ cleanupTasks.add(onCleanup)
11
+ return onCleanup
12
+ }
13
+
14
+ /**
15
+ * Remove a cleanup task without running it.
16
+ *
17
+ * @param {() => void} onCleanup
18
+ */
19
+ const removeCleanupTask = (onCleanup) => {
20
+ cleanupTasks.delete(onCleanup)
21
+ }
22
+
23
+ /** Clean up all components and elements added to the document. */
24
+ const cleanup = () => {
25
+ for (const handleCleanup of cleanupTasks.values()) {
26
+ handleCleanup()
27
+ }
28
+
29
+ cleanupTasks.clear()
30
+ }
31
+
32
+ export { addCleanupTask, cleanup, removeCleanupTask }
package/src/index.js ADDED
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Rendering core for svelte-testing-library.
3
+ *
4
+ * Defines how components are added to and removed from the DOM.
5
+ * Will switch to legacy, class-based mounting logic
6
+ * if it looks like we're in a Svelte <= 4 environment.
7
+ */
8
+ export * from './cleanup.js'
9
+ export * from './mount.js'
10
+ export * from './render.js'
11
+ export * from './setup.js'
package/src/mount.js ADDED
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Component rendering core, with support for Svelte 3, 4, and 5
3
+ */
4
+ import * as Svelte from 'svelte'
5
+
6
+ import { addCleanupTask, removeCleanupTask } from './cleanup.js'
7
+ import { createProps } from './props.svelte.js'
8
+ import { IS_MODERN_SVELTE } from './svelte-version.js'
9
+
10
+ /**
11
+ * Mount a modern Svelte 5 component into the DOM.
12
+ *
13
+ * @template {import('../types.js').Component} C
14
+ * @param {import('../types.js').ComponentType<C>} Component
15
+ * @param {import('../types.js').MountOptions<C>} options
16
+ * @returns {import('../types.js').MountResult<C>}
17
+ */
18
+ const mountModern = (Component, options) => {
19
+ const [props, updateProps] = createProps(options.props)
20
+ const component = Svelte.mount(Component, { ...options, props })
21
+
22
+ /** Remove the component from the DOM. */
23
+ const unmount = () => {
24
+ Svelte.flushSync(() => Svelte.unmount(component))
25
+ removeCleanupTask(unmount)
26
+ }
27
+
28
+ /** Update the component's props. */
29
+ const rerender = (nextProps) => {
30
+ Svelte.flushSync(() => updateProps(nextProps))
31
+ }
32
+
33
+ addCleanupTask(unmount)
34
+ Svelte.flushSync()
35
+
36
+ return { component, unmount, rerender }
37
+ }
38
+
39
+ /**
40
+ * Mount a legacy Svelte 3 or 4 component into the DOM.
41
+ *
42
+ * @template {import('../types.js').LegacyComponent} C
43
+ * @param {import('../types.js').ComponentType<C>} Component
44
+ * @param {import('../types.js').MountOptions<C>} options
45
+ * @returns {import('../types.js').MountResult<C>}
46
+ */
47
+ const mountLegacy = (Component, options) => {
48
+ const component = new Component(options)
49
+
50
+ /** Remove the component from the DOM. */
51
+ const unmount = () => {
52
+ component.$destroy()
53
+ removeCleanupTask(unmount)
54
+ }
55
+
56
+ /** Update the component's props. */
57
+ const rerender = (nextProps) => {
58
+ component.$set(nextProps)
59
+ }
60
+
61
+ // This `$$.on_destroy` listener is included for strict backwards compatibility
62
+ // with previous versions of `@testing-library/svelte`.
63
+ // It's unnecessary and will be removed in a future major version.
64
+ component.$$.on_destroy.push(() => {
65
+ removeCleanupTask(unmount)
66
+ })
67
+
68
+ addCleanupTask(unmount)
69
+
70
+ return { component, unmount, rerender }
71
+ }
72
+
73
+ /** The mount method in use. */
74
+ const mountComponent = IS_MODERN_SVELTE ? mountModern : mountLegacy
75
+
76
+ /**
77
+ * Render a Svelte component into the document.
78
+ *
79
+ * @template {import('../types.js').Component} C
80
+ * @param {import('../types.js').ComponentImport<C>} Component
81
+ * @param {import('../types.js').MountOptions<C>} options
82
+ * @returns {import('../types.js').MountResult<C>}
83
+ */
84
+ const mount = (Component, options) => {
85
+ const { component, unmount, rerender } = mountComponent(
86
+ 'default' in Component ? Component.default : Component,
87
+ options
88
+ )
89
+
90
+ return {
91
+ component,
92
+ unmount,
93
+ rerender: async (props) => {
94
+ if ('props' in props) {
95
+ console.warn(
96
+ 'rerender({ props: { ... } }) deprecated, use rerender({ ... }) instead'
97
+ )
98
+ props = props.props
99
+ }
100
+
101
+ rerender(props)
102
+ // Await the next tick for Svelte 3/4, which cannot flush changes synchronously
103
+ await Svelte.tick()
104
+ },
105
+ }
106
+ }
107
+
108
+ export { mount }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Create a shallowly reactive props object.
3
+ *
4
+ * This allows us to update props on `rerender`
5
+ * without turing `props` into a deep set of Proxy objects
6
+ *
7
+ * @template {Record<string, unknown>} Props
8
+ * @param {Props} initialProps
9
+ * @returns {[Props, (nextProps: Partial<Props>) => void]}
10
+ */
11
+ const createProps = (initialProps = {}) => {
12
+ let currentProps = $state.raw(initialProps)
13
+
14
+ const props = new Proxy(initialProps, {
15
+ get(_, key) {
16
+ return currentProps[key]
17
+ },
18
+ set(_, key, value) {
19
+ currentProps[key] = value
20
+ return true
21
+ },
22
+ has(_, key) {
23
+ return Reflect.has(currentProps, key)
24
+ },
25
+ ownKeys() {
26
+ return Reflect.ownKeys(currentProps)
27
+ },
28
+ })
29
+
30
+ const update = (nextProps) => {
31
+ currentProps = { ...currentProps, ...nextProps }
32
+ }
33
+
34
+ return [props, update]
35
+ }
36
+
37
+ export { createProps }
package/src/render.js ADDED
@@ -0,0 +1,21 @@
1
+ import { mount } from './mount.js'
2
+ import { setup } from './setup.js'
3
+
4
+ /**
5
+ * Render a component into the document.
6
+ *
7
+ * @template {import('../types.js').Component} C
8
+ *
9
+ * @param {import('../types.js').ComponentImport<C>} Component - The component to render.
10
+ * @param {import('../types.js').ComponentOptions<C>} componentOptions - Customize how Svelte renders the component.
11
+ * @param {import('../types.js').SetupOptions<C>} setupOptions - Customize how the document is set up.
12
+ * @returns {import('../types.js').RenderResult<C>} The rendered component.
13
+ */
14
+ const render = (Component, componentOptions, setupOptions = {}) => {
15
+ const { mountOptions, ...setupResult } = setup(componentOptions, setupOptions)
16
+ const mountResult = mount(Component, mountOptions)
17
+
18
+ return { ...setupResult, ...mountResult }
19
+ }
20
+
21
+ export { render }
package/src/setup.js ADDED
@@ -0,0 +1,86 @@
1
+ /** Set up the document to render a component. */
2
+ import { addCleanupTask } from './cleanup.js'
3
+ import { IS_MODERN_SVELTE } from './svelte-version.js'
4
+
5
+ /** Allowed options to the `mount` call or legacy component constructor. */
6
+ const ALLOWED_MOUNT_OPTIONS = IS_MODERN_SVELTE
7
+ ? ['target', 'anchor', 'props', 'events', 'context', 'intro']
8
+ : ['target', 'accessors', 'anchor', 'props', 'hydrate', 'intro', 'context']
9
+
10
+ class UnknownSvelteOptionsError extends TypeError {
11
+ constructor(unknownOptions) {
12
+ super(`Unknown options.
13
+
14
+ Unknown: [ ${unknownOptions.join(', ')} ]
15
+ Allowed: [ ${ALLOWED_MOUNT_OPTIONS.join(', ')} ]
16
+
17
+ To pass both Svelte options and props to a component,
18
+ or to use props that share a name with a Svelte option,
19
+ you must place all your props under the \`props\` key:
20
+
21
+ render(Component, { props: { /** props here **/ } })
22
+ `)
23
+ this.name = 'UnknownSvelteOptionsError'
24
+ }
25
+ }
26
+
27
+ /**
28
+ * Validate a component's mount options.
29
+ *
30
+ * @template {import('../types.js').Component} C
31
+ * @param {import('../types.js').ComponentOptions<C>} options - props or mount options
32
+ * @returns {Partial<import('../types.js').MountOptions<C>>}
33
+ */
34
+ const validateOptions = (options) => {
35
+ const isProps = !Object.keys(options).some((option) =>
36
+ ALLOWED_MOUNT_OPTIONS.includes(option)
37
+ )
38
+
39
+ if (isProps) {
40
+ return { props: options }
41
+ }
42
+
43
+ // Check if any props and Svelte options were accidentally mixed.
44
+ const unknownOptions = Object.keys(options).filter(
45
+ (option) => !ALLOWED_MOUNT_OPTIONS.includes(option)
46
+ )
47
+
48
+ if (unknownOptions.length > 0) {
49
+ throw new UnknownSvelteOptionsError(unknownOptions)
50
+ }
51
+
52
+ return options
53
+ }
54
+
55
+ /**
56
+ * Set up the document to render a component.
57
+ *
58
+ * @template {import('../types.js').Component} C
59
+ * @param {import('../types.js').ComponentOptions<C>} componentOptions - props or mount options
60
+ * @param {import('../types.js').SetupOptions<C>} setupOptions - base element of the document to bind any queries
61
+ * @returns {import('../types.js').SetupResult<C>}
62
+ */
63
+ const setup = (componentOptions, setupOptions = {}) => {
64
+ const mountOptions = validateOptions(componentOptions)
65
+
66
+ const baseElement =
67
+ setupOptions.baseElement ?? mountOptions.target ?? document.body
68
+
69
+ const container =
70
+ mountOptions.target ??
71
+ baseElement.appendChild(document.createElement('div'))
72
+
73
+ addCleanupTask(() => {
74
+ if (container.parentNode === document.body) {
75
+ container.remove()
76
+ }
77
+ })
78
+
79
+ return {
80
+ baseElement,
81
+ container,
82
+ mountOptions: { ...mountOptions, target: container },
83
+ }
84
+ }
85
+
86
+ export { setup, UnknownSvelteOptionsError }
@@ -0,0 +1,7 @@
1
+ /** Detect which version of Svelte we're using */
2
+ import * as Svelte from 'svelte'
3
+
4
+ /** Whether we're using Svelte >= 5. */
5
+ const IS_MODERN_SVELTE = typeof Svelte.mount === 'function'
6
+
7
+ export { IS_MODERN_SVELTE }
package/types.d.ts ADDED
@@ -0,0 +1,131 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-deprecated */
2
+ /**
3
+ * Component and utility types.
4
+ *
5
+ * Supports components from Svelte 3, 4, and 5.
6
+ */
7
+ import type {
8
+ Component as ModernComponent,
9
+ ComponentConstructorOptions as LegacyConstructorOptions,
10
+ ComponentProps,
11
+ EventDispatcher,
12
+ mount,
13
+ SvelteComponent as Svelte4LegacyComponent,
14
+ SvelteComponentTyped as Svelte3LegacyComponent,
15
+ } from 'svelte'
16
+
17
+ type IS_MODERN_SVELTE = ModernComponent extends (...args: any[]) => any
18
+ ? true
19
+ : false
20
+
21
+ type IS_LEGACY_SVELTE_4 =
22
+ EventDispatcher<any> extends (...args: any[]) => any ? true : false
23
+
24
+ /** A compiled, imported Svelte component. */
25
+ export type Component<
26
+ P extends Record<string, any> = any,
27
+ E extends Record<string, any> = any,
28
+ > = IS_MODERN_SVELTE extends true
29
+ ? ModernComponent<P, E> | LegacyComponent<P>
30
+ : LegacyComponent<P>
31
+
32
+ /** A compiled, imported Svelte 3 or 4 component. */
33
+ export type LegacyComponent<P extends Record<string, any> = any> =
34
+ IS_LEGACY_SVELTE_4 extends true
35
+ ? Svelte4LegacyComponent<P>
36
+ : Svelte3LegacyComponent<P>
37
+
38
+ /**
39
+ * The "type" of an imported, compiled Svelte component.
40
+ *
41
+ * In Svelte 5, there is no difference between the
42
+ * imported component and its "type" - it's just a function.
43
+ * In Svelte 3/4, the imported component is a class.
44
+ */
45
+ export type ComponentType<C> = C extends LegacyComponent
46
+ ? new (...args: any[]) => C
47
+ : C
48
+
49
+ /**
50
+ * A component import.
51
+ *
52
+ * A convenience type to allow dynamically `import(...)`'d
53
+ * components to be passed directly to `mount.`
54
+ */
55
+ export type ComponentImport<C> =
56
+ | ComponentType<C>
57
+ | { default: ComponentType<C> }
58
+
59
+ /** The props of a component. */
60
+ export type Props<C extends Component> = ComponentProps<C>
61
+
62
+ /**
63
+ * The exported fields of a component.
64
+ *
65
+ * In Svelte 5, this is the set of variables marked as `export`'d.
66
+ * In Svelte 4, this is simply the instance of the component class.
67
+ */
68
+ export type Exports<C> = IS_MODERN_SVELTE extends true
69
+ ? C extends ModernComponent<any, infer E>
70
+ ? E
71
+ : C & { $set: never; $on: never; $destroy: never }
72
+ : C
73
+
74
+ /**
75
+ * Options that may be passed to `mount` when rendering the component.
76
+ *
77
+ * In Svelte 4, these are the options passed to the component constructor.
78
+ */
79
+ export type MountOptions<C extends Component> = IS_MODERN_SVELTE extends true
80
+ ? Parameters<typeof mount<Props<C>, Exports<C>>>[1]
81
+ : LegacyConstructorOptions<Props<C>>
82
+
83
+ /** A component's props or some of its mount options. */
84
+ export type ComponentOptions<C extends Component> =
85
+ | Props<C>
86
+ | Partial<MountOptions<C>>
87
+
88
+ /** Update a component's props and trigger updates to the DOM. */
89
+ export type Rerender<C extends Component> = (
90
+ props: Partial<Props<C>>
91
+ ) => Promise<void>
92
+
93
+ /** The result of mounting a component into the document. */
94
+ export interface MountResult<C extends Component> {
95
+ /** The mounted component's exports. */
96
+ component: Exports<C>
97
+ /** Unmount the component. */
98
+ unmount: () => void
99
+ /** Rerender the component. */
100
+ rerender: Rerender<C>
101
+ }
102
+
103
+ /** Options for configuring the document. */
104
+ export interface SetupOptions {
105
+ /** The base document element, `document.body` if unspecified. */
106
+ baseElement?: HTMLElement
107
+ }
108
+
109
+ /** The result of setting up the document for rendering. */
110
+ export interface SetupResult<C extends Component> {
111
+ /** The base document element, usually `document.body`. */
112
+ baseElement: HTMLElement
113
+ /** The component's immediate container element, usually a `<div>` appended to `document.body`. */
114
+ container: HTMLElement
115
+ /** Options to pass to `mount`. */
116
+ mountOptions: MountOptions<C>
117
+ }
118
+
119
+ /** The result of setting up the document and rendering the component. */
120
+ export interface RenderResult<C extends Component> {
121
+ /** The base document element, usually `document.body`. */
122
+ baseElement: HTMLElement
123
+ /** The component's immediate container element, usually a `<div>` appended to `document.body`. */
124
+ container: HTMLElement
125
+ /** The mounted component's exports. */
126
+ component: Exports<C>
127
+ /** Unmount the component. */
128
+ unmount: () => void
129
+ /** Rerender the component. */
130
+ rerender: Rerender<C>
131
+ }