@viostream/viostream-player-svelte 0.1.2 → 0.1.3

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.
@@ -1,222 +1,222 @@
1
- <!--
2
- @component ViostreamPlayer
3
-
4
- Svelte 5 component that embeds a Viostream video player.
5
-
6
- Usage:
7
- ```svelte
8
- <script lang="ts">
9
- import { ViostreamPlayer } from '@viostream/viostream-player-svelte';
10
- import type { ViostreamPlayer as ViostreamPlayerType } from '@viostream/viostream-player-svelte';
11
-
12
- let player: ViostreamPlayerType | undefined = $state();
13
- </script>
14
-
15
- <ViostreamPlayer
16
- accountKey="vc-100100100"
17
- publicKey="nhedxonrxsyfee"
18
- displayTitle={true}
19
- sharing={true}
20
- onplay={() => console.log('playing!')}
21
- ontimeupdate={(d) => console.log('time:', d.seconds)}
22
- onplayerready={(p) => (player = p)}
23
- />
24
- ```
25
- -->
26
- <script lang="ts">
27
- import { onMount, type Snippet } from 'svelte';
28
- import { loadViostream, wrapRawPlayer } from '@viostream/viostream-player-core';
29
- import type {
30
- ViostreamEmbedOptions,
31
- ViostreamPlayer,
32
- RawViostreamPlayerInstance,
33
- ViostreamEventHandler,
34
- } from '@viostream/viostream-player-core';
35
- import type { ViostreamPlayerProps } from './types.js';
36
-
37
- let {
38
- // Required props
39
- accountKey,
40
- publicKey,
41
-
42
- // Embed options
43
- chapters,
44
- chapterDisplayType,
45
- chapterSlug,
46
- displayTitle,
47
- hlsQualitySelector,
48
- playerKey,
49
- sharing,
50
- speedSelector,
51
- startEndTimespan,
52
- startTime,
53
- transcriptDownload,
54
-
55
- // Event callbacks
56
- onplay,
57
- onpause,
58
- onended,
59
- ontimeupdate,
60
- onvolumechange,
61
- onerror,
62
- onprogress,
63
- onready,
64
- onseeked,
65
- onloaded,
66
-
67
- // Component callbacks
68
- onplayerready,
69
-
70
- // Snippet overrides
71
- loading: loadingSnippet,
72
- error: errorSnippet,
73
-
74
- // Styling
75
- class: className,
76
-
77
- // Spread rest for future-proofing
78
- ...restProps
79
- }: ViostreamPlayerProps & {
80
- loading?: Snippet;
81
- error?: Snippet<[string]>;
82
- } = $props();
83
-
84
- // Internal state
85
- let containerEl: HTMLDivElement | undefined = $state();
86
- let player: ViostreamPlayer | undefined = $state();
87
- let errorMsg: string | undefined = $state();
88
- let isLoading = $state(true);
89
-
90
- // Unique ID for the container
91
- const containerId = `viostream-player-${Math.random().toString(36).slice(2, 10)}`;
92
-
93
- // Build the embed options object from props
94
- function buildEmbedOptions(): ViostreamEmbedOptions {
95
- const opts: ViostreamEmbedOptions = {};
96
- if (chapters !== undefined) opts.chapters = chapters;
97
- if (chapterDisplayType !== undefined) opts.chapterDisplayType = chapterDisplayType;
98
- if (chapterSlug !== undefined) opts.chapterSlug = chapterSlug;
99
- if (displayTitle !== undefined) opts.displayTitle = displayTitle;
100
- if (hlsQualitySelector !== undefined) opts.hlsQualitySelector = hlsQualitySelector;
101
- if (playerKey !== undefined) opts.playerKey = playerKey;
102
- if (sharing !== undefined) opts.sharing = sharing;
103
- if (speedSelector !== undefined) opts.speedSelector = speedSelector;
104
- if (startEndTimespan !== undefined) opts.startEndTimespan = startEndTimespan;
105
- if (startTime !== undefined) opts.startTime = startTime;
106
- if (transcriptDownload !== undefined) opts.transcriptDownload = transcriptDownload;
107
- return opts;
108
- }
109
-
110
- // Event wiring: maps event names to their prop callbacks
111
- const EVENT_MAP: Array<[string, (() => ViostreamEventHandler | undefined)]> = [
112
- ['play', () => onplay as ViostreamEventHandler | undefined],
113
- ['pause', () => onpause as ViostreamEventHandler | undefined],
114
- ['ended', () => onended as ViostreamEventHandler | undefined],
115
- ['timeupdate', () => ontimeupdate as ViostreamEventHandler | undefined],
116
- ['volumechange', () => onvolumechange as ViostreamEventHandler | undefined],
117
- ['error', () => onerror as ViostreamEventHandler | undefined],
118
- ['progress', () => onprogress as ViostreamEventHandler | undefined],
119
- ['ready', () => onready as ViostreamEventHandler | undefined],
120
- ['seeked', () => onseeked as ViostreamEventHandler | undefined],
121
- ['loaded', () => onloaded as ViostreamEventHandler | undefined]
122
- ];
123
-
124
- onMount(() => {
125
- let destroyed = false;
126
- const unsubscribers: Array<() => void> = [];
127
-
128
- async function init() {
129
- try {
130
- const api = await loadViostream(accountKey);
131
-
132
- if (destroyed) return;
133
-
134
- const embedOpts = buildEmbedOptions();
135
- const raw: RawViostreamPlayerInstance = api.embed(publicKey, containerId, embedOpts);
136
- const wrappedPlayer = wrapRawPlayer(raw, containerId);
137
-
138
- if (destroyed) {
139
- wrappedPlayer.destroy();
140
- return;
141
- }
142
-
143
- player = wrappedPlayer;
144
- isLoading = false;
145
-
146
- // Wire up event callbacks from props
147
- for (const [eventName, getHandler] of EVENT_MAP) {
148
- const handler = getHandler();
149
- if (handler) {
150
- const unsub = wrappedPlayer.on(eventName, handler);
151
- unsubscribers.push(unsub);
152
- }
153
- }
154
-
155
- // Notify consumer that the player is ready
156
- onplayerready?.(wrappedPlayer);
157
- } catch (err) {
158
- if (!destroyed) {
159
- errorMsg = err instanceof Error ? err.message : String(err);
160
- isLoading = false;
161
- }
162
- }
163
- }
164
-
165
- init();
166
-
167
- return () => {
168
- destroyed = true;
169
- for (const unsub of unsubscribers) {
170
- unsub();
171
- }
172
- player?.destroy();
173
- player = undefined;
174
- };
175
- });
176
-
177
- // Re-wire event handlers reactively when callback props change
178
- // This handles the case where a consumer conditionally provides callbacks
179
- $effect(() => {
180
- if (!player) return;
181
-
182
- const currentUnsubscribers: Array<() => void> = [];
183
-
184
- for (const [eventName, getHandler] of EVENT_MAP) {
185
- const handler = getHandler();
186
- if (handler) {
187
- const unsub = player.on(eventName, handler);
188
- currentUnsubscribers.push(unsub);
189
- }
190
- }
191
-
192
- return () => {
193
- for (const unsub of currentUnsubscribers) {
194
- unsub();
195
- }
196
- };
197
- });
198
- </script>
199
-
200
- <div
201
- id={containerId}
202
- class={className}
203
- bind:this={containerEl}
204
- data-viostream-player
205
- data-viostream-public-key={publicKey}
206
- >
207
- {#if isLoading}
208
- {#if loadingSnippet}
209
- {@render loadingSnippet()}
210
- {/if}
211
- {/if}
212
-
213
- {#if errorMsg}
214
- {#if errorSnippet}
215
- {@render errorSnippet(errorMsg)}
216
- {:else}
217
- <div data-viostream-error style="color: red; padding: 1em;">
218
- Failed to load Viostream player: {errorMsg}
219
- </div>
220
- {/if}
221
- {/if}
222
- </div>
1
+ <!--
2
+ @component ViostreamPlayer
3
+
4
+ Svelte 5 component that embeds a Viostream video player.
5
+
6
+ Usage:
7
+ ```svelte
8
+ <script lang="ts">
9
+ import { ViostreamPlayer } from '@viostream/viostream-player-svelte';
10
+ import type { ViostreamPlayer as ViostreamPlayerType } from '@viostream/viostream-player-svelte';
11
+
12
+ let player: ViostreamPlayerType | undefined = $state();
13
+ </script>
14
+
15
+ <ViostreamPlayer
16
+ accountKey="vc-100100100"
17
+ publicKey="nhedxonrxsyfee"
18
+ displayTitle={true}
19
+ sharing={true}
20
+ onplay={() => console.log('playing!')}
21
+ ontimeupdate={(d) => console.log('time:', d.seconds)}
22
+ onplayerready={(p) => (player = p)}
23
+ />
24
+ ```
25
+ -->
26
+ <script lang="ts">
27
+ import { onMount, type Snippet } from 'svelte';
28
+ import { loadViostream, wrapRawPlayer } from '@viostream/viostream-player-core';
29
+ import type {
30
+ ViostreamEmbedOptions,
31
+ ViostreamPlayer,
32
+ RawViostreamPlayerInstance,
33
+ ViostreamEventHandler,
34
+ } from '@viostream/viostream-player-core';
35
+ import type { ViostreamPlayerProps } from './types.js';
36
+
37
+ let {
38
+ // Required props
39
+ accountKey,
40
+ publicKey,
41
+
42
+ // Embed options
43
+ chapters,
44
+ chapterDisplayType,
45
+ chapterSlug,
46
+ displayTitle,
47
+ hlsQualitySelector,
48
+ playerKey,
49
+ sharing,
50
+ speedSelector,
51
+ startEndTimespan,
52
+ startTime,
53
+ transcriptDownload,
54
+
55
+ // Event callbacks
56
+ onplay,
57
+ onpause,
58
+ onended,
59
+ ontimeupdate,
60
+ onvolumechange,
61
+ onerror,
62
+ onprogress,
63
+ onready,
64
+ onseeked,
65
+ onloaded,
66
+
67
+ // Component callbacks
68
+ onplayerready,
69
+
70
+ // Snippet overrides
71
+ loading: loadingSnippet,
72
+ error: errorSnippet,
73
+
74
+ // Styling
75
+ class: className,
76
+
77
+ // Spread rest for future-proofing
78
+ ...restProps
79
+ }: ViostreamPlayerProps & {
80
+ loading?: Snippet;
81
+ error?: Snippet<[string]>;
82
+ } = $props();
83
+
84
+ // Internal state
85
+ let containerEl: HTMLDivElement | undefined = $state();
86
+ let player: ViostreamPlayer | undefined = $state();
87
+ let errorMsg: string | undefined = $state();
88
+ let isLoading = $state(true);
89
+
90
+ // Unique ID for the container
91
+ const containerId = `viostream-player-${Math.random().toString(36).slice(2, 10)}`;
92
+
93
+ // Build the embed options object from props
94
+ function buildEmbedOptions(): ViostreamEmbedOptions {
95
+ const opts: ViostreamEmbedOptions = {};
96
+ if (chapters !== undefined) opts.chapters = chapters;
97
+ if (chapterDisplayType !== undefined) opts.chapterDisplayType = chapterDisplayType;
98
+ if (chapterSlug !== undefined) opts.chapterSlug = chapterSlug;
99
+ if (displayTitle !== undefined) opts.displayTitle = displayTitle;
100
+ if (hlsQualitySelector !== undefined) opts.hlsQualitySelector = hlsQualitySelector;
101
+ if (playerKey !== undefined) opts.playerKey = playerKey;
102
+ if (sharing !== undefined) opts.sharing = sharing;
103
+ if (speedSelector !== undefined) opts.speedSelector = speedSelector;
104
+ if (startEndTimespan !== undefined) opts.startEndTimespan = startEndTimespan;
105
+ if (startTime !== undefined) opts.startTime = startTime;
106
+ if (transcriptDownload !== undefined) opts.transcriptDownload = transcriptDownload;
107
+ return opts;
108
+ }
109
+
110
+ // Event wiring: maps event names to their prop callbacks
111
+ const EVENT_MAP: Array<[string, (() => ViostreamEventHandler | undefined)]> = [
112
+ ['play', () => onplay as ViostreamEventHandler | undefined],
113
+ ['pause', () => onpause as ViostreamEventHandler | undefined],
114
+ ['ended', () => onended as ViostreamEventHandler | undefined],
115
+ ['timeupdate', () => ontimeupdate as ViostreamEventHandler | undefined],
116
+ ['volumechange', () => onvolumechange as ViostreamEventHandler | undefined],
117
+ ['error', () => onerror as ViostreamEventHandler | undefined],
118
+ ['progress', () => onprogress as ViostreamEventHandler | undefined],
119
+ ['ready', () => onready as ViostreamEventHandler | undefined],
120
+ ['seeked', () => onseeked as ViostreamEventHandler | undefined],
121
+ ['loaded', () => onloaded as ViostreamEventHandler | undefined]
122
+ ];
123
+
124
+ onMount(() => {
125
+ let destroyed = false;
126
+ const unsubscribers: Array<() => void> = [];
127
+
128
+ async function init() {
129
+ try {
130
+ const api = await loadViostream(accountKey);
131
+
132
+ if (destroyed) return;
133
+
134
+ const embedOpts = buildEmbedOptions();
135
+ const raw: RawViostreamPlayerInstance = api.embed(publicKey, containerId, embedOpts);
136
+ const wrappedPlayer = wrapRawPlayer(raw, containerId);
137
+
138
+ if (destroyed) {
139
+ wrappedPlayer.destroy();
140
+ return;
141
+ }
142
+
143
+ player = wrappedPlayer;
144
+ isLoading = false;
145
+
146
+ // Wire up event callbacks from props
147
+ for (const [eventName, getHandler] of EVENT_MAP) {
148
+ const handler = getHandler();
149
+ if (handler) {
150
+ const unsub = wrappedPlayer.on(eventName, handler);
151
+ unsubscribers.push(unsub);
152
+ }
153
+ }
154
+
155
+ // Notify consumer that the player is ready
156
+ onplayerready?.(wrappedPlayer);
157
+ } catch (err) {
158
+ if (!destroyed) {
159
+ errorMsg = err instanceof Error ? err.message : String(err);
160
+ isLoading = false;
161
+ }
162
+ }
163
+ }
164
+
165
+ init();
166
+
167
+ return () => {
168
+ destroyed = true;
169
+ for (const unsub of unsubscribers) {
170
+ unsub();
171
+ }
172
+ player?.destroy();
173
+ player = undefined;
174
+ };
175
+ });
176
+
177
+ // Re-wire event handlers reactively when callback props change
178
+ // This handles the case where a consumer conditionally provides callbacks
179
+ $effect(() => {
180
+ if (!player) return;
181
+
182
+ const currentUnsubscribers: Array<() => void> = [];
183
+
184
+ for (const [eventName, getHandler] of EVENT_MAP) {
185
+ const handler = getHandler();
186
+ if (handler) {
187
+ const unsub = player.on(eventName, handler);
188
+ currentUnsubscribers.push(unsub);
189
+ }
190
+ }
191
+
192
+ return () => {
193
+ for (const unsub of currentUnsubscribers) {
194
+ unsub();
195
+ }
196
+ };
197
+ });
198
+ </script>
199
+
200
+ <div
201
+ id={containerId}
202
+ class={className}
203
+ bind:this={containerEl}
204
+ data-viostream-player
205
+ data-viostream-public-key={publicKey}
206
+ >
207
+ {#if isLoading}
208
+ {#if loadingSnippet}
209
+ {@render loadingSnippet()}
210
+ {/if}
211
+ {/if}
212
+
213
+ {#if errorMsg}
214
+ {#if errorSnippet}
215
+ {@render errorSnippet(errorMsg)}
216
+ {:else}
217
+ <div data-viostream-error style="color: red; padding: 1em;">
218
+ Failed to load Viostream player: {errorMsg}
219
+ </div>
220
+ {/if}
221
+ {/if}
222
+ </div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@viostream/viostream-player-svelte",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Svelte 5 SDK for the Viostream video player — embed, control, and listen to player events",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -30,7 +30,7 @@
30
30
  "!dist/**/*.spec.*"
31
31
  ],
32
32
  "dependencies": {
33
- "@viostream/viostream-player-core": "^0.1.1"
33
+ "@viostream/viostream-player-core": "^0.1.2"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "svelte": "^5.0.0"
@@ -58,4 +58,4 @@
58
58
  "embed",
59
59
  "sdk"
60
60
  ]
61
- }
61
+ }