import type { Danmu, EventMap, Icons, Input, Item, NormalizedDanmu, NormalizedOption, Owner, Point, RuntimeFactory, RuntimeOption, RuntimeResult, Slider } from 'artplayer-plugin-danmuku/runtime' import Artplayer from 'artplayer' import runtime from 'artplayer-plugin-danmuku/runtime' type Equal = (() => T extends A ? 1 : 2) extends (() => T extends B ? 1 : 2) ? true : false type Assert = T type FactoryArguments = Assert, [option: RuntimeOption]>> type FactoryReturns = Assert>, RuntimeResult>> type EmitReturns = Assert, Promise>> type LoadReturns = Assert, Promise>> type CommandReturns = Assert, Owner>> type OwnerHasNoFacadeKeys = Assert, never>> type VisiblePayload = Assert> type LoadedPayload = Assert> function expectOption(_option: NormalizedOption) {} const row: Danmu = { text: 'extended input', id: 'message-1', author: { name: 'test' }, style: { fontWeight: 'bold' } } const input: Input = () => [row] const asyncInput: Input = async () => [row] const point: Point = [10, 5] const margin: Slider<[number | string, number | string]> = { steps: [{ name: 'half', value: [10, '50%'], hide: true, show: false }] } const options: RuntimeOption = { danmuku: input, points: [point], MARGIN: margin, SPEED: { steps: [{ name: 'fast', value: 2.5, hide: true }] }, filter(danmu) { expectOption(this) const normalized: NormalizedDanmu = danmu const time: number = danmu.time const extension: unknown = danmu.author // @ts-expect-error Queue allocation has not run when filter is invoked. const state: string = danmu.$state void [normalized, time, extension, state] return true }, async beforeEmit(danmu) { expectOption(this) const text: string = danmu.text void text return true }, async beforeVisible(item) { expectOption(this) const state: 'wait' | 'ready' | 'emit' | 'stop' = item.$state const index: number = item.$index const node: HTMLDivElement | null = item.$ref const extra: unknown = item.author void [state, index, node, extra] return true }, } const art = new Artplayer({ container: '#player', url: '/video.mp4', plugins: [runtime(options)] }) const factory: RuntimeFactory = runtime const result = runtime({})(art) const registered: 'artplayerPluginDanmuku' = result.name const icon: string = runtime.icons.$check_on const icons: Icons = runtime.icons runtime.icons = icons runtime.icons.$on = '' const promise: Promise = result.emit(row) const loading: Promise = result.load(asyncInput) const replacing: Promise = result.load() const owner: Owner = result.config({ opacity: 0.5 }) const stopped: Owner = owner.stop().start().suspend().continue().reset() const configured: NormalizedOption = result.option result.option.visible = false result.mount(document.createElement('div')) result.mount('#danmuku-mount') const loadedPayload: EventMap['artplayerPluginDanmuku:loaded'] = [owner.queue] const pointsPayload: EventMap['artplayerPluginDanmuku:points'] = [[point]] const failedPayload: EventMap['artplayerPluginDanmuku:error'] = [new Error('failed')] async function consume() { const emitted = await result.emit({ text: 'await owner' }) const rows: Item[] = emitted.queue const next: Owner = emitted.hide().show() // @ts-expect-error The resolved owner does not expose the facade name. void emitted.name // @ts-expect-error The resolved owner does not own setting.mount. emitted.mount('#mount') return [rows, next] } // @ts-expect-error The factory still requires its options object. runtime() // @ts-expect-error Undefined is not a valid options object. runtime(undefined) // @ts-expect-error An emitted row requires text. result.emit({ id: 'missing-text' }) // @ts-expect-error The runtime heatmap uses mutable pairs, not historical object points. runtime({ points: [{ time: 1, value: 2 }] }) // @ts-expect-error Margin sliders carry pairs rather than scalar numbers. runtime({ MARGIN: { steps: [{ value: 10 }] } }) // @ts-expect-error A live mount needs an explicit destination. result.mount() // @ts-expect-error Facade option is a getter, although the returned options object is mutable. result.option = configured // @ts-expect-error Facade isHide is a getter. result.isHide = true // @ts-expect-error Facade isStop is a getter. result.isStop = true // @ts-expect-error emit returns a Promise; synchronous chaining is not available. result.emit(row).hide() // @ts-expect-error The factory has icons but no default self-reference. void runtime.default export type { CommandReturns, EmitReturns, FactoryArguments, FactoryReturns, LoadedPayload, LoadReturns, OwnerHasNoFacadeKeys, VisiblePayload } void [factory, registered, icon, promise, loading, replacing, stopped, loadedPayload, pointsPayload, failedPayload, consume]