yarn-spinner-runner-ts 0.1.0

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 (114) hide show
  1. package/README.md +180 -0
  2. package/dist/compile/compiler.d.ts +9 -0
  3. package/dist/compile/compiler.js +172 -0
  4. package/dist/compile/compiler.js.map +1 -0
  5. package/dist/compile/ir.d.ts +47 -0
  6. package/dist/compile/ir.js +2 -0
  7. package/dist/compile/ir.js.map +1 -0
  8. package/dist/index.d.ts +10 -0
  9. package/dist/index.js +11 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/model/ast.d.ts +72 -0
  12. package/dist/model/ast.js +2 -0
  13. package/dist/model/ast.js.map +1 -0
  14. package/dist/parse/lexer.d.ts +7 -0
  15. package/dist/parse/lexer.js +78 -0
  16. package/dist/parse/lexer.js.map +1 -0
  17. package/dist/parse/parser.d.ts +4 -0
  18. package/dist/parse/parser.js +433 -0
  19. package/dist/parse/parser.js.map +1 -0
  20. package/dist/runtime/commands.d.ts +31 -0
  21. package/dist/runtime/commands.js +157 -0
  22. package/dist/runtime/commands.js.map +1 -0
  23. package/dist/runtime/evaluator.d.ts +52 -0
  24. package/dist/runtime/evaluator.js +309 -0
  25. package/dist/runtime/evaluator.js.map +1 -0
  26. package/dist/runtime/results.d.ts +22 -0
  27. package/dist/runtime/results.js +2 -0
  28. package/dist/runtime/results.js.map +1 -0
  29. package/dist/runtime/runner.d.ts +63 -0
  30. package/dist/runtime/runner.js +456 -0
  31. package/dist/runtime/runner.js.map +1 -0
  32. package/dist/tests/full_featured.test.d.ts +1 -0
  33. package/dist/tests/full_featured.test.js +130 -0
  34. package/dist/tests/full_featured.test.js.map +1 -0
  35. package/dist/tests/index.test.d.ts +1 -0
  36. package/dist/tests/index.test.js +30 -0
  37. package/dist/tests/index.test.js.map +1 -0
  38. package/dist/tests/jump_detour.test.d.ts +1 -0
  39. package/dist/tests/jump_detour.test.js +47 -0
  40. package/dist/tests/jump_detour.test.js.map +1 -0
  41. package/dist/tests/nodes_lines.test.d.ts +1 -0
  42. package/dist/tests/nodes_lines.test.js +23 -0
  43. package/dist/tests/nodes_lines.test.js.map +1 -0
  44. package/dist/tests/once.test.d.ts +1 -0
  45. package/dist/tests/once.test.js +29 -0
  46. package/dist/tests/once.test.js.map +1 -0
  47. package/dist/tests/options.test.d.ts +1 -0
  48. package/dist/tests/options.test.js +32 -0
  49. package/dist/tests/options.test.js.map +1 -0
  50. package/dist/tests/variables_flow_cmds.test.d.ts +1 -0
  51. package/dist/tests/variables_flow_cmds.test.js +30 -0
  52. package/dist/tests/variables_flow_cmds.test.js.map +1 -0
  53. package/dist/types.d.ts +3 -0
  54. package/dist/types.js +2 -0
  55. package/dist/types.js.map +1 -0
  56. package/docs/commands.md +21 -0
  57. package/docs/compatibility-checklist.md +77 -0
  58. package/docs/css-attribute.md +47 -0
  59. package/docs/detour.md +24 -0
  60. package/docs/enums.md +25 -0
  61. package/docs/flow-control.md +25 -0
  62. package/docs/functions.md +20 -0
  63. package/docs/jumps.md +24 -0
  64. package/docs/line-groups.md +21 -0
  65. package/docs/lines-nodes-and-options.md +30 -0
  66. package/docs/logic-and-variables.md +25 -0
  67. package/docs/markup.md +19 -0
  68. package/docs/node-groups.md +13 -0
  69. package/docs/once.md +21 -0
  70. package/docs/options.md +45 -0
  71. package/docs/saliency.md +25 -0
  72. package/docs/scenes-actors-setup.md +195 -0
  73. package/docs/scenes.md +64 -0
  74. package/docs/shadow-lines.md +18 -0
  75. package/docs/smart-variables.md +19 -0
  76. package/docs/storylets-and-saliency-a-primer.md +14 -0
  77. package/docs/tags-metadata.md +18 -0
  78. package/eslint.config.cjs +33 -0
  79. package/examples/browser/README.md +40 -0
  80. package/examples/browser/index.html +23 -0
  81. package/examples/browser/main.tsx +16 -0
  82. package/examples/browser/vite.config.ts +22 -0
  83. package/examples/react/DialogueExample.tsx +2 -0
  84. package/examples/react/DialogueView.tsx +2 -0
  85. package/examples/react/useYarnRunner.tsx +2 -0
  86. package/examples/scenes/scenes.yaml +10 -0
  87. package/examples/yarn/full_featured.yarn +43 -0
  88. package/package.json +55 -0
  89. package/src/compile/compiler.ts +183 -0
  90. package/src/compile/ir.ts +28 -0
  91. package/src/index.ts +17 -0
  92. package/src/model/ast.ts +93 -0
  93. package/src/parse/lexer.ts +108 -0
  94. package/src/parse/parser.ts +435 -0
  95. package/src/react/DialogueExample.tsx +149 -0
  96. package/src/react/DialogueScene.tsx +107 -0
  97. package/src/react/DialogueView.tsx +160 -0
  98. package/src/react/dialogue.css +181 -0
  99. package/src/react/useYarnRunner.tsx +33 -0
  100. package/src/runtime/commands.ts +183 -0
  101. package/src/runtime/evaluator.ts +327 -0
  102. package/src/runtime/results.ts +27 -0
  103. package/src/runtime/runner.ts +480 -0
  104. package/src/scene/parser.ts +83 -0
  105. package/src/scene/types.ts +17 -0
  106. package/src/tests/full_featured.test.ts +131 -0
  107. package/src/tests/index.test.ts +34 -0
  108. package/src/tests/jump_detour.test.ts +47 -0
  109. package/src/tests/nodes_lines.test.ts +27 -0
  110. package/src/tests/once.test.ts +32 -0
  111. package/src/tests/options.test.ts +34 -0
  112. package/src/tests/variables_flow_cmds.test.ts +33 -0
  113. package/src/types.ts +4 -0
  114. package/tsconfig.json +21 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../../src/tests/index.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE7D,IAAI,CAAC,6BAA6B,EAAE,GAAG,EAAE;IACvC,MAAM,QAAQ,GAAG;;;;;;;;;CASlB,CAAC;IAEA,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IAChC,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACxB,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IAExD,MAAM,EAAE,GAAG,MAAM,CAAC,aAAc,CAAC;IACjC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC7B,MAAM,CAAC,OAAO,EAAE,CAAC;IACjB,MAAM,EAAE,GAAG,MAAM,CAAC,aAAc,CAAC;IACjC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAChC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAClB,MAAM,EAAE,GAAG,MAAM,CAAC,aAAc,CAAC;IACjC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC7B,IAAI,EAAE,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACvB,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,CAAC;IAClD,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,47 @@
