@meframe/server 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -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
 
@@ -49,13 +49,13 @@ export class ServerExporter {
49
49
  logger.info(`[ServerExporter][${jobId}][${elapsedMs}ms] ${message}`);
50
50
  }
51
51
  };
52
- const partSizeBytes = this.options.defaults?.partSizeBytes ?? 8 * 1024 * 1024;
53
- const contentType = this.options.defaults?.contentType ?? 'video/mp4';
52
+ const partSizeBytes = this.options.upload?.partSizeBytes ?? 8 * 1024 * 1024;
53
+ const contentType = this.options.upload?.contentType ?? 'video/mp4';
54
54
  if (partSizeBytes < 5 * 1024 * 1024) {
55
- throw new Error('defaults.partSizeBytes must be >= 5 MiB for multipart upload');
55
+ throw new Error('upload.partSizeBytes must be >= 5 MiB for multipart upload');
56
56
  }
57
57
  const key = input.key ??
58
- `${this.normalizeKeyPrefix(this.options.defaults?.keyPrefix)}` +
58
+ `${this.normalizeKeyPrefix(this.options.upload?.keyPrefix)}` +
59
59
  `${new Date().toISOString().replace(/[:.]/g, '-')}-${jobId}.mp4`;
60
60
  let browser = null;
61
61
  let page = null;
