@mengine/medeo-client 1.4.1-alpha.3 → 1.4.1-alpha.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.
- package/README.md +1 -1
- package/dist/{document-B1FlNEzF.js → document-BSAUud6c.js} +65 -50
- package/dist/{index-Bs60N9Hl.d.ts → index-B31KeDzA.d.ts} +10 -2
- package/dist/index.d.ts +7 -7
- package/dist/index.js +25 -24
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -80,7 +80,7 @@ with `assembleCaptionContent` or `assemblePhoneticScriptContent`. Broken composi
|
|
|
80
80
|
fails explicitly. Same-name fields from different bases are rejected even for equal values and even if the variant declares that field. After base fields are unambiguous, explicit own fields may override them without mutating the bases. Recorded Audio/Video/Voice can be the ASR source via
|
|
81
81
|
`audio-script-source`, without creating a synthesis variant.
|
|
82
82
|
|
|
83
|
-
`insertCaptionClip` requires `baseEntityIds` and `
|
|
83
|
+
`insertCaptionClip` requires `baseEntityIds` and one `selection` object; its optional `captionEntityId` preserves a generation-provided business identity independently of `captionClipEntityId`. The selection
|
|
84
84
|
names a source `segmentId` and optionally a half-open Unicode code-point
|
|
85
85
|
`textRange: {start, end}`. This permits display re-segmentation without rewriting
|
|
86
86
|
the original script. `upsertVoiceoverTake` requires the real
|
|
@@ -130,6 +130,7 @@ const captionStyle$1 = schema.LoroMap({
|
|
|
130
130
|
position_y: schema.Number({ required: false })
|
|
131
131
|
}, { required: false });
|
|
132
132
|
const captionPart = schema.LoroMap({
|
|
133
|
+
display_cues: schema.String({ required: false }).transform(jsonTransform()),
|
|
133
134
|
id: schema.String(),
|
|
134
135
|
initial_duration_ms: schema.Number(),
|
|
135
136
|
speech_part_id: schema.String({ required: false }),
|
|
@@ -1705,15 +1706,15 @@ function assembleCaptionContent(rows, captionEntityId) {
|
|
|
1705
1706
|
requireEntityKind(rows, captionEntityId, "caption");
|
|
1706
1707
|
const caption = assembleEntityContent(rows, captionEntityId);
|
|
1707
1708
|
const script = findComposedAudioScript(rows, captionEntityId, "caption");
|
|
1708
|
-
const
|
|
1709
|
+
const segment = selectAudioScriptSegment({
|
|
1709
1710
|
...script,
|
|
1710
1711
|
payload: caption.payload
|
|
1711
|
-
},
|
|
1712
|
+
}, captionSelection(caption));
|
|
1712
1713
|
return {
|
|
1713
1714
|
caption,
|
|
1714
1715
|
audioScript: script,
|
|
1715
|
-
segments,
|
|
1716
|
-
text:
|
|
1716
|
+
segments: [segment],
|
|
1717
|
+
text: segment.text
|
|
1717
1718
|
};
|
|
1718
1719
|
}
|
|
1719
1720
|
/**
|
|
@@ -1735,20 +1736,18 @@ function assemblePhoneticScriptContent(rows, phoneticScriptEntityId) {
|
|
|
1735
1736
|
text: segments.map((segment) => segment.text).join("")
|
|
1736
1737
|
};
|
|
1737
1738
|
}
|
|
1738
|
-
function
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
if (!selections.every(isSegmentSelection)) throw new ScriptCompositionError("invalid_selection", caption.entityId, "Caption selections require a segmentId and optional textRange");
|
|
1742
|
-
return selections;
|
|
1739
|
+
function captionSelection(caption) {
|
|
1740
|
+
if (Object.hasOwn(caption.payload, "selections") || !isSegmentSelection(caption.payload.selection)) throw new ScriptCompositionError("invalid_selection", caption.entityId, "Caption requires one selection object with segmentId and optional textRange; selections arrays are forbidden");
|
|
1741
|
+
return caption.payload.selection;
|
|
1743
1742
|
}
|
|
1744
1743
|
function isSegmentSelection(value) {
|
|
1745
1744
|
return typeof value === "object" && value != null && !Array.isArray(value) && typeof value.segmentId === "string" && value.segmentId.trim() !== "" && Object.keys(value).every((key) => key === "segmentId" || key === "textRange");
|
|
1746
1745
|
}
|
|
1747
1746
|
/** Select source text without creating another authoritative text field. */
|
|
1748
|
-
function
|
|
1749
|
-
if (!
|
|
1747
|
+
function selectAudioScriptSegment(script, selection) {
|
|
1748
|
+
if (!isSegmentSelection(selection)) throw new ScriptCompositionError("invalid_selection", script.entityId, "Caption requires one selection object with segmentId and optional textRange");
|
|
1750
1749
|
const bySegmentId = new Map(scriptSegments(script).map((segment) => [segment.segmentId, segment]));
|
|
1751
|
-
const selected =
|
|
1750
|
+
const selected = (() => {
|
|
1752
1751
|
const segment = bySegmentId.get(selection.segmentId);
|
|
1753
1752
|
if (segment === void 0) throw new ScriptCompositionError("unknown_segment", script.entityId, `Caption selection "${selection.segmentId}" does not name a segment of AudioScript "${script.entityId}"`);
|
|
1754
1753
|
if (selection.textRange === void 0) return segment;
|
|
@@ -1759,8 +1758,8 @@ function selectAudioScriptSegments(script, selections) {
|
|
|
1759
1758
|
...segment,
|
|
1760
1759
|
text: points.slice(range.start, range.end).join("")
|
|
1761
1760
|
};
|
|
1762
|
-
});
|
|
1763
|
-
if (!selected.
|
|
1761
|
+
})();
|
|
1762
|
+
if (!selected.text.trim()) throw new ScriptCompositionError("empty_selection", script.entityId, "Caption selection must contain visible source text");
|
|
1764
1763
|
return selected;
|
|
1765
1764
|
}
|
|
1766
1765
|
function requireEntityKind(rows, entityIdValue, entityKind) {
|
|
@@ -2232,25 +2231,15 @@ function validateVoicePayload(value, problems) {
|
|
|
2232
2231
|
function validateCaptionPayload(value, problems) {
|
|
2233
2232
|
validateExternalLocator(value, problems);
|
|
2234
2233
|
if (value.segmentRanges !== void 0) validateSegmentRanges(value.segmentRanges, problems);
|
|
2235
|
-
|
|
2236
|
-
|
|
2234
|
+
if (Object.hasOwn(value, "selections")) problems.push("selections is forbidden; Caption requires one selection object");
|
|
2235
|
+
const selection = value.selection;
|
|
2236
|
+
if (!isRecord(selection)) problems.push("selection must be one AudioScript segment selection object, not an array");
|
|
2237
2237
|
else {
|
|
2238
|
-
if (
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
continue;
|
|
2244
|
-
}
|
|
2245
|
-
if (typeof selection.segmentId !== "string" || selection.segmentId.trim() === "") problems.push(`selections[${index}].segmentId must be a string`);
|
|
2246
|
-
else if (seen.has(selection.segmentId)) problems.push(`selections[${index}].segmentId must be unique within the Caption`);
|
|
2247
|
-
else seen.add(selection.segmentId);
|
|
2248
|
-
if (Object.keys(selection).some((key) => key !== "segmentId" && key !== "textRange")) problems.push(`selections[${index}] may only contain segmentId and textRange`);
|
|
2249
|
-
if (selection.textRange !== void 0) {
|
|
2250
|
-
const range = selection.textRange;
|
|
2251
|
-
if (!isRecord(range) || !Number.isSafeInteger(range.start) || !Number.isSafeInteger(range.end) || range.start < 0 || range.end <= range.start || Object.keys(range).some((key) => key !== "start" && key !== "end")) problems.push(`selections[${index}].textRange must be a non-empty half-open code-point range`);
|
|
2252
|
-
}
|
|
2253
|
-
}
|
|
2238
|
+
if (typeof selection.segmentId !== "string" || !selection.segmentId.trim()) problems.push("selection.segmentId must be a non-empty string");
|
|
2239
|
+
if (Object.keys(selection).some((key) => key !== "segmentId" && key !== "textRange")) problems.push("selection may only contain segmentId and textRange");
|
|
2240
|
+
const range = selection.textRange;
|
|
2241
|
+
if (range !== void 0 && (!isRecord(range) || !Number.isSafeInteger(range.start) || !Number.isSafeInteger(range.end) || range.start < 0 || range.end <= range.start || Object.keys(range).some((key) => key !== "start" && key !== "end"))) problems.push("selection.textRange must be a non-empty half-open code-point range");
|
|
2242
|
+
if (Array.isArray(value.segmentRanges) && (value.segmentRanges.length !== 1 || !isRecord(value.segmentRanges[0]) || value.segmentRanges[0].segmentId !== selection.segmentId)) problems.push("Caption segmentRanges must contain only the selected segment timing");
|
|
2254
2243
|
}
|
|
2255
2244
|
const style = value.style;
|
|
2256
2245
|
if (style === void 0) return;
|
|
@@ -2374,7 +2363,7 @@ function isOwnedLocalEntityValuePath(entityKind, path) {
|
|
|
2374
2363
|
if (entityKind === "asset" && /^(?:external\.(?:system|key)|storageKey)$/.test(path)) return true;
|
|
2375
2364
|
if (isMediaAssetVariantKind(entityKind) && /^(?:external\.(?:system|key)|storageKey)$/.test(path)) return true;
|
|
2376
2365
|
if (entityKind === "voice" && /^voice\.(?:system|key|name)$/.test(path)) return true;
|
|
2377
|
-
if (entityKind === "caption" && (path.startsWith("style.") ||
|
|
2366
|
+
if (entityKind === "caption" && (path.startsWith("style.") || path === "selection.segmentId")) return true;
|
|
2378
2367
|
if ([
|
|
2379
2368
|
"audio-script",
|
|
2380
2369
|
"caption",
|
|
@@ -2389,7 +2378,7 @@ function isOwnedLocalIdPath(entityKind, path) {
|
|
|
2389
2378
|
"caption",
|
|
2390
2379
|
"phonetic-script"
|
|
2391
2380
|
].includes(entityKind) && /^segments\[\d+\]\.segmentId$/.test(path)) return true;
|
|
2392
|
-
if (entityKind === "caption" &&
|
|
2381
|
+
if (entityKind === "caption" && path === "selection.segmentId") return true;
|
|
2393
2382
|
if ((entityKind === "sequence-marker" || entityKind === "caption") && /^segmentRanges\[\d+\]\.segmentId$/.test(path)) return true;
|
|
2394
2383
|
if (entityKind === "asset" && /^(?:tracks\[\d+\]\.trackId|renditions\[\d+\]\.renditionId)$/.test(path)) return true;
|
|
2395
2384
|
return false;
|
|
@@ -3159,7 +3148,9 @@ function projectEntityTimeline(rows, meta) {
|
|
|
3159
3148
|
caption_ids: captionIds
|
|
3160
3149
|
} };
|
|
3161
3150
|
} else if (track.role === "caption") {
|
|
3162
|
-
const
|
|
3151
|
+
const assembled = assembleCaptionContent(rows, content.entityId);
|
|
3152
|
+
const text = assembled.text;
|
|
3153
|
+
const cues = captionDisplayCues(assembled, marker, placement.duration);
|
|
3163
3154
|
if (marker.payload.timeRemapping !== void 0) fail("Caption timeRemapping is not supported by this reader");
|
|
3164
3155
|
const style = captionStyle(content.payload.style);
|
|
3165
3156
|
const anchor = placement.anchorClipEntityId === void 0 ? void 0 : layout.clips.get(placement.anchorClipEntityId);
|
|
@@ -3168,6 +3159,7 @@ function projectEntityTimeline(rows, meta) {
|
|
|
3168
3159
|
id: clip.entityId,
|
|
3169
3160
|
kind: "caption",
|
|
3170
3161
|
text,
|
|
3162
|
+
...cues === void 0 ? {} : { display_cues: cues },
|
|
3171
3163
|
speech_part_id: anchoredToSpeech ? placement.anchorClipEntityId : void 0,
|
|
3172
3164
|
start_ms: anchoredToSpeech ? placement.anchorOffset : 0,
|
|
3173
3165
|
initial_duration_ms: placement.duration,
|
|
@@ -3304,6 +3296,32 @@ function videoSpeed(content, marker, placement) {
|
|
|
3304
3296
|
config: { linear: { speed: rate } }
|
|
3305
3297
|
};
|
|
3306
3298
|
}
|
|
3299
|
+
/** Preserve selected text intervals without minting synthetic editable Clip identities. */
|
|
3300
|
+
function captionDisplayCues(assembled, marker, duration) {
|
|
3301
|
+
const ranges = assembled.caption.payload.segmentRanges;
|
|
3302
|
+
if (!Array.isArray(ranges)) return void 0;
|
|
3303
|
+
const source = range(marker.payload.sourceRange, "Caption sourceRange");
|
|
3304
|
+
const scale = duration / (source.end - source.start);
|
|
3305
|
+
return assembled.segments.flatMap((segment) => {
|
|
3306
|
+
const timing = ranges.find((entry) => object(entry) && entry.segmentId === segment.segmentId);
|
|
3307
|
+
if (!object(timing)) fail(`Caption timing is missing for selected segment ${segment.segmentId}`);
|
|
3308
|
+
const intrinsic = range({
|
|
3309
|
+
start: timing.startMs,
|
|
3310
|
+
end: timing.endMs
|
|
3311
|
+
}, "Caption segmentRange");
|
|
3312
|
+
const start = Math.max(source.start, intrinsic.start);
|
|
3313
|
+
const end = Math.min(source.end, intrinsic.end);
|
|
3314
|
+
if (end <= start) return [];
|
|
3315
|
+
const startMs = Math.round((start - source.start) * scale);
|
|
3316
|
+
const endMs = Math.round((end - source.start) * scale);
|
|
3317
|
+
return endMs > startMs ? [{
|
|
3318
|
+
segmentId: segment.segmentId,
|
|
3319
|
+
text: segment.text,
|
|
3320
|
+
startMs,
|
|
3321
|
+
durationMs: endMs - startMs
|
|
3322
|
+
}] : [];
|
|
3323
|
+
});
|
|
3324
|
+
}
|
|
3307
3325
|
//#endregion
|
|
3308
3326
|
//#region src/entity-crdt/field-changes.ts
|
|
3309
3327
|
const atomicFields = new Set([
|
|
@@ -3314,14 +3332,14 @@ const atomicFields = new Set([
|
|
|
3314
3332
|
"extent",
|
|
3315
3333
|
"timeRemapping",
|
|
3316
3334
|
"textRange",
|
|
3335
|
+
"selection",
|
|
3317
3336
|
"external",
|
|
3318
|
-
"coordinateSpace"
|
|
3319
|
-
"segmentRanges"
|
|
3337
|
+
"coordinateSpace"
|
|
3320
3338
|
]);
|
|
3321
3339
|
const textFields = new Set(["text", "phonemeScript"]);
|
|
3322
3340
|
const orderedFields = new Set([
|
|
3323
3341
|
"segments",
|
|
3324
|
-
"
|
|
3342
|
+
"segmentRanges",
|
|
3325
3343
|
"baseEntityIds"
|
|
3326
3344
|
]);
|
|
3327
3345
|
const unsafeKeys = new Set([
|
|
@@ -4048,8 +4066,8 @@ var LoroEntityDraft = class {
|
|
|
4048
4066
|
}
|
|
4049
4067
|
record(command) {
|
|
4050
4068
|
if (command.type === "create") this.selectedRoots.add(command.row.entityId);
|
|
4051
|
-
if (command.type === "write" && !equalJson(content(workspace(this.doc, command.root)).
|
|
4052
|
-
if (command.type === "field" && command.path[0] === "
|
|
4069
|
+
if (command.type === "write" && !equalJson(content(workspace(this.doc, command.root)).selection, command.payload.selection)) this.selectedRoots.add(command.root);
|
|
4070
|
+
if (command.type === "field" && command.path[0] === "selection") this.selectedRoots.add(command.root);
|
|
4053
4071
|
apply(this.doc, command);
|
|
4054
4072
|
this.commands.push(command);
|
|
4055
4073
|
}
|
|
@@ -4165,17 +4183,14 @@ function writeBases(doc, map, ids) {
|
|
|
4165
4183
|
/** Numeric sub-spans must not silently quote different text after a collaborative edit. */
|
|
4166
4184
|
function selectionFingerprint(rows, id) {
|
|
4167
4185
|
const row = rows.entities.find((row) => row.entityId === id);
|
|
4168
|
-
if (row?.entityKind !== "caption" || !
|
|
4169
|
-
const
|
|
4170
|
-
if (
|
|
4186
|
+
if (row?.entityKind !== "caption" || !isJsonObject(row.payload.selection)) return void 0;
|
|
4187
|
+
const selection = row.payload.selection;
|
|
4188
|
+
if (selection.textRange === void 0) return void 0;
|
|
4171
4189
|
const segments = assembleEntityContent(rows, row.entityId).payload.segments;
|
|
4172
4190
|
if (!Array.isArray(segments)) throw new Error("Caption text selection has no source segments");
|
|
4173
|
-
|
|
4174
|
-
|
|
4175
|
-
|
|
4176
|
-
if (!isJsonObject(source) || typeof source.text !== "string") throw new Error("Caption text selection source is missing");
|
|
4177
|
-
return [selection, source.text];
|
|
4178
|
-
}));
|
|
4191
|
+
const source = segments.find((segment) => isJsonObject(segment) && segment.segmentId === selection.segmentId);
|
|
4192
|
+
if (!isJsonObject(source) || typeof source.text !== "string") throw new Error("Caption text selection source is missing");
|
|
4193
|
+
return hash([selection, source.text]);
|
|
4179
4194
|
}
|
|
4180
4195
|
function assertState(state) {
|
|
4181
4196
|
for (const row of state.rows.entities) assembleEntityContent(state.rows, row.entityId);
|
|
@@ -4519,4 +4534,4 @@ function createPlainMemoryAdapter(document, options) {
|
|
|
4519
4534
|
return new PlainMemoryAdapter(document, options);
|
|
4520
4535
|
}
|
|
4521
4536
|
//#endregion
|
|
4522
|
-
export { cascadeAfterVideoClipChanges as $,
|
|
4537
|
+
export { cascadeAfterVideoClipChanges as $, selectAudioScriptSegment as A, derivePositionFromAbs as B, decodeEntityRelationRows as C, assemblePhoneticScriptContent as D, assembleEntityContent as E, createRelationId as F, validateVideoDocument as G, toVideoDocument as H, hasSequence as I, LANE_KINDS_IN_STACK_ORDER as J, partUnionSchema as K, isMediaAssetVariantKind as L, variantBaseEntityIds as M, isJsonObject as N, assembleScriptText as O, createEntityId as P, solveVideoDocument as Q, buildInitialVideoDocument as R, EntityTimelineProjectionError as S, assembleCaptionContent as T, VideoDocumentValidationError as U, fromVideoDocument as V, assertValidVideoDocument as W, findLaneTrack as X, ensureLaneTrack as Y, laneTrackId as Z, assertFieldChanges as _, recordEntries as _t, applyEntityTimelineProjection as a, resolveSpeechOverlapByShiftingVideos as at, EntityProjectionGraph as b, bytesToBase64 as bt, writeVideoDocumentToDraft as c, isEmptyVideoClip as ct, LoroEntityDocument as d, DEFAULT_UNIT_TIME_MS as dt, arrangeMainTrackSeamlessly as et, LoroEntityDraft as f, ENTITY_TIMELINE_PROJECTION_SCHEMA_VERSION as ft, applyFieldChanges as g, partUnionToDraft as gt, equalJson as h, speedOf as ht, MirrorVideoDocumentAdapter as i, resolveAllSpeechOverlaps as it, updateEntityFields as j, findComposedAudioScript as k, readVideoDocumentFromDraft as l, partDurationMs as lt, entityOrderGroups as m, effectiveVideoClipDurationMs as mt, createPlainMemoryAdapter as n, reassignSpeechesToVideoClipsByTime as nt, createMirrorVideoDocument as o, syncAggregatedClipsTimePosition as ot, readEntityDocument as p, VIDEO_DOCUMENT_SCHEMA_VERSION as pt, videoDocumentSchema as q, generatePartId as r, recalculateTimelineDuration as rt, createMirrorVideoDocumentAdapter as s, TIMELINE_SKELETON_DURATION_MS as st, PlainMemoryAdapter as t, fillMainTrackTimeGaps as tt, LORO_ENTITY_SCHEMA as u, safeDurationMs as ut, resolveFieldPath as v, videoDocumentMirrorSchema as vt, ScriptCompositionError as w, resolveEntityTimelineLayout as x, projectEntityTimeline as y, base64ToBytes as yt, buildSpeechHostMap as z };
|
|
@@ -493,7 +493,15 @@ type SpeechPart = Omit<SpeechPart$1, 'duration_ms'> & {
|
|
|
493
493
|
* (AudioScript provenance) and Voice alignment are entity Relations, decoupled
|
|
494
494
|
* from this display-side legacy view.
|
|
495
495
|
*/
|
|
496
|
+
/** Derived render interval, relative to the placed Caption Clip; never an Entity. */
|
|
497
|
+
interface CaptionDisplayCue {
|
|
498
|
+
segmentId: string;
|
|
499
|
+
text: string;
|
|
500
|
+
startMs: number;
|
|
501
|
+
durationMs: number;
|
|
502
|
+
}
|
|
496
503
|
type CaptionPart = Omit<CaptionPart$1, 'duration_ms'> & {
|
|
504
|
+
display_cues?: CaptionDisplayCue[];
|
|
497
505
|
initial_duration_ms?: number | undefined;
|
|
498
506
|
};
|
|
499
507
|
/**
|
|
@@ -911,7 +919,7 @@ interface CaptionTextRange extends JsonObject {
|
|
|
911
919
|
readonly end: number;
|
|
912
920
|
}
|
|
913
921
|
/**
|
|
914
|
-
*
|
|
922
|
+
* The Caption's single text selection. `segmentId` quotes the
|
|
915
923
|
* composed AudioScript's own stable segment identity — a local id quoted by the
|
|
916
924
|
* variant, never a peer Entity reference. Text itself is never copied here;
|
|
917
925
|
* complete Caption content is assembled through its direct baseEntityIds.
|
|
@@ -1767,4 +1775,4 @@ declare const videoDocumentSchema: z.ZodObject<{
|
|
|
1767
1775
|
}, z.core.$loose>]>>>;
|
|
1768
1776
|
}, z.core.$loose>;
|
|
1769
1777
|
//#endregion
|
|
1770
|
-
export { SequenceRange as $, generatePartId as A,
|
|
1778
|
+
export { SequenceRange as $, generatePartId as A, VideoDraft as At, ResolvedEntityClipPlacement as B, Track$1 as Bt, PlannedSemanticOpKind as C, TrackItemTimePosition as Ct, SnapshotReadable as D, VideoDocumentSchemaVersion as Dt, SchemaValidator as E, VideoDocument as Et, videoDocumentMirrorSchema as F, CaptionPart$1 as Ft, EntityTimelineProjectionError as G, ResolvedEntityTrack as H, VideoDocumentValidationError as I, CaptionStyle as It, RelationRow as J, EntityRelationRows as K, assertValidVideoDocument as L, PartAggregation as Lt, TrackItemDraft as M, effectiveVideoClipDurationMs as Mt, VideoDocumentDraft as N, speedOf as Nt, ValidationError as O, VideoDocumentValidationIssue as Ot, VideoDocumentMirrorSchema as P, Attachment as Pt, SequenceDuration as Q, validateVideoDocument as R, SpeedShift as Rt, ImplementedSemanticOpKind as S, TrackItem as St, isImplementedSemanticOpKind as T, VideoClipPart as Tt, resolveEntityTimelineLayout as U, ResolvedEntityTimelineLayout as V, TrackItem$1 as Vt, projectEntityTimeline as W, CaptionStyleFields as X, CaptionSegmentSelection as Y, ScriptTextSegment as Z, SemanticEditor as _, PartKind as _t, PlainMemoryAdapter as a, buildInitialVideoDocument as at, TransactAudit as b, Timeline as bt, MirrorVideoDocumentAdapter as c, buildSpeechHostMap as ct, createMirrorVideoDocument as d, toVideoDocument as dt, VoiceDescriptor as et, createMirrorVideoDocumentAdapter as f, BgmPart as ft, SemanticDocumentAdapter as g, ENTITY_TIMELINE_PROJECTION_SCHEMA_VERSION as gt, OpActor as h, DEFAULT_UNIT_TIME_MS as ht, JournalEntry as i, InitialDocumentFacts as it, TrackDraft as j, VideoDraftPartUnion as jt, PartIdFactory as k, VideoDocumentValidationIssueCode as kt, MirrorVideoDocumentOptions as l, derivePositionFromAbs as lt, CommitOptions as m, CaptionPart as mt, videoDocumentSchema as n, JsonValue as nt, PlainMemoryAdapterOptions as o, DerivedItemPosition as ot, writeVideoDocumentToDraft as p, CaptionDisplayCue as pt, EntityRow as q, readVideoDocumentFromDraft as r, EntityId as rt, createPlainMemoryAdapter as s, SpeechHostMap as st, partUnionSchema as t, JsonObject as tt, applyEntityTimelineProjection as u, fromVideoDocument as ut, SemanticOpInput as v, PartUnion as vt, SemanticOpKind as w, VIDEO_DOCUMENT_SCHEMA_VERSION as wt, IMPLEMENTED_SEMANTIC_OP_KINDS as x, Track as xt, SemanticOpName as y, SpeechPart as yt, EntityTimelineTrackRole as z, Timeline$1 as zt };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as index_d_exports } from "./index-CMa6ZCtX.js";
|
|
2
|
-
import { $ as SequenceRange, A as generatePartId, At as
|
|
2
|
+
import { $ as SequenceRange, A as generatePartId, At as VideoDraft, B as ResolvedEntityClipPlacement, Bt as Track$1, C as PlannedSemanticOpKind, Ct as TrackItemTimePosition, D as SnapshotReadable, Dt as VideoDocumentSchemaVersion, E as SchemaValidator, Et as VideoDocument, F as videoDocumentMirrorSchema, Ft as CaptionPart$1, G as EntityTimelineProjectionError, H as ResolvedEntityTrack, I as VideoDocumentValidationError, It as CaptionStyle, J as RelationRow, K as EntityRelationRows, L as assertValidVideoDocument, Lt as PartAggregation, M as TrackItemDraft, Mt as effectiveVideoClipDurationMs, N as VideoDocumentDraft, Nt as speedOf, O as ValidationError, Ot as VideoDocumentValidationIssue, P as VideoDocumentMirrorSchema, Pt as Attachment, Q as SequenceDuration, R as validateVideoDocument, Rt as SpeedShift, S as ImplementedSemanticOpKind, St as TrackItem, T as isImplementedSemanticOpKind, Tt as VideoClipPart, U as resolveEntityTimelineLayout, V as ResolvedEntityTimelineLayout, Vt as TrackItem$1, W as projectEntityTimeline, X as CaptionStyleFields, Y as CaptionSegmentSelection, Z as ScriptTextSegment, _ as SemanticEditor, _t as PartKind, a as PlainMemoryAdapter, at as buildInitialVideoDocument, b as TransactAudit, bt as Timeline, c as MirrorVideoDocumentAdapter, ct as buildSpeechHostMap, d as createMirrorVideoDocument, dt as toVideoDocument, et as VoiceDescriptor, f as createMirrorVideoDocumentAdapter, ft as BgmPart, g as SemanticDocumentAdapter, gt as ENTITY_TIMELINE_PROJECTION_SCHEMA_VERSION, h as OpActor, ht as DEFAULT_UNIT_TIME_MS, i as JournalEntry, it as InitialDocumentFacts, j as TrackDraft, jt as VideoDraftPartUnion, k as PartIdFactory, kt as VideoDocumentValidationIssueCode, l as MirrorVideoDocumentOptions, lt as derivePositionFromAbs, m as CommitOptions, mt as CaptionPart, n as videoDocumentSchema, nt as JsonValue, o as PlainMemoryAdapterOptions, ot as DerivedItemPosition, p as writeVideoDocumentToDraft, pt as CaptionDisplayCue, q as EntityRow, r as readVideoDocumentFromDraft, rt as EntityId, s as createPlainMemoryAdapter, st as SpeechHostMap, t as partUnionSchema, tt as JsonObject, u as applyEntityTimelineProjection, ut as fromVideoDocument, v as SemanticOpInput, vt as PartUnion, w as SemanticOpKind, wt as VIDEO_DOCUMENT_SCHEMA_VERSION, x as IMPLEMENTED_SEMANTIC_OP_KINDS, xt as Track, y as SemanticOpName, yt as SpeechPart, z as EntityTimelineTrackRole, zt as Timeline$1 } from "./index-B31KeDzA.js";
|
|
3
3
|
import { LoroDoc, PeerID } from "loro-crdt";
|
|
4
4
|
import { DocState } from "@mengine/sync";
|
|
5
5
|
import { BaseDocStorage, Connection, DocDiff, DocPushReceipt, DocSnapshotRecord, DocStorage, DocStorageOptions, DocUpdate, DocUpdateRecord } from "@mengine/storage";
|
|
@@ -216,7 +216,7 @@ declare function assembleCaptionContent(rows: EntityRelationRows, captionEntityI
|
|
|
216
216
|
*/
|
|
217
217
|
declare function assemblePhoneticScriptContent(rows: EntityRelationRows, phoneticScriptEntityId: EntityId): AssembledPhoneticScriptContent;
|
|
218
218
|
/** Select source text without creating another authoritative text field. */
|
|
219
|
-
declare function
|
|
219
|
+
declare function selectAudioScriptSegment(script: EntityRow<'audio-script'>, selection: CaptionSegmentSelection): ScriptTextSegment;
|
|
220
220
|
//#endregion
|
|
221
221
|
//#region src/entity-editor/entity-graph-http-client.d.ts
|
|
222
222
|
/** One authenticated revision of the authoritative Medeo Entity graph. */
|
|
@@ -336,7 +336,7 @@ interface VoiceoverCaptionFact {
|
|
|
336
336
|
/** Directly held bases; includes the AudioScript used by the Voice. */
|
|
337
337
|
readonly baseEntityIds: readonly string[];
|
|
338
338
|
/** Ordered selection of AudioScript segments; caption text is never passed inline. */
|
|
339
|
-
readonly
|
|
339
|
+
readonly selection: CaptionSegmentSelection;
|
|
340
340
|
readonly startMs: number;
|
|
341
341
|
readonly durationMs: number;
|
|
342
342
|
readonly style?: CaptionStyleFields;
|
|
@@ -461,7 +461,7 @@ interface InsertCaptionClipInput {
|
|
|
461
461
|
/** Existing bases composed by this variant; includes an AudioScript text owner. */
|
|
462
462
|
readonly baseEntityIds: readonly string[];
|
|
463
463
|
/** Ordered selection of the AudioScript segments this Caption displays. */
|
|
464
|
-
readonly
|
|
464
|
+
readonly selection: CaptionSegmentSelection;
|
|
465
465
|
/** Intrinsic cue length of the Caption entity itself; display comes from the placement. */
|
|
466
466
|
readonly durationMs: number;
|
|
467
467
|
readonly style?: CaptionStyleFields;
|
|
@@ -624,7 +624,7 @@ declare function assertCanonicalEditorResources(rows: EntityRelationRows): void;
|
|
|
624
624
|
*/
|
|
625
625
|
declare function assertMediaAssetWritePolicy(before: EntityRelationRows, after: EntityRelationRows): void;
|
|
626
626
|
/** Add only missing editor structure; existing identities and owned settings are never replaced. */
|
|
627
|
-
declare function ensureEditorFoundation(initial: EntityRelationRows, idFactory?: EntityTimelineIdFactory, timelinePayload?: EntityRow['payload']): EditorFoundation;
|
|
627
|
+
declare function ensureEditorFoundation(initial: EntityRelationRows, idFactory?: EntityTimelineIdFactory, timelinePayload?: EntityRow['payload'], selectedAudioScriptEntityId?: string | null): EditorFoundation;
|
|
628
628
|
//#endregion
|
|
629
629
|
//#region src/entity-editor/media-asset-import.d.ts
|
|
630
630
|
interface ImportedMediaAsset {
|
|
@@ -656,7 +656,7 @@ interface CaptionContentInput {
|
|
|
656
656
|
readonly contentEntityId: string;
|
|
657
657
|
readonly audioScriptEntityId: string;
|
|
658
658
|
readonly text: string;
|
|
659
|
-
readonly
|
|
659
|
+
readonly selection?: CaptionSegmentSelection;
|
|
660
660
|
readonly durationMs: number;
|
|
661
661
|
}
|
|
662
662
|
/** Author Caption content from semantic intent; callers never reconcile variant bases or assembled fields. */
|
|
@@ -1744,4 +1744,4 @@ declare function hostForAbsMs(ranges: MainClipRange[], absMs: number): MainClipR
|
|
|
1744
1744
|
*/
|
|
1745
1745
|
declare function relativePositionForAbs(ranges: MainClipRange[], absMs: number): TrackItemTimePosition;
|
|
1746
1746
|
//#endregion
|
|
1747
|
-
export { type Aggregation, type AssembledCaptionContent, type AssembledPhoneticScriptContent, type Attachment, type AudioMediaAssetFact, type BgmPart, type CaptionContentInput, type CaptionPart, type CaptionSegmentSelection, type CaptionStyle, type ClipEntityId, type ClipPlacement, type CommitOptions, DEFAULT_UNIT_TIME_MS, type DeleteBgmInput, type DeleteClipInput, type DeleteClipTreeInput, type DeleteVoiceoverInput, type DerivedItemPosition, type DocStorageLike, type DocVersionMark, type DocumentAudioScript, type DocumentAudioScriptState, ENTITY_TIMELINE_PROJECTION_SCHEMA_VERSION, type EditorFoundation, EntityDocumentState, type EntityGraphCommitOptions, EntityGraphHttpClient, type EntityGraphState, EntityTimelineEditor, type EntityTimelineIdFactory, EntityTimelineProjectionError, type EntityTimelineTrackRole, type FieldChange, type FieldPath, IMPLEMENTED_SEMANTIC_OP_KINDS, type ImageMediaAssetFact, type ImplementedSemanticOpKind, type ImportedMediaAsset, type InitialDocumentFacts, type InsertCaptionClipInput, type InsertClipInput, type InsertMediaClipInput, type InsertMediaClipsInput, type InsertPlacedClipInput, type JournalEntry, LANE_KINDS_IN_STACK_ORDER, LORO_ENTITY_SCHEMA, type LaneKind, type LinearClipSpeed, LoroEntityDocument, LoroEntityDraft, type MainClipRange, type MakeEmptyPart, ManualSyncDoc, type ManualSyncDocOptions, MedeoHttpDocStorage, type MedeoHttpDocStorageOptions, type MediaAssetFact, type MediaClipInsertion, MemoryDocStorage, MengineAckFailedError, type MengineAuditEntry, type MengineAuditResponse, MengineDocSession, type MengineDocSessionOptions, type MengineDocSessionUpdateEvent, type MengineDocumentVersion, type MengineEventStreamOptions, MengineHttpClient, type MengineHttpClientOptions, MengineHttpRequestError, MenginePushRejectedError, type MenginePushResponse, type MenginePushUpdateResponse, type MengineRejectedResponse, type MengineSnapshotResponse, type MengineSseUpdateEvent, type MengineSyncResponse, type MengineUpdateMeta, MirrorVideoDocumentAdapter, type MirrorVideoDocumentOptions, type MoveClipInput, type MoveClipsToStartsInput, type MoveSequentialClipsInput, type MoveVoiceoverInput, type OpActor, type PartAggregation, type PartIdFactory, type PartKind, type PartUnion, type PatchCaptionStyleInput, PlainMemoryAdapter, type PlainMemoryAdapterOptions, type PlannedSemanticOpKind, type PullFailureReason, type PullResult, type PushOutcome, type PushOutcomeKind, type PushResult, type PushResultKind, type ReplaceClipContentInput, type ReplaceMediaClipInput, type ReplaceSequentialClipsInput, type ReplacementMediaClipInput, type ResolvedEntityClipPlacement, type ResolvedEntityTimelineLayout, type ResolvedEntityTrack, SchemaValidator, ScriptCompositionError, type SemanticDocumentAdapter, SemanticEditor, type SemanticOpInput, type SemanticOpKind, type SemanticOpName, type SequentialClipAnchor, type SetBgmInput, type SetCaptionVisibilityInput, type SetClipPlacementInput, type SetClipSpeedInput, type SetClipVolumeInput, type SnapshotReadable, type SolvedVideoDocument, type SpeechHostMap, type SpeechPart, type SpeedShift, TIMELINE_SKELETON_DURATION_MS, type Timeline, type TimelineDoc, type TimelineItem, type Track, type TrackDraft, type TrackItem, type TrackItemDraft, type TrackItemTimePosition, type TransactAudit, type TrimClipInput, type UpdateClipInput, type UpdateClipMarkerInput, VIDEO_DOCUMENT_SCHEMA_VERSION, ValidationError, type VideoClipPart, type VideoDocument, type VideoDocumentDraft, type VideoDocumentMirrorSchema, type VideoDocumentSchemaVersion, VideoDocumentValidationError, type VideoDocumentValidationIssue, type VideoDocumentValidationIssueCode, type VideoDraft, type CaptionPart$1 as VideoDraftCaptionPart, type VideoDraftPartUnion, type Timeline$1 as VideoDraftTimeline, type Track$1 as VideoDraftTrack, type TrackItem$1 as VideoDraftTrackItem, type VideoMediaAssetFact, type VisualMediaAssetFact, type VoiceMediaAssetFact, type VoiceoverCaptionFact, type VoiceoverTakeInput, type VoiceoverTakeResult, type WaitForServerAckOptions, applyEntityRows, applyEntityTimelineProjection, applyFieldChanges, arrangeMainTrackSeamlessly, assembleCaptionContent, assembleEntityContent, assemblePhoneticScriptContent, assembleScriptText, assertCanonicalEditorResources, assertEntityProjectionPreservesLegacy, assertFieldChanges, assertMediaAssetWritePolicy, assertValidVideoDocument, base64ToBytes, buildInitialVideoDocument, buildSpeechHostMap, bytesToBase64, cascadeAfterVideoClipChanges, compileEntityRows, createEditSandbox, createMirrorVideoDocument, createMirrorVideoDocumentAdapter, createPlainMemoryAdapter, decodeDocVersionMark, derivePositionFromAbs, effectiveVideoClipDurationMs, encodeDocVersionMark, ensureEditorFoundation, ensureLaneTrack, fillMainTrackTimeGaps, findComposedAudioScript, findLaneTrack, fromVideoDocument, generatePartId, getAt, hostForAbsMs, importMediaAsset, isEmptyVideoClip, isImplementedSemanticOpKind, isMap, laneTrackId, mainTrackRanges, migrateLegacyTimelineToEntities, partDurationMs, partUnionSchema, prepareCaptionContent, projectEntityTimeline, readDocumentAudioScript, readEntityDocument, readMainTrackItems, readMengineEventStream, readPart, readPartDurationMs, readVideoDocumentFromDraft, reassignSpeechesToVideoClipsByTime, recalculateTimelineDuration, relativePositionForAbs, replayJournal, resolveAllSpeechOverlaps, resolveEntityTimelineLayout, resolveFieldPath, resolveSpeechOverlapByShiftingVideos, safeDurationMs, index_d_exports as schemas,
|
|
1747
|
+
export { type Aggregation, type AssembledCaptionContent, type AssembledPhoneticScriptContent, type Attachment, type AudioMediaAssetFact, type BgmPart, type CaptionContentInput, type CaptionDisplayCue, type CaptionPart, type CaptionSegmentSelection, type CaptionStyle, type ClipEntityId, type ClipPlacement, type CommitOptions, DEFAULT_UNIT_TIME_MS, type DeleteBgmInput, type DeleteClipInput, type DeleteClipTreeInput, type DeleteVoiceoverInput, type DerivedItemPosition, type DocStorageLike, type DocVersionMark, type DocumentAudioScript, type DocumentAudioScriptState, ENTITY_TIMELINE_PROJECTION_SCHEMA_VERSION, type EditorFoundation, EntityDocumentState, type EntityGraphCommitOptions, EntityGraphHttpClient, type EntityGraphState, EntityTimelineEditor, type EntityTimelineIdFactory, EntityTimelineProjectionError, type EntityTimelineTrackRole, type FieldChange, type FieldPath, IMPLEMENTED_SEMANTIC_OP_KINDS, type ImageMediaAssetFact, type ImplementedSemanticOpKind, type ImportedMediaAsset, type InitialDocumentFacts, type InsertCaptionClipInput, type InsertClipInput, type InsertMediaClipInput, type InsertMediaClipsInput, type InsertPlacedClipInput, type JournalEntry, LANE_KINDS_IN_STACK_ORDER, LORO_ENTITY_SCHEMA, type LaneKind, type LinearClipSpeed, LoroEntityDocument, LoroEntityDraft, type MainClipRange, type MakeEmptyPart, ManualSyncDoc, type ManualSyncDocOptions, MedeoHttpDocStorage, type MedeoHttpDocStorageOptions, type MediaAssetFact, type MediaClipInsertion, MemoryDocStorage, MengineAckFailedError, type MengineAuditEntry, type MengineAuditResponse, MengineDocSession, type MengineDocSessionOptions, type MengineDocSessionUpdateEvent, type MengineDocumentVersion, type MengineEventStreamOptions, MengineHttpClient, type MengineHttpClientOptions, MengineHttpRequestError, MenginePushRejectedError, type MenginePushResponse, type MenginePushUpdateResponse, type MengineRejectedResponse, type MengineSnapshotResponse, type MengineSseUpdateEvent, type MengineSyncResponse, type MengineUpdateMeta, MirrorVideoDocumentAdapter, type MirrorVideoDocumentOptions, type MoveClipInput, type MoveClipsToStartsInput, type MoveSequentialClipsInput, type MoveVoiceoverInput, type OpActor, type PartAggregation, type PartIdFactory, type PartKind, type PartUnion, type PatchCaptionStyleInput, PlainMemoryAdapter, type PlainMemoryAdapterOptions, type PlannedSemanticOpKind, type PullFailureReason, type PullResult, type PushOutcome, type PushOutcomeKind, type PushResult, type PushResultKind, type ReplaceClipContentInput, type ReplaceMediaClipInput, type ReplaceSequentialClipsInput, type ReplacementMediaClipInput, type ResolvedEntityClipPlacement, type ResolvedEntityTimelineLayout, type ResolvedEntityTrack, SchemaValidator, ScriptCompositionError, type SemanticDocumentAdapter, SemanticEditor, type SemanticOpInput, type SemanticOpKind, type SemanticOpName, type SequentialClipAnchor, type SetBgmInput, type SetCaptionVisibilityInput, type SetClipPlacementInput, type SetClipSpeedInput, type SetClipVolumeInput, type SnapshotReadable, type SolvedVideoDocument, type SpeechHostMap, type SpeechPart, type SpeedShift, TIMELINE_SKELETON_DURATION_MS, type Timeline, type TimelineDoc, type TimelineItem, type Track, type TrackDraft, type TrackItem, type TrackItemDraft, type TrackItemTimePosition, type TransactAudit, type TrimClipInput, type UpdateClipInput, type UpdateClipMarkerInput, VIDEO_DOCUMENT_SCHEMA_VERSION, ValidationError, type VideoClipPart, type VideoDocument, type VideoDocumentDraft, type VideoDocumentMirrorSchema, type VideoDocumentSchemaVersion, VideoDocumentValidationError, type VideoDocumentValidationIssue, type VideoDocumentValidationIssueCode, type VideoDraft, type CaptionPart$1 as VideoDraftCaptionPart, type VideoDraftPartUnion, type Timeline$1 as VideoDraftTimeline, type Track$1 as VideoDraftTrack, type TrackItem$1 as VideoDraftTrackItem, type VideoMediaAssetFact, type VisualMediaAssetFact, type VoiceMediaAssetFact, type VoiceoverCaptionFact, type VoiceoverTakeInput, type VoiceoverTakeResult, type WaitForServerAckOptions, applyEntityRows, applyEntityTimelineProjection, applyFieldChanges, arrangeMainTrackSeamlessly, assembleCaptionContent, assembleEntityContent, assemblePhoneticScriptContent, assembleScriptText, assertCanonicalEditorResources, assertEntityProjectionPreservesLegacy, assertFieldChanges, assertMediaAssetWritePolicy, assertValidVideoDocument, base64ToBytes, buildInitialVideoDocument, buildSpeechHostMap, bytesToBase64, cascadeAfterVideoClipChanges, compileEntityRows, createEditSandbox, createMirrorVideoDocument, createMirrorVideoDocumentAdapter, createPlainMemoryAdapter, decodeDocVersionMark, derivePositionFromAbs, effectiveVideoClipDurationMs, encodeDocVersionMark, ensureEditorFoundation, ensureLaneTrack, fillMainTrackTimeGaps, findComposedAudioScript, findLaneTrack, fromVideoDocument, generatePartId, getAt, hostForAbsMs, importMediaAsset, isEmptyVideoClip, isImplementedSemanticOpKind, isMap, laneTrackId, mainTrackRanges, migrateLegacyTimelineToEntities, partDurationMs, partUnionSchema, prepareCaptionContent, projectEntityTimeline, readDocumentAudioScript, readEntityDocument, readMainTrackItems, readMengineEventStream, readPart, readPartDurationMs, readVideoDocumentFromDraft, reassignSpeechesToVideoClipsByTime, recalculateTimelineDuration, relativePositionForAbs, replayJournal, resolveAllSpeechOverlaps, resolveEntityTimelineLayout, resolveFieldPath, resolveSpeechOverlapByShiftingVideos, safeDurationMs, index_d_exports as schemas, selectAudioScriptSegment, snapshotToPlain, solveVideoDocument, speedOf, syncAggregatedClipsTimePosition, toVideoDocument, validateVideoDocument, videoDocumentMirrorSchema, videoDocumentSchema, writeVideoDocumentToDraft };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as cascadeAfterVideoClipChanges, A as
|
|
1
|
+
import { $ as cascadeAfterVideoClipChanges, A as selectAudioScriptSegment, B as derivePositionFromAbs, C as decodeEntityRelationRows, D as assemblePhoneticScriptContent, E as assembleEntityContent, F as createRelationId, G as validateVideoDocument, H as toVideoDocument, I as hasSequence, J as LANE_KINDS_IN_STACK_ORDER, K as partUnionSchema, L as isMediaAssetVariantKind, M as variantBaseEntityIds, N as isJsonObject, O as assembleScriptText, P as createEntityId, Q as solveVideoDocument, R as buildInitialVideoDocument, S as EntityTimelineProjectionError, T as assembleCaptionContent, U as VideoDocumentValidationError, V as fromVideoDocument, W as assertValidVideoDocument, X as findLaneTrack, Y as ensureLaneTrack, Z as laneTrackId, _ as assertFieldChanges, _t as recordEntries, a as applyEntityTimelineProjection, at as resolveSpeechOverlapByShiftingVideos, b as EntityProjectionGraph, bt as bytesToBase64, c as writeVideoDocumentToDraft, ct as isEmptyVideoClip, d as LoroEntityDocument, dt as DEFAULT_UNIT_TIME_MS, et as arrangeMainTrackSeamlessly, f as LoroEntityDraft, ft as ENTITY_TIMELINE_PROJECTION_SCHEMA_VERSION, g as applyFieldChanges, gt as partUnionToDraft, h as equalJson, ht as speedOf, i as MirrorVideoDocumentAdapter, it as resolveAllSpeechOverlaps, j as updateEntityFields, k as findComposedAudioScript, l as readVideoDocumentFromDraft, lt as partDurationMs, m as entityOrderGroups, mt as effectiveVideoClipDurationMs, n as createPlainMemoryAdapter, nt as reassignSpeechesToVideoClipsByTime, o as createMirrorVideoDocument, ot as syncAggregatedClipsTimePosition, p as readEntityDocument, pt as VIDEO_DOCUMENT_SCHEMA_VERSION, q as videoDocumentSchema, r as generatePartId, rt as recalculateTimelineDuration, s as createMirrorVideoDocumentAdapter, st as TIMELINE_SKELETON_DURATION_MS, t as PlainMemoryAdapter, tt as fillMainTrackTimeGaps, u as LORO_ENTITY_SCHEMA, ut as safeDurationMs, v as resolveFieldPath, vt as videoDocumentMirrorSchema, w as ScriptCompositionError, x as resolveEntityTimelineLayout, y as projectEntityTimeline, yt as base64ToBytes, z as buildSpeechHostMap } from "./document-BSAUud6c.js";
|
|
2
2
|
import { addSpeechesInputSchema, addVideoClipsInputSchema, adjustBgmVolumeInputSchema, adjustSpeechVolumeInputSchema, adjustVideoClipDurationInputSchema, adjustVideoClipVolumeInputSchema, changeSpeechScriptInputSchema, changeSpeechVoiceInputSchema, deleteBgmInputSchema, deleteSpeechesInputSchema, deleteVideoClipsInputSchema, moveSpeechesInputSchema, moveVideoClipsByAnchorInputSchema, moveVideoClipsInputSchema, replaceVideoClipContentInputSchema, replaceVideoClipSequenceInputSchema, setBgmInputSchema, setCaptionStyleInputSchema, setCaptionVisibilityInputSchema, setVideoClipSpeedShiftInputSchema, t as schemas_exports } from "./schemas.js";
|
|
3
3
|
import { LoroDoc, VersionVector } from "loro-crdt";
|
|
4
4
|
import { ClientServerSynchronizer, DocManager } from "@mengine/sync";
|
|
@@ -362,9 +362,13 @@ function memotaLocator(value) {
|
|
|
362
362
|
* explicit project attachment, multiple candidates are ambiguous. Existing
|
|
363
363
|
* content IDs are reused here; Loro editing advances their immutable versions.
|
|
364
364
|
*/
|
|
365
|
-
function ensureDocumentAudioScript(entities, idFactory) {
|
|
365
|
+
function ensureDocumentAudioScript(entities, idFactory, selectedEntityId) {
|
|
366
|
+
if (selectedEntityId != null) {
|
|
367
|
+
if (!entities.some((row) => row.entityKind === "audio-script" && row.entityId === selectedEntityId)) throw new EntityTimelineProjectionError(`Selected AudioScript ${selectedEntityId} does not exist`);
|
|
368
|
+
return selectedEntityId;
|
|
369
|
+
}
|
|
366
370
|
const scripts = entities.filter((row) => row.entityKind === "audio-script");
|
|
367
|
-
if (scripts.length > 1) throw new EntityTimelineProjectionError("
|
|
371
|
+
if (scripts.length > 1) throw new EntityTimelineProjectionError("Select an AudioScript for the editor panel when multiple scripts exist");
|
|
368
372
|
const existing = scripts[0];
|
|
369
373
|
if (existing !== void 0) return existing.entityId;
|
|
370
374
|
const id = createEntityId(idFactory("entity"));
|
|
@@ -377,7 +381,7 @@ function ensureDocumentAudioScript(entities, idFactory) {
|
|
|
377
381
|
return id;
|
|
378
382
|
}
|
|
379
383
|
/** Add only missing editor structure; existing identities and owned settings are never replaced. */
|
|
380
|
-
function ensureEditorFoundation(initial, idFactory = (prefix) => `${prefix}_${globalThis.crypto.randomUUID()}`, timelinePayload = {}) {
|
|
384
|
+
function ensureEditorFoundation(initial, idFactory = (prefix) => `${prefix}_${globalThis.crypto.randomUUID()}`, timelinePayload = {}, selectedAudioScriptEntityId) {
|
|
381
385
|
const entities = structuredClone([...initial.entities]);
|
|
382
386
|
const relations = structuredClone([...initial.relations]);
|
|
383
387
|
const roots = entities.filter((row) => row.entityKind === "timeline");
|
|
@@ -428,7 +432,7 @@ function ensureEditorFoundation(initial, idFactory = (prefix) => `${prefix}_${gl
|
|
|
428
432
|
}
|
|
429
433
|
trackEntityIds[role] = track.entityId;
|
|
430
434
|
}
|
|
431
|
-
const audioScriptEntityId = ensureDocumentAudioScript(entities, idFactory);
|
|
435
|
+
const audioScriptEntityId = ensureDocumentAudioScript(entities, idFactory, selectedAudioScriptEntityId);
|
|
432
436
|
return {
|
|
433
437
|
rows: {
|
|
434
438
|
entities,
|
|
@@ -678,8 +682,8 @@ function sameVoice(left, right) {
|
|
|
678
682
|
function requireComposedAudioScript(rows, phoneticScriptEntityId) {
|
|
679
683
|
return assemblePhoneticScriptContent(rows, phoneticScriptEntityId).audioScript.entityId;
|
|
680
684
|
}
|
|
681
|
-
function
|
|
682
|
-
return structuredClone(
|
|
685
|
+
function captionSelection(selection) {
|
|
686
|
+
return structuredClone(selection);
|
|
683
687
|
}
|
|
684
688
|
function captionBaseIds(ids) {
|
|
685
689
|
if (!Array.isArray(ids) || ids.length === 0) throw new Error("Caption requires non-empty baseEntityIds");
|
|
@@ -1373,7 +1377,7 @@ var EntityTimelineEditor = class {
|
|
|
1373
1377
|
insertCaptionClip(input) {
|
|
1374
1378
|
return this.transact((draft) => {
|
|
1375
1379
|
const durationMs = finitePositive(input.durationMs, "Caption durationMs");
|
|
1376
|
-
const
|
|
1380
|
+
const selection = captionSelection(input.selection);
|
|
1377
1381
|
const track = this.ensureRoleTrack(draft, input.timelineEntityId, "caption");
|
|
1378
1382
|
const content = {
|
|
1379
1383
|
entityId: input.captionEntityId === void 0 ? this.mintEntityId(draft) : requireAvailableEntityId(draft, input.captionEntityId),
|
|
@@ -1387,7 +1391,7 @@ var EntityTimelineEditor = class {
|
|
|
1387
1391
|
sampling: "native",
|
|
1388
1392
|
coordinateSpace: "milliseconds",
|
|
1389
1393
|
baseEntityIds: captionBaseIds(input.baseEntityIds),
|
|
1390
|
-
|
|
1394
|
+
selection,
|
|
1391
1395
|
...input.style === void 0 ? {} : { style: cloneJsonObject(input.style, "Caption style") }
|
|
1392
1396
|
}
|
|
1393
1397
|
};
|
|
@@ -1496,7 +1500,7 @@ var EntityTimelineEditor = class {
|
|
|
1496
1500
|
for (const caption of captions) {
|
|
1497
1501
|
const startMs = finiteNonNegative(caption.startMs, "Caption startMs");
|
|
1498
1502
|
const durationMs = finitePositive(caption.durationMs, "Caption durationMs");
|
|
1499
|
-
const
|
|
1503
|
+
const selection = captionSelection(caption.selection);
|
|
1500
1504
|
const baseEntityIds = captionBaseIds(caption.baseEntityIds);
|
|
1501
1505
|
if (draft.entities.find((entity) => entity.entityId === caption.captionClipEntityId) === void 0) {
|
|
1502
1506
|
const content = {
|
|
@@ -1511,7 +1515,7 @@ var EntityTimelineEditor = class {
|
|
|
1511
1515
|
sampling: "native",
|
|
1512
1516
|
coordinateSpace: "milliseconds",
|
|
1513
1517
|
baseEntityIds,
|
|
1514
|
-
|
|
1518
|
+
selection,
|
|
1515
1519
|
...caption.style === void 0 ? {} : { style: cloneJsonObject(caption.style, "Caption style") }
|
|
1516
1520
|
}
|
|
1517
1521
|
};
|
|
@@ -1553,7 +1557,7 @@ var EntityTimelineEditor = class {
|
|
|
1553
1557
|
payload: {
|
|
1554
1558
|
...content.payload,
|
|
1555
1559
|
baseEntityIds,
|
|
1556
|
-
|
|
1560
|
+
selection,
|
|
1557
1561
|
...Object.keys(style).length === 0 ? {} : { style }
|
|
1558
1562
|
}
|
|
1559
1563
|
});
|
|
@@ -2145,14 +2149,14 @@ function migrateLegacyTimelineToEntities(legacy, assetFacts, initial = {
|
|
|
2145
2149
|
const sourceText = scriptText(script);
|
|
2146
2150
|
const captionText = caption.text;
|
|
2147
2151
|
const offset = sourceText.indexOf(captionText);
|
|
2148
|
-
if (!captionText.trim() || offset < 0 || sourceText.indexOf(captionText, offset + 1) >= 0) fail("Legacy Caption needs explicit unambiguous AudioScript
|
|
2149
|
-
const
|
|
2152
|
+
if (!captionText.trim() || offset < 0 || sourceText.indexOf(captionText, offset + 1) >= 0) fail("Legacy Caption needs explicit unambiguous AudioScript selection before cutover");
|
|
2153
|
+
const selection = {
|
|
2150
2154
|
segmentId: "segment-0",
|
|
2151
2155
|
...sourceText === captionText ? {} : { textRange: {
|
|
2152
2156
|
start: Array.from(sourceText.slice(0, offset)).length,
|
|
2153
2157
|
end: Array.from(sourceText.slice(0, offset + captionText.length)).length
|
|
2154
2158
|
} }
|
|
2155
|
-
}
|
|
2159
|
+
};
|
|
2156
2160
|
content = addEntity("caption", {
|
|
2157
2161
|
extent: {
|
|
2158
2162
|
kind: "bounded",
|
|
@@ -2162,7 +2166,7 @@ function migrateLegacyTimelineToEntities(legacy, assetFacts, initial = {
|
|
|
2162
2166
|
sampling: "native",
|
|
2163
2167
|
coordinateSpace: "milliseconds",
|
|
2164
2168
|
baseEntityIds: [script.entityId],
|
|
2165
|
-
|
|
2169
|
+
selection,
|
|
2166
2170
|
...caption.style === void 0 ? {} : { style: toEntityCaptionStyle(caption.style) }
|
|
2167
2171
|
});
|
|
2168
2172
|
link("caption-alignment", content, voice, { alignment: {
|
|
@@ -2676,7 +2680,7 @@ function prepareCaptionContent(rows, input) {
|
|
|
2676
2680
|
...candidate,
|
|
2677
2681
|
payload: {
|
|
2678
2682
|
...candidate.payload,
|
|
2679
|
-
|
|
2683
|
+
selection: structuredClone(input.selection ?? selectCaptionText(textSource, input.text))
|
|
2680
2684
|
}
|
|
2681
2685
|
};
|
|
2682
2686
|
if (assembleCaptionContent({
|
|
@@ -2687,10 +2691,7 @@ function prepareCaptionContent(rows, input) {
|
|
|
2687
2691
|
}
|
|
2688
2692
|
function selectCaptionText(script, text) {
|
|
2689
2693
|
if (!text.trim()) throw new Error("Caption text selection must not be blank");
|
|
2690
|
-
const
|
|
2691
|
-
const fullText = assembleScriptText(source);
|
|
2692
|
-
const segments = source.payload.segments;
|
|
2693
|
-
if (text === fullText) return segments.map((segment) => ({ segmentId: segment.segmentId }));
|
|
2694
|
+
const segments = script.payload.segments;
|
|
2694
2695
|
const matches = [];
|
|
2695
2696
|
for (const segment of segments) {
|
|
2696
2697
|
let offset = segment.text.indexOf(text);
|
|
@@ -2706,8 +2707,8 @@ function selectCaptionText(script, text) {
|
|
|
2706
2707
|
offset = segment.text.indexOf(text, offset + 1);
|
|
2707
2708
|
}
|
|
2708
2709
|
}
|
|
2709
|
-
if (matches.length !== 1) throw new Error("Caption text must select a unique AudioScript range; provide explicit
|
|
2710
|
-
return matches;
|
|
2710
|
+
if (matches.length !== 1) throw new Error("Caption text must select a unique AudioScript range; provide explicit selection");
|
|
2711
|
+
return matches[0];
|
|
2711
2712
|
}
|
|
2712
2713
|
//#endregion
|
|
2713
2714
|
//#region src/editor/snapshot-utils.ts
|
|
@@ -4848,4 +4849,4 @@ function serverCovers(serverVV, target) {
|
|
|
4848
4849
|
return covers(server, target);
|
|
4849
4850
|
}
|
|
4850
4851
|
//#endregion
|
|
4851
|
-
export { DEFAULT_UNIT_TIME_MS, ENTITY_TIMELINE_PROJECTION_SCHEMA_VERSION, EntityGraphHttpClient, EntityTimelineEditor, EntityTimelineProjectionError, IMPLEMENTED_SEMANTIC_OP_KINDS, LANE_KINDS_IN_STACK_ORDER, LORO_ENTITY_SCHEMA, LoroEntityDocument, LoroEntityDraft, ManualSyncDoc, MedeoHttpDocStorage, MemoryDocStorage, MengineAckFailedError, MengineDocSession, MengineHttpClient, MengineHttpRequestError, MenginePushRejectedError, MirrorVideoDocumentAdapter, PlainMemoryAdapter, SchemaValidator, ScriptCompositionError, SemanticEditor, TIMELINE_SKELETON_DURATION_MS, VIDEO_DOCUMENT_SCHEMA_VERSION, ValidationError, VideoDocumentValidationError, applyEntityRows, applyEntityTimelineProjection, applyFieldChanges, arrangeMainTrackSeamlessly, assembleCaptionContent, assembleEntityContent, assemblePhoneticScriptContent, assembleScriptText, assertCanonicalEditorResources, assertEntityProjectionPreservesLegacy, assertFieldChanges, assertMediaAssetWritePolicy, assertValidVideoDocument, base64ToBytes, buildInitialVideoDocument, buildSpeechHostMap, bytesToBase64, cascadeAfterVideoClipChanges, compileEntityRows, createEditSandbox, createMirrorVideoDocument, createMirrorVideoDocumentAdapter, createPlainMemoryAdapter, decodeDocVersionMark, derivePositionFromAbs, effectiveVideoClipDurationMs, encodeDocVersionMark, ensureEditorFoundation, ensureLaneTrack, fillMainTrackTimeGaps, findComposedAudioScript, findLaneTrack, fromVideoDocument, generatePartId, getAt, hostForAbsMs, importMediaAsset, isEmptyVideoClip, isImplementedSemanticOpKind, isMap, laneTrackId, mainTrackRanges, migrateLegacyTimelineToEntities, partDurationMs, partUnionSchema, prepareCaptionContent, projectEntityTimeline, readDocumentAudioScript, readEntityDocument, readMainTrackItems, readMengineEventStream, readPart, readPartDurationMs, readVideoDocumentFromDraft, reassignSpeechesToVideoClipsByTime, recalculateTimelineDuration, relativePositionForAbs, replayJournal, resolveAllSpeechOverlaps, resolveEntityTimelineLayout, resolveFieldPath, resolveSpeechOverlapByShiftingVideos, safeDurationMs, schemas_exports as schemas,
|
|
4852
|
+
export { DEFAULT_UNIT_TIME_MS, ENTITY_TIMELINE_PROJECTION_SCHEMA_VERSION, EntityGraphHttpClient, EntityTimelineEditor, EntityTimelineProjectionError, IMPLEMENTED_SEMANTIC_OP_KINDS, LANE_KINDS_IN_STACK_ORDER, LORO_ENTITY_SCHEMA, LoroEntityDocument, LoroEntityDraft, ManualSyncDoc, MedeoHttpDocStorage, MemoryDocStorage, MengineAckFailedError, MengineDocSession, MengineHttpClient, MengineHttpRequestError, MenginePushRejectedError, MirrorVideoDocumentAdapter, PlainMemoryAdapter, SchemaValidator, ScriptCompositionError, SemanticEditor, TIMELINE_SKELETON_DURATION_MS, VIDEO_DOCUMENT_SCHEMA_VERSION, ValidationError, VideoDocumentValidationError, applyEntityRows, applyEntityTimelineProjection, applyFieldChanges, arrangeMainTrackSeamlessly, assembleCaptionContent, assembleEntityContent, assemblePhoneticScriptContent, assembleScriptText, assertCanonicalEditorResources, assertEntityProjectionPreservesLegacy, assertFieldChanges, assertMediaAssetWritePolicy, assertValidVideoDocument, base64ToBytes, buildInitialVideoDocument, buildSpeechHostMap, bytesToBase64, cascadeAfterVideoClipChanges, compileEntityRows, createEditSandbox, createMirrorVideoDocument, createMirrorVideoDocumentAdapter, createPlainMemoryAdapter, decodeDocVersionMark, derivePositionFromAbs, effectiveVideoClipDurationMs, encodeDocVersionMark, ensureEditorFoundation, ensureLaneTrack, fillMainTrackTimeGaps, findComposedAudioScript, findLaneTrack, fromVideoDocument, generatePartId, getAt, hostForAbsMs, importMediaAsset, isEmptyVideoClip, isImplementedSemanticOpKind, isMap, laneTrackId, mainTrackRanges, migrateLegacyTimelineToEntities, partDurationMs, partUnionSchema, prepareCaptionContent, projectEntityTimeline, readDocumentAudioScript, readEntityDocument, readMainTrackItems, readMengineEventStream, readPart, readPartDurationMs, readVideoDocumentFromDraft, reassignSpeechesToVideoClipsByTime, recalculateTimelineDuration, relativePositionForAbs, replayJournal, resolveAllSpeechOverlaps, resolveEntityTimelineLayout, resolveFieldPath, resolveSpeechOverlapByShiftingVideos, safeDurationMs, schemas_exports as schemas, selectAudioScriptSegment, snapshotToPlain, solveVideoDocument, speedOf, syncAggregatedClipsTimePosition, toVideoDocument, validateVideoDocument, videoDocumentMirrorSchema, videoDocumentSchema, writeVideoDocumentToDraft };
|
package/dist/testing.d.ts
CHANGED
package/dist/testing.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { bt as bytesToBase64, pt as VIDEO_DOCUMENT_SCHEMA_VERSION, s as createMirrorVideoDocumentAdapter, yt as base64ToBytes } from "./document-
|
|
1
|
+
import { bt as bytesToBase64, pt as VIDEO_DOCUMENT_SCHEMA_VERSION, s as createMirrorVideoDocumentAdapter, yt as base64ToBytes } from "./document-BSAUud6c.js";
|
|
2
2
|
import { t as classifyUpdate } from "./loro-relay-doc-ssdYpuef.js";
|
|
3
3
|
import { LoroDoc, VersionVector, encodeFrontiers } from "loro-crdt";
|
|
4
4
|
//#region src/testing/in-memory-mengine-server.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mengine/medeo-client",
|
|
3
|
-
"version": "1.4.1-alpha.
|
|
3
|
+
"version": "1.4.1-alpha.5",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
"immer": "^10.2.0",
|
|
29
29
|
"loro-mirror": "^2.2.0",
|
|
30
30
|
"zod": "^4.4.3",
|
|
31
|
-
"@mengine/
|
|
32
|
-
"@mengine/
|
|
33
|
-
"@mengine/
|
|
31
|
+
"@mengine/utils": "1.4.1-alpha.5",
|
|
32
|
+
"@mengine/sync": "1.4.1-alpha.5",
|
|
33
|
+
"@mengine/storage": "1.4.1-alpha.5"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/node": "^25.9.1",
|