vargai 0.4.0-alpha77 → 0.4.0-alpha78
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/package.json +1 -1
- package/src/react/renderers/utils.ts +23 -5
- package/src/react/resolve.ts +6 -0
package/package.json
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { existsSync, statSync } from "node:fs";
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
|
+
import { ResolvedElement } from "../resolved-element";
|
|
3
4
|
import type { VargElement, VargNode } from "../types";
|
|
4
5
|
|
|
5
6
|
export function resolvePath(path: string): string {
|
|
@@ -84,11 +85,22 @@ function serializeValue(v: unknown): string {
|
|
|
84
85
|
}
|
|
85
86
|
return v;
|
|
86
87
|
}
|
|
88
|
+
// Never put raw binary data in cache keys — use semantic identity instead.
|
|
89
|
+
// Audio segments can be 48-110KB; base64-encoding them would exceed
|
|
90
|
+
// Upstash Redis' 32KB key size limit.
|
|
87
91
|
if (v instanceof Uint8Array) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
+
return `uint8:${v.byteLength}`;
|
|
93
|
+
}
|
|
94
|
+
// ResolvedElement (e.g. a speech segment used as Video audio input):
|
|
95
|
+
// serialize by content identity (type + text + duration), not binary data.
|
|
96
|
+
if (v instanceof ResolvedElement) {
|
|
97
|
+
const parts = [v.type];
|
|
98
|
+
for (const child of v.children) {
|
|
99
|
+
if (typeof child === "string") parts.push(child);
|
|
100
|
+
}
|
|
101
|
+
if (v.meta.duration) parts.push(String(v.meta.duration));
|
|
102
|
+
if (v.meta.file?.url) parts.push(v.meta.file.url);
|
|
103
|
+
return `resolved(${parts.join(",")})`;
|
|
92
104
|
}
|
|
93
105
|
if (isVargElement(v)) {
|
|
94
106
|
return `element:${computeCacheKey(v).join(":")}`;
|
|
@@ -97,6 +109,12 @@ function serializeValue(v: unknown): string {
|
|
|
97
109
|
return `[${v.map(serializeValue).join(",")}]`;
|
|
98
110
|
}
|
|
99
111
|
if (v && typeof v === "object") {
|
|
112
|
+
// Skip File-like objects with binary data — use URL if available
|
|
113
|
+
if ("_data" in v && "_mediaType" in v) {
|
|
114
|
+
const url = (v as { _url?: string | null })._url;
|
|
115
|
+
const mediaType = (v as { _mediaType: string })._mediaType;
|
|
116
|
+
return url ? `file(${url})` : `file(${mediaType})`;
|
|
117
|
+
}
|
|
100
118
|
const entries = Object.entries(v)
|
|
101
119
|
.map(([key, val]) => `${key}:${serializeValue(val)}`)
|
|
102
120
|
.join(",");
|
|
@@ -134,7 +152,7 @@ export function computeCacheKey(element: VargElement): CacheKeyPart[] {
|
|
|
134
152
|
} else if (v === null || v === undefined) {
|
|
135
153
|
key.push(k, v);
|
|
136
154
|
} else if (v instanceof Uint8Array) {
|
|
137
|
-
key.push(k, `uint8:${v.byteLength}
|
|
155
|
+
key.push(k, `uint8:${v.byteLength}`);
|
|
138
156
|
} else if (isVargElement(v)) {
|
|
139
157
|
key.push(k, ...computeCacheKey(v));
|
|
140
158
|
} else if (Array.isArray(v) || typeof v === "object") {
|
package/src/react/resolve.ts
CHANGED
|
@@ -187,6 +187,12 @@ async function sliceSegments(
|
|
|
187
187
|
descriptors.map(async (desc) => {
|
|
188
188
|
const bytes = await sliceAudio(fullFile, desc.start, desc.end);
|
|
189
189
|
const segmentFile = File.fromBuffer(bytes, "audio/mpeg");
|
|
190
|
+
// Upload segment to storage so downstream cache keys use the URL
|
|
191
|
+
// instead of serializing raw audio bytes (which can exceed Redis key limits).
|
|
192
|
+
const ctx = getResolveContext();
|
|
193
|
+
if (ctx?.storage) {
|
|
194
|
+
await segmentFile.upload(ctx.storage);
|
|
195
|
+
}
|
|
190
196
|
|
|
191
197
|
// Rebase word timings relative to the segment's sliced audio (t=0)
|
|
192
198
|
const segmentWords = allWords
|