oddysee-react 0.1.0

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/dist/index.cjs ADDED
@@ -0,0 +1,199 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ useHlsAudioPlayer: () => useHlsAudioPlayer
24
+ });
25
+ module.exports = __toCommonJS(src_exports);
26
+
27
+ // src/use-hls-audio-player.ts
28
+ var import_react = require("react");
29
+ var import_core = require("@hls-audio-player/core");
30
+ var defaultState = {
31
+ track: null,
32
+ currentTime: 0,
33
+ duration: null,
34
+ volume: 1,
35
+ loading: false,
36
+ error: null,
37
+ readyState: 0,
38
+ isPlaying: false
39
+ };
40
+ function useHlsAudioPlayer(options = {}) {
41
+ const { config, src, autoPlay, on } = options;
42
+ const player = (0, import_react.useMemo)(() => {
43
+ return new import_core.HLSAudioPlayer(config);
44
+ }, []);
45
+ const [state, setState] = (0, import_react.useState)(
46
+ () => player.getState() ?? defaultState
47
+ );
48
+ const [loading, setLoading] = (0, import_react.useState)(player.loading ?? false);
49
+ const [error, setError] = (0, import_react.useState)(player.error ?? null);
50
+ const [readyState, setReadyState] = (0, import_react.useState)(player.readyState ?? 0);
51
+ const [isPlaying, setIsPlaying] = (0, import_react.useState)(player.isPlaying ?? false);
52
+ const [duration, setDuration] = (0, import_react.useState)(player.getState()?.duration ?? 0);
53
+ const [isLoading, setIsLoading] = (0, import_react.useState)(player.loading ?? false);
54
+ (0, import_react.useEffect)(() => {
55
+ const handleStateChange = () => {
56
+ const next = player.getState();
57
+ setState(next);
58
+ setLoading(next.loading);
59
+ setError(next.error);
60
+ setReadyState(next.readyState);
61
+ setIsPlaying(next.isPlaying);
62
+ setDuration(next.duration ?? 0);
63
+ setIsLoading(next.loading);
64
+ };
65
+ const listeners = {
66
+ play: (data) => {
67
+ handleStateChange();
68
+ on?.play?.(data);
69
+ },
70
+ pause: (data) => {
71
+ handleStateChange();
72
+ on?.pause?.(data);
73
+ },
74
+ "track-end": (data) => {
75
+ handleStateChange();
76
+ on?.["track-end"]?.(data);
77
+ },
78
+ error: (data) => {
79
+ handleStateChange();
80
+ on?.error?.(data);
81
+ },
82
+ "quality-change": (data) => {
83
+ handleStateChange();
84
+ on?.["quality-change"]?.(data);
85
+ },
86
+ "playlist-ready": (data) => {
87
+ handleStateChange();
88
+ on?.["playlist-ready"]?.(data);
89
+ },
90
+ loadedmetadata: (data) => {
91
+ handleStateChange();
92
+ on?.loadedmetadata?.(data);
93
+ },
94
+ timeupdate: (data) => {
95
+ handleStateChange();
96
+ on?.timeupdate?.(data);
97
+ },
98
+ loading: (data) => {
99
+ handleStateChange();
100
+ on?.loading?.(data);
101
+ },
102
+ canplay: (data) => {
103
+ handleStateChange();
104
+ on?.canplay?.(data);
105
+ }
106
+ };
107
+ Object.keys(listeners).forEach((event) => {
108
+ const handler = listeners[event];
109
+ player.on(event, handler);
110
+ });
111
+ return () => {
112
+ ;
113
+ Object.keys(listeners).forEach((event) => {
114
+ const handler = listeners[event];
115
+ if (handler) {
116
+ player.off(event, handler);
117
+ }
118
+ });
119
+ };
120
+ }, [player, on]);
121
+ (0, import_react.useEffect)(() => {
122
+ let cancelled = false;
123
+ if (!src)
124
+ return;
125
+ player.setSource(src.url, src.options).then((p) => {
126
+ if (cancelled)
127
+ return;
128
+ if (autoPlay) {
129
+ p.play();
130
+ }
131
+ }).catch((err) => {
132
+ if (cancelled)
133
+ return;
134
+ console.error("Failed to set HLS source", err);
135
+ });
136
+ return () => {
137
+ cancelled = true;
138
+ };
139
+ }, [player, src?.url, src?.options, autoPlay]);
140
+ (0, import_react.useEffect)(() => {
141
+ return () => {
142
+ player.destroy();
143
+ };
144
+ }, [player]);
145
+ const controls = (0, import_react.useMemo)(
146
+ () => ({
147
+ setSource: async (url, options2) => {
148
+ try {
149
+ const p = await player.setSource(url, options2);
150
+ if (autoPlay) {
151
+ p.play();
152
+ }
153
+ return p;
154
+ } catch {
155
+ return null;
156
+ }
157
+ },
158
+ play: () => {
159
+ player.play();
160
+ },
161
+ playAsync: async () => {
162
+ try {
163
+ const p = await player.playAsync();
164
+ return p;
165
+ } catch {
166
+ return null;
167
+ }
168
+ },
169
+ pause: () => {
170
+ player.pause();
171
+ },
172
+ setVolume: (volume) => {
173
+ player.setVolume(volume);
174
+ const next = player.getState();
175
+ setState(next);
176
+ },
177
+ setCurrentTime: (time) => {
178
+ const audioElement = player.getAudioElement();
179
+ audioElement.currentTime = time;
180
+ }
181
+ }),
182
+ [player, autoPlay]
183
+ );
184
+ return {
185
+ player,
186
+ state,
187
+ isPlaying,
188
+ duration,
189
+ isLoading,
190
+ loading,
191
+ error,
192
+ readyState,
193
+ controls
194
+ };
195
+ }
196
+ // Annotate the CommonJS export names for ESM import in node:
197
+ 0 && (module.exports = {
198
+ useHlsAudioPlayer
199
+ });
@@ -0,0 +1,49 @@
1
+ import { Track, PlayerError, QualityLevel, PlayerConfig, SourceOptions, PlayerEvent, HLSAudioPlayerInterface, PlayerState } from '@hls-audio-player/core';
2
+
3
+ type PlayerEventMap = {
4
+ play: void;
5
+ pause: void;
6
+ 'track-end': Track | null;
7
+ error: PlayerError;
8
+ 'quality-change': QualityLevel;
9
+ 'playlist-ready': void;
10
+ loadedmetadata: Track | null;
11
+ timeupdate: {
12
+ currentTime: number;
13
+ duration: number | null;
14
+ };
15
+ loading: void;
16
+ canplay: void;
17
+ };
18
+ interface UseHlsAudioPlayerOptions {
19
+ config?: PlayerConfig;
20
+ src?: {
21
+ url: string;
22
+ options?: SourceOptions;
23
+ };
24
+ autoPlay?: boolean;
25
+ on?: Partial<{
26
+ [K in PlayerEvent]: (data: PlayerEventMap[K]) => void;
27
+ }>;
28
+ }
29
+ interface UseHlsAudioPlayerResult {
30
+ player: HLSAudioPlayerInterface | null;
31
+ state: PlayerState;
32
+ isPlaying: boolean;
33
+ duration: number;
34
+ isLoading: boolean;
35
+ loading: boolean;
36
+ error: PlayerError | null;
37
+ readyState: number;
38
+ controls: {
39
+ setSource: (url: string, options?: SourceOptions) => Promise<HLSAudioPlayerInterface | null>;
40
+ play: () => void;
41
+ playAsync: () => Promise<HLSAudioPlayerInterface | null>;
42
+ pause: () => void;
43
+ setVolume: (volume: number) => void;
44
+ setCurrentTime: (time: number) => void;
45
+ };
46
+ }
47
+ declare function useHlsAudioPlayer(options?: UseHlsAudioPlayerOptions): UseHlsAudioPlayerResult;
48
+
49
+ export { PlayerEventMap, UseHlsAudioPlayerOptions, UseHlsAudioPlayerResult, useHlsAudioPlayer };
@@ -0,0 +1,49 @@
1
+ import { Track, PlayerError, QualityLevel, PlayerConfig, SourceOptions, PlayerEvent, HLSAudioPlayerInterface, PlayerState } from '@hls-audio-player/core';
2
+
3
+ type PlayerEventMap = {
4
+ play: void;
5
+ pause: void;
6
+ 'track-end': Track | null;
7
+ error: PlayerError;
8
+ 'quality-change': QualityLevel;
9
+ 'playlist-ready': void;
10
+ loadedmetadata: Track | null;
11
+ timeupdate: {
12
+ currentTime: number;
13
+ duration: number | null;
14
+ };
15
+ loading: void;
16
+ canplay: void;
17
+ };
18
+ interface UseHlsAudioPlayerOptions {
19
+ config?: PlayerConfig;
20
+ src?: {
21
+ url: string;
22
+ options?: SourceOptions;
23
+ };
24
+ autoPlay?: boolean;
25
+ on?: Partial<{
26
+ [K in PlayerEvent]: (data: PlayerEventMap[K]) => void;
27
+ }>;
28
+ }
29
+ interface UseHlsAudioPlayerResult {
30
+ player: HLSAudioPlayerInterface | null;
31
+ state: PlayerState;
32
+ isPlaying: boolean;
33
+ duration: number;
34
+ isLoading: boolean;
35
+ loading: boolean;
36
+ error: PlayerError | null;
37
+ readyState: number;
38
+ controls: {
39
+ setSource: (url: string, options?: SourceOptions) => Promise<HLSAudioPlayerInterface | null>;
40
+ play: () => void;
41
+ playAsync: () => Promise<HLSAudioPlayerInterface | null>;
42
+ pause: () => void;
43
+ setVolume: (volume: number) => void;
44
+ setCurrentTime: (time: number) => void;
45
+ };
46
+ }
47
+ declare function useHlsAudioPlayer(options?: UseHlsAudioPlayerOptions): UseHlsAudioPlayerResult;
48
+
49
+ export { PlayerEventMap, UseHlsAudioPlayerOptions, UseHlsAudioPlayerResult, useHlsAudioPlayer };
@@ -0,0 +1,14 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>react</title>
8
+ <script type="module" crossorigin src="/assets/index-DzSVBDbV.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-COcDBgFa.css">
10
+ </head>
11
+ <body>
12
+ <div id="root"></div>
13
+ </body>
14
+ </html>
package/dist/index.js ADDED
@@ -0,0 +1,174 @@
1
+ // src/use-hls-audio-player.ts
2
+ import { useEffect, useMemo, useState } from "react";
3
+ import {
4
+ HLSAudioPlayer
5
+ } from "@hls-audio-player/core";
6
+ var defaultState = {
7
+ track: null,
8
+ currentTime: 0,
9
+ duration: null,
10
+ volume: 1,
11
+ loading: false,
12
+ error: null,
13
+ readyState: 0,
14
+ isPlaying: false
15
+ };
16
+ function useHlsAudioPlayer(options = {}) {
17
+ const { config, src, autoPlay, on } = options;
18
+ const player = useMemo(() => {
19
+ return new HLSAudioPlayer(config);
20
+ }, []);
21
+ const [state, setState] = useState(
22
+ () => player.getState() ?? defaultState
23
+ );
24
+ const [loading, setLoading] = useState(player.loading ?? false);
25
+ const [error, setError] = useState(player.error ?? null);
26
+ const [readyState, setReadyState] = useState(player.readyState ?? 0);
27
+ const [isPlaying, setIsPlaying] = useState(player.isPlaying ?? false);
28
+ const [duration, setDuration] = useState(player.getState()?.duration ?? 0);
29
+ const [isLoading, setIsLoading] = useState(player.loading ?? false);
30
+ useEffect(() => {
31
+ const handleStateChange = () => {
32
+ const next = player.getState();
33
+ setState(next);
34
+ setLoading(next.loading);
35
+ setError(next.error);
36
+ setReadyState(next.readyState);
37
+ setIsPlaying(next.isPlaying);
38
+ setDuration(next.duration ?? 0);
39
+ setIsLoading(next.loading);
40
+ };
41
+ const listeners = {
42
+ play: (data) => {
43
+ handleStateChange();
44
+ on?.play?.(data);
45
+ },
46
+ pause: (data) => {
47
+ handleStateChange();
48
+ on?.pause?.(data);
49
+ },
50
+ "track-end": (data) => {
51
+ handleStateChange();
52
+ on?.["track-end"]?.(data);
53
+ },
54
+ error: (data) => {
55
+ handleStateChange();
56
+ on?.error?.(data);
57
+ },
58
+ "quality-change": (data) => {
59
+ handleStateChange();
60
+ on?.["quality-change"]?.(data);
61
+ },
62
+ "playlist-ready": (data) => {
63
+ handleStateChange();
64
+ on?.["playlist-ready"]?.(data);
65
+ },
66
+ loadedmetadata: (data) => {
67
+ handleStateChange();
68
+ on?.loadedmetadata?.(data);
69
+ },
70
+ timeupdate: (data) => {
71
+ handleStateChange();
72
+ on?.timeupdate?.(data);
73
+ },
74
+ loading: (data) => {
75
+ handleStateChange();
76
+ on?.loading?.(data);
77
+ },
78
+ canplay: (data) => {
79
+ handleStateChange();
80
+ on?.canplay?.(data);
81
+ }
82
+ };
83
+ Object.keys(listeners).forEach((event) => {
84
+ const handler = listeners[event];
85
+ player.on(event, handler);
86
+ });
87
+ return () => {
88
+ ;
89
+ Object.keys(listeners).forEach((event) => {
90
+ const handler = listeners[event];
91
+ if (handler) {
92
+ player.off(event, handler);
93
+ }
94
+ });
95
+ };
96
+ }, [player, on]);
97
+ useEffect(() => {
98
+ let cancelled = false;
99
+ if (!src)
100
+ return;
101
+ player.setSource(src.url, src.options).then((p) => {
102
+ if (cancelled)
103
+ return;
104
+ if (autoPlay) {
105
+ p.play();
106
+ }
107
+ }).catch((err) => {
108
+ if (cancelled)
109
+ return;
110
+ console.error("Failed to set HLS source", err);
111
+ });
112
+ return () => {
113
+ cancelled = true;
114
+ };
115
+ }, [player, src?.url, src?.options, autoPlay]);
116
+ useEffect(() => {
117
+ return () => {
118
+ player.destroy();
119
+ };
120
+ }, [player]);
121
+ const controls = useMemo(
122
+ () => ({
123
+ setSource: async (url, options2) => {
124
+ try {
125
+ const p = await player.setSource(url, options2);
126
+ if (autoPlay) {
127
+ p.play();
128
+ }
129
+ return p;
130
+ } catch {
131
+ return null;
132
+ }
133
+ },
134
+ play: () => {
135
+ player.play();
136
+ },
137
+ playAsync: async () => {
138
+ try {
139
+ const p = await player.playAsync();
140
+ return p;
141
+ } catch {
142
+ return null;
143
+ }
144
+ },
145
+ pause: () => {
146
+ player.pause();
147
+ },
148
+ setVolume: (volume) => {
149
+ player.setVolume(volume);
150
+ const next = player.getState();
151
+ setState(next);
152
+ },
153
+ setCurrentTime: (time) => {
154
+ const audioElement = player.getAudioElement();
155
+ audioElement.currentTime = time;
156
+ }
157
+ }),
158
+ [player, autoPlay]
159
+ );
160
+ return {
161
+ player,
162
+ state,
163
+ isPlaying,
164
+ duration,
165
+ isLoading,
166
+ loading,
167
+ error,
168
+ readyState,
169
+ controls
170
+ };
171
+ }
172
+ export {
173
+ useHlsAudioPlayer
174
+ };
package/dist/vite.svg ADDED
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
@@ -0,0 +1,23 @@
1
+ import js from '@eslint/js'
2
+ import globals from 'globals'
3
+ import reactHooks from 'eslint-plugin-react-hooks'
4
+ import reactRefresh from 'eslint-plugin-react-refresh'
5
+ import tseslint from 'typescript-eslint'
6
+ import { defineConfig, globalIgnores } from 'eslint/config'
7
+
8
+ export default defineConfig([
9
+ globalIgnores(['dist']),
10
+ {
11
+ files: ['**/*.{ts,tsx}'],
12
+ extends: [
13
+ js.configs.recommended,
14
+ tseslint.configs.recommended,
15
+ reactHooks.configs.flat.recommended,
16
+ reactRefresh.configs.vite,
17
+ ],
18
+ languageOptions: {
19
+ ecmaVersion: 2020,
20
+ globals: globals.browser,
21
+ },
22
+ },
23
+ ])
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "oddysee-react",
3
+ "private": false,
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "version": "0.1.0",
8
+ "type": "module",
9
+ "author": "Karelle Hofler",
10
+ "main": "dist/index.js",
11
+ "types": "dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "import": "./dist/index.js",
15
+ "types": "./dist/index.d.ts"
16
+ }
17
+ },
18
+ "scripts": {
19
+ "build": "tsup src/index.ts --format esm,cjs --dts --tsconfig tsconfig.lib.json",
20
+ "dev": "tsup src/index.ts --format esm,cjs --dts --watch",
21
+ "lint": "eslint .",
22
+ "preview": "vite preview",
23
+ "pub": "npm run build && npm publish",
24
+ "pub:test": "npm run build && npm publish --tag test"
25
+ },
26
+ "dependencies": {
27
+ "@hls-audio-player/core": "^0.1.0",
28
+ "react": "^19.2.0",
29
+ "react-dom": "^19.2.0"
30
+ },
31
+ "devDependencies": {
32
+ "@eslint/js": "^9.39.1",
33
+ "@types/node": "^24.10.1",
34
+ "@types/react": "^19.2.5",
35
+ "@types/react-dom": "^19.2.3",
36
+ "@vitejs/plugin-react": "^5.1.1",
37
+ "eslint": "^9.39.1",
38
+ "eslint-plugin-react-hooks": "^7.0.1",
39
+ "eslint-plugin-react-refresh": "^0.4.24",
40
+ "globals": "^16.5.0",
41
+ "tsup": "7.2.0",
42
+ "typescript": "~5.9.3",
43
+ "typescript-eslint": "^8.46.4",
44
+ "vite": "^7.2.4"
45
+ }
46
+ }
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { useHlsAudioPlayer } from './use-hls-audio-player'
2
+ export type { UseHlsAudioPlayerOptions, UseHlsAudioPlayerResult, PlayerEventMap } from './use-hls-audio-player'