storyforge 0.7.4 → 0.7.5
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.
|
@@ -6759,13 +6759,36 @@ var BridgePoller = class {
|
|
|
6759
6759
|
onProgress,
|
|
6760
6760
|
signal: cancelController.signal
|
|
6761
6761
|
});
|
|
6762
|
+
const specByChunk = new Map(payload.specs.map((s) => [s.chunkId, s]));
|
|
6763
|
+
const uploadOutcomes = [];
|
|
6764
|
+
for (const r of result.results) {
|
|
6765
|
+
if (!r.ok || !r.outputPath) continue;
|
|
6766
|
+
const spec = specByChunk.get(r.chunkId);
|
|
6767
|
+
if (!spec) continue;
|
|
6768
|
+
const upload = await this.uploadClipToStorj(jobId, payload.projectId, spec, r);
|
|
6769
|
+
uploadOutcomes.push({ chunkId: r.chunkId, ...upload });
|
|
6770
|
+
void this.postRenderProgress(jobId, payload.projectId, {
|
|
6771
|
+
chunkId: r.chunkId,
|
|
6772
|
+
phase: upload.ok ? "done" : "error",
|
|
6773
|
+
percent: upload.ok ? 100 : 95,
|
|
6774
|
+
elapsedMs: r.renderTimeMs,
|
|
6775
|
+
resolvedEngine: r.engine,
|
|
6776
|
+
storjKey: upload.storjKey,
|
|
6777
|
+
outputPath: r.outputPath,
|
|
6778
|
+
error: upload.ok ? void 0 : `upload failed: ${upload.error ?? "unknown"}`,
|
|
6779
|
+
ts: (/* @__PURE__ */ new Date()).toISOString()
|
|
6780
|
+
});
|
|
6781
|
+
}
|
|
6762
6782
|
const okCount = result.results.filter((r) => r.ok).length;
|
|
6783
|
+
const uploadedCount = uploadOutcomes.filter((u) => u.ok).length;
|
|
6763
6784
|
const summary = {
|
|
6764
6785
|
kind: "render-clips",
|
|
6765
|
-
ok: result.ok,
|
|
6786
|
+
ok: result.ok && uploadedCount === okCount,
|
|
6766
6787
|
total: result.results.length,
|
|
6767
6788
|
succeeded: okCount,
|
|
6768
6789
|
failed: result.results.length - okCount,
|
|
6790
|
+
uploaded: uploadedCount,
|
|
6791
|
+
uploadFailed: uploadOutcomes.filter((u) => !u.ok).length,
|
|
6769
6792
|
totalRenderTimeMs: result.totalRenderTimeMs,
|
|
6770
6793
|
observedPeakConcurrency: result.observedPeakConcurrency
|
|
6771
6794
|
};
|
|
@@ -6776,6 +6799,48 @@ var BridgePoller = class {
|
|
|
6776
6799
|
this.renderCancelControllers.delete(jobId);
|
|
6777
6800
|
}
|
|
6778
6801
|
}
|
|
6802
|
+
/**
|
|
6803
|
+
* POST a rendered clip to /api/cli-bridge/upload-clip as multipart
|
|
6804
|
+
* form data. The endpoint uploads the binary to Storj, inserts a
|
|
6805
|
+
* `clips` table row, and returns the storj_key. Best-effort — a
|
|
6806
|
+
* failed upload is recorded as a warning and the chunk's progress
|
|
6807
|
+
* event reports phase='error' but doesn't take down the whole batch.
|
|
6808
|
+
*/
|
|
6809
|
+
async uploadClipToStorj(bridgeJobId, projectId, spec, result) {
|
|
6810
|
+
try {
|
|
6811
|
+
const fs11 = await import("fs/promises");
|
|
6812
|
+
const stat = await fs11.stat(result.outputPath);
|
|
6813
|
+
if (!stat.isFile() || stat.size === 0) {
|
|
6814
|
+
return { ok: false, error: `local clip empty or missing at ${result.outputPath}` };
|
|
6815
|
+
}
|
|
6816
|
+
const buf = await fs11.readFile(result.outputPath);
|
|
6817
|
+
const durationFrames = Math.max(1, Math.round(result.durationSec * 30));
|
|
6818
|
+
const form = new FormData();
|
|
6819
|
+
form.append("bridgeJobId", bridgeJobId);
|
|
6820
|
+
form.append("chunkId", result.chunkId);
|
|
6821
|
+
form.append("engine", result.engine);
|
|
6822
|
+
form.append("aspect", spec.aspect);
|
|
6823
|
+
form.append("durationSec", String(result.durationSec));
|
|
6824
|
+
form.append("durationFrames", String(durationFrames));
|
|
6825
|
+
form.append("file", new Blob([new Uint8Array(buf)], { type: "video/mp4" }), `${result.chunkId}.mp4`);
|
|
6826
|
+
const resp = await fetch(`${this.baseUrl}/api/cli-bridge/upload-clip`, {
|
|
6827
|
+
method: "POST",
|
|
6828
|
+
headers: { Authorization: `Bearer ${this.token}` },
|
|
6829
|
+
body: form,
|
|
6830
|
+
signal: AbortSignal.timeout(5 * 6e4)
|
|
6831
|
+
});
|
|
6832
|
+
const text = await resp.text().catch(() => "");
|
|
6833
|
+
if (!resp.ok) {
|
|
6834
|
+
return { ok: false, error: `HTTP ${resp.status}: ${text.slice(0, 300)}` };
|
|
6835
|
+
}
|
|
6836
|
+
const parsed = text ? JSON.parse(text) : {};
|
|
6837
|
+
log.info(`[bridge] uploaded ${result.chunkId.slice(0, 8)} -> ${parsed.storjKey ?? "(no key)"}`);
|
|
6838
|
+
void projectId;
|
|
6839
|
+
return { ok: true, storjKey: parsed.storjKey };
|
|
6840
|
+
} catch (err) {
|
|
6841
|
+
return { ok: false, error: err.message };
|
|
6842
|
+
}
|
|
6843
|
+
}
|
|
6779
6844
|
/** POST a single RenderProgress event to /api/render-progress. */
|
|
6780
6845
|
async postRenderProgress(bridgeJobId, projectId, event) {
|
|
6781
6846
|
try {
|
package/dist/index.js
CHANGED
|
@@ -1615,7 +1615,7 @@ Return ONLY the complete updated TSX. No markdown fences, no explanation.`;
|
|
|
1615
1615
|
return "0.0.0";
|
|
1616
1616
|
})();
|
|
1617
1617
|
void (async () => {
|
|
1618
|
-
const { BridgePoller } = await import("./bridge-poller-
|
|
1618
|
+
const { BridgePoller } = await import("./bridge-poller-C2SMBUQX.js");
|
|
1619
1619
|
const poller = new BridgePoller({ baseUrl: bridgeUrl, token: bridgeToken, clientVersion: `storyforge ${pkgVersion}` });
|
|
1620
1620
|
poller.start();
|
|
1621
1621
|
})();
|
|
@@ -1992,7 +1992,7 @@ async function installRenderersCommand(opts = {}) {
|
|
|
1992
1992
|
}
|
|
1993
1993
|
|
|
1994
1994
|
// src/index.ts
|
|
1995
|
-
var VERSION = "0.7.
|
|
1995
|
+
var VERSION = "0.7.5";
|
|
1996
1996
|
var HELP = `
|
|
1997
1997
|
storyforge \u2014 local bridge for the Forge video production web app
|
|
1998
1998
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "storyforge",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.5",
|
|
4
4
|
"description": "StoryForge — local bridge for the Forge video production web app. Parallel clip-render orchestrator (Remotion 4 + Manim + HyperFrames + ffmpeg) + final video stitcher + dependency doctor.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|