@mengine/medeo-tool 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.
@@ -139,6 +139,7 @@ interface SandboxRelation {
139
139
  }
140
140
  interface EntityStoreSnapshot {
141
141
  revision: number;
142
+ /** Fixed identity outlet of the project's one AudioScript; null only before initialization (revision 0). */
142
143
  audioScriptEntityId: string | null;
143
144
  entities: SandboxEntity[];
144
145
  relations: SandboxRelation[];
@@ -206,9 +207,6 @@ interface UnlinkRelationInput {
206
207
  relation_id: string;
207
208
  }
208
209
  type EntityCommand = {
209
- kind: 'set-document-audio-script';
210
- audioScriptEntityId: string | null;
211
- } | {
212
210
  kind: 'create-entity';
213
211
  entity: SandboxEntity;
214
212
  } | {
@@ -273,4 +271,4 @@ interface RelationFacade {
273
271
  }
274
272
  //#endregion
275
273
  export { SandboxEntity as _, EntityFacade as a, UpdateEntityInput as b, JsonObject as c, KnownEntityKind as d, KnownRelationKind as f, ResourceEntityKind as g, RelationFacade as h, EntityCommand as i, JsonPrimitive as l, LinkRelationInput as m, CreateEntityInput as n, EntityPlanState as o, LinkGeneratedRelationInput as p, DeleteEntityInput as r, EntityStoreSnapshot as s, AuthorableRelationKind as t, JsonValue as u, SandboxRelation as v, UnlinkRelationInput as y };
276
- //# sourceMappingURL=entity-contract-Dm3AMEC9.d.mts.map
274
+ //# sourceMappingURL=entity-contract-SQdOaLm-.d.mts.map
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { _ as SandboxEntity, a as EntityFacade, b as UpdateEntityInput, c as JsonObject, d as KnownEntityKind, f as KnownRelationKind, g as ResourceEntityKind, h as RelationFacade, i as EntityCommand, l as JsonPrimitive, m as LinkRelationInput, n as CreateEntityInput, o as EntityPlanState, p as LinkGeneratedRelationInput, r as DeleteEntityInput, s as EntityStoreSnapshot, t as AuthorableRelationKind, u as JsonValue, v as SandboxRelation, y as UnlinkRelationInput } from "./entity-contract-Dm3AMEC9.mjs";
1
+ import { _ as SandboxEntity, a as EntityFacade, b as UpdateEntityInput, c as JsonObject, d as KnownEntityKind, f as KnownRelationKind, g as ResourceEntityKind, h as RelationFacade, i as EntityCommand, l as JsonPrimitive, m as LinkRelationInput, n as CreateEntityInput, o as EntityPlanState, p as LinkGeneratedRelationInput, r as DeleteEntityInput, s as EntityStoreSnapshot, t as AuthorableRelationKind, u as JsonValue, v as SandboxRelation, y as UnlinkRelationInput } from "./entity-contract-SQdOaLm-.mjs";
2
2
  import { JournalEntry, ManualSyncDoc, MediaAssetFact, PartIdFactory, SemanticOpName, VideoDocument, VideoDraft, fromVideoDocument } from "@mengine/medeo-client";
3
3
  import { AddSpeechesInput, AddVideoClipsInput, AdjustBgmVolumeInput, AdjustSpeechVolumeInput, AdjustVideoClipDurationInput, AdjustVideoClipVolumeInput, ChangeSpeechScriptInput, ChangeSpeechVoiceInput, DeleteBgmInput, DeleteSpeechesInput, DeleteVideoClipsInput, MoveSpeechesInput, MoveVideoClipsByAnchorInput, MoveVideoClipsInput, ReplaceVideoClipContentInput, ReplaceVideoClipSequenceInput, SetBgmInput, SetCaptionStyleInput, SetCaptionVisibilityInput, SetVideoClipSpeedShiftInput } from "@mengine/medeo-client/schemas";
4
4
 
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { c as renderPreview, l as renderCompactProjection, n as EntitySandbox, o as isMediaAssetVariantKind, r as toDslRows, s as collectAffectedPartIds, t as EditSandboxSession } from "./script-session-C2uQHYt4.mjs";
1
+ import { c as renderPreview, l as renderCompactProjection, n as EntitySandbox, o as isMediaAssetVariantKind, r as toDslRows, s as collectAffectedPartIds, t as EditSandboxSession } from "./script-session-B2UQ1W_y.mjs";
2
2
  import { EntityGraphHttpClient, ManualSyncDoc, MengineHttpClient, MengineHttpRequestError, ValidationError, createMirrorVideoDocument, createPlainMemoryAdapter, decodeDocVersionMark, encodeDocVersionMark, migrateLegacyTimelineToEntities, replayJournal, toVideoDocument } from "@mengine/medeo-client";
3
3
  import { Worker } from "node:worker_threads";
4
4
  import { randomUUID } from "node:crypto";
@@ -242,7 +242,6 @@ var EntityHttpClient = class {
242
242
  method: "POST",
243
243
  body: JSON.stringify({
244
244
  expected_revision: expectedRevision,
245
- audio_script_entity_id: state.audioScriptEntityId,
246
245
  rows: {
247
246
  entities: state.entities,
248
247
  relations: state.relations
@@ -280,9 +279,11 @@ function toSnapshot(value, expectedDocId) {
280
279
  if (!isRecord$2(value) || typeof value.doc_id !== "string" || !isNonNegativeInteger(value.revision)) throw new Error("invalid entity-state response envelope");
281
280
  if (value.doc_id !== expectedDocId) throw new Error(`entity-state response doc_id mismatch: expected "${expectedDocId}"`);
282
281
  if (!isRecord$2(value.rows) || !Array.isArray(value.rows.entities) || !Array.isArray(value.rows.relations)) throw new Error("invalid entity-state response rows");
283
- if (value.audio_script_entity_id !== null && !isTrimmed(value.audio_script_entity_id)) throw new Error("invalid document AudioScript association");
282
+ if (value.audio_script_entity_id === null) {
283
+ if (value.revision !== 0) throw new Error("Document AudioScript is not initialized");
284
+ } else if (!isTrimmed(value.audio_script_entity_id)) throw new Error("invalid document AudioScript identity");
284
285
  const response = value;
285
- if (response.audio_script_entity_id !== null && !response.rows.entities.some((entity) => entity.entity_id === response.audio_script_entity_id && entity.entity_kind === "audio-script")) throw new Error("Document AudioScript must name an AudioScript in this document");
286
+ if (response.audio_script_entity_id !== null && !response.rows.entities.some((entity) => entity.entity_id === response.audio_script_entity_id && entity.entity_kind === "audio-script")) throw new Error("Document AudioScript must name the project AudioScript");
286
287
  return {
287
288
  revision: response.revision,
288
289
  audioScriptEntityId: response.audio_script_entity_id,
@@ -794,6 +795,7 @@ const ENTITY_EDIT_SANDBOX_API_DTS = [
794
795
  "}",
795
796
  "export interface EntityStoreSnapshot {",
796
797
  " revision: number;",
798
+ " /** Fixed identity outlet of the project's one AudioScript; null only before initialization (revision 0). */",
797
799
  " audioScriptEntityId: string | null;",
798
800
  " entities: SandboxEntity[];",
799
801
  " relations: SandboxRelation[];",
@@ -1196,8 +1198,6 @@ const ENTITY_EDIT_SANDBOX_API_DTS = [
1196
1198
  "}",
1197
1199
  "/** Timeline writes accept existing media Entity ids, never Memota asset ids or URLs. */",
1198
1200
  "export interface EditApi {",
1199
- " /** Select the document AudioScript, or clear the optional association with null. */",
1200
- " setDocumentAudioScript(entityId: string | null): void;",
1201
1201
  " insertClip(input: InsertClipInput): ClipEntityId;",
1202
1202
  " insertPlacedClip(input: InsertPlacedClipInput): ClipEntityId;",
1203
1203
  " updateClipMarker(input: UpdateClipMarkerInput): void;",
@@ -1226,7 +1226,9 @@ const ENTITY_EDIT_SANDBOX_API_DTS = [
1226
1226
  " insertCaptionClip(input: InsertCaptionClipInput): ClipEntityId;",
1227
1227
  "}",
1228
1228
  "export interface TimelineApi {",
1229
- " snapshot(): EntityStoreSnapshot;",
1229
+ " snapshot(): EntityStoreSnapshot & {",
1230
+ " audioScriptEntityId: string;",
1231
+ " };",
1230
1232
  "}",
1231
1233
  "export interface SandboxCheckpoint {",
1232
1234
  " readonly index: number;",
@@ -1266,7 +1268,7 @@ The compatibility reader supports the existing four Track roles: video_clip (Ima
1266
1268
  Entities own fields; ordinary Relations express associations; variants directly hold baseEntityIds and assemble the referenced entities. These foundations are fixed: implementation must follow them, never redefine them. Any entity may compose multiple bases. Equal field names from multiple bases (even equal values) are errors, even when the variant declares that field itself. After validating all base fields are unambiguous, explicitly declared own fields may override base fields without mutating the bases. Base ordering never resolves conflicts. AudioScript owns segmented text. Caption and PhoneticScript persist baseEntityIds including their AudioScript, plus their own fields; no composition Relation exists. Create the real bases before reading or committing a variant. Inside the DSL sandbox, entities.get/list expose complete assembled fields. Consumers read fields without inspecting base IDs or merging bases. entities.update patches supplied fields and routes inherited fields to their declaring entity; omitted fields remain unchanged. entities.declareFields explicitly declares own overrides and is distinct from an ordinary field edit. Persistence keeps owned fields only. entities.readCaptionContent(id) and entities.readPhoneticScriptContent(id) return assembled text. Missing/cyclic bases and field conflicts fail before persistence.
1267
1269
  Use edit.insertCaptionClip with baseEntityIds and selections; each voiceover caption also supplies baseEntityIds. A selection names segmentId and may use a half-open Unicode code-point textRange to split a segment for the screen without rewriting AudioScript. Generate Voice from an existing PhoneticScript, then use phoneticScriptEntityId in the voiceover helper or relations.linkPhoneticScriptRender({output_entity_id,phonetic_script_entity_id}) for its render relation. Caption and Voice have their own Clips; display anchoring is explicit and independent of composition/alignment.
1268
1270
  Move or stretch only the Clip's display Marker; preserve Caption intrinsic Sequence, AudioScript text and its annotation Markers. AudioScript cannot enter a Clip and has no intrinsic time. audio-script-source links its ASR source Audio/Video/Voice; audio-script-marker attaches annotation Markers with directly assigned segmentRanges:{segmentId,startMs,endMs} in whole milliseconds. Annotation Markers have no Clip/AXVideo/content/Timeline relations and never refer to other Markers for time. BGM keeps factual source duration with durationPolicy:'timeline'. Never introduce a speech entity kind.
1269
- Create only the known entity kinds. The host initializes one Timeline and four fixed Tracks before editing; inspect and reuse their IDs from timeline.snapshot(), never create another Timeline or Track for each operation. If snapshot reports legacy migration is required, recall the listed asset facts and call migrate-legacy first. Missing facts, unsupported layouts, and version conflicts fail closed; never fall back to an old timeline method or raw update endpoint.
1271
+ Create only the known entity kinds. The host initializes one Timeline, four fixed Tracks, and the project's single AudioScript (initially segments:[]) before editing; inspect and reuse their IDs from timeline.snapshot(), never create another Timeline, Track, or AudioScript for each operation. The AudioScript identity is fixed for the project: edit its segments in place via entities.update, never delete or re-create it. If snapshot reports legacy migration is required, recall the listed asset facts and call migrate-legacy first. Missing facts, unsupported layouts, and version conflicts fail closed; never fall back to an old timeline method or raw update endpoint.
1270
1272
  Use only the globals and methods declared by the following TypeScript interface. Values not declared here are unavailable.
1271
1273
  `.trim();
1272
1274
  /** Render the complete MEngine-owned context injected before one model call. */
@@ -1923,7 +1925,6 @@ function createMedeoTool(options) {
1923
1925
  try {
1924
1926
  await getGraphClient(docId).commit({
1925
1927
  revision: state.revision,
1926
- audioScriptEntityId: state.audioScriptEntityId,
1927
1928
  rows: baseRows
1928
1929
  }, migrated, { migrationBaseVv: encodeDocVersionMark(doc.versionMark()) });
1929
1930
  } catch (error) {
@@ -2064,23 +2065,26 @@ function createMedeoTool(options) {
2064
2065
  async function migrate(input) {
2065
2066
  return runExclusive(input.doc_id, async (doc) => {
2066
2067
  assertNoPendingPush(input.doc_id);
2067
- const client = getGraphClient(input.doc_id);
2068
- const base = await client.fetchState();
2069
- if (base.rows.entities.some((row) => row.entityKind === "timeline")) return {
2068
+ const snapshotState = await getEntityClient(input.doc_id).fetchState();
2069
+ if (snapshotState.entities.some((row) => row.entity_kind === "timeline")) return {
2070
2070
  ok: true,
2071
2071
  op: "migrate-legacy",
2072
2072
  doc_id: input.doc_id,
2073
2073
  migration_status: "already_entity",
2074
- entity_revision: base.revision,
2074
+ entity_revision: snapshotState.revision,
2075
2075
  next_action: "snapshot"
2076
2076
  };
2077
2077
  const pull = await doc.pull();
2078
2078
  if (!pull.ok) throw new Error(`Migration requires a fresh canonical snapshot: ${pull.error.message}`);
2079
2079
  const migrationBaseVv = encodeDocVersionMark(doc.versionMark());
2080
- const nextRows = migrateLegacyTimelineToEntities(doc.snapshot(), input.asset_facts, base.rows);
2080
+ const baseRows = toDslRows(snapshotState);
2081
+ const nextRows = migrateLegacyTimelineToEntities(doc.snapshot(), input.asset_facts, baseRows);
2081
2082
  let revision;
2082
2083
  try {
2083
- revision = (await client.commit(base, nextRows, { migrationBaseVv })).revision;
2084
+ revision = (await getGraphClient(input.doc_id).commit({
2085
+ revision: snapshotState.revision,
2086
+ rows: baseRows
2087
+ }, nextRows, { migrationBaseVv })).revision;
2084
2088
  } catch (error) {
2085
2089
  if (error instanceof MengineHttpRequestError) throw new Error(`Migration rejected (HTTP ${error.status}): ${entityHttpErrorMessage(error.payload)}; take a fresh snapshot before retrying`);
2086
2090
  throw new Error("Migration submission is unconfirmed; take a fresh snapshot and retry migrate-legacy to inspect whether the Entity timeline already exists");