@rivmux/runtime-worker 0.5.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 +13 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +93 -6
- package/dist/index.js.map +1 -1
- package/dist/rivmux-runtime-worker.d.ts +43 -17
- package/dist/rivmux-runtime-worker.d.ts.map +1 -1
- package/dist/rivmux-runtime-worker.js +472 -215
- 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,42 +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;
|
|
40
44
|
private rejectAttach;
|
|
41
45
|
private rejectStop;
|
|
46
|
+
private rejectStart;
|
|
42
47
|
private rejectAll;
|
|
43
48
|
private flushQueuedCommands;
|
|
44
49
|
private startTimeout;
|
|
45
50
|
private failClient;
|
|
51
|
+
private notifyMessage;
|
|
46
52
|
private clearAttachTimer;
|
|
47
53
|
private clearStoppedTimer;
|
|
54
|
+
private clearStartedTimer;
|
|
48
55
|
private clearDestroyedTimer;
|
|
49
56
|
}
|
|
50
|
-
declare function createRuntimeWorker(options: NormalizedRivmuxPlayerOptions): WorkerLike;
|
|
57
|
+
export declare function createRuntimeWorker(options: NormalizedRivmuxPlayerOptions): WorkerLike;
|
|
51
58
|
//#endregion
|
|
52
|
-
export { RuntimeWorkerFactory, WorkerClient, WorkerClientHooks, WorkerLike, createRuntimeWorker, getBundledWasmUrl };
|
|
53
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
|
@@ -21,11 +21,13 @@ var WorkerClient = class {
|
|
|
21
21
|
this.failClient(error);
|
|
22
22
|
};
|
|
23
23
|
pendingAttach;
|
|
24
|
+
pendingStart;
|
|
24
25
|
pendingStop;
|
|
25
26
|
pendingDestroy;
|
|
26
27
|
workerReady = false;
|
|
27
28
|
queuedCommands = [];
|
|
28
29
|
attachTimer;
|
|
30
|
+
startedTimer;
|
|
29
31
|
stoppedTimer;
|
|
30
32
|
destroyedTimer;
|
|
31
33
|
constructor(worker, hooks) {
|
|
@@ -63,6 +65,17 @@ var WorkerClient = class {
|
|
|
63
65
|
this.post(command);
|
|
64
66
|
});
|
|
65
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
|
+
}
|
|
66
79
|
waitForDestroyed(command) {
|
|
67
80
|
if (this.pendingDestroy !== void 0) return Promise.reject(createRuntimeWorkerError("RIVMUX_DESTROY_IN_PROGRESS", "A destroy request is already pending.", false));
|
|
68
81
|
return new Promise((resolve, reject) => {
|
|
@@ -85,23 +98,37 @@ var WorkerClient = class {
|
|
|
85
98
|
this.flushQueuedCommands();
|
|
86
99
|
return;
|
|
87
100
|
}
|
|
88
|
-
this.hooks.onMessage(message);
|
|
89
101
|
if (message.type === "media-source-handle") {
|
|
90
102
|
this.resolveAttach();
|
|
103
|
+
this.notifyMessage(message);
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (message.type === "started") {
|
|
107
|
+
this.resolveStart();
|
|
108
|
+
this.notifyMessage(message);
|
|
91
109
|
return;
|
|
92
110
|
}
|
|
93
111
|
if (message.type === "stopped") {
|
|
94
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();
|
|
100
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));
|
|
101
122
|
this.rejectStop(createRuntimeWorkerError("RIVMUX_STOP_CANCELLED", "Stop was superseded by destroy.", false));
|
|
123
|
+
this.notifyMessage(message);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (message.type === "error") {
|
|
127
|
+
this.rejectPendingForWorkerError(message.error);
|
|
128
|
+
this.notifyMessage(message);
|
|
102
129
|
return;
|
|
103
130
|
}
|
|
104
|
-
|
|
131
|
+
this.notifyMessage(message);
|
|
105
132
|
}
|
|
106
133
|
rejectPendingForWorkerError(error) {
|
|
107
134
|
if (!error.terminal) return;
|
|
@@ -117,6 +144,11 @@ var WorkerClient = class {
|
|
|
117
144
|
this.pendingStop?.resolve();
|
|
118
145
|
this.pendingStop = void 0;
|
|
119
146
|
}
|
|
147
|
+
resolveStart() {
|
|
148
|
+
this.clearStartedTimer();
|
|
149
|
+
this.pendingStart?.resolve();
|
|
150
|
+
this.pendingStart = void 0;
|
|
151
|
+
}
|
|
120
152
|
resolveDestroy() {
|
|
121
153
|
this.clearDestroyedTimer();
|
|
122
154
|
this.pendingDestroy?.resolve();
|
|
@@ -132,15 +164,23 @@ var WorkerClient = class {
|
|
|
132
164
|
this.pendingStop?.reject(error);
|
|
133
165
|
this.pendingStop = void 0;
|
|
134
166
|
}
|
|
167
|
+
rejectStart(error) {
|
|
168
|
+
this.clearStartedTimer();
|
|
169
|
+
this.pendingStart?.reject(error);
|
|
170
|
+
this.pendingStart = void 0;
|
|
171
|
+
}
|
|
135
172
|
rejectAll(error) {
|
|
136
173
|
this.queuedCommands = [];
|
|
137
174
|
this.clearAttachTimer();
|
|
175
|
+
this.clearStartedTimer();
|
|
138
176
|
this.clearStoppedTimer();
|
|
139
177
|
this.clearDestroyedTimer();
|
|
140
178
|
this.pendingAttach?.reject(error);
|
|
179
|
+
this.pendingStart?.reject(error);
|
|
141
180
|
this.pendingStop?.reject(error);
|
|
142
181
|
this.pendingDestroy?.reject(error);
|
|
143
182
|
this.pendingAttach = void 0;
|
|
183
|
+
this.pendingStart = void 0;
|
|
144
184
|
this.pendingStop = void 0;
|
|
145
185
|
this.pendingDestroy = void 0;
|
|
146
186
|
}
|
|
@@ -160,7 +200,18 @@ var WorkerClient = class {
|
|
|
160
200
|
}
|
|
161
201
|
failClient(error) {
|
|
162
202
|
this.rejectAll(error);
|
|
163
|
-
|
|
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
|
+
}
|
|
164
215
|
}
|
|
165
216
|
clearAttachTimer() {
|
|
166
217
|
if (this.attachTimer !== void 0) {
|
|
@@ -174,6 +225,12 @@ var WorkerClient = class {
|
|
|
174
225
|
this.stoppedTimer = void 0;
|
|
175
226
|
}
|
|
176
227
|
}
|
|
228
|
+
clearStartedTimer() {
|
|
229
|
+
if (this.startedTimer !== void 0) {
|
|
230
|
+
clearTimeout(this.startedTimer);
|
|
231
|
+
this.startedTimer = void 0;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
177
234
|
clearDestroyedTimer() {
|
|
178
235
|
if (this.destroyedTimer !== void 0) {
|
|
179
236
|
clearTimeout(this.destroyedTimer);
|
|
@@ -181,6 +238,18 @@ var WorkerClient = class {
|
|
|
181
238
|
}
|
|
182
239
|
}
|
|
183
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
|
+
}
|
|
184
253
|
function createRuntimeWorker(options) {
|
|
185
254
|
const url = options.runtime.workerUrl === void 0 ? new URL("./rivmux-runtime-worker.js", import.meta.url) : options.runtime.workerUrl;
|
|
186
255
|
return new Worker(url, {
|
|
@@ -189,17 +258,35 @@ function createRuntimeWorker(options) {
|
|
|
189
258
|
});
|
|
190
259
|
}
|
|
191
260
|
function createRuntimeWorkerError(code, message, terminal, cause) {
|
|
192
|
-
|
|
261
|
+
if (cause === void 0) return {
|
|
193
262
|
kind: "runtime",
|
|
194
263
|
code,
|
|
195
264
|
message,
|
|
196
265
|
terminal
|
|
197
|
-
}
|
|
266
|
+
};
|
|
267
|
+
return {
|
|
198
268
|
kind: "runtime",
|
|
199
269
|
code,
|
|
200
270
|
message,
|
|
201
271
|
terminal,
|
|
202
|
-
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)
|
|
203
290
|
};
|
|
204
291
|
}
|
|
205
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.failClient(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.rejectAttach(createRuntimeWorkerError('RIVMUX_ATTACH_CANCELLED', 'Media source attachment was cancelled by stop.', false))\n this.resolveStop()\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.rejectStop(createRuntimeWorkerError('RIVMUX_STOP_CANCELLED', 'Stop was superseded by destroy.', false))\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 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 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.failClient(error)\n }, REQUEST_TIMEOUT_MS)\n }\n\n private failClient(error: PlayerError): void {\n this.rejectAll(error)\n this.hooks.onError(error)\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;
|
|
@@ -118,7 +119,7 @@ type TransmuxCoreWasmConstructor = new () => {
|
|
|
118
119
|
reset(): void;
|
|
119
120
|
destroy(): void;
|
|
120
121
|
};
|
|
121
|
-
declare class WasmTransmuxCoreHost implements TransmuxCoreHost {
|
|
122
|
+
export declare class WasmTransmuxCoreHost implements TransmuxCoreHost {
|
|
122
123
|
private readonly core;
|
|
123
124
|
constructor(Core: TransmuxCoreWasmConstructor);
|
|
124
125
|
pushChunk(chunk: Uint8Array): CoreEvent[];
|
|
@@ -126,7 +127,7 @@ declare class WasmTransmuxCoreHost implements TransmuxCoreHost {
|
|
|
126
127
|
reset(): void;
|
|
127
128
|
destroy(): void;
|
|
128
129
|
}
|
|
129
|
-
declare function normalizeCoreEvents(value: unknown): CoreEvent[];
|
|
130
|
+
export declare function normalizeCoreEvents(value: unknown): CoreEvent[];
|
|
130
131
|
//#endregion
|
|
131
132
|
//#region src/runtime/types.d.ts
|
|
132
133
|
type RuntimeMseCleanupOptions = {
|
|
@@ -162,13 +163,17 @@ type RuntimeWorkerDependencies = {
|
|
|
162
163
|
createTransmuxCore?: (options: NormalizedRivmuxPlayerOptions) => TransmuxCoreHost | undefined | Promise<TransmuxCoreHost | undefined>;
|
|
163
164
|
detectRuntime?: () => PlayerError | undefined;
|
|
164
165
|
now?: () => number;
|
|
166
|
+
sleep?: (delayMs: number, signal: AbortSignal) => Promise<void>;
|
|
167
|
+
random?: () => number;
|
|
165
168
|
};
|
|
166
169
|
//#endregion
|
|
167
170
|
//#region src/runtime/index.d.ts
|
|
168
|
-
declare class RuntimeWorker {
|
|
171
|
+
export declare class RuntimeWorker {
|
|
169
172
|
private readonly port;
|
|
170
173
|
private readonly detectRuntime;
|
|
171
174
|
private readonly now;
|
|
175
|
+
private readonly sleep;
|
|
176
|
+
private readonly random;
|
|
172
177
|
private state;
|
|
173
178
|
private url?;
|
|
174
179
|
private options?;
|
|
@@ -184,6 +189,10 @@ declare class RuntimeWorker {
|
|
|
184
189
|
private lifecycleGeneration;
|
|
185
190
|
private lifecycleAbortController;
|
|
186
191
|
private fatalCleanupPromise;
|
|
192
|
+
private recoveryPromise?;
|
|
193
|
+
private connectionAttempt;
|
|
194
|
+
private recoveryStartedAt?;
|
|
195
|
+
private pendingRecovery?;
|
|
187
196
|
constructor(port: RuntimeWorkerPort, dependencies?: RuntimeWorkerDependencies);
|
|
188
197
|
handleCommand(command: WorkerCommand): Promise<void>;
|
|
189
198
|
private executeCommand;
|
|
@@ -193,6 +202,11 @@ declare class RuntimeWorker {
|
|
|
193
202
|
private destroy;
|
|
194
203
|
private startLoader;
|
|
195
204
|
private closeLoader;
|
|
205
|
+
private scheduleRecovery;
|
|
206
|
+
private recover;
|
|
207
|
+
private markRecovered;
|
|
208
|
+
private waitForRecovery;
|
|
209
|
+
private resetRecoveryCycle;
|
|
196
210
|
private postStats;
|
|
197
211
|
private collectMseStats;
|
|
198
212
|
private quotaCleanupCutoff;
|
|
@@ -210,24 +224,37 @@ declare class RuntimeWorker {
|
|
|
210
224
|
}
|
|
211
225
|
//#endregion
|
|
212
226
|
//#region src/loader/http-flv-loader.d.ts
|
|
213
|
-
|
|
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 {
|
|
214
236
|
readonly code: string;
|
|
237
|
+
readonly phase: HttpFlvLoaderErrorPhase;
|
|
238
|
+
readonly reason?: ReconnectReason;
|
|
215
239
|
readonly status?: number;
|
|
216
|
-
|
|
240
|
+
readonly cause?: unknown;
|
|
241
|
+
constructor(code: string, message: string, options?: HttpFlvLoaderErrorOptions | number);
|
|
217
242
|
}
|
|
218
|
-
declare class HttpFlvLoader implements StreamLoader {
|
|
243
|
+
export declare class HttpFlvLoader implements StreamLoader {
|
|
219
244
|
private readonly url;
|
|
220
245
|
private readonly headers;
|
|
221
246
|
private readonly credentials;
|
|
222
|
-
private readonly
|
|
247
|
+
private readonly readIdleTimeoutMs;
|
|
223
248
|
private readonly fetchImpl;
|
|
224
249
|
private readonly now;
|
|
225
|
-
private readonly
|
|
250
|
+
private readonly setTimer;
|
|
251
|
+
private readonly clearTimer;
|
|
226
252
|
private abortController?;
|
|
227
253
|
private reader?;
|
|
228
254
|
private state;
|
|
229
255
|
private pausedState;
|
|
230
256
|
private resumeWaiters;
|
|
257
|
+
private activeReadTimeout?;
|
|
231
258
|
private readonly mutableStats;
|
|
232
259
|
constructor(config: StreamLoaderConfig);
|
|
233
260
|
get closed(): boolean;
|
|
@@ -238,13 +265,12 @@ declare class HttpFlvLoader implements StreamLoader {
|
|
|
238
265
|
pause(): void;
|
|
239
266
|
resume(): void;
|
|
240
267
|
close(): Promise<void>;
|
|
241
|
-
private openAttempt;
|
|
242
268
|
private waitUntilResumed;
|
|
243
269
|
private resolveResumeWaiters;
|
|
244
270
|
}
|
|
245
271
|
//#endregion
|
|
246
272
|
//#region src/mse/mse-controller.d.ts
|
|
247
|
-
declare class MseController {
|
|
273
|
+
export declare class MseController {
|
|
248
274
|
private mediaSource?;
|
|
249
275
|
private readonly sourceBuffers;
|
|
250
276
|
private readonly queues;
|
|
@@ -273,7 +299,7 @@ type MseCleanupOptions = {
|
|
|
273
299
|
};
|
|
274
300
|
//#endregion
|
|
275
301
|
//#region src/mse/source-buffer-queue.d.ts
|
|
276
|
-
declare class SourceBufferQueue {
|
|
302
|
+
export declare class SourceBufferQueue {
|
|
277
303
|
private readonly sourceBuffer;
|
|
278
304
|
private readonly queue;
|
|
279
305
|
private pendingDrain?;
|
|
@@ -297,10 +323,10 @@ declare class SourceBufferQueue {
|
|
|
297
323
|
}
|
|
298
324
|
//#endregion
|
|
299
325
|
//#region src/mse/mime.d.ts
|
|
300
|
-
declare function isMseSupported(mimeType: string): boolean;
|
|
326
|
+
export declare function isMseSupported(mimeType: string): boolean;
|
|
301
327
|
//#endregion
|
|
302
328
|
//#region src/wasm/wasm-loader.d.ts
|
|
303
|
-
declare function createWasmTransmuxCoreHost(Core: TransmuxCoreWasmConstructor | undefined): TransmuxCoreHost;
|
|
329
|
+
export declare function createWasmTransmuxCoreHost(Core: TransmuxCoreWasmConstructor | undefined): TransmuxCoreHost;
|
|
304
330
|
//#endregion
|
|
305
331
|
//#region src/worker-entry.d.ts
|
|
306
332
|
type DedicatedWorkerScopeLike = {
|
|
@@ -308,7 +334,7 @@ type DedicatedWorkerScopeLike = {
|
|
|
308
334
|
postMessage(message: WorkerMessage, transfer?: Transferable[]): void;
|
|
309
335
|
close(): void;
|
|
310
336
|
};
|
|
311
|
-
declare function startRuntimeWorker(scope: DedicatedWorkerScopeLike): RuntimeWorker;
|
|
337
|
+
export declare function startRuntimeWorker(scope: DedicatedWorkerScopeLike): RuntimeWorker;
|
|
312
338
|
//#endregion
|
|
313
|
-
export {
|
|
339
|
+
export type { CoreEvent, StreamChunk, StreamLoader, StreamLoaderConfig, StreamLoaderStats, TransmuxCoreHost, TransmuxCoreWasmConstructor };
|
|
314
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/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":";;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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"}
|