xbintsc 0.5.22 → 0.5.23

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.
Files changed (81) hide show
  1. package/AGENTS.md +1 -1
  2. package/README.md +15 -5
  3. package/README.zh-CN.md +11 -4
  4. package/dist/src/cli/hints.js +11 -0
  5. package/dist/src/cli/hints.js.map +1 -1
  6. package/dist/src/cli/main.js +1 -1
  7. package/dist/src/driver/compiler.js +1 -0
  8. package/dist/src/driver/compiler.js.map +1 -1
  9. package/dist/src/driver/version.d.ts +1 -1
  10. package/dist/src/driver/version.js +1 -1
  11. package/dist/src/extensions/catalog.js +2 -1
  12. package/dist/src/extensions/catalog.js.map +1 -1
  13. package/dist/src/extensions/media/index.d.ts +27 -0
  14. package/dist/src/extensions/media/index.js +60 -0
  15. package/dist/src/extensions/media/index.js.map +1 -0
  16. package/dist/src/extensions/registry.d.ts +12 -0
  17. package/dist/src/extensions/registry.js +16 -0
  18. package/dist/src/extensions/registry.js.map +1 -1
  19. package/dist/src/index.d.ts +1 -0
  20. package/dist/src/index.js +1 -0
  21. package/dist/src/index.js.map +1 -1
  22. package/dist/tests/cli/hints.test.js +15 -0
  23. package/dist/tests/cli/hints.test.js.map +1 -1
  24. package/dist/tests/cli/process.test.js +12 -0
  25. package/dist/tests/cli/process.test.js.map +1 -1
  26. package/dist/tests/e2e/gui-example-canvas.test.js +3 -1
  27. package/dist/tests/e2e/gui-example-canvas.test.js.map +1 -1
  28. package/dist/tests/e2e/gui-helpers.d.ts +3 -0
  29. package/dist/tests/e2e/gui-helpers.js +2 -0
  30. package/dist/tests/e2e/gui-helpers.js.map +1 -1
  31. package/dist/tests/e2e/gui-media-disabled.test.d.ts +9 -0
  32. package/dist/tests/e2e/gui-media-disabled.test.js +42 -0
  33. package/dist/tests/e2e/gui-media-disabled.test.js.map +1 -0
  34. package/dist/tests/e2e/gui-media.test.d.ts +6 -4
  35. package/dist/tests/e2e/gui-media.test.js +15 -12
  36. package/dist/tests/e2e/gui-media.test.js.map +1 -1
  37. package/dist/tests/e2e/unicode-output.test.d.ts +16 -0
  38. package/dist/tests/e2e/unicode-output.test.js +65 -0
  39. package/dist/tests/e2e/unicode-output.test.js.map +1 -0
  40. package/dist/tests/extensions/media.test.d.ts +1 -0
  41. package/dist/tests/extensions/media.test.js +58 -0
  42. package/dist/tests/extensions/media.test.js.map +1 -0
  43. package/dist/tests/extensions/registry.test.js +8 -0
  44. package/dist/tests/extensions/registry.test.js.map +1 -1
  45. package/dist/tests/lexer/identifiers.test.js +12 -0
  46. package/dist/tests/lexer/identifiers.test.js.map +1 -1
  47. package/dist/tests/lexer/scanner.test.js +8 -0
  48. package/dist/tests/lexer/scanner.test.js.map +1 -1
  49. package/dist/tests/lexer/strings.test.js +30 -0
  50. package/dist/tests/lexer/strings.test.js.map +1 -1
  51. package/doc/ai/cli.md +1 -1
  52. package/doc/ai/extensions.md +35 -23
  53. package/doc/ai/troubleshooting.md +9 -0
  54. package/doc/ai/zh-CN/cli.md +1 -1
  55. package/doc/ai/zh-CN/extensions.md +20 -8
  56. package/doc/ai/zh-CN/troubleshooting.md +8 -0
  57. package/doc/gui/build.md +37 -21
  58. package/doc/gui/known-issues.md +7 -6
  59. package/doc/gui/media.md +26 -11
  60. package/doc/gui.md +43 -33
  61. package/doc/zh-CN/gui/build.md +28 -16
  62. package/doc/zh-CN/gui/known-issues.md +6 -5
  63. package/doc/zh-CN/gui/media.md +21 -10
  64. package/doc/zh-CN/gui.md +37 -32
  65. package/package.json +2 -1
  66. package/runtime/ext_gui/gui_media.cpp +69 -2
  67. package/runtime/ext_gui/media.cpp +34 -488
  68. package/runtime/ext_gui/media.h +54 -19
  69. package/runtime/ext_gui/media_api.h +65 -0
  70. package/runtime/ext_media/media.cpp +507 -0
  71. package/runtime/ext_media/media_bridge.c +35 -0
  72. package/scripts/build-gui.ts +6 -72
  73. package/scripts/build-media.ts +245 -0
  74. package/src/cli/hints.ts +11 -0
  75. package/src/cli/main.ts +1 -1
  76. package/src/driver/compiler.ts +1 -0
  77. package/src/driver/version.ts +1 -1
  78. package/src/extensions/catalog.ts +2 -1
  79. package/src/extensions/media/index.ts +67 -0
  80. package/src/extensions/registry.ts +24 -0
  81. package/src/index.ts +1 -0
