harper 5.1.20 → 5.2.0-alpha.5

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 (395) hide show
  1. package/agent/operations.ts +13 -16
  2. package/components/Application.ts +188 -7
  3. package/components/ApplicationScope.ts +3 -0
  4. package/components/Scope.ts +12 -0
  5. package/components/anthropic/index.ts +9 -2
  6. package/components/bedrock/index.ts +25 -2
  7. package/components/componentLoader.ts +56 -7
  8. package/components/componentSecrets.ts +451 -0
  9. package/components/deploymentRecorder.ts +7 -1
  10. package/components/mcp/adapters/fastify.ts +3 -0
  11. package/components/mcp/adapters/harperHttp.ts +3 -0
  12. package/components/mcp/audit.ts +21 -6
  13. package/components/mcp/customResourceRegistry.ts +17 -38
  14. package/components/mcp/listChanged.ts +37 -20
  15. package/components/mcp/quota.ts +145 -0
  16. package/components/mcp/rateLimit.ts +152 -14
  17. package/components/mcp/resources.ts +2 -4
  18. package/components/mcp/toolRegistry.ts +73 -4
  19. package/components/mcp/tools/application.ts +77 -8
  20. package/components/mcp/tools/operations.ts +106 -36
  21. package/components/mcp/tools/schemas/operationDescriptions.ts +4 -4
  22. package/components/mcp/tools/schemas/operations.ts +5 -0
  23. package/components/mcp/transport.ts +55 -4
  24. package/components/ollama/index.ts +6 -2
  25. package/components/openai/index.ts +9 -2
  26. package/components/operations.js +204 -10
  27. package/components/operationsValidation.js +173 -0
  28. package/components/secretOperations.ts +498 -0
  29. package/config/configUtils.ts +25 -1
  30. package/config-app.schema.json +81 -0
  31. package/config-root.schema.json +8 -1
  32. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js +4 -3
  33. package/dataLayer/readAuditLog.ts +14 -0
  34. package/dataLayer/schemaDescribe.ts +1 -0
  35. package/dist/agent/operations.d.ts +7 -4
  36. package/dist/agent/operations.js +13 -15
  37. package/dist/agent/operations.js.map +1 -1
  38. package/dist/components/Application.d.ts +25 -2
  39. package/dist/components/Application.js +166 -7
  40. package/dist/components/Application.js.map +1 -1
  41. package/dist/components/ApplicationScope.d.ts +2 -0
  42. package/dist/components/ApplicationScope.js +3 -0
  43. package/dist/components/ApplicationScope.js.map +1 -1
  44. package/dist/components/Scope.d.ts +8 -0
  45. package/dist/components/Scope.js +11 -0
  46. package/dist/components/Scope.js.map +1 -1
  47. package/dist/components/anthropic/index.d.ts +4 -1
  48. package/dist/components/anthropic/index.js +4 -2
  49. package/dist/components/anthropic/index.js.map +1 -1
  50. package/dist/components/bedrock/index.d.ts +4 -1
  51. package/dist/components/bedrock/index.js +22 -2
  52. package/dist/components/bedrock/index.js.map +1 -1
  53. package/dist/components/componentLoader.d.ts +2 -0
  54. package/dist/components/componentLoader.js +52 -10
  55. package/dist/components/componentLoader.js.map +1 -1
  56. package/dist/components/componentSecrets.d.ts +63 -0
  57. package/dist/components/componentSecrets.js +405 -0
  58. package/dist/components/componentSecrets.js.map +1 -0
  59. package/dist/components/deploymentRecorder.d.ts +3 -0
  60. package/dist/components/deploymentRecorder.js +4 -3
  61. package/dist/components/deploymentRecorder.js.map +1 -1
  62. package/dist/components/mcp/adapters/fastify.d.ts +2 -0
  63. package/dist/components/mcp/adapters/fastify.js +1 -0
  64. package/dist/components/mcp/adapters/fastify.js.map +1 -1
  65. package/dist/components/mcp/adapters/harperHttp.d.ts +2 -0
  66. package/dist/components/mcp/adapters/harperHttp.js +1 -0
  67. package/dist/components/mcp/adapters/harperHttp.js.map +1 -1
  68. package/dist/components/mcp/audit.d.ts +2 -2
  69. package/dist/components/mcp/audit.js +20 -5
  70. package/dist/components/mcp/audit.js.map +1 -1
  71. package/dist/components/mcp/customResourceRegistry.d.ts +5 -12
  72. package/dist/components/mcp/customResourceRegistry.js +15 -30
  73. package/dist/components/mcp/customResourceRegistry.js.map +1 -1
  74. package/dist/components/mcp/listChanged.d.ts +7 -2
  75. package/dist/components/mcp/listChanged.js +28 -0
  76. package/dist/components/mcp/listChanged.js.map +1 -1
  77. package/dist/components/mcp/quota.d.ts +31 -0
  78. package/dist/components/mcp/quota.js +155 -0
  79. package/dist/components/mcp/quota.js.map +1 -0
  80. package/dist/components/mcp/rateLimit.d.ts +19 -3
  81. package/dist/components/mcp/rateLimit.js +129 -13
  82. package/dist/components/mcp/rateLimit.js.map +1 -1
  83. package/dist/components/mcp/resources.js.map +1 -1
  84. package/dist/components/mcp/toolRegistry.d.ts +39 -1
  85. package/dist/components/mcp/toolRegistry.js +60 -5
  86. package/dist/components/mcp/toolRegistry.js.map +1 -1
  87. package/dist/components/mcp/tools/application.d.ts +8 -1
  88. package/dist/components/mcp/tools/application.js +65 -5
  89. package/dist/components/mcp/tools/application.js.map +1 -1
  90. package/dist/components/mcp/tools/operations.d.ts +15 -3
  91. package/dist/components/mcp/tools/operations.js +99 -38
  92. package/dist/components/mcp/tools/operations.js.map +1 -1
  93. package/dist/components/mcp/tools/schemas/operationDescriptions.js +4 -4
  94. package/dist/components/mcp/tools/schemas/operationDescriptions.js.map +1 -1
  95. package/dist/components/mcp/tools/schemas/operations.js +4 -0
  96. package/dist/components/mcp/tools/schemas/operations.js.map +1 -1
  97. package/dist/components/mcp/transport.d.ts +6 -0
  98. package/dist/components/mcp/transport.js +47 -3
  99. package/dist/components/mcp/transport.js.map +1 -1
  100. package/dist/components/ollama/index.d.ts +4 -1
  101. package/dist/components/ollama/index.js +4 -2
  102. package/dist/components/ollama/index.js.map +1 -1
  103. package/dist/components/openai/index.d.ts +4 -1
  104. package/dist/components/openai/index.js +4 -2
  105. package/dist/components/openai/index.js.map +1 -1
  106. package/dist/components/operations.d.ts +39 -0
  107. package/dist/components/operations.js +194 -2
  108. package/dist/components/operations.js.map +1 -1
  109. package/dist/components/operationsValidation.d.ts +38 -0
  110. package/dist/components/operationsValidation.js +155 -0
  111. package/dist/components/operationsValidation.js.map +1 -1
  112. package/dist/components/secretOperations.d.ts +113 -0
  113. package/dist/components/secretOperations.js +475 -0
  114. package/dist/components/secretOperations.js.map +1 -0
  115. package/dist/config/configUtils.d.ts +4 -1
  116. package/dist/config/configUtils.js +18 -1
  117. package/dist/config/configUtils.js.map +1 -1
  118. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js +4 -3
  119. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js.map +1 -1
  120. package/dist/dataLayer/readAuditLog.js +11 -0
  121. package/dist/dataLayer/readAuditLog.js.map +1 -1
  122. package/dist/dataLayer/schemaDescribe.js +2 -0
  123. package/dist/dataLayer/schemaDescribe.js.map +1 -1
  124. package/dist/globals.d.ts +1 -1
  125. package/dist/globals.js +1 -0
  126. package/dist/globals.js.map +1 -1
  127. package/dist/index.d.ts +3 -0
  128. package/dist/index.js +1 -0
  129. package/dist/index.js.map +1 -1
  130. package/dist/json/systemSchema.json +38 -0
  131. package/dist/resources/DatabaseTransaction.d.ts +31 -3
  132. package/dist/resources/DatabaseTransaction.js +190 -29
  133. package/dist/resources/DatabaseTransaction.js.map +1 -1
  134. package/dist/resources/LMDBTransaction.d.ts +1 -1
  135. package/dist/resources/LMDBTransaction.js +43 -5
  136. package/dist/resources/LMDBTransaction.js.map +1 -1
  137. package/dist/resources/PrimaryRocksDatabase.d.ts +51 -0
  138. package/dist/resources/PrimaryRocksDatabase.js +194 -0
  139. package/dist/resources/PrimaryRocksDatabase.js.map +1 -0
  140. package/dist/resources/RecordEncoder.d.ts +1 -0
  141. package/dist/resources/RecordEncoder.js +81 -75
  142. package/dist/resources/RecordEncoder.js.map +1 -1
  143. package/dist/resources/RequestTarget.d.ts +19 -0
  144. package/dist/resources/RequestTarget.js.map +1 -1
  145. package/dist/resources/Resource.d.ts +0 -1
  146. package/dist/resources/Resource.js +103 -16
  147. package/dist/resources/Resource.js.map +1 -1
  148. package/dist/resources/ResourceInterface.d.ts +6 -2
  149. package/dist/resources/ResourceInterface.js.map +1 -1
  150. package/dist/resources/Resources.js.map +1 -1
  151. package/dist/resources/Table.d.ts +6 -4
  152. package/dist/resources/Table.js +247 -24
  153. package/dist/resources/Table.js.map +1 -1
  154. package/dist/resources/analytics/read.js +25 -28
  155. package/dist/resources/analytics/read.js.map +1 -1
  156. package/dist/resources/blob.js +165 -22
  157. package/dist/resources/blob.js.map +1 -1
  158. package/dist/resources/crdt.d.ts +2 -0
  159. package/dist/resources/crdt.js +45 -36
  160. package/dist/resources/crdt.js.map +1 -1
  161. package/dist/resources/databases.d.ts +1 -0
  162. package/dist/resources/databases.js +134 -7
  163. package/dist/resources/databases.js.map +1 -1
  164. package/dist/resources/graphql.js +8 -0
  165. package/dist/resources/graphql.js.map +1 -1
  166. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.d.ts +35 -5
  167. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js +239 -14
  168. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js.map +1 -1
  169. package/dist/resources/jsResource.js +6 -0
  170. package/dist/resources/jsResource.js.map +1 -1
  171. package/dist/resources/loadEnv.js +30 -3
  172. package/dist/resources/loadEnv.js.map +1 -1
  173. package/dist/resources/login.js +2 -2
  174. package/dist/resources/login.js.map +1 -1
  175. package/dist/resources/models/Models.js +14 -3
  176. package/dist/resources/models/Models.js.map +1 -1
  177. package/dist/resources/models/embedHook.js +10 -2
  178. package/dist/resources/models/embedHook.js.map +1 -1
  179. package/dist/resources/models/openaiStream.d.ts +56 -0
  180. package/dist/resources/models/openaiStream.js +94 -0
  181. package/dist/resources/models/openaiStream.js.map +1 -0
  182. package/dist/resources/replayLogs.js +4 -3
  183. package/dist/resources/replayLogs.js.map +1 -1
  184. package/dist/resources/search.d.ts +1 -1
  185. package/dist/resources/search.js +104 -11
  186. package/dist/resources/search.js.map +1 -1
  187. package/dist/resources/secretDecryptor.d.ts +54 -0
  188. package/dist/resources/secretDecryptor.js +131 -0
  189. package/dist/resources/secretDecryptor.js.map +1 -0
  190. package/dist/resources/tracked.js +15 -5
  191. package/dist/resources/tracked.js.map +1 -1
  192. package/dist/security/auth.js +71 -8
  193. package/dist/security/auth.js.map +1 -1
  194. package/dist/security/jsLoader.js +11 -0
  195. package/dist/security/jsLoader.js.map +1 -1
  196. package/dist/security/tokenAuthentication.d.ts +9 -1
  197. package/dist/security/tokenAuthentication.js +31 -1
  198. package/dist/security/tokenAuthentication.js.map +1 -1
  199. package/dist/server/DurableSubscriptionsSession.d.ts +1 -1
  200. package/dist/server/DurableSubscriptionsSession.js +8 -4
  201. package/dist/server/DurableSubscriptionsSession.js.map +1 -1
  202. package/dist/server/REST.js +28 -9
  203. package/dist/server/REST.js.map +1 -1
  204. package/dist/server/fastifyRoutes.js +11 -1
  205. package/dist/server/fastifyRoutes.js.map +1 -1
  206. package/dist/server/graphqlQuerying.js +4 -3
  207. package/dist/server/graphqlQuerying.js.map +1 -1
  208. package/dist/server/http.d.ts +40 -2
  209. package/dist/server/http.js +560 -77
  210. package/dist/server/http.js.map +1 -1
  211. package/dist/server/itc/serverHandlers.js +64 -0
  212. package/dist/server/itc/serverHandlers.js.map +1 -1
  213. package/dist/server/liveSubscriptionAuth.d.ts +12 -0
  214. package/dist/server/liveSubscriptionAuth.js +140 -0
  215. package/dist/server/liveSubscriptionAuth.js.map +1 -0
  216. package/dist/server/loadRootComponents.js +2 -1
  217. package/dist/server/loadRootComponents.js.map +1 -1
  218. package/dist/server/middlewareChain.d.ts +44 -1
  219. package/dist/server/middlewareChain.js +86 -10
  220. package/dist/server/middlewareChain.js.map +1 -1
  221. package/dist/server/mqtt.js +2 -1
  222. package/dist/server/mqtt.js.map +1 -1
  223. package/dist/server/operationsServer.js +1 -1
  224. package/dist/server/operationsServer.js.map +1 -1
  225. package/dist/server/serverHelpers/Headers.d.ts +9 -0
  226. package/dist/server/serverHelpers/Headers.js +22 -0
  227. package/dist/server/serverHelpers/Headers.js.map +1 -1
  228. package/dist/server/serverHelpers/JSONStream.js +3 -3
  229. package/dist/server/serverHelpers/JSONStream.js.map +1 -1
  230. package/dist/server/serverHelpers/Request.d.ts +52 -1
  231. package/dist/server/serverHelpers/Request.js +122 -1
  232. package/dist/server/serverHelpers/Request.js.map +1 -1
  233. package/dist/server/serverHelpers/contentTypes.js +3 -8
  234. package/dist/server/serverHelpers/contentTypes.js.map +1 -1
  235. package/dist/server/serverHelpers/progressEmitter.d.ts +19 -0
  236. package/dist/server/serverHelpers/progressEmitter.js +52 -4
  237. package/dist/server/serverHelpers/progressEmitter.js.map +1 -1
  238. package/dist/server/serverHelpers/registeredOperations.d.ts +40 -0
  239. package/dist/server/serverHelpers/registeredOperations.js +286 -0
  240. package/dist/server/serverHelpers/registeredOperations.js.map +1 -0
  241. package/dist/server/serverHelpers/serverHandlers.js +11 -5
  242. package/dist/server/serverHelpers/serverHandlers.js.map +1 -1
  243. package/dist/server/serverHelpers/serverUtilities.d.ts +1 -0
  244. package/dist/server/serverHelpers/serverUtilities.js +67 -5
  245. package/dist/server/serverHelpers/serverUtilities.js.map +1 -1
  246. package/dist/server/serverHelpers/uwsServer.d.ts +80 -0
  247. package/dist/server/serverHelpers/uwsServer.js +433 -0
  248. package/dist/server/serverHelpers/uwsServer.js.map +1 -0
  249. package/dist/server/static.d.ts +0 -15
  250. package/dist/server/static.js +161 -2
  251. package/dist/server/static.js.map +1 -1
  252. package/dist/server/status/index.d.ts +4 -1
  253. package/dist/server/status/index.js +64 -4
  254. package/dist/server/status/index.js.map +1 -1
  255. package/dist/server/threads/manageThreads.d.ts +10 -0
  256. package/dist/server/threads/manageThreads.js +107 -4
  257. package/dist/server/threads/manageThreads.js.map +1 -1
  258. package/dist/server/threads/socketRouter.js +5 -1
  259. package/dist/server/threads/socketRouter.js.map +1 -1
  260. package/dist/server/threads/threadServer.js +92 -14
  261. package/dist/server/threads/threadServer.js.map +1 -1
  262. package/dist/upgrade/directives/5-2-0.d.ts +7 -0
  263. package/dist/upgrade/directives/5-2-0.js +108 -0
  264. package/dist/upgrade/directives/5-2-0.js.map +1 -0
  265. package/dist/upgrade/directives/directivesController.js +2 -1
  266. package/dist/upgrade/directives/directivesController.js.map +1 -1
  267. package/dist/utility/common_utils.js +5 -0
  268. package/dist/utility/common_utils.js.map +1 -1
  269. package/dist/utility/envFile.d.ts +41 -0
  270. package/dist/utility/envFile.js +221 -0
  271. package/dist/utility/envFile.js.map +1 -0
  272. package/dist/utility/globalSchema.d.ts +9 -0
  273. package/dist/utility/hdbTerms.d.ts +25 -0
  274. package/dist/utility/hdbTerms.js +31 -0
  275. package/dist/utility/hdbTerms.js.map +1 -1
  276. package/dist/utility/logging/harper_logger.d.ts +21 -0
  277. package/dist/utility/logging/harper_logger.js +160 -8
  278. package/dist/utility/logging/harper_logger.js.map +1 -1
  279. package/dist/utility/logging/logRotator.js +29 -17
  280. package/dist/utility/logging/logRotator.js.map +1 -1
  281. package/dist/utility/logging/readLog.d.ts +1 -1
  282. package/dist/utility/logging/readLog.js +305 -2
  283. package/dist/utility/logging/readLog.js.map +1 -1
  284. package/dist/utility/operationPermissions.d.ts +18 -0
  285. package/dist/utility/operationPermissions.js +35 -1
  286. package/dist/utility/operationPermissions.js.map +1 -1
  287. package/dist/utility/operation_authorization.d.ts +17 -0
  288. package/dist/utility/operation_authorization.js +38 -0
  289. package/dist/utility/operation_authorization.js.map +1 -1
  290. package/dist/utility/secretEnvelope.d.ts +30 -0
  291. package/dist/utility/secretEnvelope.js +94 -0
  292. package/dist/utility/secretEnvelope.js.map +1 -0
  293. package/dist/utility/signalling.d.ts +7 -0
  294. package/dist/utility/signalling.js +16 -0
  295. package/dist/utility/signalling.js.map +1 -1
  296. package/dist/validation/configValidator.js +70 -24
  297. package/dist/validation/configValidator.js.map +1 -1
  298. package/index.ts +4 -0
  299. package/json/systemSchema.json +38 -0
  300. package/npm-shrinkwrap.json +15066 -9347
  301. package/package.json +13 -8
  302. package/resources/DESIGN.md +15 -12
  303. package/resources/DatabaseTransaction.ts +206 -37
  304. package/resources/LMDBTransaction.ts +43 -9
  305. package/resources/PrimaryRocksDatabase.ts +201 -0
  306. package/resources/RecordEncoder.ts +81 -69
  307. package/resources/RequestTarget.ts +21 -0
  308. package/resources/Resource.ts +109 -25
  309. package/resources/ResourceInterface.ts +6 -2
  310. package/resources/Resources.ts +1 -3
  311. package/resources/Table.ts +238 -29
  312. package/resources/analytics/read.ts +25 -30
  313. package/resources/blob.ts +159 -23
  314. package/resources/crdt.ts +37 -31
  315. package/resources/databases.ts +143 -6
  316. package/resources/graphql.ts +8 -0
  317. package/resources/indexes/HierarchicalNavigableSmallWorld.ts +251 -17
  318. package/resources/jsResource.ts +6 -0
  319. package/resources/loadEnv.ts +34 -3
  320. package/resources/login.ts +2 -2
  321. package/resources/models/Models.ts +19 -3
  322. package/resources/models/embedHook.ts +13 -2
  323. package/resources/models/openaiStream.ts +133 -0
  324. package/resources/replayLogs.ts +4 -3
  325. package/resources/search.ts +113 -11
  326. package/resources/secretDecryptor.ts +159 -0
  327. package/resources/tracked.ts +24 -17
  328. package/security/auth.ts +70 -10
  329. package/security/jsLoader.ts +12 -0
  330. package/security/tokenAuthentication.ts +42 -1
  331. package/server/DESIGN.md +10 -0
  332. package/server/DurableSubscriptionsSession.ts +8 -4
  333. package/server/REST.ts +26 -9
  334. package/server/fastifyRoutes.ts +10 -1
  335. package/server/graphqlQuerying.ts +4 -3
  336. package/server/http.ts +563 -77
  337. package/server/itc/serverHandlers.js +70 -0
  338. package/server/liveSubscriptionAuth.ts +152 -0
  339. package/server/loadRootComponents.js +2 -1
  340. package/server/middlewareChain.ts +107 -17
  341. package/server/mqtt.ts +2 -1
  342. package/server/operationsServer.ts +2 -2
  343. package/server/serverHelpers/Headers.ts +24 -0
  344. package/server/serverHelpers/JSONStream.ts +3 -3
  345. package/server/serverHelpers/Request.ts +127 -0
  346. package/server/serverHelpers/contentTypes.ts +3 -8
  347. package/server/serverHelpers/progressEmitter.ts +55 -5
  348. package/server/serverHelpers/registeredOperations.ts +259 -0
  349. package/server/serverHelpers/serverHandlers.js +11 -5
  350. package/server/serverHelpers/serverUtilities.ts +88 -5
  351. package/server/serverHelpers/uwsServer.ts +488 -0
  352. package/server/static.ts +180 -2
  353. package/server/status/index.ts +72 -4
  354. package/server/threads/manageThreads.js +102 -4
  355. package/server/threads/socketRouter.ts +5 -1
  356. package/server/threads/threadServer.js +93 -10
  357. package/studio/web/assets/{Chat-SdD1EZca.js → Chat-Cv_2paZE.js} +2 -2
  358. package/studio/web/assets/{Chat-SdD1EZca.js.map → Chat-Cv_2paZE.js.map} +1 -1
  359. package/studio/web/assets/{FloatingChat-GMq6tHK9.js → FloatingChat-CPyPIcVR.js} +4 -4
  360. package/studio/web/assets/{FloatingChat-GMq6tHK9.js.map → FloatingChat-CPyPIcVR.js.map} +1 -1
  361. package/studio/web/assets/{applications-B5hhv7uA.js → applications-C0jT2vdZ.js} +2 -2
  362. package/studio/web/assets/{applications-B5hhv7uA.js.map → applications-C0jT2vdZ.js.map} +1 -1
  363. package/studio/web/assets/{index-VFcpNWgq.js → index-D_GKOkhn.js} +6 -6
  364. package/studio/web/assets/index-D_GKOkhn.js.map +1 -0
  365. package/studio/web/assets/{index.lazy-DgcJojIA.js → index.lazy-CAmCIA65.js} +4 -4
  366. package/studio/web/assets/{index.lazy-DgcJojIA.js.map → index.lazy-CAmCIA65.js.map} +1 -1
  367. package/studio/web/assets/{profile-BqN-8vzm.js → profile-CaF-4aZe.js} +2 -2
  368. package/studio/web/assets/{profile-BqN-8vzm.js.map → profile-CaF-4aZe.js.map} +1 -1
  369. package/studio/web/assets/{setComponentFile-CHFvFq9u.js → setComponentFile-DLW1DHCt.js} +2 -2
  370. package/studio/web/assets/{setComponentFile-CHFvFq9u.js.map → setComponentFile-DLW1DHCt.js.map} +1 -1
  371. package/studio/web/assets/{setup-CQ3vWJSr.js → setup-TGCErIhq.js} +2 -2
  372. package/studio/web/assets/{setup-CQ3vWJSr.js.map → setup-TGCErIhq.js.map} +1 -1
  373. package/studio/web/assets/{status-BsW5fjuh.js → status-DG0Maoao.js} +2 -2
  374. package/studio/web/assets/{status-BsW5fjuh.js.map → status-DG0Maoao.js.map} +1 -1
  375. package/studio/web/assets/{swagger-ui-react-DITdeB9-.js → swagger-ui-react-8T4SgQ1m.js} +2 -2
  376. package/studio/web/assets/{swagger-ui-react-DITdeB9-.js.map → swagger-ui-react-8T4SgQ1m.js.map} +1 -1
  377. package/studio/web/assets/{tsMode-Dyph-OUs.js → tsMode-DJ6Sl24Q.js} +2 -2
  378. package/studio/web/assets/{tsMode-Dyph-OUs.js.map → tsMode-DJ6Sl24Q.js.map} +1 -1
  379. package/studio/web/assets/{useEntityRestURL-D0QTUqex.js → useEntityRestURL-JO2mfWTQ.js} +2 -2
  380. package/studio/web/assets/{useEntityRestURL-D0QTUqex.js.map → useEntityRestURL-JO2mfWTQ.js.map} +1 -1
  381. package/studio/web/index.html +1 -1
  382. package/upgrade/directives/5-2-0.ts +82 -0
  383. package/upgrade/directives/directivesController.ts +2 -1
  384. package/utility/common_utils.ts +5 -0
  385. package/utility/envFile.ts +218 -0
  386. package/utility/hdbTerms.ts +31 -0
  387. package/utility/logging/harper_logger.ts +156 -8
  388. package/utility/logging/logRotator.ts +24 -14
  389. package/utility/logging/readLog.ts +323 -2
  390. package/utility/operationPermissions.ts +35 -1
  391. package/utility/operation_authorization.ts +74 -1
  392. package/utility/secretEnvelope.ts +113 -0
  393. package/utility/signalling.ts +15 -0
  394. package/validation/configValidator.ts +78 -25
  395. package/studio/web/assets/index-VFcpNWgq.js.map +0 -1
