@harperfast/harper 5.2.13 → 5.3.0-beta.1

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 (655) hide show
  1. package/agent/mcpTools.ts +1 -1
  2. package/agent/session.ts +25 -14
  3. package/bin/cliOperations.ts +58 -9
  4. package/bin/copyDb.ts +282 -59
  5. package/bin/deploySetup.ts +16 -5
  6. package/bin/harper.ts +1 -1
  7. package/bin/help.ts +4 -1
  8. package/bin/lite.ts +4 -1
  9. package/bin/restart.ts +120 -4
  10. package/bin/run.ts +6 -11
  11. package/bin/upgrade.js +7 -3
  12. package/bin/workloadIdentity.ts +119 -0
  13. package/components/Application.ts +3436 -242
  14. package/components/ApplicationScope.ts +8 -0
  15. package/components/EntryHandler.ts +59 -39
  16. package/components/OptionsWatcher.ts +440 -98
  17. package/components/RuntimeModuleTracker.ts +38 -7
  18. package/components/Scope.ts +56 -15
  19. package/components/awaitRestart.ts +84 -0
  20. package/components/componentLoader.ts +381 -32
  21. package/components/componentPreparationLock.ts +16 -5
  22. package/components/deploymentOperations.ts +4 -1
  23. package/components/deploymentRecorder.ts +9 -2
  24. package/components/mcp/adapters/harperHttp.ts +4 -0
  25. package/components/mcp/listChanged.ts +4 -0
  26. package/components/mcp/toolRegistry.ts +2 -0
  27. package/components/mcp/tools/operations.ts +9 -0
  28. package/components/mcp/tools/schemas/operationDescriptions.ts +2 -2
  29. package/components/operations.js +537 -113
  30. package/components/operationsValidation.js +98 -3
  31. package/components/packageComponent.ts +25 -1
  32. package/components/requestRestart.ts +11 -0
  33. package/components/status/ComponentStatusRegistry.ts +59 -0
  34. package/config/RootConfigWatcher.ts +240 -40
  35. package/config/configReadRetry.ts +62 -0
  36. package/config/configUtils.ts +357 -48
  37. package/config/harperConfigEnvVars.ts +170 -27
  38. package/config/parseConfigFile.ts +34 -0
  39. package/config/readConfigFileSync.ts +44 -0
  40. package/config/watcherArming.ts +59 -0
  41. package/config-root.schema.json +33 -0
  42. package/dataLayer/blobBackup.ts +160 -50
  43. package/dataLayer/delete.ts +6 -1
  44. package/dataLayer/harperBridge/ResourceBridge.ts +80 -10
  45. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js +3 -1
  46. package/dataLayer/hdbInfoController.ts +34 -1
  47. package/dataLayer/insert.ts +44 -1
  48. package/dataLayer/rocksdbBackup.ts +53 -10
  49. package/dataLayer/schema.ts +11 -1
  50. package/dataLayer/schemaDescribe.ts +8 -1
  51. package/dist/agent/mcpTools.js +1 -1
  52. package/dist/agent/mcpTools.js.map +1 -1
  53. package/dist/agent/session.d.ts +22 -0
  54. package/dist/agent/session.js +26 -15
  55. package/dist/agent/session.js.map +1 -1
  56. package/dist/bin/cliOperations.js +61 -9
  57. package/dist/bin/cliOperations.js.map +1 -1
  58. package/dist/bin/copyDb.d.ts +12 -1
  59. package/dist/bin/copyDb.js +248 -60
  60. package/dist/bin/copyDb.js.map +1 -1
  61. package/dist/bin/deploySetup.d.ts +2 -0
  62. package/dist/bin/deploySetup.js +11 -3
  63. package/dist/bin/deploySetup.js.map +1 -1
  64. package/dist/bin/harper.js +1 -1
  65. package/dist/bin/harper.js.map +1 -1
  66. package/dist/bin/help.js +4 -1
  67. package/dist/bin/help.js.map +1 -1
  68. package/dist/bin/lite.js +4 -1
  69. package/dist/bin/lite.js.map +1 -1
  70. package/dist/bin/restart.js +91 -6
  71. package/dist/bin/restart.js.map +1 -1
  72. package/dist/bin/run.js +4 -10
  73. package/dist/bin/run.js.map +1 -1
  74. package/dist/bin/upgrade.js +4 -3
  75. package/dist/bin/upgrade.js.map +1 -1
  76. package/dist/bin/workloadIdentity.d.ts +18 -0
  77. package/dist/bin/workloadIdentity.js +100 -0
  78. package/dist/bin/workloadIdentity.js.map +1 -0
  79. package/dist/components/Application.d.ts +235 -17
  80. package/dist/components/Application.js +3038 -238
  81. package/dist/components/Application.js.map +1 -1
  82. package/dist/components/ApplicationScope.d.ts +8 -0
  83. package/dist/components/ApplicationScope.js +7 -0
  84. package/dist/components/ApplicationScope.js.map +1 -1
  85. package/dist/components/EntryHandler.js +26 -10
  86. package/dist/components/EntryHandler.js.map +1 -1
  87. package/dist/components/OptionsWatcher.d.ts +4 -0
  88. package/dist/components/OptionsWatcher.js +440 -99
  89. package/dist/components/OptionsWatcher.js.map +1 -1
  90. package/dist/components/RuntimeModuleTracker.js +40 -6
  91. package/dist/components/RuntimeModuleTracker.js.map +1 -1
  92. package/dist/components/Scope.js +52 -13
  93. package/dist/components/Scope.js.map +1 -1
  94. package/dist/components/awaitRestart.d.ts +33 -0
  95. package/dist/components/awaitRestart.js +61 -0
  96. package/dist/components/awaitRestart.js.map +1 -0
  97. package/dist/components/componentLoader.d.ts +38 -1
  98. package/dist/components/componentLoader.js +313 -24
  99. package/dist/components/componentLoader.js.map +1 -1
  100. package/dist/components/componentPreparationLock.d.ts +5 -0
  101. package/dist/components/componentPreparationLock.js +14 -6
  102. package/dist/components/componentPreparationLock.js.map +1 -1
  103. package/dist/components/deploymentOperations.js +4 -1
  104. package/dist/components/deploymentOperations.js.map +1 -1
  105. package/dist/components/deploymentRecorder.d.ts +4 -2
  106. package/dist/components/deploymentRecorder.js +1 -0
  107. package/dist/components/deploymentRecorder.js.map +1 -1
  108. package/dist/components/mcp/adapters/harperHttp.js +4 -0
  109. package/dist/components/mcp/adapters/harperHttp.js.map +1 -1
  110. package/dist/components/mcp/listChanged.js +5 -0
  111. package/dist/components/mcp/listChanged.js.map +1 -1
  112. package/dist/components/mcp/toolRegistry.d.ts +1 -0
  113. package/dist/components/mcp/toolRegistry.js.map +1 -1
  114. package/dist/components/mcp/tools/operations.d.ts +5 -0
  115. package/dist/components/mcp/tools/operations.js +9 -0
  116. package/dist/components/mcp/tools/operations.js.map +1 -1
  117. package/dist/components/mcp/tools/schemas/operationDescriptions.js +2 -2
  118. package/dist/components/mcp/tools/schemas/operationDescriptions.js.map +1 -1
  119. package/dist/components/operations.d.ts +28 -0
  120. package/dist/components/operations.js +476 -113
  121. package/dist/components/operations.js.map +1 -1
  122. package/dist/components/operationsValidation.js +97 -3
  123. package/dist/components/operationsValidation.js.map +1 -1
  124. package/dist/components/packageComponent.js +24 -0
  125. package/dist/components/packageComponent.js.map +1 -1
  126. package/dist/components/requestRestart.d.ts +1 -0
  127. package/dist/components/requestRestart.js +7 -0
  128. package/dist/components/requestRestart.js.map +1 -1
  129. package/dist/components/status/ComponentStatusRegistry.d.ts +0 -4
  130. package/dist/components/status/ComponentStatusRegistry.js +63 -0
  131. package/dist/components/status/ComponentStatusRegistry.js.map +1 -1
  132. package/dist/config/RootConfigWatcher.d.ts +9 -1
  133. package/dist/config/RootConfigWatcher.js +228 -37
  134. package/dist/config/RootConfigWatcher.js.map +1 -1
  135. package/dist/config/configReadRetry.d.ts +8 -0
  136. package/dist/config/configReadRetry.js +62 -0
  137. package/dist/config/configReadRetry.js.map +1 -0
  138. package/dist/config/configUtils.d.ts +11 -2
  139. package/dist/config/configUtils.js +304 -47
  140. package/dist/config/configUtils.js.map +1 -1
  141. package/dist/config/harperConfigEnvVars.d.ts +16 -0
  142. package/dist/config/harperConfigEnvVars.js +162 -25
  143. package/dist/config/harperConfigEnvVars.js.map +1 -1
  144. package/dist/config/parseConfigFile.d.ts +4 -0
  145. package/dist/config/parseConfigFile.js +35 -0
  146. package/dist/config/parseConfigFile.js.map +1 -0
  147. package/dist/config/readConfigFileSync.d.ts +1 -0
  148. package/dist/config/readConfigFileSync.js +47 -0
  149. package/dist/config/readConfigFileSync.js.map +1 -0
  150. package/dist/config/watcherArming.d.ts +15 -0
  151. package/dist/config/watcherArming.js +59 -0
  152. package/dist/config/watcherArming.js.map +1 -0
  153. package/dist/dataLayer/blobBackup.d.ts +49 -20
  154. package/dist/dataLayer/blobBackup.js +139 -50
  155. package/dist/dataLayer/blobBackup.js.map +1 -1
  156. package/dist/dataLayer/delete.js +1 -1
  157. package/dist/dataLayer/delete.js.map +1 -1
  158. package/dist/dataLayer/harperBridge/ResourceBridge.d.ts +14 -1
  159. package/dist/dataLayer/harperBridge/ResourceBridge.js +72 -12
  160. package/dist/dataLayer/harperBridge/ResourceBridge.js.map +1 -1
  161. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.d.ts +3 -1
  162. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js +3 -1
  163. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js.map +1 -1
  164. package/dist/dataLayer/hdbInfoController.d.ts +10 -0
  165. package/dist/dataLayer/hdbInfoController.js +30 -1
  166. package/dist/dataLayer/hdbInfoController.js.map +1 -1
  167. package/dist/dataLayer/insert.d.ts +9 -1
  168. package/dist/dataLayer/insert.js +30 -0
  169. package/dist/dataLayer/insert.js.map +1 -1
  170. package/dist/dataLayer/rocksdbBackup.d.ts +2 -2
  171. package/dist/dataLayer/rocksdbBackup.js +45 -8
  172. package/dist/dataLayer/rocksdbBackup.js.map +1 -1
  173. package/dist/dataLayer/schema.js +8 -0
  174. package/dist/dataLayer/schema.js.map +1 -1
  175. package/dist/dataLayer/schemaDescribe.js +8 -1
  176. package/dist/dataLayer/schemaDescribe.js.map +1 -1
  177. package/dist/index.d.ts +2 -1
  178. package/dist/index.js +4 -1
  179. package/dist/index.js.map +1 -1
  180. package/dist/json/systemSchema.json +55 -0
  181. package/dist/resources/DatabaseTransaction.d.ts +77 -0
  182. package/dist/resources/DatabaseTransaction.js +586 -54
  183. package/dist/resources/DatabaseTransaction.js.map +1 -1
  184. package/dist/resources/LMDBTransaction.d.ts +2 -1
  185. package/dist/resources/LMDBTransaction.js +43 -6
  186. package/dist/resources/LMDBTransaction.js.map +1 -1
  187. package/dist/resources/PrimaryRocksDatabase.d.ts +1 -0
  188. package/dist/resources/PrimaryRocksDatabase.js +49 -5
  189. package/dist/resources/PrimaryRocksDatabase.js.map +1 -1
  190. package/dist/resources/RecordEncoder.d.ts +20 -0
  191. package/dist/resources/RecordEncoder.js +110 -9
  192. package/dist/resources/RecordEncoder.js.map +1 -1
  193. package/dist/resources/RequestTarget.d.ts +2 -0
  194. package/dist/resources/RequestTarget.js.map +1 -1
  195. package/dist/resources/Resource.js +117 -24
  196. package/dist/resources/Resource.js.map +1 -1
  197. package/dist/resources/ResourceInterface.d.ts +28 -1
  198. package/dist/resources/ResourceInterface.js.map +1 -1
  199. package/dist/resources/RocksIndexStore.d.ts +6 -1
  200. package/dist/resources/RocksIndexStore.js +24 -9
  201. package/dist/resources/RocksIndexStore.js.map +1 -1
  202. package/dist/resources/RocksTransactionLogStore.d.ts +24 -1
  203. package/dist/resources/RocksTransactionLogStore.js +160 -49
  204. package/dist/resources/RocksTransactionLogStore.js.map +1 -1
  205. package/dist/resources/Table.d.ts +165 -10
  206. package/dist/resources/Table.js +1805 -303
  207. package/dist/resources/Table.js.map +1 -1
  208. package/dist/resources/analytics/write.js +10 -3
  209. package/dist/resources/analytics/write.js.map +1 -1
  210. package/dist/resources/auditStore.d.ts +181 -2
  211. package/dist/resources/auditStore.js +640 -29
  212. package/dist/resources/auditStore.js.map +1 -1
  213. package/dist/resources/blob.d.ts +129 -9
  214. package/dist/resources/blob.js +992 -114
  215. package/dist/resources/blob.js.map +1 -1
  216. package/dist/resources/branchDatabase.d.ts +48 -0
  217. package/dist/resources/branchDatabase.js +892 -0
  218. package/dist/resources/branchDatabase.js.map +1 -0
  219. package/dist/resources/crdt.js +50 -12
  220. package/dist/resources/crdt.js.map +1 -1
  221. package/dist/resources/dataLoader.js +3 -4
  222. package/dist/resources/dataLoader.js.map +1 -1
  223. package/dist/resources/databases.d.ts +157 -14
  224. package/dist/resources/databases.js +1462 -325
  225. package/dist/resources/databases.js.map +1 -1
  226. package/dist/resources/defineTable.d.ts +10 -2
  227. package/dist/resources/defineTable.js +9 -1
  228. package/dist/resources/defineTable.js.map +1 -1
  229. package/dist/resources/derivedIndexRegistry.d.ts +5 -0
  230. package/dist/resources/derivedIndexRegistry.js +68 -0
  231. package/dist/resources/derivedIndexRegistry.js.map +1 -0
  232. package/dist/resources/derivedIndexRuntime.d.ts +215 -0
  233. package/dist/resources/derivedIndexRuntime.js +2027 -0
  234. package/dist/resources/derivedIndexRuntime.js.map +1 -0
  235. package/dist/resources/graphql.d.ts +1 -1
  236. package/dist/resources/graphql.js +52 -16
  237. package/dist/resources/graphql.js.map +1 -1
  238. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.d.ts +103 -9
  239. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js +854 -41
  240. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js.map +1 -1
  241. package/dist/resources/indexes/hnswDerivedIndex.d.ts +67 -0
  242. package/dist/resources/indexes/hnswDerivedIndex.js +464 -0
  243. package/dist/resources/indexes/hnswDerivedIndex.js.map +1 -0
  244. package/dist/resources/indexes/hnswPlaneBinding.d.ts +65 -0
  245. package/dist/resources/indexes/hnswPlaneBinding.js +91 -0
  246. package/dist/resources/indexes/hnswPlaneBinding.js.map +1 -0
  247. package/dist/resources/longLivedTransactions.d.ts +71 -0
  248. package/dist/resources/longLivedTransactions.js +358 -0
  249. package/dist/resources/longLivedTransactions.js.map +1 -0
  250. package/dist/resources/models/backendRegistry.d.ts +26 -0
  251. package/dist/resources/models/backendRegistry.js +60 -2
  252. package/dist/resources/models/backendRegistry.js.map +1 -1
  253. package/dist/resources/models/bootstrap.d.ts +33 -1
  254. package/dist/resources/models/bootstrap.js +416 -31
  255. package/dist/resources/models/bootstrap.js.map +1 -1
  256. package/dist/resources/nodeIdMapping.d.ts +5 -0
  257. package/dist/resources/nodeIdMapping.js +49 -0
  258. package/dist/resources/nodeIdMapping.js.map +1 -1
  259. package/dist/resources/recordLock.d.ts +123 -0
  260. package/dist/resources/recordLock.js +315 -0
  261. package/dist/resources/recordLock.js.map +1 -0
  262. package/dist/resources/recordLockCoordinator.d.ts +557 -0
  263. package/dist/resources/recordLockCoordinator.js +2565 -0
  264. package/dist/resources/recordLockCoordinator.js.map +1 -0
  265. package/dist/resources/replayLogs.d.ts +14 -1
  266. package/dist/resources/replayLogs.js +157 -24
  267. package/dist/resources/replayLogs.js.map +1 -1
  268. package/dist/resources/replayLogsGuards.d.ts +94 -7
  269. package/dist/resources/replayLogsGuards.js +111 -7
  270. package/dist/resources/replayLogsGuards.js.map +1 -1
  271. package/dist/resources/replicatedApplyFailure.d.ts +16 -0
  272. package/dist/resources/replicatedApplyFailure.js +63 -0
  273. package/dist/resources/replicatedApplyFailure.js.map +1 -0
  274. package/dist/resources/scheduler/scheduler.js +3 -3
  275. package/dist/resources/scheduler/scheduler.js.map +1 -1
  276. package/dist/resources/search.d.ts +10 -4
  277. package/dist/resources/search.js +283 -37
  278. package/dist/resources/search.js.map +1 -1
  279. package/dist/resources/tracked.d.ts +5 -1
  280. package/dist/resources/tracked.js +74 -23
  281. package/dist/resources/tracked.js.map +1 -1
  282. package/dist/resources/transactionBroadcast.d.ts +1 -1
  283. package/dist/resources/transactionBroadcast.js +2 -2
  284. package/dist/resources/transactionBroadcast.js.map +1 -1
  285. package/dist/security/auth.js +61 -30
  286. package/dist/security/auth.js.map +1 -1
  287. package/dist/security/authn/oidc/claims.d.ts +22 -0
  288. package/dist/security/authn/oidc/claims.js +71 -0
  289. package/dist/security/authn/oidc/claims.js.map +1 -0
  290. package/dist/security/authn/oidc/identityToken.d.ts +27 -0
  291. package/dist/security/authn/oidc/identityToken.js +111 -0
  292. package/dist/security/authn/oidc/identityToken.js.map +1 -0
  293. package/dist/security/authn/oidc/jwks.d.ts +25 -0
  294. package/dist/security/authn/oidc/jwks.js +261 -0
  295. package/dist/security/authn/oidc/jwks.js.map +1 -0
  296. package/dist/security/authn/oidc/providers/generic.d.ts +13 -0
  297. package/dist/security/authn/oidc/providers/generic.js +34 -0
  298. package/dist/security/authn/oidc/providers/generic.js.map +1 -0
  299. package/dist/security/authn/oidc/providers/githubActions.d.ts +11 -0
  300. package/dist/security/authn/oidc/providers/githubActions.js +129 -0
  301. package/dist/security/authn/oidc/providers/githubActions.js.map +1 -0
  302. package/dist/security/authn/oidc/providers/index.d.ts +37 -0
  303. package/dist/security/authn/oidc/providers/index.js +24 -0
  304. package/dist/security/authn/oidc/providers/index.js.map +1 -0
  305. package/dist/security/authn/oidc/tokenExchange.d.ts +12 -0
  306. package/dist/security/authn/oidc/tokenExchange.js +306 -0
  307. package/dist/security/authn/oidc/tokenExchange.js.map +1 -0
  308. package/dist/security/authn/oidc/trustPolicyOperations.d.ts +49 -0
  309. package/dist/security/authn/oidc/trustPolicyOperations.js +358 -0
  310. package/dist/security/authn/oidc/trustPolicyOperations.js.map +1 -0
  311. package/dist/security/authn/oidc/types.d.ts +38 -0
  312. package/dist/security/authn/oidc/types.js +6 -0
  313. package/dist/security/authn/oidc/types.js.map +1 -0
  314. package/dist/security/certificateVerification/index.js +40 -11
  315. package/dist/security/certificateVerification/index.js.map +1 -1
  316. package/dist/security/certificateVerification/trustedIssuers.d.ts +24 -0
  317. package/dist/security/certificateVerification/trustedIssuers.js +79 -0
  318. package/dist/security/certificateVerification/trustedIssuers.js.map +1 -0
  319. package/dist/security/certificateVerification/types.d.ts +1 -0
  320. package/dist/security/credentialProvenance.d.ts +35 -0
  321. package/dist/security/credentialProvenance.js +51 -0
  322. package/dist/security/credentialProvenance.js.map +1 -0
  323. package/dist/security/credentialRejection.d.ts +4 -0
  324. package/dist/security/credentialRejection.js +24 -0
  325. package/dist/security/credentialRejection.js.map +1 -0
  326. package/dist/security/deferredAuthentication.d.ts +36 -0
  327. package/dist/security/deferredAuthentication.js +70 -0
  328. package/dist/security/deferredAuthentication.js.map +1 -0
  329. package/dist/security/impersonation.d.ts +21 -0
  330. package/dist/security/impersonation.js +108 -9
  331. package/dist/security/impersonation.js.map +1 -1
  332. package/dist/security/jsLoader.d.ts +6 -0
  333. package/dist/security/jsLoader.js +77 -15
  334. package/dist/security/jsLoader.js.map +1 -1
  335. package/dist/security/keys.js +301 -71
  336. package/dist/security/keys.js.map +1 -1
  337. package/dist/security/operationScope.d.ts +21 -0
  338. package/dist/security/operationScope.js +36 -0
  339. package/dist/security/operationScope.js.map +1 -0
  340. package/dist/security/permissionsTranslator.js +21 -0
  341. package/dist/security/permissionsTranslator.js.map +1 -1
  342. package/dist/security/tokenAuthentication.d.ts +19 -1
  343. package/dist/security/tokenAuthentication.js +191 -10
  344. package/dist/security/tokenAuthentication.js.map +1 -1
  345. package/dist/security/user.js +4 -3
  346. package/dist/security/user.js.map +1 -1
  347. package/dist/server/DurableSubscriptionsSession.d.ts +2 -2
  348. package/dist/server/DurableSubscriptionsSession.js +67 -10
  349. package/dist/server/DurableSubscriptionsSession.js.map +1 -1
  350. package/dist/server/REST.js +106 -2
  351. package/dist/server/REST.js.map +1 -1
  352. package/dist/server/graphqlQuerying.js +4 -0
  353. package/dist/server/graphqlQuerying.js.map +1 -1
  354. package/dist/server/http.d.ts +16 -1
  355. package/dist/server/http.js +122 -17
  356. package/dist/server/http.js.map +1 -1
  357. package/dist/server/itc/serverHandlers.js +8 -1
  358. package/dist/server/itc/serverHandlers.js.map +1 -1
  359. package/dist/server/jobs/jobProcess.js +6 -2
  360. package/dist/server/jobs/jobProcess.js.map +1 -1
  361. package/dist/server/jobs/jobs.js +4 -1
  362. package/dist/server/jobs/jobs.js.map +1 -1
  363. package/dist/server/liveSubscriptionAuth.d.ts +26 -4
  364. package/dist/server/liveSubscriptionAuth.js +105 -39
  365. package/dist/server/liveSubscriptionAuth.js.map +1 -1
  366. package/dist/server/loadRootComponents.js +49 -10
  367. package/dist/server/loadRootComponents.js.map +1 -1
  368. package/dist/server/mqtt.d.ts +2 -0
  369. package/dist/server/mqtt.js +165 -30
  370. package/dist/server/mqtt.js.map +1 -1
  371. package/dist/server/nodeName.d.ts +2 -0
  372. package/dist/server/nodeName.js +107 -23
  373. package/dist/server/nodeName.js.map +1 -1
  374. package/dist/server/serverHelpers/Headers.d.ts +27 -0
  375. package/dist/server/serverHelpers/Headers.js +145 -1
  376. package/dist/server/serverHelpers/Headers.js.map +1 -1
  377. package/dist/server/serverHelpers/NodeAdapterResponse.d.ts +48 -0
  378. package/dist/server/serverHelpers/NodeAdapterResponse.js +220 -0
  379. package/dist/server/serverHelpers/NodeAdapterResponse.js.map +1 -0
  380. package/dist/server/serverHelpers/Request.d.ts +5 -10
  381. package/dist/server/serverHelpers/Request.js +38 -136
  382. package/dist/server/serverHelpers/Request.js.map +1 -1
  383. package/dist/server/serverHelpers/contentTypes.d.ts +11 -0
  384. package/dist/server/serverHelpers/contentTypes.js +221 -40
  385. package/dist/server/serverHelpers/contentTypes.js.map +1 -1
  386. package/dist/server/serverHelpers/deployValidationState.d.ts +3 -0
  387. package/dist/server/serverHelpers/deployValidationState.js +9 -19
  388. package/dist/server/serverHelpers/deployValidationState.js.map +1 -1
  389. package/dist/server/serverHelpers/operationAuthorizationState.d.ts +12 -0
  390. package/dist/server/serverHelpers/operationAuthorizationState.js +24 -2
  391. package/dist/server/serverHelpers/operationAuthorizationState.js.map +1 -1
  392. package/dist/server/serverHelpers/registeredOperations.d.ts +5 -4
  393. package/dist/server/serverHelpers/registeredOperations.js +74 -21
  394. package/dist/server/serverHelpers/registeredOperations.js.map +1 -1
  395. package/dist/server/serverHelpers/requestSanitization.d.ts +11 -0
  396. package/dist/server/serverHelpers/requestSanitization.js +20 -0
  397. package/dist/server/serverHelpers/requestSanitization.js.map +1 -0
  398. package/dist/server/serverHelpers/serverHandlers.js +6 -3
  399. package/dist/server/serverHelpers/serverHandlers.js.map +1 -1
  400. package/dist/server/serverHelpers/serverUtilities.d.ts +18 -0
  401. package/dist/server/serverHelpers/serverUtilities.js +178 -29
  402. package/dist/server/serverHelpers/serverUtilities.js.map +1 -1
  403. package/dist/server/serverHelpers/sharedMessageEncoding.d.ts +67 -0
  404. package/dist/server/serverHelpers/sharedMessageEncoding.js +280 -0
  405. package/dist/server/serverHelpers/sharedMessageEncoding.js.map +1 -0
  406. package/dist/server/serverHelpers/uwsServer.js +19 -1
  407. package/dist/server/serverHelpers/uwsServer.js.map +1 -1
  408. package/dist/server/static.js +24 -28
  409. package/dist/server/static.js.map +1 -1
  410. package/dist/server/storageReclamation.d.ts +5 -0
  411. package/dist/server/storageReclamation.js +17 -1
  412. package/dist/server/storageReclamation.js.map +1 -1
  413. package/dist/server/threads/isolatedApplications.d.ts +47 -0
  414. package/dist/server/threads/isolatedApplications.js +171 -0
  415. package/dist/server/threads/isolatedApplications.js.map +1 -0
  416. package/dist/server/threads/itc.d.ts +7 -2
  417. package/dist/server/threads/itc.js +5 -1
  418. package/dist/server/threads/itc.js.map +1 -1
  419. package/dist/server/threads/logRotationTransport.d.ts +1 -0
  420. package/dist/server/threads/logRotationTransport.js +33 -0
  421. package/dist/server/threads/logRotationTransport.js.map +1 -0
  422. package/dist/server/threads/manageThreads.d.ts +83 -3
  423. package/dist/server/threads/manageThreads.js +769 -75
  424. package/dist/server/threads/manageThreads.js.map +1 -1
  425. package/dist/server/threads/socketRouter.d.ts +1 -0
  426. package/dist/server/threads/socketRouter.js +277 -31
  427. package/dist/server/threads/socketRouter.js.map +1 -1
  428. package/dist/server/threads/threadHeapMemory.d.ts +2 -0
  429. package/dist/server/threads/threadHeapMemory.js +31 -0
  430. package/dist/server/threads/threadHeapMemory.js.map +1 -0
  431. package/dist/server/threads/threadServer.js +76 -22
  432. package/dist/server/threads/threadServer.js.map +1 -1
  433. package/dist/sqlEngine/config.d.ts +1 -3
  434. package/dist/sqlEngine/config.js +19 -16
  435. package/dist/sqlEngine/config.js.map +1 -1
  436. package/dist/sqlTranslator/index.d.ts +1 -1
  437. package/dist/sqlTranslator/index.js +30 -7
  438. package/dist/sqlTranslator/index.js.map +1 -1
  439. package/dist/upgrade/directives/5-3-0.d.ts +7 -0
  440. package/dist/upgrade/directives/5-3-0.js +148 -0
  441. package/dist/upgrade/directives/5-3-0.js.map +1 -0
  442. package/dist/upgrade/directives/directivesController.js +2 -1
  443. package/dist/upgrade/directives/directivesController.js.map +1 -1
  444. package/dist/utility/OperationFunctionCaller.js +2 -1
  445. package/dist/utility/OperationFunctionCaller.js.map +1 -1
  446. package/dist/utility/common_utils.d.ts +16 -0
  447. package/dist/utility/common_utils.js +32 -6
  448. package/dist/utility/common_utils.js.map +1 -1
  449. package/dist/utility/componentNames.d.ts +8 -0
  450. package/dist/utility/componentNames.js +12 -1
  451. package/dist/utility/componentNames.js.map +1 -1
  452. package/dist/utility/environment/environmentManager.js +3 -6
  453. package/dist/utility/environment/environmentManager.js.map +1 -1
  454. package/dist/utility/environment/systemInformation.d.ts +1 -0
  455. package/dist/utility/environment/systemInformation.js +1 -0
  456. package/dist/utility/environment/systemInformation.js.map +1 -1
  457. package/dist/utility/errors/commonErrors.d.ts +2 -0
  458. package/dist/utility/errors/commonErrors.js +2 -0
  459. package/dist/utility/errors/commonErrors.js.map +1 -1
  460. package/dist/utility/errors/hdbError.d.ts +33 -0
  461. package/dist/utility/errors/hdbError.js +58 -1
  462. package/dist/utility/errors/hdbError.js.map +1 -1
  463. package/dist/utility/globalSchema.d.ts +18 -0
  464. package/dist/utility/hdbTerms.d.ts +18 -0
  465. package/dist/utility/hdbTerms.js +20 -2
  466. package/dist/utility/hdbTerms.js.map +1 -1
  467. package/dist/utility/logging/harper_logger.d.ts +2 -0
  468. package/dist/utility/logging/harper_logger.js +286 -30
  469. package/dist/utility/logging/harper_logger.js.map +1 -1
  470. package/dist/utility/logging/logGenerationCoordinator.d.ts +35 -0
  471. package/dist/utility/logging/logGenerationCoordinator.js +184 -0
  472. package/dist/utility/logging/logGenerationCoordinator.js.map +1 -0
  473. package/dist/utility/logging/logRotation.d.ts +46 -0
  474. package/dist/utility/logging/logRotation.js +365 -0
  475. package/dist/utility/logging/logRotation.js.map +1 -0
  476. package/dist/utility/logging/logRotator.d.ts +1 -1
  477. package/dist/utility/logging/logRotator.js +192 -85
  478. package/dist/utility/logging/logRotator.js.map +1 -1
  479. package/dist/utility/nodeIdentity.d.ts +9 -0
  480. package/dist/utility/nodeIdentity.js +58 -0
  481. package/dist/utility/nodeIdentity.js.map +1 -0
  482. package/dist/utility/npmUtilities.js +11 -7
  483. package/dist/utility/npmUtilities.js.map +1 -1
  484. package/dist/utility/operationPermissions.d.ts +3 -1
  485. package/dist/utility/operationPermissions.js +16 -1
  486. package/dist/utility/operationPermissions.js.map +1 -1
  487. package/dist/utility/operation_authorization.d.ts +10 -7
  488. package/dist/utility/operation_authorization.js +212 -41
  489. package/dist/utility/operation_authorization.js.map +1 -1
  490. package/dist/utility/watchPath.d.ts +29 -0
  491. package/dist/utility/watchPath.js +68 -0
  492. package/dist/utility/watchPath.js.map +1 -0
  493. package/dist/utility/watcherFallback.d.ts +41 -0
  494. package/dist/utility/watcherFallback.js +153 -0
  495. package/dist/utility/watcherFallback.js.map +1 -1
  496. package/dist/validation/configValidator.d.ts +12 -0
  497. package/dist/validation/configValidator.js +205 -75
  498. package/dist/validation/configValidator.js.map +1 -1
  499. package/dist/validation/installValidator.js +12 -0
  500. package/dist/validation/installValidator.js.map +1 -1
  501. package/dist/validation/validationWrapper.d.ts +11 -0
  502. package/dist/validation/validationWrapper.js +16 -3
  503. package/dist/validation/validationWrapper.js.map +1 -1
  504. package/index.ts +8 -0
  505. package/json/systemSchema.json +55 -0
  506. package/npm-shrinkwrap.json +286 -194
  507. package/package.json +15 -7
  508. package/resources/DESIGN.md +219 -52
  509. package/resources/DatabaseTransaction.ts +657 -52
  510. package/resources/LMDBTransaction.ts +46 -6
  511. package/resources/PrimaryRocksDatabase.ts +46 -7
  512. package/resources/RecordEncoder.ts +124 -9
  513. package/resources/RequestTarget.ts +2 -0
  514. package/resources/Resource.ts +114 -22
  515. package/resources/ResourceInterface.ts +31 -0
  516. package/resources/RocksIndexStore.ts +30 -9
  517. package/resources/RocksTransactionLogStore.ts +188 -51
  518. package/resources/Table.ts +1960 -301
  519. package/resources/analytics/write.ts +10 -3
  520. package/resources/auditStore.ts +647 -32
  521. package/resources/blob.ts +1029 -110
  522. package/resources/branchDatabase.ts +941 -0
  523. package/resources/crdt.ts +76 -12
  524. package/resources/dataLoader.ts +3 -4
  525. package/resources/databases.ts +1584 -320
  526. package/resources/defineTable.ts +18 -2
  527. package/resources/derivedIndexRegistry.ts +56 -0
  528. package/resources/derivedIndexRuntime.ts +2292 -0
  529. package/resources/graphql.ts +72 -17
  530. package/resources/indexes/HierarchicalNavigableSmallWorld.ts +911 -48
  531. package/resources/indexes/hnswDerivedIndex.ts +531 -0
  532. package/resources/indexes/hnswPlaneBinding.ts +174 -0
  533. package/resources/longLivedTransactions.ts +360 -0
  534. package/resources/models/backendRegistry.ts +84 -2
  535. package/resources/models/bootstrap.ts +473 -28
  536. package/resources/nodeIdMapping.ts +50 -0
  537. package/resources/recordLock.ts +419 -0
  538. package/resources/recordLockCoordinator.ts +3043 -0
  539. package/resources/replayLogs.ts +152 -26
  540. package/resources/replayLogsGuards.ts +171 -8
  541. package/resources/replicatedApplyFailure.ts +77 -0
  542. package/resources/scheduler/scheduler.ts +4 -4
  543. package/resources/search.ts +288 -46
  544. package/resources/tracked.ts +73 -22
  545. package/resources/transactionBroadcast.ts +3 -3
  546. package/security/auth.ts +68 -29
  547. package/security/authn/oidc/claims.ts +72 -0
  548. package/security/authn/oidc/identityToken.ts +129 -0
  549. package/security/authn/oidc/jwks.ts +260 -0
  550. package/security/authn/oidc/providers/generic.ts +40 -0
  551. package/security/authn/oidc/providers/githubActions.ts +137 -0
  552. package/security/authn/oidc/providers/index.ts +52 -0
  553. package/security/authn/oidc/tokenExchange.ts +300 -0
  554. package/security/authn/oidc/trustPolicyOperations.ts +343 -0
  555. package/security/authn/oidc/types.ts +41 -0
  556. package/security/certificateVerification/index.ts +54 -13
  557. package/security/certificateVerification/trustedIssuers.ts +76 -0
  558. package/security/certificateVerification/types.ts +1 -0
  559. package/security/credentialProvenance.ts +47 -0
  560. package/security/credentialRejection.ts +22 -0
  561. package/security/deferredAuthentication.ts +71 -0
  562. package/security/impersonation.ts +117 -12
  563. package/security/jsLoader.ts +83 -18
  564. package/security/keys.ts +298 -72
  565. package/security/operationScope.ts +33 -0
  566. package/security/permissionsTranslator.js +23 -0
  567. package/security/tokenAuthentication.ts +233 -12
  568. package/security/user.ts +4 -3
  569. package/server/DESIGN.md +194 -16
  570. package/server/DurableSubscriptionsSession.ts +71 -11
  571. package/server/REST.ts +115 -4
  572. package/server/graphqlQuerying.ts +4 -0
  573. package/server/http.ts +133 -20
  574. package/server/itc/serverHandlers.js +8 -1
  575. package/server/jobs/jobProcess.ts +8 -2
  576. package/server/jobs/jobs.ts +4 -1
  577. package/server/liveSubscriptionAuth.ts +129 -46
  578. package/server/loadRootComponents.js +50 -8
  579. package/server/mqtt.ts +179 -38
  580. package/server/nodeName.ts +103 -21
  581. package/server/serverHelpers/Headers.ts +135 -0
  582. package/server/serverHelpers/NodeAdapterResponse.ts +221 -0
  583. package/server/serverHelpers/Request.ts +33 -131
  584. package/server/serverHelpers/contentTypes.ts +217 -36
  585. package/server/serverHelpers/deployValidationState.ts +24 -13
  586. package/server/serverHelpers/operationAuthorizationState.ts +34 -3
  587. package/server/serverHelpers/registeredOperations.ts +79 -22
  588. package/server/serverHelpers/requestSanitization.ts +15 -0
  589. package/server/serverHelpers/serverHandlers.js +6 -3
  590. package/server/serverHelpers/serverUtilities.ts +232 -40
  591. package/server/serverHelpers/sharedMessageEncoding.ts +307 -0
  592. package/server/serverHelpers/uwsServer.ts +17 -2
  593. package/server/static.ts +23 -29
  594. package/server/storageReclamation.ts +15 -2
  595. package/server/threads/isolatedApplications.ts +157 -0
  596. package/server/threads/itc.js +11 -1
  597. package/server/threads/logRotationTransport.ts +40 -0
  598. package/server/threads/manageThreads.js +771 -66
  599. package/server/threads/socketRouter.ts +291 -30
  600. package/server/threads/threadHeapMemory.ts +26 -0
  601. package/server/threads/threadServer.js +73 -22
  602. package/sqlTranslator/index.ts +31 -8
  603. package/studio/web/assets/{Chat-4RrB5134.js → Chat-D3j-1yY1.js} +1 -1
  604. package/studio/web/assets/{FloatingChat-omlNMDcJ.js → FloatingChat-BxJGYcfB.js} +3 -3
  605. package/studio/web/assets/{apiToken-Bke3wvfZ.js → apiToken-CT55oWOe.js} +1 -1
  606. package/studio/web/assets/{applications-DvFDYJgK.js → applications-D9Ct9_vm.js} +1 -1
  607. package/studio/web/assets/{cssMode-C1vRa7zh.js → cssMode-DV8H7VwA.js} +1 -1
  608. package/studio/web/assets/{editor-3XRWEDWX.js → editor-uatc0unt.js} +1 -1
  609. package/studio/web/assets/{html-CTY5tdMr.js → html-Bm6D6paN.js} +1 -1
  610. package/studio/web/assets/{htmlMode-CG1vSD9t.js → htmlMode-CEn7tpLG.js} +1 -1
  611. package/studio/web/assets/{index-Dfpeofdu.js → index-BIXW6Pu4.js} +5 -5
  612. package/studio/web/assets/{index.lazy-B1VOIv-t.js → index.lazy-UI7L-Vrk.js} +1 -1
  613. package/studio/web/assets/{javascript-CJeJzGnI.js → javascript-CJ0G3AFZ.js} +1 -1
  614. package/studio/web/assets/{jsonMode-CYPBwM82.js → jsonMode-DQADAYEa.js} +1 -1
  615. package/studio/web/assets/{languageServices-IKH4GUHl.js → languageServices-CAQJXWcI.js} +1 -1
  616. package/studio/web/assets/{lspLanguageFeatures-BC8_gxKG.js → lspLanguageFeatures-CCQ8P5sY.js} +1 -1
  617. package/studio/web/assets/{notifications-BfKBpYcq.js → notifications-BbxTU6Aw.js} +1 -1
  618. package/studio/web/assets/{notifications-DFbArTfC.js → notifications-Cvb3P1lB.js} +1 -1
  619. package/studio/web/assets/{profile-Q4-T6c-S.js → profile-Yyb7gsvL.js} +1 -1
  620. package/studio/web/assets/{regions-CtkV0xje.js → regions-OgjGHlU5.js} +1 -1
  621. package/studio/web/assets/{register-1ZZuMsiA.js → register-6qwNEOY3.js} +2 -2
  622. package/studio/web/assets/{setComponentFile-ZWLcWv5X.js → setComponentFile-BilDMtgB.js} +1 -1
  623. package/studio/web/assets/{setup-DWprJyJy.js → setup-J6qJ7OIU.js} +2 -2
  624. package/studio/web/assets/{status--aNm8isn.js → status-0RWGcfyD.js} +1 -1
  625. package/studio/web/assets/{toggleHighContrast-Cq_lt3XD.js → toggleHighContrast-BIn-vErT.js} +1 -1
  626. package/studio/web/assets/{tsMode-pjgytARx.js → tsMode-DgUXku4d.js} +1 -1
  627. package/studio/web/assets/{typescript-Cdg0mqUh.js → typescript-C9orXcsM.js} +1 -1
  628. package/studio/web/assets/{useEntityRestURL-RZhaY8Rn.js → useEntityRestURL-BEoXXbUB.js} +1 -1
  629. package/studio/web/assets/{workers-BgoXIqQe.js → workers-JVzSDmgx.js} +1 -1
  630. package/studio/web/assets/{xml-BwSeDMiP.js → xml-Cq-S8S4X.js} +1 -1
  631. package/studio/web/assets/{yaml-DotCUG5l.js → yaml-sfoRdh1M.js} +1 -1
  632. package/studio/web/index.html +1 -1
  633. package/upgrade/directives/5-3-0.ts +132 -0
  634. package/upgrade/directives/directivesController.ts +2 -1
  635. package/utility/OperationFunctionCaller.ts +2 -1
  636. package/utility/common_utils.ts +30 -5
  637. package/utility/componentNames.ts +12 -0
  638. package/utility/environment/environmentManager.ts +3 -7
  639. package/utility/environment/systemInformation.ts +7 -0
  640. package/utility/errors/commonErrors.ts +4 -0
  641. package/utility/errors/hdbError.ts +57 -0
  642. package/utility/hdbTerms.ts +19 -0
  643. package/utility/logging/harper_logger.ts +278 -26
  644. package/utility/logging/logGenerationCoordinator.ts +196 -0
  645. package/utility/logging/logRotation.ts +367 -0
  646. package/utility/logging/logRotator.ts +213 -81
  647. package/utility/nodeIdentity.ts +45 -0
  648. package/utility/npmUtilities.ts +12 -8
  649. package/utility/operationPermissions.ts +18 -1
  650. package/utility/operation_authorization.ts +231 -42
  651. package/utility/watchPath.ts +63 -0
  652. package/utility/watcherFallback.ts +148 -0
  653. package/validation/configValidator.ts +215 -75
  654. package/validation/installValidator.ts +15 -0
  655. package/validation/validationWrapper.ts +18 -4