@@ -0,0 +1,9 @@
1
+ /**
2
+ * `<video>` / `<audio>` are part of the GUI DOM even when no decoder is linked.
3
+ *
4
+ * This suite compiles with `--ext gui` only (the harness never registers the
5
+ * `media` extension), which is the whole point of the split: a GUI program does
6
+ * not link FFmpeg unless it asks for it. The element still exists and its DOM
7
+ * API is callable, but opening a source fails and fires `error`.
8
+ */
9
+ export {};
@@ -0,0 +1,42 @@
1
+ /**
2
+ * `<video>` / `<audio>` are part of the GUI DOM even when no decoder is linked.
3
+ *
4
+ * This suite compiles with `--ext gui` only (the harness never registers the
5
+ * `media` extension), which is the whole point of the split: a GUI program does
6
+ * not link FFmpeg unless it asks for it. The element still exists and its DOM
7
+ * API is callable, but opening a source fails and fires `error`.
8
+ */
9
+ import { afterAll, beforeAll, describe, expect, it } from "vitest";
10
+ import { createGuiHarness, guiAvailable } from "./gui-helpers.js";
11
+ describe.skipIf(!guiAvailable)("gui extension without media", () => {
12
+ const harness = createGuiHarness();
13
+ beforeAll(() => harness.setup());
14
+ afterAll(() => harness.cleanup());
15
+ it("reports error instead of decoding when the media extension is off", () => {
16
+ const { stdout } = harness.compileAndRun("media-off", `
17
+ import { createWindow, run } from "gui";
18
+
19
+ const win = createWindow({ title: "media off", width: 320, height: 200 });
20
+ win.on("ready", () => {
21
+ win.loadHTML('<video id="v" src="missing.mp4"></video>');
22
+ const v: any = win.document.getElementById("v");
23
+ v.addEventListener("loadedmetadata", () => {
24
+ console.log("unexpected-metadata");
25
+ win.close();
26
+ });
27
+ v.addEventListener("error", () => {
28
+ console.log("media-error");
29
+ win.close();
30
+ });
31
+ // The DOM surface is still there even without a decoder.
32
+ console.log("api=" + (v.paused === true) + ":" + (v.duration === 0));
33
+ });
34
+
35
+ run();
36
+ `, { autocloseMs: 1500 });
37
+ expect(stdout).toContain("media-error");
38
+ expect(stdout).not.toContain("unexpected-metadata");
39
+ expect(stdout).toContain("api=true:true");
40
+ });
41
+ });
42
+ //# sourceMappingURL=gui-media-disabled.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gui-media-disabled.test.js","sourceRoot":"","sources":["../../../tests/e2e/gui-media-disabled.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAElE,QAAQ,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,6BAA6B,EAAE,GAAG,EAAE;IACjE,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;IACnC,SAAS,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IACjC,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAElC,EAAE,CAAC,mEAAmE,EAAE,GAAG,EAAE;QAC3E,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,aAAa,CACtC,WAAW,EACX;;;;;;;;;;;;;;;;;;;;OAoBC,EACD,EAAE,WAAW,EAAE,IAAI,EAAE,CACtB,CAAC;QAEF,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;QACpD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,8 +1,10 @@
1
1
  /**
2
- * End-to-end tests for `<video>` / `<audio>` support in the `gui` extension.
2
+ * End-to-end tests for `<video>` / `<audio>` support.
3
3
  *
4
- * These exercise the real decoding path (vendored FFmpeg + SDL audio) and the
5
- * DOM media API. The fixtures live in `examples/resources`; when they are
6
- * absent (a trim checkout) the suite is skipped rather than failing.
4
+ * These exercise the real decoding path (the `media` extension's vendored
5
+ * FFmpeg + the GUI's SDL audio sink) and the DOM media API. They are skipped
6
+ * unless both the `gui` and `media` archives exist: the `gui` extension alone
7
+ * is deliberately decoder-free. The fixtures live in `examples/resources`; when
8
+ * they are absent (a trim checkout) the suite is skipped rather than failing.
7
9
  */
