@fnet/cli 0.4.26 → 0.5.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 (184) hide show
  1. package/dist/fbin/index.js +15 -0
  2. package/dist/fnet/index.0jcm9pn5.js +1 -0
  3. package/dist/fnet/index.2084z2ed.js +2 -0
  4. package/dist/fnet/index.33f1ggpr.js +1 -0
  5. package/dist/fnet/index.3exge2js.js +1 -0
  6. package/dist/fnet/index.3kfx538h.js +1 -0
  7. package/dist/fnet/index.490y87nc.js +1 -0
  8. package/dist/fnet/index.4g9yezkq.js +1 -0
  9. package/dist/fnet/index.4jkat7r4.js +1 -0
  10. package/dist/fnet/index.7crx8ky1.js +1 -0
  11. package/dist/fnet/index.7vw06nrn.js +1 -0
  12. package/dist/fnet/index.9567fa9x.js +1 -0
  13. package/dist/fnet/index.gh75wt1m.js +1 -0
  14. package/dist/fnet/index.hzsfswvp.js +1 -0
  15. package/dist/fnet/index.jgpc3grc.js +1 -0
  16. package/dist/fnet/index.js +20 -0
  17. package/dist/fnet/index.p0zb7e1b.js +1 -0
  18. package/dist/fnet/index.r19p3bpa.js +2 -0
  19. package/dist/fnet/index.r82rtnmz.js +1 -0
  20. package/dist/fnet/index.s662t98v.js +1 -0
  21. package/dist/fnet/index.w74dpnpn.js +1 -0
  22. package/dist/fnet/index.xeaw5xa9.js +1 -0
  23. package/dist/fnet/index.zm4kesg6.js +1 -0
  24. package/dist/fnode/index.05n3mvs9.js +2 -0
  25. package/dist/fnode/index.2hc9tbyx.js +1 -0
  26. package/dist/fnode/index.2pnjg6dc.js +1 -0
  27. package/dist/fnode/index.9qgtmxq3.js +2 -0
  28. package/dist/fnode/index.b1q7y05p.js +1 -0
  29. package/dist/fnode/index.bhapgrs7.js +1 -0
  30. package/dist/fnode/index.cvxrf34y.js +2 -0
  31. package/dist/fnode/index.dp9wyahp.js +1 -0
  32. package/dist/fnode/index.eqxmcpdc.js +1 -0
  33. package/dist/fnode/index.f2tb0x3t.js +1 -0
  34. package/dist/fnode/index.fbzv6wwf.js +1 -0
  35. package/dist/fnode/index.gazd9raq.js +1 -0
  36. package/dist/fnode/index.hv4s25f0.js +3 -0
  37. package/dist/fnode/index.j5z7dtsx.js +1 -0
  38. package/dist/fnode/index.js +10 -0
  39. package/dist/fnode/index.kb4e4bxf.js +1 -0
  40. package/dist/fnode/index.qn0schqp.js +1 -0
  41. package/dist/fnode/index.rht29phd.js +1 -0
  42. package/dist/fnode/index.rzsfmek6.js +3 -0
  43. package/dist/fnode/index.s0nk6cv8.js +4 -0
  44. package/dist/fnode/index.s66v6wt4.js +1 -0
  45. package/dist/fnode/index.sv7v0y60.js +1 -0
  46. package/dist/fnode/index.tgkhgnrp.js +1 -0
  47. package/dist/fnode/index.vq706f75.js +1 -0
  48. package/dist/fnode/index.y8pvdcny.js +1 -0
  49. package/dist/fnode/index.z4vz93ww.js +1 -0
  50. package/dist/frun/index.js +2 -0
  51. package/dist/fservice/index.js +19 -0
  52. package/dist/fservice/index.q01yvaz0.js +2 -0
  53. package/package.json +74 -57
  54. package/readme.md +298 -0
  55. package/template/fnet/core/assert.js +6 -0
  56. package/template/fnet/core/message.js +3 -0
  57. package/template/fnet/core/object.js +47 -0
  58. package/template/fnet/core/sleep.js +5 -0
  59. package/template/fnet/node/.gitignore.njk +9 -0
  60. package/template/fnet/node/build.js.njk +153 -0
  61. package/template/fnet/node/package.json.njk +121 -0
  62. package/template/fnet/node/readme.md.njk +21 -0
  63. package/template/fnet/node/rollup.config.mjs.njk +498 -0
  64. package/template/fnet/node/src/app/index.html.njk +67 -0
  65. package/template/fnet/node/src/app/index.js.njk +36 -0
  66. package/template/fnet/node/src/cli/index.js.njk +9 -0
  67. package/template/fnet/node/src/cli/index.js.v1.njk +318 -0
  68. package/template/fnet/node/src/cli/v2/core/args-parser.njk +10 -0
  69. package/template/fnet/node/src/cli/v2/core/imports.njk +31 -0
  70. package/template/fnet/node/src/cli/v2/core/run-wrapper.njk +25 -0
  71. package/template/fnet/node/src/cli/v2/index.js.njk +184 -0
  72. package/template/fnet/node/src/cli/v2/modes/default/extend.njk +11 -0
  73. package/template/fnet/node/src/cli/v2/modes/default/standard.njk +20 -0
  74. package/template/fnet/node/src/cli/v2/modes/http/builtin.njk +66 -0
  75. package/template/fnet/node/src/cli/v2/modes/http/imports.njk +9 -0
  76. package/template/fnet/node/src/cli/v2/modes/http/index.njk +12 -0
  77. package/template/fnet/node/src/cli/v2/modes/mcp/imports.njk +33 -0
  78. package/template/fnet/node/src/cli/v2/modes/mcp/index.njk +30 -0
  79. package/template/fnet/node/src/cli/v2/modes/mcp/server-setup.njk +15 -0
  80. package/template/fnet/node/src/cli/v2/modes/mcp/tool-handlers.njk +46 -0
  81. package/template/fnet/node/src/cli/v2/modes/mcp/transport-http.njk +222 -0
  82. package/template/fnet/node/src/cli/v2/modes/mcp/transport-stdio.njk +9 -0
  83. package/template/fnet/node/src/cli/v2/modes/pipeline/imports.njk +9 -0
  84. package/template/fnet/node/src/cli/v2/modes/pipeline/index.njk +113 -0
  85. package/template/fnet/node/src/cli/v2/modes/webhook/imports.njk +9 -0
  86. package/template/fnet/node/src/cli/v2/modes/webhook/index.njk +127 -0
  87. package/template/fnet/node/src/cli/v2/modes/websocket/imports.njk +15 -0
  88. package/template/fnet/node/src/cli/v2/modes/websocket/index.njk +104 -0
  89. package/template/fnet/node/src/default/blocks/assign.js.njk +15 -0
  90. package/template/fnet/node/src/default/blocks/call.js.njk +110 -0
  91. package/template/fnet/node/src/default/blocks/for.js.njk +71 -0
  92. package/template/fnet/node/src/default/blocks/form.js.njk +31 -0
  93. package/template/fnet/node/src/default/blocks/http.js.njk +135 -0
  94. package/template/fnet/node/src/default/blocks/modules.js.njk +15 -0
  95. package/template/fnet/node/src/default/blocks/new.js.njk +42 -0
  96. package/template/fnet/node/src/default/blocks/next.js.njk +15 -0
  97. package/template/fnet/node/src/default/blocks/output.js.njk +15 -0
  98. package/template/fnet/node/src/default/blocks/parallel.js.njk +64 -0
  99. package/template/fnet/node/src/default/blocks/pipeline.js.njk +109 -0
  100. package/template/fnet/node/src/default/blocks/raise.js.njk +15 -0
  101. package/template/fnet/node/src/default/blocks/retry.js.njk +70 -0
  102. package/template/fnet/node/src/default/blocks/return.js.njk +21 -0
  103. package/template/fnet/node/src/default/blocks/schedule.js.njk +66 -0
  104. package/template/fnet/node/src/default/blocks/signal.js.njk +15 -0
  105. package/template/fnet/node/src/default/blocks/steps.js.njk +47 -0
  106. package/template/fnet/node/src/default/blocks/switch.js.njk +49 -0
  107. package/template/fnet/node/src/default/blocks/tryexcept.js.njk +80 -0
  108. package/template/fnet/node/src/default/blocks/wait.js.njk +14 -0
  109. package/template/fnet/node/src/default/engine.js.njk +79 -0
  110. package/template/fnet/node/src/default/input.args.js.njk +125 -0
  111. package/template/fnet/node/src/default/macros/block-assign.js.njk +3 -0
  112. package/template/fnet/node/src/default/macros/block-body-header.js.njk +7 -0
  113. package/template/fnet/node/src/default/macros/block-entry-args.js.njk +2 -0
  114. package/template/fnet/node/src/default/macros/block-footer.js.njk +3 -0
  115. package/template/fnet/node/src/default/macros/block-header.js.njk +11 -0
  116. package/template/fnet/node/src/default/macros/block-library-header.js.njk +43 -0
  117. package/template/fnet/node/src/default/macros/block-modules-header.js.njk +8 -0
  118. package/template/fnet/node/src/default/macros/block-modules.js.njk +29 -0
  119. package/template/fnet/node/src/default/macros/block-next-header.js.njk +6 -0
  120. package/template/fnet/node/src/default/macros/block-next.js.njk +21 -0
  121. package/template/fnet/node/src/default/macros/block-run-footer.js.njk +7 -0
  122. package/template/fnet/node/src/default/macros/block-run-form.js.njk +32 -0
  123. package/template/fnet/node/src/default/macros/block-run-header.js.njk +43 -0
  124. package/template/fnet/node/src/default/macros/block-signal.js.njk +3 -0
  125. package/template/fnet/node/src/default/macros/page.js.njk +8 -0
  126. package/template/fnet/node/src/default/types/block.js.njk +133 -0
  127. package/template/fnet/node/src/default/workflow.js.njk +125 -0
  128. package/template/fnet/node/tsconfig.json.njk +16 -0
  129. package/template/fnet/project/.gitignore.njk +7 -0
  130. package/template/fnet/project/.vscode/launch.json.njk +41 -0
  131. package/template/fnet/project/.vscode/tasks.json.njk +46 -0
  132. package/template/fnet/project/fnet/flows.yaml.njk +4 -0
  133. package/template/fnet/project/fnet/targets.yaml.njk +7 -0
  134. package/template/fnet/project/fnet.yaml.njk +3 -0
  135. package/template/fnode/node/.gitignore.njk +9 -0
  136. package/template/fnode/node/build.js.njk +149 -0
  137. package/template/fnode/node/package.json.njk +121 -0
  138. package/template/fnode/node/readme.md.njk +21 -0
  139. package/template/fnode/node/rollup.config.mjs.njk +498 -0
  140. package/template/fnode/node/src/app/index-js-with-react-host.njk +50 -0
  141. package/template/fnode/node/src/app/index-js-without-react-host.njk +23 -0
  142. package/template/fnode/node/src/app/index.html.njk +67 -0
  143. package/template/fnode/node/src/app/index.js.njk +9 -0
  144. package/template/fnode/node/src/cli/index.js.njk +9 -0
  145. package/template/fnode/node/src/cli/index.js.v1.njk +464 -0
  146. package/template/fnode/node/src/cli/v2/core/args-parser.njk +10 -0
  147. package/template/fnode/node/src/cli/v2/core/imports.njk +29 -0
  148. package/template/fnode/node/src/cli/v2/core/run-wrapper.njk +25 -0
  149. package/template/fnode/node/src/cli/v2/index.js.njk +184 -0
  150. package/template/fnode/node/src/cli/v2/modes/default/extend.njk +11 -0
  151. package/template/fnode/node/src/cli/v2/modes/default/standard.njk +19 -0
  152. package/template/fnode/node/src/cli/v2/modes/http/builtin.njk +61 -0
  153. package/template/fnode/node/src/cli/v2/modes/http/imports.njk +9 -0
  154. package/template/fnode/node/src/cli/v2/modes/http/index.njk +12 -0
  155. package/template/fnode/node/src/cli/v2/modes/mcp/imports.njk +33 -0
  156. package/template/fnode/node/src/cli/v2/modes/mcp/index.njk +30 -0
  157. package/template/fnode/node/src/cli/v2/modes/mcp/server-setup.njk +15 -0
  158. package/template/fnode/node/src/cli/v2/modes/mcp/tool-handlers.njk +41 -0
  159. package/template/fnode/node/src/cli/v2/modes/mcp/transport-http.njk +212 -0
  160. package/template/fnode/node/src/cli/v2/modes/mcp/transport-stdio.njk +9 -0
  161. package/template/fnode/node/src/cli/v2/modes/pipeline/imports.njk +9 -0
  162. package/template/fnode/node/src/cli/v2/modes/pipeline/index.njk +103 -0
  163. package/template/fnode/node/src/cli/v2/modes/webhook/imports.njk +9 -0
  164. package/template/fnode/node/src/cli/v2/modes/webhook/index.njk +122 -0
  165. package/template/fnode/node/src/cli/v2/modes/websocket/imports.njk +15 -0
  166. package/template/fnode/node/src/cli/v2/modes/websocket/index.njk +99 -0
  167. package/template/fnode/node/src/default/engine.js.njk +17 -0
  168. package/template/fnode/node/src/default/input.args.js.njk +126 -0
  169. package/template/fnode/node/tsconfig.json.njk +16 -0
  170. package/template/fnode/project/.gitignore.njk +11 -0
  171. package/template/fnode/project/.vscode/launch.json.njk +78 -0
  172. package/template/fnode/project/.vscode/tasks.json.njk +46 -0
  173. package/template/fnode/project/fnet/targets.yaml.njk +25 -0
  174. package/template/fnode/project/fnode.yaml.njk +12 -0
  175. package/template/fnode/python/.gitignore.njk +7 -0
  176. package/template/fnode/python/package.json.njk +4 -0
  177. package/template/fnode/python/pyproject.toml.njk +3 -0
  178. package/template/fnode/python/readme.md.njk +12 -0
  179. package/template/fnode/python/setup.py.njk +19 -0
  180. package/template/fnode/python/src/cli/index.py.njk +25 -0
  181. package/template/schemas/to-npm.yaml +14 -0
  182. package/dist/builder/lib-cli.js +0 -2
  183. package/dist/builder/wf-cli.js +0 -2
  184. package/dist/index.js +0 -2
