@harperfast/harper 5.2.9 → 5.3.0-alpha.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 (668) hide show
  1. package/agent/mcpTools.ts +1 -1
  2. package/agent/session.ts +25 -14
  3. package/bin/cliOperations.ts +46 -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 +59 -3
  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 +2414 -242
  14. package/components/ApplicationScope.ts +8 -0
  15. package/components/EntryHandler.ts +59 -39
  16. package/components/OptionsWatcher.ts +150 -74
  17. package/components/RuntimeModuleTracker.ts +38 -7
  18. package/components/Scope.ts +37 -15
  19. package/components/awaitRestart.ts +84 -0
  20. package/components/componentLoader.ts +340 -30
  21. package/components/componentPreparationLock.ts +16 -5
  22. package/components/mcp/adapters/harperHttp.ts +4 -0
  23. package/components/mcp/listChanged.ts +4 -0
  24. package/components/mcp/toolRegistry.ts +2 -0
  25. package/components/mcp/tools/operations.ts +9 -0
  26. package/components/mcp/tools/schemas/operationDescriptions.ts +2 -2
  27. package/components/operations.js +270 -78
  28. package/components/operationsValidation.js +49 -1
  29. package/components/status/ComponentStatusRegistry.ts +59 -0
  30. package/config/RootConfigWatcher.ts +80 -34
  31. package/config/configUtils.ts +291 -34
  32. package/config/harperConfigEnvVars.ts +170 -27
  33. package/config-root.schema.json +29 -0
  34. package/dataLayer/blobBackup.ts +160 -50
  35. package/dataLayer/delete.ts +6 -1
  36. package/dataLayer/harperBridge/ResourceBridge.ts +52 -8
  37. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js +3 -1
  38. package/dataLayer/hdbInfoController.ts +34 -1
  39. package/dataLayer/insert.ts +44 -1
  40. package/dataLayer/rocksdbBackup.ts +53 -10
  41. package/dataLayer/schema.ts +11 -1
  42. package/dataLayer/schemaDescribe.ts +8 -1
  43. package/dist/agent/mcpTools.js +1 -1
  44. package/dist/agent/mcpTools.js.map +1 -1
  45. package/dist/agent/session.d.ts +22 -0
  46. package/dist/agent/session.js +26 -15
  47. package/dist/agent/session.js.map +1 -1
  48. package/dist/bin/cliOperations.js +48 -9
  49. package/dist/bin/cliOperations.js.map +1 -1
  50. package/dist/bin/copyDb.d.ts +12 -1
  51. package/dist/bin/copyDb.js +248 -60
  52. package/dist/bin/copyDb.js.map +1 -1
  53. package/dist/bin/deploySetup.d.ts +2 -0
  54. package/dist/bin/deploySetup.js +11 -3
  55. package/dist/bin/deploySetup.js.map +1 -1
  56. package/dist/bin/harper.js +1 -1
  57. package/dist/bin/harper.js.map +1 -1
  58. package/dist/bin/help.js +4 -1
  59. package/dist/bin/help.js.map +1 -1
  60. package/dist/bin/lite.js +4 -1
  61. package/dist/bin/lite.js.map +1 -1
  62. package/dist/bin/restart.js +54 -5
  63. package/dist/bin/restart.js.map +1 -1
  64. package/dist/bin/run.js +4 -10
  65. package/dist/bin/run.js.map +1 -1
  66. package/dist/bin/upgrade.js +4 -3
  67. package/dist/bin/upgrade.js.map +1 -1
  68. package/dist/bin/workloadIdentity.d.ts +18 -0
  69. package/dist/bin/workloadIdentity.js +100 -0
  70. package/dist/bin/workloadIdentity.js.map +1 -0
  71. package/dist/components/Application.d.ts +139 -16
  72. package/dist/components/Application.js +2215 -267
  73. package/dist/components/Application.js.map +1 -1
  74. package/dist/components/ApplicationScope.d.ts +8 -0
  75. package/dist/components/ApplicationScope.js +7 -0
  76. package/dist/components/ApplicationScope.js.map +1 -1
  77. package/dist/components/EntryHandler.js +26 -10
  78. package/dist/components/EntryHandler.js.map +1 -1
  79. package/dist/components/OptionsWatcher.d.ts +1 -0
  80. package/dist/components/OptionsWatcher.js +141 -74
  81. package/dist/components/OptionsWatcher.js.map +1 -1
  82. package/dist/components/RuntimeModuleTracker.js +40 -6
  83. package/dist/components/RuntimeModuleTracker.js.map +1 -1
  84. package/dist/components/Scope.js +38 -13
  85. package/dist/components/Scope.js.map +1 -1
  86. package/dist/components/awaitRestart.d.ts +33 -0
  87. package/dist/components/awaitRestart.js +61 -0
  88. package/dist/components/awaitRestart.js.map +1 -0
  89. package/dist/components/componentLoader.d.ts +38 -1
  90. package/dist/components/componentLoader.js +279 -22
  91. package/dist/components/componentLoader.js.map +1 -1
  92. package/dist/components/componentPreparationLock.d.ts +5 -0
  93. package/dist/components/componentPreparationLock.js +14 -6
  94. package/dist/components/componentPreparationLock.js.map +1 -1
  95. package/dist/components/mcp/adapters/harperHttp.js +4 -0
  96. package/dist/components/mcp/adapters/harperHttp.js.map +1 -1
  97. package/dist/components/mcp/listChanged.js +5 -0
  98. package/dist/components/mcp/listChanged.js.map +1 -1
  99. package/dist/components/mcp/toolRegistry.d.ts +1 -0
  100. package/dist/components/mcp/toolRegistry.js.map +1 -1
  101. package/dist/components/mcp/tools/operations.d.ts +5 -0
  102. package/dist/components/mcp/tools/operations.js +9 -0
  103. package/dist/components/mcp/tools/operations.js.map +1 -1
  104. package/dist/components/mcp/tools/schemas/operationDescriptions.js +2 -2
  105. package/dist/components/mcp/tools/schemas/operationDescriptions.js.map +1 -1
  106. package/dist/components/operations.js +231 -77
  107. package/dist/components/operations.js.map +1 -1
  108. package/dist/components/operationsValidation.js +49 -1
  109. package/dist/components/operationsValidation.js.map +1 -1
  110. package/dist/components/status/ComponentStatusRegistry.d.ts +0 -4
  111. package/dist/components/status/ComponentStatusRegistry.js +63 -0
  112. package/dist/components/status/ComponentStatusRegistry.js.map +1 -1
  113. package/dist/config/RootConfigWatcher.d.ts +7 -1
  114. package/dist/config/RootConfigWatcher.js +64 -27
  115. package/dist/config/RootConfigWatcher.js.map +1 -1
  116. package/dist/config/configUtils.d.ts +9 -1
  117. package/dist/config/configUtils.js +254 -33
  118. package/dist/config/configUtils.js.map +1 -1
  119. package/dist/config/harperConfigEnvVars.d.ts +16 -0
  120. package/dist/config/harperConfigEnvVars.js +162 -25
  121. package/dist/config/harperConfigEnvVars.js.map +1 -1
  122. package/dist/dataLayer/blobBackup.d.ts +49 -20
  123. package/dist/dataLayer/blobBackup.js +139 -50
  124. package/dist/dataLayer/blobBackup.js.map +1 -1
  125. package/dist/dataLayer/delete.js +1 -1
  126. package/dist/dataLayer/delete.js.map +1 -1
  127. package/dist/dataLayer/harperBridge/ResourceBridge.d.ts +14 -1
  128. package/dist/dataLayer/harperBridge/ResourceBridge.js +51 -10
  129. package/dist/dataLayer/harperBridge/ResourceBridge.js.map +1 -1
  130. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.d.ts +3 -1
  131. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js +3 -1
  132. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js.map +1 -1
  133. package/dist/dataLayer/hdbInfoController.d.ts +10 -0
  134. package/dist/dataLayer/hdbInfoController.js +30 -1
  135. package/dist/dataLayer/hdbInfoController.js.map +1 -1
  136. package/dist/dataLayer/insert.d.ts +9 -1
  137. package/dist/dataLayer/insert.js +30 -0
  138. package/dist/dataLayer/insert.js.map +1 -1
  139. package/dist/dataLayer/rocksdbBackup.d.ts +2 -2
  140. package/dist/dataLayer/rocksdbBackup.js +45 -8
  141. package/dist/dataLayer/rocksdbBackup.js.map +1 -1
  142. package/dist/dataLayer/schema.js +8 -0
  143. package/dist/dataLayer/schema.js.map +1 -1
  144. package/dist/dataLayer/schemaDescribe.js +8 -1
  145. package/dist/dataLayer/schemaDescribe.js.map +1 -1
  146. package/dist/index.d.ts +1 -1
  147. package/dist/index.js.map +1 -1
  148. package/dist/json/systemSchema.json +52 -0
  149. package/dist/resources/DatabaseTransaction.d.ts +55 -0
  150. package/dist/resources/DatabaseTransaction.js +459 -45
  151. package/dist/resources/DatabaseTransaction.js.map +1 -1
  152. package/dist/resources/LMDBTransaction.js +22 -4
  153. package/dist/resources/LMDBTransaction.js.map +1 -1
  154. package/dist/resources/PrimaryRocksDatabase.d.ts +1 -0
  155. package/dist/resources/PrimaryRocksDatabase.js +29 -0
  156. package/dist/resources/PrimaryRocksDatabase.js.map +1 -1
  157. package/dist/resources/RecordEncoder.d.ts +20 -0
  158. package/dist/resources/RecordEncoder.js +94 -9
  159. package/dist/resources/RecordEncoder.js.map +1 -1
  160. package/dist/resources/RequestTarget.d.ts +2 -0
  161. package/dist/resources/RequestTarget.js.map +1 -1
  162. package/dist/resources/Resource.js +20 -11
  163. package/dist/resources/Resource.js.map +1 -1
  164. package/dist/resources/ResourceInterface.d.ts +20 -1
  165. package/dist/resources/ResourceInterface.js.map +1 -1
  166. package/dist/resources/RocksIndexStore.d.ts +6 -1
  167. package/dist/resources/RocksIndexStore.js +24 -9
  168. package/dist/resources/RocksIndexStore.js.map +1 -1
  169. package/dist/resources/RocksTransactionLogStore.d.ts +14 -1
  170. package/dist/resources/RocksTransactionLogStore.js +57 -17
  171. package/dist/resources/RocksTransactionLogStore.js.map +1 -1
  172. package/dist/resources/Table.d.ts +112 -8
  173. package/dist/resources/Table.js +1073 -191
  174. package/dist/resources/Table.js.map +1 -1
  175. package/dist/resources/auditStore.d.ts +11 -2
  176. package/dist/resources/auditStore.js +325 -71
  177. package/dist/resources/auditStore.js.map +1 -1
  178. package/dist/resources/blob.d.ts +129 -9
  179. package/dist/resources/blob.js +992 -114
  180. package/dist/resources/blob.js.map +1 -1
  181. package/dist/resources/branchDatabase.d.ts +48 -0
  182. package/dist/resources/branchDatabase.js +892 -0
  183. package/dist/resources/branchDatabase.js.map +1 -0
  184. package/dist/resources/crdt.js +50 -12
  185. package/dist/resources/crdt.js.map +1 -1
  186. package/dist/resources/databases.d.ts +150 -0
  187. package/dist/resources/databases.js +1200 -239
  188. package/dist/resources/databases.js.map +1 -1
  189. package/dist/resources/defineTable.d.ts +10 -2
  190. package/dist/resources/defineTable.js +9 -1
  191. package/dist/resources/defineTable.js.map +1 -1
  192. package/dist/resources/graphql.d.ts +1 -1
  193. package/dist/resources/graphql.js +50 -15
  194. package/dist/resources/graphql.js.map +1 -1
  195. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.d.ts +1 -0
  196. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js +6 -2
  197. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js.map +1 -1
  198. package/dist/resources/longLivedTransactions.d.ts +71 -0
  199. package/dist/resources/longLivedTransactions.js +358 -0
  200. package/dist/resources/longLivedTransactions.js.map +1 -0
  201. package/dist/resources/models/backendRegistry.d.ts +26 -0
  202. package/dist/resources/models/backendRegistry.js +60 -2
  203. package/dist/resources/models/backendRegistry.js.map +1 -1
  204. package/dist/resources/models/bootstrap.d.ts +33 -1
  205. package/dist/resources/models/bootstrap.js +416 -31
  206. package/dist/resources/models/bootstrap.js.map +1 -1
  207. package/dist/resources/recordLock.d.ts +80 -0
  208. package/dist/resources/recordLock.js +184 -0
  209. package/dist/resources/recordLock.js.map +1 -0
  210. package/dist/resources/replayLogs.d.ts +14 -1
  211. package/dist/resources/replayLogs.js +152 -24
  212. package/dist/resources/replayLogs.js.map +1 -1
  213. package/dist/resources/replayLogsGuards.d.ts +94 -7
  214. package/dist/resources/replayLogsGuards.js +111 -7
  215. package/dist/resources/replayLogsGuards.js.map +1 -1
  216. package/dist/resources/search.js +158 -6
  217. package/dist/resources/search.js.map +1 -1
  218. package/dist/resources/transactionBroadcast.d.ts +1 -1
  219. package/dist/resources/transactionBroadcast.js +2 -2
  220. package/dist/resources/transactionBroadcast.js.map +1 -1
  221. package/dist/security/auth.js +61 -30
  222. package/dist/security/auth.js.map +1 -1
  223. package/dist/security/authn/oidc/claims.d.ts +22 -0
  224. package/dist/security/authn/oidc/claims.js +71 -0
  225. package/dist/security/authn/oidc/claims.js.map +1 -0
  226. package/dist/security/authn/oidc/identityToken.d.ts +27 -0
  227. package/dist/security/authn/oidc/identityToken.js +111 -0
  228. package/dist/security/authn/oidc/identityToken.js.map +1 -0
  229. package/dist/security/authn/oidc/jwks.d.ts +25 -0
  230. package/dist/security/authn/oidc/jwks.js +261 -0
  231. package/dist/security/authn/oidc/jwks.js.map +1 -0
  232. package/dist/security/authn/oidc/providers/generic.d.ts +13 -0
  233. package/dist/security/authn/oidc/providers/generic.js +34 -0
  234. package/dist/security/authn/oidc/providers/generic.js.map +1 -0
  235. package/dist/security/authn/oidc/providers/githubActions.d.ts +11 -0
  236. package/dist/security/authn/oidc/providers/githubActions.js +129 -0
  237. package/dist/security/authn/oidc/providers/githubActions.js.map +1 -0
  238. package/dist/security/authn/oidc/providers/index.d.ts +37 -0
  239. package/dist/security/authn/oidc/providers/index.js +24 -0
  240. package/dist/security/authn/oidc/providers/index.js.map +1 -0
  241. package/dist/security/authn/oidc/tokenExchange.d.ts +12 -0
  242. package/dist/security/authn/oidc/tokenExchange.js +306 -0
  243. package/dist/security/authn/oidc/tokenExchange.js.map +1 -0
  244. package/dist/security/authn/oidc/trustPolicyOperations.d.ts +49 -0
  245. package/dist/security/authn/oidc/trustPolicyOperations.js +358 -0
  246. package/dist/security/authn/oidc/trustPolicyOperations.js.map +1 -0
  247. package/dist/security/authn/oidc/types.d.ts +38 -0
  248. package/dist/security/authn/oidc/types.js +6 -0
  249. package/dist/security/authn/oidc/types.js.map +1 -0
  250. package/dist/security/certificateVerification/index.js +40 -11
  251. package/dist/security/certificateVerification/index.js.map +1 -1
  252. package/dist/security/certificateVerification/trustedIssuers.d.ts +24 -0
  253. package/dist/security/certificateVerification/trustedIssuers.js +79 -0
  254. package/dist/security/certificateVerification/trustedIssuers.js.map +1 -0
  255. package/dist/security/certificateVerification/types.d.ts +1 -0
  256. package/dist/security/credentialProvenance.d.ts +35 -0
  257. package/dist/security/credentialProvenance.js +51 -0
  258. package/dist/security/credentialProvenance.js.map +1 -0
  259. package/dist/security/credentialRejection.d.ts +4 -0
  260. package/dist/security/credentialRejection.js +24 -0
  261. package/dist/security/credentialRejection.js.map +1 -0
  262. package/dist/security/deferredAuthentication.d.ts +36 -0
  263. package/dist/security/deferredAuthentication.js +70 -0
  264. package/dist/security/deferredAuthentication.js.map +1 -0
  265. package/dist/security/impersonation.d.ts +21 -0
  266. package/dist/security/impersonation.js +108 -9
  267. package/dist/security/impersonation.js.map +1 -1
  268. package/dist/security/jsLoader.d.ts +6 -0
  269. package/dist/security/jsLoader.js +75 -15
  270. package/dist/security/jsLoader.js.map +1 -1
  271. package/dist/security/keys.js +301 -71
  272. package/dist/security/keys.js.map +1 -1
  273. package/dist/security/operationScope.d.ts +21 -0
  274. package/dist/security/operationScope.js +36 -0
  275. package/dist/security/operationScope.js.map +1 -0
  276. package/dist/security/permissionsTranslator.js +21 -0
  277. package/dist/security/permissionsTranslator.js.map +1 -1
  278. package/dist/security/tokenAuthentication.d.ts +19 -1
  279. package/dist/security/tokenAuthentication.js +191 -10
  280. package/dist/security/tokenAuthentication.js.map +1 -1
  281. package/dist/security/user.js +4 -3
  282. package/dist/security/user.js.map +1 -1
  283. package/dist/server/DurableSubscriptionsSession.d.ts +2 -2
  284. package/dist/server/DurableSubscriptionsSession.js +67 -10
  285. package/dist/server/DurableSubscriptionsSession.js.map +1 -1
  286. package/dist/server/REST.js +73 -0
  287. package/dist/server/REST.js.map +1 -1
  288. package/dist/server/graphqlQuerying.js +4 -0
  289. package/dist/server/graphqlQuerying.js.map +1 -1
  290. package/dist/server/http.d.ts +11 -0
  291. package/dist/server/http.js +88 -15
  292. package/dist/server/http.js.map +1 -1
  293. package/dist/server/itc/serverHandlers.js +8 -1
  294. package/dist/server/itc/serverHandlers.js.map +1 -1
  295. package/dist/server/jobs/jobProcess.js +6 -2
  296. package/dist/server/jobs/jobProcess.js.map +1 -1
  297. package/dist/server/jobs/jobs.js +4 -1
  298. package/dist/server/jobs/jobs.js.map +1 -1
  299. package/dist/server/liveSubscriptionAuth.d.ts +26 -4
  300. package/dist/server/liveSubscriptionAuth.js +105 -39
  301. package/dist/server/liveSubscriptionAuth.js.map +1 -1
  302. package/dist/server/loadRootComponents.js +49 -10
  303. package/dist/server/loadRootComponents.js.map +1 -1
  304. package/dist/server/mqtt.d.ts +2 -0
  305. package/dist/server/mqtt.js +165 -30
  306. package/dist/server/mqtt.js.map +1 -1
  307. package/dist/server/nodeName.d.ts +2 -0
  308. package/dist/server/nodeName.js +107 -23
  309. package/dist/server/nodeName.js.map +1 -1
  310. package/dist/server/serverHelpers/Headers.d.ts +25 -0
  311. package/dist/server/serverHelpers/Headers.js +139 -1
  312. package/dist/server/serverHelpers/Headers.js.map +1 -1
  313. package/dist/server/serverHelpers/contentTypes.d.ts +9 -0
  314. package/dist/server/serverHelpers/contentTypes.js +32 -25
  315. package/dist/server/serverHelpers/contentTypes.js.map +1 -1
  316. package/dist/server/serverHelpers/deployValidationState.d.ts +3 -0
  317. package/dist/server/serverHelpers/deployValidationState.js +9 -19
  318. package/dist/server/serverHelpers/deployValidationState.js.map +1 -1
  319. package/dist/server/serverHelpers/operationAuthorizationState.d.ts +12 -0
  320. package/dist/server/serverHelpers/operationAuthorizationState.js +24 -2
  321. package/dist/server/serverHelpers/operationAuthorizationState.js.map +1 -1
  322. package/dist/server/serverHelpers/registeredOperations.d.ts +5 -4
  323. package/dist/server/serverHelpers/registeredOperations.js +74 -21
  324. package/dist/server/serverHelpers/registeredOperations.js.map +1 -1
  325. package/dist/server/serverHelpers/requestSanitization.d.ts +11 -0
  326. package/dist/server/serverHelpers/requestSanitization.js +20 -0
  327. package/dist/server/serverHelpers/requestSanitization.js.map +1 -0
  328. package/dist/server/serverHelpers/serverHandlers.js +6 -3
  329. package/dist/server/serverHelpers/serverHandlers.js.map +1 -1
  330. package/dist/server/serverHelpers/serverUtilities.d.ts +18 -0
  331. package/dist/server/serverHelpers/serverUtilities.js +90 -20
  332. package/dist/server/serverHelpers/serverUtilities.js.map +1 -1
  333. package/dist/server/serverHelpers/sharedMessageEncoding.d.ts +67 -0
  334. package/dist/server/serverHelpers/sharedMessageEncoding.js +280 -0
  335. package/dist/server/serverHelpers/sharedMessageEncoding.js.map +1 -0
  336. package/dist/server/serverHelpers/uwsServer.js +19 -1
  337. package/dist/server/serverHelpers/uwsServer.js.map +1 -1
  338. package/dist/server/static.js +24 -28
  339. package/dist/server/static.js.map +1 -1
  340. package/dist/server/storageReclamation.d.ts +12 -0
  341. package/dist/server/storageReclamation.js +26 -0
  342. package/dist/server/storageReclamation.js.map +1 -1
  343. package/dist/server/threads/itc.d.ts +7 -2
  344. package/dist/server/threads/itc.js +5 -1
  345. package/dist/server/threads/itc.js.map +1 -1
  346. package/dist/server/threads/manageThreads.d.ts +26 -3
  347. package/dist/server/threads/manageThreads.js +517 -65
  348. package/dist/server/threads/manageThreads.js.map +1 -1
  349. package/dist/server/threads/socketRouter.js +89 -26
  350. package/dist/server/threads/socketRouter.js.map +1 -1
  351. package/dist/server/threads/threadHeapMemory.d.ts +2 -0
  352. package/dist/server/threads/threadHeapMemory.js +31 -0
  353. package/dist/server/threads/threadHeapMemory.js.map +1 -0
  354. package/dist/server/threads/threadServer.js +46 -15
  355. package/dist/server/threads/threadServer.js.map +1 -1
  356. package/dist/sqlEngine/config.d.ts +1 -3
  357. package/dist/sqlEngine/config.js +19 -16
  358. package/dist/sqlEngine/config.js.map +1 -1
  359. package/dist/sqlTranslator/index.d.ts +1 -1
  360. package/dist/sqlTranslator/index.js +30 -7
  361. package/dist/sqlTranslator/index.js.map +1 -1
  362. package/dist/upgrade/directives/5-3-0.d.ts +7 -0
  363. package/dist/upgrade/directives/5-3-0.js +148 -0
  364. package/dist/upgrade/directives/5-3-0.js.map +1 -0
  365. package/dist/upgrade/directives/directivesController.js +2 -1
  366. package/dist/upgrade/directives/directivesController.js.map +1 -1
  367. package/dist/utility/OperationFunctionCaller.js +2 -1
  368. package/dist/utility/OperationFunctionCaller.js.map +1 -1
  369. package/dist/utility/common_utils.d.ts +16 -0
  370. package/dist/utility/common_utils.js +32 -6
  371. package/dist/utility/common_utils.js.map +1 -1
  372. package/dist/utility/componentNames.d.ts +8 -0
  373. package/dist/utility/componentNames.js +12 -1
  374. package/dist/utility/componentNames.js.map +1 -1
  375. package/dist/utility/environment/environmentManager.js +3 -6
  376. package/dist/utility/environment/environmentManager.js.map +1 -1
  377. package/dist/utility/environment/systemInformation.d.ts +1 -0
  378. package/dist/utility/environment/systemInformation.js +1 -0
  379. package/dist/utility/environment/systemInformation.js.map +1 -1
  380. package/dist/utility/errors/commonErrors.d.ts +2 -0
  381. package/dist/utility/errors/commonErrors.js +2 -0
  382. package/dist/utility/errors/commonErrors.js.map +1 -1
  383. package/dist/utility/errors/hdbError.d.ts +17 -0
  384. package/dist/utility/errors/hdbError.js +30 -1
  385. package/dist/utility/errors/hdbError.js.map +1 -1
  386. package/dist/utility/globalSchema.d.ts +18 -0
  387. package/dist/utility/hdbTerms.d.ts +16 -0
  388. package/dist/utility/hdbTerms.js +18 -2
  389. package/dist/utility/hdbTerms.js.map +1 -1
  390. package/dist/utility/logging/harper_logger.d.ts +2 -0
  391. package/dist/utility/logging/harper_logger.js +91 -14
  392. package/dist/utility/logging/harper_logger.js.map +1 -1
  393. package/dist/utility/logging/logRotator.js +76 -49
  394. package/dist/utility/logging/logRotator.js.map +1 -1
  395. package/dist/utility/nodeIdentity.d.ts +9 -0
  396. package/dist/utility/nodeIdentity.js +58 -0
  397. package/dist/utility/nodeIdentity.js.map +1 -0
  398. package/dist/utility/npmUtilities.js +9 -7
  399. package/dist/utility/npmUtilities.js.map +1 -1
  400. package/dist/utility/operationPermissions.d.ts +3 -1
  401. package/dist/utility/operationPermissions.js +16 -1
  402. package/dist/utility/operationPermissions.js.map +1 -1
  403. package/dist/utility/operation_authorization.d.ts +10 -7
  404. package/dist/utility/operation_authorization.js +212 -41
  405. package/dist/utility/operation_authorization.js.map +1 -1
  406. package/dist/utility/watchPath.d.ts +29 -0
  407. package/dist/utility/watchPath.js +68 -0
  408. package/dist/utility/watchPath.js.map +1 -0
  409. package/dist/utility/watcherFallback.d.ts +86 -0
  410. package/dist/utility/watcherFallback.js +278 -1
  411. package/dist/utility/watcherFallback.js.map +1 -1
  412. package/dist/validation/configValidator.d.ts +12 -0
  413. package/dist/validation/configValidator.js +199 -72
  414. package/dist/validation/configValidator.js.map +1 -1
  415. package/dist/validation/installValidator.js +12 -0
  416. package/dist/validation/installValidator.js.map +1 -1
  417. package/dist/validation/validationWrapper.d.ts +11 -0
  418. package/dist/validation/validationWrapper.js +16 -3
  419. package/dist/validation/validationWrapper.js.map +1 -1
  420. package/index.ts +2 -0
  421. package/json/systemSchema.json +52 -0
  422. package/npm-shrinkwrap.json +196 -194
  423. package/package.json +7 -6
  424. package/resources/DESIGN.md +114 -52
  425. package/resources/DatabaseTransaction.ts +521 -43
  426. package/resources/LMDBTransaction.ts +26 -4
  427. package/resources/PrimaryRocksDatabase.ts +28 -1
  428. package/resources/RecordEncoder.ts +103 -8
  429. package/resources/RequestTarget.ts +2 -0
  430. package/resources/Resource.ts +17 -9
  431. package/resources/ResourceInterface.ts +23 -0
  432. package/resources/RocksIndexStore.ts +30 -9
  433. package/resources/RocksTransactionLogStore.ts +78 -21
  434. package/resources/Table.ts +1110 -159
  435. package/resources/auditStore.ts +331 -73
  436. package/resources/blob.ts +1029 -110
  437. package/resources/branchDatabase.ts +941 -0
  438. package/resources/crdt.ts +76 -12
  439. package/resources/databases.ts +1310 -252
  440. package/resources/defineTable.ts +18 -2
  441. package/resources/graphql.ts +70 -16
  442. package/resources/indexes/HierarchicalNavigableSmallWorld.ts +6 -2
  443. package/resources/longLivedTransactions.ts +360 -0
  444. package/resources/models/backendRegistry.ts +84 -2
  445. package/resources/models/bootstrap.ts +473 -28
  446. package/resources/recordLock.ts +253 -0
  447. package/resources/replayLogs.ts +147 -26
  448. package/resources/replayLogsGuards.ts +171 -8
  449. package/resources/search.ts +154 -7
  450. package/resources/transactionBroadcast.ts +3 -3
  451. package/security/auth.ts +68 -29
  452. package/security/authn/oidc/claims.ts +72 -0
  453. package/security/authn/oidc/identityToken.ts +129 -0
  454. package/security/authn/oidc/jwks.ts +260 -0
  455. package/security/authn/oidc/providers/generic.ts +40 -0
  456. package/security/authn/oidc/providers/githubActions.ts +137 -0
  457. package/security/authn/oidc/providers/index.ts +52 -0
  458. package/security/authn/oidc/tokenExchange.ts +300 -0
  459. package/security/authn/oidc/trustPolicyOperations.ts +343 -0
  460. package/security/authn/oidc/types.ts +41 -0
  461. package/security/certificateVerification/index.ts +54 -13
  462. package/security/certificateVerification/trustedIssuers.ts +76 -0
  463. package/security/certificateVerification/types.ts +1 -0
  464. package/security/credentialProvenance.ts +47 -0
  465. package/security/credentialRejection.ts +22 -0
  466. package/security/deferredAuthentication.ts +71 -0
  467. package/security/impersonation.ts +117 -12
  468. package/security/jsLoader.ts +81 -18
  469. package/security/keys.ts +298 -72
  470. package/security/operationScope.ts +33 -0
  471. package/security/permissionsTranslator.js +23 -0
  472. package/security/tokenAuthentication.ts +233 -12
  473. package/security/user.ts +4 -3
  474. package/server/DESIGN.md +183 -16
  475. package/server/DurableSubscriptionsSession.ts +71 -11
  476. package/server/REST.ts +79 -1
  477. package/server/graphqlQuerying.ts +4 -0
  478. package/server/http.ts +99 -18
  479. package/server/itc/serverHandlers.js +8 -1
  480. package/server/jobs/jobProcess.ts +8 -2
  481. package/server/jobs/jobs.ts +4 -1
  482. package/server/liveSubscriptionAuth.ts +129 -46
  483. package/server/loadRootComponents.js +50 -8
  484. package/server/mqtt.ts +179 -38
  485. package/server/nodeName.ts +103 -21
  486. package/server/serverHelpers/Headers.ts +131 -0
  487. package/server/serverHelpers/contentTypes.ts +29 -21
  488. package/server/serverHelpers/deployValidationState.ts +24 -13
  489. package/server/serverHelpers/operationAuthorizationState.ts +34 -3
  490. package/server/serverHelpers/registeredOperations.ts +79 -22
  491. package/server/serverHelpers/requestSanitization.ts +15 -0
  492. package/server/serverHelpers/serverHandlers.js +6 -3
  493. package/server/serverHelpers/serverUtilities.ts +104 -31
  494. package/server/serverHelpers/sharedMessageEncoding.ts +307 -0
  495. package/server/serverHelpers/uwsServer.ts +17 -2
  496. package/server/static.ts +23 -29
  497. package/server/storageReclamation.ts +23 -0
  498. package/server/threads/itc.js +11 -1
  499. package/server/threads/manageThreads.js +526 -56
  500. package/server/threads/socketRouter.ts +81 -26
  501. package/server/threads/threadHeapMemory.ts +26 -0
  502. package/server/threads/threadServer.js +43 -15
  503. package/sqlTranslator/index.ts +31 -8
  504. package/studio/web/assets/Chat-BnCBegQz.js +2267 -0
  505. package/studio/web/assets/FloatingChat-CoDW1ySS.js +23 -0
  506. package/studio/web/assets/{abnfDiagram-VCTEODGH-C0_BAZyO.js → abnfDiagram-VCTEODGH-B0BebmD2.js} +1 -1
  507. package/studio/web/assets/{alertDialog-DIHt7Z0r.js → alertDialog-CQyAJJhl.js} +1 -1
  508. package/studio/web/assets/{apiToken-c3Rd-w6g.js → apiToken-Bwk5BLXW.js} +1 -1
  509. package/studio/web/assets/applications-DHxGi7JH.js +296 -0
  510. package/studio/web/assets/architecture-7GRP2DOG-LB-MLAAb.js +1 -0
  511. package/studio/web/assets/{architectureDiagram-5GKGNRK7-BWzrASgm.js → architectureDiagram-5GKGNRK7-7SW3GD-K.js} +1 -1
  512. package/studio/web/assets/authStore-C3Nfubqr.js +3 -0
  513. package/studio/web/assets/{blockDiagram-NRAW4CY4-BdJX9Khj.js → blockDiagram-I7D4REHJ-BqguiadH.js} +2 -2
  514. package/studio/web/assets/{button-DhiX-njv.js → button-BIsUKRZq.js} +2 -2
  515. package/studio/web/assets/{c4Diagram-UCG6FXSJ-CI6MzGmQ.js → c4Diagram-7LVT6UL2-LBNf8t_X.js} +1 -1
  516. package/studio/web/assets/channel-yictG-U-.js +1 -0
  517. package/studio/web/assets/{chevron-up-Df2c8uoU.js → chevron-up-DtKGqDn3.js} +1 -1
  518. package/studio/web/assets/{chunk-TEH6E4GO-P87k5mNi.js → chunk-4HAMMTFA-DWtTut21.js} +1 -1
  519. package/studio/web/assets/{chunk-75Z2AOVW-BT8tVmks.js → chunk-75Z2AOVW-QGQD6th2.js} +1 -1
  520. package/studio/web/assets/{chunk-DU6HZSFF-9kAOOmI6.js → chunk-DU6HZSFF-Chq20Ba5.js} +1 -1
  521. package/studio/web/assets/{chunk-F27PBJKO-BW7ao8AY.js → chunk-F27PBJKO-BVA5EPhV.js} +1 -1
  522. package/studio/web/assets/{chunk-GMAD6QVW-BNyXpoQO.js → chunk-GMAD6QVW-BeS7S07A.js} +1 -1
  523. package/studio/web/assets/{chunk-OBVCFTLP-D4wWOqDQ.js → chunk-GVQU2GXP-sbwVIQ8i.js} +1 -1
  524. package/studio/web/assets/{chunk-G27WJ6UU-COyLMcgK.js → chunk-IMKFNOWR-Bnh3tAVd.js} +1 -1
  525. package/studio/web/assets/{chunk-JQ64N6SF-Cyz1IeLf.js → chunk-L3NEJ4N5-COfUyKII.js} +1 -1
  526. package/studio/web/assets/chunk-OSK3NFVY-ByciRftO.js +10 -0
  527. package/studio/web/assets/{chunk-P2QGCYS3-DmIFY4d7.js → chunk-P2QGCYS3-CP1VhG_c.js} +1 -1
  528. package/studio/web/assets/{chunk-POPQ4Y6H-BPrvMyKz.js → chunk-POPQ4Y6H-ClWhhkwW.js} +1 -1
  529. package/studio/web/assets/{chunk-PWAF6VOD-2zB6IW9i.js → chunk-PWAF6VOD-1z1THyS5.js} +1 -1
  530. package/studio/web/assets/{chunk-RHFEMEQ7-2FgyI8YU.js → chunk-SHT3W25Y-LpQkMsah.js} +2 -2
  531. package/studio/web/assets/{chunk-SVP7TREG-FwtbH2QC.js → chunk-SVP7TREG-jtdAHw0S.js} +1 -1
  532. package/studio/web/assets/{chunk-LCL6LL3I-HOzK_ppE.js → chunk-TICWLB2K-VOwzetX-.js} +1 -1
  533. package/studio/web/assets/classDiagram-ZZMXUADV-VaEwSy_g.js +1 -0
  534. package/studio/web/assets/classDiagram-v2-VYDZK3BY-VaEwSy_g.js +1 -0
  535. package/studio/web/assets/{createLucideIcon-BKGPfjm2.js → createLucideIcon-CzW9508A.js} +1 -1
  536. package/studio/web/assets/{cssMode-CEN2mzSA.js → cssMode-s0cWI-_M.js} +1 -1
  537. package/studio/web/assets/{cynefin-OW5HDTMX-BRkpLFQV.js → cynefin-OW5HDTMX-BbdbCvub.js} +1 -1
  538. package/studio/web/assets/{cynefinDiagram-5FMLGOSQ-CHT1DaX6.js → cynefinDiagram-5FMLGOSQ-TP-aIqbt.js} +1 -1
  539. package/studio/web/assets/{dagre-3AP2YEHR-DpUXBh63.js → dagre-GXQ25YYZ-DShnGpGo.js} +1 -1
  540. package/studio/web/assets/{diagram-S7CK7UJ4-BuymVFZT.js → diagram-S7CK7UJ4-aoCVTtcy.js} +1 -1
  541. package/studio/web/assets/{diagram-UQ7AKVKN-CyP148RM.js → diagram-UQ7AKVKN-DglXtQ6x.js} +1 -1
  542. package/studio/web/assets/{diagram-VSXAHHWV-CoCAg3M9.js → diagram-VSXAHHWV-fhEdmkwM.js} +1 -1
  543. package/studio/web/assets/{diagram-VX7I27RA-BpOqCFca.js → diagram-VX7I27RA-DccVJet6.js} +1 -1
  544. package/studio/web/assets/{diagram-Z3DM3KII-Bfpw7Vbj.js → diagram-Z3DM3KII-D-RyJJb7.js} +1 -1
  545. package/studio/web/assets/{dialog-CBf0Mr1d.js → dialog-Cn2uWgD4.js} +1 -1
  546. package/studio/web/assets/{dist-lkA3O3eM.js → dist-DP8UjMB_.js} +1 -1
  547. package/studio/web/assets/{download-BtTOBem-.js → download-B5T5r7ss.js} +1 -1
  548. package/studio/web/assets/{ebnfDiagram-PWID7BFC-DS_6aWqL.js → ebnfDiagram-PWID7BFC-DJGpIpz_.js} +1 -1
  549. package/studio/web/assets/{editor-D8oDeCTL.js → editor-DNcRHK54.js} +1 -1
  550. package/studio/web/assets/{erDiagram-SSCWMZ5O-DJNk6Fgw.js → erDiagram-RLTQ6QDP-CIfNlgkC.js} +1 -1
  551. package/studio/web/assets/eventmodeling-NTZA5JFV-CLxnp2CR.js +1 -0
  552. package/studio/web/assets/flowDiagram-HODETNUW-BIbhmz9f.js +1 -0
  553. package/studio/web/assets/{ganttDiagram-EL5Y4UJY-2pOExxMY.js → ganttDiagram-EL5Y4UJY-BxToTzzD.js} +1 -1
  554. package/studio/web/assets/{getAnalytics-D4LKGeVy.js → getAnalytics-GHK8ORfM.js} +1 -1
  555. package/studio/web/assets/{gitGraph-4MIJSDKK-CH5ZxwzF.js → gitGraph-4MIJSDKK-D2s2w8lE.js} +1 -1
  556. package/studio/web/assets/{gitGraphDiagram-WWUBYQGX-DVIsIhbO.js → gitGraphDiagram-WWUBYQGX-Dwntd4-x.js} +1 -1
  557. package/studio/web/assets/{html-u3vOg7LJ.js → html-Bdssedlg.js} +1 -1
  558. package/studio/web/assets/{htmlMode-DyO31v-P.js → htmlMode-CoDlJ3fw.js} +1 -1
  559. package/studio/web/assets/{index-Cxj2_wsl.css → index-7RMEgVG1.css} +1 -1
  560. package/studio/web/assets/index-D6sxmFLR.js +824 -0
  561. package/studio/web/assets/index.lazy-tmU5BS8s.js +2 -0
  562. package/studio/web/assets/{info-A6RAGUB7-CPQfTnaG.js → info-A6RAGUB7-DYjkvb0C.js} +1 -1
  563. package/studio/web/assets/{infoDiagram-RXCK75RN-DlwLYlwm.js → infoDiagram-27XIBGKW-Bnp1FJE5.js} +1 -1
  564. package/studio/web/assets/{ishikawaDiagram-5VMMS53U-BRXRp29U.js → ishikawaDiagram-5VMMS53U-D9Xh2r6X.js} +1 -1
  565. package/studio/web/assets/{javascript-CUvxOyTC.js → javascript-B8meVSTH.js} +1 -1
  566. package/studio/web/assets/{journeyDiagram-EYS64GPL-B0ou8k0n.js → journeyDiagram-3NMN7TZE-CokIi6ll.js} +2 -2
  567. package/studio/web/assets/{jsonMode-f_IwbF3D.js → jsonMode-DpIPd35T.js} +1 -1
  568. package/studio/web/assets/{kanban-definition-3QL26DDD-uYg7iYzp.js → kanban-definition-UXKFOSKX-CukSFJfX.js} +1 -1
  569. package/studio/web/assets/{languageServices-DXtZ6rEF.js → languageServices-C_5FMJzQ.js} +1 -1
  570. package/studio/web/assets/{lspLanguageFeatures-B4pCF1zO.js → lspLanguageFeatures-BIzNBzPK.js} +1 -1
  571. package/studio/web/assets/{mermaid-parser.core-Ck-fC8b7.js → mermaid-parser.core-BlEsOWNO.js} +3 -3
  572. package/studio/web/assets/{mermaid.core-CP8aNNYm.js → mermaid.core-BlkGaMIH.js} +5 -5
  573. package/studio/web/assets/{mindmap-definition-FBJOCRG2-CgTZ-rit.js → mindmap-definition-YA3MSWOX-IprMc_0j.js} +1 -1
  574. package/studio/web/assets/{notifications-D3tIQ4sg.js → notifications-CQf18QKb.js} +1 -1
  575. package/studio/web/assets/notifications-CvZivSbh.js +1 -0
  576. package/studio/web/assets/{packet-AYTQ26CC-DEyoPtPb.js → packet-AYTQ26CC-Bi3V04Zi.js} +1 -1
  577. package/studio/web/assets/{pegDiagram-XKGWAZYB-DrD-7sD9.js → pegDiagram-XKGWAZYB-BNuPDLZY.js} +1 -1
  578. package/studio/web/assets/{pie-WAS4IAKB-wjj-EI1d.js → pie-WAS4IAKB-_6DoDbng.js} +1 -1
  579. package/studio/web/assets/{pieDiagram-E7YTZNPT-GntqDCzv.js → pieDiagram-E7YTZNPT-DqNb6Ht2.js} +1 -1
  580. package/studio/web/assets/{profile-DZWU7MgT.js → profile-DdOwtntb.js} +1 -1
  581. package/studio/web/assets/{quadrantDiagram-AXDQQJYC-0UeqXQGd.js → quadrantDiagram-AXDQQJYC-BGH9E2YR.js} +1 -1
  582. package/studio/web/assets/{radar-RG4KPBEZ-DFSA5h7k.js → radar-RG4KPBEZ-DDdVczcL.js} +1 -1
  583. package/studio/web/assets/{railroad-74A4TZTK-CaOUG9wR.js → railroad-74A4TZTK-BJUP4Jds.js} +1 -1
  584. package/studio/web/assets/railroad-abnf-HS5TGJTU-Bm3L1L0h.js +1 -0
  585. package/studio/web/assets/railroad-ebnf-LZEXJU2U-CKzLGlkw.js +1 -0
  586. package/studio/web/assets/railroad-peg-WCYAUIDC-S8xLjslx.js +1 -0
  587. package/studio/web/assets/{railroadDiagram-O6MQD6OU-yHUELZaV.js → railroadDiagram-O6MQD6OU-DGTPh2KZ.js} +1 -1
  588. package/studio/web/assets/{regions-CkyurXzE.js → regions-n69fwagr.js} +1 -1
  589. package/studio/web/assets/{register-BUyhWjBO.js → register-PfWTCXWB.js} +3 -3
  590. package/studio/web/assets/{requirementDiagram-EFPCY7ZU-DNEGFjuW.js → requirementDiagram-BXWQKSXE-BJnO6uLz.js} +1 -1
  591. package/studio/web/assets/{sankeyDiagram-P5KCCOFB-DpyAmSVR.js → sankeyDiagram-P5KCCOFB-0vSOdymH.js} +1 -1
  592. package/studio/web/assets/{sequenceDiagram-WJ2MYXX4-TyaT7xNk.js → sequenceDiagram-WJ2MYXX4-hETizDWE.js} +1 -1
  593. package/studio/web/assets/{setComponentFile-CeyKSZAa.js → setComponentFile-Bg6O7X0S.js} +1 -1
  594. package/studio/web/assets/{setup-D2kn7cAA.js → setup-CUx_aUDl.js} +2 -2
  595. package/studio/web/assets/{stateDiagram-HBIQ2CUA-CeEdTArZ.js → stateDiagram-D77RDMKH-CdYQ_KtC.js} +1 -1
  596. package/studio/web/assets/stateDiagram-v2-MP3YSRHH-CdKuzQMT.js +1 -0
  597. package/studio/web/assets/status-D7BVKqX9.js +61 -0
  598. package/studio/web/assets/{swimlanes-XN3QIQJK-B54FmF46.js → swimlanes-42K2YHIH-B8cHIpU4.js} +1 -1
  599. package/studio/web/assets/swimlanesDiagram-VR7AAH4N-DmOSJwaH.js +8 -0
  600. package/studio/web/assets/{tabs-B_G5zscN.js → tabs-BrHu7gJi.js} +1 -1
  601. package/studio/web/assets/{timeline-definition-24CTP7MA-D-a9ujbo.js → timeline-definition-24CTP7MA-BJWYSXqF.js} +1 -1
  602. package/studio/web/assets/{toggleHighContrast-C0UW6rI2.js → toggleHighContrast-DBSyXzMr.js} +1 -1
  603. package/studio/web/assets/{treeView-Q6P3EWNA-CrW_6JnS.js → treeView-Q6P3EWNA-qxe_v6CQ.js} +1 -1
  604. package/studio/web/assets/{treemap-WGGIJYW6-BxyYLdP_.js → treemap-WGGIJYW6-dDo97XXF.js} +1 -1
  605. package/studio/web/assets/{tsMode-DBC0zmDx.js → tsMode-BByKCjBS.js} +1 -1
  606. package/studio/web/assets/{typescript-DApRQir3.js → typescript-DDLnLpw9.js} +1 -1
  607. package/studio/web/assets/{useEntityRestURL-DB6JStU1.js → useEntityRestURL-31CHGaHk.js} +1 -1
  608. package/studio/web/assets/{useLocalStorage-Dtj1QS8_.js → useLocalStorage-BqMR3D8_.js} +1 -1
  609. package/studio/web/assets/vendor-core-c2JRRJpV.js +58 -0
  610. package/studio/web/assets/vendor-datadog-CLUcJXOo.js +6 -0
  611. package/studio/web/assets/{vendor-react-Dyj4O3HE.js → vendor-react-CJV_K1u4.js} +1 -1
  612. package/studio/web/assets/vendor-tanstack-DxzraizX.js +1 -0
  613. package/studio/web/assets/{vendor-ui-vhu-UHhF.js → vendor-ui-BUjK0h8a.js} +2 -2
  614. package/studio/web/assets/{vennDiagram-4TSXK5OY-Cy7s7Mpy.js → vennDiagram-4TSXK5OY-A3i-lCdl.js} +1 -1
  615. package/studio/web/assets/{wardley-WFR3VGLG-BeBL35g2.js → wardley-WFR3VGLG-B0ik-_6g.js} +1 -1
  616. package/studio/web/assets/{wardleyDiagram-VM6X3IG4-BylmIGSg.js → wardleyDiagram-VM6X3IG4-CjrkKWUR.js} +1 -1
  617. package/studio/web/assets/{workers-C0bFIedw.js → workers-pR3jRY9D.js} +1 -1
  618. package/studio/web/assets/x-DIzaLEdK.js +1 -0
  619. package/studio/web/assets/{xml-HWd01lU-.js → xml-2iRnMhQO.js} +1 -1
  620. package/studio/web/assets/{xychartDiagram-S5SC5T6Z-CoKALMXr.js → xychartDiagram-S5SC5T6Z-Biok4GYV.js} +1 -1
  621. package/studio/web/assets/{yaml-CIH0Nt-h.js → yaml-Bf92gJpd.js} +1 -1
  622. package/studio/web/index.html +14 -14
  623. package/upgrade/directives/5-3-0.ts +132 -0
  624. package/upgrade/directives/directivesController.ts +2 -1
  625. package/utility/OperationFunctionCaller.ts +2 -1
  626. package/utility/common_utils.ts +30 -5
  627. package/utility/componentNames.ts +12 -0
  628. package/utility/environment/environmentManager.ts +3 -7
  629. package/utility/environment/systemInformation.ts +7 -0
  630. package/utility/errors/commonErrors.ts +4 -0
  631. package/utility/errors/hdbError.ts +29 -0
  632. package/utility/hdbTerms.ts +17 -0
  633. package/utility/logging/harper_logger.ts +87 -14
  634. package/utility/logging/logRotator.ts +72 -45
  635. package/utility/nodeIdentity.ts +45 -0
  636. package/utility/npmUtilities.ts +10 -8
  637. package/utility/operationPermissions.ts +18 -1
  638. package/utility/operation_authorization.ts +231 -42
  639. package/utility/watchPath.ts +63 -0
  640. package/utility/watcherFallback.ts +270 -0
  641. package/validation/configValidator.ts +209 -72
  642. package/validation/installValidator.ts +15 -0
  643. package/validation/validationWrapper.ts +18 -4
  644. package/studio/web/assets/Chat-JpO8EtUu.js +0 -2067
  645. package/studio/web/assets/FloatingChat-Bcj3xSZu.js +0 -23
  646. package/studio/web/assets/applications-ByqLRKyZ.js +0 -296
  647. package/studio/web/assets/architecture-7GRP2DOG-DNdx5tEU.js +0 -1
  648. package/studio/web/assets/authStore-qKmCZcaf.js +0 -3
  649. package/studio/web/assets/channel-DtCV8PTL.js +0 -1
  650. package/studio/web/assets/chunk-R7TYR2AO-Irip67yr.js +0 -10
  651. package/studio/web/assets/classDiagram-DTDB5LWJ-DbO_dCNE.js +0 -1
  652. package/studio/web/assets/classDiagram-v2-JRS7N3AN-DbO_dCNE.js +0 -1
  653. package/studio/web/assets/eventmodeling-NTZA5JFV-5jbe4A5P.js +0 -1
  654. package/studio/web/assets/flowDiagram-A5DVABFB-Dp9Ezlow.js +0 -1
  655. package/studio/web/assets/index-aSt5tY-L.js +0 -824
  656. package/studio/web/assets/index.lazy-B9jiPwT8.js +0 -2
  657. package/studio/web/assets/notifications-CUoYgU98.js +0 -1
  658. package/studio/web/assets/railroad-abnf-HS5TGJTU-Bc0Qi0WH.js +0 -1
  659. package/studio/web/assets/railroad-ebnf-LZEXJU2U-G8rVVZ2C.js +0 -1
  660. package/studio/web/assets/railroad-peg-WCYAUIDC-CrehKBhC.js +0 -1
  661. package/studio/web/assets/stateDiagram-v2-4QOOHH4V-D4tuw9Su.js +0 -1
  662. package/studio/web/assets/status-D7Xn5ePA.js +0 -61
  663. package/studio/web/assets/swimlanesDiagram-VK2B7HYN-XOhmNEvq.js +0 -8
  664. package/studio/web/assets/vendor-core-RCcadM3e.js +0 -73
  665. package/studio/web/assets/vendor-datadog-BRv-mOv1.js +0 -6
  666. package/studio/web/assets/vendor-tanstack-BiFWSB3W.js +0 -1
  667. package/studio/web/assets/x-B9o9hsep.js +0 -1
  668. /package/studio/web/assets/{sizeCapture-X5ZJPWSS-B0uUizjq.js → sizeCapture-INFHLROL-B0uUizjq.js} +0 -0
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Waiting for a worker restart on behalf of an operation that reports whether it finished.
3
+ *
4
+ * No single clock bounds a restart: each replacement has its own startup backstop, a worker draining
5
+ * in-flight work may hold its exit for as long as the drain ceiling allows, and a wide pool rolls a
6
+ * few workers at a time. So the wait follows the restart's own progress and gives up only when
7
+ * nothing has moved for `idleTimeoutMs`, or at the absolute `ceilingMs` — a caller holding an API
8
+ * response open cannot wait forever.
9
+ */
10
+
11
+ /** How long the restart may go without reporting progress before the wait gives up. */
12
+ export const RESTART_IDLE_TIMEOUT_MS = 60_000;
13
+ /** Absolute cap on the wait, matching the default shutdown-drain ceiling. */
14
+ export const RESTART_WAIT_CEILING_MS = 600_000;
15
+
16
+ export interface RestartOutcome {
17
+ completed: boolean;
18
+ /** Workers left running the previous code because their replacement never came up. */
19
+ workersKeptOnOldCode?: number;
20
+ /** Replacements that never reported starting after their predecessor was already gone. */
21
+ replacementsNotStarted?: number;
22
+ /** The wait ended because the restart stopped reporting progress. */
23
+ stalled?: boolean;
24
+ /** The restart was handed to another thread, which reports its own completion. */
25
+ handedOff?: boolean;
26
+ /** No restart was performed: the process is already shutting down. */
27
+ declined?: boolean;
28
+ error?: any;
29
+ }
30
+
31
+ /** Reports progress; a deadline says the reporter is busy until then (e.g. a drain it asked for). */
32
+ export type RestartProgress = (untilMs?: number) => void;
33
+
34
+ export function awaitRestart(
35
+ startRestart: (onProgress: RestartProgress) => any,
36
+ { idleTimeoutMs = RESTART_IDLE_TIMEOUT_MS, ceilingMs = RESTART_WAIT_CEILING_MS } = {}
37
+ ): Promise<RestartOutcome> {
38
+ let idleTimer: any, ceilingTimer: any;
39
+ let settled = false;
40
+ let reportStalled: (outcome: RestartOutcome) => void;
41
+ const done = (outcome: RestartOutcome) => {
42
+ settled = true;
43
+ clearTimeout(idleTimer);
44
+ clearTimeout(ceilingTimer);
45
+ return outcome;
46
+ };
47
+ const onProgress: RestartProgress = (untilMs) => {
48
+ // The restart keeps reporting past the point where the wait gave up; re-arming a timer then
49
+ // would leave a live handle behind for as long as the last reported deadline.
50
+ if (settled) return;
51
+ clearTimeout(idleTimer);
52
+ // A reported deadline is what the reporter says it needs, so honor it over the idle window; the
53
+ // absolute ceiling is what keeps that bounded.
54
+ const wait = Math.max(idleTimeoutMs, untilMs === undefined ? 0 : untilMs - Date.now());
55
+ idleTimer = setTimeout(() => reportStalled(done({ completed: false, stalled: true })), wait);
56
+ };
57
+ const stalled = new Promise<RestartOutcome>((resolve) => {
58
+ reportStalled = resolve;
59
+ });
60
+ const ceiling = new Promise<RestartOutcome>((resolve) => {
61
+ ceilingTimer = setTimeout(() => resolve(done({ completed: false })), ceilingMs);
62
+ });
63
+ onProgress();
64
+ const restarted = Promise.resolve()
65
+ .then(() => startRestart(onProgress))
66
+ .then(
67
+ (result) =>
68
+ done(
69
+ result && typeof result === 'object'
70
+ ? result.declined
71
+ ? { completed: false, declined: true }
72
+ : {
73
+ completed: true,
74
+ workersKeptOnOldCode: result.workersKeptOnOldCode ?? 0,
75
+ replacementsNotStarted: result.replacementsNotStarted ?? 0,
76
+ }
77
+ : // Only the thread performing the restart can report on it; from a worker
78
+ // restartWorkers() hands it off and resolves with nothing.
79
+ { completed: false, handedOff: true }
80
+ ),
81
+ (error) => done({ completed: false, error })
82
+ );
83
+ return Promise.race([restarted, stalled, ceiling]);
84
+ }
@@ -11,6 +11,8 @@ import {
11
11
  } from 'node:fs';
