@mengine/medeo-client 1.3.1-alpha.8 → 1.3.1-alpha.9
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/index.d.ts +22 -7
- package/dist/index.js +57 -17
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -221,13 +221,12 @@ declare function selectAudioScriptSegments(script: EntityRow<'audio-script'>, se
|
|
|
221
221
|
//#region src/entity-editor/entity-graph-http-client.d.ts
|
|
222
222
|
/** One authenticated revision of the authoritative Medeo Entity graph. */
|
|
223
223
|
interface EntityGraphState {
|
|
224
|
-
|
|
224
|
+
/** Fixed identity of the project's one AudioScript; present in every readable state. */
|
|
225
|
+
readonly audioScriptEntityId: string;
|
|
225
226
|
readonly revision: number;
|
|
226
227
|
readonly rows: EntityRelationRows;
|
|
227
228
|
}
|
|
228
229
|
interface EntityGraphCommitOptions {
|
|
229
|
-
/** Omitted preserves the baseline association; null explicitly clears it. */
|
|
230
|
-
readonly audioScriptEntityId?: string | null;
|
|
231
230
|
/** Server version vector proving the explicit legacy-to-Entity migration baseline. */
|
|
232
231
|
readonly migrationBaseVv?: string;
|
|
233
232
|
}
|
|
@@ -245,7 +244,7 @@ declare class EntityGraphHttpClient {
|
|
|
245
244
|
* transient create-then-remove never becomes a request to delete unknown
|
|
246
245
|
* persisted data.
|
|
247
246
|
*/
|
|
248
|
-
commit(baseState: EntityGraphState, nextRows: EntityRelationRows, options?: EntityGraphCommitOptions): Promise<EntityGraphState>;
|
|
247
|
+
commit(baseState: Pick<EntityGraphState, 'revision' | 'rows'>, nextRows: EntityRelationRows, options?: EntityGraphCommitOptions): Promise<EntityGraphState>;
|
|
249
248
|
private request;
|
|
250
249
|
}
|
|
251
250
|
//#endregion
|
|
@@ -590,6 +589,8 @@ interface EditorFoundation {
|
|
|
590
589
|
readonly rows: EntityRelationRows;
|
|
591
590
|
readonly timelineEntityId: string;
|
|
592
591
|
readonly trackEntityIds: Readonly<Record<EditorTrackRole, string>>;
|
|
592
|
+
/** Fixed identity of the project's one AudioScript, minted here when missing. */
|
|
593
|
+
readonly audioScriptEntityId: string;
|
|
593
594
|
}
|
|
594
595
|
/**
|
|
595
596
|
* MEngine editor policy, not a cardinality restriction on the general-purpose DSL.
|
|
@@ -661,8 +662,22 @@ interface DocumentAudioScript {
|
|
|
661
662
|
readonly entityId: string;
|
|
662
663
|
readonly segments: readonly (ScriptTextSegment & Readonly<Record<string, unknown>>)[];
|
|
663
664
|
}
|
|
664
|
-
/**
|
|
665
|
-
|
|
665
|
+
/** Any state that carries the fixed document AudioScript identity outlet. */
|
|
666
|
+
interface DocumentAudioScriptState {
|
|
667
|
+
readonly rows: EntityRelationRows;
|
|
668
|
+
/**
|
|
669
|
+
* Fixed identity minted atomically at project initialization. `null` is only
|
|
670
|
+
* the internal revision-0 "not yet initialized" representation; normal
|
|
671
|
+
* projects never carry the legacy null association.
|
|
672
|
+
*/
|
|
673
|
+
readonly audioScriptEntityId: string | null;
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* Strict read of the project's one fixed AudioScript. The identity is immutable
|
|
677
|
+
* for the project's lifetime; this never selects, clears, or switches a
|
|
678
|
+
* script. Uninitialized or dangling identities are projection errors.
|
|
679
|
+
*/
|
|
680
|
+
declare function readDocumentAudioScript(state: DocumentAudioScriptState): DocumentAudioScript;
|
|
666
681
|
//#endregion
|
|
667
682
|
//#region src/editor/journal.d.ts
|
|
668
683
|
/**
|
|
@@ -1568,4 +1583,4 @@ declare function hostForAbsMs(ranges: MainClipRange[], absMs: number): MainClipR
|
|
|
1568
1583
|
*/
|
|
1569
1584
|
declare function relativePositionForAbs(ranges: MainClipRange[], absMs: number): TrackItemTimePosition;
|
|
1570
1585
|
//#endregion
|
|
1571
|
-
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, ENTITY_TIMELINE_PROJECTION_SCHEMA_VERSION, type EditorFoundation, type EntityGraphCommitOptions, EntityGraphHttpClient, type EntityGraphState, EntityTimelineEditor, type EntityTimelineIdFactory, EntityTimelineProjectionError, type EntityTimelineTrackRole, 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, type LaneKind, type LinearClipSpeed, 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, applyEntityTimelineProjection, arrangeMainTrackSeamlessly, assembleCaptionContent, assembleEntityContent, assemblePhoneticScriptContent, assembleScriptText, assertCanonicalEditorResources, assertEntityProjectionPreservesLegacy, assertMediaAssetWritePolicy, assertValidVideoDocument, base64ToBytes, buildInitialVideoDocument, buildSpeechHostMap, bytesToBase64, cascadeAfterVideoClipChanges, 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, readMainTrackItems, readMengineEventStream, readPart, readPartDurationMs, readVideoDocumentFromDraft, reassignSpeechesToVideoClipsByTime, recalculateTimelineDuration, relativePositionForAbs, replayJournal, resolveAllSpeechOverlaps, resolveEntityTimelineLayout, resolveSpeechOverlapByShiftingVideos, safeDurationMs, index_d_exports as schemas, selectAudioScriptSegments, snapshotToPlain, solveVideoDocument, speedOf, syncAggregatedClipsTimePosition, toVideoDocument, validateVideoDocument, videoDocumentMirrorSchema, videoDocumentSchema, writeVideoDocumentToDraft };
|
|
1586
|
+
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, type EntityGraphCommitOptions, EntityGraphHttpClient, type EntityGraphState, EntityTimelineEditor, type EntityTimelineIdFactory, EntityTimelineProjectionError, type EntityTimelineTrackRole, 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, type LaneKind, type LinearClipSpeed, 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, applyEntityTimelineProjection, arrangeMainTrackSeamlessly, assembleCaptionContent, assembleEntityContent, assemblePhoneticScriptContent, assembleScriptText, assertCanonicalEditorResources, assertEntityProjectionPreservesLegacy, assertMediaAssetWritePolicy, assertValidVideoDocument, base64ToBytes, buildInitialVideoDocument, buildSpeechHostMap, bytesToBase64, cascadeAfterVideoClipChanges, 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, readMainTrackItems, readMengineEventStream, readPart, readPartDurationMs, readVideoDocumentFromDraft, reassignSpeechesToVideoClipsByTime, recalculateTimelineDuration, relativePositionForAbs, replayJournal, resolveAllSpeechOverlaps, resolveEntityTimelineLayout, resolveSpeechOverlapByShiftingVideos, safeDurationMs, index_d_exports as schemas, selectAudioScriptSegments, snapshotToPlain, solveVideoDocument, speedOf, syncAggregatedClipsTimePosition, toVideoDocument, validateVideoDocument, videoDocumentMirrorSchema, videoDocumentSchema, writeVideoDocumentToDraft };
|
package/dist/index.js
CHANGED
|
@@ -218,13 +218,18 @@ function findSseFrameBoundary(buffer) {
|
|
|
218
218
|
}
|
|
219
219
|
//#endregion
|
|
220
220
|
//#region src/entity-editor/document-audio-script.ts
|
|
221
|
-
/**
|
|
221
|
+
/**
|
|
222
|
+
* Strict read of the project's one fixed AudioScript. The identity is immutable
|
|
223
|
+
* for the project's lifetime; this never selects, clears, or switches a
|
|
224
|
+
* script. Uninitialized or dangling identities are projection errors.
|
|
225
|
+
*/
|
|
222
226
|
function readDocumentAudioScript(state) {
|
|
223
227
|
const id = state.audioScriptEntityId;
|
|
224
|
-
if (id === null)
|
|
225
|
-
if (typeof id !== "string" || id.trim() !== id || !id) throw new EntityTimelineProjectionError("Invalid document AudioScript
|
|
228
|
+
if (id === null) throw new EntityTimelineProjectionError("Document AudioScript is not initialized");
|
|
229
|
+
if (typeof id !== "string" || id.trim() !== id || !id) throw new EntityTimelineProjectionError("Invalid document AudioScript identity");
|
|
230
|
+
if (state.rows.entities.filter((row) => row.entityKind === "audio-script").length !== 1) throw new EntityTimelineProjectionError("Editor requires exactly one AudioScript");
|
|
226
231
|
const entity = state.rows.entities.find((row) => row.entityId === id);
|
|
227
|
-
if (!entity || entity.entityKind !== "audio-script") throw new EntityTimelineProjectionError(`Document AudioScript ${id} must name
|
|
232
|
+
if (!entity || entity.entityKind !== "audio-script") throw new EntityTimelineProjectionError(`Document AudioScript ${id} must name the project AudioScript`);
|
|
228
233
|
const content = assembleEntityContent(state.rows, createEntityId(id));
|
|
229
234
|
assembleScriptText(content);
|
|
230
235
|
return {
|
|
@@ -251,6 +256,7 @@ const roleOrder$1 = {
|
|
|
251
256
|
*/
|
|
252
257
|
function assertCanonicalEditorResources(rows) {
|
|
253
258
|
if (rows.entities.filter((row) => row.entityKind === "timeline").length > 1) throw new EntityTimelineProjectionError("Editor requires exactly one Timeline");
|
|
259
|
+
if (rows.entities.filter((row) => row.entityKind === "audio-script").length !== 1) throw new EntityTimelineProjectionError("Editor requires exactly one AudioScript");
|
|
254
260
|
for (const role of Object.keys(roleOrder$1)) if (rows.entities.filter((row) => row.entityKind === "track" && row.payload.role === role).length > 1) throw new EntityTimelineProjectionError(`Editor has multiple ${role} Tracks`);
|
|
255
261
|
const identityByAssetKey = /* @__PURE__ */ new Map();
|
|
256
262
|
const kinds = new Map(rows.entities.map((row) => [String(row.entityId), row.entityKind]));
|
|
@@ -312,6 +318,26 @@ function memotaLocator(value) {
|
|
|
312
318
|
key: value.key
|
|
313
319
|
};
|
|
314
320
|
}
|
|
321
|
+
/**
|
|
322
|
+
* The project AudioScript is a fixed structure identity, like the Timeline: at
|
|
323
|
+
* most one may exist, and a missing one is minted atomically with empty
|
|
324
|
+
* segments. Project initialization and legacy migration share this single
|
|
325
|
+
* path, so both produce the same canonical structure.
|
|
326
|
+
*/
|
|
327
|
+
function ensureDocumentAudioScript(entities, idFactory) {
|
|
328
|
+
const scripts = entities.filter((row) => row.entityKind === "audio-script");
|
|
329
|
+
if (scripts.length > 1) throw new EntityTimelineProjectionError("Editor requires exactly one AudioScript");
|
|
330
|
+
const existing = scripts[0];
|
|
331
|
+
if (existing !== void 0) return existing.entityId;
|
|
332
|
+
const id = createEntityId(idFactory("entity"));
|
|
333
|
+
if (entities.some((row) => row.entityId === id)) throw new Error(`Duplicate entity id ${id}`);
|
|
334
|
+
entities.push({
|
|
335
|
+
entityId: id,
|
|
336
|
+
entityKind: "audio-script",
|
|
337
|
+
payload: { segments: [] }
|
|
338
|
+
});
|
|
339
|
+
return id;
|
|
340
|
+
}
|
|
315
341
|
/** Add only missing editor structure; existing identities and owned settings are never replaced. */
|
|
316
342
|
function ensureEditorFoundation(initial, idFactory = (prefix) => `${prefix}_${globalThis.crypto.randomUUID()}`, timelinePayload = {}) {
|
|
317
343
|
const entities = structuredClone([...initial.entities]);
|
|
@@ -364,13 +390,15 @@ function ensureEditorFoundation(initial, idFactory = (prefix) => `${prefix}_${gl
|
|
|
364
390
|
}
|
|
365
391
|
trackEntityIds[role] = track.entityId;
|
|
366
392
|
}
|
|
393
|
+
const audioScriptEntityId = ensureDocumentAudioScript(entities, idFactory);
|
|
367
394
|
return {
|
|
368
395
|
rows: {
|
|
369
396
|
entities,
|
|
370
397
|
relations
|
|
371
398
|
},
|
|
372
399
|
timelineEntityId: timeline.entityId,
|
|
373
|
-
trackEntityIds
|
|
400
|
+
trackEntityIds,
|
|
401
|
+
audioScriptEntityId
|
|
374
402
|
};
|
|
375
403
|
}
|
|
376
404
|
//#endregion
|
|
@@ -406,10 +434,11 @@ var EntityGraphHttpClient = class {
|
|
|
406
434
|
const baseRows = cloneAndValidateRows(baseState.rows);
|
|
407
435
|
const next = cloneAndValidateRows(nextRows);
|
|
408
436
|
assertMediaAssetWritePolicy(baseRows, next);
|
|
409
|
-
const
|
|
437
|
+
const scriptRows = next.entities.filter((row) => row.entityKind === "audio-script");
|
|
438
|
+
if (scriptRows.length !== 1) throw new EntityTimelineProjectionError("Editor requires exactly one AudioScript");
|
|
410
439
|
readDocumentAudioScript({
|
|
411
440
|
rows: next,
|
|
412
|
-
audioScriptEntityId
|
|
441
|
+
audioScriptEntityId: scriptRows[0].entityId
|
|
413
442
|
});
|
|
414
443
|
const nextEntityIds = new Set(next.entities.map((row) => row.entityId));
|
|
415
444
|
const nextRelationIds = new Set(next.relations.map((row) => row.relationId));
|
|
@@ -419,7 +448,6 @@ var EntityGraphHttpClient = class {
|
|
|
419
448
|
method: "POST",
|
|
420
449
|
body: JSON.stringify({
|
|
421
450
|
expected_revision: baseState.revision,
|
|
422
|
-
audio_script_entity_id: audioScriptEntityId,
|
|
423
451
|
rows: toWireRows(next),
|
|
424
452
|
deleted_entity_ids: deletedEntityIds,
|
|
425
453
|
deleted_relation_ids: deletedRelationIds,
|
|
@@ -442,12 +470,11 @@ function parseWireState(value, expectedDocId) {
|
|
|
442
470
|
if (value.doc_id !== expectedDocId) throw new Error(`Entity-state response doc_id mismatch: expected "${expectedDocId}"`);
|
|
443
471
|
const rows = parseWireRows(value.rows);
|
|
444
472
|
decodeEntityRelationRows(rows, numericMarkerValidation$1);
|
|
445
|
-
|
|
446
|
-
if (audioScriptEntityId !== null && typeof audioScriptEntityId !== "string") throw new Error("Invalid document AudioScript association");
|
|
473
|
+
if (typeof value.audio_script_entity_id !== "string") throw new Error("Document AudioScript is not initialized");
|
|
447
474
|
const state = {
|
|
448
475
|
revision: value.revision,
|
|
449
476
|
rows,
|
|
450
|
-
audioScriptEntityId
|
|
477
|
+
audioScriptEntityId: value.audio_script_entity_id
|
|
451
478
|
};
|
|
452
479
|
readDocumentAudioScript(state);
|
|
453
480
|
return state;
|
|
@@ -1961,6 +1988,7 @@ function migrateLegacyTimelineToEntities(legacy, assetFacts, initial = {
|
|
|
1961
1988
|
const normalizedMainRanges = overlapNormalizedMainRanges(legacy);
|
|
1962
1989
|
let entities = structuredClone([...initial.entities]);
|
|
1963
1990
|
let relations = structuredClone([...initial.relations]);
|
|
1991
|
+
const documentAudioScriptEntityId = ensureDocumentAudioScript(entities, idFactory);
|
|
1964
1992
|
const addEntity = (kind, payload, existingId) => {
|
|
1965
1993
|
const entityId = createEntityId(existingId ?? idFactory("entity"));
|
|
1966
1994
|
if (entities.some((row) => row.entityId === entityId)) fail(`Migration entity identity collision: ${entityId}`);
|
|
@@ -2023,7 +2051,7 @@ function migrateLegacyTimelineToEntities(legacy, assetFacts, initial = {
|
|
|
2023
2051
|
relations = [...imported.rows.relations];
|
|
2024
2052
|
contentByPartId.set(item.part_id, imported.contentEntityId);
|
|
2025
2053
|
const phonemeScript = speech.phoneme_script;
|
|
2026
|
-
ensureSpeechPhoneticChain(imported.contentEntityId, speech.audio_script, typeof phonemeScript === "string" ? phonemeScript : void 0, entities, relations, addEntity, link);
|
|
2054
|
+
ensureSpeechPhoneticChain(imported.contentEntityId, speech.audio_script, typeof phonemeScript === "string" ? phonemeScript : void 0, entities, relations, addEntity, link, documentAudioScriptEntityId);
|
|
2027
2055
|
} else if (part.bgm !== void 0) {
|
|
2028
2056
|
const bgm = part.bgm;
|
|
2029
2057
|
const fact = facts.get(bgm.origin_media_id);
|
|
@@ -2469,7 +2497,7 @@ function requirePart(document, partId) {
|
|
|
2469
2497
|
if (part === void 0) fail(`Placed Clip ${partId} has no part payload`);
|
|
2470
2498
|
return part;
|
|
2471
2499
|
}
|
|
2472
|
-
function ensureSpeechPhoneticChain(voiceEntityId, audioScriptText, phonemeScript, entities, relations, addEntity, link) {
|
|
2500
|
+
function ensureSpeechPhoneticChain(voiceEntityId, audioScriptText, phonemeScript, entities, relations, addEntity, link, documentAudioScriptEntityId) {
|
|
2473
2501
|
const renders = relations.filter((relation) => relation.relationKind === "phonetic-script-render" && relation.endpoint0EntityId === voiceEntityId);
|
|
2474
2502
|
if (renders.length > 1) fail(`Voice ${voiceEntityId} has ambiguous PhoneticScript provenance`);
|
|
2475
2503
|
if (renders.length === 1) {
|
|
@@ -2479,11 +2507,23 @@ function ensureSpeechPhoneticChain(voiceEntityId, audioScriptText, phonemeScript
|
|
|
2479
2507
|
if (script === void 0 || scriptText(script) !== audioScriptText) fail(`Voice ${voiceEntityId} conflicts with the legacy Speech script`);
|
|
2480
2508
|
return phonetic.entityId;
|
|
2481
2509
|
}
|
|
2510
|
+
const script = entities.find((entity) => entity.entityId === documentAudioScriptEntityId);
|
|
2511
|
+
if (script === void 0 || script.entityKind !== "audio-script") fail("Migration must carry the fixed document AudioScript");
|
|
2512
|
+
const segments = script.payload.segments;
|
|
2513
|
+
if (Array.isArray(segments) && segments.length > 0) {
|
|
2514
|
+
if (scriptText(script) !== audioScriptText) fail(`Voice ${voiceEntityId} conflicts with the project AudioScript text`);
|
|
2515
|
+
} else {
|
|
2516
|
+
const scriptIndex = entities.findIndex((row) => row.entityId === script.entityId);
|
|
2517
|
+
entities[scriptIndex] = {
|
|
2518
|
+
...script,
|
|
2519
|
+
payload: { segments: [{
|
|
2520
|
+
segmentId: "segment-0",
|
|
2521
|
+
text: audioScriptText
|
|
2522
|
+
}] }
|
|
2523
|
+
};
|
|
2524
|
+
}
|
|
2482
2525
|
const phonetic = addEntity("phonetic-script", {
|
|
2483
|
-
baseEntityIds: [
|
|
2484
|
-
segmentId: "segment-0",
|
|
2485
|
-
text: audioScriptText
|
|
2486
|
-
}] })],
|
|
2526
|
+
baseEntityIds: [script.entityId],
|
|
2487
2527
|
...phonemeScript === void 0 ? {} : { phonemeScript }
|
|
2488
2528
|
});
|
|
2489
2529
|
link("phonetic-script-render", voiceEntityId, phonetic);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mengine/medeo-client",
|
|
3
|
-
"version": "1.3.1-alpha.
|
|
3
|
+
"version": "1.3.1-alpha.9",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -27,9 +27,9 @@
|
|
|
27
27
|
"immer": "^10.2.0",
|
|
28
28
|
"loro-mirror": "^2.2.0",
|
|
29
29
|
"zod": "^4.4.3",
|
|
30
|
-
"@mengine/storage": "1.3.1-alpha.
|
|
31
|
-
"@mengine/sync": "1.3.1-alpha.
|
|
32
|
-
"@mengine/utils": "1.3.1-alpha.
|
|
30
|
+
"@mengine/storage": "1.3.1-alpha.9",
|
|
31
|
+
"@mengine/sync": "1.3.1-alpha.9",
|
|
32
|
+
"@mengine/utils": "1.3.1-alpha.9"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@types/node": "^25.9.1",
|