@meframe/server 0.0.1 → 0.0.3

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.
Files changed (35) hide show
  1. package/README.md +1 -1
  2. package/dist/ServerExporter.d.ts +2 -0
  3. package/dist/ServerExporter.d.ts.map +1 -1
  4. package/dist/ServerExporter.js +121 -80
  5. package/dist/ServerExporter.js.map +1 -1
  6. package/dist/runner/runner-browser.d.ts +21 -0
  7. package/dist/runner/runner-browser.d.ts.map +1 -0
  8. package/dist/runner/runner-browser.js +232 -0
  9. package/dist/runner/runner-browser.js.map +1 -0
  10. package/dist/runner/runner.d.ts +24 -0
  11. package/dist/runner/runner.d.ts.map +1 -0
  12. package/dist/runner/runner.js +73 -0
  13. package/dist/runner/runner.js.map +1 -0
  14. package/dist/{runner → runner-browser}/runner.mjs +1122 -1089
  15. package/dist/types.d.ts +8 -3
  16. package/dist/types.d.ts.map +1 -1
  17. package/dist/utils/abort-gate.d.ts +10 -0
  18. package/dist/utils/abort-gate.d.ts.map +1 -0
  19. package/dist/utils/abort-gate.js +45 -0
  20. package/dist/utils/abort-gate.js.map +1 -0
  21. package/docs/ARCHITECTURE.md +5 -5
  22. package/docs/INTEGRATION.md +317 -87
  23. package/package.json +3 -3
  24. package/dist/browser/puppeteer-core-launcher.d.ts +0 -3
  25. package/dist/browser/puppeteer-core-launcher.d.ts.map +0 -1
  26. package/dist/browser/puppeteer-core-launcher.js +0 -12
  27. package/dist/browser/puppeteer-core-launcher.js.map +0 -1
  28. package/dist/browser/types.d.ts +0 -21
  29. package/dist/browser/types.d.ts.map +0 -1
  30. package/dist/browser/types.js +0 -2
  31. package/dist/browser/types.js.map +0 -1
  32. package/dist/mock/MockMultipartObjectStore.d.ts +0 -37
  33. package/dist/mock/MockMultipartObjectStore.d.ts.map +0 -1
  34. package/dist/mock/MockMultipartObjectStore.js +0 -34
  35. package/dist/mock/MockMultipartObjectStore.js.map +0 -1
package/README.md CHANGED
@@ -33,7 +33,7 @@ Types are exported from `@meframe/server` root entry.
33
33
 
34
34
  ### Notes / requirements
35
35
 
36
- - **Chromium is not bundled**: this package depends on `puppeteer-core`, so production must provide a Chromium/Chrome binary and pass `executablePath` (or set env in your app).
36
+ - **Chromium is not bundled**: this package depends on `puppeteer-core` internally, so production must provide a Chromium/Chrome binary and pass `browser.executablePath` when creating `ServerExporter` (or load it from your own config system).
37
37
  - **Secure context is required** for WebCodecs: the exporter should navigate to a trustworthy origin (e.g. `http://127.0.0.1` or `https://...`) via `pageUrl` before running the runner.
38
38
  - **Worker files must be accessible** to the page at `/<workerPath>/...` (default `/meframe-workers/...`). The local example serves them from `@meframe/core/dist/workers`.
39
39
 