12
12
  import { join, basename, dirname, sep } from 'node:path';
13
13
  import { isMainThread } from 'node:worker_threads';
14
+
15
+ import { isDeployValidating } from '../server/serverHelpers/deployValidationState.ts';
14
16
  import { parseDocument } from 'yaml';
15
17
  import * as env from '../utility/environment/environmentManager.ts';
16
18
  import { PACKAGE_ROOT } from '../utility/packageUtils.js';
@@ -30,16 +32,18 @@ import { restartWorkers, getWorkerIndex } from '../server/threads/manageThreads.
30
32
  import { resetRestartNeeded, subscribeToRestartRequests } from './requestRestart.ts';
31
33
  import { trackScopeClose } from './scopeShutdown.ts';
32
34
  import { deployLifecycle } from './deployLifecycle.ts';
35
+ import { assertBranchedDatabases } from './Application.ts';
36
+ import { prepareBranches } from '../resources/branchDatabase.ts';
33
37
  import { toScopeMount, nestScopeMount, type ScopeMount } from './scopeMount.ts';
34
38
  import { scopedImport } from '../security/jsLoader.ts';
35
39
  import { server } from '../server/Server.ts';
36
40
  import { Resources } from '../resources/Resources.ts';
37
- import { table } from '../resources/databases.ts';
41
+ import { scopedTableFactory } from '../resources/databases.ts';
38
42
  import { getHdbBasePath } from '../utility/environment/environmentManager.ts';
