|
|
@@ -171,14 +171,16 @@ git commit -m "test: let the harness assert on HTTP responses and answer a pause
|
|
|
|
|
|
---
|
|
|
|
|
|
-### Task 2: `fs.readdir`
|
|
|
+### Task 2: `fs.readdir`, and a workflow id a node can see
|
|
|
|
|
|
**Files:**
|
|
|
-- Modify: `src/runner/engine/script_engine.cpp` (after the `fs.stat` registration, before `JS_SetPropertyStr(ctx, smartbotic, "fs", fs);`)
|
|
|
+- Modify: `src/runner/engine/script_engine.cpp` (after the `fs.stat` registration, before `JS_SetPropertyStr(ctx, smartbotic, "fs", fs);`, and the context object around line 4393)
|
|
|
+- Modify: `src/runner/workflow_engine.cpp:905` (the `ctx` filled before a node runs)
|
|
|
- Create: `tests/nodes/fs-readdir.json`
|
|
|
|
|
|
**Interfaces:**
|
|
|
- Produces: `smartbotic.fs.readdir(path)` returning `{success: true, entries: [{name, path, size, modifiedAt, isDirectory}]}` or `{success: false, error}`. `modifiedAt` is milliseconds since the epoch, matching `fs.stat`'s `mtime`. Not recursive.
|
|
|
+- Produces: `context.workflowId`, alongside the `context.executionId` and `context.nodeId` a node already receives. Tasks 3 and 4 key their cursors on it.
|
|
|
|
|
|
- [ ] **Step 1: Register the function**
|
|
|
|
|
|
@@ -263,11 +265,40 @@ Insert after the closing `}, "stat", 1));`:
|
|
|
}, "readdir", 1));
|
|
|
```
|
|
|
|
|
|
-- [ ] **Step 2: Build and restart**
|
|
|
+- [ ] **Step 2: Expose the workflow id to nodes**
|
|
|
+
|
|
|
+A node currently receives only `executionId` and `nodeId` on its `context`. The
|
|
|
+two polling triggers in Tasks 3 and 4 key their cursor on the workflow, and
|
|
|
+without it every workflow's cursor would collide under one key - two workflows
|
|
|
+watching different directories would consume each other's changes.
|
|
|
+
|
|
|
+`ScriptContext` already declares `workflow_id` (`script_engine.hpp:147`) and
|
|
|
+`executeNode` already receives the `Workflow`, so nothing new has to be plumbed
|
|
|
+through. It is simply never set and never exposed.
|
|
|
+
|
|
|
+In `workflow_engine.cpp`, in `executeNode` beside the other `ctx` assignments
|
|
|
+around line 903:
|
|
|
+
|
|
|
+```cpp
|
|
|
+ ctx.workflow_id = workflow.id;
|
|
|
+```
|
|
|
+
|
|
|
+In `script_engine.cpp`, in the context object built for the execute function
|
|
|
+around line 4393:
|
|
|
+
|
|
|
+```cpp
|
|
|
+ nlohmann::json ctx_json = {
|
|
|
+ {"executionId", context.execution_id},
|
|
|
+ {"nodeId", context.node_id},
|
|
|
+ {"workflowId", context.workflow_id}
|
|
|
+ };
|
|
|
+```
|
|
|
+
|
|
|
+- [ ] **Step 3: Build and restart**
|
|
|
|
|
|
Run the rebuild and restart sequence from the Reference section. Expected: clean build, all three ports listening.
|
|
|
|
|
|
-- [ ] **Step 3: Write the fixture**
|
|
|
+- [ ] **Step 4: Write the fixture**
|
|
|
|
|
|
`tests/nodes/fs-readdir.json` - a `code` node creates a directory with two files, lists it, then cleans up:
|
|
|
|
|
|
@@ -277,7 +308,7 @@ Run the rebuild and restart sequence from the Reference section. Expected: clean
|
|
|
"nodes": [
|
|
|
{"id": "n1", "name": "Trigger", "type": "click-trigger", "position": {"x": 0, "y": 0}, "config": {}},
|
|
|
{"id": "n2", "name": "List", "type": "code", "position": {"x": 0, "y": 100},
|
|
|
- "config": {"code": "const dir = '/tmp/sb-readdir-test';\nsmartbotic.fs.mkdir(dir);\nsmartbotic.fs.writeFile(dir + '/one.txt', smartbotic.utils.base64Encode('hello'));\nsmartbotic.fs.writeFile(dir + '/two.txt', smartbotic.utils.base64Encode('worldwide'));\nsmartbotic.fs.mkdir(dir + '/sub');\n\nconst listing = smartbotic.fs.readdir(dir);\nconst missing = smartbotic.fs.readdir('/tmp/sb-readdir-does-not-exist');\nconst notDir = smartbotic.fs.readdir(dir + '/one.txt');\n\nconst names = listing.entries.map(function (e) { return e.name; }).sort();\nconst one = listing.entries.filter(function (e) { return e.name === 'one.txt'; })[0];\nconst sub = listing.entries.filter(function (e) { return e.name === 'sub'; })[0];\n\nsmartbotic.fs.unlink(dir + '/one.txt');\nsmartbotic.fs.unlink(dir + '/two.txt');\n\nreturn {\n ok: listing.success,\n names: names,\n oneSize: one.size,\n oneHasMtime: one.modifiedAt > 1600000000000,\n subIsDirectory: sub.isDirectory,\n oneIsDirectory: one.isDirectory,\n missingRejected: missing.success === false,\n notDirRejected: notDir.success === false\n};"}}
|
|
|
+ "config": {"code": "const dir = '/tmp/sb-readdir-test';\nsmartbotic.fs.mkdir(dir);\nsmartbotic.fs.writeFile(dir + '/one.txt', smartbotic.utils.base64Encode('hello'));\nsmartbotic.fs.writeFile(dir + '/two.txt', smartbotic.utils.base64Encode('worldwide'));\nsmartbotic.fs.mkdir(dir + '/sub');\n\nconst listing = smartbotic.fs.readdir(dir);\nconst missing = smartbotic.fs.readdir('/tmp/sb-readdir-does-not-exist');\nconst notDir = smartbotic.fs.readdir(dir + '/one.txt');\n\nconst names = listing.entries.map(function (e) { return e.name; }).sort();\nconst one = listing.entries.filter(function (e) { return e.name === 'one.txt'; })[0];\nconst sub = listing.entries.filter(function (e) { return e.name === 'sub'; })[0];\n\nsmartbotic.fs.unlink(dir + '/one.txt');\nsmartbotic.fs.unlink(dir + '/two.txt');\n\nreturn {\n ok: listing.success,\n names: names,\n oneSize: one.size,\n oneHasMtime: one.modifiedAt > 1600000000000,\n subIsDirectory: sub.isDirectory,\n oneIsDirectory: one.isDirectory,\n missingRejected: missing.success === false,\n notDirRejected: notDir.success === false,\n hasWorkflowId: typeof context.workflowId === 'string' && context.workflowId.length > 0\n};"}}
|
|
|
],
|
|
|
"connections": [
|
|
|
{"sourceNodeId": "n1", "sourceOutput": "main", "targetNodeId": "n2", "targetInput": "data"}
|
|
|
@@ -299,16 +330,16 @@ Run the rebuild and restart sequence from the Reference section. Expected: clean
|
|
|
|
|
|
`oneSize` is 5 because the file holds `hello`. That pins the size actually being read rather than defaulted to zero.
|
|
|
|
|
|
-- [ ] **Step 4: Run it**
|
|
|
+- [ ] **Step 5: Run it**
|
|
|
|
|
|
Run: `python3 scripts/verify-node.py tests/nodes/fs-readdir.json`
|
|
|
Expected: `PASS`.
|
|
|
|
|
|
-- [ ] **Step 5: Commit**
|
|
|
+- [ ] **Step 6: Commit**
|
|
|
|
|
|
```bash
|
|
|
-git add src/runner/engine/script_engine.cpp tests/nodes/fs-readdir.json
|
|
|
-git commit -m "feat: fs.readdir, so a node can see what is in a directory"
|
|
|
+git add src/runner/engine/script_engine.cpp src/runner/workflow_engine.cpp tests/nodes/fs-readdir.json
|
|
|
+git commit -m "feat: fs.readdir, and a workflow id a node can see"
|
|
|
```
|
|
|
|
|
|
---
|