@@ -0,0 +1,104 @@
1
+ {# ============================================================================
2
+ WEBSOCKET MODE - MAIN
3
+ ============================================================================
4
+ WebSocket server for real-time bidirectional communication
5
+ Supports connection handling, message processing, and heartbeat
6
+ ============================================================================ #}
7
+
8
+ if (cliMode === 'websocket') {
9
+ // WebSocket mode code
10
+ const port = args['cli-port'] || args.cli_port || 3000;
11
+ const heartbeat = args['ws-heartbeat'] || args.ws_heartbeat || 30000; // 30 seconds default
12
+
13
+ const wss = new WebSocketServer({ port });
14
+
15
+ // Store active connections
16
+ const clients = new Set();
17
+
18
+ wss.on('connection', (ws) => {
19
+ console.log('WebSocket client connected');
20
+ clients.add(ws);
21
+
22
+ // Set up heartbeat
23
+ ws.isAlive = true;
24
+ ws.on('pong', () => {
25
+ ws.isAlive = true;
26
+ });
27
+
28
+ // Handle incoming messages
29
+ ws.on('message', async (data) => {
30
+ try {
31
+ // Parse message
32
+ const message = data.toString();
33
+ let input;
34
+
35
+ try {
36
+ input = JSON.parse(message);
37
+ } catch (e) {
38
+ // If not JSON, wrap in object
39
+ input = { data: message };
40
+ }
41
+
42
+ // Validate input
43
+ // TODO: Add schema validation if needed
44
+
45
+ // Process with Engine
46
+ {% if atom.doc.features.cli.extend===true %}
47
+ const result = await runExtended(input, { Engine });
48
+ {% else %}
49
+ const engine = new Engine();
50
+ const result = await engine.run(input);
51
+ {% endif %}
52
+
53
+ // Send response back to client
54
+ ws.send(JSON.stringify(result));
55
+
56
+ } catch (error) {
57
+ // Send error to client
58
+ ws.send(JSON.stringify({
59
+ error: error.message,
60
+ type: 'processing_error'
61
+ }));
62
+ }
63
+ });
64
+
65
+ // Handle client disconnect
66
+ ws.on('close', () => {
67
+ console.log('WebSocket client disconnected');
68
+ clients.delete(ws);
69
+ });
70
+
71
+ // Handle errors
72
+ ws.on('error', (error) => {
73
+ console.error('WebSocket error:', error.message);
74
+ clients.delete(ws);
75
+ });
76
+ });
77
+
78
+ // Heartbeat interval
79
+ if (heartbeat > 0) {
80
+ const interval = setInterval(() => {
81
+ wss.clients.forEach((ws) => {
82
+ if (ws.isAlive === false) {
83
+ console.log('Terminating inactive client');
84
+ return ws.terminate();
85
+ }
86
+
87
+ ws.isAlive = false;
88
+ ws.ping();
89
+ });
90
+ }, heartbeat);
91
+
92
+ wss.on('close', () => {
93
+ clearInterval(interval);
94
+ });
95
+ }
96
+
97
+ console.log(`WebSocket server started on port ${port}`);
98
+ if (heartbeat > 0) {
99
+ console.log(`Heartbeat interval: ${heartbeat}ms`);
100
+ }
101
+
102
+ return;
103
+ }
104
+
@@ -0,0 +1,15 @@
1
+ {% set assign=true %}
2
+ {% set signal=true %}
3
+ {% set resolve=true %}
4
+
5
+ {% import "src/default/types/block.js.njk" as block with context %}
6
+
7
+ {% call block.header() %}
8
+ {% endcall %}
9
+
10
+ {% call block.definition() %}
11
+
12
+ {% endcall %}
13
+
14
+ {% call block.footer()%}
15
+ {% endcall %}
@@ -0,0 +1,110 @@
1
+ {% set assign=true %}
2
+ {% set signal=true %}
3
+ {% set resolve=true %}
4
+ {% set result=true %}
5
+
6
+ {% import "src/default/types/block.js.njk" as block with context %}
7
+
8
+ {% call block.header() %}
9
+ {% include "src/default/macros/block-library-header.js.njk" %}
10
+ {% endcall %}
11
+
12
+ {% call block.definition() %}
13
+
14
+ {# NEW: Check if 'new' keyword is present for constructor call #}
15
+ {% if context.transform.new !== undefined %}
16
+ {# Constructor instantiation with 'new' keyword #}
17
+ {% if context.lib.type==='atom' and context.lib.atom.protocol!=='use:' %}
18
+ const LibClass=LIBRARY;
19
+ {% elseif context.lib.atom.protocol==='use:' %}
20
+ {# For use:e:: protocol, call value is the class name (e.g., use:e::Map → Map) #}
21
+ const LibClass={{context.transform.import}};
22
+ if(!LibClass) throw new Error('[use] Couldnt find class.');
23
+ {% else %}
24
+ throw new Error('Cannot instantiate: unsupported lib type.');
25
+ {% endif %}
26
+
27
+ {# Create instance with constructor args #}
28
+ {% if context.transform.new %}
29
+ const constructorArgs = {{ context.transform.new | safe }};
30
+ const instance = Array.isArray(constructorArgs) ? new LibClass(...constructorArgs) : new LibClass(constructorArgs);
31
+ {% else %}
32
+ const instance = new LibClass();
33
+ {% endif %}
34
+
35
+ {# If 'call' is specified, get the method from instance #}
36
+ {% if context.transform.call %}
37
+ const callLib = instance.{{context.transform.call}};
38
+ {% else %}
39
+ {# No method call, just return the instance #}
40
+ const callLib = () => instance;
41
+ {% endif %}
42
+
43
+ {% else %}
44
+ {# EXISTING: Normal function/method call (no 'new') #}
45
+ {% if context.lib.type==='atom'%}
46
+ {% if context.transform.libExp %}
47
+ const lib={{context.transform.libExp}};
48
+ {% else %}
49
+ const lib=LIBRARY;
50
+ {% endif %}
51
+ {% elseif context.lib.type==='subworkflow' %}
52
+ const lib={{context.lib.codeKey}};
53
+ {% elseif target.atom.protocol==='use:' %}
54
+ const lib={{context.transform.call}};
55
+ if(!lib) throw new Error('[use] Couldnt find lib.');
56
+ {% else %}
57
+ const lib=undefined;
58
+ throw new Error('Couldn file lib.');
59
+ {% endif %}
60
+
61
+ {% if context.lib.atom.doc.subtype==='workflow'%}
62
+ const Workflow=lib;
63
+ const workflow=new Workflow({app:engine.app,caller:c});
64
+ const callLib = workflow.run.bind(workflow);
65
+ {% elseif context.lib.type==='subworkflow'%}
66
+ const Workflow=lib;
67
+ const workflow=new Workflow({engine,flow,caller:c});
68
+ const callLib = workflow.run.bind(workflow);
69
+ {% else %}
70
+ const callLib = lib;
71
+ {% endif %}
72
+ {% endif %}
73
+
74
+ {# Execute the call #}
75
+ {% if context.transform.args %}
76
+ {% if context.lib.type==='subworkflow' %}
77
+ const callArgs ={ params: {{ context.transform.args | safe }} };
78
+ {% else %}
79
+ const callArgs ={{ context.transform.args | safe }} ;
80
+ {% endif %}
81
+
82
+ {% if context.transform.new !== undefined %}
83
+ {# For constructor calls, use instance as context #}
84
+ const result = Array.isArray(callArgs)? await callLib.apply(instance,callArgs): await callLib.call(instance,callArgs);
85
+ {% else %}
86
+ {# For regular calls, use _this as context #}
87
+ {% if context.transform.context !== undefined %}
88
+ const result = Array.isArray(callArgs)? await callLib.apply({{context.transform.context | safe}},callArgs): await callLib.call({{context.transform.context | safe}},callArgs);
89
+ {% else %}
90
+ const result = Array.isArray(callArgs)? await callLib.apply(_this,callArgs): await callLib.call(_this,callArgs);
91
+ {% endif %}
92
+
93
+ {% endif %}
94
+
95
+ {% else %}
96
+ {% if context.transform.new !== undefined %}
97
+ const result = await callLib.call(instance);
98
+ {% else %}
99
+ {% if context.transform.context !== undefined %}
100
+ const result = await callLib.call({{context.transform.context | safe}});
101
+ {% else %}
102
+ const result = await callLib.call(_this);
103
+ {% endif %}
104
+ {% endif %}
105
+ {% endif %}
106
+
107
+ {% endcall %}
108
+
109
+ {% call block.footer()%}
110
+ {% endcall %}
@@ -0,0 +1,71 @@
1
+ {% set assign=true %}
2
+ {% set signal=true %}
3
+ {% set resolve=true %}
4
+
5
+ {% import "src/default/types/block.js.njk" as block with context %}
6
+
7
+ {% call block.header() %}
8
+ {% if childs.length %}
9
+ {% if not childs[0].definition.dynamic %}
10
+ // FIRST CHILD: {{childs[0].indexKey}}
11
+ import {{childs[0].codeKey}} from "./{{childs[0].codeKey}}.js";
12
+ {% endif %}
13
+ {% endif%}
14
+ {% endcall %}
15
+
16
+ {% call block.definition() %}
17
+
18
+ {% if childs.length %}
19
+ {% if childs[0].definition.dynamic %}
20
+ // FIRST CHILD: {{childs[0].indexKey}}
21
+ const { default: {{childs[0].codeKey}} } = await import("./{{childs[0].codeKey}}.js");
22
+ {% endif %}
23
+ {% endif%}
24
+
25
+ for await(const {{context.transform.for.as | safe}} of {{context.transform.for.in | safe}}){
26
+ // Create Proxy for closure-like variable resolution
27
+ // Local variable shadows parent, but parent scope accessible via Proxy fallback
28
+ const localForVar = { {{context.transform.for.as | safe}}: {{context.transform.for.as | safe}} };
29
+ const forProxy = new Proxy(localForVar, {
30
+ get(target, prop) {
31
+ // Check local scope first (shadowing)
32
+ if (prop in target) return target[prop];
33
+ // Fallback to parent scope
34
+ return c.for?.[prop];
35
+ }
36
+ });
37
+
38
+ // Create new context with updated for
39
+ const loopContext = { ...c, for: forProxy };
40
+
41
+ {% if childs.length %}
42
+ let current= new {{childs[0].codeKey}}({ parent:_this, engine, flow, caller:loopContext });
43
+ let currentArgs=args;
44
+
45
+ do {
46
+
47
+ {% if workflow.parent.context.atom.doc.features.print_runners %}
48
+ console.log(new Date().toLocaleString(),' * ',_this.constructor.IndexKey,' -> ',current.constructor.IndexKey);
49
+ {% endif %}
50
+
51
+ const nextBlock= typeof currentArgs==='undefined'? await current.run()
52
+ : Array.isArray(currentArgs)? await current.run.apply(current,currentArgs) : await current.run.call(current, currentArgs) ;
53
+
54
+ if(nextBlock?.type==='return') return resolve(nextBlock);
55
+ else if(nextBlock?.type!=='block') break;
56
+
57
+ if(nextBlock.toType.ParentTypeId!==_this.constructor.TypeId)
58
+ return resolve(nextBlock);
59
+
60
+ current=new nextBlock.toType({ parent:_this, engine, flow, caller:loopContext, error });
61
+ currentArgs=nextBlock.input;
62
+
63
+ } while(true);
64
+
65
+ {% endif %}
66
+ }
67
+
68
+ {% endcall %}
69
+
70
+ {% call block.footer()%}
71
+ {% endcall %}
@@ -0,0 +1,31 @@
1
+ {% set waitForNext=true %}
2
+ {% set assign=true %}
3
+ {% set signal=true %}
4
+
5
+ {% import "src/default/types/block.js.njk" as block with context %}
6
+
7
+ {% call block.header() %}
8
+
9
+ {% include "src/default/macros/block-library-header.js.njk" %}
10
+
11
+ import React from "react";
12
+
13
+ {% endcall %}
14
+
15
+ {% call block.definition() %}
16
+
17
+ {% if context.lib.type==='atom'%}
18
+ const formLib=LIBRARY;
19
+ {% elseif context.lib.type==='subworkflow' %}
20
+ const formLib={{context.lib.codeKey}};
21
+ {% else %}
22
+ const formLib=undefined;
23
+ throw new Error('Couldnt find form.');
24
+ {% endif %}
25
+
26
+ {% include "src/default/macros/block-run-form.js.njk" %}
27
+
28
+ {% endcall %}
29
+
30
+ {% call block.footer()%}
31
+ {% endcall %}
@@ -0,0 +1,135 @@
1
+ {% set assign=true %}
2
+ {% set signal=true %}
3
+ {% set resolve=true %}
4
+ {% set result=true %}
5
+
6
+ {% import "src/default/types/block.js.njk" as block with context %}
7
+
8
+ {% call block.header() %}
9
+ {% endcall %}
10
+
11
+ {% call block.definition() %}
12
+
13
+ // HTTP configuration
14
+ let url = {{ context.transform.http.url | safe }};
15
+ let method = "{{ context.transform.http.method |safe }}";
16
+ let headers = {{ context.transform.http.headers | safe }};
17
+ let timeout = {{ context.transform.http.timeout }};
18
+ {% if context.transform.http.body !== undefined %}
19
+ let body = {% if context.transform.http.body is string %}{{ context.transform.http.body |safe }}{% else %}{{ context.transform.http.body | safe }}{% endif %};
20
+ {% endif %}
21
+ {% if context.transform.http.params %}
22
+ let params = {{ context.transform.http.params | safe }};
23
+ {% endif %}
24
+
25
+ // Create HTTP context for modules
26
+ const httpContext = { url, method, headers, timeout, params: {% if context.transform.http.params %}params{% else %}undefined{% endif %}, body: {% if context.transform.http.body !== undefined %}body{% else %}undefined{% endif %} };
27
+
28
+ // If any property is a module function (m::), call it with HTTP context
29
+ if (typeof url === 'function') {
30
+ url = await url(httpContext);
31
+ }
32
+
33
+ if (typeof method === 'function') {
34
+ method = await method(httpContext);
35
+ }
36
+
37
+ if (typeof headers === 'function') {
38
+ headers = await headers(httpContext);
39
+ }
40
+
41
+ if (typeof timeout === 'function') {
42
+ timeout = await timeout(httpContext);
43
+ }
44
+
45
+ {% if context.transform.http.params %}
46
+ if (typeof params === 'function') {
47
+ params = await params(httpContext);
48
+ }
49
+ {% endif %}
50
+
51
+ {% if context.transform.http.body !== undefined %}
52
+ if (typeof body === 'function') {
53
+ body = await body(httpContext);
54
+ }
55
+ {% endif %}
56
+
57
+ // Build URL with query parameters if provided
58
+ let finalUrl = url;
59
+ {% if context.transform.http.params %}
60
+ if (params && Object.keys(params).length > 0) {
61
+ const queryString = new URLSearchParams(params).toString();
62
+ finalUrl = url + (url.includes('?') ? '&' : '?') + queryString;
63
+ }
64
+ {% endif %}
65
+
66
+ // Prepare fetch options
67
+ const fetchOptions = {
68
+ method: method,
69
+ headers: headers
70
+ };
71
+
72
+ // Add body if present (and not GET/HEAD)
73
+ {% if context.transform.http.body %}
74
+ if (body !== undefined && method !== 'GET' && method !== 'HEAD') {
75
+ // Auto JSON.stringify if body is object
76
+ if (typeof body === 'object' && body !== null) {
77
+ fetchOptions.body = JSON.stringify(body);
78
+ // Auto set Content-Type if not already set
79
+ if (!fetchOptions.headers['Content-Type'] && !fetchOptions.headers['content-type']) {
80
+ fetchOptions.headers['Content-Type'] = 'application/json';
81
+ }
82
+ } else {
83
+ fetchOptions.body = body;
84
+ }
85
+ }
86
+ {% endif %}
87
+
88
+ // Create abort controller for timeout
89
+ const controller = new AbortController();
90
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
91
+ fetchOptions.signal = controller.signal;
92
+
93
+ let result;
94
+
95
+ try {
96
+ // Execute HTTP request
97
+ const response = await fetch(finalUrl, fetchOptions);
98
+ clearTimeout(timeoutId);
99
+
100
+ // Check if response is successful (2xx)
101
+ if (!response.ok) {
102
+ throw new Error(`HTTP ${response.status}: ${response.statusText}`);
103
+ }
104
+
105
+ // Parse response based on Content-Type
106
+ const contentType = response.headers.get('content-type');
107
+
108
+ if (contentType && contentType.includes('application/json')) {
109
+ result = await response.json();
110
+ } else if (contentType && contentType.includes('text/')) {
111
+ result = await response.text();
112
+ } else {
113
+ // Try JSON first, fallback to text
114
+ try {
115
+ result = await response.json();
116
+ } catch (e) {
117
+ result = await response.text();
118
+ }
119
+ }
120
+ } catch (error) {
121
+ clearTimeout(timeoutId);
122
+
123
+ // Handle timeout error
124
+ if (error.name === 'AbortError') {
125
+ const timeoutError = new Error(`HTTP request timeout after ${timeout}ms: ${finalUrl}`);
126
+ return reject(timeoutError);
127
+ }
128
+
129
+ // Handle other errors
130
+ return reject(error);
131
+ }
132
+ {% endcall %}
133
+
134
+ {% call block.footer()%}
135
+ {% endcall %}
@@ -0,0 +1,15 @@
1
+ {% set assign=true %}
2
+ {% set signal=true %}
3
+ {% set resolve=true %}
4
+
5
+ {% import "src/default/types/block.js.njk" as block with context %}
6
+
7
+ {% call block.header() %}
8
+ {% endcall %}
9
+
10
+ {% call block.definition() %}
11
+
12
+ {% endcall %}
13
+
14
+ {% call block.footer()%}
15
+ {% endcall %}
@@ -0,0 +1,42 @@
1
+ {% set assign=true %}
2
+ {% set signal=true %}
3
+ {% set resolve=true %}
4
+ {% set result=true %}
5
+
6
+ {% import "src/default/types/block.js.njk" as block with context %}
7
+
8
+ {% call block.header() %}
9
+ {% include "src/default/macros/block-library-header.js.njk" %}
10
+ {% endcall %}
11
+
12
+ {% call block.definition() %}
13
+
14
+ {# NEW: Check if 'new' keyword is present for constructor call #}
15
+ {% if context.transform.new !== undefined %}
16
+ {# Constructor instantiation with 'new' keyword #}
17
+ {% if context.lib.type==='atom' and context.lib.atom.protocol!=='use:' %}
18
+ const LibClass=LIBRARY;
19
+ {% elseif context.lib.atom.protocol==='use:' %}
20
+ {# For use:e:: protocol, call value is the class name (e.g., use:e::Map → Map) #}
21
+ const LibClass={{context.transform.import}};
22
+ if(!LibClass) throw new Error('[use] Couldnt find class.');
23
+ {% else %}
24
+ throw new Error('Cannot instantiate: unsupported lib type.');
25
+ {% endif %}
26
+
27
+ {# Create instance with constructor args #}
28
+ {% if context.transform.new %}
29
+ const constructorArgs = {{ context.transform.new | safe }};
30
+ const instance = Array.isArray(constructorArgs) ? new LibClass(...constructorArgs) : new LibClass(constructorArgs);
31
+ {% else %}
32
+ const instance = new LibClass();
33
+ {% endif %}
34
+
35
+ {% endif %}
36
+
37
+ const result = instance;
38
+
39
+ {% endcall %}
40
+
41
+ {% call block.footer()%}
42
+ {% endcall %}
@@ -0,0 +1,15 @@
1
+ {% set assign=true %}
2
+ {% set signal=true %}
3
+ {% set resolve=true %}
4
+
5
+ {% import "src/default/types/block.js.njk" as block with context %}
6
+
7
+ {% call block.header() %}
8
+ {% endcall %}
9
+
10
+ {% call block.definition() %}
11
+
12
+ {% endcall %}
13
+
14
+ {% call block.footer()%}
15
+ {% endcall %}
@@ -0,0 +1,15 @@
1
+ {% set assign=true %}
2
+ {% set signal=true %}
3
+ {% set resolve=true %}
4
+
5
+ {% import "src/default/types/block.js.njk" as block with context %}
6
+
7
+ {% call block.header() %}
8
+ {% endcall %}
9
+
10
+ {% call block.definition() %}
11
+
12
+ {% endcall %}
13
+
14
+ {% call block.footer()%}
15
+ {% endcall %}
@@ -0,0 +1,64 @@
1
+ {% set assign=true %}
2
+ {% set signal=true %}
3
+ {% set resolve=true %}
4
+ {% set result=true %}
5
+
6
+ {% import "src/default/types/block.js.njk" as block with context %}
7
+
8
+ {% call block.header() %}
9
+ {% for child in childs %}
10
+ {% if not child.definition.dynamic %}
11
+ // PARALLEL CHILD: {{child.indexKey}}
12
+ import {{child.codeKey}} from "./{{child.codeKey}}.js";
13
+ {% endif %}
14
+ {% endfor %}
15
+ {% endcall %}
16
+
17
+ {% call block.definition() %}
18
+ // PARALLEL EXECUTION
19
+ const promises = [];
20
+
21
+ {% for child in childs %}
22
+ {% if child.definition.dynamic %}
23
+ // PARALLEL CHILD: {{child.indexKey}}
24
+ const { default: {{child.codeKey}} } = await import("./{{child.codeKey}}.js");
25
+ {% endif %}
26
+
27
+ promises.push((async () => {
28
+ const current = new {{child.codeKey}}({ parent: _this, engine, flow, caller: c, error });
29
+
30
+ {% if workflow.parent.context.atom.doc.features.print_runners %}
31
+ console.log(new Date().toLocaleString(), ' * ', _this.constructor.IndexKey, ' -> ', current.constructor.IndexKey);
32
+ {% endif %}
33
+
34
+ const nextBlock = Array.isArray(args)
35
+ ? await current.run.apply(current, args)
36
+ : await current.run.call(current, args);
37
+
38
+ return nextBlock;
39
+ })());
40
+ {% endfor %}
41
+
42
+ // Execute based on strategy
43
+ {% set strategy = context.transform.strategy | default('all') %}
44
+ let result;
45
+
46
+ {% if strategy == 'race' %}
47
+ // Promise.race - first to complete wins
48
+ result = [await Promise.race(promises)];
49
+ {% elif strategy == 'any' %}
50
+ // Promise.any - first successful wins
51
+ result = [await Promise.any(promises)];
52
+ {% elif strategy == 'allsettled' %}
53
+ // Promise.allSettled - all complete, collect results
54
+ const settled = await Promise.allSettled(promises);
55
+ result = settled.map(r => r.status === 'fulfilled' ? r.value : null);
56
+ {% else %}
57
+ // Promise.all - all must succeed (default)
58
+ result = await Promise.all(promises);
59
+ {% endif %}
60
+
61
+ {% endcall %}
62
+
63
+ {% call block.footer()%}
64
+ {% endcall %}