@@ -1,13 +1,29 @@
1
- import { startWorker, setMonitorListener, setMainIsWorker, threadsHaveStarted } from './manageThreads.js';
1
+ import {
2
+ startWorker,
3
+ setMonitorListener,
4
+ setMainIsWorker,
5
+ threadsHaveStarted,
6
+ setIsolatedWorkerReconciler,
7
+ setRunningIsolatedApplicationsGetter,
8
+ workersForApplication,
9
+ stopWorker,
10
+ } from './manageThreads.js';
11
+ import {
12
+ presentIsolatedApplicationNames,
13
+ isolatedApplicationRefusal,
14
+ isolatedApplicationCapacityRefusal,
15
+ } from './isolatedApplications.ts';
16
+ import { lifecycle as componentLifecycle } from '../../components/status/index.ts';
2
17
  import * as hdbTerms from '../../utility/hdbTerms.ts';
3
18
  import * as harperLogger from '../../utility/logging/harper_logger.ts';
4
19
  import { recordHostname } from '../../resources/analytics/write.ts';
5
20
  import { startTransactionLogCooling } from '../transactionLogCooling.ts';
6
- import { isMainThread } from 'worker_threads';
7
- import { join } from 'path';
21
+ import { startLongLivedTransactionReporting } from '../../resources/longLivedTransactions.ts';
22
+ import { isMainThread } from 'node:worker_threads';
23
+ import { join } from 'node:path';
8
24
 
