@mengine/medeo-tool 1.4.1-alpha.4 → 2.0.1-alpha.2
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 +9 -0
- package/dist/{entity-contract-DQ56Ihrh.d.mts → entity-contract-G4HxwNXl.d.mts} +3 -3
- package/dist/{entity-sandbox-OArq9NSH.mjs → entity-sandbox-TaUVT3on.mjs} +24 -36
- package/dist/entity-sandbox-TaUVT3on.mjs.map +1 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +38 -34
- package/dist/index.mjs.map +1 -1
- package/dist/sandbox-api.d.mts +3 -3
- package/dist/worker-entry.d.mts +1 -1
- package/dist/worker-entry.mjs +77 -13
- package/dist/worker-entry.mjs.map +1 -1
- package/package.json +2 -2
- package/dist/entity-sandbox-OArq9NSH.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -84,6 +84,15 @@ Resource-free Caption composition from AudioScript is also supported. Each
|
|
|
84
84
|
on-screen placement has its own Clip and display SequenceMarker, connected by
|
|
85
85
|
ordinary relations; intrinsic Caption timing remains independent.
|
|
86
86
|
|
|
87
|
+
Voice resources use `external: {system: 'memota-speech', key: speechId}`.
|
|
88
|
+
Await `rgetAssetFromEntity(voiceId)` before constructing placement relations: the
|
|
89
|
+
host supplies `storageKey`, the full millisecond `extent`, and the optional TTS
|
|
90
|
+
`voice` locator. The loader returns `{assetId, content: {storageKey, durationMs,
|
|
91
|
+
voice?}}` from a project-scoped Speech lookup. Recorded speech omits `voice`;
|
|
92
|
+
TTS retains its explicit PhoneticScript relation. Resource reads do not create
|
|
93
|
+
script text or display markers. New or changed Speech references are also
|
|
94
|
+
resolved before commit, and failed reads publish no partial edits.
|
|
95
|
+
|
|
87
96
|
`materializeResources` and generation/resource loaders are host APIs. The model
|
|
88
97
|
never receives these capabilities. Project initialization and historical data
|
|
89
98
|
migration also remain outside script execution. Retrying an unconfirmed commit
|
|
@@ -106,7 +106,7 @@ interface EntityPayloadByKind {
|
|
|
106
106
|
};
|
|
107
107
|
caption: BoundedNativeSequencePayload & {
|
|
108
108
|
baseEntityIds: string[];
|
|
109
|
-
|
|
109
|
+
selection: CaptionTextSelection;
|
|
110
110
|
style?: JsonObject;
|
|
111
111
|
segmentRanges?: {
|
|
112
112
|
segmentId: string;
|
|
@@ -116,7 +116,7 @@ interface EntityPayloadByKind {
|
|
|
116
116
|
};
|
|
117
117
|
}
|
|
118
118
|
/** Stored own fields; a variant may obtain required content fields from its declared bases. */
|
|
119
|
-
type StoredEntityPayload<K extends KnownEntityKind> = EntityPayloadByKind[K] | (K extends 'caption' ? JsonObject & Pick<MediaAssetPayload, 'external'> : never) | (JsonObject & Partial<EntityPayloadByKind[K]> & {
|
|
119
|
+
type StoredEntityPayload<K extends KnownEntityKind> = EntityPayloadByKind[K] | (K extends 'caption' | 'voice' ? JsonObject & Pick<MediaAssetPayload, 'external'> : never) | (JsonObject & Partial<EntityPayloadByKind[K]> & {
|
|
120
120
|
baseEntityIds: string[];
|
|
121
121
|
});
|
|
122
122
|
interface SandboxEntity<K extends KnownEntityKind = KnownEntityKind> {
|
|
@@ -238,4 +238,4 @@ interface BusinessRelationFacade {
|
|
|
238
238
|
}
|
|
239
239
|
//#endregion
|
|
240
240
|
export { UpdateEntityInput as C, UnlinkRelationInput as S, LinkRelationInput as _, DeleteEntityInput as a, SandboxEntity as b, EntitySandboxCheckpoint as c, JsonObject as d, JsonPrimitive as f, LinkGeneratedRelationInput as g, KnownRelationKind as h, CreateEntityInput as i, EntityStoreSnapshot as l, KnownEntityKind as m, BusinessEntityFacade as n, EntityCommand as o, JsonValue as p, BusinessRelationFacade as r, EntityPlanState as s, AuthorableRelationKind as t, EntityUpdateInput as u, RelationUpdateInput as v, SandboxRelation as x, ResourceEntityKind as y };
|
|
241
|
-
//# sourceMappingURL=entity-contract-
|
|
241
|
+
//# sourceMappingURL=entity-contract-G4HxwNXl.d.mts.map
|
|
@@ -209,15 +209,15 @@ function assembleCaptionContent(rows, captionEntityId) {
|
|
|
209
209
|
requireEntityKind(rows, captionEntityId, "caption");
|
|
210
210
|
const caption = assembleEntityContent(rows, captionEntityId);
|
|
211
211
|
const script = findComposedAudioScript(rows, captionEntityId, "caption");
|
|
212
|
-
const
|
|
212
|
+
const segment = selectAudioScriptSegment({
|
|
213
213
|
...script,
|
|
214
214
|
payload: caption.payload
|
|
215
|
-
},
|
|
215
|
+
}, captionSelection(caption));
|
|
216
216
|
return {
|
|
217
217
|
caption,
|
|
218
218
|
audioScript: script,
|
|
219
|
-
segments,
|
|
220
|
-
text:
|
|
219
|
+
segments: [segment],
|
|
220
|
+
text: segment.text
|
|
221
221
|
};
|
|
222
222
|
}
|
|
223
223
|
/**
|
|
@@ -239,20 +239,18 @@ function assemblePhoneticScriptContent(rows, phoneticScriptEntityId) {
|
|
|
239
239
|
text: segments.map((segment) => segment.text).join("")
|
|
240
240
|
};
|
|
241
241
|
}
|
|
242
|
-
function
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
if (!selections.every(isSegmentSelection)) throw new ScriptCompositionError("invalid_selection", caption.entityId, "Caption selections require a segmentId and optional textRange");
|
|
246
|
-
return selections;
|
|
242
|
+
function captionSelection(caption) {
|
|
243
|
+
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");
|
|
244
|
+
return caption.payload.selection;
|
|
247
245
|
}
|
|
248
246
|
function isSegmentSelection(value) {
|
|
249
247
|
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");
|
|
250
248
|
}
|
|
251
249
|
/** Select source text without creating another authoritative text field. */
|
|
252
|
-
function
|
|
253
|
-
if (!
|
|
250
|
+
function selectAudioScriptSegment(script, selection) {
|
|
251
|
+
if (!isSegmentSelection(selection)) throw new ScriptCompositionError("invalid_selection", script.entityId, "Caption requires one selection object with segmentId and optional textRange");
|
|
254
252
|
const bySegmentId = new Map(scriptSegments(script).map((segment) => [segment.segmentId, segment]));
|
|
255
|
-
const selected =
|
|
253
|
+
const selected = (() => {
|
|
256
254
|
const segment = bySegmentId.get(selection.segmentId);
|
|
257
255
|
if (segment === void 0) throw new ScriptCompositionError("unknown_segment", script.entityId, `Caption selection "${selection.segmentId}" does not name a segment of AudioScript "${script.entityId}"`);
|
|
258
256
|
if (selection.textRange === void 0) return segment;
|
|
@@ -263,8 +261,8 @@ function selectAudioScriptSegments(script, selections) {
|
|
|
263
261
|
...segment,
|
|
264
262
|
text: points.slice(range.start, range.end).join("")
|
|
265
263
|
};
|
|
266
|
-
});
|
|
267
|
-
if (!selected.
|
|
264
|
+
})();
|
|
265
|
+
if (!selected.text.trim()) throw new ScriptCompositionError("empty_selection", script.entityId, "Caption selection must contain visible source text");
|
|
268
266
|
return selected;
|
|
269
267
|
}
|
|
270
268
|
function requireEntityKind(rows, entityIdValue, entityKind) {
|
|
@@ -736,25 +734,15 @@ function validateVoicePayload(value, problems) {
|
|
|
736
734
|
function validateCaptionPayload(value, problems) {
|
|
737
735
|
validateExternalLocator(value, problems);
|
|
738
736
|
if (value.segmentRanges !== void 0) validateSegmentRanges(value.segmentRanges, problems);
|
|
739
|
-
|
|
740
|
-
|
|
737
|
+
if (Object.hasOwn(value, "selections")) problems.push("selections is forbidden; Caption requires one selection object");
|
|
738
|
+
const selection = value.selection;
|
|
739
|
+
if (!isRecord(selection)) problems.push("selection must be one AudioScript segment selection object, not an array");
|
|
741
740
|
else {
|
|
742
|
-
if (
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
continue;
|
|
748
|
-
}
|
|
749
|
-
if (typeof selection.segmentId !== "string" || selection.segmentId.trim() === "") problems.push(`selections[${index}].segmentId must be a string`);
|
|
750
|
-
else if (seen.has(selection.segmentId)) problems.push(`selections[${index}].segmentId must be unique within the Caption`);
|
|
751
|
-
else seen.add(selection.segmentId);
|
|
752
|
-
if (Object.keys(selection).some((key) => key !== "segmentId" && key !== "textRange")) problems.push(`selections[${index}] may only contain segmentId and textRange`);
|
|
753
|
-
if (selection.textRange !== void 0) {
|
|
754
|
-
const range = selection.textRange;
|
|
755
|
-
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`);
|
|
756
|
-
}
|
|
757
|
-
}
|
|
741
|
+
if (typeof selection.segmentId !== "string" || !selection.segmentId.trim()) problems.push("selection.segmentId must be a non-empty string");
|
|
742
|
+
if (Object.keys(selection).some((key) => key !== "segmentId" && key !== "textRange")) problems.push("selection may only contain segmentId and textRange");
|
|
743
|
+
const range = selection.textRange;
|
|
744
|
+
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");
|
|
745
|
+
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");
|
|
758
746
|
}
|
|
759
747
|
const style = value.style;
|
|
760
748
|
if (style === void 0) return;
|
|
@@ -878,7 +866,7 @@ function isOwnedLocalEntityValuePath(entityKind, path) {
|
|
|
878
866
|
if (entityKind === "asset" && /^(?:external\.(?:system|key)|storageKey)$/.test(path)) return true;
|
|
879
867
|
if (isMediaAssetVariantKind(entityKind) && /^(?:external\.(?:system|key)|storageKey)$/.test(path)) return true;
|
|
880
868
|
if (entityKind === "voice" && /^voice\.(?:system|key|name)$/.test(path)) return true;
|
|
881
|
-
if (entityKind === "caption" && (path.startsWith("style.") ||
|
|
869
|
+
if (entityKind === "caption" && (path.startsWith("style.") || path === "selection.segmentId")) return true;
|
|
882
870
|
if ([
|
|
883
871
|
"audio-script",
|
|
884
872
|
"caption",
|
|
@@ -893,7 +881,7 @@ function isOwnedLocalIdPath(entityKind, path) {
|
|
|
893
881
|
"caption",
|
|
894
882
|
"phonetic-script"
|
|
895
883
|
].includes(entityKind) && /^segments\[\d+\]\.segmentId$/.test(path)) return true;
|
|
896
|
-
if (entityKind === "caption" &&
|
|
884
|
+
if (entityKind === "caption" && path === "selection.segmentId") return true;
|
|
897
885
|
if ((entityKind === "sequence-marker" || entityKind === "caption") && /^segmentRanges\[\d+\]\.segmentId$/.test(path)) return true;
|
|
898
886
|
if (entityKind === "asset" && /^(?:tracks\[\d+\]\.trackId|renditions\[\d+\]\.renditionId)$/.test(path)) return true;
|
|
899
887
|
return false;
|
|
@@ -2096,6 +2084,6 @@ const numericMarkerComparators = { compareMarkerPoints: (_marker, _range, left,
|
|
|
2096
2084
|
return left - right;
|
|
2097
2085
|
} };
|
|
2098
2086
|
//#endregion
|
|
2099
|
-
export {
|
|
2087
|
+
export { isJsonObject as a, isMediaAssetVariantKind as c, businessState as i, toDslRows as n, createEntityId as o, businessFacades as r, createRelationId as s, EntitySandbox as t };
|
|
2100
2088
|
|
|
2101
|
-
//# sourceMappingURL=entity-sandbox-
|
|
2089
|
+
//# sourceMappingURL=entity-sandbox-TaUVT3on.mjs.map
|