@fnet/cli 0.3.8 → 0.3.10

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fnet/cli",
3
- "version": "0.3.8",
3
+ "version": "0.3.10",
4
4
  "files": [
5
5
  "dist",
6
6
  "template"
@@ -0,0 +1,103 @@
1
+ {% include "src/default/macros/block-header.js.njk" %}
2
+
3
+ {% include "src/default/macros/block-next-header.js.njk" %}
4
+
5
+ {% include "src/default/macros/block-modules-header.js.njk" %}
6
+
7
+ {% for child in childs %}
8
+ {% if not child.definition.dynamic %}
9
+ // PARALLEL CHILD: {{child.indexKey}}
10
+ import {{child.codeKey}} from "./{{child.codeKey}}.js";
11
+ {% endif %}
12
+ {% endfor %}
13
+
14
+ export default function Block(context) {
15
+
16
+ {% include "src/default/macros/block-body-header.js.njk" %}
17
+
18
+ this.run = function () {
19
+
20
+ {% include "src/default/macros/block-entry-args.js.njk" %}
21
+
22
+ return new Promise(async (resolve, reject) => {
23
+
24
+ {% include "src/default/macros/block-run-header.js.njk" %}
25
+
26
+ {% include "src/default/macros/page.js.njk" %}
27
+
28
+ {% include "src/default/macros/block-modules.js.njk" %}
29
+
30
+ // PARALLEL EXECUTION
31
+ const promises = [];
32
+
33
+ {% for child in childs %}
34
+ {% if child.definition.dynamic %}
35
+ // PARALLEL CHILD: {{child.indexKey}}
36
+ const { default: {{child.codeKey}} } = await import("./{{child.codeKey}}.js");
37
+ {% endif %}
38
+
39
+ promises.push((async () => {
40
+ const current = new {{child.codeKey}}({ parent: _this, engine, flow, caller: c, onError, error });
41
+
42
+ {% if workflow.parent.context.atom.doc.features.print_runners %}
43
+ console.log(new Date().toLocaleString(), ' * ', _this.constructor.IndexKey, ' -> ', current.constructor.IndexKey);
44
+ {% endif %}
45
+
46
+ const nextBlock = Array.isArray(args)
47
+ ? await current.run.apply(current, args)
48
+ : await current.run.call(current, args);
49
+
50
+ return nextBlock;
51
+ })());
52
+ {% endfor %}
53
+
54
+ // Execute based on strategy
55
+ {% set strategy = context.transform.strategy | default('all') %}
56
+ let results;
57
+
58
+ {% if strategy == 'race' %}
59
+ // Promise.race - first to complete wins
60
+ results = [await Promise.race(promises)];
61
+ {% elif strategy == 'any' %}
62
+ // Promise.any - first successful wins
63
+ results = [await Promise.any(promises)];
64
+ {% elif strategy == 'allsettled' %}
65
+ // Promise.allSettled - all complete, collect results
66
+ const settled = await Promise.allSettled(promises);
67
+ results = settled.map(r => r.status === 'fulfilled' ? r.value : null);
68
+ {% else %}
69
+ // Promise.all - all must succeed (default)
70
+ results = await Promise.all(promises);
71
+ {% endif %}
72
+
73
+ // Check if any child returned or jumped
74
+ for (const result of results) {
75
+ if (result?.type === 'return') {
76
+ return resolve(result);
77
+ }
78
+ if (result?.type === 'block') {
79
+ return resolve(result);
80
+ }
81
+ }
82
+
83
+ {% include "src/default/macros/block-assign.js.njk" %}
84
+
85
+ {% include "src/default/macros/block-signal.js.njk" %}
86
+
87
+ {% if context.transform.return %}
88
+ resolve({ type: 'return', value: {{context.transform.return | safe}} });
89
+ {% elseif context.next %}
90
+ {% include "src/default/macros/block-next.js.njk" %}
91
+ {% else %}
92
+ resolve();
93
+ {% endif %}
94
+
95
+ {% include "src/default/macros/block-run-footer.js.njk" %}
96
+ });
97
+ }
98
+
99
+ Object.freeze(this);
100
+ }
101
+
102
+ {% include "src/default/macros/block-footer.js.njk" %}
103
+
@@ -0,0 +1,146 @@
1
+ {% include "src/default/macros/block-header.js.njk" %}
2
+
3
+ {% include "src/default/macros/block-next-header.js.njk" %}
4
+
5
+ {% include "src/default/macros/block-modules-header.js.njk" %}
6
+
7
+ export default function Block(context){
8
+
9
+ {% include "src/default/macros/block-body-header.js.njk" %}
10
+
11
+ this.run= function (){
12
+
13
+ {% include "src/default/macros/block-entry-args.js.njk" %}
14
+
15
+ return new Promise(async (resolve,reject)=>{
16
+
17
+ try{
18
+ {% include "src/default/macros/block-run-header.js.njk" %}
19
+
20
+ {% include "src/default/macros/page.js.njk" %}
21
+
22
+ {% include "src/default/macros/block-modules.js.njk" %}
23
+
24
+ // PIPELINE EXECUTION
25
+ const { spawn } = await import('child_process');
26
+
27
+ const pipelineBinary = '{{ context.binaryName }}';
28
+ {% if context.transform.args %}
29
+ const pipelineArgs = {{ context.transform.args | safe }};
30
+ {% else %}
31
+ const pipelineArgs = [];
32
+ {% endif %}
33
+
34
+ {% if context.transform.input %}
35
+ const pipelineInput = {{ context.transform.input | safe }};
36
+ {% else %}
37
+ const pipelineInput = null;
38
+ {% endif %}
39
+
40
+ const pipelineFormat = '{{ context.format }}';
41
+
42
+ {% if context.transform.env %}
43
+ const pipelineEnv = {{ context.transform.env | safe }};
44
+ {% else %}
45
+ const pipelineEnv = {};
46
+ {% endif %}
47
+
48
+ {% if context.transform.cwd %}
49
+ const pipelineCwd = {{ context.transform.cwd | safe }};
50
+ {% else %}
51
+ const pipelineCwd = undefined;
52
+ {% endif %}
53
+
54
+ const result = await new Promise((pipelineResolve, pipelineReject) => {
55
+ const spawnOptions = {
56
+ env: { ...process.env, ...pipelineEnv },
57
+ stdio: ['pipe', 'pipe', 'pipe'] // stdin, stdout, stderr as pipes (don't inherit parent)
58
+ };
59
+
60
+ if (pipelineCwd) {
61
+ spawnOptions.cwd = pipelineCwd;
62
+ }
63
+
64
+ const proc = spawn(pipelineBinary, pipelineArgs, spawnOptions);
65
+
66
+ let stdout = '';
67
+ let stderr = '';
68
+
69
+ proc.stdout.on('data', (data) => {
70
+ stdout += data.toString();
71
+ });
72
+
73
+ proc.stderr.on('data', (data) => {
74
+ stderr += data.toString();
75
+ });
76
+
77
+ proc.on('error', (error) => {
78
+ pipelineReject(new Error(`Failed to execute pipeline '${pipelineBinary}': ${error.message}`));
79
+ });
80
+
81
+ proc.on('close', (code) => {
82
+ if (code !== 0) {
83
+ pipelineReject(new Error(`Pipeline '${pipelineBinary}' exited with code ${code}: ${stderr}`));
84
+ return;
85
+ }
86
+
87
+ // Parse output based on format
88
+ if (pipelineFormat === 'text') {
89
+ // Text format: return as-is
90
+ pipelineResolve(stdout.trim());
91
+ } else {
92
+ // JSON format (default): parse
93
+ try {
94
+ const result = JSON.parse(stdout.trim());
95
+ pipelineResolve(result);
96
+ } catch (error) {
97
+ pipelineReject(new Error(`Failed to parse pipeline output as JSON: ${error.message}`));
98
+ }
99
+ }
100
+ });
101
+
102
+ // Write input based on type (auto-detect)
103
+ if (pipelineInput !== null && pipelineInput !== undefined) {
104
+ if (typeof pipelineInput === 'object') {
105
+ // Object/Array → JSON
106
+ proc.stdin.write(JSON.stringify(pipelineInput) + '\n');
107
+ } else if (typeof pipelineInput === 'string') {
108
+ // String → as-is (text)
109
+ proc.stdin.write(pipelineInput + '\n');
110
+ } else {
111
+ // Other types → JSON
112
+ proc.stdin.write(JSON.stringify(pipelineInput) + '\n');
113
+ }
114
+ }
115
+ proc.stdin.end();
116
+ });
117
+
118
+ {% if context.transform.result %}
119
+ flow.set('{{ context.transform.result }}', result);
120
+ {% endif %}
121
+
122
+ {% include "src/default/macros/block-assign.js.njk" %}
123
+
124
+ {% include "src/default/macros/block-signal.js.njk" %}
125
+
126
+ {% if context.transform.return %}
127
+ resolve({type:'return',value: {{context.transform.return | safe}}});
128
+ {% elseif context.next %}
129
+ {% include "src/default/macros/block-next.js.njk" %}
130
+ {% else %}
131
+ resolve();
132
+ {% endif %}
133
+
134
+ {% include "src/default/macros/block-run-footer.js.njk" %}
135
+ }
136
+ catch(error){
137
+ onError? onError(error) : reject(error);
138
+ }
139
+ });
140
+ }
141
+
142
+ Object.freeze(this);
143
+ }
144
+
145
+ {% include "src/default/macros/block-footer.js.njk" %}
146
+