@rivmux/runtime-worker 0.4.0 → 1.0.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 +7 -1
- package/dist/index.d.ts +16 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +111 -8
- package/dist/index.js.map +1 -1
- package/dist/rivmux-runtime-worker.d.ts +57 -40
- package/dist/rivmux-runtime-worker.d.ts.map +1 -1
- package/dist/rivmux-runtime-worker.js +1026 -414
- package/dist/rivmux-runtime-worker.js.map +1 -1
- package/dist/rivmux-transmux-core.wasm +0 -0
- package/package.json +5 -9
package/README.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
# Rivmux Runtime Worker
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`@rivmux/runtime-worker` 是 Rivmux 主包使用的 Dedicated Worker 运行时,负责 HTTP-FLV 加载、WASM 转封装核心、MSE SourceBuffer、播放延迟控制、重连和生命周期清理。
|
|
4
|
+
|
|
5
|
+
该包提供 Worker 脚本、WASM 资产和内部生命周期客户端,普通用户不应直接依赖。用户接入请使用 `rivmux`,以获得稳定的播放器 API、类型和错误语义。
|
|
6
|
+
|
|
7
|
+
当前运行时固定为 Worker MSE;配置在初始化命令中确定,运行期间不支持动态选项更新。播放器公共初始化事件由 facade 暴露为 `initialized`,Worker 内部消息名称不属于公共 API。
|
|
8
|
+
|
|
9
|
+
维护时需保证 Worker/WASM 资产来自同一次构建,并保持与 `@rivmux/protocol` 的消息契约一致。应用部署必须验证资产 URL、CSP/CORS 和缓存策略,并确保 Worker 与 WASM 资产来自同一版本。
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { NormalizedRivmuxPlayerOptions, PlayerError, WorkerCommand, WorkerMessage } from "@rivmux/protocol";
|
|
2
2
|
//#region src/index.d.ts
|
|
3
|
-
type WorkerLike = Pick<Worker, 'addEventListener' | 'postMessage' | 'removeEventListener' | 'terminate'>;
|
|
4
|
-
type RuntimeWorkerFactory = (options: NormalizedRivmuxPlayerOptions) => WorkerLike;
|
|
5
|
-
type WorkerClientHooks = {
|
|
3
|
+
export type WorkerLike = Pick<Worker, 'addEventListener' | 'postMessage' | 'removeEventListener' | 'terminate'>;
|
|
4
|
+
export type RuntimeWorkerFactory = (options: NormalizedRivmuxPlayerOptions) => WorkerLike;
|
|
5
|
+
export type WorkerClientHooks = {
|
|
6
6
|
onMessage(message: WorkerMessage): void;
|
|
7
7
|
onError(error: PlayerError): void;
|
|
8
8
|
};
|
|
@@ -12,39 +12,48 @@ type WorkerClientHooks = {
|
|
|
12
12
|
* Vite rewrites this static URL during the client build and emits the matching
|
|
13
13
|
* binary next to the application assets.
|
|
14
14
|
*/
|
|
15
|
-
declare function getBundledWasmUrl(): string;
|
|
16
|
-
declare class WorkerClient {
|
|
15
|
+
export declare function getBundledWasmUrl(): string;
|
|
16
|
+
export declare class WorkerClient {
|
|
17
17
|
private readonly worker;
|
|
18
18
|
private readonly hooks;
|
|
19
19
|
private readonly handleMessage;
|
|
20
20
|
private readonly handleError;
|
|
21
21
|
private pendingAttach?;
|
|
22
|
+
private pendingStart?;
|
|
22
23
|
private pendingStop?;
|
|
23
24
|
private pendingDestroy?;
|
|
24
25
|
private workerReady;
|
|
25
26
|
private queuedCommands;
|
|
26
27
|
private attachTimer?;
|
|
28
|
+
private startedTimer?;
|
|
27
29
|
private stoppedTimer?;
|
|
28
30
|
private destroyedTimer?;
|
|
29
31
|
constructor(worker: WorkerLike, hooks: WorkerClientHooks);
|
|
30
32
|
post(command: WorkerCommand): void;
|
|
31
33
|
waitForMediaSourceHandle(command: WorkerCommand): Promise<void>;
|
|
32
34
|
waitForStopped(command: WorkerCommand): Promise<void>;
|
|
35
|
+
waitForStarted(command: WorkerCommand): Promise<void>;
|
|
33
36
|
waitForDestroyed(command: WorkerCommand): Promise<void>;
|
|
34
37
|
dispose(): void;
|
|
35
38
|
private handleWorkerMessage;
|
|
36
39
|
private rejectPendingForWorkerError;
|
|
37
40
|
private resolveAttach;
|
|
38
41
|
private resolveStop;
|
|
42
|
+
private resolveStart;
|
|
39
43
|
private resolveDestroy;
|
|
44
|
+
private rejectAttach;
|
|
45
|
+
private rejectStop;
|
|
46
|
+
private rejectStart;
|
|
40
47
|
private rejectAll;
|
|
41
48
|
private flushQueuedCommands;
|
|
42
49
|
private startTimeout;
|
|
50
|
+
private failClient;
|
|
51
|
+
private notifyMessage;
|
|
43
52
|
private clearAttachTimer;
|
|
44
53
|
private clearStoppedTimer;
|
|
54
|
+
private clearStartedTimer;
|
|
45
55
|
private clearDestroyedTimer;
|
|
46
56
|
}
|
|
47
|
-
declare function createRuntimeWorker(options: NormalizedRivmuxPlayerOptions): WorkerLike;
|
|
57
|
+
export declare function createRuntimeWorker(options: NormalizedRivmuxPlayerOptions): WorkerLike;
|
|
48
58
|
//#endregion
|
|
49
|
-
export { RuntimeWorkerFactory, WorkerClient, WorkerClientHooks, WorkerLike, createRuntimeWorker, getBundledWasmUrl };
|
|
50
59
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;YAIY,aAAa,KAAK;YAElB,wBAAwB,SAAS,kCAAkC;YAOnE;EACV,UAAU,SAAS;EACnB,QAAQ,OAAO;;;;;;;;wBASD;qBAMH;mBACM;mBACA;mBACA;mBAGA;UAIT;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;UACA;EAEI,YAAA,QAAQ,YAAY,OAAO;EAOvC,KAAK,SAAS;EASd,yBAAyB,SAAS,gBAAgB;EAYlD,eAAe,SAAS,gBAAgB;EAYxC,eAAe,SAAS,gBAAgB;EAYxC,iBAAiB,SAAS,gBAAgB;EAY1C;UAOQ;UA4CA;UAQA;UAMA;UAMA;UAMA;UAMA;UAMA;UAMA;UAMA;UAgBA;UAaA;UAQA;UASA;UAQA;UAOA;UAOA;UAOA;;wBA0BM,oBAAoB,SAAS,gCAAgC"}
|
package/dist/index.js
CHANGED
|
@@ -18,15 +18,16 @@ var WorkerClient = class {
|
|
|
18
18
|
};
|
|
19
19
|
handleError = (event) => {
|
|
20
20
|
const error = createRuntimeWorkerError("RIVMUX_WORKER_ERROR", event.message || "Worker runtime failed.", true, event.error);
|
|
21
|
-
this.
|
|
22
|
-
this.hooks.onError(error);
|
|
21
|
+
this.failClient(error);
|
|
23
22
|
};
|
|
24
23
|
pendingAttach;
|
|
24
|
+
pendingStart;
|
|
25
25
|
pendingStop;
|
|
26
26
|
pendingDestroy;
|
|
27
27
|
workerReady = false;
|
|
28
28
|
queuedCommands = [];
|
|
29
29
|
attachTimer;
|
|
30
|
+
startedTimer;
|
|
30
31
|
stoppedTimer;
|
|
31
32
|
destroyedTimer;
|
|
32
33
|
constructor(worker, hooks) {
|
|
@@ -64,6 +65,17 @@ var WorkerClient = class {
|
|
|
64
65
|
this.post(command);
|
|
65
66
|
});
|
|
66
67
|
}
|
|
68
|
+
waitForStarted(command) {
|
|
69
|
+
if (this.pendingStart !== void 0) return Promise.reject(createRuntimeWorkerError("RIVMUX_START_IN_PROGRESS", "A start request is already pending.", false));
|
|
70
|
+
return new Promise((resolve, reject) => {
|
|
71
|
+
this.pendingStart = {
|
|
72
|
+
resolve,
|
|
73
|
+
reject
|
|
74
|
+
};
|
|
75
|
+
this.startedTimer = this.startTimeout("RIVMUX_START_TIMEOUT", "Timed out waiting for worker start.", reject);
|
|
76
|
+
this.post(command);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
67
79
|
waitForDestroyed(command) {
|
|
68
80
|
if (this.pendingDestroy !== void 0) return Promise.reject(createRuntimeWorkerError("RIVMUX_DESTROY_IN_PROGRESS", "A destroy request is already pending.", false));
|
|
69
81
|
return new Promise((resolve, reject) => {
|
|
@@ -86,20 +98,37 @@ var WorkerClient = class {
|
|
|
86
98
|
this.flushQueuedCommands();
|
|
87
99
|
return;
|
|
88
100
|
}
|
|
89
|
-
this.hooks.onMessage(message);
|
|
90
101
|
if (message.type === "media-source-handle") {
|
|
91
102
|
this.resolveAttach();
|
|
103
|
+
this.notifyMessage(message);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (message.type === "started") {
|
|
107
|
+
this.resolveStart();
|
|
108
|
+
this.notifyMessage(message);
|
|
92
109
|
return;
|
|
93
110
|
}
|
|
94
111
|
if (message.type === "stopped") {
|
|
112
|
+
this.rejectAttach(createRuntimeWorkerError("RIVMUX_ATTACH_CANCELLED", "Media source attachment was cancelled by stop.", false));
|
|
113
|
+
this.rejectStart(createRuntimeWorkerError("RIVMUX_START_CANCELLED", "Start was cancelled by stop.", false));
|
|
95
114
|
this.resolveStop();
|
|
115
|
+
this.notifyMessage(message);
|
|
96
116
|
return;
|
|
97
117
|
}
|
|
98
118
|
if (message.type === "destroyed") {
|
|
99
119
|
this.resolveDestroy();
|
|
120
|
+
this.rejectAttach(createRuntimeWorkerError("RIVMUX_ATTACH_CANCELLED", "Media source attachment was cancelled by destroy.", false));
|
|
121
|
+
this.rejectStart(createRuntimeWorkerError("RIVMUX_START_CANCELLED", "Start was cancelled by destroy.", false));
|
|
122
|
+
this.rejectStop(createRuntimeWorkerError("RIVMUX_STOP_CANCELLED", "Stop was superseded by destroy.", false));
|
|
123
|
+
this.notifyMessage(message);
|
|
100
124
|
return;
|
|
101
125
|
}
|
|
102
|
-
if (message.type === "error")
|
|
126
|
+
if (message.type === "error") {
|
|
127
|
+
this.rejectPendingForWorkerError(message.error);
|
|
128
|
+
this.notifyMessage(message);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
this.notifyMessage(message);
|
|
103
132
|
}
|
|
104
133
|
rejectPendingForWorkerError(error) {
|
|
105
134
|
if (!error.terminal) return;
|
|
@@ -115,20 +144,43 @@ var WorkerClient = class {
|
|
|
115
144
|
this.pendingStop?.resolve();
|
|
116
145
|
this.pendingStop = void 0;
|
|
117
146
|
}
|
|
147
|
+
resolveStart() {
|
|
148
|
+
this.clearStartedTimer();
|
|
149
|
+
this.pendingStart?.resolve();
|
|
150
|
+
this.pendingStart = void 0;
|
|
151
|
+
}
|
|
118
152
|
resolveDestroy() {
|
|
119
153
|
this.clearDestroyedTimer();
|
|
120
154
|
this.pendingDestroy?.resolve();
|
|
121
155
|
this.pendingDestroy = void 0;
|
|
122
156
|
}
|
|
157
|
+
rejectAttach(error) {
|
|
158
|
+
this.clearAttachTimer();
|
|
159
|
+
this.pendingAttach?.reject(error);
|
|
160
|
+
this.pendingAttach = void 0;
|
|
161
|
+
}
|
|
162
|
+
rejectStop(error) {
|
|
163
|
+
this.clearStoppedTimer();
|
|
164
|
+
this.pendingStop?.reject(error);
|
|
165
|
+
this.pendingStop = void 0;
|
|
166
|
+
}
|
|
167
|
+
rejectStart(error) {
|
|
168
|
+
this.clearStartedTimer();
|
|
169
|
+
this.pendingStart?.reject(error);
|
|
170
|
+
this.pendingStart = void 0;
|
|
171
|
+
}
|
|
123
172
|
rejectAll(error) {
|
|
124
173
|
this.queuedCommands = [];
|
|
125
174
|
this.clearAttachTimer();
|
|
175
|
+
this.clearStartedTimer();
|
|
126
176
|
this.clearStoppedTimer();
|
|
127
177
|
this.clearDestroyedTimer();
|
|
128
178
|
this.pendingAttach?.reject(error);
|
|
179
|
+
this.pendingStart?.reject(error);
|
|
129
180
|
this.pendingStop?.reject(error);
|
|
130
181
|
this.pendingDestroy?.reject(error);
|
|
131
182
|
this.pendingAttach = void 0;
|
|
183
|
+
this.pendingStart = void 0;
|
|
132
184
|
this.pendingStop = void 0;
|
|
133
185
|
this.pendingDestroy = void 0;
|
|
134
186
|
}
|
|
@@ -143,9 +195,24 @@ var WorkerClient = class {
|
|
|
143
195
|
return setTimeout(() => {
|
|
144
196
|
const error = createRuntimeWorkerError(code, message, true);
|
|
145
197
|
reject(error);
|
|
146
|
-
this.
|
|
198
|
+
this.failClient(error);
|
|
147
199
|
}, REQUEST_TIMEOUT_MS);
|
|
148
200
|
}
|
|
201
|
+
failClient(error) {
|
|
202
|
+
this.rejectAll(error);
|
|
203
|
+
try {
|
|
204
|
+
this.hooks.onError(error);
|
|
205
|
+
} catch (hookError) {
|
|
206
|
+
reportHookError(hookError);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
notifyMessage(message) {
|
|
210
|
+
try {
|
|
211
|
+
this.hooks.onMessage(message);
|
|
212
|
+
} catch (error) {
|
|
213
|
+
reportHookError(error);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
149
216
|
clearAttachTimer() {
|
|
150
217
|
if (this.attachTimer !== void 0) {
|
|
151
218
|
clearTimeout(this.attachTimer);
|
|
@@ -158,6 +225,12 @@ var WorkerClient = class {
|
|
|
158
225
|
this.stoppedTimer = void 0;
|
|
159
226
|
}
|
|
160
227
|
}
|
|
228
|
+
clearStartedTimer() {
|
|
229
|
+
if (this.startedTimer !== void 0) {
|
|
230
|
+
clearTimeout(this.startedTimer);
|
|
231
|
+
this.startedTimer = void 0;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
161
234
|
clearDestroyedTimer() {
|
|
162
235
|
if (this.destroyedTimer !== void 0) {
|
|
163
236
|
clearTimeout(this.destroyedTimer);
|
|
@@ -165,6 +238,18 @@ var WorkerClient = class {
|
|
|
165
238
|
}
|
|
166
239
|
}
|
|
167
240
|
};
|
|
241
|
+
function reportHookError(error) {
|
|
242
|
+
try {
|
|
243
|
+
const reportError = globalThis.reportError;
|
|
244
|
+
if (typeof reportError === "function") {
|
|
245
|
+
reportError(error);
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
} catch {}
|
|
249
|
+
try {
|
|
250
|
+
globalThis.console?.error(error);
|
|
251
|
+
} catch {}
|
|
252
|
+
}
|
|
168
253
|
function createRuntimeWorker(options) {
|
|
169
254
|
const url = options.runtime.workerUrl === void 0 ? new URL("./rivmux-runtime-worker.js", import.meta.url) : options.runtime.workerUrl;
|
|
170
255
|
return new Worker(url, {
|
|
@@ -173,17 +258,35 @@ function createRuntimeWorker(options) {
|
|
|
173
258
|
});
|
|
174
259
|
}
|
|
175
260
|
function createRuntimeWorkerError(code, message, terminal, cause) {
|
|
176
|
-
|
|
261
|
+
if (cause === void 0) return {
|
|
177
262
|
kind: "runtime",
|
|
178
263
|
code,
|
|
179
264
|
message,
|
|
180
265
|
terminal
|
|
181
|
-
}
|
|
266
|
+
};
|
|
267
|
+
return {
|
|
182
268
|
kind: "runtime",
|
|
183
269
|
code,
|
|
184
270
|
message,
|
|
185
271
|
terminal,
|
|
186
|
-
cause
|
|
272
|
+
cause: serializeCause(cause)
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
function serializeCause(cause) {
|
|
276
|
+
if (cause instanceof Error) return {
|
|
277
|
+
name: cause.name,
|
|
278
|
+
message: cause.message
|
|
279
|
+
};
|
|
280
|
+
if (typeof cause === "object" && cause !== null) {
|
|
281
|
+
const value = cause;
|
|
282
|
+
return {
|
|
283
|
+
name: typeof value.name === "string" ? value.name : "Error",
|
|
284
|
+
message: typeof value.message === "string" ? value.message : String(cause)
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
return {
|
|
288
|
+
name: "Error",
|
|
289
|
+
message: String(cause)
|
|
187
290
|
};
|
|
188
291
|
}
|
|
189
292
|
//#endregion
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { NormalizedRivmuxPlayerOptions, PlayerError, WorkerCommand, WorkerMessage } from '@rivmux/protocol'\n\nconst bundledWasmUrl = new URL('./rivmux-transmux-core.wasm', import.meta.url)\n\nexport type WorkerLike = Pick<Worker, 'addEventListener' | 'postMessage' | 'removeEventListener' | 'terminate'>\n\nexport type RuntimeWorkerFactory = (options: NormalizedRivmuxPlayerOptions) => WorkerLike\n\ntype PendingRequest = {\n resolve: () => void\n reject: (error: PlayerError) => void\n}\n\nexport type WorkerClientHooks = {\n onMessage(message: WorkerMessage): void\n onError(error: PlayerError): void\n}\n\n/**\n * Returns the packaged WASM asset URL for the application bundler to track.\n *\n * Vite rewrites this static URL during the client build and emits the matching\n * binary next to the application assets.\n */\nexport function getBundledWasmUrl(): string {\n return bundledWasmUrl.href\n}\n\nconst REQUEST_TIMEOUT_MS = 5000\n\nexport class WorkerClient {\n private readonly worker: WorkerLike\n private readonly hooks: WorkerClientHooks\n private readonly handleMessage = (event: MessageEvent<WorkerMessage>): void => {\n this.handleWorkerMessage(event.data)\n }\n private readonly handleError = (event: ErrorEvent): void => {\n const error = createRuntimeWorkerError('RIVMUX_WORKER_ERROR', event.message || 'Worker runtime failed.', true, event.error)\n this.rejectAll(error)\n this.hooks.onError(error)\n }\n private pendingAttach?: PendingRequest\n private pendingStop?: PendingRequest\n private pendingDestroy?: PendingRequest\n private workerReady = false\n private queuedCommands: WorkerCommand[] = []\n private attachTimer?: ReturnType<typeof setTimeout>\n private stoppedTimer?: ReturnType<typeof setTimeout>\n private destroyedTimer?: ReturnType<typeof setTimeout>\n\n constructor(worker: WorkerLike, hooks: WorkerClientHooks) {\n this.worker = worker\n this.hooks = hooks\n this.worker.addEventListener('message', this.handleMessage as EventListener)\n this.worker.addEventListener('error', this.handleError as EventListener)\n }\n\n post(command: WorkerCommand): void {\n if (!this.workerReady) {\n this.queuedCommands.push(command)\n return\n }\n\n this.worker.postMessage(command)\n }\n\n waitForMediaSourceHandle(command: WorkerCommand): Promise<void> {\n if (this.pendingAttach !== undefined) {\n return Promise.reject(createRuntimeWorkerError('RIVMUX_ATTACH_IN_PROGRESS', 'A media source attach request is already pending.', false))\n }\n\n return new Promise((resolve, reject) => {\n this.pendingAttach = { resolve, reject }\n this.attachTimer = this.startTimeout('RIVMUX_ATTACH_TIMEOUT', 'Timed out waiting for worker MediaSourceHandle.', reject)\n this.post(command)\n })\n }\n\n waitForStopped(command: WorkerCommand): Promise<void> {\n if (this.pendingStop !== undefined) {\n return Promise.reject(createRuntimeWorkerError('RIVMUX_STOP_IN_PROGRESS', 'A stop request is already pending.', false))\n }\n\n return new Promise((resolve, reject) => {\n this.pendingStop = { resolve, reject }\n this.stoppedTimer = this.startTimeout('RIVMUX_STOP_TIMEOUT', 'Timed out waiting for worker stop.', reject)\n this.post(command)\n })\n }\n\n waitForDestroyed(command: WorkerCommand): Promise<void> {\n if (this.pendingDestroy !== undefined) {\n return Promise.reject(createRuntimeWorkerError('RIVMUX_DESTROY_IN_PROGRESS', 'A destroy request is already pending.', false))\n }\n\n return new Promise((resolve, reject) => {\n this.pendingDestroy = { resolve, reject }\n this.destroyedTimer = this.startTimeout('RIVMUX_DESTROY_TIMEOUT', 'Timed out waiting for worker destroy.', reject)\n this.post(command)\n })\n }\n\n dispose(): void {\n this.rejectAll(createRuntimeWorkerError('RIVMUX_WORKER_DISPOSED', 'Worker client was disposed.', true))\n this.worker.removeEventListener('message', this.handleMessage as EventListener)\n this.worker.removeEventListener('error', this.handleError as EventListener)\n this.worker.terminate()\n }\n\n private handleWorkerMessage(message: WorkerMessage): void {\n if (message.type === 'worker-ready') {\n this.flushQueuedCommands()\n return\n }\n\n this.hooks.onMessage(message)\n\n if (message.type === 'media-source-handle') {\n this.resolveAttach()\n return\n }\n\n if (message.type === 'stopped') {\n this.resolveStop()\n return\n }\n\n if (message.type === 'destroyed') {\n this.resolveDestroy()\n return\n }\n\n if (message.type === 'error') {\n this.rejectPendingForWorkerError(message.error)\n }\n }\n\n private rejectPendingForWorkerError(error: PlayerError): void {\n if (!error.terminal) {\n return\n }\n\n this.rejectAll(error)\n }\n\n private resolveAttach(): void {\n this.clearAttachTimer()\n this.pendingAttach?.resolve()\n this.pendingAttach = undefined\n }\n\n private resolveStop(): void {\n this.clearStoppedTimer()\n this.pendingStop?.resolve()\n this.pendingStop = undefined\n }\n\n private resolveDestroy(): void {\n this.clearDestroyedTimer()\n this.pendingDestroy?.resolve()\n this.pendingDestroy = undefined\n }\n\n private rejectAll(error: PlayerError): void {\n this.queuedCommands = []\n this.clearAttachTimer()\n this.clearStoppedTimer()\n this.clearDestroyedTimer()\n this.pendingAttach?.reject(error)\n this.pendingStop?.reject(error)\n this.pendingDestroy?.reject(error)\n this.pendingAttach = undefined\n this.pendingStop = undefined\n this.pendingDestroy = undefined\n }\n\n private flushQueuedCommands(): void {\n if (this.workerReady) {\n return\n }\n\n this.workerReady = true\n const commands = this.queuedCommands\n this.queuedCommands = []\n for (const command of commands) {\n this.worker.postMessage(command)\n }\n }\n\n private startTimeout(code: string, message: string, reject: (error: PlayerError) => void): ReturnType<typeof setTimeout> {\n return setTimeout(() => {\n const error = createRuntimeWorkerError(code, message, true)\n reject(error)\n this.rejectAll(error)\n }, REQUEST_TIMEOUT_MS)\n }\n\n private clearAttachTimer(): void {\n if (this.attachTimer !== undefined) {\n clearTimeout(this.attachTimer)\n this.attachTimer = undefined\n }\n }\n\n private clearStoppedTimer(): void {\n if (this.stoppedTimer !== undefined) {\n clearTimeout(this.stoppedTimer)\n this.stoppedTimer = undefined\n }\n }\n\n private clearDestroyedTimer(): void {\n if (this.destroyedTimer !== undefined) {\n clearTimeout(this.destroyedTimer)\n this.destroyedTimer = undefined\n }\n }\n}\n\nexport function createRuntimeWorker(options: NormalizedRivmuxPlayerOptions): WorkerLike {\n const url = options.runtime.workerUrl === undefined ? new URL('./rivmux-runtime-worker.js', import.meta.url) : options.runtime.workerUrl\n\n return new Worker(url, {\n name: 'rivmux-runtime-worker',\n type: 'module',\n })\n}\n\nfunction createRuntimeWorkerError(code: string, message: string, terminal: boolean, cause?: unknown): PlayerError {\n return cause === undefined ? { kind: 'runtime', code, message, terminal } : { kind: 'runtime', code, message, terminal, cause }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { NormalizedRivmuxPlayerOptions, PlayerError, WorkerCommand, WorkerMessage } from '@rivmux/protocol'\n\nconst bundledWasmUrl = new URL('./rivmux-transmux-core.wasm', import.meta.url)\n\nexport type WorkerLike = Pick<Worker, 'addEventListener' | 'postMessage' | 'removeEventListener' | 'terminate'>\n\nexport type RuntimeWorkerFactory = (options: NormalizedRivmuxPlayerOptions) => WorkerLike\n\ntype PendingRequest = {\n resolve: () => void\n reject: (error: PlayerError) => void\n}\n\nexport type WorkerClientHooks = {\n onMessage(message: WorkerMessage): void\n onError(error: PlayerError): void\n}\n\n/**\n * Returns the packaged WASM asset URL for the application bundler to track.\n *\n * Vite rewrites this static URL during the client build and emits the matching\n * binary next to the application assets.\n */\nexport function getBundledWasmUrl(): string {\n return bundledWasmUrl.href\n}\n\nconst REQUEST_TIMEOUT_MS = 5000\n\nexport class WorkerClient {\n private readonly worker: WorkerLike\n private readonly hooks: WorkerClientHooks\n private readonly handleMessage = (event: MessageEvent<WorkerMessage>): void => {\n this.handleWorkerMessage(event.data)\n }\n private readonly handleError = (event: ErrorEvent): void => {\n const error = createRuntimeWorkerError('RIVMUX_WORKER_ERROR', event.message || 'Worker runtime failed.', true, event.error)\n this.failClient(error)\n }\n private pendingAttach?: PendingRequest\n private pendingStart?: PendingRequest\n private pendingStop?: PendingRequest\n private pendingDestroy?: PendingRequest\n private workerReady = false\n private queuedCommands: WorkerCommand[] = []\n private attachTimer?: ReturnType<typeof setTimeout>\n private startedTimer?: ReturnType<typeof setTimeout>\n private stoppedTimer?: ReturnType<typeof setTimeout>\n private destroyedTimer?: ReturnType<typeof setTimeout>\n\n constructor(worker: WorkerLike, hooks: WorkerClientHooks) {\n this.worker = worker\n this.hooks = hooks\n this.worker.addEventListener('message', this.handleMessage as EventListener)\n this.worker.addEventListener('error', this.handleError as EventListener)\n }\n\n post(command: WorkerCommand): void {\n if (!this.workerReady) {\n this.queuedCommands.push(command)\n return\n }\n\n this.worker.postMessage(command)\n }\n\n waitForMediaSourceHandle(command: WorkerCommand): Promise<void> {\n if (this.pendingAttach !== undefined) {\n return Promise.reject(createRuntimeWorkerError('RIVMUX_ATTACH_IN_PROGRESS', 'A media source attach request is already pending.', false))\n }\n\n return new Promise((resolve, reject) => {\n this.pendingAttach = { resolve, reject }\n this.attachTimer = this.startTimeout('RIVMUX_ATTACH_TIMEOUT', 'Timed out waiting for worker MediaSourceHandle.', reject)\n this.post(command)\n })\n }\n\n waitForStopped(command: WorkerCommand): Promise<void> {\n if (this.pendingStop !== undefined) {\n return Promise.reject(createRuntimeWorkerError('RIVMUX_STOP_IN_PROGRESS', 'A stop request is already pending.', false))\n }\n\n return new Promise((resolve, reject) => {\n this.pendingStop = { resolve, reject }\n this.stoppedTimer = this.startTimeout('RIVMUX_STOP_TIMEOUT', 'Timed out waiting for worker stop.', reject)\n this.post(command)\n })\n }\n\n waitForStarted(command: WorkerCommand): Promise<void> {\n if (this.pendingStart !== undefined) {\n return Promise.reject(createRuntimeWorkerError('RIVMUX_START_IN_PROGRESS', 'A start request is already pending.', false))\n }\n\n return new Promise((resolve, reject) => {\n this.pendingStart = { resolve, reject }\n this.startedTimer = this.startTimeout('RIVMUX_START_TIMEOUT', 'Timed out waiting for worker start.', reject)\n this.post(command)\n })\n }\n\n waitForDestroyed(command: WorkerCommand): Promise<void> {\n if (this.pendingDestroy !== undefined) {\n return Promise.reject(createRuntimeWorkerError('RIVMUX_DESTROY_IN_PROGRESS', 'A destroy request is already pending.', false))\n }\n\n return new Promise((resolve, reject) => {\n this.pendingDestroy = { resolve, reject }\n this.destroyedTimer = this.startTimeout('RIVMUX_DESTROY_TIMEOUT', 'Timed out waiting for worker destroy.', reject)\n this.post(command)\n })\n }\n\n dispose(): void {\n this.rejectAll(createRuntimeWorkerError('RIVMUX_WORKER_DISPOSED', 'Worker client was disposed.', true))\n this.worker.removeEventListener('message', this.handleMessage as EventListener)\n this.worker.removeEventListener('error', this.handleError as EventListener)\n this.worker.terminate()\n }\n\n private handleWorkerMessage(message: WorkerMessage): void {\n if (message.type === 'worker-ready') {\n this.flushQueuedCommands()\n return\n }\n\n if (message.type === 'media-source-handle') {\n this.resolveAttach()\n this.notifyMessage(message)\n return\n }\n\n if (message.type === 'started') {\n this.resolveStart()\n this.notifyMessage(message)\n return\n }\n\n if (message.type === 'stopped') {\n this.rejectAttach(createRuntimeWorkerError('RIVMUX_ATTACH_CANCELLED', 'Media source attachment was cancelled by stop.', false))\n this.rejectStart(createRuntimeWorkerError('RIVMUX_START_CANCELLED', 'Start was cancelled by stop.', false))\n this.resolveStop()\n this.notifyMessage(message)\n return\n }\n\n if (message.type === 'destroyed') {\n this.resolveDestroy()\n this.rejectAttach(createRuntimeWorkerError('RIVMUX_ATTACH_CANCELLED', 'Media source attachment was cancelled by destroy.', false))\n this.rejectStart(createRuntimeWorkerError('RIVMUX_START_CANCELLED', 'Start was cancelled by destroy.', false))\n this.rejectStop(createRuntimeWorkerError('RIVMUX_STOP_CANCELLED', 'Stop was superseded by destroy.', false))\n this.notifyMessage(message)\n return\n }\n\n if (message.type === 'error') {\n this.rejectPendingForWorkerError(message.error)\n this.notifyMessage(message)\n return\n }\n\n this.notifyMessage(message)\n }\n\n private rejectPendingForWorkerError(error: PlayerError): void {\n if (!error.terminal) {\n return\n }\n\n this.rejectAll(error)\n }\n\n private resolveAttach(): void {\n this.clearAttachTimer()\n this.pendingAttach?.resolve()\n this.pendingAttach = undefined\n }\n\n private resolveStop(): void {\n this.clearStoppedTimer()\n this.pendingStop?.resolve()\n this.pendingStop = undefined\n }\n\n private resolveStart(): void {\n this.clearStartedTimer()\n this.pendingStart?.resolve()\n this.pendingStart = undefined\n }\n\n private resolveDestroy(): void {\n this.clearDestroyedTimer()\n this.pendingDestroy?.resolve()\n this.pendingDestroy = undefined\n }\n\n private rejectAttach(error: PlayerError): void {\n this.clearAttachTimer()\n this.pendingAttach?.reject(error)\n this.pendingAttach = undefined\n }\n\n private rejectStop(error: PlayerError): void {\n this.clearStoppedTimer()\n this.pendingStop?.reject(error)\n this.pendingStop = undefined\n }\n\n private rejectStart(error: PlayerError): void {\n this.clearStartedTimer()\n this.pendingStart?.reject(error)\n this.pendingStart = undefined\n }\n\n private rejectAll(error: PlayerError): void {\n this.queuedCommands = []\n this.clearAttachTimer()\n this.clearStartedTimer()\n this.clearStoppedTimer()\n this.clearDestroyedTimer()\n this.pendingAttach?.reject(error)\n this.pendingStart?.reject(error)\n this.pendingStop?.reject(error)\n this.pendingDestroy?.reject(error)\n this.pendingAttach = undefined\n this.pendingStart = undefined\n this.pendingStop = undefined\n this.pendingDestroy = undefined\n }\n\n private flushQueuedCommands(): void {\n if (this.workerReady) {\n return\n }\n\n this.workerReady = true\n const commands = this.queuedCommands\n this.queuedCommands = []\n for (const command of commands) {\n this.worker.postMessage(command)\n }\n }\n\n private startTimeout(code: string, message: string, reject: (error: PlayerError) => void): ReturnType<typeof setTimeout> {\n return setTimeout(() => {\n const error = createRuntimeWorkerError(code, message, true)\n reject(error)\n this.failClient(error)\n }, REQUEST_TIMEOUT_MS)\n }\n\n private failClient(error: PlayerError): void {\n this.rejectAll(error)\n try {\n this.hooks.onError(error)\n } catch (hookError) {\n reportHookError(hookError)\n }\n }\n\n private notifyMessage(message: WorkerMessage): void {\n try {\n this.hooks.onMessage(message)\n } catch (error) {\n reportHookError(error)\n }\n }\n\n private clearAttachTimer(): void {\n if (this.attachTimer !== undefined) {\n clearTimeout(this.attachTimer)\n this.attachTimer = undefined\n }\n }\n\n private clearStoppedTimer(): void {\n if (this.stoppedTimer !== undefined) {\n clearTimeout(this.stoppedTimer)\n this.stoppedTimer = undefined\n }\n }\n\n private clearStartedTimer(): void {\n if (this.startedTimer !== undefined) {\n clearTimeout(this.startedTimer)\n this.startedTimer = undefined\n }\n }\n\n private clearDestroyedTimer(): void {\n if (this.destroyedTimer !== undefined) {\n clearTimeout(this.destroyedTimer)\n this.destroyedTimer = undefined\n }\n }\n}\n\nfunction reportHookError(error: unknown): void {\n try {\n const reportError = (globalThis as typeof globalThis & { reportError?: (error: unknown) => void }).reportError\n if (typeof reportError === 'function') {\n reportError(error)\n return\n }\n } catch {\n // Fall through to the non-throwing console fallback.\n }\n\n try {\n globalThis.console?.error(error)\n } catch {\n // Hook error reporting must never affect worker lifecycle state.\n }\n}\n\nexport function createRuntimeWorker(options: NormalizedRivmuxPlayerOptions): WorkerLike {\n const url = options.runtime.workerUrl === undefined ? new URL('./rivmux-runtime-worker.js', import.meta.url) : options.runtime.workerUrl\n\n return new Worker(url, {\n name: 'rivmux-runtime-worker',\n type: 'module',\n })\n}\n\nfunction createRuntimeWorkerError(code: string, message: string, terminal: boolean, cause?: unknown): PlayerError {\n if (cause === undefined) {\n return { kind: 'runtime', code, message, terminal }\n }\n\n return {\n kind: 'runtime',\n code,\n message,\n terminal,\n cause: serializeCause(cause),\n }\n}\n\nfunction serializeCause(cause: unknown): { name: string; message: string } {\n if (cause instanceof Error) {\n return { name: cause.name, message: cause.message }\n }\n\n if (typeof cause === 'object' && cause !== null) {\n const value = cause as { name?: unknown; message?: unknown }\n return {\n name: typeof value.name === 'string' ? value.name : 'Error',\n message: typeof value.message === 'string' ? value.message : String(cause),\n }\n }\n\n return { name: 'Error', message: String(cause) }\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { NormalizedNetworkOptions, NormalizedRivmuxPlayerOptions, PlayerError, WorkerCommand, WorkerMessage } from "@rivmux/protocol";
|
|
1
|
+
import { NormalizedNetworkOptions, NormalizedRivmuxPlayerOptions, PlayerError, ReconnectReason, WorkerCommand, WorkerMessage } from "@rivmux/protocol";
|
|
2
2
|
//#region src/latency/buffer-ranges.d.ts
|
|
3
3
|
type BufferedRange = {
|
|
4
4
|
start: number;
|
|
@@ -22,7 +22,8 @@ type StreamLoaderConfig = {
|
|
|
22
22
|
network: NormalizedNetworkOptions;
|
|
23
23
|
fetch?: typeof fetch;
|
|
24
24
|
now?: () => number;
|
|
25
|
-
|
|
25
|
+
setTimeout?: (callback: () => void, ms: number) => ReturnType<typeof setTimeout>;
|
|
26
|
+
clearTimeout?: (timer: ReturnType<typeof setTimeout>) => void;
|
|
26
27
|
};
|
|
27
28
|
type StreamLoader = {
|
|
28
29
|
readonly closed: boolean;
|
|
@@ -88,16 +89,10 @@ type CoreEvent = {
|
|
|
88
89
|
type: 'mediaSegment';
|
|
89
90
|
data: CoreMediaSegment;
|
|
90
91
|
} | {
|
|
91
|
-
type: '
|
|
92
|
+
type: 'trackConfig';
|
|
92
93
|
data: unknown;
|
|
93
94
|
} | {
|
|
94
|
-
type: '
|
|
95
|
-
data: unknown;
|
|
96
|
-
} | {
|
|
97
|
-
type: 'videoSample';
|
|
98
|
-
data: unknown;
|
|
99
|
-
} | {
|
|
100
|
-
type: 'audioSample';
|
|
95
|
+
type: 'sample';
|
|
101
96
|
data: unknown;
|
|
102
97
|
} | {
|
|
103
98
|
type: 'metadata';
|
|
@@ -124,7 +119,7 @@ type TransmuxCoreWasmConstructor = new () => {
|
|
|
124
119
|
reset(): void;
|
|
125
120
|
destroy(): void;
|
|
126
121
|
};
|
|
127
|
-
declare class WasmTransmuxCoreHost implements TransmuxCoreHost {
|
|
122
|
+
export declare class WasmTransmuxCoreHost implements TransmuxCoreHost {
|
|
128
123
|
private readonly core;
|
|
129
124
|
constructor(Core: TransmuxCoreWasmConstructor);
|
|
130
125
|
pushChunk(chunk: Uint8Array): CoreEvent[];
|
|
@@ -132,9 +127,9 @@ declare class WasmTransmuxCoreHost implements TransmuxCoreHost {
|
|
|
132
127
|
reset(): void;
|
|
133
128
|
destroy(): void;
|
|
134
129
|
}
|
|
135
|
-
declare function normalizeCoreEvents(value: unknown): CoreEvent[];
|
|
130
|
+
export declare function normalizeCoreEvents(value: unknown): CoreEvent[];
|
|
136
131
|
//#endregion
|
|
137
|
-
//#region src/runtime.d.ts
|
|
132
|
+
//#region src/runtime/types.d.ts
|
|
138
133
|
type RuntimeMseCleanupOptions = {
|
|
139
134
|
force?: boolean;
|
|
140
135
|
};
|
|
@@ -168,75 +163,98 @@ type RuntimeWorkerDependencies = {
|
|
|
168
163
|
createTransmuxCore?: (options: NormalizedRivmuxPlayerOptions) => TransmuxCoreHost | undefined | Promise<TransmuxCoreHost | undefined>;
|
|
169
164
|
detectRuntime?: () => PlayerError | undefined;
|
|
170
165
|
now?: () => number;
|
|
166
|
+
sleep?: (delayMs: number, signal: AbortSignal) => Promise<void>;
|
|
167
|
+
random?: () => number;
|
|
171
168
|
};
|
|
172
|
-
|
|
169
|
+
//#endregion
|
|
170
|
+
//#region src/runtime/index.d.ts
|
|
171
|
+
export declare class RuntimeWorker {
|
|
173
172
|
private readonly port;
|
|
174
|
-
private readonly createMseController;
|
|
175
|
-
private readonly createLoader;
|
|
176
|
-
private readonly createTransmuxCore;
|
|
177
173
|
private readonly detectRuntime;
|
|
178
174
|
private readonly now;
|
|
175
|
+
private readonly sleep;
|
|
176
|
+
private readonly random;
|
|
179
177
|
private state;
|
|
180
178
|
private url?;
|
|
181
179
|
private options?;
|
|
182
|
-
private
|
|
183
|
-
private loader?;
|
|
184
|
-
private transmuxCore?;
|
|
180
|
+
private readonly session;
|
|
185
181
|
private latencyController?;
|
|
186
182
|
private videoState?;
|
|
187
183
|
private lastLatencyMetrics;
|
|
188
184
|
private statsTimer?;
|
|
189
185
|
private statsTickInFlight;
|
|
190
|
-
private loaderRunId;
|
|
191
|
-
private outputBytes;
|
|
192
186
|
private appendQueueMaxLength;
|
|
193
187
|
private appendQueueMaxBytes;
|
|
188
|
+
private commandTail;
|
|
189
|
+
private lifecycleGeneration;
|
|
190
|
+
private lifecycleAbortController;
|
|
191
|
+
private fatalCleanupPromise;
|
|
192
|
+
private recoveryPromise?;
|
|
193
|
+
private connectionAttempt;
|
|
194
|
+
private recoveryStartedAt?;
|
|
195
|
+
private pendingRecovery?;
|
|
194
196
|
constructor(port: RuntimeWorkerPort, dependencies?: RuntimeWorkerDependencies);
|
|
195
197
|
handleCommand(command: WorkerCommand): Promise<void>;
|
|
198
|
+
private executeCommand;
|
|
196
199
|
private attachMediaSource;
|
|
197
200
|
private start;
|
|
198
201
|
private stop;
|
|
199
202
|
private destroy;
|
|
200
203
|
private startLoader;
|
|
201
|
-
private runLoader;
|
|
202
204
|
private closeLoader;
|
|
203
|
-
private
|
|
204
|
-
private
|
|
205
|
+
private scheduleRecovery;
|
|
206
|
+
private recover;
|
|
207
|
+
private markRecovered;
|
|
208
|
+
private waitForRecovery;
|
|
209
|
+
private resetRecoveryCycle;
|
|
205
210
|
private postStats;
|
|
206
|
-
private processTransmuxEvents;
|
|
207
211
|
private collectMseStats;
|
|
208
|
-
private appendToMse;
|
|
209
|
-
private retryAppendAfterQuotaCleanup;
|
|
210
212
|
private quotaCleanupCutoff;
|
|
211
213
|
private applyLatencyPolicy;
|
|
212
214
|
private startStatsTimer;
|
|
213
215
|
private stopStatsTimer;
|
|
214
216
|
private emitStatsTick;
|
|
217
|
+
private currentLifecycleContext;
|
|
218
|
+
private isLifecycleContextCurrent;
|
|
215
219
|
private fail;
|
|
216
220
|
private failWithError;
|
|
217
221
|
private enterFatalErrorState;
|
|
218
222
|
private post;
|
|
223
|
+
private invalidateLifecycle;
|
|
219
224
|
}
|
|
220
225
|
//#endregion
|
|
221
226
|
//#region src/loader/http-flv-loader.d.ts
|
|
222
|
-
|
|
227
|
+
type HttpFlvLoaderErrorPhase = 'open' | 'read';
|
|
228
|
+
type HttpFlvLoaderErrorOptions = {
|
|
229
|
+
phase: HttpFlvLoaderErrorPhase;
|
|
230
|
+
reason?: ReconnectReason;
|
|
231
|
+
status?: number;
|
|
232
|
+
cause?: unknown;
|
|
233
|
+
};
|
|
234
|
+
/** Structured failure raised by one HTTP-FLV connection. */
|
|
235
|
+
export declare class HttpFlvLoaderError extends Error {
|
|
223
236
|
readonly code: string;
|
|
237
|
+
readonly phase: HttpFlvLoaderErrorPhase;
|
|
238
|
+
readonly reason?: ReconnectReason;
|
|
224
239
|
readonly status?: number;
|
|
225
|
-
|
|
240
|
+
readonly cause?: unknown;
|
|
241
|
+
constructor(code: string, message: string, options?: HttpFlvLoaderErrorOptions | number);
|
|
226
242
|
}
|
|
227
|
-
declare class HttpFlvLoader implements StreamLoader {
|
|
243
|
+
export declare class HttpFlvLoader implements StreamLoader {
|
|
228
244
|
private readonly url;
|
|
229
245
|
private readonly headers;
|
|
230
246
|
private readonly credentials;
|
|
231
|
-
private readonly
|
|
247
|
+
private readonly readIdleTimeoutMs;
|
|
232
248
|
private readonly fetchImpl;
|
|
233
249
|
private readonly now;
|
|
234
|
-
private readonly
|
|
250
|
+
private readonly setTimer;
|
|
251
|
+
private readonly clearTimer;
|
|
235
252
|
private abortController?;
|
|
236
253
|
private reader?;
|
|
237
254
|
private state;
|
|
238
255
|
private pausedState;
|
|
239
256
|
private resumeWaiters;
|
|
257
|
+
private activeReadTimeout?;
|
|
240
258
|
private readonly mutableStats;
|
|
241
259
|
constructor(config: StreamLoaderConfig);
|
|
242
260
|
get closed(): boolean;
|
|
@@ -247,13 +265,12 @@ declare class HttpFlvLoader implements StreamLoader {
|
|
|
247
265
|
pause(): void;
|
|
248
266
|
resume(): void;
|
|
249
267
|
close(): Promise<void>;
|
|
250
|
-
private openAttempt;
|
|
251
268
|
private waitUntilResumed;
|
|
252
269
|
private resolveResumeWaiters;
|
|
253
270
|
}
|
|
254
271
|
//#endregion
|
|
255
272
|
//#region src/mse/mse-controller.d.ts
|
|
256
|
-
declare class MseController {
|
|
273
|
+
export declare class MseController {
|
|
257
274
|
private mediaSource?;
|
|
258
275
|
private readonly sourceBuffers;
|
|
259
276
|
private readonly queues;
|
|
@@ -282,7 +299,7 @@ type MseCleanupOptions = {
|
|
|
282
299
|
};
|
|
283
300
|
//#endregion
|
|
284
301
|
//#region src/mse/source-buffer-queue.d.ts
|
|
285
|
-
declare class SourceBufferQueue {
|
|
302
|
+
export declare class SourceBufferQueue {
|
|
286
303
|
private readonly sourceBuffer;
|
|
287
304
|
private readonly queue;
|
|
288
305
|
private pendingDrain?;
|
|
@@ -306,10 +323,10 @@ declare class SourceBufferQueue {
|
|
|
306
323
|
}
|
|
307
324
|
//#endregion
|
|
308
325
|
//#region src/mse/mime.d.ts
|
|
309
|
-
declare function isMseSupported(mimeType: string): boolean;
|
|
326
|
+
export declare function isMseSupported(mimeType: string): boolean;
|
|
310
327
|
//#endregion
|
|
311
328
|
//#region src/wasm/wasm-loader.d.ts
|
|
312
|
-
declare function createWasmTransmuxCoreHost(Core: TransmuxCoreWasmConstructor | undefined): TransmuxCoreHost;
|
|
329
|
+
export declare function createWasmTransmuxCoreHost(Core: TransmuxCoreWasmConstructor | undefined): TransmuxCoreHost;
|
|
313
330
|
//#endregion
|
|
314
331
|
//#region src/worker-entry.d.ts
|
|
315
332
|
type DedicatedWorkerScopeLike = {
|
|
@@ -317,7 +334,7 @@ type DedicatedWorkerScopeLike = {
|
|
|
317
334
|
postMessage(message: WorkerMessage, transfer?: Transferable[]): void;
|
|
318
335
|
close(): void;
|
|
319
336
|
};
|
|
320
|
-
declare function startRuntimeWorker(scope: DedicatedWorkerScopeLike): RuntimeWorker;
|
|
337
|
+
export declare function startRuntimeWorker(scope: DedicatedWorkerScopeLike): RuntimeWorker;
|
|
321
338
|
//#endregion
|
|
322
|
-
export {
|
|
339
|
+
export type { CoreEvent, StreamChunk, StreamLoader, StreamLoaderConfig, StreamLoaderStats, TransmuxCoreHost, TransmuxCoreWasmConstructor };
|
|
323
340
|
//# sourceMappingURL=rivmux-runtime-worker.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rivmux-runtime-worker.d.ts","names":[],"sources":["../src/latency/buffer-ranges.ts","../src/loader/loader.ts","../src/wasm/rivmux-transmux-wasm.ts","../src/runtime.ts","../src/loader/http-flv-loader.ts","../src/mse/mse-controller.ts","../src/mse/source-buffer-queue.ts","../src/mse/mime.ts","../src/wasm/wasm-loader.ts","../src/worker-entry.ts"],"mappings":";;KAAY;EACV;EACA;;;;KCAU;EACV,OAAO;EACP;;KAGU;EACV;EACA;EACA;EACA;EACA;;KAGU;EACV;EACA,SAAS;EACT,eAAe;EACf;EACA,
|
|
1
|
+
{"version":3,"file":"rivmux-runtime-worker.d.ts","names":[],"sources":["../src/latency/buffer-ranges.ts","../src/loader/loader.ts","../src/wasm/rivmux-transmux-wasm.ts","../src/runtime/types.ts","../src/runtime/index.ts","../src/loader/http-flv-loader.ts","../src/mse/mse-controller.ts","../src/mse/source-buffer-queue.ts","../src/mse/mime.ts","../src/wasm/wasm-loader.ts","../src/worker-entry.ts"],"mappings":"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"}
|