@@ -7,6 +7,8 @@ export declare class ServerExporter {
7
7
  private waiters;
8
8
  private runnerModuleCodePromise;
9
9
  constructor(options: ServerExporterOptions);
10
+ private createAbortError;
11
+ private abortMultipartUploadBestEffort;
10
12
  private acquireSlot;
11
13
  private releaseSlot;
12
14
  exportToStore(input: ExportToStoreInput): Promise<ExportToStoreResult>;
@@ -1 +1 @@
1
- {"version":3,"file":"ServerExporter.d.ts","sourceRoot":"","sources":["../src/ServerExporter.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAEV,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAGpB,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiC;IACvD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,uBAAuB,CAAgC;gBAEnD,OAAO,EAAE,qBAAqB;YAS5B,WAAW;IAWzB,OAAO,CAAC,WAAW;IAMb,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IA6L5E,OAAO,CAAC,gBAAgB;YA0BV,mBAAmB;IAmBjC,OAAO,CAAC,kBAAkB;CAI3B"}
1
+ {"version":3,"file":"ServerExporter.d.ts","sourceRoot":"","sources":["../src/ServerExporter.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAEV,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AASpB,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiC;IACvD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,OAAO,CAKP;IACR,OAAO,CAAC,uBAAuB,CAAgC;gBAEnD,OAAO,EAAE,qBAAqB;IAS1C,OAAO,CAAC,gBAAgB;YAIV,8BAA8B;YAa9B,WAAW;IAyBzB,OAAO,CAAC,WAAW;IAWb,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IA8L5E,OAAO,CAAC,gBAAgB;YA0BV,mBAAmB;IA2BjC,OAAO,CAAC,kBAAkB;CAI3B"}
@@ -4,6 +4,7 @@ import os from 'node:os';
4
4
  import path from 'node:path';
5
5
  import { launch } from 'puppeteer-core';
6
6
  import { runExportInPage } from './runner/runner.js';
7
+ import { AbortError, createAbortError, createAbortGate, throwIfAborted, } from './utils/abort-gate.js';
7
8
  export class ServerExporter {
8
9
  store;
9
10
  options;
@@ -19,24 +20,56 @@ export class ServerExporter {
19
20
  this.runnerModuleCodePromise = Promise.resolve(options.runner.moduleCode);
20
21
  }
21
22
  }
22
- async acquireSlot() {
23
+ createAbortError(message = 'Export aborted') {
24
+ return createAbortError(message);
25
+ }
26
+ async abortMultipartUploadBestEffort(input) {
27
+ if (!input.uploadId)
28
+ return;
29
+ try {
30
+ await this.store.abortMultipartUpload({ key: input.key, uploadId: input.uploadId });
31
+ }
32
+ catch (abortErr) {
33
+ input.logger.warn('[ServerExporter] abort failed', abortErr);
34
+ }
35
+ }
36
+ async acquireSlot(abortSignal) {
37
+ if (abortSignal?.aborted) {
38
+ throw this.createAbortError();
39
+ }
23
40
  if (this.activeJobs < this.maxJobs) {
24
41
  this.activeJobs += 1;
25
42
  return;
26
43
  }
27
- await new Promise((resolve) => {
28
- this.waiters.push(resolve);
44
+ await new Promise((resolve, reject) => {
45
+ const waiter = { resolve, reject, abortSignal };
46
+ if (abortSignal) {
47
+ const abortListener = () => {
48
+ const idx = this.waiters.indexOf(waiter);
49
+ if (idx >= 0)
50
+ this.waiters.splice(idx, 1);
51
+ abortSignal.removeEventListener('abort', abortListener);
52
+ reject(this.createAbortError());
53
+ };
54
+ waiter.abortListener = abortListener;
55
+ abortSignal.addEventListener('abort', abortListener, { once: true });
56
+ }
57
+ this.waiters.push(waiter);
29
58
  });
30
59
  this.activeJobs += 1;
31
60
  }
32
61
  releaseSlot() {
33
62
  this.activeJobs -= 1;
34
63
  const next = this.waiters.shift();
35
- if (next)
36
- next();
64
+ if (next) {
65
+ if (next.abortSignal && next.abortListener) {
66
+ next.abortSignal.removeEventListener('abort', next.abortListener);
67
+ }
68
+ next.resolve();
69
+ }
37
70
  }
38
71
  async exportToStore(input) {
39
- await this.acquireSlot();
72
+ await this.acquireSlot(input.abortSignal);
40
73
  const jobId = crypto.randomUUID();
41
74
  const logger = this.options.logger ?? console;
42
75
  const t0 = Date.now();
@@ -49,29 +82,36 @@ export class ServerExporter {
49
82
  logger.info(`[ServerExporter][${jobId}][${elapsedMs}ms] ${message}`);
50
83
  }
51
84
  };
52
- const partSizeBytes = this.options.defaults?.partSizeBytes ?? 8 * 1024 * 1024;
53
- const contentType = this.options.defaults?.contentType ?? 'video/mp4';
85
+ const partSizeBytes = this.options.upload?.partSizeBytes ?? 8 * 1024 * 1024;
86
+ const contentType = this.options.upload?.contentType ?? 'video/mp4';
87
+ const partUrlExpiresInSeconds = this.options.upload?.partUrlExpiresInSeconds ?? 600;
54
88
  if (partSizeBytes < 5 * 1024 * 1024) {
55
- throw new Error('defaults.partSizeBytes must be >= 5 MiB for multipart upload');
89
+ throw new Error('upload.partSizeBytes must be >= 5 MiB for multipart upload');
56
90
  }
57
91
  const key = input.key ??
58
- `${this.normalizeKeyPrefix(this.options.defaults?.keyPrefix)}` +
92
+ `${this.normalizeKeyPrefix(this.options.upload?.keyPrefix)}` +
59
93
  `${new Date().toISOString().replace(/[:.]/g, '-')}-${jobId}.mp4`;
60
94
  let browser = null;
61
95
  let page = null;
62
- let abortListener = null;
63
96
  let uploadId = null;
64
97
  let userDataDir = null;
65
98
  let abortedByUser = false;
99
+ const { abortPromise, dispose: disposeAbortGate } = createAbortGate(input.abortSignal, () => {
100
+ abortedByUser = true;
101
+ // Hard-stop the page so the job can exit quickly (runner promise rejects on page close).
102
+ void page?.close({ runBeforeUnload: false }).catch(() => { });
103
+ });
66
104
  try {
67
105
  log('Preparing job', {
68
106
  key,
69
107
  partSizeBytes,
70
- headless: this.options.puppeteer?.headless ?? true,
71
- executablePath: this.options.puppeteer?.executablePath,
108
+ headless: this.options.browser?.headless ?? true,
109
+ executablePath: this.options.browser?.executablePath,
72
110
  });
73
- userDataDir = await fs.mkdtemp(path.join(this.options.puppeteer?.userDataDirBase ?? os.tmpdir(), 'meframe-server-'));
111
+ throwIfAborted(input.abortSignal);
112
+ userDataDir = await fs.mkdtemp(path.join(this.options.browser?.userDataDirBase ?? os.tmpdir(), 'meframe-server-'));
74
113
  log('Created userDataDir', { userDataDir });
114
+ throwIfAborted(input.abortSignal);
75
115
  const uploadInit = await this.store.createMultipartUpload({
76
116
  key,
77
117
  contentType,
@@ -87,66 +127,68 @@ export class ServerExporter {
87
127
  this.options.onProgress?.({ jobId, ...evt });
88
128
  };
89
129
  log('Loading runner bundle...');
130
+ throwIfAborted(input.abortSignal);
90
131
  const runnerModuleCode = await this.getRunnerModuleCode();
91
132
  log('Runner bundle loaded', { bytes: runnerModuleCode.length });
92
133
  log('Launching browser...');
134
+ throwIfAborted(input.abortSignal);
93
135
  browser = await launch({
94
- headless: this.options.puppeteer?.headless ?? true,
95
- executablePath: this.options.puppeteer?.executablePath,
96
- args: this.options.puppeteer?.launchArgs,
136
+ headless: this.options.browser?.headless ?? true,
137
+ executablePath: this.options.browser?.executablePath,
138
+ args: this.options.browser?.launchArgs,
97
139
  userDataDir,
98
140
  });
99
141
  log('Browser launched');
100
142
  log('Creating page...');
143
+ throwIfAborted(input.abortSignal);
101
144
  page = await browser.newPage();
102
145
  log('Page created');
103
146
  // Forward runner logs / errors to Node side for observability.
104
- page.on('console', (msg) => logger.info('[runner:console]', msg.text()));
105
- page.on('pageerror', (err) => logger.error('[runner:pageerror]', err));
106
- page.on('error', (err) => logger.error('[runner:error]', err));
147
+ page.on('console', (msg) => logger.info(`[runner:console][${jobId}][${msg?.type?.() ?? 'log'}]`, msg.text()));
148
+ page.on('pageerror', (err) => logger.error(`[runner:pageerror][${jobId}]`, err));
149
+ page.on('error', (err) => logger.error(`[runner:error][${jobId}]`, err));
107
150
  page.on('requestfailed', (req) => {
108
- logger.warn('[runner:requestfailed]', {
151
+ const failure = req?.failure?.();
152
+ if (failure?.errorText === 'net::ERR_ABORTED')
153
+ return;
154
+ logger.warn(`[runner:requestfailed][${jobId}]`, {
109
155
  url: req?.url?.(),
110
156
  method: req?.method?.(),
111
- failure: req?.failure?.(),
157
+ failure,
112
158
  });
113
159
  });
114
- if (input.abortSignal) {
115
- abortListener = () => {
116
- // Best-effort; page may already be closed.
117
- abortedByUser = true;
118
- void page?.evaluate(() => window.__serverAbort?.()).catch(() => { });
119
- };
120
- input.abortSignal.addEventListener('abort', abortListener);
121
- }
122
160
  log('Running export in page...');
123
- await runExportInPage(page, {
124
- requestPartUrl: async (partNumber) => this.store.getUploadPartUrl({
125
- key,
161
+ await Promise.race([
162
+ runExportInPage(page, {
163
+ requestPartUrl: async (partNumber) => this.store.getUploadPartUrl({
164
+ key,
165
+ uploadId: uploadId,
166
+ partNumber,
167
+ expiresInSeconds: partUrlExpiresInSeconds,
168
+ }),
169
+ reportPartDone: async (partNumber, etag) => {
170
+ const normalizedEtag = etag.replace(/^"+|"+$/g, '');
171
+ parts.push({ partNumber, etag: normalizedEtag });
172
+ },
173
+ reportProgress: async (event) => onProgress(event),
174
+ reportError: async (message) => {
175
+ throw new Error(message);
176
+ },
177
+ reportComplete: async (_totalBytes) => {
178
+ // no-op, completion handled after runner resolves
179
+ },
180
+ }, {
181
+ model: input.model,
182
+ exportOptions: input.exportOptions ?? {},
183
+ partSizeBytes,
126
184
  uploadId: uploadId,
127
- partNumber,
128
- expiresInSeconds: 600,
185
+ key,
186
+ runnerModuleCode,
187
+ pageUrl: input.pageUrl,
188
+ workerPath: input.workerPath,
129
189
  }),
130
- reportPartDone: async (partNumber, etag) => {
131
- parts.push({ partNumber, etag });
132
- },
133
- reportProgress: async (event) => onProgress(event),
134
- reportError: async (message) => {
135
- throw new Error(message);
136
- },
137
- reportComplete: async (_totalBytes) => {
138
- // no-op, completion handled after runner resolves
139
- },
140
- }, {
141
- model: input.model,
142
- exportOptions: input.exportOptions ?? {},
143
- partSizeBytes,
144
- uploadId: uploadId,
145
- key,
146
- runnerModuleCode,
147
- pageUrl: input.pageUrl,
148
- workerPath: input.workerPath,
149
- });
190
+ abortPromise,
191
+ ]);
150
192
  log('Runner resolved');
151
193
  parts.sort((a, b) => a.partNumber - b.partNumber);
152
194
  this.assertPartsValid(parts);
@@ -158,6 +200,7 @@ export class ServerExporter {
158
200
  catch (error) {
159
201
  const isAbort = abortedByUser ||
160
202
  input.abortSignal?.aborted === true ||
203
+ error instanceof AbortError ||
161
204
  (error instanceof DOMException && error.name === 'AbortError') ||
162
205
  (error instanceof Error && error.name === 'AbortError');
163
206
  if (isAbort) {
@@ -166,37 +209,30 @@ export class ServerExporter {
166
209
  else {
167
210
  logger.error('[ServerExporter] export failed', error);
168
211
  }
169
- // Best-effort abort
170
- try {
171
- const keyToAbort = key;
172
- const uploadIdToAbort = uploadId ?? error?.uploadId;
173
- if (uploadIdToAbort) {
174
- await this.store.abortMultipartUpload({ key: keyToAbort, uploadId: uploadIdToAbort });
175
- }
176
- }
177
- catch (abortErr) {
178
- logger.warn('[ServerExporter] abort failed', abortErr);
179
- }
212
+ await this.abortMultipartUploadBestEffort({ key, uploadId, logger });
180
213
  if (isAbort) {
181
- throw new DOMException('Export aborted', 'AbortError');
214
+ throw this.createAbortError();
182
215
  }
183
216
  throw error;
184
217
  }
185
218
  finally {
186
- if (input.abortSignal && abortListener) {
187
- input.abortSignal.removeEventListener('abort', abortListener);
188
- }
189
- const cleanupTasks = [];
219
+ disposeAbortGate();
220
+ // Cleanup order matters: Chromium may still be writing to the profile directory
221
+ // while closing. Close the browser first, then remove userDataDir.
190
222
  if (browser) {
191
- cleanupTasks.push(browser.close());
223
+ try {
224
+ await browser.close();
225
+ }
226
+ catch (e) {
227
+ logger.warn('[ServerExporter] cleanup failed', e);
228
+ }
192
229
  }
193
230
  if (userDataDir) {
194
- cleanupTasks.push(fs.rm(userDataDir, { recursive: true, force: true }));
195
- }
196
- const results = await Promise.allSettled(cleanupTasks);
197
- for (const r of results) {
198
- if (r.status === 'rejected') {
199
- logger.warn('[ServerExporter] cleanup failed', r.reason);
231
+ try {
232
+ await fs.rm(userDataDir, { recursive: true, force: true });
233
+ }
234
+ catch (e) {
235
+ logger.warn('[ServerExporter] cleanup failed', e);
200
236
  }
201
237
  }
202
238
  this.releaseSlot();
@@ -227,8 +263,8 @@ export class ServerExporter {
227
263
  }
228
264
  async getRunnerModuleCode() {
229
265
  if (!this.runnerModuleCodePromise) {
230
- this.runnerModuleCodePromise = (async () => {
231
- const runnerModuleFile = new URL('./runner/runner.mjs', import.meta.url);
266
+ const promise = (async () => {
267
+ const runnerModuleFile = new URL('./runner-browser/runner.mjs', import.meta.url);
232
268
  try {
233
269
  return await fs.readFile(runnerModuleFile, 'utf8');
234
270
  }
@@ -239,6 +275,11 @@ export class ServerExporter {
239
275
  throw e;
240
276
  }
241
277
  })();
278
+ // Only cache successful reads; allow retry if it fails.
279
+ this.runnerModuleCodePromise = promise.then((code) => code, (err) => {
280
+ this.runnerModuleCodePromise = null;
281
+ throw err;
282
+ });
242
283
  }
243
284
  return await this.runnerModuleCodePromise;
244
285
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ServerExporter.js","sourceRoot":"","sources":["../src/ServerExporter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ServerExporter.js","sourceRoot":"","sources":["../src/ServerExporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ declare global {
2
+ interface Window {
3
+ __MEFRAME_RUNNER_CONFIG__?: {
4
+ model: any;
5
+ exportOptions: any;
6
+ partSizeBytes: number;
7
+ workerPath?: string;
8
+ };
9
+ __serverAbort?: () => void;
10
+ runnerRequestPartUrl: (partNumber: number) => Promise<{
11
+ url: string;
12
+ headers?: Record<string, string>;
13
+ }>;
14
+ runnerReportPartDone: (partNumber: number, etag: string) => Promise<void>;
15
+ runnerReportProgress: (event: any) => Promise<void>;
16
+ runnerReportError: (message: string) => Promise<void>;
17
+ runnerReportComplete: (totalBytes: number) => Promise<void>;
18
+ }
19
+ }
20
+ export {};
21
+ //# sourceMappingURL=runner-browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner-browser.d.ts","sourceRoot":"","sources":["../../src/runner/runner-browser.ts"],"names":[],"mappings":"AAEA,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,yBAAyB,CAAC,EAAE;YAC1B,KAAK,EAAE,GAAG,CAAC;YACX,aAAa,EAAE,GAAG,CAAC;YACnB,aAAa,EAAE,MAAM,CAAC;YACtB,UAAU,CAAC,EAAE,MAAM,CAAC;SACrB,CAAC;QACF,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;QAC3B,oBAAoB,EAAE,CACpB,UAAU,EAAE,MAAM,KACf,OAAO,CAAC;YAAE,GAAG,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;SAAE,CAAC,CAAC;QAChE,oBAAoB,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QAC1E,oBAAoB,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACpD,iBAAiB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACtD,oBAAoB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KAC7D;CACF"}
@@ -0,0 +1,232 @@
1
+ import { Meframe, MeframeEvent } from '@meframe/core';
2
+ async function main() {
3
+ // Basic environment sanity checks (helps debug "hangs" where WebCodecs isn't available)
4
+ console.log('[meframe-runner] boot', {
5
+ isSecureContext: globalThis.isSecureContext,
6
+ crossOriginIsolated: globalThis.crossOriginIsolated,
7
+ hasVideoEncoder: typeof globalThis.VideoEncoder === 'function',
8
+ hasVideoDecoder: typeof globalThis.VideoDecoder === 'function',
9
+ hasAudioEncoder: typeof globalThis.AudioEncoder === 'function',
10
+ hasAudioDecoder: typeof globalThis.AudioDecoder === 'function',
11
+ });
12
+ const cfg = window.__MEFRAME_RUNNER_CONFIG__;
13
+ if (!cfg) {
14
+ throw new Error('Missing __MEFRAME_RUNNER_CONFIG__');
15
+ }
16
+ const { model, exportOptions, partSizeBytes, workerPath } = cfg;
17
+ if (typeof globalThis.VideoEncoder !== 'function') {
18
+ throw new Error('WebCodecs VideoEncoder is not available in this browser context');
19
+ }
20
+ console.log('[meframe-runner] creating meframe...');
21
+ const normalizeWorkerPath = (p) => {
22
+ if (!p)
23
+ return undefined;
24
+ return p.replace(/\/+$/, '');
25
+ };
26
+ const meframe = await Meframe.create({
27
+ global: {
28
+ workerPath: normalizeWorkerPath(workerPath),
29
+ },
30
+ });
31
+ console.log('[meframe-runner] setCompositionModel...');
32
+ await meframe.setCompositionModel(model);
33
+ let totalBytes = 0;
34
+ const abortController = new AbortController();
35
+ window.__serverAbort = () => abortController.abort();
36
+ const sleep = (ms) => new Promise((resolve) => {
37
+ setTimeout(resolve, ms);
38
+ });
39
+ const shouldRetryUpload = (status) => status === 429 || (status >= 500 && status <= 599);
40
+ const partStates = new Map();
41
+ const pendingUploads = new Map();
42
+ const getOrCreatePart = (partNo) => {
43
+ let p = partStates.get(partNo);
44
+ if (!p) {
45
+ p = { buf: new Uint8Array(partSizeBytes), ranges: [], uploaded: false };
46
+ partStates.set(partNo, p);
47
+ }
48
+ return p;
49
+ };
50
+ const addRange = (ranges, start, end) => {
51
+ if (end <= start)
52
+ return;
53
+ ranges.push({ start, end });
54
+ ranges.sort((a, b) => a.start - b.start);
55
+ // Merge in-place
56
+ let w = 0;
57
+ for (let i = 0; i < ranges.length; i++) {
58
+ const cur = ranges[i];
59
+ if (w === 0) {
60
+ ranges[w++] = cur;
61
+ continue;
62
+ }
63
+ const prev = ranges[w - 1];
64
+ if (cur.start <= prev.end) {
65
+ prev.end = Math.max(prev.end, cur.end);
66
+ }
67
+ else {
68
+ ranges[w++] = cur;
69
+ }
70
+ }
71
+ ranges.length = w;
72
+ };
73
+ const isRangeCovered = (ranges, expectedSize) => {
74
+ if (expectedSize <= 0)
75
+ return true;
76
+ if (ranges.length === 0)
77
+ return false;
78
+ // ranges are kept sorted and merged by addRange(), but there may still be gaps.
79
+ // We must ensure [0, expectedSize) is continuously covered.
80
+ let coveredEnd = ranges[0].start === 0 ? ranges[0].end : 0;
81
+ if (coveredEnd === 0)
82
+ return false;
83
+ for (let i = 1; i < ranges.length && coveredEnd < expectedSize; i++) {
84
+ const r = ranges[i];
85
+ if (r.start > coveredEnd) {
86
+ return false; // gap
87
+ }
88
+ coveredEnd = Math.max(coveredEnd, r.end);
89
+ }
90
+ return coveredEnd >= expectedSize;
91
+ };
92
+ const uploadPart = async (bodyParts, partNo) => {
93
+ const MAX_ATTEMPTS = 4;
94
+ for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
95
+ if (abortController.signal.aborted) {
96
+ throw new DOMException('Export aborted', 'AbortError');
97
+ }
98
+ const { url, headers } = await window.runnerRequestPartUrl(partNo);
99
+ const blob = new Blob(bodyParts, { type: 'application/octet-stream' });
100
+ try {
101
+ const response = await fetch(url, {
102
+ method: 'PUT',
103
+ body: blob,
104
+ headers: headers ?? {},
105
+ signal: abortController.signal,
106
+ });
107
+ if (!response.ok) {
108
+ if (attempt < MAX_ATTEMPTS && shouldRetryUpload(response.status)) {
109
+ const backoffMs = Math.min(8000, 250 * 2 ** (attempt - 1));
110
+ await sleep(backoffMs);
111
+ continue;
112
+ }
113
+ throw new Error(`UploadPart failed: HTTP ${response.status}`);
114
+ }
115
+ const etag = response.headers.get('etag') || response.headers.get('ETag');
116
+ if (!etag) {
117
+ throw new Error('UploadPart missing ETag header');
118
+ }
119
+ await window.runnerReportPartDone(partNo, etag);
120
+ return;
121
+ }
122
+ catch (e) {
123
+ if (e instanceof DOMException && e.name === 'AbortError') {
124
+ throw e;
125
+ }
126
+ if (attempt < MAX_ATTEMPTS) {
127
+ const backoffMs = Math.min(8000, 250 * 2 ** (attempt - 1));
128
+ await sleep(backoffMs);
129
+ continue;
130
+ }
131
+ throw e;
132
+ }
133
+ }
134
+ };
135
+ let flushChain = Promise.resolve();
136
+ let isFinalizing = false;
137
+ const scheduleTryUpload = (partNo, expectedSize) => {
138
+ // Delay uploading part 1 until finalization; avoid creating a long chain of no-op tasks.
139
+ if (partNo === 1 && !isFinalizing)
140
+ return;
141
+ const prevExpectedSize = pendingUploads.get(partNo);
142
+ if (prevExpectedSize !== undefined) {
143
+ pendingUploads.set(partNo, Math.max(prevExpectedSize, expectedSize));
144
+ return;
145
+ }
146
+ pendingUploads.set(partNo, expectedSize);
147
+ flushChain = flushChain.then(async () => {
148
+ const expectedSizeToUpload = pendingUploads.get(partNo);
149
+ pendingUploads.delete(partNo);
150
+ if (expectedSizeToUpload === undefined)
151
+ return;
152
+ const p = partStates.get(partNo);
153
+ if (!p || p.uploaded)
154
+ return;
155
+ if (!isRangeCovered(p.ranges, expectedSizeToUpload))
156
+ return;
157
+ // Upload a stable snapshot of the part.
158
+ const body = p.buf.subarray(0, expectedSizeToUpload);
159
+ await uploadPart([body], partNo);
160
+ p.uploaded = true;
161
+ // Free memory ASAP.
162
+ partStates.delete(partNo);
163
+ });
164
+ };
165
+ const onMuxData = (data, position) => {
166
+ totalBytes = Math.max(totalBytes, position + data.byteLength);
167
+ let remaining = data;
168
+ let pos = position;
169
+ while (remaining.byteLength > 0) {
170
+ const partNo = Math.floor(pos / partSizeBytes) + 1;
171
+ const offsetInPart = pos % partSizeBytes;
172
+ const bytesInThisPart = Math.min(partSizeBytes - offsetInPart, remaining.byteLength);
173
+ const p = getOrCreatePart(partNo);
174
+ p.buf.set(remaining.subarray(0, bytesInThisPart), offsetInPart);
175
+ addRange(p.ranges, offsetInPart, offsetInPart + bytesInThisPart);
176
+ // For any non-last part, it must be exactly partSizeBytes.
177
+ // We don't know which part is last yet, but attempting early uploads is safe:
178
+ // - If it's not fully covered, the guard will prevent upload.
179
+ // - If it ends up being the last part and smaller, we'll upload it in finalize below.
180
+ scheduleTryUpload(partNo, partSizeBytes);
181
+ remaining = remaining.subarray(bytesInThisPart);
182
+ pos += bytesInThisPart;
183
+ }
184
+ };
185
+ let lastProgressLogAt = 0;
186
+ meframe.events.on(MeframeEvent.ExportProgress, (evt) => {
187
+ void window.runnerReportProgress(evt);
188
+ const now = Date.now();
189
+ if (now - lastProgressLogAt >= 1000) {
190
+ lastProgressLogAt = now;
191
+ console.log('[meframe-runner] progress', evt);
192
+ }
193
+ });
194
+ meframe.events.on(MeframeEvent.ExportStart, (evt) => {
195
+ console.log('[meframe-runner] export:start', evt);
196
+ });
197
+ meframe.events.on(MeframeEvent.ExportComplete, (evt) => {
198
+ console.log('[meframe-runner] export:complete', evt);
199
+ });
200
+ console.log('[meframe-runner] export()...');
201
+ await meframe.export({
202
+ ...exportOptions,
203
+ exportMode: 'stream',
204
+ onMuxData,
205
+ // IMPORTANT:
206
+ // mp4-muxer@5.2.2 StreamTarget "chunked" mode buffers into fixed-size chunks and only emits
207
+ // when a whole chunk is filled (or on finalize). With our current muxing pattern (seek+patch),
208
+ // we've observed 0-byte output in some environments. Disable chunked mode and let the runner
209
+ // aggregate into multipart partSizeBytes instead.
210
+ muxChunked: false,
211
+ signal: abortController.signal,
212
+ });
213
+ if (totalBytes === 0) {
214
+ throw new Error(`[meframe-runner] stream mux produced 0 bytes. ` +
215
+ `This indicates mp4-muxer StreamTarget did not emit any data.`);
216
+ }
217
+ console.log('[meframe-runner] finalize: flushing parts...');
218
+ // Finalize uploads based on final totalBytes. The last part may be smaller than partSizeBytes.
219
+ const totalParts = Math.ceil(totalBytes / partSizeBytes);
220
+ isFinalizing = true;
221
+ for (let partNo = 1; partNo <= totalParts; partNo++) {
222
+ const expectedSize = partNo === totalParts ? totalBytes - (totalParts - 1) * partSizeBytes : partSizeBytes;
223
+ scheduleTryUpload(partNo, expectedSize);
224
+ }
225
+ await flushChain;
226
+ console.log('[meframe-runner] done', { totalBytes });
227
+ await window.runnerReportComplete(totalBytes);
228
+ }
229
+ main().catch(async (error) => {
230
+ await window.runnerReportError(error?.message ?? String(error)).catch(() => { });
231
+ });
232
+ //# sourceMappingURL=runner-browser.js.map