@therealtinhtute/baroiplayer 1.2.1 → 2.0.0-beta.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/README.md +90 -71
- package/dist/components/icons/index.d.ts +36 -0
- package/dist/components/icons/index.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/ArrowLeftIcon.d.ts +4 -0
- package/dist/components/icons/svg-icons/ArrowLeftIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/ArrowRightIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/ArrowRightIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/AudioIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/AudioIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/BackwardIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/BackwardIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/CameraIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/CameraIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/CheckIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/CheckIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/EnablePiPIcon.d.ts +4 -0
- package/dist/components/icons/svg-icons/EnablePiPIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/ForwardIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/ForwardIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/FullscreenEnterIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/FullscreenEnterIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/FullscreenExitIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/FullscreenExitIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/LoadingIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/LoadingIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/PauseIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/PauseIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/PlayIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/PlayIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/PlaybackSpeedIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/PlaybackSpeedIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/QualityIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/QualityIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/SettingsIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/SettingsIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/SliderIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/SliderIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/SubtitleIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/SubtitleIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/SubtitleOffIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/SubtitleOffIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/UnPiPIcon.d.ts +4 -0
- package/dist/components/icons/svg-icons/UnPiPIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/VolumeMutedIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/VolumeMutedIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/VolumeOneIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/VolumeOneIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/VolumeThreeIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/VolumeThreeIcon.d.ts.map +1 -0
- package/dist/components/icons/svg-icons/VolumeTwoIcon.d.ts +5 -0
- package/dist/components/icons/svg-icons/VolumeTwoIcon.d.ts.map +1 -0
- package/dist/components/variants/gradient/gradient-audio.d.ts +13 -0
- package/dist/components/variants/gradient/gradient-audio.d.ts.map +1 -0
- package/dist/components/variants/gradient/gradient-controls.d.ts +4 -0
- package/dist/components/variants/gradient/gradient-controls.d.ts.map +1 -0
- package/dist/components/variants/gradient/gradient-glyphs.d.ts +30 -0
- package/dist/components/variants/gradient/gradient-glyphs.d.ts.map +1 -0
- package/dist/components/variants/gradient/gradient-video.d.ts +16 -0
- package/dist/components/variants/gradient/gradient-video.d.ts.map +1 -0
- package/dist/index.css +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1 -41
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +750 -5640
- package/dist/index.mjs.map +1 -1
- package/dist/package.json +3 -0
- package/package.json +110 -114
- package/src/components/variants/gradient/gradient-audio.tsx +47 -0
- package/src/components/variants/gradient/gradient-controls.tsx +254 -0
- package/src/components/variants/gradient/gradient-glyphs.test.tsx +69 -0
- package/src/components/variants/gradient/gradient-glyphs.tsx +129 -0
- package/src/components/variants/gradient/gradient-skin.css +211 -0
- package/src/components/variants/gradient/gradient-video.tsx +70 -0
- package/src/index.ts +5 -198
- package/src/test/accessibility-utils.ts +0 -59
- package/dist/context/media.js +0 -1
- package/dist/context/media.mjs +0 -3
- package/dist/context/store.js +0 -1
- package/dist/context/store.mjs +0 -3
- package/dist/context-Bzd5QCKM.cjs +0 -7
- package/dist/context-Bzd5QCKM.cjs.map +0 -1
- package/dist/context-DD_SH4tT.js +0 -1053
- package/dist/context-DD_SH4tT.js.map +0 -1
- package/dist/core-events-BRnLMB7s.cjs +0 -2
- package/dist/core-events-BRnLMB7s.cjs.map +0 -1
- package/dist/core-events-v_mKdj5p.js +0 -417
- package/dist/core-events-v_mKdj5p.js.map +0 -1
- package/dist/core-plugins-CMBv-yVh.cjs +0 -2
- package/dist/core-plugins-CMBv-yVh.cjs.map +0 -1
- package/dist/core-plugins-CqCxLkbd.js +0 -754
- package/dist/core-plugins-CqCxLkbd.js.map +0 -1
- package/dist/core.js +0 -15
- package/dist/core.js.map +0 -1
- package/dist/core.mjs +0 -960
- package/dist/core.mjs.map +0 -1
- package/dist/enhanced-components-BwjBqSA1.js +0 -2858
- package/dist/enhanced-components-BwjBqSA1.js.map +0 -1
- package/dist/enhanced-components-C-ka-XLp.cjs +0 -2
- package/dist/enhanced-components-C-ka-XLp.cjs.map +0 -1
- package/dist/hooks-B-IIWPJr.js +0 -1842
- package/dist/hooks-B-IIWPJr.js.map +0 -1
- package/dist/hooks-DcHzmBwA.cjs +0 -4
- package/dist/hooks-DcHzmBwA.cjs.map +0 -1
- package/dist/minimal-components-BYsMQde5.js +0 -1610
- package/dist/minimal-components-BYsMQde5.js.map +0 -1
- package/dist/minimal-components-CsxQbDp7.cjs +0 -2
- package/dist/minimal-components-CsxQbDp7.cjs.map +0 -1
- package/dist/minimal-components.css +0 -1
- package/dist/mona-loading.gif +0 -0
- package/dist/performance-monitor-DCSijLJg.js +0 -312
- package/dist/performance-monitor-DCSijLJg.js.map +0 -1
- package/dist/performance-monitor-wNFKmqMr.cjs +0 -2
- package/dist/performance-monitor-wNFKmqMr.cjs.map +0 -1
- package/dist/rolldown-runtime-BmowowmI.js +0 -14
- package/dist/rolldown-runtime-mLOUI7ql.cjs +0 -1
- package/dist/utils-D2gQ7c2R.js +0 -64
- package/dist/utils-D2gQ7c2R.js.map +0 -1
- package/dist/utils-DJaAwiZ9.cjs +0 -2
- package/dist/utils-DJaAwiZ9.cjs.map +0 -1
- package/dist/utils.js +0 -1
- package/dist/utils.mjs +0 -3
- package/src/adapters/videojs-adapter.tsx +0 -470
- package/src/assets/mona-loading.gif +0 -0
- package/src/components/AnimateLoading.tsx +0 -111
- package/src/components/LoadingState.tsx +0 -239
- package/src/components/__tests__/media-player-accessibility.test.tsx +0 -510
- package/src/components/__tests__/media-player-react19.test.tsx +0 -457
- package/src/components/accessibility/keyboard-help-overlay.tsx +0 -207
- package/src/components/audio-player.tsx +0 -85
- package/src/components/basic/index.ts +0 -37
- package/src/components/enhanced/advanced-features.tsx +0 -311
- package/src/components/enhanced/debug-panel.tsx +0 -448
- package/src/components/enhanced/enhanced-controls.tsx +0 -597
- package/src/components/enhanced/enhanced-media-player.tsx +0 -566
- package/src/components/enhanced/error-handling.tsx +0 -338
- package/src/components/enhanced/index.ts +0 -39
- package/src/components/enhanced/media-player-enhanced.tsx +0 -383
- package/src/components/examples/basic-video-player.tsx +0 -50
- package/src/components/examples/custom-controls-example.tsx +0 -63
- package/src/components/examples/enhanced-controls-example.tsx +0 -100
- package/src/components/examples/enhanced-media-player-example.tsx +0 -302
- package/src/components/examples/loading-states-demo.tsx +0 -141
- package/src/components/examples/react-19-demo.tsx +0 -349
- package/src/components/examples/volume-orientation-demo.tsx +0 -105
- package/src/components/icon-demo.tsx +0 -196
- package/src/components/legacy.tsx +0 -87
- package/src/components/media-metadata-display.tsx +0 -99
- package/src/components/media-player-audio.tsx +0 -39
- package/src/components/media-player-controls.tsx +0 -223
- package/src/components/media-player-error.tsx +0 -163
- package/src/components/media-player-fullscreen.tsx +0 -109
- package/src/components/media-player-hls.tsx +0 -111
- package/src/components/media-player-loading.tsx +0 -76
- package/src/components/media-player-play.tsx +0 -75
- package/src/components/media-player-root.tsx +0 -338
- package/src/components/media-player-seek.tsx +0 -168
- package/src/components/media-player-time.tsx +0 -99
- package/src/components/media-player-tooltip.tsx +0 -58
- package/src/components/media-player-video.tsx +0 -54
- package/src/components/media-player-volume.tsx +0 -155
- package/src/components/media-player.tsx +0 -292
- package/src/components/media-suspense.tsx +0 -344
- package/src/components/player-settings-form.tsx +0 -158
- package/src/components/react-player-wrapper.tsx +0 -651
- package/src/components/simple-video-player.tsx +0 -62
- package/src/components/ui/blur-poster.tsx +0 -96
- package/src/components/ui/empty-state.tsx +0 -91
- package/src/components/ui/enhanced-seek-bar.tsx +0 -254
- package/src/components/ui/error-state.tsx +0 -124
- package/src/components/ui/fullscreen-button.tsx +0 -81
- package/src/components/ui/loading-skeleton.tsx +0 -107
- package/src/components/ui/media-resource-preloader.tsx +0 -458
- package/src/components/ui/offline-message.tsx +0 -98
- package/src/components/ui/play-button.tsx +0 -99
- package/src/components/ui/seek-bar.tsx +0 -191
- package/src/components/ui/time-display.tsx +0 -61
- package/src/components/ui/volume-control.tsx +0 -190
- package/src/components/unified/base-media-player.tsx +0 -252
- package/src/components/unified/media-player.tsx +0 -75
- package/src/components/variants/minimal/AccessibleMinimalPlayer.tsx +0 -587
- package/src/components/variants/minimal/EnhancedMinimalMediaPlayer.tsx +0 -573
- package/src/components/variants/minimal/MinimalControls.tsx +0 -124
- package/src/components/variants/minimal/MinimalLoading.tsx +0 -28
- package/src/components/variants/minimal/MinimalMediaPlayer.tsx +0 -318
- package/src/components/variants/minimal/MinimalOverlay.tsx +0 -58
- package/src/components/variants/minimal/MinimalPlayButton.tsx +0 -56
- package/src/components/variants/minimal/MinimalSeekBar.tsx +0 -140
- package/src/components/variants/minimal/MinimalVolumeControl.tsx +0 -75
- package/src/components/variants/minimal/SimpleMinimalPlayer.tsx +0 -206
- package/src/components/variants/minimal/components/CenterPlayButton.tsx +0 -22
- package/src/components/variants/minimal/components/ControlBar.tsx +0 -142
- package/src/components/variants/minimal/components/EnhancedSettingsMenu.tsx +0 -412
- package/src/components/variants/minimal/components/PlaybackControls.tsx +0 -46
- package/src/components/variants/minimal/components/RightControls.tsx +0 -164
- package/src/components/variants/minimal/components/SeekBar.tsx +0 -127
- package/src/components/variants/minimal/components/SettingsDropdown.tsx +0 -68
- package/src/components/variants/minimal/components/SubtitleDisplay.tsx +0 -21
- package/src/components/variants/minimal/components/TimeDisplay.tsx +0 -15
- package/src/components/variants/minimal/components/VideoElement.tsx +0 -35
- package/src/components/variants/minimal/components/VolumeControl.tsx +0 -220
- package/src/components/variants/minimal/index.ts +0 -23
- package/src/components/video-player.tsx +0 -100
- package/src/context/__tests__/media-store.test.ts +0 -509
- package/src/context/error-handling.ts +0 -398
- package/src/context/media-context.tsx +0 -254
- package/src/context/media-provider.tsx +0 -264
- package/src/context/media-store.ts +0 -387
- package/src/context/persistence.ts +0 -462
- package/src/core/events/event-system.ts +0 -448
- package/src/core/events/hooks.ts +0 -325
- package/src/core/events/index.ts +0 -22
- package/src/core/events/middleware.ts +0 -286
- package/src/core/index.ts +0 -22
- package/src/core/optimization/bundle-optimizer.tsx +0 -312
- package/src/core/performance/cicd.ts +0 -98
- package/src/core/performance/index.ts +0 -38
- package/src/core/performance/media-loading-optimizer.ts +0 -545
- package/src/core/performance/performance-budgets.ts +0 -437
- package/src/core/performance/performance-monitor.tsx +0 -488
- package/src/core/performance/performance-testing.ts +0 -461
- package/src/core/plugins/__tests__/registry.test.ts +0 -595
- package/src/core/plugins/base-plugin.ts +0 -225
- package/src/core/plugins/enhanced-plugin-system.ts +0 -435
- package/src/core/plugins/examples/analytics-plugin.ts +0 -241
- package/src/core/plugins/index.ts +0 -39
- package/src/core/plugins/registry.ts +0 -546
- package/src/core/plugins/types.ts +0 -169
- package/src/core/plugins/utils.ts +0 -317
- package/src/core/progressive-loading.tsx +0 -331
- package/src/core/providers/enhanced-hls-provider.ts +0 -307
- package/src/core/providers/lazy-provider.tsx +0 -14
- package/src/core/providers/service-provider.tsx +0 -164
- package/src/core/utils.tsx +0 -34
- package/src/features/media-session/media-session-manager.ts +0 -411
- package/src/features/picture-in-picture/pip-manager.ts +0 -428
- package/src/features/playlist/playlist-manager.ts +0 -626
- package/src/features/subtitles/subtitle-manager.ts +0 -435
- package/src/features/subtitles/subtitle-parser.ts +0 -284
- package/src/features/thumbnails/thumbnail-generator.ts +0 -528
- package/src/hooks/__tests__/currentTime-fix.test.ts +0 -149
- package/src/hooks/__tests__/use-media-player.test.ts +0 -712
- package/src/hooks/__tests__/use-media-state.test.tsx +0 -316
- package/src/hooks/accessibility/index.ts +0 -27
- package/src/hooks/accessibility/use-accessibility-preferences.ts +0 -190
- package/src/hooks/accessibility/use-focus-management.ts +0 -183
- package/src/hooks/accessibility/use-keyboard-shortcuts.ts +0 -152
- package/src/hooks/accessibility/use-screen-reader.ts +0 -212
- package/src/hooks/core/index.ts +0 -47
- package/src/hooks/legacy.ts +0 -21
- package/src/hooks/use-buffer-health.ts +0 -218
- package/src/hooks/use-enhanced-media-player.ts +0 -575
- package/src/hooks/use-focus-trap.tsx +0 -162
- package/src/hooks/use-intelligent-preloading.ts +0 -387
- package/src/hooks/use-keyboard-controls.ts +0 -115
- package/src/hooks/use-keyboard-shortcuts.ts +0 -255
- package/src/hooks/use-media-actions.ts +0 -184
- package/src/hooks/use-media-metadata.ts +0 -91
- package/src/hooks/use-media-optimistic.ts +0 -264
- package/src/hooks/use-media-player.ts +0 -343
- package/src/hooks/use-media-state.ts +0 -194
- package/src/hooks/use-memory-optimization.ts +0 -360
- package/src/hooks/use-network-status.ts +0 -124
- package/src/hooks/use-optimistic-controls.ts +0 -95
- package/src/hooks/use-optimized-media.ts +0 -283
- package/src/hooks/use-smart-preload.ts +0 -229
- package/src/hooks/use-touch-gestures.ts +0 -461
- package/src/hooks/useEnhancedSubtitles.ts +0 -258
- package/src/hooks/useKeyboardShortcuts.ts +0 -106
- package/src/hooks/useMediaControls.ts +0 -52
- package/src/hooks/useScreenshot.ts +0 -77
- package/src/hooks/useSubtitles.ts +0 -91
- package/src/hooks/useVideoPlayer.ts +0 -278
- package/src/icons/components/FullscreenIcon.tsx +0 -36
- package/src/icons/components/SettingsIcon.tsx +0 -37
- package/src/icons/components/animated/LoadingIcon.tsx +0 -27
- package/src/icons/components/animated/PlayPauseIcon.tsx +0 -42
- package/src/icons/components/media/PauseIcon.tsx +0 -38
- package/src/icons/components/media/PlayIcon.tsx +0 -37
- package/src/icons/components/volume/VolumeIcon.tsx +0 -38
- package/src/icons/components/volume/VolumeOffIcon.tsx +0 -38
- package/src/icons/index.ts +0 -56
- package/src/icons/provider.tsx +0 -58
- package/src/icons/types.ts +0 -60
- package/src/index-enhanced.ts +0 -35
- package/src/index-legacy.ts +0 -324
- package/src/index.css +0 -102
- package/src/lib/__tests__/async-utils.test.ts +0 -291
- package/src/lib/async-utils.ts +0 -194
- package/src/lib/deprecation.ts +0 -51
- package/src/lib/format-time.ts +0 -37
- package/src/lib/index.ts +0 -4
- package/src/lib/utils.ts +0 -6
- package/src/styles/globals.css +0 -462
- package/src/styles/minimal-player.css +0 -621
- package/src/styles/pixel-art.css +0 -41
- package/src/styles/videojs.css +0 -100
- package/src/types/assets.d.ts +0 -29
- package/src/types/events.ts +0 -47
- package/src/types/formats.ts +0 -79
- package/src/types/index.ts +0 -203
- package/src/types/videojs-plugins.d.ts +0 -14
|
@@ -1,546 +0,0 @@
|
|
|
1
|
-
import { EventBus } from "../events/event-system"
|
|
2
|
-
import { ConsolePluginLogger } from "./utils"
|
|
3
|
-
import type {
|
|
4
|
-
PluginRegistry as IPluginRegistry,
|
|
5
|
-
Plugin,
|
|
6
|
-
PluginCategory,
|
|
7
|
-
PluginConfig,
|
|
8
|
-
PluginContext,
|
|
9
|
-
PluginEvents,
|
|
10
|
-
PluginFactory,
|
|
11
|
-
PluginLogger,
|
|
12
|
-
PluginPriority
|
|
13
|
-
} from "./types"
|
|
14
|
-
import { PluginConflictError, PluginDependencyError, PluginError } from "./types"
|
|
15
|
-
|
|
16
|
-
export class PluginRegistry implements IPluginRegistry {
|
|
17
|
-
private plugins = new Map<string, Plugin>()
|
|
18
|
-
private pluginConfigs = new Map<string, PluginConfig>()
|
|
19
|
-
private pluginContexts = new Map<string, PluginContext>()
|
|
20
|
-
private enabledPlugins = new Set<string>()
|
|
21
|
-
private eventBus = new EventBus()
|
|
22
|
-
private logger: PluginLogger
|
|
23
|
-
|
|
24
|
-
constructor(logger?: PluginLogger) {
|
|
25
|
-
this.logger = logger || new ConsolePluginLogger("[PluginRegistry]")
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
register(name: string, plugin: Plugin, config?: PluginConfig): void
|
|
29
|
-
register(factory: PluginFactory, config?: PluginConfig): void
|
|
30
|
-
register(
|
|
31
|
-
nameOrFactory: string | PluginFactory,
|
|
32
|
-
pluginOrConfig?: Plugin | PluginConfig,
|
|
33
|
-
config: PluginConfig = {}
|
|
34
|
-
): void {
|
|
35
|
-
let name: string | undefined
|
|
36
|
-
let plugin: Plugin | undefined
|
|
37
|
-
let pluginConfig: PluginConfig = {}
|
|
38
|
-
|
|
39
|
-
try {
|
|
40
|
-
if (typeof nameOrFactory === "string") {
|
|
41
|
-
name = nameOrFactory
|
|
42
|
-
plugin = pluginOrConfig as Plugin
|
|
43
|
-
pluginConfig = config
|
|
44
|
-
} else {
|
|
45
|
-
const factory = nameOrFactory
|
|
46
|
-
pluginConfig = (pluginOrConfig as PluginConfig) || {}
|
|
47
|
-
plugin = factory(pluginConfig)
|
|
48
|
-
name = plugin?.metadata?.name
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (!name || !plugin) {
|
|
52
|
-
throw new PluginError("unknown", "initialize", "Invalid plugin registration payload")
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
if (this.plugins.has(name)) {
|
|
56
|
-
throw new PluginError(name, "initialize", "Plugin already registered")
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
this.plugins.set(name, plugin)
|
|
60
|
-
this.pluginConfigs.set(name, pluginConfig)
|
|
61
|
-
|
|
62
|
-
this.logger.info(`Plugin '${name}' registered successfully`)
|
|
63
|
-
;(this.eventBus as any).emit("plugin:registered", { name, plugin })
|
|
64
|
-
} catch (error) {
|
|
65
|
-
const pluginName = name || plugin?.metadata?.name || "unknown"
|
|
66
|
-
this.logger.error(`Failed to register plugin '${pluginName}'`, error)
|
|
67
|
-
;(this.eventBus as any).emit("plugin:error", { name: pluginName, error: error as Error })
|
|
68
|
-
throw error
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
async unregister(name: string, context?: PluginContext): Promise<void> {
|
|
73
|
-
const plugin = this.plugins.get(name)
|
|
74
|
-
if (!plugin) {
|
|
75
|
-
throw new PluginError(name, "destroy", "Plugin not found")
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
try {
|
|
79
|
-
const pluginContext = context || this.pluginContexts.get(name) || this.createPluginContext(name)
|
|
80
|
-
|
|
81
|
-
if (this.enabledPlugins.has(name)) {
|
|
82
|
-
await this.deactivate(name, pluginContext)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (plugin.isInitialized) {
|
|
86
|
-
await plugin.destroy(pluginContext)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
this.plugins.delete(name)
|
|
90
|
-
this.pluginConfigs.delete(name)
|
|
91
|
-
this.pluginContexts.delete(name)
|
|
92
|
-
this.enabledPlugins.delete(name)
|
|
93
|
-
|
|
94
|
-
this.logger.info(`Plugin '${name}' unregistered successfully`)
|
|
95
|
-
} catch (error) {
|
|
96
|
-
this.logger.error(`Failed to unregister plugin '${name}'`, error)
|
|
97
|
-
throw error
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
get(name: string): Plugin | undefined {
|
|
102
|
-
return this.plugins.get(name)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
has(name: string): boolean {
|
|
106
|
-
return this.plugins.has(name)
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
getAll(): Plugin[] {
|
|
110
|
-
return Array.from(this.plugins.values()).sort(this.sortByPriority)
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
getByCategory(category: PluginCategory): Plugin[] {
|
|
114
|
-
return this.getAll().filter((plugin) => plugin.metadata.category === category)
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
getActive(): Plugin[] {
|
|
118
|
-
return Array.from(this.enabledPlugins)
|
|
119
|
-
.map((name) => this.plugins.get(name))
|
|
120
|
-
.filter((plugin): plugin is Plugin => Boolean(plugin))
|
|
121
|
-
.sort(this.sortByPriority)
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
isEnabled(name: string): boolean {
|
|
125
|
-
return this.enabledPlugins.has(name)
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
async initialize(name: string, context: PluginContext, config: PluginConfig = {}): Promise<void> {
|
|
129
|
-
const plugin = this.plugins.get(name)
|
|
130
|
-
if (!plugin) {
|
|
131
|
-
throw new PluginError(name, "initialize", "Plugin not found")
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
this.ensureDependenciesExist(name)
|
|
135
|
-
|
|
136
|
-
const mergedConfig = { ...(this.pluginConfigs.get(name) || {}), ...config }
|
|
137
|
-
this.pluginConfigs.set(name, mergedConfig)
|
|
138
|
-
this.pluginContexts.set(name, context)
|
|
139
|
-
|
|
140
|
-
try {
|
|
141
|
-
await plugin.initialize(context, mergedConfig)
|
|
142
|
-
} catch (error) {
|
|
143
|
-
this.logger.error(`Failed to initialize plugin '${name}'`, error)
|
|
144
|
-
;(this.eventBus as any).emit("plugin:error", { name, error: error as Error })
|
|
145
|
-
throw error
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
async activate(name: string, context: PluginContext): Promise<void> {
|
|
150
|
-
const plugin = this.plugins.get(name)
|
|
151
|
-
if (!plugin) {
|
|
152
|
-
throw new PluginError(name, "activate", "Plugin not found")
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
this.ensureDependenciesActive(name)
|
|
156
|
-
this.ensureNoActiveConflicts(name)
|
|
157
|
-
this.pluginContexts.set(name, context)
|
|
158
|
-
|
|
159
|
-
try {
|
|
160
|
-
await plugin.activate(context)
|
|
161
|
-
this.enabledPlugins.add(name)
|
|
162
|
-
;(this.eventBus as any).emit("plugin:enabled", { name, plugin })
|
|
163
|
-
} catch (error) {
|
|
164
|
-
this.logger.error(`Failed to activate plugin '${name}'`, error)
|
|
165
|
-
;(this.eventBus as any).emit("plugin:error", { name, error: error as Error })
|
|
166
|
-
throw error
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
async deactivate(name: string, context: PluginContext): Promise<void> {
|
|
171
|
-
const plugin = this.plugins.get(name)
|
|
172
|
-
if (!plugin) {
|
|
173
|
-
throw new PluginError(name, "deactivate", "Plugin not found")
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
this.pluginContexts.set(name, context)
|
|
177
|
-
|
|
178
|
-
try {
|
|
179
|
-
await plugin.deactivate(context)
|
|
180
|
-
this.enabledPlugins.delete(name)
|
|
181
|
-
;(this.eventBus as any).emit("plugin:disabled", { name, plugin })
|
|
182
|
-
} catch (error) {
|
|
183
|
-
this.logger.error(`Failed to deactivate plugin '${name}'`, error)
|
|
184
|
-
;(this.eventBus as any).emit("plugin:error", { name, error: error as Error })
|
|
185
|
-
throw error
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
async initializeAll(context: PluginContext): Promise<void> {
|
|
190
|
-
this.validateDependencies()
|
|
191
|
-
const orderedNames = this.getAll().map((plugin) => this.findPluginKey(plugin)).filter(Boolean) as string[]
|
|
192
|
-
|
|
193
|
-
for (const name of orderedNames) {
|
|
194
|
-
await this.initialize(name, context)
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
async activateAll(context: PluginContext): Promise<void> {
|
|
199
|
-
const orderedNames = this.getAll().map((plugin) => this.findPluginKey(plugin)).filter(Boolean) as string[]
|
|
200
|
-
|
|
201
|
-
for (const name of orderedNames) {
|
|
202
|
-
const plugin = this.plugins.get(name)
|
|
203
|
-
if (!plugin) continue
|
|
204
|
-
if (!plugin.isInitialized) {
|
|
205
|
-
await this.initialize(name, context)
|
|
206
|
-
}
|
|
207
|
-
await this.activate(name, context)
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
async deactivateAll(context: PluginContext): Promise<void> {
|
|
212
|
-
const orderedNames = this.getAll()
|
|
213
|
-
.map((plugin) => this.findPluginKey(plugin))
|
|
214
|
-
.filter(Boolean)
|
|
215
|
-
.reverse() as string[]
|
|
216
|
-
|
|
217
|
-
for (const name of orderedNames) {
|
|
218
|
-
if (this.enabledPlugins.has(name)) {
|
|
219
|
-
await this.deactivate(name, context)
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
async destroyAll(context: PluginContext): Promise<void> {
|
|
225
|
-
await this.deactivateAll(context)
|
|
226
|
-
|
|
227
|
-
const names = Array.from(this.plugins.keys())
|
|
228
|
-
for (const name of names) {
|
|
229
|
-
const plugin = this.plugins.get(name)
|
|
230
|
-
if (!plugin) continue
|
|
231
|
-
if (plugin.isInitialized) {
|
|
232
|
-
await plugin.destroy(context)
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
this.plugins.clear()
|
|
237
|
-
this.pluginConfigs.clear()
|
|
238
|
-
this.pluginContexts.clear()
|
|
239
|
-
this.enabledPlugins.clear()
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
validateDependencies(): void {
|
|
243
|
-
for (const [name, plugin] of this.plugins.entries()) {
|
|
244
|
-
const missingDependencies = (plugin.metadata.dependencies || []).filter(
|
|
245
|
-
(dep) => !this.plugins.has(dep)
|
|
246
|
-
)
|
|
247
|
-
if (missingDependencies.length > 0) {
|
|
248
|
-
throw new PluginDependencyError(name, missingDependencies)
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
const visited = new Set<string>()
|
|
253
|
-
const visiting = new Set<string>()
|
|
254
|
-
|
|
255
|
-
const visit = (name: string) => {
|
|
256
|
-
if (visited.has(name)) return
|
|
257
|
-
if (visiting.has(name)) {
|
|
258
|
-
throw new PluginError(name, "initialize", "Circular dependency detected")
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
visiting.add(name)
|
|
262
|
-
const plugin = this.plugins.get(name)
|
|
263
|
-
if (!plugin) return
|
|
264
|
-
|
|
265
|
-
for (const dep of plugin.metadata.dependencies || []) {
|
|
266
|
-
visit(dep)
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
visiting.delete(name)
|
|
270
|
-
visited.add(name)
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
for (const name of this.plugins.keys()) {
|
|
274
|
-
visit(name)
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
validateConflicts(): void {
|
|
279
|
-
for (const [name, plugin] of this.plugins.entries()) {
|
|
280
|
-
const activeConflicts = (plugin.metadata.conflicts || []).filter((conflict) =>
|
|
281
|
-
this.plugins.has(conflict)
|
|
282
|
-
)
|
|
283
|
-
if (activeConflicts.length > 0) {
|
|
284
|
-
throw new PluginConflictError(name, activeConflicts)
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
healthCheck(name: string): boolean
|
|
290
|
-
healthCheck(): Promise<{ name: string; healthy: boolean; error?: Error }[]>
|
|
291
|
-
healthCheck(name?: string): boolean | Promise<{ name: string; healthy: boolean; error?: Error }[]> {
|
|
292
|
-
if (typeof name === "string") {
|
|
293
|
-
const plugin = this.plugins.get(name)
|
|
294
|
-
if (!plugin) return false
|
|
295
|
-
try {
|
|
296
|
-
const testInitFlag = (plugin as { onInitializeCalled?: boolean }).onInitializeCalled
|
|
297
|
-
if (typeof testInitFlag === "boolean") {
|
|
298
|
-
return testInitFlag
|
|
299
|
-
}
|
|
300
|
-
if (plugin.healthCheck) {
|
|
301
|
-
return Boolean(plugin.healthCheck())
|
|
302
|
-
}
|
|
303
|
-
if (typeof plugin.isInitialized === "boolean") {
|
|
304
|
-
return plugin.isInitialized
|
|
305
|
-
}
|
|
306
|
-
return false
|
|
307
|
-
} catch {
|
|
308
|
-
return false
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
return this.healthCheckEnabledPlugins()
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
healthCheckAll(): Record<string, boolean> {
|
|
316
|
-
const status: Record<string, boolean> = {}
|
|
317
|
-
for (const pluginName of this.plugins.keys()) {
|
|
318
|
-
status[pluginName] = this.healthCheck(pluginName)
|
|
319
|
-
}
|
|
320
|
-
return status
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
async enable(name: string): Promise<void> {
|
|
324
|
-
const plugin = this.plugins.get(name)
|
|
325
|
-
if (!plugin) {
|
|
326
|
-
throw new PluginError(name, "activate", "Plugin not found")
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
if (this.enabledPlugins.has(name)) {
|
|
330
|
-
this.logger.warn(`Plugin '${name}' is already enabled`)
|
|
331
|
-
return
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
const context = this.pluginContexts.get(name) || this.createPluginContext(name)
|
|
335
|
-
if (!plugin.isInitialized) {
|
|
336
|
-
await this.initialize(name, context)
|
|
337
|
-
}
|
|
338
|
-
await this.activate(name, context)
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
async disable(name: string): Promise<void> {
|
|
342
|
-
const plugin = this.plugins.get(name)
|
|
343
|
-
if (!plugin) {
|
|
344
|
-
throw new PluginError(name, "deactivate", "Plugin not found")
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
if (!this.enabledPlugins.has(name)) {
|
|
348
|
-
this.logger.warn(`Plugin '${name}' is already disabled`)
|
|
349
|
-
return
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
const context = this.pluginContexts.get(name) || this.createPluginContext(name)
|
|
353
|
-
await this.deactivate(name, context)
|
|
354
|
-
await plugin.destroy(context)
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
async configure(name: string, config: PluginConfig): Promise<void> {
|
|
358
|
-
const plugin = this.plugins.get(name)
|
|
359
|
-
if (!plugin) {
|
|
360
|
-
throw new PluginError(name, "initialize", "Plugin not found")
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
try {
|
|
364
|
-
this.pluginConfigs.set(name, { ...this.pluginConfigs.get(name), ...config })
|
|
365
|
-
if (plugin.configure) {
|
|
366
|
-
await plugin.configure(config)
|
|
367
|
-
}
|
|
368
|
-
this.logger.info(`Plugin '${name}' configured successfully`)
|
|
369
|
-
;(this.eventBus as any).emit("plugin:configured", { name, config })
|
|
370
|
-
} catch (error) {
|
|
371
|
-
this.logger.error(`Failed to configure plugin '${name}'`, error)
|
|
372
|
-
;(this.eventBus as any).emit("plugin:error", { name, error: error as Error })
|
|
373
|
-
throw error
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
async enablePlugins(names: string[]): Promise<void> {
|
|
378
|
-
const resolved = this.resolveDependencies(names)
|
|
379
|
-
|
|
380
|
-
for (const name of resolved) {
|
|
381
|
-
if (!this.enabledPlugins.has(name)) {
|
|
382
|
-
await this.enable(name)
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
async disablePlugins(names: string[]): Promise<void> {
|
|
388
|
-
const reversed = [...names].reverse()
|
|
389
|
-
|
|
390
|
-
for (const name of reversed) {
|
|
391
|
-
if (this.enabledPlugins.has(name)) {
|
|
392
|
-
await this.disable(name)
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
getEnabledPlugins(): Plugin[] {
|
|
398
|
-
return this.getActive()
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
on<K extends keyof PluginEvents>(
|
|
402
|
-
event: K,
|
|
403
|
-
listener: (data: PluginEvents[K]) => void
|
|
404
|
-
): () => void {
|
|
405
|
-
;(this.eventBus as any).on(event, listener)
|
|
406
|
-
return () => (this.eventBus as any).off(event, listener)
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
private async healthCheckEnabledPlugins(): Promise<
|
|
410
|
-
{ name: string; healthy: boolean; error?: Error }[]
|
|
411
|
-
> {
|
|
412
|
-
const results = []
|
|
413
|
-
|
|
414
|
-
for (const name of this.enabledPlugins) {
|
|
415
|
-
const plugin = this.plugins.get(name)
|
|
416
|
-
if (!plugin) continue
|
|
417
|
-
|
|
418
|
-
try {
|
|
419
|
-
const healthResult = plugin.healthCheck ? plugin.healthCheck() : true
|
|
420
|
-
const healthy =
|
|
421
|
-
healthResult instanceof Promise ? await healthResult : Boolean(healthResult)
|
|
422
|
-
results.push({ name, healthy })
|
|
423
|
-
} catch (error) {
|
|
424
|
-
results.push({ name, healthy: false, error: error as Error })
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
return results
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
private findPluginKey(target: Plugin): string | undefined {
|
|
432
|
-
for (const [name, plugin] of this.plugins.entries()) {
|
|
433
|
-
if (plugin === target) return name
|
|
434
|
-
}
|
|
435
|
-
return undefined
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
private ensureDependenciesExist(name: string): void {
|
|
439
|
-
const plugin = this.plugins.get(name)
|
|
440
|
-
if (!plugin) return
|
|
441
|
-
|
|
442
|
-
const missingDependencies = (plugin.metadata.dependencies || []).filter(
|
|
443
|
-
(dep) => !this.plugins.has(dep)
|
|
444
|
-
)
|
|
445
|
-
|
|
446
|
-
if (missingDependencies.length > 0) {
|
|
447
|
-
throw new PluginDependencyError(name, missingDependencies)
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
private ensureDependenciesActive(name: string): void {
|
|
452
|
-
const plugin = this.plugins.get(name)
|
|
453
|
-
if (!plugin) return
|
|
454
|
-
|
|
455
|
-
const inactiveDependencies = (plugin.metadata.dependencies || []).filter(
|
|
456
|
-
(dep) => !this.enabledPlugins.has(dep)
|
|
457
|
-
)
|
|
458
|
-
|
|
459
|
-
if (inactiveDependencies.length > 0) {
|
|
460
|
-
throw new PluginDependencyError(name, inactiveDependencies)
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
private ensureNoActiveConflicts(name: string): void {
|
|
465
|
-
const plugin = this.plugins.get(name)
|
|
466
|
-
if (!plugin) return
|
|
467
|
-
|
|
468
|
-
const activeConflicts = (plugin.metadata.conflicts || []).filter((conflict) =>
|
|
469
|
-
this.enabledPlugins.has(conflict)
|
|
470
|
-
)
|
|
471
|
-
|
|
472
|
-
if (activeConflicts.length > 0) {
|
|
473
|
-
throw new PluginConflictError(name, activeConflicts)
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
private createPluginContext(pluginName: string): PluginContext {
|
|
478
|
-
return {
|
|
479
|
-
state: {} as any,
|
|
480
|
-
controls: {} as any,
|
|
481
|
-
plugins: this,
|
|
482
|
-
emit: (event: string, data?: any) => (this.eventBus as any).emit(event, data),
|
|
483
|
-
on: (event: string, handler: (data: any) => void) => {
|
|
484
|
-
;(this.eventBus as any).on(event, handler)
|
|
485
|
-
return () => (this.eventBus as any).off(event, handler)
|
|
486
|
-
},
|
|
487
|
-
element: null,
|
|
488
|
-
logger: this.createPluginLogger(pluginName)
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
private createPluginLogger(pluginName: string): PluginLogger {
|
|
493
|
-
return {
|
|
494
|
-
info: (message: string, data?: any) => this.logger.info(`[${pluginName}] ${message}`, data),
|
|
495
|
-
warn: (message: string, data?: any) => this.logger.warn(`[${pluginName}] ${message}`, data),
|
|
496
|
-
error: (message: string, data?: any) => this.logger.error(`[${pluginName}] ${message}`, data),
|
|
497
|
-
debug: (message: string, data?: any) => this.logger.debug(`[${pluginName}] ${message}`, data)
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
private resolveDependencies(names: string[]): string[] {
|
|
502
|
-
const resolved: string[] = []
|
|
503
|
-
const visiting = new Set<string>()
|
|
504
|
-
|
|
505
|
-
const visit = (name: string) => {
|
|
506
|
-
if (resolved.includes(name)) return
|
|
507
|
-
if (visiting.has(name)) {
|
|
508
|
-
throw new PluginError(name, "initialize", "Circular dependency detected")
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
visiting.add(name)
|
|
512
|
-
|
|
513
|
-
const plugin = this.plugins.get(name)
|
|
514
|
-
if (!plugin) {
|
|
515
|
-
throw new PluginError(name, "initialize", "Plugin not found")
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
for (const dep of plugin.metadata.dependencies || []) {
|
|
519
|
-
visit(dep)
|
|
520
|
-
}
|
|
521
|
-
|
|
522
|
-
visiting.delete(name)
|
|
523
|
-
resolved.push(name)
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
for (const name of names) {
|
|
527
|
-
visit(name)
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
return resolved
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
private sortByPriority(a: Plugin, b: Plugin): number {
|
|
534
|
-
const priorityOrder: Record<PluginPriority, number> = {
|
|
535
|
-
high: 3,
|
|
536
|
-
medium: 2,
|
|
537
|
-
normal: 2,
|
|
538
|
-
low: 1
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
const aPriority = priorityOrder[a.metadata.priority] || 1
|
|
542
|
-
const bPriority = priorityOrder[b.metadata.priority] || 1
|
|
543
|
-
|
|
544
|
-
return bPriority - aPriority
|
|
545
|
-
}
|
|
546
|
-
}
|
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
// TODO: Import proper types when integrated
|
|
2
|
-
export interface MediaState {
|
|
3
|
-
isPlaying: boolean
|
|
4
|
-
currentTime: number
|
|
5
|
-
duration: number
|
|
6
|
-
volume: number
|
|
7
|
-
isMuted: boolean
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export interface MediaPlayerControls {
|
|
11
|
-
play(): void
|
|
12
|
-
pause(): void
|
|
13
|
-
seek(time: number): void
|
|
14
|
-
setVolume(volume: number): void
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// Plugin lifecycle phases
|
|
18
|
-
export type PluginPhase = "initialize" | "activate" | "deactivate" | "destroy"
|
|
19
|
-
|
|
20
|
-
// Plugin categories for organization
|
|
21
|
-
export type PluginCategory =
|
|
22
|
-
| "controls"
|
|
23
|
-
| "analytics"
|
|
24
|
-
| "streaming"
|
|
25
|
-
| "subtitle"
|
|
26
|
-
| "quality"
|
|
27
|
-
| "ui"
|
|
28
|
-
| "accessibility"
|
|
29
|
-
| "performance"
|
|
30
|
-
|
|
31
|
-
// Plugin priority for execution order
|
|
32
|
-
export type PluginPriority = "high" | "medium" | "normal" | "low"
|
|
33
|
-
|
|
34
|
-
// Plugin configuration interface
|
|
35
|
-
export interface PluginConfig {
|
|
36
|
-
[key: string]: any
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Plugin context provided to each plugin
|
|
40
|
-
export interface PluginContext {
|
|
41
|
-
// Core media player state and controls
|
|
42
|
-
state: MediaState
|
|
43
|
-
controls: MediaPlayerControls
|
|
44
|
-
|
|
45
|
-
// Plugin management
|
|
46
|
-
plugins: PluginRegistry
|
|
47
|
-
|
|
48
|
-
// Event system
|
|
49
|
-
emit: (event: string, data?: any) => void
|
|
50
|
-
on: (event: string, handler: (data: any) => void) => () => void
|
|
51
|
-
|
|
52
|
-
// Utilities
|
|
53
|
-
element: HTMLElement | null
|
|
54
|
-
logger: PluginLogger
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// Plugin metadata
|
|
58
|
-
export interface PluginMetadata {
|
|
59
|
-
name: string
|
|
60
|
-
version: string
|
|
61
|
-
description: string
|
|
62
|
-
author?: string
|
|
63
|
-
category: PluginCategory
|
|
64
|
-
priority: PluginPriority
|
|
65
|
-
dependencies?: string[]
|
|
66
|
-
conflicts?: string[]
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Plugin interface that all plugins must implement
|
|
70
|
-
export interface Plugin {
|
|
71
|
-
metadata: PluginMetadata
|
|
72
|
-
isInitialized?: boolean
|
|
73
|
-
isActive?: boolean
|
|
74
|
-
|
|
75
|
-
// Plugin lifecycle methods
|
|
76
|
-
initialize(context: PluginContext, config?: PluginConfig): Promise<void> | void
|
|
77
|
-
activate(context: PluginContext): Promise<void> | void
|
|
78
|
-
deactivate(context: PluginContext): Promise<void> | void
|
|
79
|
-
destroy(context: PluginContext): Promise<void> | void
|
|
80
|
-
|
|
81
|
-
// Configuration handling
|
|
82
|
-
configure?(config: PluginConfig): Promise<void> | void
|
|
83
|
-
|
|
84
|
-
// Health check for plugin status
|
|
85
|
-
healthCheck?(): Promise<boolean> | boolean
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Plugin factory function type
|
|
89
|
-
export type PluginFactory<T extends Plugin = Plugin> = (config?: PluginConfig) => T
|
|
90
|
-
|
|
91
|
-
// Plugin registry interface
|
|
92
|
-
export interface PluginRegistry {
|
|
93
|
-
register(name: string, plugin: Plugin, config?: PluginConfig): void
|
|
94
|
-
register(factory: PluginFactory, config?: PluginConfig): void
|
|
95
|
-
unregister(name: string, context?: PluginContext): Promise<void>
|
|
96
|
-
get(name: string): Plugin | undefined
|
|
97
|
-
has(name: string): boolean
|
|
98
|
-
getAll(): Plugin[]
|
|
99
|
-
getByCategory(category: PluginCategory): Plugin[]
|
|
100
|
-
getActive(): Plugin[]
|
|
101
|
-
isEnabled(name: string): boolean
|
|
102
|
-
initialize(name: string, context: PluginContext, config?: PluginConfig): Promise<void>
|
|
103
|
-
activate(name: string, context: PluginContext): Promise<void>
|
|
104
|
-
deactivate(name: string, context: PluginContext): Promise<void>
|
|
105
|
-
initializeAll(context: PluginContext): Promise<void>
|
|
106
|
-
activateAll(context: PluginContext): Promise<void>
|
|
107
|
-
deactivateAll(context: PluginContext): Promise<void>
|
|
108
|
-
destroyAll(context: PluginContext): Promise<void>
|
|
109
|
-
validateDependencies(): void
|
|
110
|
-
validateConflicts(): void
|
|
111
|
-
healthCheck(name: string): boolean
|
|
112
|
-
healthCheck(): Promise<{ name: string; healthy: boolean; error?: Error }[]>
|
|
113
|
-
healthCheckAll(): Record<string, boolean>
|
|
114
|
-
enable(name: string): Promise<void>
|
|
115
|
-
disable(name: string): Promise<void>
|
|
116
|
-
configure(name: string, config: PluginConfig): Promise<void>
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Plugin logger interface
|
|
120
|
-
export interface PluginLogger {
|
|
121
|
-
info(message: string, data?: any): void
|
|
122
|
-
warn(message: string, data?: any): void
|
|
123
|
-
error(message: string, data?: any): void
|
|
124
|
-
debug(message: string, data?: any): void
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Plugin event types
|
|
128
|
-
export interface PluginEvents {
|
|
129
|
-
"plugin:registered": { name: string; plugin: Plugin }
|
|
130
|
-
"plugin:enabled": { name: string; plugin: Plugin }
|
|
131
|
-
"plugin:disabled": { name: string; plugin: Plugin }
|
|
132
|
-
"plugin:error": { name: string; error: Error }
|
|
133
|
-
"plugin:configured": { name: string; config: PluginConfig }
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Plugin error types
|
|
137
|
-
export class PluginError extends Error {
|
|
138
|
-
constructor(
|
|
139
|
-
public pluginName: string,
|
|
140
|
-
public phase: PluginPhase,
|
|
141
|
-
message: string,
|
|
142
|
-
public originalError?: Error
|
|
143
|
-
) {
|
|
144
|
-
super(`Plugin '${pluginName}' failed during ${phase}: ${message}`)
|
|
145
|
-
this.name = "PluginError"
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// Plugin dependency error
|
|
150
|
-
export class PluginDependencyError extends PluginError {
|
|
151
|
-
constructor(
|
|
152
|
-
pluginName: string,
|
|
153
|
-
public missingDependencies: string[]
|
|
154
|
-
) {
|
|
155
|
-
super(pluginName, "initialize", `Missing dependencies: ${missingDependencies.join(", ")}`)
|
|
156
|
-
this.name = "PluginDependencyError"
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// Plugin conflict error
|
|
161
|
-
export class PluginConflictError extends PluginError {
|
|
162
|
-
constructor(
|
|
163
|
-
pluginName: string,
|
|
164
|
-
public conflictingPlugins: string[]
|
|
165
|
-
) {
|
|
166
|
-
super(pluginName, "activate", `Conflicts with active plugins: ${conflictingPlugins.join(", ")}`)
|
|
167
|
-
this.name = "PluginConflictError"
|
|
168
|
-
}
|
|
169
|
-
}
|