@mengine/medeo-client 2.0.1-alpha.20 → 2.0.1-alpha.21
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/dist/{document-yPiwEmkJ.js → document-BXQcpnOg.js} +60 -9
- package/dist/{index-C0uUWqkz.d.ts → index-CzDNr1Tb.d.ts} +21 -3
- package/dist/index.d.ts +411 -165
- package/dist/index.js +1598 -55
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +1 -1
- package/package.json +4 -4
|
@@ -1177,7 +1177,8 @@ function toAuthoritativePartLibrary(partLibrary) {
|
|
|
1177
1177
|
if (typeof part !== "object" || part == null) continue;
|
|
1178
1178
|
if (part.video_clip != null) out[partId] = { video_clip: withTrimWindowFromDuration(part.video_clip) };
|
|
1179
1179
|
else if (part.speech != null) {
|
|
1180
|
-
const {
|
|
1180
|
+
const { origin_asset_system: _originAssetSystem, ...readSpeech } = part.speech;
|
|
1181
|
+
const { duration_ms, rest } = splitDurationMs(readSpeech);
|
|
1181
1182
|
out[partId] = { speech: {
|
|
1182
1183
|
...rest,
|
|
1183
1184
|
media_duration_ms: rest.media_duration_ms ?? duration_ms
|
|
@@ -3035,7 +3036,7 @@ function resolveGraphLayout(graph) {
|
|
|
3035
3036
|
if (clip.entityKind !== "clip" || graph.adjacent(clip.entityId, "track-clip").length !== 1) fail(`Clip ${clip.entityId} must belong to exactly one Track`);
|
|
3036
3037
|
const marker = graph.one(clip.entityId, "clip-marker", "sequence-marker");
|
|
3037
3038
|
const content = graph.one(marker.entityId, "marker-content");
|
|
3038
|
-
|
|
3039
|
+
assertTrackContent(graph, typedRole, content);
|
|
3039
3040
|
const source = range(marker.payload.sourceRange, "sourceRange");
|
|
3040
3041
|
const durationFact = marker.payload.duration;
|
|
3041
3042
|
if (!object(durationFact)) fail(`Marker ${marker.entityId} requires duration`);
|
|
@@ -3154,6 +3155,32 @@ function resolveGraphLayout(graph) {
|
|
|
3154
3155
|
}))
|
|
3155
3156
|
};
|
|
3156
3157
|
}
|
|
3158
|
+
function assertTrackContent(graph, role, content) {
|
|
3159
|
+
if (role === "speech") {
|
|
3160
|
+
assertSpeechContent(graph, content);
|
|
3161
|
+
return;
|
|
3162
|
+
}
|
|
3163
|
+
if (!(role === "video_clip" ? ["image", "video"] : role === "caption" ? ["caption"] : ["audio"]).includes(content.entityKind)) fail(`unsupported compatibility content kind ${content.entityKind} on ${role} Track`);
|
|
3164
|
+
}
|
|
3165
|
+
function assertSpeechContent(graph, content) {
|
|
3166
|
+
const assetLinks = graph.rows.relations.filter((relation) => relation.relationKind === "from-asset" && (relation.endpoint0EntityId === content.entityId || relation.endpoint1EntityId === content.entityId));
|
|
3167
|
+
if (assetLinks.length !== 1 || assetLinks[0].endpoint0EntityId !== content.entityId) fail("Speech content requires one ordered from-asset binding");
|
|
3168
|
+
const asset = graph.entity(assetLinks[0].endpoint1EntityId, "asset");
|
|
3169
|
+
if (content.entityKind === "voiceover") {
|
|
3170
|
+
const renders = graph.rows.relations.filter((relation) => relation.relationKind === "phonetic-script-render" && (relation.endpoint0EntityId === content.entityId || relation.endpoint1EntityId === content.entityId));
|
|
3171
|
+
if (renders.length !== 1 || renders[0].endpoint0EntityId !== content.entityId || graph.entity(renders[0].endpoint1EntityId).entityKind !== "phonetic-script") fail("Synthesized Speech Voiceover requires one ordered PhoneticScript render");
|
|
3172
|
+
if (asset.payload.system !== "memota-speech") fail("Synthesized Speech Voiceover requires an explicit memota-speech key");
|
|
3173
|
+
return;
|
|
3174
|
+
}
|
|
3175
|
+
if (content.entityKind === "audio") {
|
|
3176
|
+
const sources = graph.rows.relations.filter((relation) => relation.relationKind === "audio-script-source" && (relation.endpoint0EntityId === content.entityId || relation.endpoint1EntityId === content.entityId));
|
|
3177
|
+
if (sources.length > 1) fail("Recorded speech has an ambiguous AudioScript source receipt");
|
|
3178
|
+
if (sources.length === 1 && (sources[0].endpoint1EntityId !== content.entityId || graph.entity(sources[0].endpoint0EntityId).entityKind !== "audio-script")) fail("Recorded Speech AudioScript source must use ordered endpoints");
|
|
3179
|
+
if (asset.payload.system !== "memota") fail("Recorded Speech Audio requires an explicit memota key");
|
|
3180
|
+
return;
|
|
3181
|
+
}
|
|
3182
|
+
fail(`unsupported compatibility content kind ${content.entityKind} on speech Track`);
|
|
3183
|
+
}
|
|
3157
3184
|
//#endregion
|
|
3158
3185
|
//#region src/document/entity-projection.ts
|
|
3159
3186
|
/**
|
|
@@ -3195,20 +3222,21 @@ function projectEntityTimeline(rows) {
|
|
|
3195
3222
|
} else if (track.role === "speech") {
|
|
3196
3223
|
const asset = mediaAssetFacts(graph, content);
|
|
3197
3224
|
requireUntrimmedAudio(content, marker, placement);
|
|
3198
|
-
const external = externalLocator(asset, "memota-speech");
|
|
3199
|
-
const renderEdges = graph.adjacent(content.entityId, "phonetic-script-render");
|
|
3200
3225
|
const timbreEdges = graph.adjacent(content.entityId, "voice-timbre");
|
|
3201
|
-
const
|
|
3226
|
+
const isSynthesized = content.entityKind === "voiceover";
|
|
3227
|
+
const external = externalLocator(asset, isSynthesized ? "memota-speech" : "memota");
|
|
3228
|
+
const assembled = isSynthesized ? assemblePhoneticScriptContent(rows, graph.one(content.entityId, "phonetic-script-render", "phonetic-script").entityId) : void 0;
|
|
3202
3229
|
if (timbreEdges.length > 1) fail("A voiceover resolves at most one Voice identity");
|
|
3203
3230
|
const voice = timbreEdges.length === 0 ? void 0 : graph.one(content.entityId, "voice-timbre", "voice").payload.voice;
|
|
3204
3231
|
if (voice !== void 0 && (!object(voice) || voice.system !== "voice-library" || typeof voice.key !== "string")) fail("Voice must use an explicit voice-library locator");
|
|
3205
3232
|
const captionIds = layout.tracks.flatMap((candidate) => candidate.role === "caption" ? candidate.clips.filter((caption) => caption.anchorClipEntityId === clip.entityId).map((caption) => caption.clipEntityId) : []);
|
|
3206
|
-
|
|
3233
|
+
const speech = {
|
|
3207
3234
|
id: clip.entityId,
|
|
3208
3235
|
kind: "speech",
|
|
3209
3236
|
media_duration_ms: placement.duration,
|
|
3210
3237
|
audio_storage_key: storageKey(asset),
|
|
3211
3238
|
origin_speech_id: external.key,
|
|
3239
|
+
origin_asset_system: external.system,
|
|
3212
3240
|
audio_script: assembled?.text ?? (graph.adjacent(content.entityId, "audio-script-source").length > 0 ? assembleScriptText(graph.one(content.entityId, "audio-script-source", "audio-script")) : ""),
|
|
3213
3241
|
volume: volume.data,
|
|
3214
3242
|
voice: object(voice) ? {
|
|
@@ -3216,7 +3244,8 @@ function projectEntityTimeline(rows) {
|
|
|
3216
3244
|
name: typeof voice.name === "string" ? voice.name : void 0
|
|
3217
3245
|
} : void 0,
|
|
3218
3246
|
caption_ids: captionIds
|
|
3219
|
-
}
|
|
3247
|
+
};
|
|
3248
|
+
parts[clip.entityId] = { speech };
|
|
3220
3249
|
} else if (track.role === "caption") {
|
|
3221
3250
|
const assembled = assembleCaptionContent(rows, content.entityId);
|
|
3222
3251
|
const text = assembled.text;
|
|
@@ -3296,7 +3325,10 @@ function storageKey(asset) {
|
|
|
3296
3325
|
function externalLocator(asset, system) {
|
|
3297
3326
|
const { system: found, key } = asset.payload;
|
|
3298
3327
|
if (found !== system || typeof key !== "string" || key.trim() === "") fail("Asset " + asset.entityId + " requires an explicit " + system + " key");
|
|
3299
|
-
return {
|
|
3328
|
+
return {
|
|
3329
|
+
key,
|
|
3330
|
+
system
|
|
3331
|
+
};
|
|
3300
3332
|
}
|
|
3301
3333
|
function captionStyle(value) {
|
|
3302
3334
|
if (value === void 0) return void 0;
|
|
@@ -3940,6 +3972,25 @@ var LoroEntityDocument = class LoroEntityDocument {
|
|
|
3940
3972
|
if (id === void 0) return [];
|
|
3941
3973
|
return this.snapshot().rows.relations.filter((row) => row.endpoint0EntityId === id || row.endpoint1EntityId === id);
|
|
3942
3974
|
}
|
|
3975
|
+
/** Read unlinked Relation records for durable effect receipts; never part of the current semantic graph. */
|
|
3976
|
+
tombstonedRelations() {
|
|
3977
|
+
const result = [];
|
|
3978
|
+
for (const key of section(this.doc, "relations").keys().sort((a, b) => a < b ? -1 : a > b ? 1 : 0)) {
|
|
3979
|
+
const map = section(this.doc, "relations").get(key);
|
|
3980
|
+
if (!(map instanceof LoroMap) || map.get("deleted") !== true) continue;
|
|
3981
|
+
const identity = map.get("identity");
|
|
3982
|
+
if (!identity || identity.endpoints.length !== 2) throw new Error(`Invalid tombstoned Relation ${key}`);
|
|
3983
|
+
result.push({
|
|
3984
|
+
relationId: createRelationId(key),
|
|
3985
|
+
relationKind: identity.kind,
|
|
3986
|
+
endpoint0EntityId: createEntityId(identity.endpoints[0]),
|
|
3987
|
+
endpoint1EntityId: createEntityId(identity.endpoints[1]),
|
|
3988
|
+
metadata: requireMap(map, "metadata").toJSON(),
|
|
3989
|
+
trace: requireMap(map, "trace").toJSON()
|
|
3990
|
+
});
|
|
3991
|
+
}
|
|
3992
|
+
return result;
|
|
3993
|
+
}
|
|
3943
3994
|
/** Resolve a queued edit target through its native identity without changing history. */
|
|
3944
3995
|
resolveCurrentEntityId(id) {
|
|
3945
3996
|
return currentId(this.doc, id);
|
|
@@ -4727,4 +4778,4 @@ function createPlainMemoryAdapter(document, options) {
|
|
|
4727
4778
|
return new PlainMemoryAdapter(document, options);
|
|
4728
4779
|
}
|
|
4729
4780
|
//#endregion
|
|
4730
|
-
export {
|
|
4781
|
+
export { validateVideoDocument as $, EntityTimelineProjectionError as A, variantBaseEntityIds as B, equalJson as C, partUnionToDraft as Ct, projectEntityTimeline as D, bytesToBase64 as Dt, resolveFieldPath as E, base64ToBytes as Et, assemblePhoneticScriptContent as F, isMediaAssetVariantKind as G, createEntityId as H, assembleScriptText as I, derivePositionFromAbs as J, buildInitialVideoDocument as K, findComposedAudioScript as L, ScriptCompositionError as M, assembleCaptionContent as N, EntityProjectionGraph as O, assembleEntityContent as P, assertValidVideoDocument as Q, selectAudioScriptSegment as R, canonicalJson as S, speedOf as St, assertFieldChanges as T, videoDocumentMirrorSchema as Tt, createRelationId as U, isJsonObject as V, hasSequence as W, toVideoDocument as X, fromVideoDocument as Y, VideoDocumentValidationError as Z, audioScriptAssetOf as _, isEmptyVideoClip as _t, createMirrorVideoDocument as a, hasResolvedPlacement as at, phoneticScriptAssetOf as b, DEFAULT_UNIT_TIME_MS as bt, DocumentMutationGuard as c, cascadeAfterVideoClipChanges as ct, LoroEntityDraft as d, reassignSpeechesToVideoClipsByTime as dt, partUnionSchema as et, readEntityDocument as f, recalculateTimelineDuration as ft, audioScriptAssetHash as g, TIMELINE_SKELETON_DURATION_MS as gt, audioScriptAssetFields as h, syncAggregatedClipsTimePosition as ht, MirrorVideoDocumentAdapter as i, findLaneTrack as it, decodeEntityRelationRows as j, resolveEntityTimelineLayout as k, LORO_ENTITY_SCHEMA as l, arrangeMainTrackSeamlessly as lt, audioScriptAssetContent as m, resolveSpeechOverlapByShiftingVideos as mt, createPlainMemoryAdapter as n, LANE_KINDS_IN_STACK_ORDER as nt, createMirrorVideoDocumentAdapter as o, laneTrackId as ot, entityOrderGroups as p, resolveAllSpeechOverlaps as pt, buildSpeechHostMap as q, generatePartId as r, ensureLaneTrack as rt, readVideoDocumentFromDraft as s, solveVideoDocument as st, PlainMemoryAdapter as t, videoDocumentSchema as tt, LoroEntityDocument as u, fillMainTrackTimeGaps as ut, phoneticScriptAssetContent as v, partDurationMs as vt, applyFieldChanges as w, recordEntries as wt, scriptSourceAssetOf as x, effectiveVideoClipDurationMs as xt, phoneticScriptAssetHash as y, safeDurationMs as yt, updateEntityFields as z };
|
|
@@ -473,6 +473,8 @@ type VideoClipPart = Omit<VideoClipPart$1, 'duration_ms'>;
|
|
|
473
473
|
type SpeechPart = Omit<SpeechPart$1, 'duration_ms'> & {
|
|
474
474
|
media_duration_ms?: number | undefined;
|
|
475
475
|
};
|
|
476
|
+
/** Asset namespace exposed only by the legacy read view; never an authoritative Speech fact. */
|
|
477
|
+
type SpeechOriginAssetSystem = 'memota' | 'memota-speech';
|
|
476
478
|
/**
|
|
477
479
|
* Authoritative caption part. The IDL `CaptionPart` carries `duration_ms` (the
|
|
478
480
|
* effective display length, a derived read-view value); the authoritative store
|
|
@@ -621,7 +623,8 @@ type VideoDraftPartUnion = {
|
|
|
621
623
|
} | {
|
|
622
624
|
video_clip?: never;
|
|
623
625
|
speech: SpeechPart & {
|
|
624
|
-
duration_ms?: number;
|
|
626
|
+
duration_ms?: number; /** Absent only on historical drafts created before this read-view discriminator. */
|
|
627
|
+
origin_asset_system?: SpeechOriginAssetSystem;
|
|
625
628
|
};
|
|
626
629
|
caption?: never;
|
|
627
630
|
bgm?: never;
|
|
@@ -669,6 +672,7 @@ type VideoDraftContentPartUnion = {
|
|
|
669
672
|
video_clip?: never;
|
|
670
673
|
speech: SpeechPart & {
|
|
671
674
|
duration_ms: number | undefined;
|
|
675
|
+
origin_asset_system?: SpeechOriginAssetSystem;
|
|
672
676
|
};
|
|
673
677
|
caption?: never;
|
|
674
678
|
bgm?: never;
|
|
@@ -1143,12 +1147,26 @@ declare class EntityTimelineProjectionError extends Error {
|
|
|
1143
1147
|
}
|
|
1144
1148
|
//#endregion
|
|
1145
1149
|
//#region src/document/entity-projection.d.ts
|
|
1150
|
+
type EntityTimelineProjectionPart = Exclude<PartUnion, {
|
|
1151
|
+
speech: SpeechPart;
|
|
1152
|
+
}> | {
|
|
1153
|
+
video_clip?: never;
|
|
1154
|
+
speech: SpeechPart & {
|
|
1155
|
+
origin_asset_system: SpeechOriginAssetSystem;
|
|
1156
|
+
};
|
|
1157
|
+
caption?: never;
|
|
1158
|
+
bgm?: never;
|
|
1159
|
+
};
|
|
1160
|
+
/** Ephemeral compatibility document; the origin discriminator is never stored in Loro. */
|
|
1161
|
+
type EntityTimelineProjectionDocument = Omit<VideoDocument, 'part_library'> & {
|
|
1162
|
+
part_library: Record<string, EntityTimelineProjectionPart>;
|
|
1163
|
+
};
|
|
1146
1164
|
/**
|
|
1147
1165
|
* One-way compatibility view over the Entity graph. A legacy part is never
|
|
1148
1166
|
* consulted as an editing fact. Peer IDs appear only in this derived read
|
|
1149
1167
|
* contract, reconstructed from relations; they are not stored in payloads.
|
|
1150
1168
|
*/
|
|
1151
|
-
declare function projectEntityTimeline(rows: EntityRelationRows):
|
|
1169
|
+
declare function projectEntityTimeline(rows: EntityRelationRows): EntityTimelineProjectionDocument;
|
|
1152
1170
|
//#endregion
|
|
1153
1171
|
//#region src/document/entity-timeline-layout.d.ts
|
|
1154
1172
|
type EntityTimelineTrackRole = 'video_clip' | 'speech' | 'caption' | 'bgm';
|
|
@@ -1870,4 +1888,4 @@ declare const videoDocumentSchema: z.ZodObject<{
|
|
|
1870
1888
|
}, z.core.$loose>]>>>;
|
|
1871
1889
|
}, z.core.$loose>;
|
|
1872
1890
|
//#endregion
|
|
1873
|
-
export {
|
|
1891
|
+
export { DerivedItemPosition as $, assertValidVideoDocument as A, VideoDocument as At, EntityRelationRows as B, CaptionStyle as Bt, isImplementedSemanticOpKind as C, SpeechOriginAssetSystem as Ct, PartIdFactory as D, TrackItem as Dt, ValidationError as E, Track as Et, ResolvedEntityTrack as F, VideoDraftPartUnion as Ft, ScriptTextSegment as G, TrackItem$1 as Gt, RelationRow as H, SpeedShift as Ht, resolveEntityTimelineLayout as I, effectiveVideoClipDurationMs as It, VoiceDescriptor as J, SequenceDuration as K, EntityTimelineProjectionDocument as L, speedOf as Lt, EntityTimelineTrackRole as M, VideoDocumentValidationIssueCode as Mt, ResolvedEntityClipPlacement as N, VideoDraft as Nt, generatePartId as O, TrackItemTimePosition as Ot, ResolvedEntityTimelineLayout as P, VideoDraftContent as Pt, buildInitialVideoDocument as Q, projectEntityTimeline as R, Attachment as Rt, SemanticOpKind as S, PartUnion as St, SnapshotReadable as T, Timeline as Tt, CaptionSegmentSelection as U, Timeline$1 as Ut, EntityRow as V, PartAggregation as Vt, CaptionStyleFields as W, Track$1 as Wt, JsonValue as X, JsonObject as Y, EntityId as Z, SemanticOpName as _, BgmPart as _t, PlainMemoryAdapter as a, LANE_KINDS_IN_STACK_ORDER as at, ImplementedSemanticOpKind as b, DEFAULT_UNIT_TIME_MS as bt, MirrorVideoDocumentAdapter as c, ensureLaneTrack as ct, createMirrorVideoDocumentAdapter as d, solveVideoDocument as dt, SpeechHostMap as et, CommitOptions as f, TrackDraft as ft, SemanticOpInput as g, videoDocumentMirrorSchema as gt, SemanticEditor as h, VideoDocumentMirrorSchema as ht, JournalEntry as i, toVideoDocument as it, validateVideoDocument as j, VideoDocumentValidationIssue as jt, VideoDocumentValidationError as k, VideoClipPart as kt, MirrorVideoDocumentOptions as l, findLaneTrack as lt, SemanticDocumentAdapter as m, VideoDocumentDraft as mt, videoDocumentSchema as n, derivePositionFromAbs as nt, PlainMemoryAdapterOptions as o, LaneKind as ot, OpActor as p, TrackItemDraft as pt, SequenceRange as q, readVideoDocumentFromDraft as r, fromVideoDocument as rt, createPlainMemoryAdapter as s, SolvedVideoDocument as st, partUnionSchema as t, buildSpeechHostMap as tt, createMirrorVideoDocument as u, laneTrackId as ut, TransactAudit as v, CaptionDisplayCue as vt, SchemaValidator as w, SpeechPart as wt, PlannedSemanticOpKind as x, PartKind as xt, IMPLEMENTED_SEMANTIC_OP_KINDS as y, CaptionPart as yt, EntityTimelineProjectionError as z, CaptionPart$1 as zt };
|