39
43
  import * as auth from '../security/auth.ts';
40
44
  import * as mqtt from '../server/mqtt.ts';
41
45
  import { getConfigObj, getConfigPath } from '../config/configUtils.ts';
42
- import { bootstrapModels } from '../resources/models/bootstrap.ts';
46
+ import { bootstrapModels, startModelsConfigHotReload } from '../resources/models/bootstrap.ts';
43
47
  import { ErrorResource } from '../resources/ErrorResource.ts';
44
48
  import { Scope } from './Scope.ts';
45
49
  import { ApplicationScope } from './ApplicationScope.ts';
@@ -47,17 +51,71 @@ import { ComponentV1, processResourceExtensionComponent } from './ComponentV1.ts
47
51
  import * as httpComponent from '../server/http.ts';
48
52
  import * as mcpComponent from './mcp/index.ts';
49
53
  import { Status } from '../server/status/index.ts';
50
- import { lifecycle as componentLifecycle } from './status/index.ts';
54
+ import { lifecycle as componentLifecycle, statusForComponent } from './status/index.ts';
51
55
  import { DEFAULT_CONFIG } from './DEFAULT_CONFIG.ts';
52
56
  import { materializeGlobalSecrets, processComponentEnv } from './componentSecrets.ts';
53
57
  import { PluginModule } from './PluginModule.ts';
