yaml-flow 5.0.0 → 5.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.
- package/examples/example-board/demo-server-config.json +7 -0
- package/examples/example-board/demo-server.js +39 -2
- package/examples/example-board/demo-shell-browser.html +3 -3
- package/examples/example-board/demo-shell-with-server.html +2 -2
- package/examples/example-board/reusable-server-runtime.js +65 -8
- package/package.json +1 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import http from 'node:http';
|
|
4
|
+
import fs from 'node:fs';
|
|
4
5
|
import path from 'node:path';
|
|
5
6
|
import { fileURLToPath } from 'node:url';
|
|
6
7
|
|
|
@@ -13,7 +14,40 @@ import {
|
|
|
13
14
|
const __filename = fileURLToPath(import.meta.url);
|
|
14
15
|
const __dirname = path.dirname(__filename);
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
function loadServerConfig() {
|
|
18
|
+
const configPath = path.join(__dirname, 'demo-server-config.json');
|
|
19
|
+
if (!fs.existsSync(configPath)) return {};
|
|
20
|
+
try {
|
|
21
|
+
const raw = fs.readFileSync(configPath, 'utf-8');
|
|
22
|
+
const parsed = JSON.parse(raw);
|
|
23
|
+
return parsed && typeof parsed === 'object' ? parsed : {};
|
|
24
|
+
} catch {
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function resolveFromConfig(configValue) {
|
|
30
|
+
if (typeof configValue !== 'string' || !configValue.trim()) return null;
|
|
31
|
+
return path.resolve(__dirname, configValue);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const serverConfig = loadServerConfig();
|
|
35
|
+
const configuredCliJs = resolveFromConfig(serverConfig.boardLiveCardsCliJs);
|
|
36
|
+
const configuredTaskExecutorPath = resolveFromConfig(serverConfig.taskExecutorPath || serverConfig.demoTaskExecutorPath);
|
|
37
|
+
const configuredStepMachineCliPath = resolveFromConfig(serverConfig.stepMachineCliPath);
|
|
38
|
+
const configuredChatHandlerPath = resolveFromConfig(serverConfig.chatHandlerPath);
|
|
39
|
+
|
|
40
|
+
if (!process.env.BOARD_LIVE_CARDS_CLI_JS && configuredCliJs) {
|
|
41
|
+
process.env.BOARD_LIVE_CARDS_CLI_JS = configuredCliJs;
|
|
42
|
+
}
|
|
43
|
+
if (!process.env.DEMO_STEP_MACHINE_CLI_PATH && configuredStepMachineCliPath) {
|
|
44
|
+
process.env.DEMO_STEP_MACHINE_CLI_PATH = configuredStepMachineCliPath;
|
|
45
|
+
}
|
|
46
|
+
if (!process.env.DEMO_CHAT_HANDLER_PATH && configuredChatHandlerPath) {
|
|
47
|
+
process.env.DEMO_CHAT_HANDLER_PATH = configuredChatHandlerPath;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const PORT = Number(process.env.DEMO_SERVER_PORT || serverConfig.port || 7799);
|
|
17
51
|
const CORS_HEADERS = {
|
|
18
52
|
'Access-Control-Allow-Origin': '*',
|
|
19
53
|
'Access-Control-Allow-Headers': 'content-type,x-file-name',
|
|
@@ -22,7 +56,10 @@ const CORS_HEADERS = {
|
|
|
22
56
|
|
|
23
57
|
const runtime = createMultiBoardServerRuntime({
|
|
24
58
|
apiBasePath: '/api/boards',
|
|
25
|
-
defaultTaskExecutorPath: process.env.DEMO_TASK_EXECUTOR_PATH || path.join(__dirname, 'demo-task-executor.js'),
|
|
59
|
+
defaultTaskExecutorPath: process.env.DEMO_TASK_EXECUTOR_PATH || configuredTaskExecutorPath || path.join(__dirname, 'demo-task-executor.js'),
|
|
60
|
+
defaultStepMachineCliPath: process.env.DEMO_STEP_MACHINE_CLI_PATH || configuredStepMachineCliPath,
|
|
61
|
+
defaultChatHandlerPath: process.env.DEMO_CHAT_HANDLER_PATH || configuredChatHandlerPath || path.join(__dirname, 'demo-chat-handler.js'),
|
|
62
|
+
boardLiveCardsCliJs: process.env.BOARD_LIVE_CARDS_CLI_JS || configuredCliJs,
|
|
26
63
|
});
|
|
27
64
|
|
|
28
65
|
const dispatch = createRuntimeRequestDispatcher(runtime);
|
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
<title>Example Board Demo (Browser Runtime)</title>
|
|
7
7
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />
|
|
8
8
|
<script src="https://cdn.jsdelivr.net/npm/jsonata/jsonata.min.js"></script>
|
|
9
|
-
<script src="
|
|
10
|
-
<script src="
|
|
11
|
-
<script src="
|
|
9
|
+
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@latest/browser/card-compute.js" onerror="this.onerror=null;this.src='../../browser/card-compute.js';"></script>
|
|
10
|
+
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@latest/browser/live-cards.js" onerror="this.onerror=null;this.src='../../browser/live-cards.js';"></script>
|
|
11
|
+
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@latest/browser/board-livegraph-runtime.js" onerror="this.onerror=null;this.src='../../browser/board-livegraph-runtime.js';"></script>
|
|
12
12
|
<script src="./reusable-runtime-artifacts-adapter.js"></script>
|
|
13
13
|
</head>
|
|
14
14
|
<body class="bg-light">
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
<title>Example Board Demo (Server Runtime)</title>
|
|
7
7
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" />
|
|
8
8
|
<script src="https://cdn.jsdelivr.net/npm/jsonata/jsonata.min.js"></script>
|
|
9
|
-
<script src="
|
|
10
|
-
<script src="
|
|
9
|
+
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@latest/browser/card-compute.js" onerror="this.onerror=null;this.src='../../browser/card-compute.js';"></script>
|
|
10
|
+
<script src="https://cdn.jsdelivr.net/npm/yaml-flow@latest/browser/live-cards.js" onerror="this.onerror=null;this.src='../../browser/live-cards.js';"></script>
|
|
11
11
|
<script src="./reusable-runtime-artifacts-adapter.js"></script>
|
|
12
12
|
<script src="./reusable-board-runtime-client.js"></script>
|
|
13
13
|
</head>
|
|
@@ -138,6 +138,12 @@ export function createMultiBoardServerRuntime(options = {}) {
|
|
|
138
138
|
const defaultTaskExecutorPath = typeof entry.taskExecutorPath === 'string'
|
|
139
139
|
? entry.taskExecutorPath
|
|
140
140
|
: options.defaultTaskExecutorPath;
|
|
141
|
+
const defaultStepMachineCliPath = typeof entry.stepMachineCliPath === 'string'
|
|
142
|
+
? entry.stepMachineCliPath
|
|
143
|
+
: options.defaultStepMachineCliPath;
|
|
144
|
+
const defaultChatHandlerPath = typeof entry.chatHandlerPath === 'string'
|
|
145
|
+
? entry.chatHandlerPath
|
|
146
|
+
: options.defaultChatHandlerPath;
|
|
141
147
|
|
|
142
148
|
const service = createExampleBoardServerRuntime({
|
|
143
149
|
apiBasePath: `${apiBasePath}/${boardId}`,
|
|
@@ -148,6 +154,9 @@ export function createMultiBoardServerRuntime(options = {}) {
|
|
|
148
154
|
tmpSurfaceDir: path.join(boardRoot, 'surface'),
|
|
149
155
|
runtimeOutDir: path.join(boardRoot, 'runtime-out'),
|
|
150
156
|
defaultTaskExecutorPath,
|
|
157
|
+
defaultStepMachineCliPath,
|
|
158
|
+
defaultChatHandlerPath,
|
|
159
|
+
boardLiveCardsCliJs: options.boardLiveCardsCliJs,
|
|
151
160
|
});
|
|
152
161
|
|
|
153
162
|
boardServiceCache.set(boardId, service);
|
|
@@ -197,6 +206,7 @@ export function createMultiBoardServerRuntime(options = {}) {
|
|
|
197
206
|
const label = typeof body.label === 'string' && body.label.trim() ? body.label.trim() : id;
|
|
198
207
|
const entry = { id, label };
|
|
199
208
|
if (typeof body.cardsDir === 'string') entry.cardsDir = body.cardsDir;
|
|
209
|
+
if (typeof body.stepMachineCliPath === 'string') entry.stepMachineCliPath = body.stepMachineCliPath;
|
|
200
210
|
config.boards.push(entry);
|
|
201
211
|
writeBoardsConfig(config);
|
|
202
212
|
|
|
@@ -310,6 +320,24 @@ export function createExampleBoardServerRuntime(options = {}) {
|
|
|
310
320
|
? options.defaultTaskExecutorPath
|
|
311
321
|
: path.resolve(process.cwd(), options.defaultTaskExecutorPath))
|
|
312
322
|
: null;
|
|
323
|
+
const configuredStepMachineCliPath = typeof options.defaultStepMachineCliPath === 'string'
|
|
324
|
+
&& options.defaultStepMachineCliPath.trim()
|
|
325
|
+
? (path.isAbsolute(options.defaultStepMachineCliPath)
|
|
326
|
+
? options.defaultStepMachineCliPath
|
|
327
|
+
: path.resolve(process.cwd(), options.defaultStepMachineCliPath))
|
|
328
|
+
: null;
|
|
329
|
+
const configuredBoardLiveCardsCliJs = typeof options.boardLiveCardsCliJs === 'string'
|
|
330
|
+
&& options.boardLiveCardsCliJs.trim()
|
|
331
|
+
? (path.isAbsolute(options.boardLiveCardsCliJs)
|
|
332
|
+
? options.boardLiveCardsCliJs
|
|
333
|
+
: path.resolve(process.cwd(), options.boardLiveCardsCliJs))
|
|
334
|
+
: null;
|
|
335
|
+
const configuredChatHandlerPath = typeof options.defaultChatHandlerPath === 'string'
|
|
336
|
+
&& options.defaultChatHandlerPath.trim()
|
|
337
|
+
? (path.isAbsolute(options.defaultChatHandlerPath)
|
|
338
|
+
? options.defaultChatHandlerPath
|
|
339
|
+
: path.resolve(process.cwd(), options.defaultChatHandlerPath))
|
|
340
|
+
: null;
|
|
313
341
|
|
|
314
342
|
const statusSnapshotFile = path.join(runtimeOutDir, 'board-livegraph-status.json');
|
|
315
343
|
const boardFile = path.join(boardDir, 'board-graph.json');
|
|
@@ -318,6 +346,8 @@ export function createExampleBoardServerRuntime(options = {}) {
|
|
|
318
346
|
let didDemoSetup = false;
|
|
319
347
|
|
|
320
348
|
function resolveCliJsPath() {
|
|
349
|
+
if (configuredBoardLiveCardsCliJs && fs.existsSync(configuredBoardLiveCardsCliJs)) return configuredBoardLiveCardsCliJs;
|
|
350
|
+
|
|
321
351
|
const envOverride = process.env.BOARD_LIVE_CARDS_CLI_JS;
|
|
322
352
|
if (envOverride && fs.existsSync(envOverride)) return envOverride;
|
|
323
353
|
|
|
@@ -341,6 +371,10 @@ export function createExampleBoardServerRuntime(options = {}) {
|
|
|
341
371
|
|
|
342
372
|
const cliJs = resolveCliJsPath();
|
|
343
373
|
|
|
374
|
+
if (!process.env.DEMO_STEP_MACHINE_CLI_PATH && configuredStepMachineCliPath && fs.existsSync(configuredStepMachineCliPath)) {
|
|
375
|
+
process.env.DEMO_STEP_MACHINE_CLI_PATH = configuredStepMachineCliPath;
|
|
376
|
+
}
|
|
377
|
+
|
|
344
378
|
function ensureCardStorageDirs(cardId) {
|
|
345
379
|
const safeCardId = String(cardId || '').replace(/[^a-zA-Z0-9_-]/g, '_') || 'unknown-card';
|
|
346
380
|
const cardDir = path.join(tmpCardsDir, safeCardId);
|
|
@@ -417,7 +451,7 @@ export function createExampleBoardServerRuntime(options = {}) {
|
|
|
417
451
|
function ensureBuilt() {
|
|
418
452
|
if (!cliJs || !fs.existsSync(cliJs)) {
|
|
419
453
|
throw new Error(
|
|
420
|
-
'Unable to locate board-live-cards CLI. Set BOARD_LIVE_CARDS_CLI_JS or install yaml-flow in this project.'
|
|
454
|
+
'Unable to locate board-live-cards CLI. Set boardLiveCardsCliJs option, BOARD_LIVE_CARDS_CLI_JS, or install yaml-flow in this project.'
|
|
421
455
|
);
|
|
422
456
|
}
|
|
423
457
|
}
|
|
@@ -631,29 +665,51 @@ export function createExampleBoardServerRuntime(options = {}) {
|
|
|
631
665
|
return resolved;
|
|
632
666
|
}
|
|
633
667
|
|
|
634
|
-
function
|
|
668
|
+
function resolveChatHandlerPath(chatHandlerPathParam) {
|
|
669
|
+
const raw = typeof chatHandlerPathParam === 'string' ? chatHandlerPathParam.trim() : '';
|
|
670
|
+
const resolved = raw
|
|
671
|
+
? (path.isAbsolute(raw) ? raw : path.resolve(__dirname, raw))
|
|
672
|
+
: configuredChatHandlerPath;
|
|
673
|
+
if (!resolved) return null;
|
|
674
|
+
if (!fs.existsSync(resolved)) {
|
|
675
|
+
const err = new Error(`Chat handler script not found: ${resolved}`);
|
|
676
|
+
err.statusCode = 400;
|
|
677
|
+
throw err;
|
|
678
|
+
}
|
|
679
|
+
return resolved;
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
function initBoard(taskExecutorPathParam, chatHandlerPathParam) {
|
|
635
683
|
fs.mkdirSync(boardDir, { recursive: true });
|
|
636
684
|
|
|
637
685
|
const taskExecutorPath = resolveTaskExecutorPath(taskExecutorPathParam);
|
|
686
|
+
const chatHandlerPath = resolveChatHandlerPath(chatHandlerPathParam);
|
|
638
687
|
const taskExecutorCmd = `${shellQuote(process.execPath)} ${shellQuote(taskExecutorPath)}`;
|
|
688
|
+
const chatHandlerCmd = chatHandlerPath
|
|
689
|
+
? `${shellQuote(process.execPath)} ${shellQuote(chatHandlerPath)}`
|
|
690
|
+
: null;
|
|
691
|
+
|
|
692
|
+
const initArgs = ['init', boardDir, '--task-executor', taskExecutorCmd];
|
|
693
|
+
if (chatHandlerCmd) initArgs.push('--chat-handler', chatHandlerCmd);
|
|
694
|
+
initArgs.push('--runtime-out', runtimeOutDir);
|
|
639
695
|
|
|
640
696
|
try {
|
|
641
|
-
runCli(
|
|
697
|
+
runCli(initArgs);
|
|
642
698
|
} catch (err) {
|
|
643
699
|
const msg = String((err && err.message) || err);
|
|
644
700
|
if (!msg.includes('no valid board-graph.json')) throw err;
|
|
645
701
|
|
|
646
702
|
clearDirContents(boardDir);
|
|
647
703
|
fs.mkdirSync(boardDir, { recursive: true });
|
|
648
|
-
runCli(
|
|
704
|
+
runCli(initArgs);
|
|
649
705
|
}
|
|
650
706
|
}
|
|
651
707
|
|
|
652
|
-
function initBoardAndSetup(taskExecutorPathParam) {
|
|
708
|
+
function initBoardAndSetup(taskExecutorPathParam, chatHandlerPathParam) {
|
|
653
709
|
ensureDemoSetup();
|
|
654
710
|
|
|
655
711
|
if (!fs.existsSync(boardFile)) {
|
|
656
|
-
initBoard(taskExecutorPathParam);
|
|
712
|
+
initBoard(taskExecutorPathParam, chatHandlerPathParam);
|
|
657
713
|
}
|
|
658
714
|
|
|
659
715
|
const expectedCardsRoot = path.resolve(tmpCardsDir);
|
|
@@ -665,7 +721,7 @@ export function createExampleBoardServerRuntime(options = {}) {
|
|
|
665
721
|
|
|
666
722
|
if (hasStaleMapping) {
|
|
667
723
|
clearDirContents(boardDir);
|
|
668
|
-
initBoard(taskExecutorPathParam);
|
|
724
|
+
initBoard(taskExecutorPathParam, chatHandlerPathParam);
|
|
669
725
|
}
|
|
670
726
|
}
|
|
671
727
|
|
|
@@ -1095,7 +1151,8 @@ export function createExampleBoardServerRuntime(options = {}) {
|
|
|
1095
1151
|
try {
|
|
1096
1152
|
if (method === 'GET' && p === `${apiBasePath}/init-board`) {
|
|
1097
1153
|
const taskExecutorPathParam = url.searchParams.get('taskExecutorPath') || '';
|
|
1098
|
-
|
|
1154
|
+
const chatHandlerPathParam = url.searchParams.get('chatHandlerPath') || '';
|
|
1155
|
+
initBoardAndSetup(taskExecutorPathParam, chatHandlerPathParam);
|
|
1099
1156
|
json(res, 200, buildPublishedRuntimePayload());
|
|
1100
1157
|
return true;
|
|
1101
1158
|
}
|