refactor(core): [CORE-21] generate compatible public and editor declarations

This commit is contained in:
Harvey Zhao committed 2026-09-11 17:56:05 +08:00
1 parent ee895a558f
commit faaa3e8c2d
123 files changed
+31305 -1712

No files matched your search

+17
View File
@@ -0,0 +1,17 @@
/* eslint-disable ts/no-require-imports, ts/no-this-alias -- Exercise actual CJS syntax and callback receiver types. */
import Artplayer = require('artplayer/runtime')
import LegacyRuntime = require('artplayer/runtime/legacy')
const option: Artplayer.OptionInput = { container: '#player' }
const art: Artplayer = new Artplayer(option)
const legacy: Artplayer = new LegacyRuntime(option)
const factory: Artplayer.PluginFactory<{ name: string }> = function (instance) {
const receiver: Artplayer.PluginHost = this
const value: undefined = instance.seek
void [receiver, value]
return { name: 'cjs' }
}
const registry: Artplayer.Plugins = art.plugins.add(factory)
// @ts-expect-error CJS must not reintroduce legacy false getter values.
const falseSeek: number = legacy.seek
void [registry, falseSeek]
+28
View File
@@ -0,0 +1,28 @@
import type { Component, Controls } from '../../packages/artplayer/public/runtime/component'
import type { Setting, SettingItem } from '../../packages/artplayer/public/runtime/setting'
import type Artplayer from '../../packages/artplayer/src'
import type { ControlHost } from '../../packages/artplayer/src/control/types'
import type { SettingHost } from '../../packages/artplayer/src/setting/types'
declare const source: Artplayer
const controls: Controls<ControlHost> = source.controls
const component: Component<ControlHost> = source.controls
const setting: Setting<SettingHost> = source.setting
const added: undefined = controls.add({ name: 'sample', html: 1, position: 'left' })
const updated: undefined = controls.update({ name: 'sample', html: 2 })
const nullable: SettingItem<SettingHost> | null = setting.find('absent')
const item = { name: 'setting', html: 'Item', extra: 1 }
const same: typeof item = setting.add(item)
const changed: SettingItem<SettingHost> = setting.update({ name: 'setting', html: 'Updated' })
const removed: void = setting.remove('setting')
setting.add({ name: 'callback', html: 'Callback', onClick(entry) {
const offset: number = this.subtitleOffset
return [offset, entry.name]
} })
// @ts-expect-error The updated item is not the whole setting registry.
const registry: Setting<SettingHost> = setting.update({ name: 'setting' })
// @ts-expect-error A missing setting result is null, not undefined.
const absent: undefined = setting.find('absent')
// @ts-expect-error Control add does not return a mounted element.
const element: HTMLElement = controls.add({ html: 'Button', position: 'left' })
export { absent, added, changed, component, element, nullable, registry, removed, same, updated }
+72
View File
@@ -0,0 +1,72 @@
/* eslint-disable ts/no-this-alias -- Assignments verify callback initialization views. */
import type { ContextmenuHost, ControlHost, CustomTypeHost, LayerHost, OptionInput, PluginHost, ProxyHost } from 'artplayer/runtime'
import Artplayer from 'artplayer/runtime'
const option: OptionInput = {
container: document.createElement('div'),
proxy(art) {
const host: ProxyHost = art
const id: number = host.id
art.on('ready', () => {})
// @ts-expect-error Template has not returned during proxy construction.
void art.template
// @ts-expect-error Accessing the video getter before Template returns would throw.
void art.video
// @ts-expect-error Player descriptors have not been installed yet.
art.seek = 1
void id
return document.createElement('video')
},
customType: { custom(video, url, art) {
const host: CustomTypeHost = art
host.seek = '1'
const seek: undefined = host.seek
// URL assignment defers customType until construction has finished.
const player: object = art.player
art.controls.show = true
void [video, url, seek, player]
} },
layers: [art => ({ html: String(art.id), mounted() {
const host: LayerHost = this
host.seek = 1
// @ts-expect-error Layer has not returned when its mounted callback runs.
host.layers.show = true
} })],
controls: [{ position: 'left', mounted() {
const host: ControlHost = this
host.layers.show = true
// @ts-expect-error Control has not returned when its mounted callback runs.
host.controls.show = true
} }],
contextmenu: [{ mounted() {
const host: ContextmenuHost = this
host.controls.show = true
// @ts-expect-error Contextmenu has not returned when its mounted callback runs.
host.contextmenu.show = true
} }],
setting: true,
settings: [{ html: 'Setting', mounted() {
// Setting mounted uses a deferred callback after construction completes.
const host: Artplayer = this
host.setting.show = true
host.plugins.add(() => ({ name: 'from-setting' }))
} }],
plugins: [function (art) {
const host: PluginHost = art
host.setting.show = true
host.seek = 1
// @ts-expect-error Registry is assigned only after constructor factories return.
host.plugins.add(() => ({ name: 'too-early' }))
return { name: 'construction' }
}],
}
const art = new Artplayer(option, function (art) {
art.seek = 2
this.controls.show = true
this.plugins.add(() => ({ name: 'ready' }))
})
// @ts-expect-error Only div containers satisfy the runtime element validation.
const invalidContainer: OptionInput = { container: document.createElement('section') }
// @ts-expect-error A configured proxy must return a video or media-like canvas.
const invalidProxy: OptionInput = { container: '#player', proxy: () => undefined }
void [art, invalidContainer, invalidProxy]
+30
View File
@@ -0,0 +1,30 @@
import type { Emitter } from '../../packages/artplayer/public/emitter'
import type { Events } from '../../packages/artplayer/public/runtime/events'
import type { Notice, Subtitle, SubtitleCue } from '../../packages/artplayer/public/runtime/subtitle'
import type Artplayer from '../../packages/artplayer/src'
declare const source: Artplayer
const events: Emitter<Events> = source
const subtitle: Subtitle = source.subtitle
const notice: Notice = source.notice
const visible: boolean = notice.show
notice.show = 'message'
const switched: Promise<string | null | undefined> = subtitle.switch('/subtitle.vtt')
const styled: HTMLDivElement = subtitle.style('font-size', 20)
events.on('subtitleBeforeUpdate', (cues) => {
const actual: SubtitleCue[] = cues
return actual.map(cue => cue.text)
})
events.on('blur', event => event.type)
source.on('subtitleBeforeUpdate', cues => cues.map(cue => cue.text))
events.emit('subtitleAfterUpdate', [])
events.emit('seek', 1.5, '1.5')
// @ts-expect-error The corrected payload cannot retain historical scalar cue inference.
events.on('subtitleBeforeUpdate', (cue: VTTCue) => cue.text)
// @ts-expect-error Native focus loss carries its original Event.
events.emit('blur')
// @ts-expect-error The actual source map must also reject a scalar update payload.
source.emit('subtitleAfterUpdate', 1)
// @ts-expect-error A visibility getter does not return the last message.
const message: string = notice.show
export { events, message, styled, switched, visible }
+31
View File
@@ -0,0 +1,31 @@
import type SourceArtplayer from '../../packages/artplayer/src'
import type { I18nHost } from '../../packages/artplayer/src/i18n'
import type RuntimeArtplayer from '../../packages/artplayer/types/runtime'
import type { ArtplayerConstructor } from '../../packages/artplayer/types/runtime'
import type { Config, EventRegistry, Hotkey, I18n, Storage } from '../../packages/artplayer/types/runtime/services'
declare const source: SourceArtplayer
declare const constructor: typeof SourceArtplayer
const events: EventRegistry = source.events
const storage: Storage = source.storage
const hotkey: Hotkey<SourceArtplayer> = source.hotkey
const language: I18n<I18nHost> = source.i18n
const config: Config = constructor.config
const validator: ArtplayerConstructor['validator'] = constructor.validator
const kindOf: ArtplayerConstructor['kindOf'] = constructor.kindOf
const scheme: ArtplayerConstructor['scheme'] = constructor.scheme
// The facade covers every implementation member without whole-instance assertions.
const missingInstance: Exclude<keyof SourceArtplayer, keyof RuntimeArtplayer> extends never ? true : false = true
const extraInstance: Exclude<keyof RuntimeArtplayer, keyof SourceArtplayer | 'flv' | 'm3u8' | 'hls' | 'ts' | 'mpd' | 'torrent'> extends never ? true : false = true
const missingStatic: Exclude<keyof typeof SourceArtplayer, keyof ArtplayerConstructor> extends never ? true : false = true
const extraStatic: Exclude<keyof ArtplayerConstructor, keyof typeof SourceArtplayer> extends never ? true : false = true
type ValueMembers = 'id' | 'isLock' | 'isReady' | 'isFocus' | 'isInput' | 'isRotate' | 'isDestroy' | 'video' | 'player' | 'reset' | 'destroy'
const values: Pick<RuntimeArtplayer, ValueMembers> = source
type SharedOptions = Exclude<keyof RuntimeArtplayer['option'], 'proxy' | 'plugins' | 'customType' | 'layers' | 'controls' | 'contextmenu' | 'settings'>
const options: Pick<RuntimeArtplayer['option'], SharedOptions> = source.option
const storageValue: unknown = storage.get()
// @ts-expect-error Persisted JSON can be a primitive, not just a settings object.
const falseSettings: Record<string, unknown> = storage.get()
void [events, storage, hotkey, language, config, validator, kindOf, scheme, missingInstance, extraInstance, missingStatic, extraStatic, values, options, storageValue, falseSettings]
+54
View File
@@ -0,0 +1,54 @@
import type { Emitter } from 'artplayer'
import type { Controls } from '../../packages/artplayer/types/runtime/component.js'
import type { Events } from '../../packages/artplayer/types/runtime/events.js'
import type { NativeMedia } from '../../packages/artplayer/types/runtime/media.js'
import type { Player } from '../../packages/artplayer/types/runtime/player.js'
import type { Plugins } from '../../packages/artplayer/types/runtime/plugin.js'
import type { Setting, SettingItem } from '../../packages/artplayer/types/runtime/setting.js'
import type { Notice, Subtitle } from '../../packages/artplayer/types/runtime/subtitle.js'
import type { Icons, Template } from '../../packages/artplayer/types/runtime/template.js'
import type { Utils } from '../../packages/artplayer/types/runtime/utils.js'
declare const player: Player<NativeMedia>
declare const registry: Plugins<Player<NativeMedia>>
declare const events: Emitter<Events>
declare const notice: Notice
declare const subtitle: Subtitle
declare const template: Template<Player<NativeMedia>, NativeMedia>
declare const icons: Icons
declare const utils: Utils
declare const controls: Controls<Player<NativeMedia>>
declare const setting: Setting<Player<NativeMedia>>
const read: undefined = player.seek
player.seek = '2'
const play: Promise<void> = player.play()
const pip: Element | null | boolean = player.pip
const immediate: typeof registry = registry.add(art => ({ name: 'plain', value: art.currentTime }))
const pending: Promise<typeof registry> = registry.add(async art => ({ name: 'async', value: art.currentTime }))
events.on('subtitleBeforeUpdate', cues => cues.map(cue => cue.text))
events.on('video:error', event => event.type)
const visible: boolean = notice.show
notice.show = new Error('test')
const changed: Promise<string | null | undefined> = subtitle.switch('/subtitle.vtt')
const native: NativeMedia = template.$video
const wrapper: HTMLElement = icons.play
const custom: HTMLElement | undefined = icons.custom
const target = { id: 1 }
const same: typeof target = utils.def(target, 'name', { value: 'name' })
const delayed: void = utils.debounce(() => 1, 0, {})()
const mounted: undefined = controls.add({ name: 'button', html: 'Button', position: 'left' })
const settingResult: SettingItem<Player<NativeMedia>> | null = setting.find('entry')
const input = { name: 'entry', html: 'Entry', custom: 123 }
const settingIdentity: typeof input = setting.add(input)
const updated: SettingItem<Player<NativeMedia>> = setting.update(input)
// @ts-expect-error Reading a setter-only command is not a numeric result.
const number: number = player.seek
// @ts-expect-error Native error forwarding preserves Event, not an Error object.
events.emit('video:error', new Error('wrong payload'))
// @ts-expect-error Update callbacks receive arrays.
events.on('subtitleBeforeUpdate', (cue: VTTCue) => cue.text)
// @ts-expect-error Deferred callbacks have no immediate numeric result.
const immediateNumber: number = utils.throttle(() => 1, 0)()
// @ts-expect-error A setting update returns the item, not the registry.
const settingRegistry: typeof setting = setting.update(input)
export { changed, custom, delayed, immediate, immediateNumber, mounted, native, number, pending, pip, play, read, same, settingIdentity, settingRegistry, settingResult, updated, visible, wrapper }
+36
View File
@@ -0,0 +1,36 @@
import type { CanvasMedia, MediaSurface, NativeMedia } from '../../packages/artplayer/public/runtime/media'
import type { Player } from '../../packages/artplayer/public/runtime/player'
import type { MediaSurface as SourceMedia } from '../../packages/artplayer/src/media/types'
import type { PlayerProperties } from '../../packages/artplayer/src/player/properties'
declare const actual: PlayerProperties
declare const media: SourceMedia
declare const native: Player<NativeMedia>
declare const canvas: Player<CanvasMedia>
const publicPlayer: Player = actual
const publicMedia: MediaSurface = media
const internalMedia: SourceMedia = publicMedia
const commands: undefined[] = [publicPlayer.seek, publicPlayer.forward, publicPlayer.backward, publicPlayer.switch, publicPlayer.quality]
const pip: Element | null | boolean = publicPlayer.pip
const url: string | null = publicPlayer.url
const nativePlay: Promise<void> = native.play()
const nativePause: void = native.pause()
const nativeToggle: void | Promise<void> = native.toggle()
const proxyPlay: Promise<unknown> = canvas.play()
publicPlayer.seek = '1.5'
publicPlayer.forward = 2
publicPlayer.quality = [{ html: document.createElement('span'), url: '/video.mp4' }]
publicPlayer.pip = true
// @ts-expect-error Commands do not have the historical fictitious numeric getters.
const position: number = publicPlayer.seek
// @ts-expect-error Accurate write types are not widened just to satisfy TS 4.3's accessor restriction.
publicPlayer.quality = undefined
// @ts-expect-error A native PiP element is a result, not a supported setter input.
publicPlayer.pip = document.createElement('video')
// @ts-expect-error The proxy play result cannot be assumed to be a native void result.
const proxyNative: Promise<void> = canvas.play()
type Assert<Condition extends true> = Condition
type Complete = Assert<Exclude<keyof PlayerProperties, keyof Player> extends never ? true : false>
type NoInventedProperties = Assert<Exclude<keyof Player, keyof PlayerProperties> extends never ? true : false>
export type { Complete, NoInventedProperties }
export { commands, internalMedia, nativePause, nativePlay, nativeToggle, pip, position, proxyNative, proxyPlay, url }
+165
View File
@@ -0,0 +1,165 @@
/* eslint-disable ts/no-this-alias -- Assignments prove contextual callback receiver types. */
import type { PluginFactory as LegacyPluginFactory } from 'artplayer'
import type { CustomTypeHost, Events, OptionInput, PluginFactory, PluginHost, Plugins } from 'artplayer/runtime'
import chapter from 'artplayer-plugin-chapter'
import Artplayer from 'artplayer/runtime'
import LegacyRuntime from 'artplayer/runtime/legacy'
declare module 'artplayer/types' {
interface Plugins {
legacyRuntimeExtension?: { set: (count: number) => void }
}
interface Events {
'legacy-runtime:update': [count: number]
}
}
declare module 'artplayer/runtime/types' {
interface Plugins {
runtimeExtension?: { update: (count: number) => void }
}
interface Events {
'runtime-extension:update': [count: number]
}
}
const factory: PluginFactory<{ name: string, update: (count: number) => void }> = function (art) {
const seek: undefined = this.seek
void seek
// @ts-expect-error A constructor factory cannot assume the registry has been assigned.
void art.plugins.art
return { name: 'runtimeExtension', update(count) {
art.emit('runtime-extension:update', count)
} }
}
const option: OptionInput = {
container: document.createElement('div'),
plugins: [factory, function (art) {
const receiver: PluginHost = this
const value: undefined = art.seek
void [receiver, value]
return { name: 'inline' }
}],
controls: [{ name: 'test', position: 'left', mounted(element) {
const value: undefined = this.seek
element.textContent = String(value)
} }],
settings: [{ html: 'Custom', onClick(item) {
const visible: boolean = this.notice.show
return `${item.html}: ${visible}`
} }],
customType: { hls(video, url, art) {
const receiver: CustomTypeHost = this
const value: undefined = art.forward
void [receiver, value, video, url]
} },
}
const art = new Artplayer(option, function (instance) {
const receiver: Artplayer = this
instance.plugins.runtimeExtension?.update(1)
void receiver
})
const sync: Plugins = art.plugins.add(factory)
const async: Promise<Plugins> = art.plugins.add(async () => ({ name: 'async' }))
const inline = art.plugins.add(function (instance) {
const receiver: Artplayer = this
const value: undefined = instance.backward
void [receiver, value]
return { name: 'inlineAdd' }
})
const same: Plugins = inline
const seek: undefined = art.seek
art.seek = 2
art.seek = '2'
art.notice.show = 'Message'
const shown: boolean = art.notice.show
const pip: Element | null | boolean = art.pip
art.pip = true
const icon: HTMLElement = art.icons.play
const customIcon: HTMLElement | undefined = art.icons.customIcon
const queried: HTMLDivElement | null = art.template.query<HTMLDivElement>('.optional')
const settingItem = { name: 'precise-item', html: 'Item', marker: 1 }
const added: typeof settingItem = art.setting.add(settingItem)
const removed: void = art.setting.remove(settingItem.name)
const subtitleStyle: HTMLDivElement = art.subtitle.style({ color: 'red' })
const target = { count: 1 }
const defined: typeof target = Artplayer.utils.def(target, Symbol('count'), {
get() { return this.count },
})
const debounced = Artplayer.utils.debounce((value: number) => value + 1, 10)
const throttled = Artplayer.utils.throttle((value: number) => value + 1, 10)
const delayed: void = debounced(1)
const limited: void = throttled(1)
const missing = art.setting.find('missing')
if (missing)
missing.html = 'Found'
art.on('runtime-extension:update', count => count.toFixed())
art.on('subtitleAfterUpdate', cues => cues.map(cue => cue.text))
art.plugins.runtimeExtension?.update(2)
const payload: Events['runtime-extension:update'] = [1]
Artplayer.config.events.push('custom-event')
Artplayer.DEBUG = false
// @ts-expect-error defineProperty requires an object target in an installed consumer too.
Artplayer.utils.def(123, 'value', { value: 1 })
declare const legacyFactory: LegacyPluginFactory
const legacyResult: Plugins | Promise<Plugins> = art.plugins.add(legacyFactory)
art.plugins.add(chapter())
art.plugins.legacyRuntimeExtension?.set(2)
art.on('legacy-runtime:update', count => count.toFixed())
const legacyRuntime: Artplayer = new LegacyRuntime(option)
const legacyOptions = new Artplayer({ container: '#legacy', plugins: [legacyFactory] }, function (instance) {
const value: undefined = this.seek
const other: undefined = instance.seek
void [value, other]
})
class Derived extends Artplayer {
marker = true
}
const derived = new Derived(option)
const chained: Derived = derived.on('ready', () => {})
// @ts-expect-error Command properties have no getter value.
const falseSeek: number = art.seek
// @ts-expect-error New control entries require one of the three supported positions.
art.controls.add({ html: 'Missing position' })
// @ts-expect-error Unknown control positions fail runtime validation.
art.controls.add({ html: 'Wrong position', position: 'middle' })
// @ts-expect-error Synchronous registration is not a Promise.
const falsePromise: Promise<Plugins> = sync
// @ts-expect-error Getter visibility is boolean.
const falseNotice: string = art.notice.show
// @ts-expect-error Native PiP returns an element or null, while WebKit returns boolean.
const falsePip: boolean = pip
// @ts-expect-error The PiP setter takes a boolean, not the native getter's element.
art.pip = document.createElement('video')
// @ts-expect-error Icons expose wrapper elements, not their SVG input strings.
const falseIcon: string = art.icons.play
// @ts-expect-error SSR and custom query results may be absent.
const falseQuery: HTMLDivElement = art.template.query<HTMLDivElement>('.optional')
// @ts-expect-error A delayed wrapper does not return the callback's number.
const falseDelayed: number = debounced(1)
// @ts-expect-error A throttled wrapper does not return the callback's number.
const falseLimited: number = throttled(1)
// @ts-expect-error defineProperty returns its target, not a descriptor.
const falseDescriptor: PropertyDescriptor = defined
// @ts-expect-error Precise built-in events reject scalar subtitle payloads.
art.emit('subtitleAfterUpdate', 'bad')
// @ts-expect-error Augmented payloads stay checked.
art.emit('runtime-extension:update', 'bad')
// @ts-expect-error Augmented plugin methods stay checked.
art.plugins.runtimeExtension?.update('bad')
// @ts-expect-error Legacy plugin augmentation keeps its method types on the precise view.
art.plugins.legacyRuntimeExtension?.set('bad')
// @ts-expect-error Legacy event augmentation keeps its payload type on the precise view.
art.emit('legacy-runtime:update', 'bad')
// @ts-expect-error Static env was never exposed by the runtime.
void Artplayer.env
// @ts-expect-error Template html belongs to the constructor.
void art.template.html
// @ts-expect-error Missing setting entries are null, not undefined.
const falseMissing: undefined = art.setting.find('missing')
void [sync, async, same, seek, shown, payload, legacyResult, legacyRuntime, legacyOptions, chained, falseSeek, falsePromise, falseNotice, falseMissing]
void [pip, icon, customIcon, queried, added, removed, subtitleStyle, defined, delayed, limited, falsePip, falseIcon, falseQuery, falseDelayed, falseLimited, falseDescriptor]
+34
View File
@@ -0,0 +1,34 @@
import type { PluginFactory, Plugins } from '../../packages/artplayer/public/runtime/plugin'
import type { IconName, Icons, Template } from '../../packages/artplayer/public/runtime/template'
import type Artplayer from '../../packages/artplayer/src'
import type iconDefaults from '../../packages/artplayer/src/icons/defaults'
declare const source: Artplayer
const plugins: Plugins<Artplayer> = source.plugins
const sync: Plugins<Artplayer> = plugins.add(function (art) {
// eslint-disable-next-line ts/no-this-alias -- Check the public factory's inferred receiver against the actual source instance.
const same: Artplayer = this
return { name: 'sync', same, art }
})
const asyncRegistry: Promise<Plugins<Artplayer>> = plugins.add(async () => ({ name: 'async' }))
declare const unknownFactory: PluginFactory<Artplayer>
const uncertain: Plugins<Artplayer> | Promise<Plugins<Artplayer>> = plugins.add(unknownFactory)
const template: Template<Artplayer> = source.template
const icons: Icons = source.icons
const icon: HTMLElement = icons.play
const customIcon: HTMLElement | undefined = icons.custom
const subtitle: HTMLDivElement | null = template.$subtitle
const query: HTMLVideoElement | null = template.query<HTMLVideoElement>('video')
// @ts-expect-error Sync registration is not a Promise.
const syncPromise: Promise<Plugins<Artplayer>> = plugins.add(() => ({ name: 'plain' }))
// @ts-expect-error Template.html belongs to the constructor, not its instance.
const instanceHtml = template.html
// @ts-expect-error Icon wrappers are not promised to be div elements.
const div: HTMLDivElement = icons.play
// @ts-expect-error Missing custom icon keys require a presence guard.
const present: HTMLElement = icons.custom
type Assert<Condition extends true> = Condition
type AllIcons = Assert<Exclude<keyof typeof iconDefaults, IconName> extends never ? true : false>
type NoInventedIcons = Assert<Exclude<IconName, keyof typeof iconDefaults> extends never ? true : false>
export type { AllIcons, NoInventedIcons }
export { asyncRegistry, customIcon, div, icon, instanceHtml, present, query, subtitle, sync, syncPromise, uncertain }
+31
View File
@@ -0,0 +1,31 @@
import type { Utils } from '../../packages/artplayer/public/runtime/utils'
import * as source from '../../packages/artplayer/src/utils'
const utils: Utils = source
const target = { enabled: true }
const same: typeof target = utils.def(target, 'value', { value: 1 })
const delayed: void = utils.debounce(() => 123, 0, {})()
const throttled: void = utils.throttle(() => 456, 0)()
const receiver = { count: 0 }
const callback = utils.debounce(function (this: typeof receiver, increment: number) {
this.count += increment
}, 0)
callback.call(receiver, 2)
const append: Element | ChildNode | null = utils.append(document.createElement('div'), '')
const style: number | string = utils.getStyle(document.body, 'width', Math.random() > 0.5)
const queried: HTMLVideoElement | null = utils.query<HTMLVideoElement>('video', document.createDocumentFragment())
const removed: Text = utils.remove(document.createTextNode('text'))
utils.sleep()
// @ts-expect-error The callback result is not returned by the debounce wrapper.
const immediate: number = utils.debounce(() => 1, 0)()
// @ts-expect-error Native defineProperty requires a descriptor object.
utils.def(target, 'value', 123)
// @ts-expect-error Native defineProperty also requires an object target.
utils.def(123, 'value', { value: 1 })
// @ts-expect-error Optional event targets do not make composed paths optional arrays.
const nullable: null = utils.getComposedPath({ target: null })
type Assert<Condition extends true> = Condition
type Complete = Assert<Exclude<keyof typeof source, keyof Utils> extends never ? true : false>
type NoInventedExports = Assert<Exclude<keyof Utils, keyof typeof source> extends never ? true : false>
export type { Complete, NoInventedExports }
export { append, delayed, immediate, nullable, queried, removed, same, style, throttled }