9
25
  const workers = [];
10
- const workersReady = [];
26
+ const HTTP_WORKER_STARTUP_DIAGNOSTIC_MS = 60000;
11
27
  // startHTTPThreads() can be called more than once in-process (e.g. a test harness adding more
12
28
  // worker threads to an already-running server via addThreads()). The crash-path sweep below must
13
29
  // run only on the very first call — a later call happens after real mirrors are already bound, and
@@ -18,6 +34,9 @@ let sweptSocketsDirectory = false;
18
34
  if (isMainThread) {
19
35
  process.on('uncaughtException', (error) => {
20
36
  // TODO: Maybe we should try to log the first of each type of error
37
+ // Same `isHandled` contract as threadServer.js: an error another handler has already
38
+ // classified (a lost native file watch, for instance) must not be logged again here.
39
+ if ((error as any).isHandled) return;
21
40
  if ((error as any).code === 'ECONNRESET') return; // that's what network connections do
22
41
  if ((error as any).code === 'EIO') {
23
42
  // that means the terminal is closed
@@ -29,6 +48,7 @@ if (isMainThread) {
29
48
  }
30
49
 
31
50
  export async function startHTTPThreads(threadCount = 2, dynamicThreads?: boolean) {
51
+ const workerSlots = [];
32
52
  // Crash-path defense: a hard crash can skip a worker's exit-time UDS cleanup and leave stale
33
53
  // mirror files behind. This runs before any worker below can start (and thus before any mirror
34
54
  // can bind), so it can only ever clear files nothing is using yet — never a live mirror. The
@@ -48,13 +68,16 @@ export async function startHTTPThreads(threadCount = 2, dynamicThreads?: boolean
48
68
  // process-global singleton; see startTransactionLogCooling). Runs for all
49
69
  // thread modes below, including the single-threaded (threadCount === 0) path.
50
70
  startTransactionLogCooling();
71
+ startLongLivedTransactionReporting();
51
72
  try {
52
73
  if (dynamicThreads) {
53
74
  // No caller currently passes dynamicThreads. If one ever does, note that the main thread
54
75
  // does not bind ports in this mode, so on platforms without SO_REUSEPORT (macOS/Windows)
55
76
  // worker 0's exclusive HTTP bind would silently swallow an external EADDRINUSE — the
56
77
  // external-conflict detection in listenOnPorts() assumes the main thread binds first.
57
- startHTTPWorker(0, 1);
78
+ const slot = startHTTPWorker(0, 1);
79
+ workerSlots.push(slot);
80
+ poolSlots.push(slot);
58
81
  } else {
59
82
  const { loadRootComponents } = require('../loadRootComponents.js');
60
83
  if (threadCount === 0) {
@@ -72,44 +95,282 @@ export async function startHTTPThreads(threadCount = 2, dynamicThreads?: boolean
72
95
  // Windows does not support SO_REUSEPORT, so only a single HTTP worker is supported.
73
96
  if (process.platform === 'win32') threadCount = 1;
74
97
  }
98
+ poolSize = threadCount;
99
+ nextIsolatedIndex = Math.max(nextIsolatedIndex, threadCount);
100
+ const isolated = admittedIsolatedApplications([...isolatedSlots.keys()]);
101
+ const heapShareCount = threadCount + isolated.length;
75
102
  for (let i = 0; i < threadCount; i++) {
76
- startHTTPWorker(i, threadCount);
103
+ const slot = startHTTPWorker(i, threadCount, undefined, heapShareCount);
104
+ workerSlots.push(slot);
105
+ poolSlots.push(slot);
77
106
  }
78
- await Promise.all(workersReady);
107
+ // One dedicated worker per isolated application, numbered past the pool so no pool-only duty
108
+ // (worker 0's startup log, the last worker's cleanup) ever lands on it.
109
+ for (const application of isolated) {
110
+ if (isolatedSlots.has(application)) continue;
111
+ const slot = startHTTPWorker(nextIsolatedIndex++, threadCount, application, heapShareCount);
112
+ isolatedSlots.set(application, slot);
113
+ workerSlots.push(slot);
114
+ void watchDedicatedStart(application, slot);
115
+ }
116
+ await Promise.all(workerSlots.filter((slot) => !slot.application).map((slot) => slot.ready));
79
117
  } finally {
118
+ for (const slot of workerSlots) if (!slot.application) slot.finishStartup();
80
119
  threadsHaveStarted(undefined as any);
81
120
  }
82
121
  }
83
122
 
84
- function startHTTPWorker(index, threadCount = 1) {
85
- startWorker(join(__dirname, './threadServer.js'), {
123
+ let poolSize = 0;
124
+ const refusedIsolated = new Set<string>(); // reported once, not on every reconcile
125
+ const ISOLATED_WORKER_READY_TIMEOUT_MS = 60_000; // the pool replacement path's backstop
126
+ let nextIsolatedIndex = 0;
127
+ type IsolatedSlot = {
128
+ ready: Promise<void>;
129
+ finishStartup: () => void;
130
+ shutdown: () => Promise<void>;
131
+ setHeapShareCount: (count: number) => void;
132
+ application?: string;
133
+ };
134
+ const isolatedSlots = new Map<string, IsolatedSlot>();
135
+ const poolSlots: IsolatedSlot[] = [];
136
+
137
+ /**
138
+ * The isolated applications that get a dedicated worker. Ones already running keep their place; new
139
+ * ones are admitted up to `threads.maxIsolated`, and only while a dedicated worker would be reachable
140
+ * at all. Everything refused is refused loudly and loaded nowhere -- never downgraded to the pool.
141
+ */
142
+ function admittedIsolatedApplications(running: string[]): string[] {
143
+ const names = presentIsolatedApplicationNames();
144
+ const admitted = [];
145
+ for (const name of running) {
146
+ if (!names.includes(name)) continue;
147
+ const refusal = isolatedApplicationRefusal(name);
148
+ if (refusal) {
149
+ reportIsolatedRefusal(name, refusal);
150
+ continue;
151
+ }
152
+ admitted.push(name);
153
+ }
154
+ for (const name of names) {
155
+ if (admitted.includes(name)) continue;
156
+ const refusal = isolatedApplicationRefusal(name) ?? isolatedApplicationCapacityRefusal(name, admitted);
157
+ if (refusal) {
158
+ reportIsolatedRefusal(name, refusal);
159
+ continue;
160
+ }
161
+ refusedIsolated.delete(name);
162
+ admitted.push(name);
163
+ }
164
+ return admitted;
165
+ }
166
+
167
+ function reportIsolatedRefusal(name: string, refusal: string) {
168
+ if (refusedIsolated.has(name)) return;
169
+ refusedIsolated.add(name);
170
+ const error = new Error(
171
+ `Application '${name}' is isolated but gets no dedicated worker: ${refusal}; it is not loaded anywhere`
172
+ );
173
+ harperLogger.error(error.message);
174
+ componentLifecycle.failed(name, error, `Component '${name}' failed to load`);
175
+ }
176
+
177
+ /**
178
+ * Wait for a dedicated worker to become ready, with the pool replacement path's backstop. A worker that
179
+ * fails, or stays alive without ever reporting ready, is recorded as a failed component, stopped, and
180
+ * only then has its slot freed, so the next reconcile retries against a worker that has exited.
181
+ * Resolves whether it became ready.
182
+ */
183
+ function watchDedicatedStart(application: string, slot: IsolatedSlot): Promise<boolean> {
184
+ return Promise.race([
185
+ slot.ready,
186
+ new Promise<never>((_, reject) =>
187
+ setTimeout(
188
+ () => reject(new Error(`Dedicated worker for '${application}' did not become ready in time`)),
189
+ ISOLATED_WORKER_READY_TIMEOUT_MS
190
+ ).unref()
191
+ ),
192
+ ])
193
+ .then(() => true)
194
+ .catch(async (error) => {
195
+ harperLogger.error(`Dedicated worker for isolated application '${application}' failed to start`, error);
196
+ componentLifecycle.failed(application, error, `Component '${application}' failed to load`);
197
+ // The slot IS the lease: holding it until the failed worker has actually exited is what stops a
198
+ // reconcile from starting a replacement over its still-bound UDS mirror and still-open stores,
199
+ // and what makes a concurrent drop's `await slot.shutdown()` cover this worker too.
200
+ await slot.shutdown();
201
+ if (isolatedSlots.get(application) !== slot) return false; // a drop already withdrew this lease
202
+ isolatedSlots.delete(application);
203
+ const { cleanupApplicationSockets } = await import('../http.ts');
204
+ // A reconcile may have installed a replacement while that import resolved. Never unlink its mirror.
205
+ if (!isolatedSlots.has(application)) cleanupApplicationSockets(application);
206
+ return false;
207
+ })
208
+ .finally(() => slot.finishStartup());
209
+ }
210
+
211
+ /**
212
+ * Bring the dedicated workers in line with the root config: start one for each isolated application
213
+ * that has none, stop the one of an application that is no longer isolated or no longer configured.
214
+ * Runs on the main thread after every root-component reload (deploy, drop, restart).
215
+ */
216
+ let reconciling: Promise<string[]> = Promise.resolve([]);
217
+ export function reconcileIsolatedWorkers(): Promise<string[]> {
218
+ // serialized: two reloads in flight must not compute `wanted` against each other's half-done work
219
+ reconciling = reconciling.then(reconcileIsolatedWorkersNow, reconcileIsolatedWorkersNow);
220
+ return reconciling;
221
+ }
222
+
223
+ async function reconcileIsolatedWorkersNow(): Promise<string[]> {
224
+ if (!isMainThread || poolSize === 0) return [];
225
+ const wanted = new Set(admittedIsolatedApplications([...isolatedSlots.keys()]));
226
+ const stopping = [];
227
+ for (const [application, slot] of isolatedSlots) {
228
+ if (wanted.has(application)) continue;
229
+ isolatedSlots.delete(application);
230
+ // awaited: a caller that goes on to remove the application's storage must see its worker gone
231
+ stopping.push(slot.shutdown().then(() => application));
232
+ }
233
+ const stoppedApplications = await Promise.all(stopping);
234
+ if (stoppedApplications.length > 0) {
235
+ const { cleanupApplicationSockets } = await import('../http.ts');
236
+ for (const application of stoppedApplications) cleanupApplicationSockets(application);
237
+ }
238
+ const started: string[] = [];
239
+ const heapShareCount = poolSize + wanted.size;
240
+ for (const slot of poolSlots) slot.setHeapShareCount(heapShareCount);
241
+ for (const slot of isolatedSlots.values()) slot.setHeapShareCount(heapShareCount);
242
+ for (const application of wanted) {
243
+ if (isolatedSlots.has(application)) continue;
244
+ const slot = startHTTPWorker(nextIsolatedIndex++, poolSize, application, heapShareCount);
245
+ isolatedSlots.set(application, slot);
246
+ started.push(application);
247
+ void watchDedicatedStart(application, slot);
248
+ }
249
+ return started;
250
+ }
251
+ if (isMainThread) {
252
+ setIsolatedWorkerReconciler(reconcileIsolatedWorkers);
253
+ setRunningIsolatedApplicationsGetter(() => [...isolatedSlots.keys()]);
254
+ }
255
+
256
+ function startHTTPWorker(index, threadCount = 1, application?: string, heapShareCount?: number) {
257
+ const { promise: ready, resolve: resolveReady, reject: rejectReady } = Promise.withResolvers<void>();
258
+ let waitingForInitialReady = true;
259
+ let finishCurrentStartup = () => {};
260
+ let startupAttempts = 0;
261
+ // A Worker's threadId reads back as -1 once it has exited, which is exactly when the diagnostics
262
+ // below run, so each attempt records its id while the worker is still alive.
263
+ let lastThreadId = -1;
264
+ let isolatedSlot: IsolatedSlot | undefined;
265
+ const finishStartup = () => {
266
+ waitingForInitialReady = false;
267
+ finishCurrentStartup();
268
+ };
269
+ const failStartup = (error) => {
270
+ if (!waitingForInitialReady) return;
271
+ waitingForInitialReady = false;
272
+ finishCurrentStartup();
273
+ rejectReady(error);
274
+ };
275
+ const workerOptions = {
86
276
  name: hdbTerms.THREAD_TYPES.HTTP,
87
277
  workerIndex: index,
88
278
  threadCount,
89
- async onStarted(worker) {
90
- // note that this can be called multiple times, once when started, and again when threads are restarted
91
- const ready = new Promise((resolve, reject) => {
92
- function onMessage(message) {
93
- if (message.type === 'child_started') {
94
- worker.removeListener('message', onMessage);
95
- resolve(worker);
96
- }
279
+ application,
280
+ heapShareCount,
281
+ shouldAutoRestart: application
282
+ ? () => isolatedSlot !== undefined && isolatedSlots.get(application) === isolatedSlot
283
+ : undefined,
284
+ onStarted(worker) {
285
+ const attempt = ++startupAttempts;
286
+ const threadId = (lastThreadId = worker.threadId);
287
+ let startupPhase = 'starting';
288
+ let workerReady = false;
289
+ let startupDiagnostic;
290
+ const removeWorker = () => {
291
+ const workerPosition = workers.indexOf(worker);
292
+ if (workerPosition > -1) workers.splice(workerPosition, 1);
293
+ };
294
+ const cleanupStartup = () => {
295
+ clearTimeout(startupDiagnostic);
296
+ worker.off('message', onMessage);
297
+ };
298
+ const describeStartup = (event) =>
299
+ `HTTP worker slot ${index}${application ? ` (isolated application '${application}')` : ''} ${event} before ready (thread ${threadId}, attempt ${attempt}, phase ${startupPhase})`;
300
+ const onMessage = (message) => {
301
+ if (message.type === hdbTerms.ITC_EVENT_TYPES.CHILD_STARTUP_PHASE) {
302
+ startupPhase = message.phase;
303
+ return;
97
304
  }
98
-
99
- worker.on('message', onMessage);
100
- worker.on('error', reject);
101
- });
102
- workersReady.push(ready);
103
- await ready;
104
- workers.push(worker);
105
- worker.on('exit', removeWorker);
106
- worker.on('shutdown', removeWorker);
107
- function removeWorker() {
108
- const index = workers.indexOf(worker);
109
- if (index > -1) workers.splice(index, 1);
305
+ if (message.type !== hdbTerms.ITC_EVENT_TYPES.CHILD_STARTED) return;
306
+ workerReady = true;
307
+ cleanupStartup();
308
+ if (waitingForInitialReady) {
309
+ waitingForInitialReady = false;
310
+ resolveReady();
311
+ }
312
+ if (!workers.includes(worker)) workers.push(worker);
313
+ worker.on('shutdown', removeWorker);
314
+ };
315
+ const onExit = () => {
316
+ cleanupStartup();
317
+ if (workerReady) removeWorker();
318
+ // A rolling restart marks both the outgoing worker and its still-booting replacement
319
+ // wasShutdown, so a shutdown landing mid-boot is routine, not a startup failure.
320
+ else if (!worker.wasShutdown) harperLogger.error(describeStartup('exited'));
321
+ };
322
+ worker.on('message', onMessage);
323
+ worker.on('exit', onExit);
324
+ if (waitingForInitialReady) {
325
+ startupDiagnostic = setTimeout(() => {
326
+ if (workerReady || !waitingForInitialReady) return;
327
+ const message = describeStartup(`has not become ready after ${HTTP_WORKER_STARTUP_DIAGNOSTIC_MS}ms`);
328
+ harperLogger.error(message);
329
+ }, HTTP_WORKER_STARTUP_DIAGNOSTIC_MS).unref();
330
+ finishCurrentStartup = cleanupStartup;
110
331
  }
111
332
  },
112
- });
333
+ onRestartExhausted() {
334
+ const error = new Error(`HTTP worker slot ${index} exhausted restarts (thread ${lastThreadId})`);
335
+ if (waitingForInitialReady) failStartup(error);
336
+ else if (application && isolatedSlot && isolatedSlots.get(application) === isolatedSlot) {
337
+ isolatedSlots.delete(application);
338
+ componentLifecycle.failed(application, error, `Component '${application}' worker failed`);
339
+ void import('../http.ts').then(
340
+ ({ cleanupApplicationSockets }) => {
341
+ // A config reconciliation may already have installed a replacement after the
342
+ // exhausted slot released its lease. Never unlink that replacement's mirror.
343
+ if (isolatedSlots.has(application)) return;
344
+ cleanupApplicationSockets(application);
345
+ },
346
+ (cleanupError) => {
347
+ harperLogger.error(
348
+ `Could not clean sockets for failed isolated application '${application}'`,
349
+ cleanupError
350
+ );
351
+ }
352
+ );
353
+ }
354
+ },
355
+ };
356
+ startWorker(join(__dirname, './threadServer.js'), workerOptions);
357
+ // Stop of a dedicated worker whose application is gone: every worker carrying the application,
358
+ // a crashed one's replacement still booting included, so none is left running the removed app.
359
+ let shutdownPromise: Promise<void> | undefined;
360
+ const shutdown = (): Promise<void> => {
361
+ if (!application) return Promise.resolve();
362
+ if (shutdownPromise) return shutdownPromise;
363
+ shutdownPromise = Promise.all(workersForApplication(application).map((worker) => stopWorker(worker))).then(
364
+ () => undefined
365
+ );
366
+ failStartup(new Error(`Dedicated worker for '${application}' was stopped before it became ready`));
367
+ return shutdownPromise;
368
+ };
369
+ const setHeapShareCount = (count: number) => {
370
+ workerOptions.heapShareCount = count;
371
+ };
372
+ isolatedSlot = { ready, finishStartup, shutdown, setHeapShareCount, application };
373
+ return isolatedSlot;
113
374
  }
114
375
 
115
376
  // basically, the amount of additional idleness to expect based on previous idleness (some work will continue, some
@@ -0,0 +1,26 @@
1
+ import harperLogger from '../../utility/logging/harper_logger.ts';
2
+ import { MIN_THREAD_HEAP_MEMORY_MB } from '../../utility/hdbTerms.ts';
3
+
4
+ let recoveryWarned = false;
5
+
6
+ export function isStartableThreadHeapMemory(configuredMb: unknown): boolean {
7
+ return Number.isFinite(configuredMb) && (configuredMb as number) >= MIN_THREAD_HEAP_MEMORY_MB;
8
+ }
9
+
10
+ // Below the minimum, Node aborts the whole process from v8::Isolate::Initialize before any
11
+ // JavaScript runs, so this has to be caught ahead of startWorker — no error handler downstream can
12
+ // contain it. The value on disk is an untrusted boot input (replicated, env var, hand edit, older
13
+ // peer), so an unstartable one falls back to the caller's computed default rather than stopping the
14
+ // node.
15
+ export function resolveThreadHeapMemoryMb(configured: unknown): number | undefined {
16
+ if (configured == null) return undefined;
17
+ const configuredMb = Number(configured);
18
+ if (isStartableThreadHeapMemory(configuredMb)) return configuredMb;
19
+ if (!recoveryWarned) {
20
+ recoveryWarned = true;
21
+ harperLogger.error(
22
+ `Ignoring threads.maxHeapMemory: ${JSON.stringify(configured)} is below the ${MIN_THREAD_HEAP_MEMORY_MB}MB a worker thread can start on. Using the default instead; replace the configured value before downgrading.`
23
+ );
24
+ }
25
+ return undefined;
26
+ }
@@ -26,6 +26,11 @@ const {
26
26
  getShutdownDrainCeilingMs,
27
27
  } = require('../../components/shutdownDrain.ts');
28
28
  const { realExit } = require('./workerProcessGuard.ts');
29
+ const {
30
+ thisThreadsIsolatedApplication,
31
+ applicationSocketName,
32
+ shouldStartUwsListenerHere,
33
+ } = require('./isolatedApplications.ts');
29
34
  const { isBun } = require('../serverHelpers/Request.ts');
30
35
  const { getDomainSocketPathMaxBytes, isDomainSocketPathTooLong } = require('../../utility/domainSocket.ts');
31
36
  const { createTLSSelector, getEffectiveTlsCiphers } = require('../../security/keys.ts');
@@ -169,6 +174,22 @@ function closeServers() {
169
174
  }
170
175
 
171
176
  function startServers() {
177
+ // A worker that has not yet posted child_started owns no ref'd handle: addPort()
178
+ // (manageThreads) unrefs parentPort, component watchers are persistent:false, and the
179
+ // reporting timers are unref'd. An await inside loadRootComponents whose completion
180
+ // arrives through a non-ref-holding source — e.g. rocksdb-js delivers cross-thread
181
+ // lock-release and parked-commit-retry wakes through unref'd threadsafe functions —
182
+ // can then drain the event loop, exiting the worker cleanly (code 0) before the ready
183
+ // handshake and aborting the whole node's startup. Hold a ref for the entire pre-ready
184
+ // window; the SHUTDOWN path unrefs it for graceful exit as before.
185
+ parentPort?.ref();
186
+ let startupPhase = 'loading components';
187
+ const reportStartupPhase = (phase) => {
188
+ startupPhase = phase;
189
+ try {
190
+ parentPort?.postMessage({ type: terms.ITC_EVENT_TYPES.CHILD_STARTUP_PHASE, phase });
191
+ } catch {}
192
+ };
172
193
  const rootPath = env.get(terms.CONFIG_PARAMS.ROOTPATH);
173
194
  if (rootPath) {
174
195
  try {
@@ -177,7 +198,9 @@ function startServers() {
177
198
  // ignore any errors with this; just a best effort for now
178
199
  }
179
200
  }
180
- let loaded = require('../loadRootComponents.js')
201
+ reportStartupPhase(startupPhase);
202
+ let listening;
203
+ const loaded = require('../loadRootComponents.js')
181
204
  .loadRootComponents(true)
182
205
  .then(() => {
183
206
  parentPort
@@ -207,6 +230,7 @@ function startServers() {
207
230
  })
208
231
  .then(() => closeServers())
209
232
  .then(() => whenScopesClosed())
233
+ .then(() => require('../../resources/databases.ts').closeBranchDatabases())
210
234
  .then(() => {
211
235
  realExit(0);
212
236
  });
@@ -222,21 +246,30 @@ function startServers() {
222
246
  }
223
247
  })
224
248
  .ref(); // use this to keep the thread running until we are ready to shutdown and clean up handles
225
- const listening = listenOnPorts();
226
-
227
- // notify that we are now ready to start receiving requests
228
- Promise.resolve(listening).then(() => {
229
- if (getWorkerIndex() === 0) {
230
- try {
231
- startupLog(portServer);
232
- } catch (err) {
233
- console.error('Error displaying start-up log', err);
234
- }
235
- }
236
- parentPort?.postMessage({ type: terms.ITC_EVENT_TYPES.CHILD_STARTED });
237
- });
249
+ reportStartupPhase('binding listeners');
250
+ listening = listenOnPorts();
238
251
  });
239
252
  componentsLoadedResolve(loaded);
253
+ const started = loaded
254
+ .then(() => listening)
255
+ .then(() => {
256
+ reportStartupPhase('ready');
257
+ if (getWorkerIndex() === 0) {
258
+ try {
259
+ startupLog(portServer);
260
+ } catch (err) {
261
+ console.error('Error displaying start-up log', err);
262
+ }
263
+ }
264
+ parentPort?.postMessage({ type: terms.ITC_EVENT_TYPES.CHILD_STARTED });
265
+ })
266
+ .catch((error) => {
267
+ const failedPhase = startupPhase;
268
+ reportStartupPhase(`failed during ${failedPhase}`);
269
+ harperLogger.fatal(`HTTP worker startup failed during ${failedPhase}`, error);
270
+ if (isMainThread) throw error;
271
+ realExit(1);
272
+ });
240
273
  // Clean up UDS files and force-close Bun server connections on unexpected exit.
241
274
  // Without the stop(true) call, clients holding keep-alive connections to a dead Bun
242
275
  // worker never receive a FIN/RST and hang indefinitely waiting for a response.
@@ -253,7 +286,7 @@ function startServers() {
253
286
  }
254
287
  httpComponent.cleanupUdsFiles();
255
288
  });
256
- return loaded;
289
+ return started;
257
290
  }
258
291
  /**
259
292
  * An overlong path is the only condition that can skip a domain-socket listener. Check before
@@ -302,10 +335,15 @@ function listenOnPorts() {
302
335
  const server = SERVERS[port];
303
336
 
304
337
  // If server is unix domain socket
338
+ // A worker dedicated to an isolated application binds only its own per-thread mirrors: not the shared
339
+ // ports (the kernel would hand it every application's connections) and not a global domain socket
340
+ // such as the operations API's, which it would take from the main thread.
305
341
  if (port.includes?.('/')) {
306
- listening.push(listenOnDomainSocket(port, server));
342
+ if (!thisThreadsIsolatedApplication() || server.isPerThreadSocket)
343
+ listening.push(listenOnDomainSocket(port, server));
307
344
  continue;
308
345
  }
346
+ if (thisThreadsIsolatedApplication()) continue;
309
347
  let listen_on;
310
348
  let ownerWorkerIndex = 0; // lowest eligible worker index for this port
311
349
  const threadRange = env.get(terms.CONFIG_PARAMS.HTTP_THREADRANGE);
@@ -378,6 +416,7 @@ function listenOnPorts() {
378
416
  if (uwsServeConfigs) {
379
417
  for (const key in uwsServeConfigs) {
380
418
  const cfg = uwsServeConfigs[key];
419
+ if (!shouldStartUwsListenerHere(cfg)) continue; // dedicated worker: its own mirrors only
381
420
  if (cfg.socketPath && existsSync(cfg.socketPath)) unlinkSync(cfg.socketPath);
382
421
  const { createUwsServer } = require('../serverHelpers/uwsServer.ts');
383
422
  listening.push(
@@ -427,7 +466,7 @@ async function listenOnPortsBun() {
427
466
  for (let port in bunServeConfigs) {
428
467
  const config = bunServeConfigs[port];
429
468
  const threadRange = env.get(terms.CONFIG_PARAMS.HTTP_THREADRANGE);
430
- if (threadRange) {
469
+ if (threadRange && !thisThreadsIsolatedApplication()) {
431
470
  let threadRangeArray = typeof threadRange === 'string' ? threadRange.split('-') : threadRange;
432
471
  let threadIndex = getWorkerIndex();
433
472
  if (threadIndex < threadRangeArray[0] || threadIndex > threadRangeArray[1]) {
@@ -504,15 +543,22 @@ async function listenOnPortsBun() {
504
543
  delete serveOptions.port;
505
544
  }
506
545
  if (isNaN(serveOptions.port)) continue;
507
- const bunServer = Bun.serve(serveOptions);
508
- SERVERS[port] = bunServer;
509
- harperLogger.trace('Bun listening on port ' + port, threadId);
546
+ // Keep ownership independent of address syntax: adding a Bun UDS route later must not widen
547
+ // a dedicated worker's ingress beyond its application-addressed mirror below.
548
+ if (!thisThreadsIsolatedApplication()) {
549
+ const bunServer = Bun.serve(serveOptions);
550
+ SERVERS[port] = bunServer;
551
+ harperLogger.trace('Bun listening on port ' + port, threadId);
552
+ }
510
553
 
511
554
  // Create a corresponding Unix Domain Socket mirror for secure ports
512
555
  if (config.isSecure && env.get(terms.CONFIG_PARAMS.TLS_UNIXDOMAINSOCKETS)) {
513
556
  const socketsDir = join(env.getHdbBasePath(), 'sockets');
514
557
  mkdirSync(socketsDir, { recursive: true });
515
- const socketName = `${getWorkerIndex()}-${port}`;
558
+ const isolatedApplication = thisThreadsIsolatedApplication();
559
+ const socketName = isolatedApplication
560
+ ? applicationSocketName(isolatedApplication, port)
561
+ : `${getWorkerIndex()}-${port}`;
516
562
  const udsPath = join(socketsDir, `${socketName}.sock`);
517
563
  const yamlPath = join(socketsDir, `${socketName}.yaml`);
518
564
  if (existsSync(udsPath)) unlinkSync(udsPath);
@@ -536,6 +582,7 @@ async function listenOnPortsBun() {
536
582
  }
537
583
  } catch (error) {
538
584
  harperLogger.error(`Unable to start Bun server on port ${port}`, error);
585
+ if (thisThreadsIsolatedApplication()) throw error;
539
586
  }
540
587
  }
541
588
  // Also start any non-HTTP servers (raw socket servers) that were registered in SERVERS
@@ -546,6 +593,7 @@ async function listenOnPortsBun() {
546
593
  if (server?.stop || bunServeConfigs[port]) continue;
547
594
  if (server?.listen) {
548
595
  if (port.includes?.('/')) {
596
+ if (thisThreadsIsolatedApplication() && !server.isPerThreadSocket) continue; // as in listenOnPorts
549
597
  listening.push(listenOnDomainSocket(port, server));
550
598
  } else {
551
599
  const lastColon = String(port).lastIndexOf(':');
@@ -645,7 +693,10 @@ function onSocket(listener, options) {
645
693
  if (env.get(terms.CONFIG_PARAMS.TLS_UNIXDOMAINSOCKETS)) {
646
694
  const socketsDir = join(env.getHdbBasePath(), 'sockets');
647
695
  mkdirSync(socketsDir, { recursive: true });
648
- const socketName = `${getWorkerIndex()}-${options.securePort}`;
696
+ const isolatedApplication = thisThreadsIsolatedApplication();
697
+ const socketName = isolatedApplication
698
+ ? applicationSocketName(isolatedApplication, options.securePort)
699
+ : `${getWorkerIndex()}-${options.securePort}`;
649
700
  const udsPath = join(socketsDir, `${socketName}.sock`);
650
701
  const yamlPath = join(socketsDir, `${socketName}.yaml`);
651
702
 
@@ -17,7 +17,7 @@ import * as terms from '../utility/hdbTerms.ts';
17
17
  import { handleHDBError } from '../utility/errors/hdbError.ts';
18
18
  import { HTTP_STATUS_CODES } from '../utility/errors/commonErrors.ts';
19
19
  import * as sqlEngineRouter from '../sqlEngine/router.ts';
20
- import { isOperationAuthorizationBypassed } from '../server/serverHelpers/operationAuthorizationState.ts';
20
+ import { getOperationAuthorizationState } from '../server/serverHelpers/operationAuthorizationState.ts';
21
21
 
22
22
  //here we call to define and import custom functions to alasql
23
23
  alasqlFunctionImporter(alasql);
@@ -73,21 +73,37 @@ export function evaluateSQL(jsonMessage: any, callback: any) {
73
73
  * @param parsedSqlObject - The Parsed SQL statement specified in the inbound json message, of type ParsedSQLObject.
74
74
  * @returns {Array} - False if permissions check denys the statement.
75
75
  */
76
- export function checkASTPermissions(jsonMessage: any, parsedSqlObject: any) {
76
+ export function checkASTPermissions(jsonMessage: any, parsedSqlObject: any, apiOperation?: string) {
77
77
  let verifyResult = undefined;
78
78
  try {
79
79
  verifyResult = opAuth.verifyPermsAST(
80
80
  parsedSqlObject.ast.statements[0],
81
81
  jsonMessage.hdb_user,
82
- parsedSqlObject.variant
82
+ parsedSqlObject.variant,
83
+ // The top-level API operation for the token-scope check: `sql` for a direct SQL call, but
84
+ // `export_local`/`export_to_s3` when the SQL rides inside a job's search_operation.
85
+ //
86
+ // From the explicit argument or the dispatched operation — deliberately NEVER a field read
87
+ // off `jsonMessage`. On the direct-SQL path that object IS the client's request body, and
88
+ // this check is the ONLY gate there, since the `sql` branch of chooseOperation is mutually
89
+ // exclusive with its verifyPerms call. Any body field consulted here is therefore a way for
90
+ // a caller to name whichever operation their token scope happens to allow and run arbitrary
91
+ // SQL under it.
92
+ //
93
+ // A job's re-parse would otherwise land here with the nested search_operation, whose
94
+ // `operation` is the inner `sql`; the job worker supplies the real one out of async context
95
+ // instead (operationAuthorizationState), which a request cannot set.
96
+ apiOperation ?? jsonMessage.operation
83
97
  );
84
- parsedSqlObject.permissions_checked = true;
85
98
  } catch (e) {
86
99
  throw e;
87
100
  }
88
101
  if (verifyResult) {
89
102
  return verifyResult;
90
103
  }
104
+ // Only after a pass: this flag is what processAST trusts to skip the gate, so a denied AST
105
+ // carrying it would read as already authorized.
106
+ parsedSqlObject.permissions_checked = true;
91
107
  return null;
92
108
  }
93
109
 
@@ -134,10 +150,17 @@ export function processAST(jsonMessage: any, parsedSqlObject: any, callback: any
134
150
  // runWithOperationAuthorizationBypass), never body state — jsonMessage.bypass_auth is
135
151
  // caller-controlled and is stripped before operation code sees it (see
136
152
  // server/serverHelpers/serverHandlers.js and components/mcp/tools/operations.ts).
137
- if (!isOperationAuthorizationBypassed() && !parsedSqlObject.permissions_checked) {
138
- let permissionsCheck = checkASTPermissions(jsonMessage, parsedSqlObject);
139
- if (permissionsCheck && permissionsCheck.length > 0) {
140
- return callback(UNAUTHORIZED_RESPONSE, permissionsCheck);
153
+ if (!parsedSqlObject.permissions_checked) {
154
+ const authorizationState = getOperationAuthorizationState();
155
+ if (authorizationState?.bypassAuth !== true) {
156
+ let permissionsCheck = checkASTPermissions(jsonMessage, parsedSqlObject, authorizationState?.apiOperation);
157
+ // A denial is a PermissionResponseObject, which has no `length`.
158
+ if (permissionsCheck) {
159
+ // Logged here because this is the last place the reason exists: evaluateSQL drops the
160
+ // second callback argument, so a job worker records only the bare status.
161
+ logger.warn('SQL statement refused by AST permission check:', permissionsCheck);
162
+ return callback(UNAUTHORIZED_RESPONSE, permissionsCheck);
163
+ }
141
164
  }
142
165
  }
143
166