8
10
  export {};
@@ -1,9 +1,11 @@
1
1
  /**
2
- * End-to-end tests for `<video>` / `<audio>` support in the `gui` extension.
2
+ * End-to-end tests for `<video>` / `<audio>` support.
3
3
  *
4
- * These exercise the real decoding path (vendored FFmpeg + SDL audio) and the
5
- * DOM media API. The fixtures live in `examples/resources`; when they are
6
- * absent (a trim checkout) the suite is skipped rather than failing.
4
+ * These exercise the real decoding path (the `media` extension's vendored
5
+ * FFmpeg + the GUI's SDL audio sink) and the DOM media API. They are skipped
6
+ * unless both the `gui` and `media` archives exist: the `gui` extension alone
7
+ * is deliberately decoder-free. The fixtures live in `examples/resources`; when
8
+ * they are absent (a trim checkout) the suite is skipped rather than failing.
7
9
  */
8
10
  import { existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
9
11
  import { tmpdir } from "node:os";
@@ -14,6 +16,8 @@ import { afterAll, beforeAll, describe, expect, it } from "vitest";
14
16
  import { build } from "../../src/driver/compiler.js";
15
17
  import { createDefaultRegistry } from "../../src/extensions/registry.js";
16
18
  import { guiExtension } from "../../src/extensions/gui/index.js";
19
+ import { mediaExtension } from "../../src/extensions/media/index.js";
20
+ import { findRuntimeLibrary } from "../../src/driver/runtime-lib.js";
17
21
  import { createGuiHarness, guiAvailable } from "./gui-helpers.js";
18
22
  const root = resolve(dirname(fileURLToPath(import.meta.url)), "..", "..");
19
23
  const resourceDir = join(root, "examples", "resources");
@@ -27,13 +31,12 @@ function mediaSrc(absolutePath) {
27
31
  }
28
32
  const resourcesAvailable = existsSync(moviePath) && existsSync(soundPath);
29
33
  /**
30
- * Windows builds the GUI archive without FFmpeg on purpose (see
31
- * `doc/gui/known-issues.md`), so media elements are inert there and the suite
32
- * would only report the expected `error` events as failures. It stays skipped
33
- * even with `xbintsc_GUI_TESTS=1`.
34
+ * The `media` archive is built separately (`npm run media`) and is POSIX-only
35
+ * for now. Without it the suite would compile GUI programs that report the
36
+ * expected `error` events, i.e. it would test the wrong thing.
34
37
  */
35
- const mediaAvailable = process.platform !== "win32";
36
- describe.skipIf(!guiAvailable || !resourcesAvailable || !mediaAvailable)("gui extension — media", () => {
38
+ const mediaAvailable = process.platform !== "win32" && findRuntimeLibrary("media") !== undefined;
39
+ describe.skipIf(!guiAvailable || !resourcesAvailable || !mediaAvailable)("gui + media extensions", () => {
37
40
  const harness = createGuiHarness();
38
41
  beforeAll(() => harness.setup());
39
42
  afterAll(() => harness.cleanup());
@@ -81,7 +84,7 @@ describe.skipIf(!guiAvailable || !resourcesAvailable || !mediaAvailable)("gui ex
81
84
  });
82
85
 
83
86
  run();
84
- `, { autocloseMs: 8000 });
87
+ `, { autocloseMs: 8000, extensions: [mediaExtension] });
85
88
  expect(stdout).not.toContain("video-error");
86
89
  expect(stdout).not.toContain("audio-error");
87
90
  expect(value("duration")).toBe("true:true");
@@ -98,7 +101,7 @@ describe.skipIf(!guiAvailable || !resourcesAvailable || !mediaAvailable)("gui ex
98
101
  try {
99
102
  writeFileSync(join(workdir, "media.html"), readFileSync(join(exampleDir, "media.html"), "utf8"));
100
103
  writeFileSync(join(workdir, "media.ts"), readFileSync(join(exampleDir, "media.ts"), "utf8"));
101
- const extensions = createDefaultRegistry().register(guiExtension);
104
+ const extensions = createDefaultRegistry().register(guiExtension).register(mediaExtension);
102
105
  const result = build(join(workdir, "media.ts"), {
103
106
  emit: "exe",
104
107
  outDir: join(workdir, "out"),
@@ -1 +1 @@
1
- {"version":3,"file":"gui-media.test.js","sourceRoot":"","sources":["../../../tests/e2e/gui-media.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gui-media.test.js","sourceRoot":"","sources":["../../../tests/e2e/gui-media.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Regression coverage for Chinese (and other non-ASCII) text reaching stdout.
3
+ *
4
+ * The driver reads a source file as UTF-8 bytes, the lexer stores a literal's
5
+ * bytes, and the runtime writes those bytes straight to `stdout`/`stderr`. A
6
+ * mis-encoded literal, a UTF-16 code-unit leak or a console writer that
7
+ * re-encodes the bytes changes the output sequence even when adjacent English
8
+ * text still looks fine — the issue reports exactly that:
9
+ *
10
+ * console.log('你好世界!');
11
+ * console.log('Hello World!');
12
+ *
13
+ * The program is run with its stdout/stderr captured as pipes, so these cases
14
+ * pin the bytes the terminal receives without depending on a local code page.
15
+ */
16
+ export {};
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Regression coverage for Chinese (and other non-ASCII) text reaching stdout.
3
+ *
4
+ * The driver reads a source file as UTF-8 bytes, the lexer stores a literal's
5
+ * bytes, and the runtime writes those bytes straight to `stdout`/`stderr`. A
6
+ * mis-encoded literal, a UTF-16 code-unit leak or a console writer that
7
+ * re-encodes the bytes changes the output sequence even when adjacent English
8
+ * text still looks fine — the issue reports exactly that:
9
+ *
10
+ * console.log('你好世界!');
11
+ * console.log('Hello World!');
12
+ *
13
+ * The program is run with its stdout/stderr captured as pipes, so these cases
14
+ * pin the bytes the terminal receives without depending on a local code page.
15
+ */
16
+ import { expect, it } from "vitest";
17
+ import { describeE2E } from "./harness.js";
18
+ /** The UTF-8 bytes of `text`, as hexadecimal, so a re-encoding cannot pass. */
19
+ function utf8Hex(text) {
20
+ return Buffer.from(text, "utf8").toString("hex");
21
+ }
22
+ const issueProgram = `console.log('你好世界!');
23
+ console.log('Hello World!');
24
+ `;
25
+ describeE2E("non-ASCII console output", (harness) => {
26
+ it("prints the issue's Chinese and English lines as exact UTF-8", () => {
27
+ const result = harness.runProgramFull(issueProgram, { name: "chinese_issue" });
28
+ expect(result.status).toBe(0);
29
+ expect(result.stderr).toBe("");
30
+ expect(result.stdout).toBe("你好世界!\nHello World!\n");
31
+ expect(utf8Hex(result.stdout)).toBe("e4bda0e5a5bde4b896e7958cefbc810a48656c6c6f20576f726c64210a");
32
+ });
33
+ it("prints Chinese literals, escapes, templates and identifiers byte-identically", () => {
34
+ const result = harness.runProgramFull(`
35
+ const 名字 = "世界";
36
+ console.log("你好," + 名字 + "!");
37
+ console.log("\\u4f60\\u597d\\uff0c\\u4e16\\u754c\\uff01");
38
+ console.log(\`你好,\${名字}!\`);
39
+ console.log(["中文", { 键: "值" }]);
40
+ console.log(JSON.stringify({ 你好: "世界" }));
41
+ `, { name: "chinese_values" });
42
+ expect(result.status).toBe(0);
43
+ expect(result.stderr).toBe("");
44
+ expect(result.stdout).toBe([
45
+ "你好,世界!",
46
+ "你好,世界!",
47
+ "你好,世界!",
48
+ "[ '中文', { '键': '值' } ]",
49
+ '{"你好":"世界"}',
50
+ "",
51
+ ].join("\n"));
52
+ });
53
+ it("routes Chinese console levels to the matching stream", () => {
54
+ const result = harness.runProgramFull(`
55
+ console.log("日志:中文");
56
+ console.info("信息:中文");
57
+ console.warn("警告:中文");
58
+ console.error("错误:中文");
59
+ `, { name: "chinese_console_levels" });
60
+ expect(result.status).toBe(0);
61
+ expect(result.stdout).toBe("日志:中文\n信息:中文\n");
62
+ expect(result.stderr).toBe("警告:中文\n错误:中文\n");
63
+ });
64
+ });
65
+ //# sourceMappingURL=unicode-output.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unicode-output.test.js","sourceRoot":"","sources":["../../../tests/e2e/unicode-output.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,+EAA+E;AAC/E,SAAS,OAAO,CAAC,IAAY;IAC3B,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,YAAY,GAAG;;CAEpB,CAAC;AAEF,WAAW,CAAC,0BAA0B,EAAE,CAAC,OAAO,EAAE,EAAE;IAClD,EAAE,CAAC,6DAA6D,EAAE,GAAG,EAAE;QACrE,MAAM,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,CAAC;QAC/E,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QACpD,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,4DAA4D,CAAC,CAAC;IACpG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8EAA8E,EAAE,GAAG,EAAE;QACtF,MAAM,MAAM,GAAG,OAAO,CAAC,cAAc,CACnC;;;;;;;OAOC,EACD,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAC3B,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/B,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CACxB;YACE,QAAQ;YACR,QAAQ;YACR,QAAQ;YACR,wBAAwB;YACxB,aAAa;YACb,EAAE;SACH,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,MAAM,GAAG,OAAO,CAAC,cAAc,CACnC;;;;;OAKC,EACD,EAAE,IAAI,EAAE,wBAAwB,EAAE,CACnC,CAAC;QACF,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC9B,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,58 @@
1
+ import { afterEach, describe, expect, it, vi } from "vitest";
2
+ const mocks = vi.hoisted(() => ({ findRuntimeLibrary: vi.fn() }));
3
+ /* Keep the archive lookup deterministic so both the success and the
4
+ * "not built yet" branches of `nativeObjects` can be exercised. */
5
+ vi.mock("../../src/driver/runtime-lib.js", () => ({
6
+ findRuntimeLibrary: mocks.findRuntimeLibrary,
7
+ }));
8
+ import { bundledExtensions } from "../../src/extensions/catalog.js";
9
+ import { createDefaultRegistry } from "../../src/extensions/registry.js";
10
+ import { guiExtension } from "../../src/extensions/gui/index.js";
11
+ import { mediaExtension } from "../../src/extensions/media/index.js";
12
+ afterEach(() => {
13
+ vi.restoreAllMocks();
14
+ mocks.findRuntimeLibrary.mockReset();
15
+ });
16
+ /** Pretend to be a POSIX host so the Windows-only guard does not fire. */
17
+ function posixHost() {
18
+ vi.spyOn(process, "platform", "get").mockReturnValue("darwin");
19
+ }
20
+ describe("media extension object", () => {
21
+ it("is a separate extension that depends on gui", () => {
22
+ expect(mediaExtension.name).toBe("media");
23
+ expect(mediaExtension.description).toMatch(/FFmpeg/);
24
+ expect(mediaExtension.requires).toEqual(["gui"]);
25
+ // Media is advertised as a bundled extension, but is not enabled by
26
+ // enabling `gui`: that separation is the point of the split.
27
+ expect(bundledExtensions().map((extension) => extension.name)).toContain("media");
28
+ });
29
+ it("links the bridge object and the prebuilt archive", () => {
30
+ posixHost();
31
+ mocks.findRuntimeLibrary.mockReturnValue("/tmp/media.a");
32
+ const sources = mediaExtension.runtimeSources?.() ?? [];
33
+ expect(sources).toHaveLength(1);
34
+ expect(sources[0]).toMatch(/runtime[\\/]ext_media[\\/]media_bridge\.c$/);
35
+ expect(mediaExtension.nativeObjects?.()).toEqual(["/tmp/media.a"]);
36
+ expect(mocks.findRuntimeLibrary).toHaveBeenCalledWith("media");
37
+ });
38
+ it("fails with an actionable message when the archive is missing", () => {
39
+ posixHost();
40
+ mocks.findRuntimeLibrary.mockReturnValue(undefined);
41
+ expect(() => mediaExtension.nativeObjects?.()).toThrow(/media native library not found/);
42
+ expect(() => mediaExtension.nativeObjects?.()).toThrow(/npm run media/);
43
+ });
44
+ it("reports that Windows has no media archive yet", () => {
45
+ vi.spyOn(process, "platform", "get").mockReturnValue("win32");
46
+ expect(() => mediaExtension.nativeObjects?.()).toThrow(/not available on Windows/);
47
+ });
48
+ it("rejects a build that enables media without gui", () => {
49
+ const registry = createDefaultRegistry().register(mediaExtension);
50
+ expect(() => registry.validate()).toThrow(/requires the 'gui' extension/);
51
+ expect(() => registry.validate()).toThrow(/--ext gui,media/);
52
+ });
53
+ it("accepts gui + media together", () => {
54
+ const registry = createDefaultRegistry().register(guiExtension).register(mediaExtension);
55
+ expect(() => registry.validate()).not.toThrow();
56
+ });
57
+ });
58
+ //# sourceMappingURL=media.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media.test.js","sourceRoot":"","sources":["../../../tests/extensions/media.test.ts"],"names":[],"mappings":"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"}
@@ -83,6 +83,14 @@ describe("ExtensionRegistry", () => {
83
83
  expect(registry.runtimeSources()).toEqual(["/tmp/demo.c"]);
84
84
  expect(registry.linkerFlags()).toEqual(["-ldemo"]);
85
85
  });
86
+ it("validates declared extension dependencies", () => {
87
+ const base = { name: "base" };
88
+ const dependent = { name: "dependent", requires: ["base"] };
89
+ expect(() => new ExtensionRegistry().register(dependent).validate()).toThrow(/extension 'dependent' requires the 'base' extension/);
90
+ expect(() => new ExtensionRegistry().register(base).register(dependent).validate()).not.toThrow();
91
+ // An extension with no declared dependencies always validates.
92
+ expect(() => new ExtensionRegistry().register(base).validate()).not.toThrow();
93
+ });
86
94
  it("ships a core extension exposing print", () => {
87
95
  expect(coreExtension.builtins?.().print?.symbol).toBe("xt_println");
88
96
  expect(createDefaultRegistry().has("core")).toBe(true);
@@ -1 +1 @@
1
- {"version":3,"file":"registry.test.js","sourceRoot":"","sources":["../../../tests/extensions/registry.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.test.js","sourceRoot":"","sources":["../../../tests/extensions/registry.test.ts"],"names":[],"mappings":"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"}
@@ -9,5 +9,17 @@ describe("scanner identifiers", () => {
9
9
  expect(diagnostics).toHaveLength(0);
10
10
  expect(tokens.some((token) => token.kind === TokenKind.Identifier && token.text === "a\\u0041bc")).toBe(true);
11
11
  });
12
+ it("scans a Chinese identifier as one identifier token", () => {
13
+ const { tokens, diagnostics } = lex("const 姓名 = 1;");
14
+ expect(diagnostics).toHaveLength(0);
15
+ const identifiers = tokens.filter((token) => token.kind === TokenKind.Identifier);
16
+ expect(identifiers).toHaveLength(1);
17
+ const name = Buffer.from("姓名", "utf8").toString("latin1");
18
+ expect(identifiers[0].text).toBe(name);
19
+ // The scanner walks UTF-8 source bytes, so the token covers all six bytes
20
+ // of the name rather than stopping after the first one.
21
+ expect(identifiers[0].start).toBe("const ".length);
22
+ expect(identifiers[0].end).toBe(identifiers[0].start + name.length);
23
+ });
12
24
  });
13
25
  //# sourceMappingURL=identifiers.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"identifiers.test.js","sourceRoot":"","sources":["../../../tests/lexer/identifiers.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,0EAA0E;QAC1E,qEAAqE;QACrE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC,uBAAuB,CAAC,CAAC;QAC7D,MAAM,CAAC,WAAW,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,UAAU,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChH,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"identifiers.test.js","sourceRoot":"","sources":["../../../tests/lexer/identifiers.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAErD,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,0EAA0E;QAC1E,qEAAqE;QACrE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC,uBAAuB,CAAC,CAAC;QAC7D,MAAM,CAAC,WAAW,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,UAAU,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC,eAAe,CAAC,CAAC;QACrD,MAAM,CAAC,WAAW,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACpC,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,UAAU,CAAC,CAAC;QAClF,MAAM,CAAC,WAAW,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACpC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC1D,MAAM,CAAC,WAAW,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxC,0EAA0E;QAC1E,wDAAwD;QACxD,MAAM,CAAC,WAAW,CAAC,CAAC,CAAE,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACpD,MAAM,CAAC,WAAW,CAAC,CAAC,CAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAE,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -77,6 +77,14 @@ describe("scanner", () => {
77
77
  expect(diagnostics).toHaveLength(0);
78
78
  expect(tokens[0].kind).toBe(TokenKind.Identifier);
79
79
  });
80
+ it("skips Chinese comments without disturbing the following token", () => {
81
+ const { tokens, diagnostics } = lex("// 中文行注释\n/* 多行\n中文块注释 */\nconst x = 1;");
82
+ expect(diagnostics).toHaveLength(0);
83
+ expect(tokens[0].kind).toBe(TokenKind.ConstKeyword);
84
+ expect(tokens[0].precededByLineBreak).toBe(true);
85
+ const identifier = tokens.find((token) => token.kind === TokenKind.Identifier);
86
+ expect(identifier.text).toBe("x");
87
+ });
80
88
  it("tracks whether a token is preceded by a line break", () => {
81
89
  const { tokens } = lex("a\nb c");
82
90
  const identifiers = tokens.filter((t) => t.kind === TokenKind.Identifier);
@@ -1 +1 @@
1
- {"version":3,"file":"scanner.test.js","sourceRoot":"","sources":["../../../tests/lexer/scanner.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scanner.test.js","sourceRoot":"","sources":["../../../tests/lexer/scanner.test.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,10 @@ function decoded(source) {
16
16
  function escaped(code) {
17
17
  return Buffer.from(String.fromCodePoint(code), "utf8").toString("latin1");
18
18
  }
19
+ /** The byte string `lex` hands the scanner for a piece of UTF-8 source text. */
20
+ function utf8(text) {
21
+ return Buffer.from(text, "utf8").toString("latin1");
22
+ }
19
23
  describe("scanner string literals", () => {
20
24
  it("decodes the simple control escapes", () => {
21
25
  expect(decoded('"a\\nb"')).toBe("a\nb");
@@ -48,6 +52,32 @@ describe("scanner string literals", () => {
48
52
  it("keeps surrogate pairs and non-ASCII characters intact", () => {
49
53
  expect(decoded('"héllo→"')).toBe(Buffer.from("héllo→", "utf8").toString("latin1"));
50
54
  });
55
+ it("keeps Chinese text and its unicode escapes as the same bytes", () => {
56
+ const expected = utf8("你好世界!");
57
+ // A literal is read from the file as UTF-8 bytes; an escape names code
58
+ // points and spells the same bytes. Both must reach codegen unchanged, or
59
+ // the program prints mojibake while its English lines stay readable.
60
+ expect(decoded('"你好世界!"')).toBe(expected);
61
+ expect(decoded('"\\u4f60\\u597d\\u4e16\\u754c\\uff01"')).toBe(expected);
62
+ expect(decoded('"\\u{4F60}\\u{597D}"')).toBe(utf8("你好"));
63
+ });
64
+ it("keeps a Chinese literal token's source and range intact", () => {
65
+ const { tokens, diagnostics } = lex('const s = "中文";\nconst t = 1;');
66
+ expect(diagnostics).toHaveLength(0);
67
+ const literal = tokens.find((token) => token.kind === TokenKind.StringLiteral);
68
+ const source = utf8('"中文"');
69
+ expect(literal.text).toBe(source);
70
+ expect(literal.start).toBe(utf8("const s = ").length);
71
+ expect(literal.end).toBe(literal.start + source.length);
72
+ });
73
+ it("keeps Chinese text in template literals and template heads", () => {
74
+ const plain = lex("`你好世界!`").tokens[0];
75
+ expect(plain.kind).toBe(TokenKind.NoSubstitutionTemplateLiteral);
76
+ expect(plain.value).toBe(utf8("你好世界!"));
77
+ const head = lex("`你好,${name}!`").tokens[0];
78
+ expect(head.kind).toBe(TokenKind.TemplateHead);
79
+ expect(head.value).toBe(utf8("你好,"));
80
+ });
51
81
  it("reports an unterminated string when a line break is reached", () => {
52
82
  const { diagnostics } = lex('"line\nnext"');
53
83
  expect(diagnostics.map((d) => d.code)).toContain(DiagnosticCode.UnterminatedString);
@@ -1 +1 @@
1
- {"version":3,"file":"strings.test.js","sourceRoot":"","sources":["../../../tests/lexer/strings.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"strings.test.js","sourceRoot":"","sources":["../../../tests/lexer/strings.test.ts"],"names":[],"mappings":"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"}
package/doc/ai/cli.md CHANGED
@@ -37,7 +37,7 @@ so restart it after installing a dependency.
37
37
  --out <dir> Output directory (default: build/)
38
38
  --emit <kind> exe | obj | ir (default: exe)
39
39
  -O0 .. -O3 Optimization level passed to clang (default: -O2)
40
- --ext <names> Enable bundled extensions, comma separated (e.g. node,gui)
40
+ --ext <names> Enable bundled extensions, comma separated (e.g. node,gui,media)
41
41
  --ext-native <m> Register a C++/Rust extension from a JSON manifest
42
42
  (comma separated for several)
43
43
  --config <path> Use this project config instead of discovering one
@@ -1,4 +1,4 @@
1
- # Extensions: Node modules, GUI, C++/Rust libraries
1
+ # Extensions: Node modules, GUI, media, C++/Rust libraries
2
2
 
3
3
  The compiler core is platform-agnostic. Anything platform-specific — Node's
4
4
  `fs`, an HTML/CSS renderer, your own C++ library — arrives as an **extension**
@@ -69,28 +69,40 @@ import { createWindow, run } from "gui";
69
69
 
70
70
  It is a self-contained GPU-accelerated renderer (own HTML parser, CSS cascade,
71
71
  layout and compositor) — not a system WebView. It ships as a per-platform
72
- prebuilt `gui.a`/`gui.lib` because it is C++. `<img>`, `<video>` and `<audio>`
73
- really decode: a minimal static FFmpeg is bundled into the archive, and the DOM
74
- media API (`play`/`pause`/`currentTime`/`volume`/…) plus the
75
- `loadedmetadata`/`play`/`pause`/`ended`/`timeupdate`/`error` events let a
76
- program drive playback. There are no built-in controls — draw your own chrome
77
- with elements and CSS (see `examples/gui/media.ts`). Video frames and audio PCM
78
- are decoded on the main thread. `<canvas>` is supported too: `getContext("2d")`
79
- returns a context whose fills, paths, gradients, text and `drawImage` are
80
- rasterised by a self-written CPU rasteriser (plus line caps/joins, dashed
81
- strokes, `ellipse` and `roundRect`), and element handles expose `canvas` drawing
82
- plus `width`/`height`. CSS `transform`/`transform-origin` work as paint-time
83
- effects, so a box (and the text, images and children in it) can be translated,
84
- scaled and rotated without reflowing anything — animate it per frame from
85
- `requestAnimationFrame` or with `transition: transform` (see
86
- `examples/gui/pelican-svg`). If that archive is missing for
87
- your platform, the build fails with an actionable message; design and roadmap
88
- live in [../gui.md](../gui.md) (overview; the engine is documented by function
89
- under [`doc/gui/`](../gui/)), and the scripting surface in
90
- [../gui-scripts.md](../gui-scripts.md). Media playback is the one part that
91
- Windows does not get: the Windows `gui.a` is built without FFmpeg and media
92
- slots are inert. See [../gui/canvas.md](../gui/canvas.md) for the canvas API and
93
- its limits.
72
+ prebuilt `gui.a`/`gui.lib` because it is C++. `<img>` decodes through the engine
73
+ itself; `<video>`/`<audio>` do **not** work with `gui` alone — they need the
74
+ separate [`media`](#media--videoaudio-decoding) extension. `<canvas>` is
75
+ supported too: `getContext("2d")` returns a context whose fills, paths,
76
+ gradients, text and `drawImage` are rasterised by a self-written CPU rasteriser
77
+ (plus line caps/joins, dashed strokes, `ellipse` and `roundRect`), and element
78
+ handles expose `canvas` drawing plus `width`/`height`. CSS
79
+ `transform`/`transform-origin` work as paint-time effects, so a box (and the
80
+ text, images and children in it) can be translated, scaled and rotated without
81
+ reflowing anything — animate it per frame from `requestAnimationFrame` or with
82
+ `transition: transform` (see `examples/gui/pelican-svg`). If the archive is
83
+ missing for your platform, the build fails with an actionable message; design
84
+ and roadmap live in [../gui.md](../gui.md) (overview; the engine is documented by
85
+ function under [`doc/gui/`](../gui/)), and the scripting surface in
86
+ [../gui-scripts.md](../gui-scripts.md). See
87
+ [../gui/canvas.md](../gui/canvas.md) for the canvas API and its limits.
88
+
89
+ ### `media` — video/audio decoding
90
+
91
+ Enable with `--ext media` **together with** `gui` (`--ext gui,media`; the
92
+ registry rejects `media` on its own). It links a separate FFmpeg-backed
93
+ `media.a`, so adding `<video>`/`<audio>` playback does not make a GUI-only
94
+ binary any larger.
95
+
96
+ The DOM API is the same as for any HTML media element: `play()` / `pause()` /
97
+ `load()`, the `paused` / `ended` / `duration` / `currentTime` / `volume` /
98
+ `muted` / `loop` / `autoplay` / `videoWidth` / `videoHeight` / `readyState` /
99
+ `src` properties, and `loadedmetadata`/`play`/`pause`/`ended`/`timeupdate`/
100
+ `error` events. There are no built-in controls — draw your own chrome with
101
+ elements and CSS (see `examples/gui/media.ts`). Video frames and audio PCM are
102
+ decoded on the main thread; video goes through the image texture path. Without
103
+ the extension, opening a media source fails and fires `error` (the element and
104
+ its API still exist). The archive is POSIX-only for now, so Windows reports the
105
+ same `error`; see [../gui/known-issues.md](../gui/known-issues.md).
94
106
 
95
107
  ## Third-party npm packages
96
108