54
- import { getEnvBuiltInComponents } from './Application.ts';
58
+ import {
59
+ getEnvBuiltInComponents,
60
+ recoverInterruptedActivations,
61
+ recoverInterruptedComponentExtraction,
62
+ recoverInterruptedComponentExtractions,
63
+ unsettleableComponentsFromDisk,
64
+ } from './Application.ts';
65
+ import { ComponentPreparationLockTimeoutError } from './componentPreparationLock.ts';
55
66
  import { pathToFileURL } from 'node:url';
56
67
 
57
68
  const CF_ROUTES_DIR = getConfigPath(CONFIG_PARAMS.COMPONENTSROOT);
69
+
58
70
  let loadedComponents = new Map<any, any>();
71
+
72
+ // Marks a registry entry as belonging to a deploy validation's throwaway load, so cleanup can tell whether
73
+ // an ordinary load has since ADOPTED that module. Checking "was it already loaded?" before the fact is not
74
+ // enough: ownership changes after that check when a real load reuses the entry while the validation is
75
+ // still running, and deleting it then removes a module a live consumer depends on.
76
+ const VALIDATION_OWNED = Symbol('validationOwnedModule');
59
77
  let watchesSetup;
60
78
  let resources;
79
+ const componentLoadTails = new Map<string, Promise<void>>();
80
+ type ComponentReadyPromises = WeakMap<object, Promise<void>>;
81
+
82
+ function serializeComponentLoad<T>(appName: string, load: () => Promise<T>): Promise<T> {
83
+ const previousLoad = componentLoadTails.get(appName);
84
+ const currentLoad = previousLoad ? previousLoad.then(load) : load();
85
+ const loadTail = currentLoad.then(
86
+ () => undefined,
87
+ () => undefined
88
+ );
89
+ componentLoadTails.set(appName, loadTail);
90
+ void loadTail.then(() => {
91
+ if (componentLoadTails.get(appName) === loadTail) componentLoadTails.delete(appName);
92
+ });
93
+ return currentLoad;
94
+ }
95
+
96
+ export async function readyComponentModules(
97
+ serverModules: Iterable<any>,
98
+ readyComponentPromises: ComponentReadyPromises = new WeakMap()
99
+ ): Promise<void> {
100
+ const readyPromises: Promise<void>[] = [];
101
+ for (const serverModule of serverModules) {
102
+ if (
103
+ (typeof serverModule !== 'object' && typeof serverModule !== 'function') ||
104
+ serverModule === null ||
105
+ typeof serverModule.ready !== 'function'
106
+ ) {
107
+ continue;
108
+ }
109
+ let readyPromise = readyComponentPromises.get(serverModule);
110
+ if (!readyPromise) {
111
+ readyPromise = Promise.resolve().then(() => serverModule.ready());
112
+ readyComponentPromises.set(serverModule, readyPromise);
113
+ void readyPromise.catch(() => readyComponentPromises.delete(serverModule));
114
+ }
115
+ readyPromises.push(readyPromise);
116
+ }
117
+ await Promise.all(readyPromises);
118
+ }
61
119
 
