@growth-labs/video 0.3.1 → 0.3.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@growth-labs/video",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -54,12 +54,13 @@ const captionsSrc = showCaptions
54
54
  data-video-id={videoId}
55
55
  data-premium={premium ? 'true' : 'false'}
56
56
  data-session-route={premium ? config.premium?.sessionRoute : undefined}
57
+ data-pending-src={premium ? src : undefined}
57
58
  data-chapters-src={chaptersSrc}
58
59
  data-captions-src={captionsSrc}
59
60
  data-captions-lang={captionsLang}
60
61
  data-progress-marks={JSON.stringify(config.analytics.progressMarks)}
61
62
  title={title}
62
- src={src}
63
+ src={premium ? undefined : src}
63
64
  poster={poster}
64
65
  preload={config.player.preload}
65
66
  autoplay={Astro.props.autoplay ?? config.player.autoplay}
@@ -82,6 +83,8 @@ const captionsSrc = showCaptions
82
83
  </media-player>
83
84
 
84
85
  <script>
86
+ import { bootstrapPremiumPlayer } from './premium-bootstrap'
87
+
85
88
  import('vidstack/elements').then((mod: any) => {
86
89
  if (typeof mod.defineCustomElements === 'function') {
87
90
  mod.defineCustomElements()
@@ -90,36 +93,16 @@ const captionsSrc = showCaptions
90
93
 
91
94
  const VIDEO_ACCESS_DENIED = 'gl:video-access-denied'
92
95
 
96
+ // Premium players ship without `src` and with `data-pending-src` carrying
97
+ // the manifest URL. Establish the session cookie *before* Vidstack loads
98
+ // the manifest — otherwise preload="metadata" 401s on mount.
93
99
  document.querySelectorAll<HTMLElement>('media-player[data-premium="true"]').forEach((player) => {
94
- const videoId = player.dataset.videoId
95
- const sessionRoute = player.dataset.sessionRoute
96
- if (!videoId || !sessionRoute) return
97
-
98
- let sessionChecked = false
99
- const ensure = async () => {
100
- if (sessionChecked) return
101
- sessionChecked = true
102
- try {
103
- const res = await fetch(sessionRoute, {
104
- method: 'POST',
105
- credentials: 'same-origin',
106
- headers: { 'Content-Type': 'application/json' },
107
- body: JSON.stringify({ videoId }),
108
- })
109
- if (!res.ok) {
110
- window.dispatchEvent(
111
- new CustomEvent(VIDEO_ACCESS_DENIED, { detail: { videoId } }),
112
- )
113
- }
114
- } catch {
100
+ bootstrapPremiumPlayer(player as unknown as Parameters<typeof bootstrapPremiumPlayer>[0], {
101
+ emitAccessDenied: (videoId) =>
115
102
  window.dispatchEvent(
116
103
  new CustomEvent(VIDEO_ACCESS_DENIED, { detail: { videoId } }),
117
- )
118
- }
119
- }
120
-
121
- player.addEventListener('pointerenter', ensure, { once: true })
122
- player.addEventListener('play', ensure)
104
+ ),
105
+ })
123
106
  })
124
107
 
125
108
  const emit = (name: string, detail: unknown) =>
@@ -0,0 +1,38 @@
1
+ export interface PremiumPlayerLike {
2
+ dataset: { videoId?: string; sessionRoute?: string; pendingSrc?: string }
3
+ src?: string
4
+ }
5
+
6
+ export interface BootstrapOptions {
7
+ fetch?: typeof fetch
8
+ emitAccessDenied?: (videoId: string) => void
9
+ }
10
+
11
+ export async function bootstrapPremiumPlayer(
12
+ player: PremiumPlayerLike,
13
+ opts: BootstrapOptions = {},
14
+ ): Promise<'authorized' | 'denied' | 'skipped'> {
15
+ const { videoId, sessionRoute, pendingSrc } = player.dataset
16
+ if (!videoId || !sessionRoute) return 'skipped'
17
+
18
+ const f = opts.fetch ?? fetch
19
+ let ok = false
20
+ try {
21
+ const res = await f(sessionRoute, {
22
+ method: 'POST',
23
+ credentials: 'same-origin',
24
+ headers: { 'Content-Type': 'application/json' },
25
+ body: JSON.stringify({ videoId }),
26
+ })
27
+ ok = res.ok
28
+ } catch {
29
+ ok = false
30
+ }
31
+
32
+ if (ok) {
33
+ if (pendingSrc) player.src = pendingSrc
34
+ return 'authorized'
35
+ }
36
+ opts.emitAccessDenied?.(videoId)
37
+ return 'denied'
38
+ }