@comake/skl-js-engine 1.3.8 → 1.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.
Files changed (297) hide show
  1. package/dist/JsExecutor/PermissionBuilder.d.ts +1 -0
  2. package/dist/JsExecutor/PermissionBuilder.d.ts.map +1 -0
  3. package/dist/JsExecutor/PermissionBuilder.js.map +1 -1
  4. package/dist/JsExecutor/constants.d.ts +1 -0
  5. package/dist/JsExecutor/constants.d.ts.map +1 -0
  6. package/dist/JsExecutor/constants.js.map +1 -1
  7. package/dist/JsExecutor/denoUtils.d.ts +1 -0
  8. package/dist/JsExecutor/denoUtils.d.ts.map +1 -0
  9. package/dist/JsExecutor/denoUtils.js.map +1 -1
  10. package/dist/JsExecutor/errors.d.ts +1 -0
  11. package/dist/JsExecutor/errors.d.ts.map +1 -0
  12. package/dist/JsExecutor/errors.js.map +1 -1
  13. package/dist/JsExecutor/examples/basic/index.d.ts +1 -0
  14. package/dist/JsExecutor/examples/basic/index.d.ts.map +1 -0
  15. package/dist/JsExecutor/examples/basic/index.js.map +1 -1
  16. package/dist/JsExecutor/examples/basic/process.d.ts +1 -0
  17. package/dist/JsExecutor/examples/basic/process.d.ts.map +1 -0
  18. package/dist/JsExecutor/examples/basic/process.js.map +1 -1
  19. package/dist/JsExecutor/examples/jsExecutor/index.d.ts +1 -0
  20. package/dist/JsExecutor/examples/jsExecutor/index.d.ts.map +1 -0
  21. package/dist/JsExecutor/examples/jsExecutor/index.js.map +1 -1
  22. package/dist/JsExecutor/examples/jsExecutor/process.d.ts +1 -0
  23. package/dist/JsExecutor/examples/jsExecutor/process.d.ts.map +1 -0
  24. package/dist/JsExecutor/examples/jsExecutor/process.js.map +1 -1
  25. package/dist/JsExecutor/index.d.ts +1 -0
  26. package/dist/JsExecutor/index.d.ts.map +1 -0
  27. package/dist/JsExecutor/index.js.map +1 -1
  28. package/dist/JsExecutor/jsExecutor.d.ts +1 -0
  29. package/dist/JsExecutor/jsExecutor.d.ts.map +1 -0
  30. package/dist/JsExecutor/jsExecutor.js.map +1 -1
  31. package/dist/JsExecutor/jsonRpc/JsonRpcClient.d.ts +1 -0
  32. package/dist/JsExecutor/jsonRpc/JsonRpcClient.d.ts.map +1 -0
  33. package/dist/JsExecutor/jsonRpc/JsonRpcClient.js.map +1 -1
  34. package/dist/JsExecutor/jsonRpc/JsonRpcServer.d.ts +1 -0
  35. package/dist/JsExecutor/jsonRpc/JsonRpcServer.d.ts.map +1 -0
  36. package/dist/JsExecutor/jsonRpc/JsonRpcServer.js.map +1 -1
  37. package/dist/JsExecutor/jsonRpc/index.d.ts +1 -0
  38. package/dist/JsExecutor/jsonRpc/index.d.ts.map +1 -0
  39. package/dist/JsExecutor/jsonRpc/index.js.map +1 -1
  40. package/dist/JsExecutor/jsonRpc/types.d.ts +1 -0
  41. package/dist/JsExecutor/jsonRpc/types.d.ts.map +1 -0
  42. package/dist/JsExecutor/jsonRpc/types.js.map +1 -1
  43. package/dist/JsExecutor/transport/Transport.d.ts +1 -0
  44. package/dist/JsExecutor/transport/Transport.d.ts.map +1 -0
  45. package/dist/JsExecutor/transport/Transport.js.map +1 -1
  46. package/dist/JsExecutor/transport/base/BaseTransport.d.ts +1 -0
  47. package/dist/JsExecutor/transport/base/BaseTransport.d.ts.map +1 -0
  48. package/dist/JsExecutor/transport/base/BaseTransport.js.map +1 -1
  49. package/dist/JsExecutor/transport/index.d.ts +1 -0
  50. package/dist/JsExecutor/transport/index.d.ts.map +1 -0
  51. package/dist/JsExecutor/transport/index.js.map +1 -1
  52. package/dist/JsExecutor/transport/process/ProcessManager.d.ts +1 -0
  53. package/dist/JsExecutor/transport/process/ProcessManager.d.ts.map +1 -0
  54. package/dist/JsExecutor/transport/process/ProcessManager.js.map +1 -1
  55. package/dist/JsExecutor/transport/stdio/ChildStdioTransport.d.ts +1 -0
  56. package/dist/JsExecutor/transport/stdio/ChildStdioTransport.d.ts.map +1 -0
  57. package/dist/JsExecutor/transport/stdio/ChildStdioTransport.js.map +1 -1
  58. package/dist/JsExecutor/transport/stdio/ParentStdioTransport.d.ts +1 -0
  59. package/dist/JsExecutor/transport/stdio/ParentStdioTransport.d.ts.map +1 -0
  60. package/dist/JsExecutor/transport/stdio/ParentStdioTransport.js.map +1 -1
  61. package/dist/JsExecutor/transport/utils/MessageUtils.d.ts +1 -0
  62. package/dist/JsExecutor/transport/utils/MessageUtils.d.ts.map +1 -0
  63. package/dist/JsExecutor/transport/utils/MessageUtils.js.map +1 -1
  64. package/dist/JsExecutor/transport/utils/PollingUtils.d.ts +1 -0
  65. package/dist/JsExecutor/transport/utils/PollingUtils.d.ts.map +1 -0
  66. package/dist/JsExecutor/transport/utils/PollingUtils.js.map +1 -1
  67. package/dist/JsExecutor/types.d.ts +1 -0
  68. package/dist/JsExecutor/types.d.ts.map +1 -0
  69. package/dist/JsExecutor/types.js.map +1 -1
  70. package/dist/SklEngine.d.ts +1 -0
  71. package/dist/SklEngine.d.ts.map +1 -0
  72. package/dist/SklEngine.js.map +1 -1
  73. package/dist/SklEngineOptions.d.ts +1 -0
  74. package/dist/SklEngineOptions.d.ts.map +1 -0
  75. package/dist/SklEngineOptions.js.map +1 -1
  76. package/dist/constants.d.ts +1 -0
  77. package/dist/constants.d.ts.map +1 -0
  78. package/dist/constants.js.map +1 -1
  79. package/dist/customCapabilities.d.ts +1 -0
  80. package/dist/customCapabilities.d.ts.map +1 -0
  81. package/dist/customCapabilities.js.map +1 -1
  82. package/dist/examples/customCapabilitiesExample.d.ts +1 -0
  83. package/dist/examples/customCapabilitiesExample.d.ts.map +1 -0
  84. package/dist/examples/customCapabilitiesExample.js.map +1 -1
  85. package/dist/hooks/globalHooks.d.ts +1 -0
  86. package/dist/hooks/globalHooks.d.ts.map +1 -0
  87. package/dist/hooks/globalHooks.js.map +1 -1
  88. package/dist/hooks/types.d.ts +1 -0
  89. package/dist/hooks/types.d.ts.map +1 -0
  90. package/dist/hooks/types.js.map +1 -1
  91. package/dist/index.d.ts +1 -0
  92. package/dist/index.d.ts.map +1 -0
  93. package/dist/index.js.map +1 -1
  94. package/dist/logger.d.ts +1 -0
  95. package/dist/logger.d.ts.map +1 -0
  96. package/dist/logger.js.map +1 -1
  97. package/dist/mapping/Mapper.d.ts +1 -0
  98. package/dist/mapping/Mapper.d.ts.map +1 -0
  99. package/dist/mapping/Mapper.js.map +1 -1
  100. package/dist/storage/FindOperator.d.ts +1 -0
  101. package/dist/storage/FindOperator.d.ts.map +1 -0
  102. package/dist/storage/FindOperator.js.map +1 -1
  103. package/dist/storage/FindOptionsTypes.d.ts +1 -0
  104. package/dist/storage/FindOptionsTypes.d.ts.map +1 -0
  105. package/dist/storage/FindOptionsTypes.js.map +1 -1
  106. package/dist/storage/GroupOptionTypes.d.ts +1 -0
  107. package/dist/storage/GroupOptionTypes.d.ts.map +1 -0
  108. package/dist/storage/GroupOptionTypes.js.map +1 -1
  109. package/dist/storage/operator/And.d.ts +1 -0
  110. package/dist/storage/operator/And.d.ts.map +1 -0
  111. package/dist/storage/operator/And.js.map +1 -1
  112. package/dist/storage/operator/Contains.d.ts +1 -0
  113. package/dist/storage/operator/Contains.d.ts.map +1 -0
  114. package/dist/storage/operator/Contains.js.map +1 -1
  115. package/dist/storage/operator/Equal.d.ts +1 -0
  116. package/dist/storage/operator/Equal.d.ts.map +1 -0
  117. package/dist/storage/operator/Equal.js.map +1 -1
  118. package/dist/storage/operator/Exists.d.ts +1 -0
  119. package/dist/storage/operator/Exists.d.ts.map +1 -0
  120. package/dist/storage/operator/Exists.js.map +1 -1
  121. package/dist/storage/operator/GreaterThan.d.ts +1 -0
  122. package/dist/storage/operator/GreaterThan.d.ts.map +1 -0
  123. package/dist/storage/operator/GreaterThan.js.map +1 -1
  124. package/dist/storage/operator/GreaterThanOrEqual.d.ts +1 -0
  125. package/dist/storage/operator/GreaterThanOrEqual.d.ts.map +1 -0
  126. package/dist/storage/operator/GreaterThanOrEqual.js.map +1 -1
  127. package/dist/storage/operator/In.d.ts +1 -0
  128. package/dist/storage/operator/In.d.ts.map +1 -0
  129. package/dist/storage/operator/In.js.map +1 -1
  130. package/dist/storage/operator/Inverse.d.ts +1 -0
  131. package/dist/storage/operator/Inverse.d.ts.map +1 -0
  132. package/dist/storage/operator/Inverse.js.map +1 -1
  133. package/dist/storage/operator/InversePath.d.ts +1 -0
  134. package/dist/storage/operator/InversePath.d.ts.map +1 -0
  135. package/dist/storage/operator/InversePath.js.map +1 -1
  136. package/dist/storage/operator/InverseRelation.d.ts +1 -0
  137. package/dist/storage/operator/InverseRelation.d.ts.map +1 -0
  138. package/dist/storage/operator/InverseRelation.js.map +1 -1
  139. package/dist/storage/operator/InverseRelationOrder.d.ts +1 -0
  140. package/dist/storage/operator/InverseRelationOrder.d.ts.map +1 -0
  141. package/dist/storage/operator/InverseRelationOrder.js.map +1 -1
  142. package/dist/storage/operator/LessThan.d.ts +1 -0
  143. package/dist/storage/operator/LessThan.d.ts.map +1 -0
  144. package/dist/storage/operator/LessThan.js.map +1 -1
  145. package/dist/storage/operator/LessThanOrEqual.d.ts +1 -0
  146. package/dist/storage/operator/LessThanOrEqual.d.ts.map +1 -0
  147. package/dist/storage/operator/LessThanOrEqual.js.map +1 -1
  148. package/dist/storage/operator/Not.d.ts +1 -0
  149. package/dist/storage/operator/Not.d.ts.map +1 -0
  150. package/dist/storage/operator/Not.js.map +1 -1
  151. package/dist/storage/operator/OneOrMorePath.d.ts +1 -0
  152. package/dist/storage/operator/OneOrMorePath.d.ts.map +1 -0
  153. package/dist/storage/operator/OneOrMorePath.js.map +1 -1
  154. package/dist/storage/operator/Sequence.d.ts +1 -0
  155. package/dist/storage/operator/Sequence.d.ts.map +1 -0
  156. package/dist/storage/operator/Sequence.js.map +1 -1
  157. package/dist/storage/operator/SequencePath.d.ts +1 -0
  158. package/dist/storage/operator/SequencePath.d.ts.map +1 -0
  159. package/dist/storage/operator/SequencePath.js.map +1 -1
  160. package/dist/storage/operator/ZeroOrMorePath.d.ts +1 -0
  161. package/dist/storage/operator/ZeroOrMorePath.d.ts.map +1 -0
  162. package/dist/storage/operator/ZeroOrMorePath.js.map +1 -1
  163. package/dist/storage/query-adapter/QueryAdapter.d.ts +1 -0
  164. package/dist/storage/query-adapter/QueryAdapter.d.ts.map +1 -0
  165. package/dist/storage/query-adapter/QueryAdapter.js.map +1 -1
  166. package/dist/storage/query-adapter/sparql/SparqlQueryAdapter.d.ts +1 -0
  167. package/dist/storage/query-adapter/sparql/SparqlQueryAdapter.d.ts.map +1 -0
  168. package/dist/storage/query-adapter/sparql/SparqlQueryAdapter.js +28 -4
  169. package/dist/storage/query-adapter/sparql/SparqlQueryAdapter.js.map +1 -1
  170. package/dist/storage/query-adapter/sparql/SparqlQueryAdapterOptions.d.ts +1 -0
  171. package/dist/storage/query-adapter/sparql/SparqlQueryAdapterOptions.d.ts.map +1 -0
  172. package/dist/storage/query-adapter/sparql/SparqlQueryAdapterOptions.js.map +1 -1
  173. package/dist/storage/query-adapter/sparql/SparqlQueryBuilder.d.ts +1 -0
  174. package/dist/storage/query-adapter/sparql/SparqlQueryBuilder.d.ts.map +1 -0
  175. package/dist/storage/query-adapter/sparql/SparqlQueryBuilder.js +7 -21
  176. package/dist/storage/query-adapter/sparql/SparqlQueryBuilder.js.map +1 -1
  177. package/dist/storage/query-adapter/sparql/SparqlUpdateBuilder.d.ts +1 -0
  178. package/dist/storage/query-adapter/sparql/SparqlUpdateBuilder.d.ts.map +1 -0
  179. package/dist/storage/query-adapter/sparql/SparqlUpdateBuilder.js.map +1 -1
  180. package/dist/storage/query-adapter/sparql/VariableGenerator.d.ts +1 -0
  181. package/dist/storage/query-adapter/sparql/VariableGenerator.d.ts.map +1 -0
  182. package/dist/storage/query-adapter/sparql/VariableGenerator.js.map +1 -1
  183. package/dist/storage/query-adapter/sparql/query-executor/InMemorySparqlQueryExecutor.d.ts +1 -0
  184. package/dist/storage/query-adapter/sparql/query-executor/InMemorySparqlQueryExecutor.d.ts.map +1 -0
  185. package/dist/storage/query-adapter/sparql/query-executor/InMemorySparqlQueryExecutor.js.map +1 -1
  186. package/dist/storage/query-adapter/sparql/query-executor/SparqlEndpointQueryExecutor.d.ts +1 -0
  187. package/dist/storage/query-adapter/sparql/query-executor/SparqlEndpointQueryExecutor.d.ts.map +1 -0
  188. package/dist/storage/query-adapter/sparql/query-executor/SparqlEndpointQueryExecutor.js.map +1 -1
  189. package/dist/storage/query-adapter/sparql/query-executor/SparqlQueryExecutor.d.ts +1 -0
  190. package/dist/storage/query-adapter/sparql/query-executor/SparqlQueryExecutor.d.ts.map +1 -0
  191. package/dist/storage/query-adapter/sparql/query-executor/SparqlQueryExecutor.js.map +1 -1
  192. package/dist/util/PerformanceLogger.d.ts +1 -0
  193. package/dist/util/PerformanceLogger.d.ts.map +1 -0
  194. package/dist/util/PerformanceLogger.js.map +1 -1
  195. package/dist/util/SparqlUtil.d.ts +1 -0
  196. package/dist/util/SparqlUtil.d.ts.map +1 -0
  197. package/dist/util/SparqlUtil.js.map +1 -1
  198. package/dist/util/TripleUtil.d.ts +1 -0
  199. package/dist/util/TripleUtil.d.ts.map +1 -0
  200. package/dist/util/TripleUtil.js +10 -0
  201. package/dist/util/TripleUtil.js.map +1 -1
  202. package/dist/util/Types.d.ts +1 -0
  203. package/dist/util/Types.d.ts.map +1 -0
  204. package/dist/util/Types.js.map +1 -1
  205. package/dist/util/Util.d.ts +1 -0
  206. package/dist/util/Util.d.ts.map +1 -0
  207. package/dist/util/Util.js.map +1 -1
  208. package/dist/util/Vocabularies/Shared.d.ts +1 -0
  209. package/dist/util/Vocabularies/Shared.d.ts.map +1 -0
  210. package/dist/util/Vocabularies/Shared.js.map +1 -1
  211. package/dist/util/Vocabularies/helper.d.ts +1 -0
  212. package/dist/util/Vocabularies/helper.d.ts.map +1 -0
  213. package/dist/util/Vocabularies/helper.js.map +1 -1
  214. package/dist/util/Vocabularies/index.d.ts +1 -0
  215. package/dist/util/Vocabularies/index.d.ts.map +1 -0
  216. package/dist/util/Vocabularies/index.js.map +1 -1
  217. package/dist/util/safeJsonStringify.d.ts +1 -0
  218. package/dist/util/safeJsonStringify.d.ts.map +1 -0
  219. package/dist/util/safeJsonStringify.js.map +1 -1
  220. package/package.json +6 -3
  221. package/src/JsExecutor/PermissionBuilder.ts +60 -0
  222. package/src/JsExecutor/constants.ts +27 -0
  223. package/src/JsExecutor/denoUtils.ts +20 -0
  224. package/src/JsExecutor/errors.ts +63 -0
  225. package/src/JsExecutor/examples/basic/index.ts +54 -0
  226. package/src/JsExecutor/examples/basic/process.ts +39 -0
  227. package/src/JsExecutor/examples/jsExecutor/README.md +3 -0
  228. package/src/JsExecutor/examples/jsExecutor/index.ts +50 -0
  229. package/src/JsExecutor/examples/jsExecutor/process.ts +79 -0
  230. package/src/JsExecutor/index.ts +19 -0
  231. package/src/JsExecutor/jsExecutor.ts +194 -0
  232. package/src/JsExecutor/jsonRpc/JsonRpcClient.ts +422 -0
  233. package/src/JsExecutor/jsonRpc/JsonRpcServer.ts +454 -0
  234. package/src/JsExecutor/jsonRpc/index.ts +4 -0
  235. package/src/JsExecutor/jsonRpc/types.ts +231 -0
  236. package/src/JsExecutor/transport/README.md +67 -0
  237. package/src/JsExecutor/transport/Transport.ts +106 -0
  238. package/src/JsExecutor/transport/base/BaseTransport.ts +83 -0
  239. package/src/JsExecutor/transport/index.ts +56 -0
  240. package/src/JsExecutor/transport/process/ProcessManager.ts +281 -0
  241. package/src/JsExecutor/transport/stdio/ChildStdioTransport.ts +251 -0
  242. package/src/JsExecutor/transport/stdio/ParentStdioTransport.ts +308 -0
  243. package/src/JsExecutor/transport/utils/MessageUtils.ts +139 -0
  244. package/src/JsExecutor/transport/utils/PollingUtils.ts +114 -0
  245. package/src/JsExecutor/types.ts +130 -0
  246. package/src/SklEngine.ts +1828 -0
  247. package/src/SklEngineOptions.ts +28 -0
  248. package/src/constants.ts +120 -0
  249. package/src/customCapabilities.ts +65 -0
  250. package/src/examples/customCapabilitiesExample.ts +77 -0
  251. package/src/hooks/globalHooks.ts +238 -0
  252. package/src/hooks/types.ts +7 -0
  253. package/src/index.ts +45 -0
  254. package/src/logger.ts +144 -0
  255. package/src/mapping/Mapper.ts +52 -0
  256. package/src/storage/FindOperator.ts +55 -0
  257. package/src/storage/FindOptionsTypes.ts +107 -0
  258. package/src/storage/GroupOptionTypes.ts +32 -0
  259. package/src/storage/operator/And.ts +10 -0
  260. package/src/storage/operator/Contains.ts +9 -0
  261. package/src/storage/operator/Equal.ts +13 -0
  262. package/src/storage/operator/Exists.ts +6 -0
  263. package/src/storage/operator/GreaterThan.ts +12 -0
  264. package/src/storage/operator/GreaterThanOrEqual.ts +12 -0
  265. package/src/storage/operator/In.ts +12 -0
  266. package/src/storage/operator/Inverse.ts +11 -0
  267. package/src/storage/operator/InversePath.ts +17 -0
  268. package/src/storage/operator/InverseRelation.ts +18 -0
  269. package/src/storage/operator/InverseRelationOrder.ts +17 -0
  270. package/src/storage/operator/LessThan.ts +12 -0
  271. package/src/storage/operator/LessThanOrEqual.ts +12 -0
  272. package/src/storage/operator/Not.ts +11 -0
  273. package/src/storage/operator/OneOrMorePath.ts +17 -0
  274. package/src/storage/operator/Sequence.ts +11 -0
  275. package/src/storage/operator/SequencePath.ts +17 -0
  276. package/src/storage/operator/ZeroOrMorePath.ts +17 -0
  277. package/src/storage/query-adapter/QueryAdapter.ts +110 -0
  278. package/src/storage/query-adapter/sparql/SparqlQueryAdapter.ts +400 -0
  279. package/src/storage/query-adapter/sparql/SparqlQueryAdapterOptions.ts +38 -0
  280. package/src/storage/query-adapter/sparql/SparqlQueryBuilder.ts +1524 -0
  281. package/src/storage/query-adapter/sparql/SparqlUpdateBuilder.ts +347 -0
  282. package/src/storage/query-adapter/sparql/VariableGenerator.ts +8 -0
  283. package/src/storage/query-adapter/sparql/query-executor/InMemorySparqlQueryExecutor.ts +135 -0
  284. package/src/storage/query-adapter/sparql/query-executor/SparqlEndpointQueryExecutor.ts +146 -0
  285. package/src/storage/query-adapter/sparql/query-executor/SparqlQueryExecutor.ts +51 -0
  286. package/src/util/PerformanceLogger.ts +286 -0
  287. package/src/util/SparqlUtil.ts +516 -0
  288. package/src/util/TripleUtil.ts +412 -0
  289. package/src/util/Types.ts +399 -0
  290. package/src/util/Util.ts +116 -0
  291. package/src/util/Vocabularies/Shared.ts +99 -0
  292. package/src/util/Vocabularies/helper.ts +14 -0
  293. package/src/util/Vocabularies/index.ts +108 -0
  294. package/src/util/safeJsonStringify.ts +19 -0
  295. package/dist/JsExecutor/transport/StdioTransport.d.ts +0 -0
  296. package/dist/JsExecutor/transport/StdioTransport.js +0 -641
  297. package/dist/JsExecutor/transport/StdioTransport.js.map +0 -1
