@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
@@ -1,4 +1,5 @@
1
1
  import type { Resources } from '../resources/Resources.ts';
2
+ import type { BranchDatabase } from '../resources/databases.ts';
2
3
  import { type Server } from '../server/Server.ts';
3
4
  import { forComponent } from '../utility/logging/harper_logger.ts';
4
5
  import { scopedImport } from '../security/jsLoader.ts';
@@ -28,6 +29,13 @@ export class ApplicationScope {
28
29
  allowedPath?: string;
29
30
  runtimeRoot?: string;
30
31
  config: any;
32
+ /**
33
+ * Private forks of the databases this application declared, keyed by the LOGICAL name its code
34
+ * uses (`data`). Present only for a branched application; `getHarperExports` reads it to build
35
+ * the scoped `databases` binding, and an unbranched scope leaves it undefined so that binding
36
+ * stays the process-wide singleton by identity.
37
+ */
38
+ branches?: Map<string, BranchDatabase>;
31
39
  moduleCache: any; // used by the loader to retain a cache of modules, type is an internal detail of the loader
32
40
  #runtimeModules: RuntimeModuleTracker;
33
41
  constructor(name: string, resources: Resources, server: Server, isInternal = false) {
@@ -4,17 +4,20 @@ import { createHash } from 'node:crypto';
4
4
  import type { Stats } from 'node:fs';
5
5
  import { EventEmitter } from 'node:events';
6
6
  import { Component, FileAndURLPathConfig } from './Component.ts';
7
- import chokidar, { FSWatcher, FSWatcherEventMap } from 'chokidar';
8
- import { join } from 'node:path';
7
+ import { FSWatcher, FSWatcherEventMap } from 'chokidar';
8
+ import { isAbsolute, join } from 'node:path';
9
9
  import { readFile } from 'node:fs/promises';
10
10
  import { FilesOption } from './deriveGlobOptions.ts';
11
11
  import { deriveURLPath } from './deriveURLPath.ts';
12
12
  import { isMatch } from 'micromatch';
13
13
  import {
14
14
  DIRECTORY_POLLING_FALLBACK_OPTIONS,
15
+ claimLostNativeWatchError,
16
+ guardedWatch,
15
17
  isWatcherExhaustionError,
16
18
  warnWatcherFallback,
17
19
  } from '../utility/watcherFallback.ts';
20
+ import { resolveWatchTarget } from '../utility/watchPath.ts';
18
21
 
19
22
  export interface BaseEntry {
20
23
  stats?: Stats;
@@ -391,6 +394,11 @@ export class EntryHandler extends EventEmitter<EntryHandlerEventMap> {
391
394
  }
392
395
 
393
396
  #handleWatcherError(error: unknown): void {
397
+ // A lost native watch handle (the watched tree was deleted or replaced) is
398
+ // benign and not actionable by a consumer. chokidar's non-persistent branch
399
+ // never routes it here today — installLostNativeWatchGuard() catches it at
400
+ // the process instead — but the polling branch and a fixed chokidar would.
401
+ if (claimLostNativeWatchError(error)) return;
394
402
  if (isWatcherExhaustionError(error)) {
395
403
  // Swallow every exhaustion error — chokidar can emit several before the
396
404
  // failed native watcher closes, and we don't want a flurry of ENOSPC to
@@ -536,45 +544,57 @@ export class EntryHandler extends EventEmitter<EntryHandlerEventMap> {
536
544
  readFailures: new Map(),
537
545
  };
538
546
 
539
- const allowedBases = this.#component.patternBases.map((base) => join(this.#component.directory, base));
547
+ // `ignored` receives absolute paths built from `cwd`, so its bases must come from the same
548
+ // directory spelling. Event paths are relative to `cwd`, so reads below stay on `this.directory`.
549
+ const watchTarget = resolveWatchTarget(this.#component.directory);
550
+ if (watchTarget.mustPoll) this.#usingPolling = true;
551
+ const watchDirectory = watchTarget.path;
552
+ const normalizedDirectory = watchDirectory.replace(/\\/g, '/');
553
+ const normalizedBases = this.#component.patternBases.map((base) => join(watchDirectory, base).replace(/\\/g, '/'));
554
+
555
+ // chokidar resolves a relative pattern base against `cwd`, but an absolute one reaches the
556
+ // native watch as spelled, bypassing the canonicalized `cwd` above.
557
+ let watchPattern = this.#component.commonPatternBase;
558
+ if (isAbsolute(watchPattern)) {
559
+ const patternTarget = resolveWatchTarget(watchPattern);
560
+ if (patternTarget.mustPoll) this.#usingPolling = true;
561
+ watchPattern = patternTarget.path;
562
+ }
540
563
 
541
564
  this.#openCount++;
542
- const watcher = (this.#watcher = chokidar
543
- .watch(this.#component.commonPatternBase, {
544
- cwd: this.#component.directory,
545
- persistent: false,
546
- followSymlinks: false,
547
- ...(this.#usingPolling ? DIRECTORY_POLLING_FALLBACK_OPTIONS : {}),
548
- ignored: (path) => {
549
- const normalizedPath = path.replace(/\\/g, '/');
550
- const normalizedBases = allowedBases.map((base) => base.replace(/\\/g, '/'));
551
- const normalizedDirectory = this.#component.directory.replace(/\\/g, '/');
552
-
553
- // Determine the path relative to the component directory. Leading '/' is preserved
554
- // (or empty when the path *is* the component directory) so the regex anchors below
555
- // can use `(?:^|/)` to match the first segment without false positives on names
556
- // that merely contain the same substring (e.g. `mynode_modules`, `notgit`).
557
- const relativePath = normalizedPath.startsWith(normalizedDirectory)
558
- ? normalizedPath.slice(normalizedDirectory.length)
559
- : normalizedPath;
560
-
561
- // Skip node_modules at any depth. This allows plugins loaded from node_modules
562
- // to still watch their own component files while ignoring their dependencies.
563
- if (/(?:^|\/)node_modules(?:\/|$)/.test(relativePath)) return true;
564
-
565
- // Skip transient package manager and VCS artifacts. Without these, an in-place
566
- // `npm install` during a component deploy writes log files and atomic-rename
567
- // temp directories that fire change events and drive an auto-reload restart
568
- // storm — see harper#488.
569
- if (/(?:^|\/)\.git(?:\/|$)/.test(relativePath)) return true;
570
- if (/(?:^|\/)\.tmp-/.test(relativePath)) return true;
571
- if (/(?:^|\/)(?:npm-debug|yarn-error|yarn-debug|pnpm-debug)\.log(?:\/|$)/.test(relativePath)) return true;
572
-
573
- return (
574
- normalizedPath !== normalizedDirectory && normalizedBases.every((base) => !normalizedPath.startsWith(base))
575
- );
576
- },
577
- })
565
+ const watcher = (this.#watcher = guardedWatch(watchPattern, {
566
+ cwd: watchDirectory,
567
+ persistent: false,
568
+ followSymlinks: false,
569
+ ...(this.#usingPolling ? DIRECTORY_POLLING_FALLBACK_OPTIONS : {}),
570
+ ignored: (path) => {
571
+ const normalizedPath = path.replace(/\\/g, '/');
572
+
573
+ // Determine the path relative to the component directory. Leading '/' is preserved
574
+ // (or empty when the path *is* the component directory) so the regex anchors below
575
+ // can use `(?:^|/)` to match the first segment without false positives on names
576
+ // that merely contain the same substring (e.g. `mynode_modules`, `notgit`).
577
+ const relativePath = normalizedPath.startsWith(normalizedDirectory)
578
+ ? normalizedPath.slice(normalizedDirectory.length)
579
+ : normalizedPath;
580
+
581
+ // Skip node_modules at any depth. This allows plugins loaded from node_modules
582
+ // to still watch their own component files while ignoring their dependencies.
583
+ if (/(?:^|\/)node_modules(?:\/|$)/.test(relativePath)) return true;
584
+
585
+ // Skip transient package manager and VCS artifacts. Without these, an in-place
586
+ // `npm install` during a component deploy writes log files and atomic-rename
587
+ // temp directories that fire change events and drive an auto-reload restart
588
+ // storm — see harper#488.
589
+ if (/(?:^|\/)\.git(?:\/|$)/.test(relativePath)) return true;
590
+ if (/(?:^|\/)\.tmp-/.test(relativePath)) return true;
591
+ if (/(?:^|\/)(?:npm-debug|yarn-error|yarn-debug|pnpm-debug)\.log(?:\/|$)/.test(relativePath)) return true;
592
+
593
+ return (
594
+ normalizedPath !== normalizedDirectory && normalizedBases.every((base) => !normalizedPath.startsWith(base))
595
+ );
596
+ },
597
+ })
578
598
  .on('all', (...args) => this.#handleAll(generation, ...args))
579
599
  .on('error', (error) => {
580
600
  if (generation === this.#watchGeneration) this.#handleWatcherError(error);
@@ -2,12 +2,22 @@ import { type Logger } from '../utility/logging/logger.ts';
2
2
  import { loggerWithTag } from '../utility/logging/harper_logger.ts';
3
3
  import { EventEmitter, once } from 'events';
4
4
  import yaml from 'yaml';
5
- import chokidar, { type FSWatcher } from 'chokidar';
5
+ import { type FSWatcher } from 'chokidar';
6
6
  import { readFile } from 'node:fs/promises';
7
+ import { readFileSync } from 'node:fs';
7
8
  import { isDeepStrictEqual } from 'util';
8
9
  import { DEFAULT_CONFIG } from './DEFAULT_CONFIG.ts';
9
10
  import { cloneDeep } from 'lodash';
10
- import { POLLING_FALLBACK_OPTIONS, isWatcherExhaustionError, warnWatcherFallback } from '../utility/watcherFallback.ts';
11
+ import {
12
+ POLLING_FALLBACK_OPTIONS,
13
+ PartialReadRetry,
14
+ claimLostNativeWatchError,
15
+ guardedWatch,
16
+ isPartialReadError,
17
+ isWatcherExhaustionError,
18
+ warnWatcherFallback,
19
+ } from '../utility/watcherFallback.ts';
20
+ import { resolveWatchTarget } from '../utility/watchPath.ts';
11
21
  import { overlayRootEnvConfig, isRootConfigFilename } from '../config/harperConfigEnvVars.ts';
12
22
 
13
23
  export interface Config {
@@ -84,6 +94,7 @@ export class CannotSetPropertyError extends Error {
84
94
  */
85
95
  export class OptionsWatcher extends EventEmitter<OptionsWatcherEventMap> {
86
96
  #filePath: string;
97
+ #watchPath: string;
87
98
  #watcher!: FSWatcher;
88
99
  #scopedConfig?: ConfigValue;
89
100
  #rootConfig?: Config;
@@ -94,18 +105,22 @@ export class OptionsWatcher extends EventEmitter<OptionsWatcherEventMap> {
94
105
  #closed: boolean;
95
106
  #openCount: number = 0;
96
107
  #pendingReads: Set<Promise<void>> = new Set();
108
+ #partialRead: PartialReadRetry;
97
109
  ready: Promise<any[]>;
98
110
 
99
111
  constructor(name: string, filePath: string, logger?: Logger, isRootConfig?: boolean) {
100
112
  super();
101
113
  this.#name = name;
102
114
  this.#filePath = filePath;
115
+ const watchTarget = resolveWatchTarget(filePath);
116
+ this.#watchPath = watchTarget.path;
117
+ this.#partialRead = new PartialReadRetry(filePath);
103
118
  // Root-config watchers must see runtime env config (HARPER_SET_CONFIG et al.)
104
119
  // even when it hasn't been flushed to disk yet — see #handleChange (#1618).
105
120
  // Application scopes watch their own config.yaml and are never overlaid.
106
121
  this.#isRootConfig = isRootConfig ?? isRootConfigFilename(filePath);
107
122
  this.#logger = logger || loggerWithTag(name);
108
- this.#usingPolling = false;
123
+ this.#usingPolling = watchTarget.mustPoll;
109
124
  this.#closed = false;
110
125
  this.ready = once(this, 'ready');
111
126
  this.#openWatcher();
@@ -113,11 +128,10 @@ export class OptionsWatcher extends EventEmitter<OptionsWatcherEventMap> {
113
128
 
114
129
  #openWatcher() {
115
130
  this.#openCount++;
116
- this.#watcher = chokidar
117
- .watch(this.#filePath, {
118
- persistent: false,
119
- ...(this.#usingPolling ? POLLING_FALLBACK_OPTIONS : {}),
120
- })
131
+ this.#watcher = guardedWatch(this.#watchPath, {
132
+ persistent: false,
133
+ ...(this.#usingPolling ? POLLING_FALLBACK_OPTIONS : {}),
134
+ })
121
135
  .on('add', this.#handleChange.bind(this))
122
136
  .on('change', this.#handleChange.bind(this))
123
137
  .on('error', this.#handleError.bind(this))
@@ -125,73 +139,127 @@ export class OptionsWatcher extends EventEmitter<OptionsWatcherEventMap> {
125
139
  .on('ready', this.#handleChange.bind(this));
126
140
  }
127
141
 
142
+ // Root config only: see the descriptor-lifetime invariant on atomicWriteFile (DESIGN.md).
128
143
  #handleChange() {
144
+ if (this.#isRootConfig) {
145
+ this.#applyRead(() => readFileSync(this.#filePath, 'utf-8'));
146
+ return;
147
+ }
129
148
  const read: Promise<void> = readFile(this.#filePath, 'utf-8')
130
- .then((contents) => {
131
- let parsed = yaml.parse(contents);
132
- // The on-disk root config is not guaranteed to include runtime env config at
133
- // boot: the file flush races component loading, so a scope's boot-time reads
134
- // (e.g. an `enabled` gate in handleApplication) could observe pre-env values
135
- // the componentLoader itself never saw. Ask the config layer to overlay env
136
- // config onto EVERY root-config read so scope.options matches the resolved
137
- // view (#1618). Non-root scopes and the no-env-vars case are untouched
138
- // (overlayRootEnvConfig is a no-op there).
139
- if (this.#isRootConfig) parsed = overlayRootEnvConfig(parsed);
140
- this.#rootConfig = parsed && typeof parsed === 'object' ? parsed : undefined;
141
- // If the extension is in the config file
142
- if (this.#rootConfig && this.#name in this.#rootConfig) {
143
- // If a config object does not exist
144
- if (!this.#scopedConfig) {
145
- // set it
146
- this.#scopedConfig = this.#rootConfig[this.#name];
147
- // and emit a ready event
148
- this.emit('ready', this.#scopedConfig);
149
- } else {
150
- // Otherwise, merge the new config with the old config
151
- this.#merge(this.#rootConfig[this.#name], this.#scopedConfig);
152
- }
153
- } else {
154
- // Otherwise, if the extension is not in the config file
155
- // This means the plugin was removed from the config file
156
- if (this.#scopedConfig) {
157
- // and a config exists, remove it
158
- this.#scopedConfig = undefined;
159
- this.emit('remove');
160
- }
161
- // Otherwise do nothing - the user may add the config back in later
162
- }
163
- })
164
- .catch((error) => {
165
- // If the config file does not exist
166
- if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
167
- // A readFile ENOENT here is the install window (file not written yet) or a
168
- // transient read race — NOT a real deletion, which chokidar routes to
169
- // `#handleUnlink`. Env config is file-independent, so when it provides this
170
- // scope the missing file must not discard it (#1618). When it does not, fall
171
- // through to the original ENOENT handling with #rootConfig untouched, so a
172
- // first boot still emits `ready` (not `remove`, which nothing consumes at
173
- // boot → `ready` would hang forever).
174
- if (this.#applyEnvOnlyConfig()) return;
175
- // And a config already exists, reset it to the default
176
- if (this.#rootConfig) {
177
- this.#resetConfig();
178
- this.emit('remove');
179
- } else {
180
- // Otherwise, if no config exists, then just set to default and emit ready
181
- this.#resetConfig();
182
- this.emit('ready');
183
- }
184
- return;
185
- }
186
- this.emit('error', error);
187
- })
149
+ .then((contents) => this.#applyRead(() => contents))
150
+ .catch((error) => this.#recoverOrReport(error))
188
151
  .finally(() => {
189
152
  this.#pendingReads.delete(read);
190
153
  });
191
154
  this.#pendingReads.add(read);
192
155
  }
193
156
 
157
+ #applyRead(read: () => string) {
158
+ let parsed;
159
+ try {
160
+ parsed = yaml.parse(read());
161
+ } catch (error) {
162
+ // A read or parse that fails while the file is being replaced is the same event as an
163
+ // incomplete one, and #handleReadError's ENOENT arm would answer it with a `remove`
164
+ // that restarts the scope. Re-read first; only an exhausted budget means it is real.
165
+ this.#recoverOrReport(error);
166
+ return;
167
+ }
168
+ // Tested on the file's own parse, before any env overlay: `''`, `'\n'` and a truncated
169
+ // document all parse to null, and an env-configured deployment would otherwise overlay
170
+ // one into a valid-looking object and adopt it. A file that is still unusable once the
171
+ // budget is spent is taken at face value, so emptying one still reaches `remove`.
172
+ if (!parsed || typeof parsed !== 'object') {
173
+ if (this.#partialRead.schedule(() => this.#handleChange())) return;
174
+ this.#partialRead.gaveUp();
175
+ } else {
176
+ this.#partialRead.settled();
177
+ }
178
+ try {
179
+ this.#applyParsed(this.#overlayEnvConfig(parsed));
180
+ } catch (error) {
181
+ // Applying is past the point where an incomplete file could explain a failure, so a
182
+ // listener's throw keeps the error route rather than being retried.
183
+ this.emit('error', error);
184
+ }
185
+ }
186
+
187
+ #recoverOrReport(error: unknown) {
188
+ if (!isPartialReadError(error)) return this.#handleReadError(error);
189
+ if (this.#partialRead.schedule(() => this.#handleChange())) return;
190
+ // Same give-up as the unusable-parse case, so the budget is restored for the repair: the
191
+ // write that fixes the file can itself be read mid-write. The error still takes the
192
+ // scope's own route.
193
+ this.#partialRead.gaveUp(error);
194
+ this.#handleReadError(error);
195
+ }
196
+
197
+ #overlayEnvConfig(parsed: unknown) {
198
+ // The on-disk root config is not guaranteed to include runtime env config at
199
+ // boot: the file flush races component loading, so a scope's boot-time reads
200
+ // (e.g. an `enabled` gate in handleApplication) could observe pre-env values
201
+ // the componentLoader itself never saw. Ask the config layer to overlay env
202
+ // config onto EVERY root-config read so scope.options matches the resolved
203
+ // view (#1618). Non-root scopes and the no-env-vars case are untouched
204
+ // (overlayRootEnvConfig is a no-op there).
205
+ return this.#isRootConfig ? overlayRootEnvConfig(parsed) : parsed;
206
+ }
207
+
208
+ #applyParsed(parsed: unknown) {
209
+ this.#rootConfig = parsed && typeof parsed === 'object' ? (parsed as Config) : undefined;
210
+ // If the extension is in the config file
211
+ if (this.#rootConfig && this.#name in this.#rootConfig) {
212
+ // If a config object does not exist
213
+ if (!this.#scopedConfig) {
214
+ // set it
215
+ this.#scopedConfig = this.#rootConfig[this.#name];
216
+ // and emit a ready event
217
+ this.emit('ready', this.#scopedConfig);
218
+ } else {
219
+ // Otherwise, merge the new config with the old config
220
+ this.#merge(this.#rootConfig[this.#name], this.#scopedConfig);
221
+ }
222
+ } else {
223
+ // Otherwise, if the extension is not in the config file
224
+ // This means the plugin was removed from the config file
225
+ if (this.#scopedConfig) {
226
+ // and a config exists, remove it
227
+ this.#scopedConfig = undefined;
228
+ this.emit('remove');
229
+ }
230
+ // Otherwise do nothing - the user may add the config back in later
231
+ }
232
+ }
233
+
234
+ #handleReadError(error: unknown) {
235
+ // If the config file does not exist
236
+ if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
237
+ // A readFile ENOENT here is the install window (file not written yet) or a
238
+ // transient read race — NOT a real deletion, which chokidar routes to
239
+ // `#handleUnlink`. Env config is file-independent, so when it provides this
240
+ // scope the missing file must not discard it (#1618). When it does not, fall
241
+ // through to the original ENOENT handling with #rootConfig untouched, so a
242
+ // first boot still emits `ready` (not `remove`, which nothing consumes at
243
+ // boot → `ready` would hang forever).
244
+ if (this.#applyEnvOnlyConfig()) return;
245
+ // And a config already exists, reset it to the default
246
+ if (this.#rootConfig) {
247
+ this.#resetConfig();
248
+ this.emit('remove');
249
+ } else {
250
+ // Otherwise, if no config exists, then just set to default and emit ready
251
+ this.#resetConfig();
252
+ this.emit('ready');
253
+ }
254
+ return;
255
+ }
256
+ this.emit('error', error);
257
+ }
258
+
194
259
  #handleError(error: unknown) {
260
+ // See EntryHandler.#handleWatcherError: a lost native watch handle is benign
261
+ // and must not be surfaced to consumers as a config-watch failure.
262
+ if (claimLostNativeWatchError(error)) return;
195
263
  if (isWatcherExhaustionError(error)) {
196
264
  // Swallow every exhaustion error — chokidar can emit several before the
197
265
  // failed native watcher closes, and we don't want a flurry of ENOSPC to
@@ -199,18 +267,17 @@ export class OptionsWatcher extends EventEmitter<OptionsWatcherEventMap> {
199
267
  if (!this.#usingPolling) {
200
268
  warnWatcherFallback(this.#filePath);
201
269
  this.#usingPolling = true;
202
- // Close the failed native watcher and reopen with polling. Guard
203
- // against reopen-after-close: the caller may have invoked close()
204
- // while this teardown was in flight. The .catch is required because
205
- // `finally` would re-raise a teardown rejection as an unhandled one.
206
- this.#watcher
207
- .close()
270
+ // Start close() from a microtask, not directly here, so a synchronous throw
271
+ // can't escape this 'error' listener as an uncaught exception.
272
+ Promise.resolve()
273
+ .then(() => this.#watcher.close())
208
274
  .catch(() => {
209
275
  // Teardown errors on an already-failed watcher are not actionable.
210
276
  })
211
- .finally(() => {
277
+ .then(() => {
212
278
  if (!this.#closed) this.#openWatcher();
213
- });
279
+ })
280
+ .catch((error) => this.#logger.error?.(`Could not reopen the ${this.#filePath} watch on polling:`, error));
214
281
  }
215
282
  return;
216
283
  }
@@ -385,6 +452,14 @@ export class OptionsWatcher extends EventEmitter<OptionsWatcherEventMap> {
385
452
  this.emit('change', keys, value, this.#scopedConfig);
386
453
  }
387
454
 
455
+ // Test-only: run the change handler directly, since the read's timing relative to its caller
456
+ // is the behaviour under test and a chokidar event cannot be observed at that granularity.
457
+ // Resolves once the read has landed, which for the root config has already happened.
458
+ _handleChangeForTests(): Promise<unknown> {
459
+ this.#handleChange();
460
+ return Promise.allSettled([...this.#pendingReads]);
461
+ }
462
+
388
463
  // Test-only: simulate the underlying chokidar watcher emitting an error.
389
464
  // Exposed so the polling-fallback path can be exercised without triggering a
390
465
  // real ENOSPC/EMFILE on the host.
@@ -411,6 +486,7 @@ export class OptionsWatcher extends EventEmitter<OptionsWatcherEventMap> {
411
486
  */
412
487
  close(): Promise<this> {
413
488
  this.#closed = true;
489
+ this.#partialRead.cancel();
414
490
  const pendingReads = [...this.#pendingReads];
415
491
  const watcherClose = Promise.resolve(this.#watcher.close()).catch(() => {});
416
492
 
@@ -1,5 +1,5 @@
1
1
  import { createHash } from 'node:crypto';
2
- import { lstatSync, readFileSync, readlinkSync } from 'node:fs';
2
+ import { lstatSync, readFileSync, readlinkSync, realpathSync } from 'node:fs';
3
3
  import { lstat, readFile, readlink } from 'node:fs/promises';
4
4
  import { createRequire, Module } from 'node:module';
5
5
  import { dirname, isAbsolute, relative, resolve, sep } from 'node:path';
@@ -43,7 +43,7 @@ export class RuntimeModuleTracker {
43
43
  recordModule(moduleUrl: string, source: Source): void {
44
44
  const modulePath = this.#localPath(moduleUrl);
45
45
  if (!modulePath) return;
46
- if (!this.#modules.has(modulePath)) this.#modules.set(modulePath, digest(source));
46
+ if (!this.#modules.has(modulePath)) this.#modules.set(modulePath, moduleDigest(modulePath, source));
47
47
  if (this.#deployInFlight) this.#loadedDuringDeploy = true;
48
48
  }
49
49
 
@@ -78,7 +78,7 @@ export class RuntimeModuleTracker {
78
78
  const changed = await Promise.all(
79
79
  modules.slice(start, start + MODULE_COMPARE_CONCURRENCY).map(async ([modulePath, previousDigest]) => {
80
80
  try {
81
- return digest(await readFile(modulePath)) !== previousDigest;
81
+ return moduleDigest(modulePath, await readFile(modulePath)) !== previousDigest;
82
82
  } catch {
83
83
  return true;
84
84
  }
@@ -138,8 +138,21 @@ function higherPriorityResolutionCandidates(
138
138
  const candidates = [...new Set(RESOLUTION_EXTENSIONS.map((extension) => basePath + extension))];
139
139
  candidates.push(resolve(basePath, 'package.json'));
140
140
  for (const extension of RESOLUTION_EXTENSIONS.slice(1)) candidates.push(resolve(basePath, `index${extension}`));
141
- const resolvedIndex = candidates.indexOf(resolvedPath);
142
- if (resolvedIndex === -1) return;
141
+ let resolvedIndex = candidates.indexOf(resolvedPath);
142
+ if (resolvedIndex === -1) {
143
+ let canonicalResolvedPath = resolvedPath;
144
+ try {
145
+ canonicalResolvedPath = realpathSync(resolvedPath);
146
+ } catch {}
147
+ resolvedIndex = candidates.findIndex((candidate) => {
148
+ try {
149
+ return realpathSync(candidate) === canonicalResolvedPath;
150
+ } catch {
151
+ return false;
152
+ }
153
+ });
154
+ }
155
+ if (resolvedIndex === -1) return candidates.slice(0, RESOLUTION_EXTENSIONS.length + 1);
143
156
  return candidates.slice(0, resolvedIndex);
144
157
  }
145
158
 
@@ -149,7 +162,7 @@ function candidateState(path: string): string {
149
162
  if (stats.isSymbolicLink()) return `link:${readlinkSync(path)}`;
150
163
  if (stats.isDirectory()) return 'directory';
151
164
  if (!stats.isFile()) return 'other';
152
- return path.endsWith('package.json') ? `file:${digest(readFileSync(path))}` : 'file';
165
+ return path.endsWith('package.json') ? `file:${moduleDigest(path, readFileSync(path))}` : 'file';
153
166
  } catch (error) {
154
167
  if ((error as NodeJS.ErrnoException).code === 'ENOENT') return 'missing';
155
168
  return `error:${(error as NodeJS.ErrnoException).code ?? 'unknown'}`;
@@ -162,7 +175,7 @@ async function candidateStateAsync(path: string): Promise<string> {
162
175
  if (stats.isSymbolicLink()) return `link:${await readlink(path)}`;
163
176
  if (stats.isDirectory()) return 'directory';
164
177
  if (!stats.isFile()) return 'other';
165
- return path.endsWith('package.json') ? `file:${digest(await readFile(path))}` : 'file';
178
+ return path.endsWith('package.json') ? `file:${moduleDigest(path, await readFile(path))}` : 'file';
166
179
  } catch (error) {
167
180
  if ((error as NodeJS.ErrnoException).code === 'ENOENT') return 'missing';
168
181
  return `error:${(error as NodeJS.ErrnoException).code ?? 'unknown'}`;
@@ -187,3 +200,21 @@ function invalidateResolutionCache(specifier: string, referrerPath: string, prev
187
200
  function digest(source: Source): string {
188
201
  return createHash('sha256').update(source).digest('base64');
189
202
  }
203
+
204
+ function moduleDigest(path: string, source: Source): string {
205
+ if (path.endsWith('package.json')) {
206
+ try {
207
+ return digest(JSON.stringify(canonicalizeJSON(JSON.parse(source.toString()))));
208
+ } catch {}
209
+ }
210
+ return digest(source);
211
+ }
212
+
213
+ function canonicalizeJSON(value: unknown): unknown {
214
+ if (Array.isArray(value)) return value.map(canonicalizeJSON);
215
+ if (!value || typeof value !== 'object') return value;
216
+ const canonical: Record<string, unknown> = Object.create(null);
217
+ for (const key of Object.keys(value).sort())
218
+ canonical[key] = canonicalizeJSON((value as Record<string, unknown>)[key]);
219
+ return canonical;
220
+ }
@@ -1,7 +1,7 @@
1
1
  import { type Logger } from '../utility/logging/logger.ts';
2
2
  import { loggerWithTag } from '../utility/logging/harper_logger.ts';
3
3
  import { EventEmitter, once } from 'node:events';
4
- import { databaseEventsEmitter, table } from '../resources/databases.ts';
4
+ import { databaseEventsEmitter, scopedTableFactory } from '../resources/databases.ts';
5
5
  import { server, type Server } from '../server/Server.ts';
6
6
  import { EntryHandler, type EntryHandlerEventMap, type onEntryEventHandler } from './EntryHandler.ts';
7
7
  import { OptionsWatcher, OptionsWatcherEventMap } from './OptionsWatcher.ts';
@@ -241,7 +241,7 @@ export class Scope extends EventEmitter<ScopeEventsMap> {
241
241
 
242
242
  ensureTable<TableResourceType = unknown>(options: any): TableResourceType {
243
243
  options.origin = this.#origin;
244
- return table<TableResourceType>(options);
244
+ return scopedTableFactory(this.applicationScope?.branches)<TableResourceType>(options);
245
245
  }
246
246
 
247
247
  #handleOptionsWatcherReady(): void {
@@ -461,33 +461,55 @@ export class Scope extends EventEmitter<ScopeEventsMap> {
461
461
  targetEntryHandler: EntryHandler,
462
462
  entryEventHandler: onEntryEventHandler
463
463
  ): onEntryEventHandler => {
464
- const pendingOperations = new Set<Promise<void>>();
464
+ // Retained until the drain below reports them: an operation dropped as it settles is invisible
465
+ // to that drain, so a handler rejecting before `ready` would report nothing at all.
466
+ let initialOperations: Promise<void>[] | null = [];
465
467
 
466
468
  const wrapped: onEntryEventHandler = (entry) => {
467
- const result = entryEventHandler(entry);
469
+ let result;
470
+ try {
471
+ result = entryEventHandler(entry);
472
+ } catch (error) {
473
+ // A synchronous throw is the same failure as a rejection. Left to propagate, EntryHandler
474
+ // catches it for its own reporting and the initial load completes as if nothing failed.
475
+ result = Promise.reject(error);
476
+ }
468
477
  if (result instanceof Promise) {
469
- const tracked = result
470
- .catch((error) => {
471
- this.#logger.error?.('Error in async entry handler:', error);
478
+ const tracked = result.catch((error) => {
479
+ this.#logger.error?.('Error in async entry handler:', error);
480
+ try {
472
481
  this.#handleError(error);
473
- throw error;
474
- })
475
- .finally(() => pendingOperations.delete(tracked));
476
- pendingOperations.add(tracked);
482
+ } catch (reportingError) {
483
+ // Reporting must not replace the failure it is reporting.
484
+ this.#logger.error?.('Error reporting an entry handler failure:', reportingError);
485
+ }
486
+ throw error;
487
+ });
488
+ // Nothing awaits `tracked` until the drain, which leaves an early rejection unhandled.
489
+ tracked.catch(() => {});
490
+ initialOperations?.push(tracked);
477
491
  }
478
492
  };
479
493
 
480
- // When the entry handler's initial scan completes, wait for all pending async operations
494
+ // When the entry handler's initial scan completes, wait for all of its async operations
481
495
  const initialLoadPromise = once(targetEntryHandler, 'ready').then(async () => {
482
- if (pendingOperations.size > 0) {
483
- await Promise.all(pendingOperations);
496
+ const operations = initialOperations ?? [];
497
+ initialOperations = null;
498
+ // Drained, not fail-fast: the loader holds the plugin-wide load lock until this settles, so a
499
+ // first failure reported while a sibling still runs would let the next application in.
500
+ for (const result of await Promise.allSettled(operations)) {
501
+ if (result.status === 'rejected') throw result.reason;
484
502
  }
485
503
  targetEntryHandler.emit('initialLoadComplete');
486
504
  });
487
505
 
488
506
  // Track this promise so the component loader can await it
489
507
  this.#pendingInitialLoads.add(initialLoadPromise);
490
- initialLoadPromise.finally(() => this.#pendingInitialLoads.delete(initialLoadPromise));
508
+ // Two-branch cleanup, not `.finally`: its derivative would reject with nobody left to handle it.
509
+ const forgetInitialLoad = () => {
510
+ this.#pendingInitialLoads.delete(initialLoadPromise);
511
+ };
512
+ initialLoadPromise.then(forgetInitialLoad, forgetInitialLoad);
491
513
 
492
514
  return wrapped;
493
515
  };