@@ -67,10 +67,10 @@ export class ServerExporter {
67
67
  log('Preparing job', {
68
68
  key,
69
69
  partSizeBytes,
70
- headless: this.options.puppeteer?.headless ?? true,
71
- executablePath: this.options.puppeteer?.executablePath,
70
+ headless: this.options.browser?.headless ?? true,
71
+ executablePath: this.options.browser?.executablePath,
72
72
  });
73
- userDataDir = await fs.mkdtemp(path.join(this.options.puppeteer?.userDataDirBase ?? os.tmpdir(), 'meframe-server-'));
73
+ userDataDir = await fs.mkdtemp(path.join(this.options.browser?.userDataDirBase ?? os.tmpdir(), 'meframe-server-'));
74
74
  log('Created userDataDir', { userDataDir });
75
75
  const uploadInit = await this.store.createMultipartUpload({
76
76
  key,
@@ -91,9 +91,9 @@ export class ServerExporter {
91
91
  log('Runner bundle loaded', { bytes: runnerModuleCode.length });
92
92
  log('Launching browser...');
93
93
  browser = await launch({
94
- headless: this.options.puppeteer?.headless ?? true,
95
- executablePath: this.options.puppeteer?.executablePath,
96
- args: this.options.puppeteer?.launchArgs,
94
+ headless: this.options.browser?.headless ?? true,
95
+ executablePath: this.options.browser?.executablePath,
96
+ args: this.options.browser?.launchArgs,
97
97
  userDataDir,
98
98
  });
99
99
  log('Browser launched');
@@ -228,7 +228,7 @@ export class ServerExporter {
228
228
  async getRunnerModuleCode() {
229
229
  if (!this.runnerModuleCodePromise) {
230
230
  this.runnerModuleCodePromise = (async () => {
231
- const runnerModuleFile = new URL('./runner/runner.mjs', import.meta.url);
231
+ const runnerModuleFile = new URL('./runner-browser/runner.mjs', import.meta.url);
232
232
  try {
233
233
  return await fs.readFile(runnerModuleFile, 'utf8');
234
234
  }
@@ -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":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,EAA2B,MAAM,gBAAgB,CAAC;AAQjE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,OAAO,cAAc;IACR,KAAK,CAAiC;IACtC,OAAO,CAAwB;IAC/B,OAAO,CAAS;IACzB,UAAU,GAAG,CAAC,CAAC;IACf,OAAO,GAAsB,EAAE,CAAC;IAChC,uBAAuB,GAA2B,IAAI,CAAC;IAE/D,YAAY,OAA8B;QACxC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,WAAW,EAAE,OAAO,IAAI,CAAC,CAAC;QACjD,IAAI,OAAO,OAAO,CAAC,MAAM,EAAE,UAAU,KAAK,QAAQ,EAAE,CAAC;YACnD,IAAI,CAAC,uBAAuB,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,WAAW;QACvB,IAAI,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;YACnC,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAClC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC;IACvB,CAAC;IAEO,WAAW;QACjB,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC;QACrB,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAClC,IAAI,IAAI;YAAE,IAAI,EAAE,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,KAAyB;QAC3C,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC;QAC9C,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACtB,MAAM,GAAG,GAAG,CAAC,OAAe,EAAE,KAA+B,EAAE,EAAE;YAC/D,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;YAClC,IAAI,KAAK,EAAE,CAAC;gBACV,MAAM,CAAC,IAAI,CAAC,oBAAoB,KAAK,KAAK,SAAS,OAAO,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;YAC9E,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,CAAC,oBAAoB,KAAK,KAAK,SAAS,OAAO,OAAO,EAAE,CAAC,CAAC;YACvE,CAAC;QACH,CAAC,CAAC;QACF,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,aAAa,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;QAC5E,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,WAAW,IAAI,WAAW,CAAC;QACpE,IAAI,aAAa,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;QAChF,CAAC;QACD,MAAM,GAAG,GACP,KAAK,CAAC,GAAG;YACT,GAAG,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE;gBAC1D,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC;QAErE,IAAI,OAAO,GAAmB,IAAI,CAAC;QACnC,IAAI,IAAI,GAAgB,IAAI,CAAC;QAC7B,IAAI,aAAa,GAAwB,IAAI,CAAC;QAC9C,IAAI,QAAQ,GAAkB,IAAI,CAAC;QACnC,IAAI,WAAW,GAAkB,IAAI,CAAC;QACtC,IAAI,aAAa,GAAG,KAAK,CAAC;QAE1B,IAAI,CAAC;YACH,GAAG,CAAC,eAAe,EAAE;gBACnB,GAAG;gBACH,aAAa;gBACb,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,IAAI,IAAI;gBAChD,cAAc,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,cAAc;aACrD,CAAC,CAAC;YAEH,WAAW,GAAG,MAAM,EAAE,CAAC,OAAO,CAC5B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,eAAe,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CACnF,CAAC;YACF,GAAG,CAAC,qBAAqB,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;YAE5C,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC;gBACxD,GAAG;gBACH,WAAW;gBACX,QAAQ,EAAE,KAAK,CAAC,QAAQ;aACzB,CAAC,CAAC;YACH,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC;YAC/B,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;YACvD,CAAC;YACD,GAAG,CAAC,0BAA0B,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;YAE9C,MAAM,KAAK,GAAgD,EAAE,CAAC;YAC9D,MAAM,UAAU,GAAG,CAAC,GAAwB,EAAE,EAAE;gBAC9C,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC;YAC/C,CAAC,CAAC;YAEF,GAAG,CAAC,0BAA0B,CAAC,CAAC;YAChC,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC1D,GAAG,CAAC,sBAAsB,EAAE,EAAE,KAAK,EAAE,gBAAgB,CAAC,MAAM,EAAE,CAAC,CAAC;YAEhE,GAAG,CAAC,sBAAsB,CAAC,CAAC;YAC5B,OAAO,GAAG,MAAM,MAAM,CAAC;gBACrB,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,IAAI,IAAI;gBAChD,cAAc,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,cAAc;gBACpD,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,UAAU;gBACtC,WAAW;aACZ,CAAC,CAAC;YACH,GAAG,CAAC,kBAAkB,CAAC,CAAC;YAExB,GAAG,CAAC,kBAAkB,CAAC,CAAC;YACxB,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;YAC/B,GAAG,CAAC,cAAc,CAAC,CAAC;YAEpB,+DAA+D;YAC/D,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAQ,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,kBAAkB,EAAE,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;YAC9E,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,GAAQ,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE,GAAG,CAAC,CAAC,CAAC;YAC5E,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAQ,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC,CAAC;YACpE,IAAI,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,GAAQ,EAAE,EAAE;gBACpC,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE;oBACpC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;oBACjB,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE;oBACvB,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE;iBAC1B,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;gBACtB,aAAa,GAAG,GAAG,EAAE;oBACnB,2CAA2C;oBAC3C,aAAa,GAAG,IAAI,CAAC;oBACrB,KAAK,IAAI,EAAE,QAAQ,CAAC,GAAG,EAAE,CAAE,MAAc,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;gBAC/E,CAAC,CAAC;gBACF,KAAK,CAAC,WAAW,CAAC,gBAAgB,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;YAC7D,CAAC;YAED,GAAG,CAAC,2BAA2B,CAAC,CAAC;YACjC,MAAM,eAAe,CACnB,IAAI,EACJ;gBACE,cAAc,EAAE,KAAK,EAAE,UAAkB,EAAE,EAAE,CAC3C,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC;oBAC1B,GAAG;oBACH,QAAQ,EAAE,QAAS;oBACnB,UAAU;oBACV,gBAAgB,EAAE,GAAG;iBACtB,CAAC;gBACJ,cAAc,EAAE,KAAK,EAAE,UAAkB,EAAE,IAAY,EAAE,EAAE;oBACzD,KAAK,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;gBACnC,CAAC;gBACD,cAAc,EAAE,KAAK,EAAE,KAA0B,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC;gBACvE,WAAW,EAAE,KAAK,EAAE,OAAe,EAAE,EAAE;oBACrC,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;gBAC3B,CAAC;gBACD,cAAc,EAAE,KAAK,EAAE,WAAmB,EAAE,EAAE;oBAC5C,kDAAkD;gBACpD,CAAC;aACF,EACD;gBACE,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,aAAa,EAAE,KAAK,CAAC,aAAa,IAAI,EAAE;gBACxC,aAAa;gBACb,QAAQ,EAAE,QAAS;gBACnB,GAAG;gBACH,gBAAgB;gBAChB,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,UAAU,EAAE,KAAK,CAAC,UAAU;aAC7B,CACF,CAAC;YACF,GAAG,CAAC,iBAAiB,CAAC,CAAC;YAEvB,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC;YAClD,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;YAC7B,GAAG,CAAC,gCAAgC,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;YAC/D,MAAM,IAAI,CAAC,KAAK,CAAC,uBAAuB,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAS,EAAE,KAAK,EAAE,CAAC,CAAC;YAC9E,GAAG,CAAC,kBAAkB,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;YACjC,OAAO,EAAE,GAAG,EAAE,CAAC;QACjB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GACX,aAAa;gBACb,KAAK,CAAC,WAAW,EAAE,OAAO,KAAK,IAAI;gBACnC,CAAC,KAAK,YAAY,YAAY,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC;gBAC9D,CAAC,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC;YAE1D,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;YACjD,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC;YACxD,CAAC;YAED,oBAAoB;YACpB,IAAI,CAAC;gBACH,MAAM,UAAU,GAAG,GAAG,CAAC;gBACvB,MAAM,eAAe,GAAG,QAAQ,IAAK,KAAa,EAAE,QAAQ,CAAC;gBAC7D,IAAI,eAAe,EAAE,CAAC;oBACpB,MAAM,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC,CAAC;gBACxF,CAAC;YACH,CAAC;YAAC,OAAO,QAAQ,EAAE,CAAC;gBAClB,MAAM,CAAC,IAAI,CAAC,+BAA+B,EAAE,QAAQ,CAAC,CAAC;YACzD,CAAC;YACD,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,IAAI,YAAY,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC;YACzD,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;gBAAS,CAAC;YACT,IAAI,KAAK,CAAC,WAAW,IAAI,aAAa,EAAE,CAAC;gBACvC,KAAK,CAAC,WAAW,CAAC,mBAAmB,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;YAChE,CAAC;YAED,MAAM,YAAY,GAA4B,EAAE,CAAC;YACjD,IAAI,OAAO,EAAE,CAAC;gBACZ,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;YACrC,CAAC;YACD,IAAI,WAAW,EAAE,CAAC;gBAChB,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAC1E,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;YACvD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;gBACxB,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;oBAC5B,MAAM,CAAC,IAAI,CAAC,iCAAiC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;gBAC3D,CAAC;YACH,CAAC;YAED,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,CAAC;IACH,CAAC;IAEO,gBAAgB,CAAC,KAAkD;QACzE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACtD,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAE,CAAC;YACvB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,UAAU,IAAI,CAAC,EAAE,CAAC;gBAC/D,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;YAC5D,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;YAC9D,CAAC;YACD,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC9B,MAAM,IAAI,KAAK,CAAC,yBAAyB,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;YAC9D,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAE1B,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAC;YACvB,IAAI,IAAI,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;gBACjC,MAAM,IAAI,KAAK,CAAC,uCAAuC,QAAQ,SAAS,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;YAC7F,CAAC;QACH,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,mBAAmB;QAC/B,IAAI,CAAC,IAAI,CAAC,uBAAuB,EAAE,CAAC;YAClC,IAAI,CAAC,uBAAuB,GAAG,CAAC,KAAK,IAAI,EAAE;gBACzC,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,6BAA6B,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACjF,IAAI,CAAC;oBACH,OAAO,MAAM,EAAE,CAAC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;gBACrD,CAAC;gBAAC,OAAO,CAAM,EAAE,CAAC;oBAChB,IAAI,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;wBACtD,MAAM,IAAI,KAAK,CACb,oGAAoG,CACrG,CAAC;oBACJ,CAAC;oBACD,MAAM,CAAC,CAAC;gBACV,CAAC;YACH,CAAC,CAAC,EAAE,CAAC;QACP,CAAC;QACD,OAAO,MAAM,IAAI,CAAC,uBAAuB,CAAC;IAC5C,CAAC;IAEO,kBAAkB,CAAC,MAA0B;QACnD,IAAI,CAAC,MAAM;YAAE,OAAO,UAAU,CAAC;QAC/B,OAAO,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,CAAC;IACtD,CAAC;CACF"}
@@ -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,223 @@
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 getOrCreatePart = (partNo) => {
42
+ let p = partStates.get(partNo);
43
+ if (!p) {
44
+ p = { buf: new Uint8Array(partSizeBytes), ranges: [], uploaded: false };
45
+ partStates.set(partNo, p);
46
+ }
47
+ return p;
48
+ };
49
+ const addRange = (ranges, start, end) => {
50
+ if (end <= start)
51
+ return;
52
+ ranges.push({ start, end });
53
+ ranges.sort((a, b) => a.start - b.start);
54
+ // Merge in-place
55
+ let w = 0;
56
+ for (let i = 0; i < ranges.length; i++) {
57
+ const cur = ranges[i];
58
+ if (w === 0) {
59
+ ranges[w++] = cur;
60
+ continue;
61
+ }
62
+ const prev = ranges[w - 1];
63
+ if (cur.start <= prev.end) {
64
+ prev.end = Math.max(prev.end, cur.end);
65
+ }
66
+ else {
67
+ ranges[w++] = cur;
68
+ }
69
+ }
70
+ ranges.length = w;
71
+ };
72
+ const isRangeCovered = (ranges, expectedSize) => {
73
+ if (expectedSize <= 0)
74
+ return true;
75
+ if (ranges.length === 0)
76
+ return false;
77
+ // ranges are kept sorted and merged by addRange(), but there may still be gaps.
78
+ // We must ensure [0, expectedSize) is continuously covered.
79
+ let coveredEnd = ranges[0].start === 0 ? ranges[0].end : 0;
80
+ if (coveredEnd === 0)
81
+ return false;
82
+ for (let i = 1; i < ranges.length && coveredEnd < expectedSize; i++) {
83
+ const r = ranges[i];
84
+ if (r.start > coveredEnd) {
85
+ return false; // gap
86
+ }
87
+ coveredEnd = Math.max(coveredEnd, r.end);
88
+ }
89
+ return coveredEnd >= expectedSize;
90
+ };
91
+ const uploadPart = async (bodyParts, partNo) => {
92
+ const MAX_ATTEMPTS = 4;
93
+ for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
94
+ if (abortController.signal.aborted) {
95
+ throw new DOMException('Export aborted', 'AbortError');
96
+ }
97
+ const { url, headers } = await window.runnerRequestPartUrl(partNo);
98
+ const blob = new Blob(bodyParts, { type: 'application/octet-stream' });
99
+ try {
100
+ const response = await fetch(url, {
101
+ method: 'PUT',
102
+ body: blob,
103
+ headers: headers ?? {},
104
+ signal: abortController.signal,
105
+ });
106
+ if (!response.ok) {
107
+ if (attempt < MAX_ATTEMPTS && shouldRetryUpload(response.status)) {
108
+ const backoffMs = Math.min(8000, 250 * 2 ** (attempt - 1));
109
+ await sleep(backoffMs);
110
+ continue;
111
+ }
112
+ throw new Error(`UploadPart failed: HTTP ${response.status}`);
113
+ }
114
+ const etag = response.headers.get('etag') || response.headers.get('ETag');
115
+ if (!etag) {
116
+ throw new Error('UploadPart missing ETag header');
117
+ }
118
+ await window.runnerReportPartDone(partNo, etag);
119
+ return;
120
+ }
121
+ catch (e) {
122
+ if (e instanceof DOMException && e.name === 'AbortError') {
123
+ throw e;
124
+ }
125
+ if (attempt < MAX_ATTEMPTS) {
126
+ const backoffMs = Math.min(8000, 250 * 2 ** (attempt - 1));
127
+ await sleep(backoffMs);
128
+ continue;
129
+ }
130
+ throw e;
131
+ }
132
+ }
133
+ };
134
+ let flushChain = Promise.resolve();
135
+ let isFinalizing = false;
136
+ const scheduleTryUpload = (partNo, expectedSize) => {
137
+ flushChain = flushChain.then(async () => {
138
+ const p = partStates.get(partNo);
139
+ if (!p || p.uploaded)
140
+ return;
141
+ if (!isRangeCovered(p.ranges, expectedSize))
142
+ return;
143
+ // mp4-muxer may "seek+patch" early bytes (e.g. mdat size in the header).
144
+ // To avoid uploading stale bytes that later get patched, we delay uploading part 1
145
+ // until finalization (where expected sizes are known and no more patches should occur).
146
+ if (partNo === 1 && !isFinalizing)
147
+ return;
148
+ // Upload a stable snapshot of the part.
149
+ const body = p.buf.subarray(0, expectedSize);
150
+ await uploadPart([body], partNo);
151
+ p.uploaded = true;
152
+ // Free memory ASAP.
153
+ partStates.delete(partNo);
154
+ });
155
+ };
156
+ const onMuxData = (data, position) => {
157
+ totalBytes = Math.max(totalBytes, position + data.byteLength);
158
+ let remaining = data;
159
+ let pos = position;
160
+ while (remaining.byteLength > 0) {
161
+ const partNo = Math.floor(pos / partSizeBytes) + 1;
162
+ const offsetInPart = pos % partSizeBytes;
163
+ const bytesInThisPart = Math.min(partSizeBytes - offsetInPart, remaining.byteLength);
164
+ const p = getOrCreatePart(partNo);
165
+ p.buf.set(remaining.subarray(0, bytesInThisPart), offsetInPart);
166
+ addRange(p.ranges, offsetInPart, offsetInPart + bytesInThisPart);
167
+ // For any non-last part, it must be exactly partSizeBytes.
168
+ // We don't know which part is last yet, but attempting early uploads is safe:
169
+ // - If it's not fully covered, the guard will prevent upload.
170
+ // - If it ends up being the last part and smaller, we'll upload it in finalize below.
171
+ scheduleTryUpload(partNo, partSizeBytes);
172
+ remaining = remaining.subarray(bytesInThisPart);
173
+ pos += bytesInThisPart;
174
+ }
175
+ };
176
+ let lastProgressLogAt = 0;
177
+ meframe.events.on(MeframeEvent.ExportProgress, (evt) => {
178
+ void window.runnerReportProgress(evt);
179
+ const now = Date.now();
180
+ if (now - lastProgressLogAt >= 1000) {
181
+ lastProgressLogAt = now;
182
+ console.log('[meframe-runner] progress', evt);
183
+ }
184
+ });
185
+ meframe.events.on(MeframeEvent.ExportStart, (evt) => {
186
+ console.log('[meframe-runner] export:start', evt);
187
+ });
188
+ meframe.events.on(MeframeEvent.ExportComplete, (evt) => {
189
+ console.log('[meframe-runner] export:complete', evt);
190
+ });
191
+ console.log('[meframe-runner] export()...');
192
+ await meframe.export({
193
+ ...exportOptions,
194
+ exportMode: 'stream',
195
+ onMuxData,
196
+ // IMPORTANT:
197
+ // mp4-muxer@5.2.2 StreamTarget "chunked" mode buffers into fixed-size chunks and only emits
198
+ // when a whole chunk is filled (or on finalize). With our current muxing pattern (seek+patch),
199
+ // we've observed 0-byte output in some environments. Disable chunked mode and let the runner
200
+ // aggregate into multipart partSizeBytes instead.
201
+ muxChunked: false,
202
+ signal: abortController.signal,
203
+ });
204
+ if (totalBytes === 0) {
205
+ throw new Error(`[meframe-runner] stream mux produced 0 bytes. ` +
206
+ `This indicates mp4-muxer StreamTarget did not emit any data.`);
207
+ }
208
+ console.log('[meframe-runner] finalize: flushing parts...');
209
+ // Finalize uploads based on final totalBytes. The last part may be smaller than partSizeBytes.
210
+ const totalParts = Math.ceil(totalBytes / partSizeBytes);
211
+ isFinalizing = true;
212
+ for (let partNo = 1; partNo <= totalParts; partNo++) {
213
+ const expectedSize = partNo === totalParts ? totalBytes - (totalParts - 1) * partSizeBytes : partSizeBytes;
214
+ scheduleTryUpload(partNo, expectedSize);
215
+ }
216
+ await flushChain;
217
+ console.log('[meframe-runner] done', { totalBytes });
218
+ await window.runnerReportComplete(totalBytes);
219
+ }
220
+ main().catch(async (error) => {
221
+ await window.runnerReportError(error?.message ?? String(error));
222
+ });
223
+ //# sourceMappingURL=runner-browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner-browser.js","sourceRoot":"","sources":["../../src/runner/runner-browser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { Page } from 'puppeteer-core';
2
+ import type { ExportProgressEvent } from '../types.js';
3
+ export interface RunnerParams {
4
+ model: any;
5
+ exportOptions: any;
6
+ partSizeBytes: number;
7
+ uploadId: string;
8
+ key: string;
9
+ runnerModuleCode: string;
10
+ pageUrl?: string;
11
+ workerPath?: string;
12
+ }
13
+ export interface RunnerBridge {
14
+ requestPartUrl(partNumber: number): Promise<{
15
+ url: string;
16
+ headers?: Record<string, string>;
17
+ }>;
18
+ reportPartDone(partNumber: number, etag: string): Promise<void>;
19
+ reportProgress(event: ExportProgressEvent): Promise<void>;
20
+ reportError(message: string): Promise<void>;
21
+ reportComplete(totalBytes: number): Promise<void>;
22
+ onAbortRequested?: () => void;
23
+ }
24
+ export declare function runExportInPage(page: Page, bridge: RunnerBridge, params: RunnerParams): Promise<void>;
25
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/runner/runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,GAAG,CAAC;IACX,aAAa,EAAE,GAAG,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC,CAAC;IAC/F,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;CAC/B;AAED,wBAAsB,eAAe,CACnC,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,YAAY,GACnB,OAAO,CAAC,IAAI,CAAC,CAiEf"}
@@ -0,0 +1,51 @@
1
+ export async function runExportInPage(page, bridge, params) {
2
+ const { model, exportOptions, partSizeBytes, uploadId, key, // reserved for future use (e.g., logging)
3
+ runnerModuleCode, pageUrl, workerPath, } = params;
4
+ let doneResolve;
5
+ let doneReject;
6
+ const done = new Promise((resolve, reject) => {
7
+ doneResolve = resolve;
8
+ doneReject = reject;
9
+ });
10
+ // Bridge functions exposed to the browser context
11
+ await page.exposeFunction('runnerRequestPartUrl', bridge.requestPartUrl);
12
+ await page.exposeFunction('runnerReportPartDone', bridge.reportPartDone);
13
+ await page.exposeFunction('runnerReportProgress', bridge.reportProgress);
14
+ await page.exposeFunction('runnerReportError', async (message) => {
15
+ await bridge.reportError(message);
16
+ doneReject(new Error(message));
17
+ });
18
+ await page.exposeFunction('runnerReportComplete', async (totalBytes) => {
19
+ await bridge.reportComplete(totalBytes);
20
+ doneResolve();
21
+ });
22
+ const runnerConfig = {
23
+ model,
24
+ exportOptions,
25
+ partSizeBytes,
26
+ uploadId,
27
+ key,
28
+ workerPath,
29
+ };
30
+ if (pageUrl) {
31
+ // Ensure a trustworthy origin so Web APIs like WebCodecs are available.
32
+ // e.g. http://127.0.0.1 is considered a secure context.
33
+ await page.goto(pageUrl, { waitUntil: 'domcontentloaded' });
34
+ }
35
+ // Avoid module import inside page.evaluate(). Use a module script to bootstrap the runner.
36
+ await page.setContent(`<!doctype html>
37
+ <html>
38
+ <head>
39
+ <meta charset="utf-8" />
40
+ <script>
41
+ window.__MEFRAME_RUNNER_CONFIG__ = ${JSON.stringify(runnerConfig)};
42
+ </script>
43
+ <script type="module">
44
+ ${runnerModuleCode}
45
+ </script>
46
+ </head>
47
+ <body></body>
48
+ </html>`);
49
+ await done;
50
+ }
51
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/runner/runner.ts"],"names":[],"mappings":"AAuBA,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAU,EACV,MAAoB,EACpB,MAAoB;IAEpB,MAAM,EACJ,KAAK,EACL,aAAa,EACb,aAAa,EACb,QAAQ,EACR,GAAG,EAAE,0CAA0C;IAC/C,gBAAgB,EAChB,OAAO,EACP,UAAU,GACX,GAAG,MAAM,CAAC;IAEX,IAAI,WAAwB,CAAC;IAC7B,IAAI,UAAiC,CAAC;IACtC,MAAM,IAAI,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACjD,WAAW,GAAG,OAAO,CAAC;QACtB,UAAU,GAAG,MAAM,CAAC;IACtB,CAAC,CAAC,CAAC;IAEH,kDAAkD;IAClD,MAAM,IAAI,CAAC,cAAc,CAAC,sBAAsB,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC;IACzE,MAAM,IAAI,CAAC,cAAc,CAAC,sBAAsB,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC;IACzE,MAAM,IAAI,CAAC,cAAc,CAAC,sBAAsB,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC;IACzE,MAAM,IAAI,CAAC,cAAc,CAAC,mBAAmB,EAAE,KAAK,EAAE,OAAe,EAAE,EAAE;QACvE,MAAM,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAClC,UAAU,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IACH,MAAM,IAAI,CAAC,cAAc,CAAC,sBAAsB,EAAE,KAAK,EAAE,UAAkB,EAAE,EAAE;QAC7E,MAAM,MAAM,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;QACxC,WAAW,EAAE,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG;QACnB,KAAK;QACL,aAAa;QACb,aAAa;QACb,QAAQ;QACR,GAAG;QACH,UAAU;KACX,CAAC;IAEF,IAAI,OAAO,EAAE,CAAC;QACZ,wEAAwE;QACxE,wDAAwD;QACxD,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,2FAA2F;IAC3F,MAAM,IAAI,CAAC,UAAU,CACnB;;;;;2CAKuC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC;;;EAGrE,gBAAgB;;;;QAIV,CACL,CAAC;IAEF,MAAM,IAAI,CAAC;AACb,CAAC"}
package/dist/types.d.ts CHANGED
@@ -38,11 +38,11 @@ export interface ServerExporterOptions {
38
38
  runner?: {
39
39
  /**
40
40
  * Optional pre-bundled runner module code to inject into the page.
41
- * When provided, @meframe/server will not read dist/runner/runner.mjs from disk.
41
+ * When provided, @meframe/server will not read dist/runner-browser/runner.mjs from disk.
42
42
  */
43
43
  moduleCode?: string;
44
44
  };
45
- puppeteer?: {
45
+ browser?: {
46
46
  headless?: boolean;
47
47
  executablePath?: string;
48
48
  launchArgs?: string[];
@@ -51,7 +51,7 @@ export interface ServerExporterOptions {
51
51
  concurrency?: {
52
52
  maxJobs: number;
53
53
  };
54
- defaults?: {
54
+ upload?: {
55
55
  keyPrefix?: string;
56
56
  partSizeBytes?: number;
57
57
  contentType?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -60,8 +60,8 @@
60
60
  已实现:
61
61
 
62
62
  - **ServerExporter(Node)**
63
- - 通过 `puppeteer-core` 启动 Chromium,并为每个 job 创建独立 page
64
- - 以内联 `<script type="module">` 注入 runner 模块(默认从 `dist/runner/runner.mjs` 读取;也支持传入 `runner.moduleCode`)
63
+ - 通过浏览器自动化(当前内部使用 `puppeteer-core`)启动 Chromium,并为每个 job 创建独立 page
64
+ - 以内联 `<script type="module">` 注入 runner 模块(默认从 `dist/runner-browser/runner.mjs` 读取;也支持传入 `runner.moduleCode`)
65
65
  - 通过 `page.exposeFunction` 建立 runner ↔ Node 桥接:
66
66
  - runner 请求 part URL(Node 调 `store.getUploadPartUrl`)
67
67
  - runner 上报 part 完成(`etag` 收集)
@@ -101,10 +101,10 @@
101
101
  - 计算输出 `key`(调用方提供或生成)。
102
102
  - `store.createMultipartUpload` 获取 `uploadId`。
103
103
  - 获取并发 slot(限制同时运行的 job 数;海量并发应由上层队列与水平扩容解决)。
104
- - 启动 Puppeteer/Chromium
104
+ - 启动 Chromium(浏览器自动化):
105
105
  - 每个 job 使用独立 `userDataDir`,隔离 OPFS/锁/缓存,避免并发任务互相影响。
106
106
  - 打开 runner 页面(后续会在本包内提供 runner 静态资源或内联脚本)。
107
- - 通过 Puppeteer 建立 Node ↔ runner 的 RPC:
107
+ - 通过浏览器自动化建立 Node ↔ runner 的 RPC:
108
108
  - runner 请求 part 上传信息:Node 调 `store.getUploadPartUrl` 返回 `{ url, headers? }`
109
109
  - runner 上报已上传 part 的 `etag`:Node 记录 `parts[]`
110
110
  - runner 上报 progress/error/done:Node 转发给调用方,并驱动 complete/abort
@@ -113,7 +113,7 @@
113
113
 
114
114
  补充说明(runner 注入方式):
115
115
 
116
- - `@meframe/server` 默认会从 `dist/runner/runner.mjs` 读取 runner bundle 的模块代码,并以内联 `<script type="module">` 的方式注入到页面。
116
+ - `@meframe/server` 默认会从 `dist/runner-browser/runner.mjs` 读取 runner bundle 的模块代码,并以内联 `<script type="module">` 的方式注入到页面。
117
117
  - 如需避免磁盘依赖(例如在某些部署/打包环境),可通过 `ServerExporterOptions.runner.moduleCode` 直接注入 runner 模块代码字符串。
118
118
 
119
119
  #### 7.2 浏览器 runner 侧
@@ -1,131 +1,370 @@
1
- ## `@meframe/server` 集成指南(中文)
1
+ ## `@meframe/server` 集成指南
2
2
 
3
- 本文档面向“上层业务应用”的工程集成:如何在 Node 侧驱动 Chromium 执行 `@meframe/core` 导出,并将 MP4 以 multipart 方式上传到对象存储(如 S3)。
3
+ 本文档面向“上层业务应用”的工程集成:只看这一份文档,就能把:
4
+
5
+ - `@meframe/adapter-medeo`:把 Medeo `VideoDraft`(JSON)转换成 `@meframe/core` 的 `CompositionModelData`
6
+ - `@meframe/server`:在 Node 里驱动 Chromium 执行导出,并通过 multipart 上传得到最终 MP4
4
7
 
5
8
  适用读者:后端/平台工程同学(需要把导出能力集成进服务、队列、任务系统)。
6
9
 
7
- > 设计背景与约束请先阅读:
8
- >
9
- > - `packages/server/docs/ARCHITECTURE.md`
10
- >
11
- > (实现细节与注意事项已并入 ARCHITECTURE 与本文档,避免重复。)
10
+ ### 0. 你需要准备的 4 件东西(最重要)
12
11
 
13
- ### 1. 一句话说明:它是怎么“在服务端导出”的
12
+ 要把导出跑起来,你最终只需要把这 4 个东西传给代码:
14
13
 
15
- - Node 进程通过 `puppeteer-core` 启动一个真实 Chromium
16
- - Chromium 里运行 `@meframe/core` 的导出(WebCodecs / OPFS / Workers 等都在浏览器里完成)
17
- - mux 输出使用 `exportMode: 'stream'`,将 MP4 字节块按 `(data, position)` 推送出来
18
- - runner 在浏览器里把字节块聚合为 multipart 分片,并对每个分片做 `fetch(PUT)` 上传
19
- - Node 侧仅负责:
20
- - 生成/管理 multipart upload 生命周期(create / presign / complete / abort)
21
- - 记录每个 part 的 `ETag`
22
- - 转发进度、处理取消、清理资源
14
+ - **Chromium 可执行文件路径**:传给 `new ServerExporter({ browser: { executablePath } })`
15
+ - **可信 origin 的页面 URL**:传给 `exportToStore({ pageUrl })`
16
+ - **worker bundle base URL**:传给 `exportToStore({ workerPath })`(或使用 core 默认约定)
17
+ - **MultipartObjectStore 实现**:传给 `new ServerExporter({ store })`
23
18
 
24
- ### 2. 集成前置条件(必须满足)
19
+ 其他(draft 获取方式、存储 SDK、配置系统、队列/超时/重试)都由上层应用自行决定。
25
20
 
26
- #### 2.1 Chromium(必须)
21
+ ### 1. 安装依赖
27
22
 
28
- `@meframe/server` 依赖 `puppeteer-core`,**不自带浏览器**。生产环境需要你提供 Chromium/Chrome 可执行文件路径。
23
+ ```bash
24
+ pnpm add @meframe/server @meframe/adapter-medeo
25
+ ```
26
+
27
+ ```bash
28
+ npm i @meframe/server @meframe/adapter-medeo
29
+ ```
29
30
 
30
- 示例(本地):
31
+ 如果你要用 S3(或兼容 S3 的对象存储)做 multipart 上传,你还需要在你的上层应用里安装对应 SDK(例如 AWS SDK v3)。
31
32
 
32
- - `MEFRAME_CHROME_PATH=/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome`
33
+ ### 2. 前置条件(必须满足)
34
+
35
+ #### 2.1 Chromium(必须)
36
+
37
+ `@meframe/server` 依赖 `puppeteer-core`,**不自带浏览器**。生产环境需要你提供 Chromium/Chrome 可执行文件路径。
33
38
 
34
- #### 2.2 可信 origin(必须)
39
+ #### 2.2 `pageUrl`:可信 origin(必须)
35
40
 
36
- WebCodecs 需要 secure/trustworthy origin。`ServerExporter.exportToStore({ pageUrl })` 会先导航到一个可信页面,再注入 runner。
41
+ WebCodecs 等 API 需要 secure/trustworthy origin。`exportToStore({ pageUrl })` 会先导航到该页面,再注入 runner。
37
42
 
38
43
  推荐:
39
44
 
40
45
  - 本地调试:`http://127.0.0.1:<port>/`
41
- - 生产:你自己的 HTTPS 页面(建议是一个非常简单的静态页)
46
+ - 生产:你自己控制的 HTTPS 页面(建议极简静态页)
42
47
 
43
- 对应示例:
48
+ 你不需要在这个页面里写任何业务代码;它的职责只是提供一个可信 origin。
44
49
 
45
- - 本地:`packages/server/examples/local/local-server.mjs` 会启动 `http://127.0.0.1` 并提供 `/` 页面
46
-
47
- #### 2.3 Worker bundle 可访问(必须)
50
+ #### 2.3 `workerPath`:worker bundle 可访问(必须)
48
51
 
49
52
  `@meframe/core` 导出依赖 Worker。浏览器页面必须能加载到 worker 文件:
50
53
 
51
54
  - 你需要把 `@meframe/core/dist/workers` 托管到一个可访问路径(同源或跨域需 CORS)
52
- - 并在导出时传入 `workerPath`(或使用 core 的默认 workerPath 约定)
55
+ - 然后把这个 **base URL** 作为 `workerPath` 传入(例如 `https://stg.medeo.app/fe-assets/meframe-workers-2`)
53
56
 
54
- 对应示例:
57
+ > 核心原则:`CompositionModelData.resources[*].uri`、`workerPath` 指向的文件,都必须能在 Chromium 里直接 `fetch()`/加载到。
55
58
 
56
- - `packages/server/examples/local/export-to-local.mjs` / `packages/server/examples/s3/export-to-s3.mjs`
57
- - 都要求设置 `MEFRAME_WORKER_PATH`
59
+ ### 3. `@meframe/adapter-medeo`:Draft → `CompositionModelData`
58
60
 
59
- ### 3. 你需要实现什么:MultipartObjectStore(核心接口)
61
+ `@meframe/server` 不关心你的业务数据长什么样,它只吃 `CompositionModelData`。
60
62
 
61
- 服务端上传能力被抽象成一个“multipart store”接口(存储无关):
63
+ 如果你的输入是 Medeo `VideoDraft` JSON,那么推荐用 `@meframe/adapter-medeo`:
62
64
 
63
- - `createMultipartUpload({ key, contentType, metadata? }) -> { uploadId }`
64
- - `getUploadPartUrl({ key, uploadId, partNumber, expiresInSeconds? }) -> { url, headers? }`
65
- - `completeMultipartUpload({ key, uploadId, parts: [{ partNumber, etag }] })`
66
- - `abortMultipartUpload({ key, uploadId })`
65
+ - `resolveResources(draftRaw, { fetcher, getPublicUrl })`:把 draft 里的 mediaId / storageKey 变成 **浏览器可 fetch 的最终 URL**
66
+ - `toCompositionModel(draftRaw, { scene, resources, hasAudioByResourceId, ... })`:生成 `CompositionModelData`
67
67
 
68
- 关键约束(非常重要):
68
+ `toCompositionModel()` 内部会解析 draft 并在字段缺失时抛错;文档里不需要额外的解析/校验步骤。
69
69
 
70
- - runner 在浏览器内对 `url` 发起 `PUT`,并要求能从响应头读取到 `ETag`
71
- - 否则 runner 无法上报 `etag`,Node 无法 `completeMultipartUpload`
70
+ #### 3.1 你需要实现一个 `AssetFetcher`
72
71
 
73
- #### 3.1 S3 集成要点(CORS 必须配)
72
+ `resolveResources()` 需要一个 `fetcher`,用于把 main track 的 `origin_media_id`(mediaId)解析成:
74
73
 
75
- S3(或兼容 S3 的对象存储)需要 Bucket CORS 允许跨域 PUT,并且暴露 `ETag`:
74
+ ```ts
75
+ type Asset = {
76
+ id: string;
77
+ type: string; // e.g. "video_mp4" / "audio_mp3" / ...
78
+ storageKey: string;
79
+ extraProps?: { video?: { hasAudio?: boolean } };
80
+ };
81
+ ```
76
82
 
77
- - **AllowedMethods**: `PUT`
78
- - **AllowedOrigins**: 必须包含 runner 页面 origin(也就是 `pageUrl` 的 origin)
79
- - **AllowedHeaders**: `*`(或包含你需要的签名 headers)
80
- - **ExposeHeaders**: 必须包含 `ETag`
83
+ 最简单的实现方式:在你的上层应用里包一层“媒体元信息 API”(无论是 Medeo API 还是你自己的服务),实现 `fetchAssetById()`。
81
84
 
82
- 对应示例:
85
+ 下面是一个 **Medeo API 风格** 的 fetcher(仅示意,你可以按自己的鉴权/错误处理/重试策略改)。
83
86
 
84
- - `packages/server/examples/s3/s3-store.mjs`:使用 AWS SDK v3 实现 `MultipartObjectStore`
85
- - `packages/server/examples/local/local-server.mjs`:在本地 store 上方注释了 S3 映射关系与 CORS 要点
87
+ ```ts
88
+ import type { AssetFetcher } from '@meframe/adapter-medeo';
86
89
 
87
- ### 4. 业务侧典型调用方式(推荐结构)
90
+ const apiBase = 'https://api.stg.medeo.app/api/v2/medias';
91
+ const apiToken = undefined as string | undefined; // optional
88
92
 
89
- 推荐把“导出模型构建”和“上传实现”解耦:
93
+ const fetcher: AssetFetcher = {
94
+ async fetchAssetById(id: string, signal?: AbortSignal) {
95
+ const url = `${apiBase}/${encodeURIComponent(id)}`;
96
+ const res = await fetch(url, {
97
+ signal,
98
+ headers: apiToken ? { Authorization: `Bearer ${apiToken}` } : undefined,
99
+ });
100
+ if (!res.ok) {
101
+ throw new Error(`HTTP ${res.status} ${res.statusText} for ${url}`);
102
+ }
103
+ const json = await res.json();
104
+ const media = json?.body ?? json?.data ?? json;
105
+ if (!media || typeof media !== 'object') return null;
90
106
 
91
- - **上层应用负责**:把业务数据转换成 `CompositionModelData`(保证 `resource.uri` 是浏览器可 fetch 的最终 URL)
92
- - **`@meframe/server` 负责**:在浏览器里执行导出 + 上传(通过 `store` 注入)
107
+ const type = media.type ?? media.media_type ?? 'video';
108
+ const storageKey = media.storage_key;
109
+ const hasAudio = media.extra_props?.video?.has_audio;
110
+ if (!storageKey) return null;
93
111
 
94
- 对应示例:
112
+ return {
113
+ id: media.id ?? id,
114
+ type,
115
+ storageKey,
116
+ extraProps: { video: { hasAudio } },
117
+ };
118
+ },
119
+ };
120
+ ```
95
121
 
96
- - 本地闭环(可跑通):`packages/server/examples/local/export-to-local.mjs`
97
- - S3(参考实现):`packages/server/examples/s3/export-to-s3.mjs`
122
+ #### 3.2 你需要提供 `getPublicUrl(storageKey) => url`
98
123
 
99
- ### 5. 环境变量约定(示例级)
124
+ `resolveResources()` 需要把 `storageKey` 拼成 **浏览器可 fetch 的 URL**(通常是 CDN URL 或对象存储的公网 URL):
100
125
 
101
- 以下 env 变量在 examples 中使用,你可以按业务习惯重命名,但含义建议保持一致:
126
+ ```ts
127
+ import type { GetPublicUrl } from '@meframe/adapter-medeo';
102
128
 
103
- #### 5.1 通用(local / s3 都需要)
129
+ const publicBaseUrl = 'https://oss.stg.medeo.app';
104
130
 
105
- - `MEFRAME_CHROME_PATH` / `CHROME_BIN`:Chromium/Chrome 可执行文件路径
106
- - `MEFRAME_WORKER_PATH`:worker bundle base URL(例如 `https://.../meframe-workers-2`)
107
- - `MEFRAME_RUNNER_PAGE_URL`(S3 示例用):可信 origin 的页面 URL(生产建议 HTTPS)
131
+ const getPublicUrl: GetPublicUrl = (path?: string) => {
132
+ const p = String(path ?? '');
133
+ if (!p) return '';
134
+ return `${publicBaseUrl.replace(/\/$/, '')}/${p.replace(/^\//, '')}`;
135
+ };
136
+ ```
108
137
 
109
- #### 5.2 S3 相关(`examples/s3/s3-store.mjs`)
138
+ #### 3.3 生成 `CompositionModelData`
110
139
 
111
- - `S3_BUCKET`(必填)
112
- - `S3_KEY_PREFIX`(默认 `meframe/exports/`)
113
- - `AWS_REGION` / `AWS_DEFAULT_REGION`(默认 `us-east-1`)
114
- - 可选(兼容 S3 的 endpoint):
115
- - `S3_ENDPOINT`
116
- - `S3_FORCE_PATH_STYLE=1`
140
+ ```ts
141
+ import { resolveResources, toCompositionModel } from '@meframe/adapter-medeo';
117
142
 
118
- AWS 凭证通过 AWS SDK 默认链路加载(env / shared config / IAM role 等)。
143
+ const draftRaw = /* 你的 VideoDraft JSON */;
119
144
 
120
- #### 5.3 Medeo 资源解析(示例用)
145
+ const { resources, hasAudioByResourceId } = await resolveResources(draftRaw, {
146
+ fetcher,
147
+ getPublicUrl,
148
+ });
121
149
 
122
- examples 使用 `@meframe/adapter-medeo` 来把 Medeo draft 转换为 `CompositionModelData`,并通过 API 获取 `storage_key` 等元信息:
150
+ const model = toCompositionModel(draftRaw, {
151
+ scene: 'export',
152
+ resources,
153
+ hasAudioByResourceId,
154
+ });
155
+ ```
123
156
 
124
- - `MEDEO_API_BASE`(默认 `https://api.stg.medeo.app/api/v2/medias`)
125
- - `MEDEO_API_TOKEN`(可选)
126
- - `MEDEO_PUBLIC_BASE_URL`(示例里必填,用于把 `storage_key` 拼成可访问 URL)
157
+ ### 4. 实现 `MultipartObjectStore`(Node 侧上传抽象)
127
158
 
128
- > 生产环境通常不需要依赖 Medeo API:你的上层服务应直接提供可 fetch 的最终 URL(或你的 CDN URL)。
159
+ `@meframe/server` 不依赖任何云厂商 SDK。你需要在上层应用里实现下面这个接口,并注入给 `ServerExporter`:
160
+
161
+ ```ts
162
+ export interface MultipartObjectStore {
163
+ createMultipartUpload(input: {
164
+ key: string;
165
+ contentType: string;
166
+ metadata?: Record<string, string>;
167
+ }): Promise<{ uploadId: string }>;
168
+
169
+ getUploadPartUrl(input: {
170
+ key: string;
171
+ uploadId: string;
172
+ partNumber: number;
173
+ expiresInSeconds?: number;
174
+ }): Promise<{ url: string; headers?: Record<string, string> }>;
175
+
176
+ completeMultipartUpload(input: {
177
+ key: string;
178
+ uploadId: string;
179
+ parts: Array<{ partNumber: number; etag: string }>;
180
+ }): Promise<void>;
181
+
182
+ abortMultipartUpload(input: { key: string; uploadId: string }): Promise<void>;
183
+ }
184
+ ```
185
+
186
+ 关键约束(非常重要):
187
+
188
+ - runner 在浏览器内对 `url` 发起 `PUT` 上传,并要求能从响应头读取到 `ETag`
189
+ - 否则 runner 无法上报 `etag`,Node 无法 `completeMultipartUpload`
190
+
191
+ #### 4.1 S3(或兼容 S3)需要的 CORS(必配)
192
+
193
+ 如果 runner 页面与对象存储是跨域关系,Bucket CORS 至少要满足:
194
+
195
+ - **AllowedMethods**: `PUT`
196
+ - **AllowedOrigins**: 必须包含 runner 页面 origin(也就是 `pageUrl` 的 origin)
197
+ - **AllowedHeaders**: `*`(或包含你需要的签名 headers)
198
+ - **ExposeHeaders**: 必须包含 `ETag`
199
+
200
+ S3 侧你需要实现的核心动作是 multipart upload 生命周期(create / presign upload part / complete / abort)。
201
+
202
+ 它与 `MultipartObjectStore` 的映射关系如下:
203
+
204
+ - `createMultipartUpload` → `CreateMultipartUploadCommand`
205
+ - `getUploadPartUrl` → `UploadPartCommand` + `@aws-sdk/s3-request-presigner` 的 `getSignedUrl()`(生成给浏览器 `fetch(PUT)` 用的 presigned URL)
206
+ - `completeMultipartUpload` → `CompleteMultipartUploadCommand`(注意 parts 顺序与 ETag 原样透传)
207
+ - `abortMultipartUpload` → `AbortMultipartUploadCommand`
208
+
209
+ 如果你要对照官方文档(了解概念与约束),可以参考:
210
+
211
+ - **Multipart Upload 概览**:[Uploading and copying objects using multipart upload](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html)
212
+ - **CORS 配置**:[Cross-origin resource sharing (CORS)](https://docs.aws.amazon.com/AmazonS3/latest/userguide/enabling-cors-examples.html)
213
+ - 记得 `ExposeHeaders` 里包含 `ETag`,否则浏览器拿不到 `ETag`,无法 `completeMultipartUpload`
214
+ - **预签名 URL(给浏览器 PUT UploadPart 用)**:[Using presigned URLs to upload a file](https://docs.aws.amazon.com/AmazonS3/latest/userguide/PresignedUrlUploadObject.html)
215
+
216
+ > 备注:runner 的行为是对 `getUploadPartUrl()` 返回的 URL 直接 `fetch(PUT)` 上传分片,并从响应头读取 `ETag`;所以你的 bucket CORS 必须允许跨域 PUT 且暴露 `ETag`。
217
+
218
+ 下面给出一个 **AWS SDK v3** 的参考实现(可直接改成你自己的 `store` 实现):
219
+
220
+ ```js
221
+ import { S3Client } from '@aws-sdk/client-s3';
222
+ import {
223
+ AbortMultipartUploadCommand,
224
+ CompleteMultipartUploadCommand,
225
+ CreateMultipartUploadCommand,
226
+ UploadPartCommand,
227
+ } from '@aws-sdk/client-s3';
228
+ import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
229
+
230
+ export function createS3MultipartObjectStore(input) {
231
+ const {
232
+ bucket,
233
+ region = 'us-east-1',
234
+ keyPrefix = 'meframe/exports/',
235
+ endpoint,
236
+ forcePathStyle = false,
237
+ } = input;
238
+
239
+ if (!bucket) throw new Error('Missing bucket');
240
+
241
+ const s3 = new S3Client({
242
+ region,
243
+ ...(endpoint ? { endpoint } : {}),
244
+ ...(forcePathStyle ? { forcePathStyle: true } : {}),
245
+ });
246
+
247
+ const store = {
248
+ async createMultipartUpload({ key, contentType, metadata }) {
249
+ const out = await s3.send(
250
+ new CreateMultipartUploadCommand({
251
+ Bucket: bucket,
252
+ Key: key,
253
+ ContentType: contentType,
254
+ Metadata: metadata,
255
+ })
256
+ );
257
+ if (!out.UploadId) throw new Error('S3 CreateMultipartUpload: missing UploadId');
258
+ return { uploadId: out.UploadId };
259
+ },
260
+
261
+ async getUploadPartUrl({ key, uploadId, partNumber, expiresInSeconds }) {
262
+ const cmd = new UploadPartCommand({
263
+ Bucket: bucket,
264
+ Key: key,
265
+ UploadId: uploadId,
266
+ PartNumber: partNumber,
267
+ });
268
+ const url = await getSignedUrl(s3, cmd, { expiresIn: expiresInSeconds ?? 3600 });
269
+ return { url };
270
+ },
271
+
272
+ async completeMultipartUpload({ key, uploadId, parts }) {
273
+ await s3.send(
274
+ new CompleteMultipartUploadCommand({
275
+ Bucket: bucket,
276
+ Key: key,
277
+ UploadId: uploadId,
278
+ MultipartUpload: {
279
+ Parts: parts.map((p) => ({ PartNumber: p.partNumber, ETag: p.etag })),
280
+ },
281
+ })
282
+ );
283
+ },
284
+
285
+ async abortMultipartUpload({ key, uploadId }) {
286
+ await s3.send(
287
+ new AbortMultipartUploadCommand({
288
+ Bucket: bucket,
289
+ Key: key,
290
+ UploadId: uploadId,
291
+ })
292
+ );
293
+ },
294
+ };
295
+
296
+ return { store, keyPrefix };
297
+ }
298
+ ```
299
+
300
+ ### 5. 端到端:把两者串起来(可直接抄)
301
+
302
+ 下面是一段“你可以放进自己的服务里”的最小串联代码(省略了队列/重试/监控等工程化部分):
303
+
304
+ ```ts
305
+ import { ServerExporter } from '@meframe/server';
306
+ import type { MultipartObjectStore } from '@meframe/server';
307
+
308
+ import { resolveResources, toCompositionModel } from '@meframe/adapter-medeo';
309
+
310
+ // 示例值(可按需替换)
311
+ const chromeExecutablePath = '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome';
312
+ const workerPath = 'https://stg.medeo.app/fe-assets/meframe-workers-2';
313
+
314
+ export async function exportMedeoDraftToMp4(input: {
315
+ draftRaw: any;
316
+ pageUrl: string;
317
+ store: MultipartObjectStore;
318
+ outputKey: string;
319
+ abortSignal?: AbortSignal;
320
+ }) {
321
+ const { draftRaw, pageUrl, store, outputKey, abortSignal } = input;
322
+
323
+ const { resources, hasAudioByResourceId } = await resolveResources(draftRaw, {
324
+ fetcher,
325
+ getPublicUrl,
326
+ abortSignal,
327
+ });
328
+
329
+ const model = toCompositionModel(draftRaw, {
330
+ scene: 'export',
331
+ resources,
332
+ hasAudioByResourceId,
333
+ });
334
+
335
+ const exporter = new ServerExporter({
336
+ store,
337
+ browser: {
338
+ executablePath: chromeExecutablePath,
339
+ headless: true,
340
+ launchArgs: ['--no-sandbox'],
341
+ },
342
+ upload: {
343
+ keyPrefix: 'exports/',
344
+ // 对 S3 来说,除最后一个 part 外,最小 5MiB
345
+ partSizeBytes: 16 * 1024 * 1024,
346
+ contentType: 'video/mp4',
347
+ },
348
+ onProgress: (evt) => {
349
+ // evt: { jobId, progress, stage, timeUs? }
350
+ // 这里建议你把进度转发到任务系统/日志/指标
351
+ // console.log('progress', evt);
352
+ },
353
+ logger: console,
354
+ });
355
+
356
+ const result = await exporter.exportToStore({
357
+ model,
358
+ exportOptions: { format: 'mp4' },
359
+ pageUrl,
360
+ workerPath,
361
+ key: outputKey,
362
+ abortSignal,
363
+ });
364
+
365
+ return result; // { key }
366
+ }
367
+ ```
129
368
 
130
369
  ### 6. 取消与超时(建议)
131
370
 
@@ -151,7 +390,7 @@ examples 使用 `@meframe/adapter-medeo` 来把 Medeo draft 转换为 `Compositi
151
390
 
152
391
  确保:
153
392
 
154
- - `MEFRAME_WORKER_PATH` 指向的地址能在 Chromium 内打开(网络、DNS、证书)
393
+ - `workerPath` 指向的地址能在 Chromium 内打开(网络、DNS、证书)
155
394
  - 跨域时 CORS 允许加载
156
395
 
157
396
  #### 7.3 上传成功但最终 MP4 播放失败/损坏
@@ -161,12 +400,3 @@ multipart 上传必须满足:
161
400
  - 每个 part 都完整、连续覆盖;runner 已做 range 覆盖校验
162
401
  - `ETag` 必须正确回传给 Node 并用于 complete
163
402
  - 对象存储端的 `CompleteMultipartUpload` parts 顺序必须正确(按 partNumber)
164
-
165
- ### 8. 示例索引
166
-
167
- - `packages/server/examples/local/`
168
- - `export-to-local.mjs`:本地闭环(本地 HTTP store + 生成 out.mp4)
169
- - `local-server.mjs`:本地 multipart store + S3 映射注释
170
- - `packages/server/examples/s3/`
171
- - `export-to-s3.mjs`:导出并上传到 S3(参考)
172
- - `s3-store.mjs`:S3 MultipartObjectStore(AWS SDK v3)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meframe/server",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Server-side exporter for @meframe/core (browser-driven, multipart upload via injected store)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,3 +0,0 @@
1
- import type { BrowserLauncher } from './types.js';
2
- export declare const puppeteerCoreLauncher: BrowserLauncher;
3
- //# sourceMappingURL=puppeteer-core-launcher.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"puppeteer-core-launcher.d.ts","sourceRoot":"","sources":["../../src/browser/puppeteer-core-launcher.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAqC,MAAM,YAAY,CAAC;AAErF,eAAO,MAAM,qBAAqB,EAAE,eASnC,CAAC"}
@@ -1,12 +0,0 @@
1
- import { launch } from 'puppeteer-core';
2
- export const puppeteerCoreLauncher = {
3
- async launch(options) {
4
- return await launch({
5
- headless: options.headless ?? true,
6
- executablePath: options.executablePath,
7
- args: options.args,
8
- userDataDir: options.userDataDir,
9
- });
10
- },
11
- };
12
- //# sourceMappingURL=puppeteer-core-launcher.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"puppeteer-core-launcher.js","sourceRoot":"","sources":["../../src/browser/puppeteer-core-launcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAGxC,MAAM,CAAC,MAAM,qBAAqB,GAAoB;IACpD,KAAK,CAAC,MAAM,CAAC,OAA6B;QACxC,OAAO,MAAM,MAAM,CAAC;YAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,IAAI;YAClC,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,WAAW,EAAE,OAAO,CAAC,WAAW;SACjC,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
@@ -1,21 +0,0 @@
1
- export interface PageLike {
2
- setContent(html: string): Promise<unknown>;
3
- goto(url: string, options?: any): Promise<unknown>;
4
- exposeFunction(name: string, fn: (...args: any[]) => any): Promise<unknown>;
5
- evaluate(fn: (...args: any[]) => any, ...args: any[]): Promise<unknown>;
6
- on(event: string, handler: (...args: any[]) => void): void;
7
- }
8
- export interface BrowserLike {
9
- newPage(): Promise<PageLike>;
10
- close(): Promise<void>;
11
- }
12
- export interface BrowserLaunchOptions {
13
- headless?: boolean;
14
- executablePath?: string;
15
- args?: string[];
16
- userDataDir?: string;
17
- }
18
- export interface BrowserLauncher {
19
- launch(options: BrowserLaunchOptions): Promise<BrowserLike>;
20
- }
21
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/browser/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3C,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACnD,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5E,QAAQ,CAAC,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACxE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,IAAI,CAAC;CAC5D;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC7B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CAC7D"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/browser/types.ts"],"names":[],"mappings":""}
@@ -1,37 +0,0 @@
1
- import type { MultipartObjectStore } from '../../dist/types';
2
- export declare class MockMultipartObjectStore implements MultipartObjectStore {
3
- private uploads;
4
- createMultipartUpload(input: {
5
- key: string;
6
- contentType: string;
7
- metadata?: Record<string, string> | undefined;
8
- }): Promise<{
9
- uploadId: string;
10
- }>;
11
- getUploadPartUrl(input: {
12
- key: string;
13
- uploadId: string;
14
- partNumber: number;
15
- expiresInSeconds?: number | undefined;
16
- }): Promise<{
17
- url: string;
18
- headers?: Record<string, string> | undefined;
19
- }>;
20
- completeMultipartUpload(input: {
21
- key: string;
22
- uploadId: string;
23
- parts: {
24
- partNumber: number;
25
- etag: string;
26
- }[];
27
- }): Promise<void>;
28
- abortMultipartUpload(input: {
29
- key: string;
30
- uploadId: string;
31
- }): Promise<void>;
32
- getCompletedParts(uploadId: string): Array<{
33
- partNumber: number;
34
- etag: string;
35
- }> | undefined;
36
- }
37
- //# sourceMappingURL=MockMultipartObjectStore.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"MockMultipartObjectStore.d.ts","sourceRoot":"","sources":["../../src/mock/MockMultipartObjectStore.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AASrD,qBAAa,wBAAyB,YAAW,oBAAoB;IACnE,OAAO,CAAC,OAAO,CAAmC;IAE5C,qBAAqB,CAAC,KAAK,EAAE;QACjC,GAAG,EAAE,MAAM,CAAC;QACZ,WAAW,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;KAC/C,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAW3B,gBAAgB,CAAC,KAAK,EAAE;QAC5B,GAAG,EAAE,MAAM,CAAC;QACZ,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;KACvC,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAA;KAAE,CAAC;IAQpE,uBAAuB,CAAC,KAAK,EAAE;QACnC,GAAG,EAAE,MAAM,CAAC;QACZ,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE;YAAE,UAAU,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;KAC/C,GAAG,OAAO,CAAC,IAAI,CAAC;IAMX,oBAAoB,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAInF,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,SAAS;CAG7F"}
@@ -1,34 +0,0 @@
1
- import crypto from 'node:crypto';
2
- export class MockMultipartObjectStore {
3
- uploads = new Map();
4
- async createMultipartUpload(input) {
5
- const uploadId = crypto.randomUUID();
6
- this.uploads.set(uploadId, {
7
- key: input.key,
8
- contentType: input.contentType,
9
- metadata: input.metadata,
10
- parts: [],
11
- });
12
- return { uploadId };
13
- }
14
- async getUploadPartUrl(input) {
15
- // For tests we return a pseudo URL; uploading is simulated by runner mocks.
16
- if (!this.uploads.has(input.uploadId)) {
17
- throw new Error('Unknown uploadId');
18
- }
19
- return { url: `mock://${input.key}/part/${input.partNumber}` };
20
- }
21
- async completeMultipartUpload(input) {
22
- const record = this.uploads.get(input.uploadId);
23
- if (!record)
24
- throw new Error('Unknown uploadId');
25
- record.parts = input.parts.slice();
26
- }
27
- async abortMultipartUpload(input) {
28
- this.uploads.delete(input.uploadId);
29
- }
30
- getCompletedParts(uploadId) {
31
- return this.uploads.get(uploadId)?.parts;
32
- }
33
- }
34
- //# sourceMappingURL=MockMultipartObjectStore.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"MockMultipartObjectStore.js","sourceRoot":"","sources":["../../src/mock/MockMultipartObjectStore.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAUjC,MAAM,OAAO,wBAAwB;IAC3B,OAAO,GAAG,IAAI,GAAG,EAAwB,CAAC;IAElD,KAAK,CAAC,qBAAqB,CAAC,KAI3B;QACC,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;QACrC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE;YACzB,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,KAAK,EAAE,EAAE;SACV,CAAC,CAAC;QACH,OAAO,EAAE,QAAQ,EAAE,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,KAKtB;QACC,4EAA4E;QAC5E,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACtC,CAAC;QACD,OAAO,EAAE,GAAG,EAAE,UAAU,KAAK,CAAC,GAAG,SAAS,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC;IACjE,CAAC;IAED,KAAK,CAAC,uBAAuB,CAAC,KAI7B;QACC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAChD,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACjD,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,KAAwC;QACjE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACtC,CAAC;IAED,iBAAiB,CAAC,QAAgB;QAChC,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC;IAC3C,CAAC;CACF"}
File without changes