@@ -0,0 +1,251 @@
1
+ /* eslint-disable indent */
2
+ import { EventEmitter } from 'node:events';
3
+ import type { ClientTransport } from '../../jsonRpc/JsonRpcClient';
4
+ import { JsonRpcClient } from '../../jsonRpc/JsonRpcClient';
5
+ import { JsonRpcServer } from '../../jsonRpc/JsonRpcServer';
6
+ import { isResponse, MessageBuffer } from '../utils/MessageUtils';
7
+
8
+ /**
9
+ * Custom logger that outputs to stderr to avoid contaminating stdout JSON-RPC channel
10
+ */
11
+ class ChildProcessLogger {
12
+ private readonly name?: string;
13
+ private metadata: Record<string, any> = {};
14
+
15
+ public setMetadata(metadata: Record<string, any>): void {
16
+ this.metadata = { ...this.metadata, ...metadata };
17
+ }
18
+
19
+ public log(message: string, data?: any): void {
20
+ const logEntry = {
21
+ message,
22
+ metadata: this.metadata,
23
+ ...data && { data }
24
+ };
25
+ // Use stderr to avoid contaminating stdout JSON-RPC channel
26
+ process.stderr.write(`${message} ${JSON.stringify(logEntry.metadata)} ${data ? JSON.stringify(data) : ''}\n`);
27
+ }
28
+
29
+ public error(message: string, error?: Error): void {
30
+ const logEntry = {
31
+ level: 'error',
32
+ message,
33
+ metadata: this.metadata,
34
+ ...error && { error: error.message, stack: error.stack }
35
+ };
36
+ process.stderr.write(`ERROR: ${JSON.stringify(logEntry)}\n`);
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Bidirectional StdioTransport for child processes
42
+ * This class handles both server (receiving requests) and client (sending requests) functionality
43
+ * over a single stdio channel with proper message routing.
44
+ *
45
+ * Usage in child process:
46
+ * ```typescript
47
+ * const transport = new ChildStdioTransport();
48
+ *
49
+ * // Register methods that parent can call
50
+ * transport.registerMethod('ping', async () => 'pong');
51
+ *
52
+ * // Make requests to parent
53
+ * const result = await transport.request('getTime');
54
+ * ```
55
+ */
56
+ export class ChildStdioTransport extends EventEmitter {
57
+ private readonly server: JsonRpcServer;
58
+ private readonly client: JsonRpcClient;
59
+ private readonly logger = new ChildProcessLogger();
60
+ private readonly messageBuffer = new MessageBuffer();
61
+ private name?: string;
62
+ private initialized = false;
63
+
64
+ public constructor() {
65
+ super();
66
+ this.server = new JsonRpcServer({
67
+ requestTimeout: 60 * 60 * 1000
68
+ });
69
+ this.client = new JsonRpcClient({
70
+ defaultTimeout: 60 * 60 * 1000
71
+ });
72
+
73
+ // Set up the client transport that routes through our stdio
74
+ const clientTransport: ClientTransport = {
75
+ send: async(message: string): Promise<void> => {
76
+ this.sendMessage(message);
77
+ },
78
+ onMessage(): void {
79
+ // The message routing will handle client responses automatically
80
+ },
81
+ async close(): Promise<void> {
82
+ // Nothing to close for stdio
83
+ }
84
+ };
85
+
86
+ this.client.setTransport(clientTransport);
87
+ this.setupEventHandlers();
88
+ }
89
+
90
+ /**
91
+ * Set a name for this transport (used in logging)
92
+ */
93
+ public setName(name: string): void {
94
+ this.name = name;
95
+ this.logger.setMetadata({ name, transport: 'ChildStdioTransport' });
96
+ }
97
+
98
+ /**
99
+ * Initialize the bidirectional transport
100
+ * This should be called once after setting up all methods
101
+ */
102
+ public async initialize(): Promise<void> {
103
+ if (this.initialized) {
104
+ throw new Error('Transport already initialized');
105
+ }
106
+
107
+ this.initialized = true;
108
+ this.setupStdioCommunication();
109
+ this.logger.log('Transport initialized');
110
+ }
111
+
112
+ /**
113
+ * Register a method that the parent can call
114
+ * @param method - Method name
115
+ * @param handler - Method handler function
116
+ */
117
+ public registerMethod<TParams = any, TResult = any>(
118
+ method: string,
119
+ handler: (params: TParams) => Promise<TResult> | TResult
120
+ ): void {
121
+ this.server.registerMethod(method, handler);
122
+ }
123
+
124
+ /**
125
+ * Send a request to the parent process
126
+ * @param method - Method name
127
+ * @param params - Method parameters
128
+ * @param options - Request options
129
+ * @returns Promise resolving to the response
130
+ */
131
+ public async request<TParams = any, TResult = any>(
132
+ method: string,
133
+ params?: TParams,
134
+ options?: { timeout?: number }
135
+ ): Promise<TResult> {
136
+ if (!this.initialized) {
137
+ throw new Error('Transport not initialized. Call initialize() first.');
138
+ }
139
+ return this.client.request<TParams, TResult>(method, params, options);
140
+ }
141
+
142
+ /**
143
+ * Send a notification to the parent process (no response expected)
144
+ * @param method - Method name
145
+ * @param params - Method parameters
146
+ */
147
+ public async notify<TParams = any>(method: string, params?: TParams): Promise<void> {
148
+ if (!this.initialized) {
149
+ throw new Error('Transport not initialized. Call initialize() first.');
150
+ }
151
+ return this.client.notify(method, params);
152
+ }
153
+
154
+ /**
155
+ * Get transport statistics
156
+ */
157
+ public getStats(): {
158
+ serverMethods: number;
159
+ pendingRequests: number;
160
+ initialized: boolean;
161
+ } {
162
+ return {
163
+ serverMethods: 0,
164
+ pendingRequests: this.client.getStats().pendingRequests,
165
+ initialized: this.initialized
166
+ };
167
+ }
168
+
169
+ /**
170
+ * Close the transport and cleanup resources
171
+ */
172
+ public async close(): Promise<void> {
173
+ await this.client.close();
174
+ this.initialized = false;
175
+ this.removeAllListeners();
176
+ }
177
+
178
+ /**
179
+ * Set up stdio communication handlers
180
+ */
181
+ private setupStdioCommunication(): void {
182
+ // Handle incoming data from parent
183
+ process.stdin.on('data', async(data: Buffer): Promise<void> => {
184
+ const messages = this.messageBuffer.addData(data.toString());
185
+
186
+ for (const messageData of messages) {
187
+ await this.handleIncomingMessage(messageData);
188
+ }
189
+ });
190
+
191
+ // Handle process termination gracefully
192
+ process.on('SIGTERM', (): void => {
193
+ this.close().finally((): void => process.exit(0));
194
+ });
195
+
196
+ process.on('SIGINT', (): void => {
197
+ this.close().finally((): void => process.exit(0));
198
+ });
199
+ }
200
+
201
+ /**
202
+ * Handle incoming message and route to appropriate handler
203
+ */
204
+ private async handleIncomingMessage(messageData: string): Promise<void> {
205
+ try {
206
+ const message = JSON.parse(messageData);
207
+
208
+ // Check if this is a response to our request (has 'result' or 'error' and 'id')
209
+ if (isResponse(message)) {
210
+ // This is a response to a request we made - route to client
211
+ this.logger.log(`Routing response to client: ${message.id}`);
212
+ await this.client.handleIncomingMessage(messageData);
213
+ } else {
214
+ // This is a request or notification for us - route to server
215
+ this.logger.log(`Routing request to server: ${message.method}`);
216
+ const response = await this.server.processMessage(messageData);
217
+ this.logger.log('Sending response to parent process', response);
218
+ // Only send response if there is one (requests get responses, notifications don't)
219
+ if (response) {
220
+ this.sendMessage(JSON.stringify(response));
221
+ }
222
+ }
223
+ } catch (error: unknown) {
224
+ process.stderr.write(`Error processing message: ${(error as Error).message}\n`);
225
+ this.emit('error', error);
226
+ }
227
+ }
228
+
229
+ /**
230
+ * Send a message to the parent process
231
+ */
232
+ private sendMessage(message: string): void {
233
+ this.logger.log(`Sending: ${message}`);
234
+ process.stdout.write(`${message}\n`);
235
+ }
236
+
237
+ /**
238
+ * Set up event handlers
239
+ */
240
+ private setupEventHandlers(): void {
241
+ this.server.on('error', (error: Error): void => {
242
+ this.logger.error('Server error', error);
243
+ this.emit('error', error);
244
+ });
245
+
246
+ this.client.on('error', (error: Error): void => {
247
+ this.logger.error('Client error', error);
248
+ this.emit('error', error);
249
+ });
250
+ }
251
+ }
@@ -0,0 +1,308 @@
1
+ import { Logger } from '../../../logger';
2
+ import type { ClientTransport } from '../../jsonRpc/JsonRpcClient';
3
+ import { JsonRpcClient } from '../../jsonRpc/JsonRpcClient';
4
+ import type { JsonRpcServer } from '../../jsonRpc/JsonRpcServer';
5
+ import type { LogNotification, StatusRequest, StatusResponse } from '../../jsonRpc/types';
6
+ import { STANDARD_METHODS } from '../../jsonRpc/types';
7
+ import type { ExecutionOptions } from '../../types';
8
+ import { BaseTransport } from '../base/BaseTransport';
9
+ import { ProcessManager } from '../process/ProcessManager';
10
+ import type { TransportConfig } from '../Transport';
11
+ import { TransportStatus } from '../Transport';
12
+ import { isResponse, MessageBuffer } from '../utils/MessageUtils';
13
+ import { pollUntilSuccess } from '../utils/PollingUtils';
14
+
15
+ /**
16
+ * Client transport implementation for stdio communication
17
+ */
18
+ export class StdioClientTransport implements ClientTransport {
19
+ private messageHandler?: (message: string) => void;
20
+ private name?: string;
21
+ private readonly logger = Logger.getInstance();
22
+
23
+ public constructor(private readonly processManager: ProcessManager) {}
24
+
25
+ public setName(name: string): void {
26
+ this.name = name;
27
+ this.logger.setMetadata({ name, transport: 'StdioClientTransport' });
28
+ }
29
+
30
+ public async send(message: string): Promise<void> {
31
+ this.logger.log('Sending message', message);
32
+ this.processManager.write(`${message}\n`);
33
+ }
34
+
35
+ public onMessage(handler: (message: string) => void): void {
36
+ this.messageHandler = handler;
37
+ // Note: Message handling is done in the main ParentStdioTransport class
38
+ // This is here for interface compliance
39
+ }
40
+
41
+ public async close(): Promise<void> {
42
+ this.messageHandler = undefined;
43
+ }
44
+ }
45
+
46
+ /**
47
+ * StdioTransport implementation for parent process communication with child
48
+ * This is the parent-side transport that manages a child process
49
+ */
50
+ export class ParentStdioTransport extends BaseTransport {
51
+ private readonly processManager = new ProcessManager();
52
+ private readonly server: JsonRpcServer;
53
+ private readonly client: JsonRpcClient;
54
+ private readonly clientTransport: StdioClientTransport;
55
+ private readonly executorScriptPath: string;
56
+ private readonly messageBuffer = new MessageBuffer();
57
+
58
+ public constructor(executorScriptPath: string, server: JsonRpcServer) {
59
+ super();
60
+ this.executorScriptPath = executorScriptPath;
61
+ this.server = server;
62
+ this.client = new JsonRpcClient({
63
+ // 1 hour
64
+ defaultTimeout: 60 * 60 * 1000
65
+ });
66
+ this.clientTransport = new StdioClientTransport(this.processManager);
67
+
68
+ this.setupServerMethods();
69
+ this.setupEventHandlers();
70
+ }
71
+
72
+ /**
73
+ * Initialize the transport connection
74
+ */
75
+ public async initialize(config?: TransportConfig, executionOptions?: ExecutionOptions): Promise<void> {
76
+ if (this.internalStatus !== TransportStatus.disconnected) {
77
+ throw new Error(`Cannot initialize transport in ${this.internalStatus} state`);
78
+ }
79
+
80
+ try {
81
+ this.setStatus(TransportStatus.connecting);
82
+
83
+ // Set up client transport
84
+ this.client.setTransport(this.clientTransport);
85
+
86
+ // Spawn the process
87
+ // Use spawnTimeout if provided, otherwise fall back to timeout or default
88
+ const spawnTimeout = config?.spawnTimeout ?? config?.timeout ?? 3000;
89
+ await this.processManager.spawn({
90
+ scriptPath: this.executorScriptPath,
91
+ executionOptions,
92
+ startupTimeout: spawnTimeout
93
+ });
94
+
95
+ // Set up process communication
96
+ this.setupProcessCommunication();
97
+
98
+ // Wait for process to be ready
99
+ // Use readyTimeout if provided, otherwise fall back to timeout or default
100
+ const readyTimeout = config?.readyTimeout ?? config?.timeout ?? 10000;
101
+ await this.waitForReady(readyTimeout);
102
+
103
+ this.setStatus(TransportStatus.connected);
104
+ } catch (error: unknown) {
105
+ this.setStatus(TransportStatus.error);
106
+ throw error;
107
+ }
108
+ }
109
+
110
+ /**
111
+ * Send a message through the transport
112
+ */
113
+ public async send<TRequest, TResponse>(message: TRequest): Promise<TResponse> {
114
+ if (!this.isReady()) {
115
+ throw new Error('Transport is not ready');
116
+ }
117
+
118
+ // Expect message to have method and params for direct RPC calls
119
+ const rpcMessage = message as any;
120
+ if (rpcMessage.method) {
121
+ return this.client.request(rpcMessage.method, rpcMessage.params);
122
+ }
123
+ throw new Error('Message must have a method property for RPC calls');
124
+ }
125
+
126
+ /**
127
+ * Make a direct RPC request to the child process
128
+ */
129
+ public async request<TParams = any, TResult = any>(
130
+ method: string,
131
+ params?: TParams,
132
+ options?: { timeout?: number; retries?: number }
133
+ ): Promise<TResult> {
134
+ if (!this.isReady()) {
135
+ throw new Error('Transport is not ready');
136
+ }
137
+ return this.client.request<TParams, TResult>(method, params, options);
138
+ }
139
+
140
+ /**
141
+ * Send a notification to the child process (no response expected)
142
+ */
143
+ public async notify<TParams = any>(method: string, params?: TParams): Promise<void> {
144
+ if (!this.isReady()) {
145
+ throw new Error('Transport is not ready');
146
+ }
147
+ return this.client.notify(method, params);
148
+ }
149
+
150
+ /**
151
+ * Close the transport connection
152
+ */
153
+ public async close(): Promise<void> {
154
+ if (this.internalStatus === TransportStatus.disconnected) {
155
+ return;
156
+ }
157
+
158
+ this.setStatus(TransportStatus.disconnected);
159
+
160
+ // Close JSON-RPC client
161
+ await this.client.close();
162
+
163
+ // Terminate child process
164
+ await this.processManager.terminate();
165
+ }
166
+
167
+ /**
168
+ * Check if the transport is ready for communication
169
+ */
170
+ public isReady(): boolean {
171
+ return this.internalStatus === TransportStatus.connected && this.processManager.isRunning();
172
+ }
173
+
174
+ /**
175
+ * Set up server methods for handling incoming requests from Deno process
176
+ */
177
+ private setupServerMethods(): void {
178
+ // Handle status requests
179
+ this.server.registerMethod<StatusRequest, StatusResponse>(STANDARD_METHODS.getStatus, async() => ({
180
+ status: 'ready',
181
+ uptime: process.uptime() * 1000,
182
+ memoryUsage: {
183
+ used: process.memoryUsage().heapUsed,
184
+ total: process.memoryUsage().heapTotal
185
+ }
186
+ }));
187
+
188
+ // Handle ping requests
189
+ this.server.registerMethod(STANDARD_METHODS.ping, async() => 'pong');
190
+
191
+ // Handle log notifications
192
+ this.server.registerMethod<LogNotification, void>(STANDARD_METHODS.log, async params => {
193
+ if (this.messageHandler) {
194
+ await this.messageHandler(params);
195
+ }
196
+ });
197
+ }
198
+
199
+ /**
200
+ * Set up event handlers
201
+ */
202
+ private setupEventHandlers(): void {
203
+ this.server.on('error', error => {
204
+ this.emit('error', error);
205
+ });
206
+
207
+ this.client.on('error', error => {
208
+ this.emit('error', error);
209
+ });
210
+
211
+ this.processManager.on('error', error => {
212
+ this.emit('error', error);
213
+ });
214
+
215
+ this.processManager.on('exit', (code, signal) => {
216
+ if (this.internalStatus === TransportStatus.connected) {
217
+ const error = new Error(`Process exited unexpectedly (code: ${code}, signal: ${signal})`);
218
+ this.setStatus(TransportStatus.error);
219
+ this.emit('error', error);
220
+ }
221
+ });
222
+ }
223
+
224
+ /**
225
+ * Set up process communication handlers
226
+ */
227
+ private setupProcessCommunication(): void {
228
+ // Handle stdout data (responses from Deno process)
229
+ this.processManager.on('stdout', (data: Buffer) => {
230
+ const messages = this.messageBuffer.addData(data.toString());
231
+
232
+ for (const messageData of messages) {
233
+ this.logger.log('Received message', messageData);
234
+ this.handleIncomingMessage(messageData).catch(error => {
235
+ this.emit('error', error);
236
+ });
237
+ }
238
+ });
239
+
240
+ // Handle stderr data (log messages and errors from Deno process)
241
+ this.processManager.on('stderr', (data: Buffer) => {
242
+ const stderrOutput = data.toString().trim();
243
+
244
+ // Only treat messages starting with "ERROR:" as actual errors
245
+ if (stderrOutput.startsWith('ERROR:')) {
246
+ this.emit('error', new Error(`Deno process error: ${stderrOutput}`));
247
+ } else {
248
+ // Log normal stderr output as debug information
249
+ this.logger.log('Child process log', stderrOutput);
250
+ }
251
+ });
252
+ }
253
+
254
+ /**
255
+ * Handle incoming message from Deno process with bidirectional routing
256
+ */
257
+ private async handleIncomingMessage(messageData: string): Promise<void> {
258
+ try {
259
+ const message = JSON.parse(messageData);
260
+
261
+ // Check if this is a response to our request (has 'result' or 'error' and 'id')
262
+ if (isResponse(message)) {
263
+ // This is a response to a request we made - route to client
264
+ this.logger.log('Routing response to parent client', { id: message.id });
265
+ await this.client.handleIncomingMessage(messageData);
266
+ } else {
267
+ // This is a request or notification for us - route to server
268
+ this.logger.log('Routing request to parent server', { method: message.method, id: message.id });
269
+ const response = await this.server.processMessage(messageData);
270
+ this.logger.log('Sending response to parent process', response);
271
+
272
+ // Only send response if there is one (requests get responses, notifications don't)
273
+ if (response) {
274
+ const responseData = `${JSON.stringify(response)}\n`;
275
+ this.processManager.write(responseData);
276
+ }
277
+ }
278
+ } catch (error: unknown) {
279
+ // Silently ignore invalid JSON messages (likely log output from child process)
280
+ if (error instanceof SyntaxError && error.message.includes('JSON')) {
281
+ this.logger.log('Ignoring invalid JSON message', { message: messageData });
282
+ return;
283
+ }
284
+
285
+ // Re-throw other types of errors
286
+ this.emit('error', new Error(`Failed to handle incoming message: ${(error as Error).message}`));
287
+ }
288
+ }
289
+
290
+ /**
291
+ * Wait for the process to be ready
292
+ */
293
+ private async waitForReady(timeout: number): Promise<void> {
294
+ // Use a reasonable ping timeout (1/4 of total timeout, min 500ms, max 2000ms)
295
+ const pingTimeout = Math.max(500, Math.min(2000, timeout / 4));
296
+
297
+ await pollUntilSuccess(
298
+ () => this.client.request(STANDARD_METHODS.ping, undefined, { timeout: pingTimeout }),
299
+ {
300
+ timeout,
301
+ interval: 100,
302
+ // Let process start before first ping
303
+ initialDelay: 100
304
+ },
305
+ 'Transport initialization timed out'
306
+ );
307
+ }
308
+ }
@@ -0,0 +1,139 @@
1
+ import type { JsonRpcResponse } from '../../jsonRpc/types';
2
+
3
+ /**
4
+ * Safely parse a JSON message, returning undefined if parsing fails
5
+ * @param message - String message to parse
6
+ * @returns Parsed object or undefined if invalid JSON
7
+ */
8
+ export function safeParse(message: string): any {
9
+ try {
10
+ return JSON.parse(message);
11
+ } catch {
12
+ return undefined;
13
+ }
14
+ }
15
+
16
+ /**
17
+ * Check if a message is a JSON-RPC response (vs request/notification)
18
+ * @param message - Parsed message object
19
+ * @returns True if message is a response
20
+ */
21
+ export function isResponse(message: any): boolean {
22
+ return message &&
23
+ typeof message === 'object' &&
24
+ ('result' in message || 'error' in message) &&
25
+ 'id' in message &&
26
+ !('method' in message);
27
+ }
28
+
29
+ /**
30
+ * Check if a message is a JSON-RPC request
31
+ * @param message - Parsed message object
32
+ * @returns True if message is a request
33
+ */
34
+ export function isRequest(message: any): boolean {
35
+ return message &&
36
+ typeof message === 'object' &&
37
+ 'method' in message &&
38
+ 'id' in message;
39
+ }
40
+
41
+ /**
42
+ * Check if a message is a JSON-RPC notification
43
+ * @param message - Parsed message object
44
+ * @returns True if message is a notification
45
+ */
46
+ export function isNotification(message: any): boolean {
47
+ return message &&
48
+ typeof message === 'object' &&
49
+ 'method' in message &&
50
+ !('id' in message);
51
+ }
52
+
53
+ /**
54
+ * Create a JSON-RPC error response
55
+ * @param id - Request ID
56
+ * @param code - Error code
57
+ * @param message - Error message
58
+ * @param data - Optional error data
59
+ * @returns JSON-RPC error response object
60
+ */
61
+ export function createErrorResponse(
62
+ id: string | number | null,
63
+ code: number,
64
+ message: string,
65
+ data?: any
66
+ ): JsonRpcResponse {
67
+ return {
68
+ jsonrpc: '2.0',
69
+ id,
70
+ error: {
71
+ code,
72
+ message,
73
+ ...data && { data }
74
+ }
75
+ };
76
+ }
77
+
78
+ /**
79
+ * Create a JSON-RPC success response
80
+ * @param id - Request ID
81
+ * @param result - Response result
82
+ * @returns JSON-RPC success response object
83
+ */
84
+ export function createSuccessResponse(id: string | number, result: any): JsonRpcResponse {
85
+ return {
86
+ jsonrpc: '2.0',
87
+ id,
88
+ result
89
+ };
90
+ }
91
+
92
+ /**
93
+ * Validate that a message is a valid JSON-RPC message
94
+ * @param message - Message to validate
95
+ * @returns True if valid JSON-RPC message
96
+ */
97
+ export function isValidJsonRpc(message: any): boolean {
98
+ return message &&
99
+ typeof message === 'object' &&
100
+ message.jsonrpc === '2.0' &&
101
+ (isRequest(message) || isNotification(message) || isResponse(message));
102
+ }
103
+
104
+ /**
105
+ * Buffer manager for handling streaming message data
106
+ */
107
+ export class MessageBuffer {
108
+ private buffer = '';
109
+
110
+ /**
111
+ * Add data to the buffer and extract complete messages
112
+ * @param data - Incoming data chunk
113
+ * @returns Array of complete message strings
114
+ */
115
+ public addData(data: string): string[] {
116
+ this.buffer += data;
117
+
118
+ // Process complete JSON messages (newline-delimited)
119
+ const lines = this.buffer.split('\n');
120
+ // Keep incomplete line in buffer
121
+ this.buffer = lines.pop() ?? '';
122
+
123
+ return lines.filter((line): string => line.trim());
124
+ }
125
+
126
+ /**
127
+ * Clear the buffer
128
+ */
129
+ public clear(): void {
130
+ this.buffer = '';
131
+ }
132
+
133
+ /**
134
+ * Get current buffer content (for debugging)
135
+ */
136
+ public getContent(): string {
137
+ return this.buffer;
138
+ }
139
+ }