yarn-spinner-runner-ts 0.1.0 → 0.1.1-b
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/.github/workflows/npm-publish-github-packages.yml +39 -0
- package/README.md +205 -20
- package/dist/compile/compiler.js +5 -3
- package/dist/compile/compiler.js.map +1 -1
- package/dist/compile/ir.d.ts +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/parse/parser.js +5 -2
- package/dist/parse/parser.js.map +1 -1
- package/dist/react/DialogueExample.d.ts +1 -0
- package/dist/react/DialogueExample.js +105 -0
- package/dist/react/DialogueExample.js.map +1 -0
- package/dist/react/DialogueScene.d.ts +11 -0
- package/dist/react/DialogueScene.js +70 -0
- package/dist/react/DialogueScene.js.map +1 -0
- package/dist/react/DialogueView.d.ts +9 -0
- package/dist/react/DialogueView.js +94 -0
- package/dist/react/DialogueView.js.map +1 -0
- package/dist/react/useYarnRunner.d.ts +8 -0
- package/dist/react/useYarnRunner.js +18 -0
- package/dist/react/useYarnRunner.js.map +1 -0
- package/dist/runtime/commands.js +1 -1
- package/dist/runtime/commands.js.map +1 -1
- package/dist/runtime/evaluator.js +0 -1
- package/dist/runtime/evaluator.js.map +1 -1
- package/dist/runtime/results.d.ts +4 -0
- package/dist/runtime/runner.js +3 -3
- package/dist/runtime/runner.js.map +1 -1
- package/dist/scene/parser.d.ts +9 -0
- package/dist/scene/parser.js +78 -0
- package/dist/scene/parser.js.map +1 -0
- package/dist/scene/types.d.ts +13 -0
- package/dist/scene/types.js +5 -0
- package/dist/scene/types.js.map +1 -0
- package/eslint.config.cjs +3 -0
- package/examples/browser/main.tsx +2 -0
- package/package.json +3 -2
- package/scripts/run-tests.js +57 -0
- package/src/react/DialogueScene.tsx +2 -1
- package/src/react/DialogueView.tsx +2 -1
- package/src/react/css.d.ts +9 -0
- package/src/react/useYarnRunner.tsx +3 -1
- package/src/runtime/commands.ts +1 -4
- package/src/runtime/evaluator.ts +0 -1
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scene configuration parser using js-yaml
|
|
3
|
+
* Supports YAML string or plain object
|
|
4
|
+
*/
|
|
5
|
+
import yaml from "js-yaml";
|
|
6
|
+
/**
|
|
7
|
+
* Parse scene configuration from YAML string or object
|
|
8
|
+
*/
|
|
9
|
+
export function parseScenes(input) {
|
|
10
|
+
// If already an object, use it directly
|
|
11
|
+
if (typeof input === "object" && input !== null) {
|
|
12
|
+
return parseScenesFromObject(input);
|
|
13
|
+
}
|
|
14
|
+
// Parse YAML string
|
|
15
|
+
try {
|
|
16
|
+
const parsed = yaml.load(input);
|
|
17
|
+
return parseScenesFromObject(parsed || {});
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
console.error("Failed to parse YAML scene config:", error);
|
|
21
|
+
throw new Error(`Invalid YAML scene configuration: ${error instanceof Error ? error.message : String(error)}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function parseScenesFromObject(obj) {
|
|
25
|
+
const scenes = {};
|
|
26
|
+
// Extract global actors if defined separately
|
|
27
|
+
const globalActors = {};
|
|
28
|
+
if (typeof obj.actors === "object" && obj.actors !== null) {
|
|
29
|
+
for (const [actorName, actorData] of Object.entries(obj.actors)) {
|
|
30
|
+
if (typeof actorData === "object" && actorData !== null) {
|
|
31
|
+
// Nested format: actorName: { image: "..." }
|
|
32
|
+
globalActors[actorName] = {
|
|
33
|
+
image: typeof actorData.image === "string" ? actorData.image : undefined,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
else if (typeof actorData === "string") {
|
|
37
|
+
// Shorthand: actorName: "/path/to/image.png"
|
|
38
|
+
globalActors[actorName] = { image: actorData };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Parse scenes
|
|
43
|
+
if (typeof obj.scenes === "object" && obj.scenes !== null) {
|
|
44
|
+
const scenesObj = obj.scenes;
|
|
45
|
+
for (const [sceneName, sceneData] of Object.entries(scenesObj)) {
|
|
46
|
+
if (typeof sceneData === "object" && sceneData !== null) {
|
|
47
|
+
const data = sceneData;
|
|
48
|
+
const sceneActors = { ...globalActors }; // Start with global actors
|
|
49
|
+
// Override with scene-specific actors if defined
|
|
50
|
+
if (typeof data.actors === "object" && data.actors !== null) {
|
|
51
|
+
for (const [actorName, actorData] of Object.entries(data.actors)) {
|
|
52
|
+
if (typeof actorData === "object" && actorData !== null) {
|
|
53
|
+
sceneActors[actorName] = {
|
|
54
|
+
image: typeof actorData.image === "string" ? actorData.image : undefined,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
else if (typeof actorData === "string") {
|
|
58
|
+
sceneActors[actorName] = { image: actorData };
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
scenes[sceneName] = {
|
|
63
|
+
background: typeof data.background === "string" ? data.background : "",
|
|
64
|
+
actors: sceneActors,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
else if (typeof sceneData === "string") {
|
|
68
|
+
// Shorthand: scene1: "/path/to/background.png" (uses global actors)
|
|
69
|
+
scenes[sceneName] = {
|
|
70
|
+
background: sceneData,
|
|
71
|
+
actors: { ...globalActors },
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return { scenes };
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/scene/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scene configuration types
|
|
3
|
+
*/
|
|
4
|
+
export interface ActorConfig {
|
|
5
|
+
image?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface SceneConfig {
|
|
8
|
+
background: string;
|
|
9
|
+
actors: Record<string, ActorConfig>;
|
|
10
|
+
}
|
|
11
|
+
export interface SceneCollection {
|
|
12
|
+
scenes: Record<string, SceneConfig>;
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/scene/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
package/eslint.config.cjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { createRoot } from "react-dom/client";
|
|
3
3
|
import { DialogueExample } from "../../src/react/DialogueExample.js";
|
|
4
|
+
// Import CSS for dialogue system
|
|
5
|
+
import "../../src/react/dialogue.css";
|
|
4
6
|
|
|
5
7
|
const rootEl = document.getElementById("root");
|
|
6
8
|
if (!rootEl) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yarn-spinner-runner-ts",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1b",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "TypeScript parser, compiler, and runtime for Yarn Spinner 3.x with React adapter",
|
|
6
6
|
"license": "MIT",
|
|
@@ -13,8 +13,9 @@
|
|
|
13
13
|
"clean": "rimraf dist",
|
|
14
14
|
"dev": "tsc -w -p tsconfig.json",
|
|
15
15
|
"lint": "eslint \"src/**/*.ts\" \"src/**/*.tsx\"",
|
|
16
|
+
"ts-check": "tsc -p tsconfig.json",
|
|
16
17
|
"pretest": "npm run build",
|
|
17
|
-
"test": "node
|
|
18
|
+
"test": "node scripts/run-tests.js",
|
|
18
19
|
"demo": "vite --config examples/browser/vite.config.ts --host 0.0.0.0",
|
|
19
20
|
"demo:build": "vite build --config examples/browser/vite.config.ts"
|
|
20
21
|
},
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Test runner script that discovers and runs all test files
|
|
5
|
+
* This ensures cross-platform compatibility (Windows, Linux, macOS)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { readdir } from "fs/promises";
|
|
9
|
+
import { join, dirname } from "path";
|
|
10
|
+
import { fileURLToPath } from "url";
|
|
11
|
+
import { spawn } from "child_process";
|
|
12
|
+
|
|
13
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
+
const __dirname = dirname(__filename);
|
|
15
|
+
const projectRoot = join(__dirname, "..");
|
|
16
|
+
const testsDir = join(projectRoot, "dist", "tests");
|
|
17
|
+
|
|
18
|
+
async function findTestFiles() {
|
|
19
|
+
try {
|
|
20
|
+
const files = await readdir(testsDir);
|
|
21
|
+
return files
|
|
22
|
+
.filter((file) => file.endsWith(".test.js"))
|
|
23
|
+
.map((file) => join(testsDir, file));
|
|
24
|
+
} catch (error) {
|
|
25
|
+
console.error(`Error reading tests directory: ${error.message}`);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function runTests() {
|
|
31
|
+
const testFiles = await findTestFiles();
|
|
32
|
+
|
|
33
|
+
if (testFiles.length === 0) {
|
|
34
|
+
console.error("No test files found!");
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
console.log(`Found ${testFiles.length} test file(s):`);
|
|
39
|
+
testFiles.forEach((file) => console.log(` - ${file}`));
|
|
40
|
+
|
|
41
|
+
const args = ["--test", "--enable-source-maps", ...testFiles];
|
|
42
|
+
|
|
43
|
+
const proc = spawn("node", args, {
|
|
44
|
+
stdio: "inherit",
|
|
45
|
+
cwd: projectRoot,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
proc.on("exit", (code) => {
|
|
49
|
+
process.exit(code || 0);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
runTests().catch((error) => {
|
|
54
|
+
console.error(`Error running tests: ${error.message}`);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
});
|
|
57
|
+
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { useState, useEffect } from "react";
|
|
2
2
|
import type { SceneCollection, SceneConfig } from "../scene/types.js";
|
|
3
|
-
|
|
3
|
+
// Note: CSS is imported in the browser demo entry point (examples/browser/main.tsx)
|
|
4
|
+
// This prevents Node.js from trying to resolve CSS imports during tests
|
|
4
5
|
|
|
5
6
|
export interface DialogueSceneProps {
|
|
6
7
|
sceneName?: string;
|
|
@@ -2,7 +2,8 @@ import React from "react";
|
|
|
2
2
|
import type { RuntimeResult } from "../runtime/results.js";
|
|
3
3
|
import { DialogueScene } from "./DialogueScene.js";
|
|
4
4
|
import type { SceneCollection } from "../scene/types.js";
|
|
5
|
-
|
|
5
|
+
// Note: CSS is imported in the browser demo entry point (examples/browser/main.tsx)
|
|
6
|
+
// This prevents Node.js from trying to resolve CSS imports during tests
|
|
6
7
|
|
|
7
8
|
export interface DialogueViewProps {
|
|
8
9
|
result: RuntimeResult | null;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { useState, useCallback, useRef } from "react";
|
|
2
|
-
import { YarnRunner, type
|
|
2
|
+
import { YarnRunner, type RunnerOptions } from "../runtime/runner.js";
|
|
3
|
+
import type { IRProgram } from "../compile/ir.js";
|
|
4
|
+
import type { RuntimeResult } from "../runtime/results.js";
|
|
3
5
|
|
|
4
6
|
export function useYarnRunner(
|
|
5
7
|
program: IRProgram,
|
package/src/runtime/commands.ts
CHANGED
|
@@ -162,7 +162,7 @@ export class CommandHandler {
|
|
|
162
162
|
} else if (value.startsWith(".")) {
|
|
163
163
|
// Shorthand - we can't infer enum type from declaration alone
|
|
164
164
|
// Store as-is, will be resolved on first use if variable has enum type
|
|
165
|
-
|
|
165
|
+
// Value is already set correctly above
|
|
166
166
|
}
|
|
167
167
|
}
|
|
168
168
|
|
|
@@ -178,6 +178,3 @@ export class CommandHandler {
|
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
// Forward reference type (avoid circular import)
|
|
182
|
-
type ExpressionEvaluator = import("./evaluator").ExpressionEvaluator;
|
|
183
|
-
|
package/src/runtime/evaluator.ts
CHANGED
|
@@ -202,7 +202,6 @@ export class ExpressionEvaluator {
|
|
|
202
202
|
|
|
203
203
|
// Try shorthand enum: .CaseName (requires context from variables)
|
|
204
204
|
if (expr.startsWith(".") && expr.length > 1) {
|
|
205
|
-
const caseName = expr.slice(1);
|
|
206
205
|
// Try to infer enum from variable types - for now, return as-is and let validation handle it
|
|
207
206
|
return expr;
|
|
208
207
|
}
|