62
120
  /**
63
121
  * Load all the applications registered in Harper, those in the components directory as well as any directly
@@ -86,6 +144,23 @@ function rootConfigMount(appName: string): ScopeMount | undefined {
86
144
  return toScopeMount(getConfigObj()?.[appName]);
87
145
  }
88
146
 
147
+ /**
148
+ * The databases an operator declared that `appName` should get a private fork of, from the root
149
+ * config — the same place `host`/`urlPath` are declared, and for the same reason. Which databases an
150
+ * application forks is a deployment decision, not something the application checks in: the operator
151
+ * deploying it onto a cluster is who knows whether it should run against its own copy.
152
+ *
153
+ * ```yaml
154
+ * my-app:
155
+ * host: api.example.com
156
+ * branchedDatabases: [data]
157
+ * ```
158
+ */
159
+ function rootConfigBranchedDatabases(appName: string): string[] | true | undefined {
160
+ if (Object.hasOwn(TRUSTED_RESOURCE_PLUGINS, appName)) return undefined;
161
+ return (getConfigObj()?.[appName] as any)?.branchedDatabases;
162
+ }
163
+
89
164
  /**
90
165
  * Resolves the mount for `appName`, or reports the failure and returns `undefined` if the
91
166
  * configured `host`/`urlPath` is invalid. The caller must skip loading the application in that
@@ -110,15 +185,114 @@ function tryRootConfigMount(appName: string): { ok: true; mount: ScopeMount | un
110
185
  }
111
186
  }
112
187
 
113
- export async function loadComponentDirectories(loadedPluginModules?: Map<any, any>, loadedResources?: Resources) {
188
+ export async function loadComponentDirectories(
189
+ loadedPluginModules?: Map<any, any>,
190
+ loadedResources?: Resources,
191
+ readyComponentPromises: ComponentReadyPromises = new WeakMap(),
192
+ // Settled by boot BEFORE installApplications(), because that installs from the root config and would
193
+ // otherwise reinstall the previous release over an already-live candidate. `undefined` on a worker,
194
+ // which never runs that pass — distinct from an empty map, which would claim nothing is unreconciled.
195
+ interruptedActivationFailures?: Map<string, Error>
196
+ ) {
114
197
  if (loadedResources) resources = loadedResources;
115
198
  if (loadedPluginModules) loadedComponents = loadedPluginModules;
199
+ const cycleResources = resources;
200
+ const failedRecoveries = new Map<string, Error>(interruptedActivationFailures ?? []);
201
+ if (!interruptedActivationFailures) {
202
+ // No verdict from boot means this is a worker, which never runs the recovery pass. It reads the same
203
+ // evidence instead: a component whose activation could not be settled must not load here either,
204
+ // since workers are what actually serve it.
205
+ //
206
+ // Settlement itself runs here too, not just the read-only check. A worker can be auto-restarted at any
207
+ // time — including mid-activation — and the legacy pass below then has an unsettled journal in front
208
+ // of it, which it refuses to restore against: the component stalls instead of loading. Main-thread
209
+ // startup sequencing does not protect a worker that restarts later. Safe to run on any thread: each deployment is settled under
210
+ // the component preparation lock, which is cross-thread and cross-process, and the pass is idempotent.
211
+ try {
212
+ for (const [component, error] of await recoverInterruptedActivations(CF_ROUTES_DIR)) {
213
+ if (!failedRecoveries.has(component)) failedRecoveries.set(component, error);
214
+ }
215
+ } catch (error) {
216
+ harperLogger.warn(
217
+ 'Could not settle interrupted component activations on this thread:',
218
+ errorForLog(error instanceof Error ? error : new Error(String(error)))
219
+ );
220
+ }
221
+ // Plus anything a previous pass recorded as unsettleable, which settlement above leaves in place.
222
+ try {
223
+ for (const [component, error] of await unsettleableComponentsFromDisk(CF_ROUTES_DIR)) {
224
+ if (!failedRecoveries.has(component)) failedRecoveries.set(component, error);
225
+ }
226
+ } catch (error) {
227
+ harperLogger.warn(
228
+ 'Could not check for unsettled component activations:',
229
+ errorForLog(error instanceof Error ? error : new Error(String(error)))
230
+ );
231
+ }
232
+ }
233
+ try {
234
+ for (const [component, error] of await recoverInterruptedComponentExtractions(CF_ROUTES_DIR)) {
235
+ if (!failedRecoveries.has(component)) failedRecoveries.set(component, error);
236
+ }
237
+ } catch (error) {
238
+ const recoveryError = error instanceof Error ? error : new Error(String(error));
239
+ harperLogger.warn(
240
+ 'Loading existing filesystem components without deploy recovery because staging could not be inspected:',
241
+ errorForLog(recoveryError)
242
+ );
243
+ }
116
244
  // Materialize hdb_secret global-tier rows into process.env and snapshot the scoped tier before
117
245
  // any application loads (root components — including the Pro custody registration — have
118
246
  // already loaded by this point). Re-runs on each reload cycle, which is how changed/late-custody
119
247
  // secrets heal. Never throws.
120
248
  await materializeGlobalSecrets();
121
249
  const cfsLoaded: Promise<any>[] = [];
250
+ const deferredRecoveries = new Map(
251
+ [...failedRecoveries].filter(([, error]) => error instanceof ComponentPreparationLockTimeoutError)
252
+ );
253
+ const unreportedFailedRecoveries = new Map(
254
+ [...failedRecoveries].filter(([, error]) => !(error instanceof ComponentPreparationLockTimeoutError))
255
+ );
256
+ const deferComponentLoad = (appName: string) => {
257
+ const appFolder = join(CF_ROUTES_DIR, appName);
258
+ const appWasVisible = existsSync(appFolder);
259
+ if (appWasVisible) {
260
+ componentLifecycle.loading(appName, `Component '${appName}' is waiting for in-progress preparation to finish`);
261
+ }
262
+ void serializeComponentLoad(appName, () =>
263
+ recoverInterruptedComponentExtraction(CF_ROUTES_DIR, appName)
264
+ .then(async () => {
265
+ if (!existsSync(appFolder)) {
266
+ if (appWasVisible) {
267
+ statusForComponent(appName).unknown('Component directory no longer exists after preparation settled');
268
+ }
269
+ return;
270
+ }
271
+ const mountResult = tryRootConfigMount(appName);
272
+ if (!mountResult.ok) return;
273
+ const loadedModules = new Set<any>();
274
+ await loadComponent(appFolder, cycleResources, HDB_ROOT_DIR_NAME, {
275
+ isRoot: false,
276
+ autoReload: false,
277
+ appName,
278
+ mount: mountResult.mount,
279
+ branchedDatabases: rootConfigBranchedDatabases(appName),
280
+ collectLoadedModules: loadedModules,
281
+ });
282
+ await readyComponentModules(loadedModules, readyComponentPromises);
283
+ })
284
+ .catch((error) => {
285
+ const recoveryError = error instanceof Error ? error : new Error(String(error));
286
+ if (appWasVisible) {
287
+ componentLifecycle.failed(
288
+ appName,
289
+ recoveryError,
290
+ `Component '${appName}' failed to load after waiting for in-progress preparation`
291
+ );
292
+ }
293
+ })
294
+ );
295
+ };
122
296
  if (existsSync(CF_ROUTES_DIR)) {
123
297
  const cfFolders = readdirSync(CF_ROUTES_DIR, { withFileTypes: true });
124
298
  for (const appEntry of cfFolders) {
@@ -127,35 +301,70 @@ export async function loadComponentDirectories(loadedPluginModules?: Map<any, an
127
301
  // Harper's own staging dirs (e.g. deploy aside copies) from loading as components.
128
302
  if (appEntry.name.startsWith('.')) continue;
129
303
  const appName = appEntry.name;
304
+ const recoveryError = failedRecoveries.get(appName);
305
+ if (recoveryError) {
306
+ if (recoveryError instanceof ComponentPreparationLockTimeoutError) {
307
+ deferredRecoveries.delete(appName);
308
+ deferComponentLoad(appName);
309
+ continue;
310
+ }
311
+ unreportedFailedRecoveries.delete(appName);
312
+ componentLifecycle.failed(
313
+ appName,
314
+ recoveryError,
315
+ `Component '${appName}' failed to load because its interrupted deployment could not be recovered`
316
+ );
317
+ continue;
318
+ }
130
319
  const appFolder = join(CF_ROUTES_DIR, appName);
131
320
  const mountResult = tryRootConfigMount(appName);
132
321
  if (!mountResult.ok) continue;
133
322
  cfsLoaded.push(
134
- loadComponent(appFolder, resources, HDB_ROOT_DIR_NAME, {
135
- isRoot: false,
136
- autoReload: false,
137
- appName,
138
- mount: mountResult.mount,
323
+ serializeComponentLoad(appName, () =>
324
+ loadComponent(appFolder, cycleResources, HDB_ROOT_DIR_NAME, {
325
+ isRoot: false,
326
+ autoReload: false,
327
+ appName,
328
+ mount: mountResult.mount,
329
+ branchedDatabases: rootConfigBranchedDatabases(appName),
330
+ })
331
+ ).catch((error) => {
332
+ const loadError = error instanceof Error ? error : new Error(String(error));
333
+ componentLifecycle.failed(appName, loadError, `Component '${appName}' failed to load`);
139
334
  })
140
335
  );
141
336
  }
142
337
  }
338
+ for (const [appName, recoveryError] of unreportedFailedRecoveries) {
339
+ componentLifecycle.failed(
340
+ appName,
341
+ recoveryError,
342
+ `Component '${appName}' failed to load because its interrupted deployment could not be recovered`
343
+ );
344
+ }
345
+ for (const appName of deferredRecoveries.keys()) deferComponentLoad(appName);
143
346
  const hdbAppFolder = process.env.RUN_HDB_APP;
144
347
  if (hdbAppFolder) {
145
348
  if (getWorkerIndex() === 0) harperLogger.info?.('Loading application from ' + hdbAppFolder);
146
349
  const mountResult = tryRootConfigMount(basename(hdbAppFolder));
147
350
  if (mountResult.ok) {
148
351
  cfsLoaded.push(
149
- loadComponent(hdbAppFolder, resources, hdbAppFolder, {
150
- isRoot: false,
151
- autoReload: Boolean(process.env.DEV_MODE),
152
- appName: hdbAppFolder,
153
- mount: mountResult.mount,
154
- })
352
+ serializeComponentLoad(hdbAppFolder, () =>
353
+ loadComponent(hdbAppFolder, cycleResources, hdbAppFolder, {
354
+ isRoot: false,
355
+ autoReload: Boolean(process.env.DEV_MODE),
356
+ // The directory arg above stays the absolute path -- that's a real filesystem
357
+ // location -- but `appName` here is the branch identity, and a branch path segment
358
+ // cannot contain `/`; use the same basename the config lookup on the next line uses.
359
+ appName: basename(hdbAppFolder),
360
+ mount: mountResult.mount,
361
+ branchedDatabases: rootConfigBranchedDatabases(basename(hdbAppFolder)),
362
+ })
363
+ )
155
364
  );
156
365
  }
157
366
  }
158
- return Promise.all(cfsLoaded).then(() => {
367
+ return await Promise.all(cfsLoaded).then(() => {
159
368
  watchesSetup = true;
160
369
  });
161
370
  }
@@ -233,6 +442,51 @@ export const loadedPaths = new Map();
233
442
  export const mainThreadInitialized = new Map<string, any>();
234
443
 
235
444
  let errorReporter;
445
+ /**
446
+ * Forget that a directory was loaded, so a throwaway load does not retain it forever. `loadedPaths` is
447
+ * keyed by realpath and never pruned, and every deploy validates a candidate under a fresh
448
+ * `.deploy-staging/<uuid>/` path — so without this the map grows by one dead entry per deploy for the life
449
+ * of the process.
450
+ */
451
+ export function forgetLoadedPath(componentDirectory: string): void {
452
+ let resolved: string | undefined;
453
+ try {
454
+ resolved = realpathSync(componentDirectory);
455
+ } catch {
456
+ // Already renamed live or discarded; fall through and prune by prefix anyway.
457
+ }
458
+ if (resolved) loadedPaths.delete(resolved);
459
+ // Nested `loadComponent()` calls register plugin and dependency realpaths UNDER the candidate, so
460
+ // deleting only the root leaves those behind — one dead entry per nested load, per deploy, forever.
461
+ const prefixes = [componentDirectory, resolved].filter(Boolean) as string[];
462
+ for (const key of loadedPaths.keys()) {
463
+ if (typeof key === 'string' && prefixes.some((prefix) => key === prefix || key.startsWith(prefix + sep))) {
464
+ loadedPaths.delete(key);
465
+ }
466
+ }
467
+ }
468
+
469
+ /**
470
+ * Release exactly the modules a throwaway validation load registered, as collected by that load's
471
+ * `collectLoadedModules` set.
472
+ *
473
+ * Exactly those, not a before/after diff of the global registry: validations are serialized with each other
474
+ * but not with ordinary loads, so a deferred real load for another component can register between the two
475
+ * snapshots — and a diff would then delete that live module.
476
+ */
477
+ export function forgetLoadedModules(modules: Iterable<any>): void {
478
+ // Only entries STILL owned by that validation. Validations serialize with each other but not with
479
+ // ordinary loads, so a real load can adopt a module the validation registered while it is still running —
480
+ // re-registering the same entry as live — and deleting it afterwards would take a live module with it.
481
+ for (const module of modules) {
482
+ if (loadedComponents.get(module) === VALIDATION_OWNED) loadedComponents.delete(module);
483
+ }
484
+ }
485
+
486
+ /** So a caller that installs a reporter can put the previous one back when it is done with it. */
487
+ export function getErrorReporter() {
488
+ return errorReporter;
489
+ }
236
490
  export function setErrorReporter(reporter) {
237
491
  errorReporter = reporter;
238
492
  }
