@scenar/cli 0.1.18 → 0.1.19

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scenar/cli",
3
- "version": "0.1.18",
3
+ "version": "0.1.19",
4
4
  "description": "Scenar CLI — validate scenarios, generate narration, and render videos.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -27,9 +27,9 @@
27
27
  "main": "./src/index.js",
28
28
  "types": "./src/index.d.ts",
29
29
  "dependencies": {
30
- "@scenar/core": "0.1.18",
31
- "@scenar/preview": "0.1.18",
32
- "@scenar/sdk": "0.1.18",
30
+ "@scenar/core": "0.1.19",
31
+ "@scenar/preview": "0.1.19",
32
+ "@scenar/sdk": "0.1.19",
33
33
  "commander": "^13.0.0",
34
34
  "yaml": "^2.7.0"
35
35
  },
@@ -2,16 +2,16 @@ import { describe, it, expect, vi, beforeEach } from "vitest";
2
2
 
3
3
  vi.mock("edge-tts-universal", () => {
4
4
  const mockSynthesize = vi.fn();
5
- const MockEdgeTTS = vi.fn().mockImplementation(() => ({
5
+ const MockIsomorphicEdgeTTS = vi.fn().mockImplementation(() => ({
6
6
  synthesize: mockSynthesize,
7
7
  }));
8
- return { EdgeTTS: MockEdgeTTS, __mockSynthesize: mockSynthesize };
8
+ return { IsomorphicEdgeTTS: MockIsomorphicEdgeTTS, __mockSynthesize: mockSynthesize };
9
9
  });
10
10
 
11
- import { EdgeTTS } from "edge-tts-universal";
11
+ import { IsomorphicEdgeTTS } from "edge-tts-universal";
12
12
 
13
13
  // Access the inner mock so tests can configure per-call responses.
14
- const MockEdgeTTS = vi.mocked(EdgeTTS);
14
+ const MockIsomorphicEdgeTTS = vi.mocked(IsomorphicEdgeTTS);
15
15
  const mockSynthesize = (
16
16
  await import("edge-tts-universal") as { __mockSynthesize: ReturnType<typeof vi.fn> }
17
17
  ).__mockSynthesize;
@@ -33,7 +33,7 @@ describe("Edge TTS provider", () => {
33
33
  const provider = createEdgeTtsProvider();
34
34
  const result = await provider.synthesize("Hello world", { voice: "en-US-JennyNeural" });
35
35
 
36
- expect(MockEdgeTTS).toHaveBeenCalledWith("Hello world", "en-US-JennyNeural");
36
+ expect(MockIsomorphicEdgeTTS).toHaveBeenCalledWith("Hello world", "en-US-JennyNeural");
37
37
  expect(result.audio).toBeInstanceOf(Buffer);
38
38
  expect(result.durationMs).toBe(2500);
39
39
  });
@@ -48,7 +48,7 @@ describe("Edge TTS provider", () => {
48
48
  const provider = createEdgeTtsProvider();
49
49
  await provider.synthesize("Test", {});
50
50
 
51
- expect(MockEdgeTTS).toHaveBeenCalledWith("Test", "en-US-AndrewMultilingualNeural");
51
+ expect(MockIsomorphicEdgeTTS).toHaveBeenCalledWith("Test", "en-US-AndrewMultilingualNeural");
52
52
  });
53
53
 
54
54
  it("computes duration from the last subtitle entry", async () => {
@@ -11,6 +11,14 @@ export declare function isEdgeTtsAvailable(): Promise<boolean>;
11
11
  * `edge-tts-universal` is an **optional peer dependency** (AGPL-3.0 licensed).
12
12
  * Users must install it explicitly: `pnpm add edge-tts-universal`.
13
13
  *
14
+ * Uses `IsomorphicEdgeTTS` instead of `EdgeTTS` because the latter
15
+ * delegates to `Communicate` whose WebSocket handler calls
16
+ * `message.subarray()` assuming a Node.js `Buffer`. On Node v23+ the
17
+ * `ws` library may deliver typed arrays or other non-Buffer objects,
18
+ * causing `TypeError: message.subarray is not a function`.
19
+ * `IsomorphicEdgeTTS` → `IsomorphicCommunicate` normalises all
20
+ * incoming data types before processing.
21
+ *
14
22
  * Duration is extracted from word-boundary subtitle metadata returned by
15
23
  * the service. Falls back to a bitrate-based estimate when metadata is
16
24
  * unavailable — same approach proven in Stigmer's narration pipeline.
@@ -1 +1 @@
1
- {"version":3,"file":"edge-tts.d.ts","sourceRoot":"","sources":["../../../src/tts/edge-tts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAyB,MAAM,YAAY,CAAC;AAUrE;;;GAGG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO3D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,IAAI,WAAW,CAsCnD"}
1
+ {"version":3,"file":"edge-tts.d.ts","sourceRoot":"","sources":["../../../src/tts/edge-tts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAyB,MAAM,YAAY,CAAC;AAUrE;;;GAGG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO3D;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,qBAAqB,IAAI,WAAW,CAsCnD"}
@@ -24,6 +24,14 @@ export async function isEdgeTtsAvailable() {
24
24
  * `edge-tts-universal` is an **optional peer dependency** (AGPL-3.0 licensed).
25
25
  * Users must install it explicitly: `pnpm add edge-tts-universal`.
26
26
  *
27
+ * Uses `IsomorphicEdgeTTS` instead of `EdgeTTS` because the latter
28
+ * delegates to `Communicate` whose WebSocket handler calls
29
+ * `message.subarray()` assuming a Node.js `Buffer`. On Node v23+ the
30
+ * `ws` library may deliver typed arrays or other non-Buffer objects,
31
+ * causing `TypeError: message.subarray is not a function`.
32
+ * `IsomorphicEdgeTTS` → `IsomorphicCommunicate` normalises all
33
+ * incoming data types before processing.
34
+ *
27
35
  * Duration is extracted from word-boundary subtitle metadata returned by
28
36
  * the service. Falls back to a bitrate-based estimate when metadata is
29
37
  * unavailable — same approach proven in Stigmer's narration pipeline.
@@ -33,10 +41,10 @@ export function createEdgeTtsProvider() {
33
41
  name: "edge-tts",
34
42
  async synthesize(text, options) {
35
43
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
36
- let EdgeTTS;
44
+ let IsomorphicEdgeTTS;
37
45
  try {
38
46
  const mod = await import("edge-tts-universal");
39
- EdgeTTS = mod.EdgeTTS;
47
+ IsomorphicEdgeTTS = mod.IsomorphicEdgeTTS;
40
48
  }
41
49
  catch {
42
50
  throw new Error("edge-tts-universal is not installed. Install it with:\n\n" +
@@ -44,7 +52,7 @@ export function createEdgeTtsProvider() {
44
52
  "Or use a different TTS provider: --tts echogarden, --tts openai");
45
53
  }
46
54
  const voice = options.voice ?? DEFAULT_VOICE;
47
- const tts = new EdgeTTS(text, voice);
55
+ const tts = new IsomorphicEdgeTTS(text, voice);
48
56
  const result = await tts.synthesize();
49
57
  const audioBuffer = Buffer.from(await result.audio.arrayBuffer());
50
58
  let durationMs = 0;
@@ -1 +1 @@
1
- {"version":3,"file":"edge-tts.js","sourceRoot":"","sources":["../../../src/tts/edge-tts.ts"],"names":[],"mappings":"AAEA,MAAM,aAAa,GAAG,gCAAgC,CAAC;AAEvD;;;GAGG;AACH,MAAM,qBAAqB,GAAG,EAAE,CAAC;AAEjC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO;QACL,IAAI,EAAE,UAAU;QAEhB,KAAK,CAAC,UAAU,CAAC,IAAY,EAAE,OAAmB;YAChD,8DAA8D;YAC9D,IAAI,OAAY,CAAC;YACjB,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;gBAC/C,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;YACxB,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,IAAI,KAAK,CACb,2DAA2D;oBACzD,mCAAmC;oBACnC,iEAAiE,CACpE,CAAC;YACJ,CAAC;YAED,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,aAAa,CAAC;YAC7C,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YACrC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC;YAEtC,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;YAElE,IAAI,UAAU,GAAG,CAAC,CAAC;YACnB,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC/B,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBACzD,kDAAkD;gBAClD,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC,CAAC;YACjE,CAAC;YAED,IAAI,UAAU,KAAK,CAAC,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC/C,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,qBAAqB,CAAC,CAAC;YAC3E,CAAC;YAED,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;QAC5C,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"edge-tts.js","sourceRoot":"","sources":["../../../src/tts/edge-tts.ts"],"names":[],"mappings":"AAEA,MAAM,aAAa,GAAG,gCAAgC,CAAC;AAEvD;;;GAGG;AACH,MAAM,qBAAqB,GAAG,EAAE,CAAC;AAEjC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO;QACL,IAAI,EAAE,UAAU;QAEhB,KAAK,CAAC,UAAU,CAAC,IAAY,EAAE,OAAmB;YAChD,8DAA8D;YAC9D,IAAI,iBAAsB,CAAC;YAC3B,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;gBAC/C,iBAAiB,GAAG,GAAG,CAAC,iBAAiB,CAAC;YAC5C,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,IAAI,KAAK,CACb,2DAA2D;oBACzD,mCAAmC;oBACnC,iEAAiE,CACpE,CAAC;YACJ,CAAC;YAED,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,aAAa,CAAC;YAC7C,MAAM,GAAG,GAAG,IAAI,iBAAiB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAC/C,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,UAAU,EAAE,CAAC;YAEtC,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;YAElE,IAAI,UAAU,GAAG,CAAC,CAAC;YACnB,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC/B,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBACzD,kDAAkD;gBAClD,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC,CAAC;YACjE,CAAC;YAED,IAAI,UAAU,KAAK,CAAC,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC/C,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,qBAAqB,CAAC,CAAC;YAC3E,CAAC;YAED,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;QAC5C,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -28,6 +28,14 @@ export async function isEdgeTtsAvailable(): Promise<boolean> {
28
28
  * `edge-tts-universal` is an **optional peer dependency** (AGPL-3.0 licensed).
29
29
  * Users must install it explicitly: `pnpm add edge-tts-universal`.
30
30
  *
31
+ * Uses `IsomorphicEdgeTTS` instead of `EdgeTTS` because the latter
32
+ * delegates to `Communicate` whose WebSocket handler calls
33
+ * `message.subarray()` assuming a Node.js `Buffer`. On Node v23+ the
34
+ * `ws` library may deliver typed arrays or other non-Buffer objects,
35
+ * causing `TypeError: message.subarray is not a function`.
36
+ * `IsomorphicEdgeTTS` → `IsomorphicCommunicate` normalises all
37
+ * incoming data types before processing.
38
+ *
31
39
  * Duration is extracted from word-boundary subtitle metadata returned by
32
40
  * the service. Falls back to a bitrate-based estimate when metadata is
33
41
  * unavailable — same approach proven in Stigmer's narration pipeline.
@@ -38,10 +46,10 @@ export function createEdgeTtsProvider(): TtsProvider {
38
46
 
39
47
  async synthesize(text: string, options: TtsOptions): Promise<TtsResult> {
40
48
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
41
- let EdgeTTS: any;
49
+ let IsomorphicEdgeTTS: any;
42
50
  try {
43
51
  const mod = await import("edge-tts-universal");
44
- EdgeTTS = mod.EdgeTTS;
52
+ IsomorphicEdgeTTS = mod.IsomorphicEdgeTTS;
45
53
  } catch {
46
54
  throw new Error(
47
55
  "edge-tts-universal is not installed. Install it with:\n\n" +
@@ -51,7 +59,7 @@ export function createEdgeTtsProvider(): TtsProvider {
51
59
  }
52
60
 
53
61
  const voice = options.voice ?? DEFAULT_VOICE;
54
- const tts = new EdgeTTS(text, voice);
62
+ const tts = new IsomorphicEdgeTTS(text, voice);
55
63
  const result = await tts.synthesize();
56
64
 
57
65
  const audioBuffer = Buffer.from(await result.audio.arrayBuffer());