1
+ import { test } from "node:test";
2
+ import { strictEqual } from "node:assert";
3
+ import { parseYarn, compile, YarnRunner } from "../index.js";
4
+ test("jump and detour", () => {
5
+ const script = `
6
+ title: Start
7
+ ---
8
+ Narrator: Go to Next
9
+ <<jump Next>>
10
+ ===
11
+
12
+ title: Next
13
+ ---
14
+ Narrator: In Next
15
+ <<detour Aside>>
16
+ Narrator: Back from Aside
17
+ ===
18
+
19
+ title: Aside
20
+ ---
21
+ Narrator: Inside Aside
22
+ ===
23
+ `;
24
+ const doc = parseYarn(script);
25
+ const ir = compile(doc);
26
+ const runner = new YarnRunner(ir, { startAt: "Start" });
27
+ const a = runner.currentResult;
28
+ strictEqual(a.type, "text");
29
+ if (a.type === "text")
30
+ strictEqual(/Go to Next/.test(a.text), true, "Expect first line");
31
+ runner.advance(); // executes jump, should produce Next's first line
32
+ const b = runner.currentResult;
33
+ strictEqual(b.type, "text");
34
+ if (b.type === "text")
35
+ strictEqual(/In Next/.test(b.text), true, "Expect Next node line");
36
+ runner.advance(); // should detour into Aside and emit its first line
37
+ const c = runner.currentResult;
38
+ strictEqual(c.type, "text");
39
+ if (c.type === "text")
40
+ strictEqual(/Inside Aside/.test(c.text), true, "Expect detour content");
41
+ runner.advance(); // should return from detour and continue
42
+ const d = runner.currentResult;
43
+ strictEqual(d.type, "text");
44
+ if (d.type === "text")
45
+ strictEqual(/Back from Aside/.test(d.text), true, "Expect return from detour");
46
+ });
47
+ //# sourceMappingURL=jump_detour.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jump_detour.test.js","sourceRoot":"","sources":["../../src/tests/jump_detour.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE7D,IAAI,CAAC,iBAAiB,EAAE,GAAG,EAAE;IAC3B,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;CAkBhB,CAAC;IAEA,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAC9B,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACxB,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IAExD,MAAM,CAAC,GAAG,MAAM,CAAC,aAAc,CAAC;IAChC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC5B,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;QAAE,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,mBAAmB,CAAC,CAAC;IACzF,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,kDAAkD;IACpE,MAAM,CAAC,GAAG,MAAM,CAAC,aAAc,CAAC;IAChC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC5B,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;QAAE,WAAW,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,uBAAuB,CAAC,CAAC;IAC1F,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,mDAAmD;IACrE,MAAM,CAAC,GAAG,MAAM,CAAC,aAAc,CAAC;IAChC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC5B,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;QAAE,WAAW,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,uBAAuB,CAAC,CAAC;IAC/F,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,yCAAyC;IAC3D,MAAM,CAAC,GAAG,MAAM,CAAC,aAAc,CAAC;IAChC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC5B,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;QAAE,WAAW,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,2BAA2B,CAAC,CAAC;AACxG,CAAC,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,23 @@
1
+ import { test } from "node:test";
2
+ import { strictEqual } from "node:assert";
3
+ import { parseYarn, compile, YarnRunner } from "../index.js";
4
+ test("nodes and lines delivery", () => {
5
+ const script = `
6
+ title: Start
7
+ ---
8
+ Narrator: Line one
9
+ Narrator: Line two
10
+ ===
11
+ `;
12
+ const doc = parseYarn(script);
13
+ const ir = compile(doc);
14
+ const runner = new YarnRunner(ir, { startAt: "Start" });
15
+ strictEqual(runner.currentResult?.type, "text", "Expected first result to be text");
16
+ strictEqual(runner.currentResult?.text.includes("Line one"), true, "Expected 'Line one'");
17
+ runner.advance();
18
+ strictEqual(runner.currentResult?.type, "text", "Should still be text");
19
+ strictEqual(runner.currentResult?.text.includes("Line two"), true, "Expected 'Line two'");
20
+ runner.advance();
21
+ strictEqual(runner.currentResult?.isDialogueEnd, true, "Expected dialogue end after lines");
22
+ });
23
+ //# sourceMappingURL=nodes_lines.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nodes_lines.test.js","sourceRoot":"","sources":["../../src/tests/nodes_lines.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE7D,IAAI,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACpC,MAAM,MAAM,GAAG;;;;;;CAMhB,CAAC;IAEA,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAC9B,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACxB,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IAExD,WAAW,CAAC,MAAM,CAAC,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,kCAAkC,CAAC,CAAC;IACpF,WAAW,CAAC,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,qBAAqB,CAAC,CAAC;IAC1F,MAAM,CAAC,OAAO,EAAE,CAAC;IACjB,WAAW,CAAC,MAAM,CAAC,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,sBAAsB,CAAC,CAAC;IACxE,WAAW,CAAC,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,qBAAqB,CAAC,CAAC;IAC1F,MAAM,CAAC,OAAO,EAAE,CAAC;IACjB,WAAW,CAAC,MAAM,CAAC,aAAa,EAAE,aAAa,EAAE,IAAI,EAAE,mCAAmC,CAAC,CAAC;AAC9F,CAAC,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,29 @@
1
+ import { test } from "node:test";
2
+ import { strictEqual } from "node:assert";
3
+ import { parseYarn, compile, YarnRunner } from "../index.js";
4
+ test("once block behavior", () => {
5
+ const script = `
6
+ title: Start
7
+ ---
8
+ <<once>>
9
+ Narrator: One time only
10
+ <<endonce>>
11
+ Narrator: Always
12
+ ===
13
+ `;
14
+ const doc = parseYarn(script);
15
+ const ir = compile(doc);
16
+ // First run
17
+ let runner = new YarnRunner(ir, { startAt: "Start" });
18
+ const a = runner.currentResult;
19
+ strictEqual(a.type, "text");
20
+ if (a.type === "text")
21
+ strictEqual(/One time only/.test(a.text), true, "Expect once block content on first run");
22
+ runner.advance();
23
+ const b = runner.currentResult;
24
+ strictEqual(b.type, "text");
25
+ if (b.type === "text")
26
+ strictEqual(/Always/.test(b.text), true, "Expect always line after once");
27
+ // Note: persistence of once across sessions depends on integration; not asserting second run behavior here.
28
+ });
29
+ //# sourceMappingURL=once.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"once.test.js","sourceRoot":"","sources":["../../src/tests/once.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE7D,IAAI,CAAC,qBAAqB,EAAE,GAAG,EAAE;IAC/B,MAAM,MAAM,GAAG;;;;;;;;CAQhB,CAAC;IAEA,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAC9B,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAExB,YAAY;IACZ,IAAI,MAAM,GAAG,IAAI,UAAU,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IACtD,MAAM,CAAC,GAAG,MAAM,CAAC,aAAc,CAAC;IAChC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC5B,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;QAAE,WAAW,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,wCAAwC,CAAC,CAAC;IACjH,MAAM,CAAC,OAAO,EAAE,CAAC;IACjB,MAAM,CAAC,GAAG,MAAM,CAAC,aAAc,CAAC;IAChC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC5B,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;QAAE,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,+BAA+B,CAAC,CAAC;IAEjG,4GAA4G;AAC9G,CAAC,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,32 @@
1
+ import { test } from "node:test";
2
+ import { strictEqual } from "node:assert";
3
+ import { parseYarn, compile, YarnRunner } from "../index.js";
4
+ test("options selection", () => {
5
+ const script = `
6
+ title: Start
7
+ ---
8
+ Narrator: Choose one
9
+ -> A
10
+ Narrator: Picked A
11
+ -> B
12
+ Narrator: Picked B
13
+ ===
14
+ `;
15
+ const doc = parseYarn(script);
16
+ const ir = compile(doc);
17
+ const runner = new YarnRunner(ir, { startAt: "Start" });
18
+ const a = runner.currentResult;
19
+ strictEqual(a.type, "text", "Expected intro text");
20
+ runner.advance();
21
+ const b = runner.currentResult;
22
+ strictEqual(b.type, "options", "Expected options after intro");
23
+ if (b.type === "options")
24
+ strictEqual(b.options.length, 2, "Should have 2 options");
25
+ // choose B (index 1)
26
+ runner.advance(1);
27
+ const c = runner.currentResult;
28
+ strictEqual(c.type, "text", "Should be text after selection");
29
+ if (c.type === "text")
30
+ strictEqual(c.text.includes("Picked B"), true, "Expected body of option B");
31
+ });
32
+ //# sourceMappingURL=options.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.test.js","sourceRoot":"","sources":["../../src/tests/options.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE7D,IAAI,CAAC,mBAAmB,EAAE,GAAG,EAAE;IAC7B,MAAM,MAAM,GAAG;;;;;;;;;CAShB,CAAC;IAEA,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAC9B,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACxB,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IAExD,MAAM,CAAC,GAAG,MAAM,CAAC,aAAc,CAAC;IAChC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,qBAAqB,CAAC,CAAC;IACnD,MAAM,CAAC,OAAO,EAAE,CAAC;IACjB,MAAM,CAAC,GAAG,MAAM,CAAC,aAAc,CAAC;IAChC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,8BAA8B,CAAC,CAAC;IAC/D,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS;QAAE,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,uBAAuB,CAAC,CAAC;IACpF,qBAAqB;IACrB,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAClB,MAAM,CAAC,GAAG,MAAM,CAAC,aAAc,CAAC;IAChC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,gCAAgC,CAAC,CAAC;IAC9D,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;QAAE,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,2BAA2B,CAAC,CAAC;AACrG,CAAC,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,30 @@
1
+ import { test } from "node:test";
2
+ import { strictEqual } from "node:assert";
3
+ import { parseYarn, compile, YarnRunner } from "../index.js";
4
+ test("variables, flow control, and commands", () => {
5
+ const script = `
6
+ title: Start
7
+ ---
8
+ <<set $score to 10>>
9
+ <<if $score >= 10>>
10
+ Narrator: High
11
+ <<else>>
12
+ Narrator: Low
13
+ <<endif>>
14
+ ===
15
+ `;
16
+ const doc = parseYarn(script);
17
+ const ir = compile(doc);
18
+ const runner = new YarnRunner(ir, { startAt: "Start" });
19
+ // After command, expect if-branch 'High'
20
+ // First result should be command emission
21
+ const a = runner.currentResult;
22
+ strictEqual(a.type, "command", "First result should be command");
23
+ runner.advance();
24
+ const b = runner.currentResult;
25
+ strictEqual(b.type, "text", "Should be text after command");
26
+ if (b.type === "text")
27
+ strictEqual(/High/.test(b.text), true, "Expected High branch");
28
+ strictEqual(runner.getVariable("score"), 10, "Variable should be set");
29
+ });
30
+ //# sourceMappingURL=variables_flow_cmds.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"variables_flow_cmds.test.js","sourceRoot":"","sources":["../../src/tests/variables_flow_cmds.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE7D,IAAI,CAAC,uCAAuC,EAAE,GAAG,EAAE;IACjD,MAAM,MAAM,GAAG;;;;;;;;;;CAUhB,CAAC;IAEA,MAAM,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAC9B,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACxB,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IAExD,yCAAyC;IACzC,0CAA0C;IAC1C,MAAM,CAAC,GAAG,MAAM,CAAC,aAAc,CAAC;IAChC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,gCAAgC,CAAC,CAAC;IACjE,MAAM,CAAC,OAAO,EAAE,CAAC;IACjB,MAAM,CAAC,GAAG,MAAM,CAAC,aAAc,CAAC;IAChC,WAAW,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,8BAA8B,CAAC,CAAC;IAC5D,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;QAAE,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,sBAAsB,CAAC,CAAC;IACtF,WAAW,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,wBAAwB,CAAC,CAAC;AACzE,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export type { YarnDocument, YarnNode, Statement, Line, Command, OptionGroup, Option, IfBlock, OnceBlock, Jump, Detour } from "./model/ast";
2
+ export type { IRProgram, IRNode, IRInstruction } from "./compile/ir";
3
+ export type { RuntimeResult, TextResult, OptionsResult, CommandResult } from "./runtime/results";
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,21 @@
1
+ ## Commands (Yarn Spinner)
2
+
3
+ Source: [docs.yarnspinner.dev — Commands](https://docs.yarnspinner.dev/write-yarn-scripts/scripting-fundamentals/commands)
4
+
5
+ ### What it covers
6
+ - Inline instructions to the host game/engine using `<<command ...>>`.
7
+ - Often used to trigger animations, SFX, gameplay events, or state changes.
8
+
9
+ ### Examples
10
+ ```yarn
11
+ title: Start
12
+ ---
13
+ Narrator: Opening the door.
14
+ <<play_sfx name="door_open">>
15
+ <<animate target="Door" action="Open">>
16
+ ===
17
+ ```
18
+
19
+ Exact command names and parameters are defined by your game integration.
20
+
21
+
@@ -0,0 +1,77 @@
1
+ # Yarn Spinner Compatibility Checklist
2
+
3
+ This document tracks compatibility with the official Yarn Spinner documentation.
4
+
5
+ ## ✅ Implemented Features
6
+
7
+ ### Variables
8
+ - ✅ Variable storage (numbers, strings, booleans)
9
+ - ✅ `<<set>>` command
10
+ - ✅ Basic operators: `==`, `!=`, `>`, `<`, `<=`, `>=`, `&&`, `||`, `!`
11
+ - ✅ Variable usage in condition expressions
12
+ - ✅ Implicit variable declaration (when not declared, defaults to 0/false/"")
13
+
14
+ ### Flow Control
15
+ - ✅ `{if condition}...{endif}` blocks (using `{if}` syntax instead of `<<if>>`)
16
+ - ✅ `{else if condition}` branches
17
+ - ✅ `{else}` branches
18
+ - ✅ Condition evaluation in if/elseif
19
+
20
+ ## ❌ Missing Features
21
+
22
+ ### Variables
23
+ 1. **`<<declare>>` command** - Not implemented
24
+ - Docs: `<<declare $playerName = "Reginald the Wizard">>`
25
+ - Status: Missing
26
+
27
+ 2. **Variable substitution in lines** - Not implemented
28
+ - Docs: `The value is {$variableName}.`
29
+ - Status: Variables are stored but not substituted into line text at runtime
30
+
31
+ 3. **`<<set>>` with `to` keyword** - Partially supported
32
+ - Docs: `<<set $greeting to "Hello, Yarn!">>`
33
+ - Status: Currently supports `<<set var value>>` or `<<set var = value>>`, but not `to` keyword
34
+
35
+ 4. **Math expressions in `<<set>>`** - Partially supported
36
+ - Docs: `<<set $x = 2 + 1>>`
37
+ - Status: Value is parsed but expressions aren't evaluated (e.g., `"2 + 1"` stored as string, not `3`)
38
+
39
+ 5. **Additional operator aliases** - Missing
40
+ - Docs support: `eq`, `is`, `neq`, `gt`, `lt`, `lte`, `gte`, `xor`, `not`, `and`, `or`
41
+ - Status: We support: `==`, `!=`, `>`, `<`, `<=`, `>=`, `&&`, `||`, `!`
42
+ - Missing: `eq`, `is`, `neq`, `gt`, `lt`, `lte`, `gte`, `xor`, `not`, `and`, `or` aliases
43
+
44
+ 6. **Type conversion functions** - Not implemented
45
+ - Docs: `string()`, `number()`, `bool()` functions
46
+ - Status: Missing
47
+
48
+ 7. **`$` prefix for variables** - Not enforced
49
+ - Docs: Variables should start with `$` (e.g., `$gold`)
50
+ - Status: We accept variables without `$` prefix
51
+
52
+ ### Flow Control
53
+ 8. **Conditional options** - Not implemented
54
+ - Docs: `-> Option text <<if $reputation > 10>>`
55
+ - Status: Options can't have conditions attached
56
+
57
+ 9. **`<<if>>` command blocks** - Different syntax
58
+ - Docs: `<<if condition>>...<<endif>>`
59
+ - Status: We use `{if condition}...{endif}` (inline markup) instead
60
+ - Note: This is a valid alternative syntax, just different from docs
61
+
62
+ ## Recommendations
63
+
64
+ To improve compatibility, consider implementing:
65
+
66
+ 1. **Variable substitution** (`{$var}`) - High priority
67
+ 2. **Math expressions in `<<set>>`** - High priority
68
+ 3. **Conditional options** - Medium priority
69
+ 4. **`<<declare>>` command** - Medium priority
70
+ 5. **Operator aliases** (`eq`, `gt`, etc.) - Low priority
71
+ 6. **Type conversion functions** - Low priority
72
+
73
+ ## Syntax Differences
74
+
75
+ - **If blocks**: We use `{if}...{endif}` instead of `<<if>>...<<endif>>`
76
+ - This is valid Yarn syntax, just a different style
77
+
@@ -0,0 +1,47 @@
1
+ ## Custom CSS Attribute (&css{})
2
+
3
+ This project adds a custom `&css{}` attribute to Yarn scripts to carry UI styles to consumers (e.g., React components).
4
+
5
+ ### Node-level CSS
6
+
7
+ Attach a CSS block to a node header value by starting it with `&css{` and closing it with `}`. The block may span multiple lines until the closing brace, and must appear before the `---` line.
8
+
9
+ ```yarn
10
+ title: Scene2
11
+ style: &css{
12
+ backgroundColor: red;
13
+ color: white;
14
+ fontFamily: "Arial", sans-serif;
15
+ }
16
+ ---
17
+ Narrator: Hello!
18
+ ===
19
+ ```
20
+
21
+ Parsed into `YarnNode.css` and propagated to IR (`IRNode.css`).
22
+
23
+ ### Option-level CSS (inline)
24
+
25
+ Append an inline `&css{...}` to an option text to style that option.
26
+
27
+ ```yarn
28
+ -> Option 1 &css{backgroundColor: blue; color: white;}
29
+ Narrator: You chose option 1.
30
+ -> Option 2 &css{backgroundColor: green; color: black;}
31
+ Narrator: You chose option 2.
32
+ ```
33
+
34
+ Parsed into `Option.css`, passed through IR, and emitted at runtime on `options` results:
35
+
36
+ ```ts
37
+ if (result.type === "options") {
38
+ // result.options[i].css contains the inline CSS string
39
+ }
40
+ ```
41
+
42
+ ### Notes
43
+
44
+ - The CSS content is treated as a raw string (not parsed). Use a simple `property: value;` format that your UI layer can interpret.
45
+ - This feature is additive and does not affect core Yarn semantics.
46
+
47
+
package/docs/detour.md ADDED
@@ -0,0 +1,24 @@
1
+ ## Detour Command (Yarn Spinner)
2
+
3
+ Source: [docs.yarnspinner.dev — Detour](https://docs.yarnspinner.dev/write-yarn-scripts/scripting-fundamentals/detour)
4
+
5
+ ### What it covers
6
+ - **`<<detour NodeTitle>>`**: temporarily visit another node and return when it finishes.
7
+ - Useful for side conversations, tooltips, or contextual asides.
8
+
9
+ ### Example
10
+ ```yarn
11
+ title: Main
12
+ ---
13
+ Narrator: Before we continue, a quick aside.
14
+ <<detour Aside>>
15
+ Narrator: Back to the main thread.
16
+ ===
17
+
18
+ title: Aside
19
+ ---
20
+ Narrator: Here's some extra info.
21
+ ===
22
+ ```
23
+
24
+
package/docs/enums.md ADDED
@@ -0,0 +1,25 @@
1
+ ## Enums (Yarn Spinner)
2
+
3
+ Source: [docs.yarnspinner.dev — Enums](https://docs.yarnspinner.dev/write-yarn-scripts/scripting-fundamentals/enums)
4
+
5
+ ### What it covers
6
+ - Define named sets of values for clarity and safety.
7
+ - Compare enum values in conditions and assignments.
8
+
9
+ ### Example
10
+ ```yarn
11
+ title: Setup
12
+ ---
13
+ <<declare Mood = enum { Happy, Neutral, Sad }>>
14
+ <<set currentMood = Mood.Happy>>
15
+ ===
16
+
17
+ title: Check
18
+ ---
19
+ {if currentMood == Mood.Happy}
20
+ NPC: Great to see you!
21
+ {endif}
22
+ ===
23
+ ```
24
+
25
+
@@ -0,0 +1,25 @@
1
+ ## Flow Control (Yarn Spinner)
2
+
3
+ Source: [docs.yarnspinner.dev — Flow Control](https://docs.yarnspinner.dev/write-yarn-scripts/scripting-fundamentals/flow-control)
4
+
5
+ ### What it covers
6
+ - Conditional blocks with `{if}`, `{else if}`, `{else}`, `{endif}`.
7
+ - Loops and structural control features provided by Yarn (engine-dependent usage).
8
+ - Combining flow with variables and options.
9
+
10
+ ### Example
11
+ ```yarn
12
+ title: Start
13
+ ---
14
+ <<set affinity = 3>>
15
+ {if affinity >= 5}
16
+ NPC: We're close friends.
17
+ {else if affinity >= 2}
18
+ NPC: We're friendly enough.
19
+ {else}
20
+ NPC: Do I know you?
21
+ {endif}
22
+ ===
23
+ ```
24
+
25
+
@@ -0,0 +1,20 @@
1
+ ## Functions (Yarn Spinner)
2
+
3
+ Source: [docs.yarnspinner.dev — Functions](https://docs.yarnspinner.dev/write-yarn-scripts/scripting-fundamentals/functions)
4
+
5
+ ### What it covers
6
+ - Use functions in expressions for calculations and queries.
7
+ - Custom functions can be exposed by the host game.
8
+
9
+ ### Examples
10
+ ```yarn
11
+ title: Start
12
+ ---
13
+ <<set total = add(2, 3)>>
14
+ Narrator: The total is {total}.
15
+ ===
16
+ ```
17
+
18
+ Function names/arity/behavior depend on your integration’s function bindings.
19
+
20
+
package/docs/jumps.md ADDED
@@ -0,0 +1,24 @@
1
+ ## Jump Command (Yarn Spinner)
2
+
3
+ Source: [docs.yarnspinner.dev — Jump Command](https://docs.yarnspinner.dev/write-yarn-scripts/scripting-fundamentals/jumps)
4
+
5
+ ### What it covers
6
+ - **`<<jump NodeTitle>>`**: transfer execution to another node by title.
7
+ - Visualized in graph views as an arrow to the target node.
8
+ - Works across files; node titles must be unique in the project.
9
+
10
+ ### Example
11
+ ```yarn
12
+ title: Start
13
+ ---
14
+ Narrator: Proceeding to the next scene.
15
+ <<jump NextScene>>
16
+ ===
17
+
18
+ title: NextScene
19
+ ---
20
+ Narrator: We are in the next scene.
21
+ ===
22
+ ```
23
+
24
+
@@ -0,0 +1,21 @@
1
+ ## Line Groups (Yarn Spinner)
2
+
3
+ Source: [docs.yarnspinner.dev — Line Groups](https://docs.yarnspinner.dev/write-yarn-scripts/scripting-fundamentals/line-groups)
4
+
5
+ ### What it covers
6
+ - Group related lines for localization, organization, or metadata.
7
+ - Often used to assign tags or manage VO/loc pipelines.
8
+
9
+ ### Example (conceptual)
10
+ ```yarn
11
+ title: Start
12
+ ---
13
+ // Lines here can be assigned to a group via editor metadata.
14
+ Narrator: Grouped line A.
15
+ Narrator: Grouped line B.
16
+ ===
17
+ ```
18
+
19
+ Details vary by tooling (e.g., Yarn Spinner Editor/VS Code integration).
20
+
21
+
@@ -0,0 +1,30 @@
1
+ ## Nodes and Lines (Yarn Spinner)
2
+
3
+ Source: [docs.yarnspinner.dev — Nodes and Lines](https://docs.yarnspinner.dev/write-yarn-scripts/scripting-fundamentals/lines-nodes-and-options)
4
+
5
+ ### What it covers
6
+ - **Nodes**: titled containers for dialogue. Headers above `---`, body between `---` and `===`.
7
+ - **Lines**: dialogue or narration lines emitted to the game one at a time.
8
+ - **Character prefix**: `Name: Dialogue` marks the speaking character.
9
+ - **Node rules**: titles start with a letter; letters/numbers/underscores only; no `.`.
10
+
11
+ ### Basic structure
12
+ ```yarn
13
+ title: Start
14
+ ---
15
+ Narrator: Hi, I'm the narrator for the documentation!
16
+ ===
17
+ ```
18
+
19
+ ### Character speaking vs narration
20
+ ```yarn
21
+ This is a line of dialogue, without a character name.
22
+ Speaker: This is another line said by a character called "Speaker".
23
+ ```
24
+
25
+ ### Tips
26
+ - Use multiple nodes to manage long or branching stories.
27
+ - Additional headers (e.g., `color:`, `group:`) organize nodes in editors.
28
+ - The game decides how to render each delivered line.
29
+
30
+
@@ -0,0 +1,25 @@
1
+ ## Logic and Variables (Yarn Spinner)
2
+
3
+ Source: [docs.yarnspinner.dev — Logic and Variables](https://docs.yarnspinner.dev/write-yarn-scripts/scripting-fundamentals/logic-and-variables)
4
+
5
+ ### What it covers
6
+ - Declaring and using variables; reading and writing from the game.
7
+ - Basic expressions for conditions and assignments.
8
+ - Interpolating values in lines.
9
+
10
+ ### Examples
11
+ ```yarn
12
+ title: Start
13
+ ---
14
+ <<set hasKey = true>>
15
+ <<set score = 10 + 5>>
16
+
17
+ {if hasKey}
18
+ Narrator: You unlock the door. Score: {score}
19
+ {else}
20
+ Narrator: The door is locked.
21
+ {endif}
22
+ ===
23
+ ```
24
+
25
+
package/docs/markup.md ADDED
@@ -0,0 +1,19 @@
1
+ ## Markup (Yarn Spinner)
2
+
3
+ Source: [docs.yarnspinner.dev — Markup](https://docs.yarnspinner.dev/write-yarn-scripts/advanced-scripting/markup)
4
+
5
+ ### What it covers
6
+ - Rich text features embedded in lines (emphasis, links, inline commands).
7
+ - Parsed and passed to the host for rendering.
8
+
9
+ ### Example
10
+ ```yarn
11
+ title: Start
12
+ ---
13
+ Narrator: This is *italic*, this is **bold**, and this is a [link](game:codex/entry1).
14
+ ===
15
+ ```
16
+
17
+ Supported markup and rendering vary by integration.
18
+
19
+
@@ -0,0 +1,13 @@
1
+ ## Node Groups (Yarn Spinner)
2
+
3
+ Source: [docs.yarnspinner.dev — Node Groups](https://docs.yarnspinner.dev/write-yarn-scripts/advanced-scripting/node-groups)
4
+
5
+ ### What it covers
6
+ - Organize nodes into higher-level groups for structure and navigation.
7
+ - Helpful in large projects for editor graph organization and categorization.
8
+
9
+ ### Usage
10
+ - Assign `group:` headers in nodes to categorize.
11
+ - Use editor features to visualize and manage grouped nodes.
12
+
13
+
package/docs/once.md ADDED
@@ -0,0 +1,21 @@
1
+ ## Once (Yarn Spinner)
2
+
3
+ Source: [docs.yarnspinner.dev — Once](https://docs.yarnspinner.dev/write-yarn-scripts/scripting-fundamentalsendonce)
4
+
5
+ ### What it covers
6
+ - Ensure a section runs only the first time it’s reached.
7
+ - Useful for tutorials, first-time greetings, unique rewards.
8
+
9
+ ### Example
10
+ ```yarn
11
+ title: Start
12
+ ---
13
+ <<once>>
14
+ Guide: Welcome! This shows only once.
15
+ <<endonce>>
16
+
17
+ Guide: This shows every time.
18
+ ===
19
+ ```
20
+
21
+