@@ -252,22 +506,27 @@ export const getComponentName = () => compName;
252
506
  * every non-root component load and repaired if missing or pointing elsewhere.
253
507
  */
254
508
  function symlinkHarperModule(componentDirectory: string) {
255
- return new Promise<void>((resolve, reject) => {
509
+ return new Promise<void>((resolve) => {
256
510
  const store = Status.primaryStore;
257
- // Create timeout to avoid deadlocks
258
- const timeout = setTimeout(() => {
259
- store.unlock(componentDirectory);
260
- reject(new Error('symlinking harperdb module timed out'));
261
- }, 10_000);
262
-
263
- const callback = () => {
511
+ let timeout: NodeJS.Timeout;
512
+ const onUnlocked = () => {
264
513
  clearTimeout(timeout);
265
514
  resolve();
266
515
  };
267
- const lockAcquired = store.tryLock(componentDirectory, callback);
516
+ const lockAcquired = store.tryLock(componentDirectory, onUnlocked);
268
517
 
269
518
  if (!lockAcquired) {
270
- clearTimeout(timeout);
519
+ // The lock holder performs the fixup; wait for its unlock. The timer bounds the wait if
520
+ // the holder dies without unlocking, and must stay ref'd: the unlock wake arrives via an
521
+ // unref'd threadsafe function (see the invariant comment in threadServer.startServers).
522
+ // Timing out resolves rather than rejects: the fixup is idempotent maintenance, never
523
+ // worth failing the component load over.
524
+ timeout = setTimeout(() => {
525
+ harperLogger.warn(
526
+ `Timed out waiting for another thread to verify the harper module link in ${componentDirectory}; continuing with the link in its current state`
527
+ );
528
+ resolve();
529
+ }, 10_000);
271
530
  } else {
272
531
  try {
273
532
  // validate node_modules directory exists
@@ -311,6 +570,9 @@ function symlinkHarperModule(componentDirectory: string) {
311
570
  });
312
571
  }
313
572
 
573
+ // Direct access keeps lock timing deterministic without exposing a broader component-load seam.
574
+ export const _symlinkHarperModuleForTests = symlinkHarperModule;
575
+
314
576
  /**
315
577
  * This function handles the `handleApplication` call for a plugin in a sequential manner.
316
578
  * It ensures the execution of `handleApplication` happens on one thread at a time for a given scope.
@@ -421,11 +683,14 @@ export interface LoadComponentOptions {
421
683
  autoReload?: boolean;
422
684
  providedLoadedComponents?: Map<any, any>;
423
685
  appName?: string;
686
+ /** Databases this application forks, from its root-config entry (see `rootConfigBranchedDatabases`). */
687
+ branchedDatabases?: string[] | true;
424
688
  // When provided, every Scope created during this load is added to this set instead of being
425
689
  // auto-closed on worker shutdown. The caller then owns closing them. Used by transient loads
426
690
  // (e.g. the deploy pre-flight validation) so their deploy-lifecycle listeners don't accumulate
427
691
  // across deploys (#1462).
428
692
  collectScopes?: Set<Scope>;
693
+ collectLoadedModules?: Set<any>;
429
694
  // Routing the operator declared for this application in the root config (`host`/`urlPath` on
430
695
  // the application's entry). Applied to every plugin scope this load creates, and inherited by
431
696
  // components the application itself declares, so the whole subtree moves together.
@@ -457,6 +722,7 @@ export async function loadComponent(
457
722
  autoReload,
458
723
  appName,
459
724
  mount,
725
+ collectLoadedModules,
460
726
  } = options;
461
727
  applicationScope.runtimeRoot ??= resolvedFolder;
462
728
  applicationScope.allowedPath ??= realpathSync(componentDirectory);
@@ -477,6 +743,36 @@ export async function loadComponent(
477
743
  }
478
744
  applicationScope.config ??= config;
479
745
 
746
+ // Before any of the application's modules are imported: a branch has to exist by the time its
747
+ // code first reaches `databases`, and a declared branch that cannot be created must fail this
748
+ // application's load rather than let it run against the base it asked not to share.
749
+ // Declaring it in the application's own config.yaml is refused rather than ignored: it is a
750
+ // deployment decision and lives in the root config, and an application that believed it had a
751
+ // private fork while silently sharing the base is the one outcome this feature exists to stop.
752
+ if (!isRoot && config?.branchedDatabases !== undefined) {
753
+ const misplaced =
754
+ `Application '${options.appName ?? basename(componentDirectory)}' declares branchedDatabases in its own ` +
755
+ `config; it belongs in the root config entry for the application, alongside host and urlPath`;
756
+ // Logged as well as thrown: a component load that rejects this way surfaces downstream only as
757
+ // the application's routes and operations being absent, which says nothing about the cause.
758
+ harperLogger.error?.(misplaced);
759
+ throw new Error(misplaced);
760
+ }
761
+ // Only on the application's own load: nested components share its scope and its branches, and
762
+ // re-preparing per component would key a second branch off the same application name.
763
+ if (!isRoot && !options.applicationScope && options.branchedDatabases !== undefined) {
764
+ // The loader's own application identity, not the directory's basename: a branch path is
765
+ // keyed by this, and two components can share a basename (a nested one and a top-level one)
766
+ // while being different applications that must not share a fork each believes is private.
767
+ const branchAppName = options.appName ?? basename(componentDirectory);
768
+ assertBranchedDatabases(branchAppName, options.branchedDatabases);
769
+ applicationScope.branches = await prepareBranches(
770
+ branchAppName,
771
+ options.branchedDatabases,
772
+ applicationScope.mode
773
+ );
774
+ }
775
+
480
776
  // For non-root components with empty/null config (e.g., comment-only YAML),
481
777
  // don't synthesize DEFAULT_CONFIG. Empty config means the component has nothing
482
778
  // to load; falling back to DEFAULT_CONFIG would cause OptionsWatcher to wait
@@ -493,7 +789,10 @@ export async function loadComponent(
493
789
  // methods. Per-entry errors are logged and skipped by `bootstrapModels`.
494
790
  // Awaited so module-backed entries (#1471) finish importing before the
495
791
  // per-component iteration below; built-in entries register synchronously.
496
- if (isRoot) await bootstrapModels(config);
792
+ if (isRoot) {
793
+ await bootstrapModels(config);
794
+ startModelsConfigHotReload();
795
+ }
497
796
 
498
797
  // The `env:` block declares the component's environment expectations (string literal →
499
798
  // process.env; object → declaration satisfied from the hdb_secret store / process.env).
@@ -601,6 +900,7 @@ export async function loadComponent(
601
900
  autoReload: false,
602
901
  appName: appName || componentName,
603
902
  collectScopes: options.collectScopes,
903
+ collectLoadedModules,
604
904
  // `host`/`urlPath` on this entry route the component being loaded. For an
605
905
  // application (no plugin module of its own) that entry is the only place an
606
906
  // operator can say where the app is served — its own config.yaml declares the
@@ -640,7 +940,7 @@ export async function loadComponent(
640
940
  // our own trusted modules can be directly retrieved from our map, otherwise use the (configurable) secure module loader
641
941
  const ensureTable = (options: any) => {
642
942
  options.origin = origin;
643
- return table(options);
943
+ return scopedTableFactory(applicationScope.branches)(options);
644
944
  };
645
945
  // call the main start hook
646
946
  const network =
@@ -792,7 +1092,17 @@ export async function loadComponent(
792
1092
  resources,
793
1093
  ...componentConfig,
794
1094
  })) || extensionModule;
795
- loadedComponents.set(extensionModule, true);
1095
+ // `collectLoadedModules` serves two different purposes, so the two decisions below are made
1096
+ // separately. A deferred ORDINARY load passes one too, to await readiness — for that it has to
1097
+ // collect what it loaded whether or not the module was already registered. Only a VALIDATION
1098
+ // restricts its set, because there the set doubles as the cleanup list and a shared
1099
+ // `rest`/`graphql` module already live from a real load must not go on it.
1100
+ const validating = isDeployValidating();
1101
+ if (!validating || !loadedComponents.has(extensionModule)) collectLoadedModules?.add(extensionModule);
1102
+ // Ownership follows the validation CONTEXT, not the presence of a collect set. Keying it on the
1103
+ // set labelled a deferred ordinary load's registrations validation-owned, which would let the
1104
+ // next validation that collects that module delete a live one.
1105
+ loadedComponents.set(extensionModule, validating ? VALIDATION_OWNED : true);
796
1106
 
797
1107
  if (
798
1108
  (extensionModule.handleFile ||