@@ -0,0 +1,488 @@
1
+ /**
2
+ * uWebSockets.js HTTP server adapter (#914, github.com/HarperFast/harper, default-off backend).
3
+ *
4
+ * Creates a non-SSL uWS App — on a Unix domain socket (`socketPath`) or a TCP port (`port`) —
5
+ * and bridges each request through Harper's existing pipeline: it builds a {@link UwsRequest}
6
+ * (same duck-typed shape as BunRequest), invokes the supplied `handler` (i.e. `httpChain[port]`),
7
+ * and serializes the returned Harper response descriptor back onto the uWS HttpResponse.
8
+ * Streaming/SSE bodies are written incrementally with backpressure; a WebSocket `wsHandler`
9
+ * (when supplied) accepts upgrades via native app.ws() bridged through {@link UwsWebSocket}.
10
+ *
11
+ * Two topologies, both gated default-off in http.ts:
12
+ * - HARPER_UWS_UDS: the plaintext-UDS-behind-symphony mirror — TLS/mTLS/HTTP-2 terminated by
13
+ * symphony upstream, real client IP via X-Forwarded-For, so this server never touches certs.
14
+ * - HARPER_UWS_HTTP: a direct plaintext TCP HTTP port (real peer IP from the socket).
15
+ *
16
+ * `uWebSockets.js` is an optionalDependency (ABI/platform-specific, built by CI).
17
+ */
18
+ import { STATUS_CODES } from 'node:http';
19
+ import { EventEmitter } from 'node:events';
20
+ import { UwsRequest, UwsRequestBody } from './Request.ts';
21
+ import { Headers } from './Headers.ts';
22
+ import { when } from '../../utility/when.ts';
23
+ import { ClientError } from '../../utility/errors/hdbError.ts';
24
+
25
+ // uWS has no npm package; it's installed from a GitHub tag and is platform/ABI-specific.
26
+ // Imported lazily so harper builds/loads on platforms without a uWS binary.
27
+ type UwsApp = any;
28
+ type UwsResponse = any;
29
+ type UwsRequestRaw = any;
30
+
31
+ export interface UwsServerOptions {
32
+ /** Bind a Unix domain socket at this path (the symphony-fronted topology). */
33
+ socketPath?: string;
34
+ /** Bind a TCP port instead of a UDS (plaintext HTTP, e.g. the main http port). */
35
+ port?: number;
36
+ /** Optional host/interface for the TCP bind (defaults to all interfaces). */
37
+ host?: string;
38
+ secure?: boolean;
39
+ /** httpChain[port]-style handler: (request) => Harper response descriptor (or undefined). */
40
+ handler: (request: UwsRequest) => Promise<HarperResponse | undefined> | HarperResponse | undefined;
41
+ /**
42
+ * Coarse socket-level ceiling on request-body bytes (default 100 MiB, matching ws maxPayload). The
43
+ * real per-request limit is enforced downstream by streamToBuffer (HTTP_MAXREQUESTBODYSIZE); this
44
+ * only guards against an unconsumed body growing unbounded, since uWS gives no inbound backpressure.
45
+ */
46
+ maxBodyBytes?: number;
47
+ /** Max WebSocket frame payload; falls back to maxBodyBytes when unset. */
48
+ wsMaxPayload?: number;
49
+ /**
50
+ * Optional WebSocket handler. When provided, uWS accepts upgrades on this app/port and calls this
51
+ * with a ws-library-shaped {@link UwsWebSocket} adapter plus the captured upgrade request, so
52
+ * Harper's existing websocket chain (auth + listeners) runs unchanged.
53
+ */
54
+ wsHandler?: (ws: UwsWebSocket, upgrade: UwsUpgrade) => void;
55
+ }
56
+
57
+ export interface UwsUpgrade {
58
+ url: string;
59
+ headers: Record<string, string | string[]>;
60
+ ip: string;
61
+ adapter?: UwsWebSocket;
62
+ }
63
+
64
+ export interface HarperResponse {
65
+ status?: number;
66
+ headers?: Headers | Record<string, string | string[]>;
67
+ body?: string | Buffer | Uint8Array | Iterable<any> | AsyncIterable<any> | { pipe?: any } | null;
68
+ handlesHeaders?: boolean;
69
+ wasCacheMiss?: boolean;
70
+ }
71
+
72
+ // uWS writeStatus() needs a full "<code> <reason>" line; an empty reason phrase is rejected by
73
+ // some reverse-proxy parsers, so fall back to "Unknown" for codes Node doesn't know.
74
+ const statusText = (s: number) => `${s} ${STATUS_CODES[s] ?? 'Unknown'}`;
75
+
76
+ export async function createUwsServer(options: UwsServerOptions): Promise<{ app: UwsApp; close: () => void }> {
77
+ const { default: uWS } = await import('uWebSockets.js' as any);
78
+ const {
79
+ socketPath,
80
+ port,
81
+ host,
82
+ secure = false,
83
+ handler,
84
+ wsHandler,
85
+ wsMaxPayload,
86
+ maxBodyBytes = 100 * 1024 * 1024,
87
+ } = options;
88
+ const app: UwsApp = uWS.App();
89
+
90
+ // Accept WebSocket upgrades on this app/port when a ws handler is supplied. Registered before the
91
+ // HTTP routes so uWS routes upgrade requests here; normal requests still fall through to app.get/any.
92
+ if (wsHandler) registerWsBehavior(app, wsHandler, wsMaxPayload ?? maxBodyBytes);
93
+
94
+ const onRequest = (res: UwsResponse, req: UwsRequestRaw, hasBody: boolean) => {
95
+ // uWS HttpRequest is only valid synchronously inside this callback — copy everything now.
96
+ const method = req.getMethod().toUpperCase();
97
+ const query = req.getQuery();
98
+ const url = req.getUrl() + (query ? '?' + query : '');
99
+ const headers: Record<string, string | string[]> = {};
100
+ req.forEach((k: string, v: string) => {
101
+ // uWS calls this once per header line, so preserve repeats (e.g. multiple Cookie/Forwarded).
102
+ const existing = headers[k];
103
+ if (existing === undefined) headers[k] = v;
104
+ else if (Array.isArray(existing)) existing.push(v);
105
+ else headers[k] = [existing, v];
106
+ });
107
+
108
+ // Capture the peer address synchronously (res is only valid in this callback). Only populated for
109
+ // the direct-TCP path, where it's authoritative; behind symphony on a UDS it's left unset so the
110
+ // real client IP comes from X-Forwarded-For (UwsRequest.ip falls back to XFF only when no socket
111
+ // address is set). request.ip feeds local-auth (security/auth.ts AUTHORIZE_LOCAL), rate limiting,
112
+ // and logging.
113
+ const ip = port != null ? normalizeAddress(Buffer.from(res.getRemoteAddressAsText()).toString()) : undefined;
114
+
115
+ const ac = new AbortController();
116
+ res.onAborted(() => ac.abort());
117
+ // Once a response has been committed (handler result, error, or a 413), writing again to the
118
+ // same uWS response is invalid and aborts the process — so every write site guards on this in
119
+ // addition to ac.signal.aborted (which only covers a client-side teardown, not our own writes).
120
+ let responseCompleted = false;
121
+
122
+ const dispatch = (body?: UwsRequestBody) => {
123
+ const request = new UwsRequest({ method, url, headers, secure, body, signal: ac.signal, ip });
124
+ // when() keeps a synchronously-returning handler synchronous (no extra microtask/promise).
125
+ when(
126
+ handler(request),
127
+ (response) => {
128
+ if (ac.signal.aborted || responseCompleted) return;
129
+ responseCompleted = true;
130
+ writeResponse(res, response, ac.signal, method);
131
+ },
132
+ (error) => {
133
+ if (ac.signal.aborted || responseCompleted) return;
134
+ responseCompleted = true;
135
+ const status = (error && error.statusCode) || 500;
136
+ res.cork(() => {
137
+ res.writeStatus(statusText(status));
138
+ res.writeHeader('content-type', 'text/plain');
139
+ res.end(String((error && error.message) || error));
140
+ });
141
+ }
142
+ );
143
+ };
144
+
145
+ if (hasBody) {
146
+ // Stream the body: dispatch immediately with a push-based Readable and feed each chunk in as it
147
+ // arrives, so consumers (streamToBuffer, streaming deserializers) don't wait on — or hold — the
148
+ // whole body. streamToBuffer owns concatenation and the configurable per-request size limit;
149
+ // maxBodyBytes is only the coarse ceiling below, since uWS offers no way to pause the socket.
150
+ const body = new UwsRequestBody();
151
+ let total = 0;
152
+ let ended = false;
153
+ // Only surface a teardown as a stream 'error' when a consumer is listening; destroying with an
154
+ // error and no 'error' listener would throw. An unconsumed body just gets its chunks released.
155
+ const tearDown = (error?: Error) => {
156
+ if (ended || body.destroyed) return;
157
+ ended = true;
158
+ body.destroy(error && body.listenerCount('error') > 0 ? error : undefined);
159
+ };
160
+ ac.signal.addEventListener('abort', () => tearDown(new Error('request aborted')), { once: true });
161
+ res.onData((chunk: ArrayBuffer, isLast: boolean) => {
162
+ if (ended || body.destroyed) return;
163
+ total += chunk.byteLength;
164
+ if (total > maxBodyBytes) {
165
+ // Only send 413 if nothing has been written yet: the handler may have already responded
166
+ // (or streamed) without consuming the body, and writing to that completed response aborts.
167
+ if (!ac.signal.aborted && !responseCompleted) {
168
+ responseCompleted = true;
169
+ res.cork(() => res.writeStatus('413 Payload Too Large').end());
170
+ }
171
+ tearDown(new ClientError(`Request body exceeds ${maxBodyBytes} bytes`, 413));
172
+ ac.abort();
173
+ return;
174
+ }
175
+ // uWS neuters/reuses the ArrayBuffer once this callback returns, and the body is read
176
+ // asynchronously by the consumer — so copy the bytes out now. `Buffer.from(arrayBuffer)`
177
+ // would alias uWS's memory; wrapping in a Uint8Array first forces an owned copy.
178
+ body.push(Buffer.from(new Uint8Array(chunk)));
179
+ if (isLast) {
180
+ ended = true;
181
+ body.push(null);
182
+ }
183
+ });
184
+ dispatch(body);
185
+ } else {
186
+ dispatch(undefined);
187
+ }
188
+ };
189
+
190
+ // Route the known-bodyless methods so they dispatch immediately, and treat everything else —
191
+ // including non-standard body-bearing methods like QUERY (REST vector search) — as having a
192
+ // body. uWS still fires onData(len=0, isLast=true) for a bodyless request that lands on the
193
+ // any() fallback, so this can't stall the connection.
194
+ const bodyless = (res: UwsResponse, req: UwsRequestRaw) => onRequest(res, req, false);
195
+ const withBody = (res: UwsResponse, req: UwsRequestRaw) => onRequest(res, req, true);
196
+ app.get('/*', bodyless);
197
+ app.head('/*', bodyless);
198
+ app.options('/*', bodyless);
199
+ app.connect('/*', bodyless);
200
+ app.trace('/*', bodyless);
201
+ app.any('/*', withBody);
202
+
203
+ await new Promise<void>((resolve, reject) => {
204
+ const onListen = (listenSocket: unknown) =>
205
+ listenSocket ? resolve() : reject(new Error(`uWS failed to bind ${host ?? ''}:${port ?? socketPath}`));
206
+ // uWS shares the port across workers (SO_REUSEPORT) by default, matching the Node reusePort path.
207
+ if (port != null) {
208
+ if (host) app.listen(host, port, onListen);
209
+ else app.listen(port, onListen);
210
+ } else {
211
+ app.listen_unix(onListen, socketPath!);
212
+ }
213
+ });
214
+
215
+ return {
216
+ app,
217
+ close: () => app.close(),
218
+ };
219
+ }
220
+
221
+ // Write every response header except Content-Length (uWS derives that from end(body); for streaming
222
+ // there is no fixed length and it must be omitted so uWS uses chunked transfer encoding).
223
+ function writeHeaders(res: UwsResponse, headers: Headers): void {
224
+ // WHATWG Headers comma-join Set-Cookie on iteration, which merges multiple cookies into one and
225
+ // corrupts values containing commas (e.g. `expires=` dates). Emit them individually via
226
+ // getSetCookie() and skip the joined entry from the main loop. A Harper Headers has no
227
+ // getSetCookie(); it stores multiple cookies as an array, handled by the Array.isArray branch.
228
+ const setCookies =
229
+ typeof (headers as any).getSetCookie === 'function' ? ((headers as any).getSetCookie() as string[]) : null;
230
+ for (const [name, value] of headers) {
231
+ const lower = (name as string).toLowerCase();
232
+ if (lower === 'content-length') continue;
233
+ if (setCookies && lower === 'set-cookie') continue;
234
+ if (Array.isArray(value)) for (const v of value) res.writeHeader(name, String(v));
235
+ else if (value != null) res.writeHeader(name, String(value));
236
+ }
237
+ if (setCookies) for (const cookie of setCookies) res.writeHeader('set-cookie', cookie);
238
+ }
239
+
240
+ function writeResponse(
241
+ res: UwsResponse,
242
+ response: HarperResponse | undefined,
243
+ signal?: AbortSignal,
244
+ method?: string
245
+ ): void {
246
+ if (!response) {
247
+ res.cork(() => res.writeStatus('404 Not Found').end('Not found\n'));
248
+ return;
249
+ }
250
+ const status = response.status || 200;
251
+ // A HEAD response must carry no body. The REST layer already nulls it, but uWS (unlike Node's
252
+ // ServerResponse) has no HEAD guard, so enforce it here for any handler that returns one.
253
+ const isHead = method === 'HEAD';
254
+ const body = isHead ? null : response.body;
255
+
256
+ // Normalize headers to something iterable with .get. Keep an existing Headers-like object
257
+ // (Harper or WHATWG) as-is — converting a WHATWG Headers via `new Headers()` would comma-join
258
+ // Set-Cookie on iteration before writeHeaders can split it back out via getSetCookie(). Only
259
+ // plain objects get wrapped.
260
+ const rawHeaders = response.headers as any;
261
+ const headers =
262
+ rawHeaders && typeof rawHeaders.get === 'function' && rawHeaders[Symbol.iterator]
263
+ ? (rawHeaders as Headers)
264
+ : new Headers(rawHeaders);
265
+
266
+ // Streaming body (Node stream / normalized async-iterable): write incrementally with backpressure.
267
+ if (body != null && typeof (body as any).pipe === 'function') {
268
+ streamResponse(res, status, headers, body as any, signal);
269
+ return;
270
+ }
271
+
272
+ res.cork(() => {
273
+ res.writeStatus(statusText(status));
274
+ writeHeaders(res, headers);
275
+ if (body == null) res.end();
276
+ else res.end(body as any); // string | Buffer | Uint8Array
277
+ });
278
+ }
279
+
280
+ /**
281
+ * Stream a Node Readable to the uWS response with backpressure. uWS only flushes the status/headers
282
+ * on the first body write, so for text/event-stream (SSE) — where the client must see the stream
283
+ * open before any event — we emit a spec-valid comment line to force the flush. Client disconnect
284
+ * (via `signal`) or a source error destroys the source and stops writing (writing to an aborted uWS
285
+ * response is invalid).
286
+ */
287
+ function streamResponse(
288
+ res: UwsResponse,
289
+ status: number,
290
+ headers: Headers,
291
+ source: { on: Function; once: Function; pause: Function; resume: Function; destroy?: Function },
292
+ signal?: AbortSignal
293
+ ): void {
294
+ let finished = false;
295
+ const finish = (endResponse: boolean) => {
296
+ if (finished) return;
297
+ finished = true;
298
+ signal?.removeEventListener('abort', onAbort);
299
+ if (endResponse) res.cork(() => res.end());
300
+ };
301
+ function onAbort() {
302
+ if (finished) return;
303
+ finished = true;
304
+ source.destroy?.();
305
+ }
306
+ if (signal?.aborted) return onAbort();
307
+ signal?.addEventListener('abort', onAbort, { once: true });
308
+
309
+ const isSse = String(headers.get('content-type') ?? '').includes('text/event-stream');
310
+ res.cork(() => {
311
+ res.writeStatus(statusText(status));
312
+ writeHeaders(res, headers);
313
+ if (isSse) res.write(':\n\n'); // SSE comment: flushes headers immediately, ignored by clients
314
+ });
315
+
316
+ source.on('data', (chunk: Buffer) => {
317
+ if (finished) return;
318
+ let ok = true;
319
+ res.cork(() => {
320
+ ok = res.write(chunk);
321
+ });
322
+ if (!ok) {
323
+ // Backpressure: pause the source until uWS drains, then resume.
324
+ source.pause();
325
+ res.onWritable(() => {
326
+ if (!finished) source.resume();
327
+ return true;
328
+ });
329
+ }
330
+ });
331
+ source.once('end', () => finish(true));
332
+ source.once('error', () => finish(true)); // headers already sent; just terminate the response
333
+ }
334
+
335
+ // Normalize uWS's remote-address text (raw IPv6 form, IPv4-mapped for v4 peers) to a readable IP.
336
+ function normalizeAddress(text: string): string {
337
+ const mapped = /^0000:0000:0000:0000:0000:ffff:([0-9a-f]{4}):([0-9a-f]{4})$/.exec(text);
338
+ if (mapped) {
339
+ const hi = parseInt(mapped[1], 16);
340
+ const lo = parseInt(mapped[2], 16);
341
+ return `${hi >> 8}.${hi & 0xff}.${lo >> 8}.${lo & 0xff}`;
342
+ }
343
+ return text;
344
+ }
345
+
346
+ function registerWsBehavior(
347
+ app: UwsApp,
348
+ wsHandler: (ws: UwsWebSocket, upgrade: UwsUpgrade) => void,
349
+ maxPayload: number
350
+ ): void {
351
+ app.ws('/*', {
352
+ maxPayload,
353
+ // Capture the upgrade request synchronously (uWS's HttpRequest is only valid here) and upgrade.
354
+ // Auth runs after open() in the ws chain, matching the Node path (which upgrades then authorizes).
355
+ upgrade: (res: UwsResponse, req: UwsRequestRaw, context: unknown) => {
356
+ const query = req.getQuery();
357
+ const url = req.getUrl() + (query ? '?' + query : '');
358
+ const headers: Record<string, string | string[]> = {};
359
+ req.forEach((k: string, v: string) => {
360
+ const existing = headers[k];
361
+ if (existing === undefined) headers[k] = v;
362
+ else if (Array.isArray(existing)) existing.push(v);
363
+ else headers[k] = [existing, v];
364
+ });
365
+ const ip = normalizeAddress(Buffer.from(res.getRemoteAddressAsText()).toString());
366
+ const upgradeData: UwsUpgrade = { url, headers, ip };
367
+ res.upgrade(
368
+ upgradeData,
369
+ req.getHeader('sec-websocket-key'),
370
+ req.getHeader('sec-websocket-protocol'),
371
+ req.getHeader('sec-websocket-extensions'),
372
+ context
373
+ );
374
+ },
375
+ open: (ws: any) => {
376
+ const data = ws.getUserData() as UwsUpgrade;
377
+ const adapter = new UwsWebSocket(ws);
378
+ adapter._socket.remoteAddress = data.ip;
379
+ data.adapter = adapter;
380
+ wsHandler(adapter, data);
381
+ },
382
+ message: (ws: any, message: ArrayBuffer, isBinary: boolean) =>
383
+ ws.getUserData().adapter?._message(message, isBinary),
384
+ drain: (ws: any) => ws.getUserData().adapter?._drain(),
385
+ close: (ws: any, code: number, message: ArrayBuffer) => ws.getUserData().adapter?._closed(code, message),
386
+ });
387
+ }
388
+
389
+ /**
390
+ * A backpressure-aware stand-in for the `ws` library's underlying socket. Harper's WS consumers read
391
+ * `remoteAddress` and gate on `writableNeedDrain` / `'drain'`; uWS surfaces those via getBufferedAmount()
392
+ * and the behavior's drain callback.
393
+ */
394
+ class UwsSocketShim extends EventEmitter {
395
+ remoteAddress = '';
396
+ #raw: any;
397
+ constructor(raw: any) {
398
+ super();
399
+ this.#raw = raw;
400
+ }
401
+ get writableNeedDrain(): boolean {
402
+ try {
403
+ return this.#raw.getBufferedAmount() > 0;
404
+ } catch {
405
+ return false;
406
+ }
407
+ }
408
+ }
409
+
410
+ /**
411
+ * Adapts a uWS WebSocket to the subset of the `ws` library's WebSocket interface that Harper's WS
412
+ * consumers use (MQTT-over-WS in server/mqtt.ts, subscriptions in server/REST.ts): send/close/
413
+ * terminate/ping, the 'message'/'close'/'error' events, `_socket`, and `readyState`. This lets the
414
+ * existing websocket chain run unchanged on the uWS transport.
415
+ */
416
+ export class UwsWebSocket extends EventEmitter {
417
+ #raw: any;
418
+ #open = true;
419
+ #closeEmitted = false;
420
+ public _socket: UwsSocketShim;
421
+ public binaryType = 'nodebuffer';
422
+
423
+ constructor(raw: any) {
424
+ super();
425
+ this.#raw = raw;
426
+ this._socket = new UwsSocketShim(raw);
427
+ }
428
+ get readyState(): number {
429
+ return this.#open ? 1 /* OPEN */ : 3; /* CLOSED */
430
+ }
431
+ send(data: any, optionsOrCb?: any, maybeCb?: any): void {
432
+ // ws-library signature is send(data[, options][, callback]); tolerate either arrangement.
433
+ const cb: ((error?: Error) => void) | undefined =
434
+ typeof optionsOrCb === 'function' ? optionsOrCb : typeof maybeCb === 'function' ? maybeCb : undefined;
435
+ if (!this.#open) {
436
+ cb?.(new Error('WebSocket is not open'));
437
+ return;
438
+ }
439
+ try {
440
+ const isBinary = typeof data !== 'string';
441
+ const payload = isBinary && !Buffer.isBuffer(data) && !(data instanceof Uint8Array) ? Buffer.from(data) : data;
442
+ this.#raw.send(payload, isBinary);
443
+ cb?.();
444
+ } catch (error) {
445
+ cb?.(error as Error);
446
+ }
447
+ }
448
+ close(code?: number, reason?: string): void {
449
+ if (!this.#open) return;
450
+ this.#open = false;
451
+ try {
452
+ if (code != null) this.#raw.end(code, reason);
453
+ else this.#raw.end();
454
+ } catch {
455
+ /* already closed by the peer */
456
+ }
457
+ }
458
+ terminate(): void {
459
+ if (!this.#open) return;
460
+ this.#open = false;
461
+ try {
462
+ this.#raw.close();
463
+ } catch {
464
+ /* already closed */
465
+ }
466
+ }
467
+ ping(): void {
468
+ try {
469
+ this.#raw.ping();
470
+ } catch {
471
+ /* not open */
472
+ }
473
+ }
474
+ // uWS behavior hooks:
475
+ _message(message: ArrayBuffer, isBinary: boolean): void {
476
+ // Copy out of uWS's buffer — it's neutered once this callback returns and consumers read async.
477
+ this.emit('message', Buffer.from(new Uint8Array(message)), isBinary);
478
+ }
479
+ _drain(): void {
480
+ this._socket.emit('drain');
481
+ }
482
+ _closed(code: number, message: ArrayBuffer): void {
483
+ this.#open = false;
484
+ if (this.#closeEmitted) return;
485
+ this.#closeEmitted = true;
486
+ this.emit('close', code, message ? Buffer.from(new Uint8Array(message)) : Buffer.alloc(0));
487
+ }
488
+ }