@hopecloud/jetstream-player 1.3.0 → 1.4.0-rc.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 CHANGED
@@ -1,10 +1,14 @@
1
- # @hopecloud/jetstream-player
1
+ # Jetstream Player SDK
2
2
 
3
- Control an embedded [Jetstream](https://jetstream-player.docs.hope.cloud/) player
4
- from your page play, pause, seek, mute, read playback state, and subscribe to
5
- events across the iframe boundary, with no server glue.
3
+ Put the [Jetstream](https://docs.hope.cloud/libs/jetstream-player/) Player on
4
+ your website and drive it from your own code. The player itself lives in an
5
+ iframe served by Jetstream; this SDK is your remote control for it — play,
6
+ pause, seek, mute, ask what's happening, and react to events, without ever
7
+ thinking about the iframe boundary.
6
8
 
7
- **[Full documentation →](https://jetstream-player.docs.hope.cloud/)**
9
+ It works the same way for videos, audio, and whole playlists.
10
+
11
+ **[Full documentation →](https://docs.hope.cloud/libs/jetstream-player/)**
8
12
 
9
13
  ## Install
10
14
 
@@ -14,6 +18,14 @@ npm i @hopecloud/jetstream-player
14
18
 
15
19
  ## Quick start
16
20
 
21
+ Give the player a place on your page — any element with an id:
22
+
23
+ ```html
24
+ <div id="player"></div>
25
+ ```
26
+
27
+ Then create the player and tell it what to play:
28
+
17
29
  ```ts
18
30
  import { JetstreamPlayer } from '@hopecloud/jetstream-player';
19
31
 
@@ -21,7 +33,7 @@ const player = new JetstreamPlayer('#player', {
21
33
  mediaId: 'jsv:xxxxxxxxxx',
22
34
  events: {
23
35
  ready: () => console.log('ready'),
24
- timeupdate: (time) => console.log('time', time),
36
+ timeupdate: (seconds) => console.log('now at', seconds),
25
37
  },
26
38
  });
27
39
 
@@ -29,48 +41,56 @@ player.play();
29
41
  const muted = await player.isMuted();
30
42
  ```
31
43
 
32
- `mediaId` is the only required option; the library creates and mounts the iframe
33
- at the given selector.
44
+ `mediaId` a video, an audio, or a playlist id from Jetstream — is the only
45
+ required option. The SDK creates the iframe and mounts it inside your element;
46
+ no other markup needed.
34
47
 
35
48
  ## What you can do
36
49
 
37
- - **Commands** — `play()`, `pause()`, `mute()`, `unmute()`, `seekTo(seconds)`,
38
- `playNext()`, `playPrev()`.
39
- - **Getters** (Promise-based) — `isMuted()`, `isPaused()`,
40
- `getVideoCurrentTime()`, `getDuration()`. They reject after 5s if the player
41
- doesn't reply.
42
- - **Events** — subscribe via `options.events`: `ready`, `timeupdate`, `play`,
43
- `pause`, `loadedmetadata`, `ended`, `volumechange`, `error`.
44
- - **Teardown** `dispose()` removes listeners and tears down Picture-in-Picture.
50
+ - **Control playback** — `play()`, `pause()`, `seekTo(seconds)`, `mute()`,
51
+ `unmute()`, and `playNext()` / `playPrev()` for playlists.
52
+ - **Ask the player questions** — `isMuted()`, `isPaused()`, `getCurrentTime()`,
53
+ `getDuration()`. The answers come from the player itself, so these return
54
+ Promises (and reject after 5 seconds if the player doesn't reply).
55
+ - **React to events** — pass handlers in `options.events`, or subscribe later
56
+ with `on()` (it returns an unsubscribe function): `ready`, `play`, `pause`,
57
+ `timeupdate`, `loadedmetadata`, `ended`, `volumechange`, `error`.
58
+ - **Keep it on screen** — `sticky: true` pins the player to a corner of the
59
+ screen when the visitor scrolls past it.
60
+ - **Clean up** — `dispose()` when your page removes the player.
45
61
 
46
- See the [options](https://jetstream-player.docs.hope.cloud/api/player-options)
47
- and [methods](https://jetstream-player.docs.hope.cloud/api/player-methods)
48
- reference for the full list.
62
+ Start with [Getting Started](https://docs.hope.cloud/libs/jetstream-player/getting-started),
63
+ then see [Player Options](https://docs.hope.cloud/libs/jetstream-player/player-options)
64
+ and [Player Methods](https://docs.hope.cloud/libs/jetstream-player/player-methods)
65
+ for everything you can configure and call.
49
66
 
50
- ## Targeting a non-prod embed
67
+ ## Pointing at a staging environment
51
68
 
52
- By default the player loads the production embed. Point it at another host
53
- (staging/dev) with `origin`:
69
+ By default the player loads the production embed. For special setups a
70
+ staging or dev environment — point it elsewhere with `embedOrigin`:
54
71
 
55
72
  ```ts
56
- new JetstreamPlayer('#player', {
73
+ const player = new JetstreamPlayer('#player', {
57
74
  mediaId: 'jsv:xxxxxxxxxx',
58
- origin: 'https://embed-stage.jetstream.studio',
75
+ embedOrigin: 'https://embed-stage.jetstream.studio',
59
76
  });
60
77
  ```
61
78
 
62
- Communication is cross-origin `postMessage`, and the SDK learns the iframe's
63
- real origin at runtime — so it keeps working even when the embed redirects.
79
+ Under the hood everything is cross-origin `postMessage`, and the SDK learns
80
+ the iframe's real origin at runtime — so it keeps working even when the embed
81
+ host redirects.
64
82
 
65
83
  ## Development
66
84
 
67
85
  ```bash
68
86
  pnpm install
69
- pnpm build # rolldown + .d.ts
70
- pnpm test # vitest
71
- pnpm lint
72
- pnpm typecheck
73
- pnpm docs:dev # vitepress docs
87
+ pnpm build # vp pack — bundle + .d.ts
88
+ pnpm test # vp test (vitest)
89
+ pnpm check # format check + type-aware lint + type errors (the CI gate)
74
90
  ```
75
91
 
76
- Architecture decisions are recorded in [`adr/`](./adr).
92
+ Documentation lives in the monorepo's public docs site at
93
+ `docs/cloud/libs/jetstream-player/`, published to docs.hope.cloud.
94
+
95
+ Architecture decisions are recorded in the monorepo at
96
+ `docs/adr/jetstream-player/`.
package/dist/index.d.ts CHANGED
@@ -1,2 +1,78 @@
1
- export { JetstreamPlayer } from './player';
2
- export * from './player.type';
1
+ //#region src/bridge/protocol.types.d.ts
2
+ interface PlayerEventMap {
3
+ ready: unknown;
4
+ timeupdate: number;
5
+ play: unknown;
6
+ pause: unknown;
7
+ loadedmetadata: undefined;
8
+ ended: boolean;
9
+ volumechange: number;
10
+ error: unknown;
11
+ }
12
+ type PlayerEvents = keyof PlayerEventMap;
13
+ declare const playerListenEvents: readonly PlayerEvents[];
14
+ type PlayerGetterEvents = "is-muted" | "get-current-time" | "get-video-current-time" | "get-duration" | "is-paused";
15
+ interface PlayerEvent {
16
+ type: PlayerEvents | PlayerGetterEvents;
17
+ value?: unknown;
18
+ }
19
+ type PlayerCommandEvent = "play" | "pause" | "mute" | "unmute" | "seek-to" | "seekTo" | "play-next" | "play-prev";
20
+ interface PlayerCommand {
21
+ name: PlayerCommandEvent | PlayerGetterEvents;
22
+ params?: unknown;
23
+ }
24
+ //#endregion
25
+ //#region src/embed/embed-frame.types.d.ts
26
+ interface EmbedFrameOptions {
27
+ mediaId: string;
28
+ playerId?: string;
29
+ region?: "eu";
30
+ audioLang?: string;
31
+ subtitleLang?: string;
32
+ embedOrigin?: string;
33
+ /** @deprecated Use {@link embedOrigin} instead. */
34
+ origin?: string;
35
+ width?: string;
36
+ height?: string;
37
+ }
38
+ //#endregion
39
+ //#region src/player.types.d.ts
40
+ type PlayerEventHandler<E extends PlayerEvents = PlayerEvents> = (value: PlayerEventMap[E]) => void;
41
+ type PlayerEventHandlers = { [E in PlayerEvents]?: PlayerEventHandler<E> };
42
+ type JetstreamPlayerOptions = {
43
+ sticky?: boolean;
44
+ events?: PlayerEventHandlers;
45
+ } & EmbedFrameOptions;
46
+ //#endregion
47
+ //#region src/player.d.ts
48
+ declare class JetstreamPlayer {
49
+ private options;
50
+ private readonly listeners;
51
+ private iFramePiP;
52
+ private bridge;
53
+ constructor(el: string, options: JetstreamPlayerOptions);
54
+ private registerEvents;
55
+ private emit;
56
+ on<E extends PlayerEvents>(event: E, handler: PlayerEventHandler<E>): () => void;
57
+ off<E extends PlayerEvents>(event: E, handler?: PlayerEventHandler<E>): void;
58
+ private request;
59
+ play(): void;
60
+ pause(): void;
61
+ mute(): void;
62
+ unmute(): void;
63
+ seekTo(seconds: number): void;
64
+ playNext(): void;
65
+ playPrev(): void;
66
+ isMuted(): Promise<boolean>;
67
+ isPaused(): Promise<boolean>;
68
+ getCurrentTime(): Promise<number>;
69
+ /** @deprecated Use {@link getCurrentTime} instead. */
70
+ getVideoCurrentTime(): Promise<number>;
71
+ getDuration(): Promise<number>;
72
+ dispose(): void;
73
+ }
74
+ //#endregion
75
+ //#region src/bridge/protocol.d.ts
76
+ declare const decodeCommand: (raw: string) => PlayerCommand | null;
77
+ //#endregion
78
+ export { type EmbedFrameOptions, JetstreamPlayer, type JetstreamPlayerOptions, type PlayerCommand, type PlayerCommandEvent, type PlayerEvent, type PlayerEventHandler, type PlayerEventHandlers, type PlayerEventMap, type PlayerEvents, type PlayerGetterEvents, decodeCommand, playerListenEvents };
package/dist/index.js CHANGED
@@ -1,5 +1,86 @@
1
- //#region src/embed-frame.ts
2
- const DEFAULT_ORIGIN = "https://jstre.am";
1
+ //#region src/bridge/protocol.ts
2
+ const encode = (command) => JSON.stringify(command);
3
+ const parseObjectWithStringKey = (raw, key) => {
4
+ if (typeof raw !== "string") return null;
5
+ try {
6
+ const parsed = JSON.parse(raw);
7
+ if (typeof parsed === "object" && parsed !== null && typeof parsed[key] === "string") return parsed;
8
+ return null;
9
+ } catch {
10
+ return null;
11
+ }
12
+ };
13
+ const decode = (raw) => parseObjectWithStringKey(raw, "type");
14
+ const decodeCommand = (raw) => parseObjectWithStringKey(raw, "name");
15
+ //#endregion
16
+ //#region src/bridge/player-bridge.ts
17
+ const REQUEST_TIMEOUT_MS = 5e3;
18
+ var PlayerBridge = class {
19
+ transport;
20
+ targetOrigin;
21
+ listeners = /* @__PURE__ */ new Set();
22
+ detach;
23
+ constructor(transport, initialTargetOrigin) {
24
+ this.transport = transport;
25
+ this.targetOrigin = initialTargetOrigin;
26
+ this.detach = this.transport.subscribe((message, origin) => {
27
+ const event = decode(message);
28
+ if (!event) return;
29
+ this.targetOrigin = origin;
30
+ this.listeners.forEach((listener) => listener(event));
31
+ });
32
+ }
33
+ send(command) {
34
+ this.transport.send(encode(command), this.targetOrigin);
35
+ }
36
+ subscribe(listener) {
37
+ this.listeners.add(listener);
38
+ return () => {
39
+ this.listeners.delete(listener);
40
+ };
41
+ }
42
+ request(command, timeoutMs = REQUEST_TIMEOUT_MS) {
43
+ return new Promise((resolve, reject) => {
44
+ let off = () => void 0;
45
+ const timer = setTimeout(() => {
46
+ off();
47
+ reject(/* @__PURE__ */ new Error(`Timed out waiting for "${command.name}" response`));
48
+ }, timeoutMs);
49
+ off = this.subscribe((event) => {
50
+ if (event.type === command.name) {
51
+ clearTimeout(timer);
52
+ off();
53
+ resolve(event.value);
54
+ }
55
+ });
56
+ this.send(command);
57
+ });
58
+ }
59
+ dispose() {
60
+ this.detach();
61
+ this.listeners.clear();
62
+ }
63
+ };
64
+ //#endregion
65
+ //#region src/bridge/player-transport.ts
66
+ const windowTransport = (iframe) => ({
67
+ send: (message, targetOrigin) => {
68
+ iframe.contentWindow?.postMessage(message, targetOrigin);
69
+ },
70
+ subscribe: (handler) => {
71
+ const listener = (event) => {
72
+ if (event.source !== iframe.contentWindow) return;
73
+ handler(event.data, event.origin);
74
+ };
75
+ window.addEventListener("message", listener);
76
+ return () => {
77
+ window.removeEventListener("message", listener);
78
+ };
79
+ }
80
+ });
81
+ //#endregion
82
+ //#region src/embed/embed-frame.ts
83
+ const DEFAULT_EMBED_ORIGIN = "https://jstre.am";
3
84
  const regionOrigin = (origin, region) => {
4
85
  const url = new URL(origin);
5
86
  if (region === "eu") {
@@ -11,9 +92,9 @@ const regionOrigin = (origin, region) => {
11
92
  };
12
93
  const buildEmbedSrc = (options) => {
13
94
  if (options.mediaId === "") throw new Error("mediaId not provided!");
14
- const origin = regionOrigin(options.origin ?? DEFAULT_ORIGIN, options.region);
95
+ const embedOrigin = regionOrigin(options.embedOrigin ?? options.origin ?? DEFAULT_EMBED_ORIGIN, options.region);
15
96
  const path = options.playerId ? `/embed/${options.mediaId}/${options.playerId}` : `/embed/${options.mediaId}`;
16
- const url = new URL(`${origin}${path}`);
97
+ const url = new URL(`${embedOrigin}${path}`);
17
98
  if (options.region === "eu") url.searchParams.append("region", "eu");
18
99
  if (options.audioLang) url.searchParams.append("audioLang", options.audioLang.toLowerCase());
19
100
  if (options.subtitleLang) url.searchParams.append("subtitleLang", options.subtitleLang.toLowerCase());
@@ -24,12 +105,12 @@ const mountEmbedFrame = (selector, options) => {
24
105
  const iframe = document.createElement("iframe");
25
106
  iframe.allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture";
26
107
  iframe.allowFullscreen = true;
27
- iframe.frameBorder = "0";
28
- iframe.title = "Jetstream player";
108
+ iframe.style.border = "0";
109
+ iframe.title = "Jetstream Player";
29
110
  iframe.src = src;
30
111
  iframe.width = options.width || "480px";
31
112
  iframe.height = options.height || "270px";
32
- iframe.classList.add("jet-stream-iframe-player");
113
+ iframe.classList.add("jetstream-player-iframe");
33
114
  const parent = document.querySelector(selector);
34
115
  if (parent) parent.appendChild(iframe);
35
116
  else console.error(`Element matching selector "${selector}" not found.`);
@@ -39,7 +120,7 @@ const mountEmbedFrame = (selector, options) => {
39
120
  };
40
121
  };
41
122
  //#endregion
42
- //#region src/iframe-pip-plugin.ts
123
+ //#region src/pip/iframe-pip-plugin.ts
43
124
  const PiP_STYLES = {
44
125
  position: "fixed",
45
126
  bottom: "20px",
@@ -55,8 +136,6 @@ var IFramePiPPlugin = class {
55
136
  originalIframeStyle = null;
56
137
  parent = null;
57
138
  constructor(containerSelector, iframe) {
58
- this.containerSelector = containerSelector;
59
- this.iframe = iframe;
60
139
  this.containerSelector = containerSelector;
61
140
  this.iframe = iframe;
62
141
  this.init();
@@ -68,8 +147,10 @@ var IFramePiPPlugin = class {
68
147
  this.parent = parent;
69
148
  this.originalParentHeight = parent.style.height || null;
70
149
  this.originalIframeStyle = this.iframe.getAttribute("style");
71
- this.observer = new IntersectionObserver(([{ isIntersecting }]) => {
72
- if (!isIntersecting) {
150
+ this.observer = new IntersectionObserver((entries) => {
151
+ const entry = entries[0];
152
+ if (!entry) return;
153
+ if (!entry.isIntersecting) {
73
154
  const height = parent.getBoundingClientRect().height;
74
155
  parent.style.height = `${height}px`;
75
156
  this.iframe.style.position = PiP_STYLES.position;
@@ -98,90 +179,8 @@ var IFramePiPPlugin = class {
98
179
  if (this.iframe) if (this.originalIframeStyle) this.iframe.setAttribute("style", this.originalIframeStyle);
99
180
  else this.iframe.removeAttribute("style");
100
181
  }
101
- destory() {
102
- this.destroy();
103
- }
104
- };
105
- //#endregion
106
- //#region src/protocol.ts
107
- const encode = (command) => JSON.stringify(command);
108
- const decode = (raw) => {
109
- if (typeof raw !== "string") return null;
110
- try {
111
- const parsed = JSON.parse(raw);
112
- if (typeof parsed === "object" && parsed !== null && typeof parsed.type === "string") return parsed;
113
- return null;
114
- } catch {
115
- return null;
116
- }
117
- };
118
- //#endregion
119
- //#region src/player-bridge.ts
120
- const REQUEST_TIMEOUT_MS = 5e3;
121
- var PlayerBridge = class {
122
- transport;
123
- targetOrigin;
124
- listeners = /* @__PURE__ */ new Set();
125
- detach;
126
- constructor(transport, initialTargetOrigin) {
127
- this.transport = transport;
128
- this.targetOrigin = initialTargetOrigin;
129
- this.detach = this.transport.subscribe((message, origin) => {
130
- const event = decode(message);
131
- if (!event) return;
132
- this.targetOrigin = origin;
133
- this.listeners.forEach((listener) => listener(event));
134
- });
135
- }
136
- send(command) {
137
- this.transport.send(encode(command), this.targetOrigin);
138
- }
139
- subscribe(listener) {
140
- this.listeners.add(listener);
141
- return () => {
142
- this.listeners.delete(listener);
143
- };
144
- }
145
- request(command, timeoutMs = REQUEST_TIMEOUT_MS) {
146
- return new Promise((resolve, reject) => {
147
- let off = () => void 0;
148
- const timer = setTimeout(() => {
149
- off();
150
- reject(/* @__PURE__ */ new Error(`Timed out waiting for "${command.name}" response`));
151
- }, timeoutMs);
152
- off = this.subscribe((event) => {
153
- if (event.type === command.name) {
154
- clearTimeout(timer);
155
- off();
156
- resolve(event.value);
157
- }
158
- });
159
- this.send(command);
160
- });
161
- }
162
- dispose() {
163
- this.detach();
164
- this.listeners.clear();
165
- }
166
182
  };
167
183
  //#endregion
168
- //#region src/player-transport.ts
169
- const windowTransport = (iframe) => ({
170
- send: (message, targetOrigin) => {
171
- iframe.contentWindow?.postMessage(message, targetOrigin);
172
- },
173
- subscribe: (handler) => {
174
- const listener = (event) => {
175
- if (event.source !== iframe.contentWindow) return;
176
- handler(event.data, event.origin);
177
- };
178
- window.addEventListener("message", listener);
179
- return () => {
180
- window.removeEventListener("message", listener);
181
- };
182
- }
183
- });
184
- //#endregion
185
184
  //#region src/player.ts
186
185
  var JetstreamPlayer = class {
187
186
  options;
@@ -256,7 +255,7 @@ var JetstreamPlayer = class {
256
255
  }
257
256
  seekTo(seconds) {
258
257
  this.bridge?.send({
259
- name: "seekTo",
258
+ name: "seek-to",
260
259
  params: seconds
261
260
  });
262
261
  }
@@ -272,8 +271,12 @@ var JetstreamPlayer = class {
272
271
  isPaused() {
273
272
  return this.request({ name: "is-paused" });
274
273
  }
274
+ getCurrentTime() {
275
+ return this.request({ name: "get-current-time" });
276
+ }
277
+ /** @deprecated Use {@link getCurrentTime} instead. */
275
278
  getVideoCurrentTime() {
276
- return this.request({ name: "get-video-current-time" });
279
+ return this.getCurrentTime();
277
280
  }
278
281
  getDuration() {
279
282
  return this.request({ name: "get-duration" });
@@ -285,7 +288,7 @@ var JetstreamPlayer = class {
285
288
  }
286
289
  };
287
290
  //#endregion
288
- //#region src/player.type.ts
291
+ //#region src/bridge/protocol.types.ts
289
292
  const playerListenEvents = [
290
293
  "ready",
291
294
  "timeupdate",
@@ -297,4 +300,4 @@ const playerListenEvents = [
297
300
  "error"
298
301
  ];
299
302
  //#endregion
300
- export { JetstreamPlayer, playerListenEvents };
303
+ export { JetstreamPlayer, decodeCommand, playerListenEvents };
package/package.json CHANGED
@@ -1,54 +1,39 @@
1
1
  {
2
2
  "name": "@hopecloud/jetstream-player",
3
- "version": "1.3.0",
3
+ "version": "1.4.0-rc.1",
4
4
  "description": "Jetstream Embed Player SDK",
5
- "type": "module",
6
- "sideEffects": false,
7
- "repository": {
8
- "type": "git",
9
- "url": "git+https://github.com/hopechannel/hopecloud.git",
10
- "directory": "libs/jetstream-player"
11
- },
12
- "homepage": "https://jetstream-player.docs.hope.cloud/",
13
- "engines": {
14
- "node": "24"
15
- },
16
- "publishConfig": {
17
- "access": "public"
5
+ "homepage": "https://docs.hope.cloud/libs/jetstream-player/",
6
+ "author": {
7
+ "name": "DV Software",
8
+ "email": "code@deepvision.software"
18
9
  },
19
- "main": "dist/index.js",
20
10
  "files": [
21
11
  "dist"
22
12
  ],
13
+ "type": "module",
14
+ "sideEffects": false,
15
+ "main": "dist/index.js",
23
16
  "exports": {
24
17
  ".": {
25
18
  "types": "./dist/index.d.ts",
26
19
  "import": "./dist/index.js"
27
20
  }
28
21
  },
29
- "author": {
30
- "email": "code@deepvision.software",
31
- "name": "DV Software"
22
+ "publishConfig": {
23
+ "access": "public"
32
24
  },
33
25
  "devDependencies": {
34
- "@deepvision/eslint-plugin": "2.0.3",
35
26
  "@types/node": "24.12.0",
36
- "eslint": "10.1.0",
37
27
  "happy-dom": "^20.4.0",
38
- "rolldown": "^1.1.4",
39
- "typescript": "6.0.3",
40
- "vitepress": "^1.6.4",
41
- "vitest": "^4.0.18"
28
+ "vite-plus": "^0.2.2"
29
+ },
30
+ "engines": {
31
+ "node": "24"
42
32
  },
43
33
  "scripts": {
44
- "build": "rolldown --config && tsc --emitDeclarationOnly",
45
- "docs:dev": "vitepress dev docs",
46
- "docs:build": "vitepress build docs",
47
- "docs:preview": "vitepress preview docs",
48
- "lint": "eslint",
49
- "lint:fix": "eslint --fix",
50
- "type-check": "tsc --noEmit",
51
- "test": "vitest",
52
- "test:run": "vitest run"
34
+ "build": "vp pack",
35
+ "check": "vp check",
36
+ "check:fix": "vp check --fix",
37
+ "test": "vp test"
53
38
  }
54
39
  }
@@ -1,7 +0,0 @@
1
- import type { EmbedFrameOptions } from './player.type';
2
- export declare const buildEmbedSrc: (options: EmbedFrameOptions) => string;
3
- export interface MountedFrame {
4
- iframe: HTMLIFrameElement;
5
- src: string;
6
- }
7
- export declare const mountEmbedFrame: (selector: string, options: EmbedFrameOptions) => MountedFrame;
@@ -1,12 +0,0 @@
1
- export declare class IFramePiPPlugin {
2
- containerSelector: string;
3
- iframe: HTMLIFrameElement;
4
- private observer;
5
- private originalParentHeight;
6
- private originalIframeStyle;
7
- private parent;
8
- constructor(containerSelector: string, iframe: HTMLIFrameElement);
9
- init(): void;
10
- destroy(): void;
11
- destory(): void;
12
- }
@@ -1,13 +0,0 @@
1
- import type { PlayerCommand, PlayerEvent } from './player.type';
2
- import type { PlayerTransport } from './player-transport';
3
- export declare class PlayerBridge {
4
- private readonly transport;
5
- private targetOrigin;
6
- private readonly listeners;
7
- private readonly detach;
8
- constructor(transport: PlayerTransport, initialTargetOrigin: string);
9
- send(command: PlayerCommand): void;
10
- subscribe(listener: (event: PlayerEvent) => void): () => void;
11
- request<T>(command: PlayerCommand, timeoutMs?: number): Promise<T>;
12
- dispose(): void;
13
- }
@@ -1,5 +0,0 @@
1
- export interface PlayerTransport {
2
- send(message: string, targetOrigin: string): void;
3
- subscribe(handler: (message: string, origin: string) => void): () => void;
4
- }
5
- export declare const windowTransport: (iframe: HTMLIFrameElement) => PlayerTransport;
package/dist/player.d.ts DELETED
@@ -1,25 +0,0 @@
1
- import type { PlayerEvents, JetstreamPlayerOptions, PlayerEventHandler } from './player.type';
2
- export declare class JetstreamPlayer {
3
- private options;
4
- private readonly listeners;
5
- private iFramePiP;
6
- private bridge;
7
- constructor(el: string, options: JetstreamPlayerOptions);
8
- private registerEvents;
9
- private emit;
10
- on(event: PlayerEvents, handler: PlayerEventHandler): () => void;
11
- off(event: PlayerEvents, handler?: PlayerEventHandler): void;
12
- private request;
13
- play(): void;
14
- pause(): void;
15
- mute(): void;
16
- unmute(): void;
17
- seekTo(seconds: number): void;
18
- playNext(): void;
19
- playPrev(): void;
20
- isMuted(): Promise<boolean>;
21
- isPaused(): Promise<boolean>;
22
- getVideoCurrentTime(): Promise<number>;
23
- getDuration(): Promise<number>;
24
- dispose(): void;
25
- }
@@ -1,27 +0,0 @@
1
- export declare const playerListenEvents: readonly ["ready", "timeupdate", "play", "pause", "loadedmetadata", "ended", "volumechange", "error"];
2
- export type PlayerEvents = 'ready' | 'timeupdate' | 'play' | 'pause' | 'loadedmetadata' | 'ended' | 'volumechange' | 'error';
3
- export type PlayerGetterEvents = 'is-muted' | 'get-video-current-time' | 'get-duration' | 'is-paused';
4
- export interface PlayerEvent {
5
- type: PlayerEvents | PlayerGetterEvents;
6
- value?: unknown;
7
- }
8
- export type PlayerEventHandler = (value?: unknown) => void;
9
- export type PlayerCommandEvent = 'play' | 'pause' | 'mute' | 'unmute' | 'seekTo' | 'play-next' | 'play-prev';
10
- export interface PlayerCommand {
11
- name: PlayerCommandEvent | PlayerGetterEvents;
12
- params?: unknown;
13
- }
14
- export interface EmbedFrameOptions {
15
- mediaId: string;
16
- playerId?: string;
17
- region?: 'eu';
18
- audioLang?: string;
19
- subtitleLang?: string;
20
- origin?: string;
21
- width?: string;
22
- height?: string;
23
- }
24
- export type JetstreamPlayerOptions = {
25
- sticky?: boolean;
26
- events?: Partial<Record<PlayerEvents, PlayerEventHandler>>;
27
- } & EmbedFrameOptions;
@@ -1,3 +0,0 @@
1
- import type { PlayerCommand, PlayerEvent } from './player.type';
2
- export declare const encode: (command: PlayerCommand) => string;
3
- export declare const decode: (raw: string) => PlayerEvent | null;