@harperfast/harper 5.2.13 → 5.3.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (655) hide show
  1. package/agent/mcpTools.ts +1 -1
  2. package/agent/session.ts +25 -14
  3. package/bin/cliOperations.ts +58 -9
  4. package/bin/copyDb.ts +282 -59
  5. package/bin/deploySetup.ts +16 -5
  6. package/bin/harper.ts +1 -1
  7. package/bin/help.ts +4 -1
  8. package/bin/lite.ts +4 -1
  9. package/bin/restart.ts +120 -4
  10. package/bin/run.ts +6 -11
  11. package/bin/upgrade.js +7 -3
  12. package/bin/workloadIdentity.ts +119 -0
  13. package/components/Application.ts +3436 -242
  14. package/components/ApplicationScope.ts +8 -0
  15. package/components/EntryHandler.ts +59 -39
  16. package/components/OptionsWatcher.ts +440 -98
  17. package/components/RuntimeModuleTracker.ts +38 -7
  18. package/components/Scope.ts +56 -15
  19. package/components/awaitRestart.ts +84 -0
  20. package/components/componentLoader.ts +381 -32
  21. package/components/componentPreparationLock.ts +16 -5
  22. package/components/deploymentOperations.ts +4 -1
  23. package/components/deploymentRecorder.ts +9 -2
  24. package/components/mcp/adapters/harperHttp.ts +4 -0
  25. package/components/mcp/listChanged.ts +4 -0
  26. package/components/mcp/toolRegistry.ts +2 -0
  27. package/components/mcp/tools/operations.ts +9 -0
  28. package/components/mcp/tools/schemas/operationDescriptions.ts +2 -2
  29. package/components/operations.js +537 -113
  30. package/components/operationsValidation.js +98 -3
  31. package/components/packageComponent.ts +25 -1
  32. package/components/requestRestart.ts +11 -0
  33. package/components/status/ComponentStatusRegistry.ts +59 -0
  34. package/config/RootConfigWatcher.ts +240 -40
  35. package/config/configReadRetry.ts +62 -0
  36. package/config/configUtils.ts +357 -48
  37. package/config/harperConfigEnvVars.ts +170 -27
  38. package/config/parseConfigFile.ts +34 -0
  39. package/config/readConfigFileSync.ts +44 -0
  40. package/config/watcherArming.ts +59 -0
  41. package/config-root.schema.json +33 -0
  42. package/dataLayer/blobBackup.ts +160 -50
  43. package/dataLayer/delete.ts +6 -1
  44. package/dataLayer/harperBridge/ResourceBridge.ts +80 -10
  45. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js +3 -1
  46. package/dataLayer/hdbInfoController.ts +34 -1
  47. package/dataLayer/insert.ts +44 -1
  48. package/dataLayer/rocksdbBackup.ts +53 -10
  49. package/dataLayer/schema.ts +11 -1
  50. package/dataLayer/schemaDescribe.ts +8 -1
  51. package/dist/agent/mcpTools.js +1 -1
  52. package/dist/agent/mcpTools.js.map +1 -1
  53. package/dist/agent/session.d.ts +22 -0
  54. package/dist/agent/session.js +26 -15
  55. package/dist/agent/session.js.map +1 -1
  56. package/dist/bin/cliOperations.js +61 -9
  57. package/dist/bin/cliOperations.js.map +1 -1
  58. package/dist/bin/copyDb.d.ts +12 -1
  59. package/dist/bin/copyDb.js +248 -60
  60. package/dist/bin/copyDb.js.map +1 -1
  61. package/dist/bin/deploySetup.d.ts +2 -0
  62. package/dist/bin/deploySetup.js +11 -3
  63. package/dist/bin/deploySetup.js.map +1 -1
  64. package/dist/bin/harper.js +1 -1
  65. package/dist/bin/harper.js.map +1 -1
  66. package/dist/bin/help.js +4 -1
  67. package/dist/bin/help.js.map +1 -1
  68. package/dist/bin/lite.js +4 -1
  69. package/dist/bin/lite.js.map +1 -1
  70. package/dist/bin/restart.js +91 -6
  71. package/dist/bin/restart.js.map +1 -1
  72. package/dist/bin/run.js +4 -10
  73. package/dist/bin/run.js.map +1 -1
  74. package/dist/bin/upgrade.js +4 -3
  75. package/dist/bin/upgrade.js.map +1 -1
  76. package/dist/bin/workloadIdentity.d.ts +18 -0
  77. package/dist/bin/workloadIdentity.js +100 -0
  78. package/dist/bin/workloadIdentity.js.map +1 -0
  79. package/dist/components/Application.d.ts +235 -17
  80. package/dist/components/Application.js +3038 -238
  81. package/dist/components/Application.js.map +1 -1
  82. package/dist/components/ApplicationScope.d.ts +8 -0
  83. package/dist/components/ApplicationScope.js +7 -0
  84. package/dist/components/ApplicationScope.js.map +1 -1
  85. package/dist/components/EntryHandler.js +26 -10
  86. package/dist/components/EntryHandler.js.map +1 -1
  87. package/dist/components/OptionsWatcher.d.ts +4 -0
  88. package/dist/components/OptionsWatcher.js +440 -99
  89. package/dist/components/OptionsWatcher.js.map +1 -1
  90. package/dist/components/RuntimeModuleTracker.js +40 -6
  91. package/dist/components/RuntimeModuleTracker.js.map +1 -1
  92. package/dist/components/Scope.js +52 -13
  93. package/dist/components/Scope.js.map +1 -1
  94. package/dist/components/awaitRestart.d.ts +33 -0
  95. package/dist/components/awaitRestart.js +61 -0
  96. package/dist/components/awaitRestart.js.map +1 -0
  97. package/dist/components/componentLoader.d.ts +38 -1
  98. package/dist/components/componentLoader.js +313 -24
  99. package/dist/components/componentLoader.js.map +1 -1
  100. package/dist/components/componentPreparationLock.d.ts +5 -0
  101. package/dist/components/componentPreparationLock.js +14 -6
  102. package/dist/components/componentPreparationLock.js.map +1 -1
  103. package/dist/components/deploymentOperations.js +4 -1
  104. package/dist/components/deploymentOperations.js.map +1 -1
  105. package/dist/components/deploymentRecorder.d.ts +4 -2
  106. package/dist/components/deploymentRecorder.js +1 -0
  107. package/dist/components/deploymentRecorder.js.map +1 -1
  108. package/dist/components/mcp/adapters/harperHttp.js +4 -0
  109. package/dist/components/mcp/adapters/harperHttp.js.map +1 -1
  110. package/dist/components/mcp/listChanged.js +5 -0
  111. package/dist/components/mcp/listChanged.js.map +1 -1
  112. package/dist/components/mcp/toolRegistry.d.ts +1 -0
  113. package/dist/components/mcp/toolRegistry.js.map +1 -1
  114. package/dist/components/mcp/tools/operations.d.ts +5 -0
  115. package/dist/components/mcp/tools/operations.js +9 -0
  116. package/dist/components/mcp/tools/operations.js.map +1 -1
  117. package/dist/components/mcp/tools/schemas/operationDescriptions.js +2 -2
  118. package/dist/components/mcp/tools/schemas/operationDescriptions.js.map +1 -1
  119. package/dist/components/operations.d.ts +28 -0
  120. package/dist/components/operations.js +476 -113
  121. package/dist/components/operations.js.map +1 -1
  122. package/dist/components/operationsValidation.js +97 -3
  123. package/dist/components/operationsValidation.js.map +1 -1
  124. package/dist/components/packageComponent.js +24 -0
  125. package/dist/components/packageComponent.js.map +1 -1
  126. package/dist/components/requestRestart.d.ts +1 -0
  127. package/dist/components/requestRestart.js +7 -0
  128. package/dist/components/requestRestart.js.map +1 -1
  129. package/dist/components/status/ComponentStatusRegistry.d.ts +0 -4
  130. package/dist/components/status/ComponentStatusRegistry.js +63 -0
  131. package/dist/components/status/ComponentStatusRegistry.js.map +1 -1
  132. package/dist/config/RootConfigWatcher.d.ts +9 -1
  133. package/dist/config/RootConfigWatcher.js +228 -37
  134. package/dist/config/RootConfigWatcher.js.map +1 -1
  135. package/dist/config/configReadRetry.d.ts +8 -0
  136. package/dist/config/configReadRetry.js +62 -0
  137. package/dist/config/configReadRetry.js.map +1 -0
  138. package/dist/config/configUtils.d.ts +11 -2
  139. package/dist/config/configUtils.js +304 -47
  140. package/dist/config/configUtils.js.map +1 -1
  141. package/dist/config/harperConfigEnvVars.d.ts +16 -0
  142. package/dist/config/harperConfigEnvVars.js +162 -25
  143. package/dist/config/harperConfigEnvVars.js.map +1 -1
  144. package/dist/config/parseConfigFile.d.ts +4 -0
  145. package/dist/config/parseConfigFile.js +35 -0
  146. package/dist/config/parseConfigFile.js.map +1 -0
  147. package/dist/config/readConfigFileSync.d.ts +1 -0
  148. package/dist/config/readConfigFileSync.js +47 -0
  149. package/dist/config/readConfigFileSync.js.map +1 -0
  150. package/dist/config/watcherArming.d.ts +15 -0
  151. package/dist/config/watcherArming.js +59 -0
  152. package/dist/config/watcherArming.js.map +1 -0
  153. package/dist/dataLayer/blobBackup.d.ts +49 -20
  154. package/dist/dataLayer/blobBackup.js +139 -50
  155. package/dist/dataLayer/blobBackup.js.map +1 -1
  156. package/dist/dataLayer/delete.js +1 -1
  157. package/dist/dataLayer/delete.js.map +1 -1
  158. package/dist/dataLayer/harperBridge/ResourceBridge.d.ts +14 -1
  159. package/dist/dataLayer/harperBridge/ResourceBridge.js +72 -12
  160. package/dist/dataLayer/harperBridge/ResourceBridge.js.map +1 -1
  161. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.d.ts +3 -1
  162. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js +3 -1
  163. package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js.map +1 -1
  164. package/dist/dataLayer/hdbInfoController.d.ts +10 -0
  165. package/dist/dataLayer/hdbInfoController.js +30 -1
  166. package/dist/dataLayer/hdbInfoController.js.map +1 -1
  167. package/dist/dataLayer/insert.d.ts +9 -1
  168. package/dist/dataLayer/insert.js +30 -0
  169. package/dist/dataLayer/insert.js.map +1 -1
  170. package/dist/dataLayer/rocksdbBackup.d.ts +2 -2
  171. package/dist/dataLayer/rocksdbBackup.js +45 -8
  172. package/dist/dataLayer/rocksdbBackup.js.map +1 -1
  173. package/dist/dataLayer/schema.js +8 -0
  174. package/dist/dataLayer/schema.js.map +1 -1
  175. package/dist/dataLayer/schemaDescribe.js +8 -1
  176. package/dist/dataLayer/schemaDescribe.js.map +1 -1
  177. package/dist/index.d.ts +2 -1
  178. package/dist/index.js +4 -1
  179. package/dist/index.js.map +1 -1
  180. package/dist/json/systemSchema.json +55 -0
  181. package/dist/resources/DatabaseTransaction.d.ts +77 -0
  182. package/dist/resources/DatabaseTransaction.js +586 -54
  183. package/dist/resources/DatabaseTransaction.js.map +1 -1
  184. package/dist/resources/LMDBTransaction.d.ts +2 -1
  185. package/dist/resources/LMDBTransaction.js +43 -6
  186. package/dist/resources/LMDBTransaction.js.map +1 -1
  187. package/dist/resources/PrimaryRocksDatabase.d.ts +1 -0
  188. package/dist/resources/PrimaryRocksDatabase.js +49 -5
  189. package/dist/resources/PrimaryRocksDatabase.js.map +1 -1
  190. package/dist/resources/RecordEncoder.d.ts +20 -0
  191. package/dist/resources/RecordEncoder.js +110 -9
  192. package/dist/resources/RecordEncoder.js.map +1 -1
  193. package/dist/resources/RequestTarget.d.ts +2 -0
  194. package/dist/resources/RequestTarget.js.map +1 -1
  195. package/dist/resources/Resource.js +117 -24
  196. package/dist/resources/Resource.js.map +1 -1
  197. package/dist/resources/ResourceInterface.d.ts +28 -1
  198. package/dist/resources/ResourceInterface.js.map +1 -1
  199. package/dist/resources/RocksIndexStore.d.ts +6 -1
  200. package/dist/resources/RocksIndexStore.js +24 -9
  201. package/dist/resources/RocksIndexStore.js.map +1 -1
  202. package/dist/resources/RocksTransactionLogStore.d.ts +24 -1
  203. package/dist/resources/RocksTransactionLogStore.js +160 -49
  204. package/dist/resources/RocksTransactionLogStore.js.map +1 -1
  205. package/dist/resources/Table.d.ts +165 -10
  206. package/dist/resources/Table.js +1805 -303
  207. package/dist/resources/Table.js.map +1 -1
  208. package/dist/resources/analytics/write.js +10 -3
  209. package/dist/resources/analytics/write.js.map +1 -1
  210. package/dist/resources/auditStore.d.ts +181 -2
  211. package/dist/resources/auditStore.js +640 -29
  212. package/dist/resources/auditStore.js.map +1 -1
  213. package/dist/resources/blob.d.ts +129 -9
  214. package/dist/resources/blob.js +992 -114
  215. package/dist/resources/blob.js.map +1 -1
  216. package/dist/resources/branchDatabase.d.ts +48 -0
  217. package/dist/resources/branchDatabase.js +892 -0
  218. package/dist/resources/branchDatabase.js.map +1 -0
  219. package/dist/resources/crdt.js +50 -12
  220. package/dist/resources/crdt.js.map +1 -1
  221. package/dist/resources/dataLoader.js +3 -4
  222. package/dist/resources/dataLoader.js.map +1 -1
  223. package/dist/resources/databases.d.ts +157 -14
  224. package/dist/resources/databases.js +1462 -325
  225. package/dist/resources/databases.js.map +1 -1
  226. package/dist/resources/defineTable.d.ts +10 -2
  227. package/dist/resources/defineTable.js +9 -1
  228. package/dist/resources/defineTable.js.map +1 -1
  229. package/dist/resources/derivedIndexRegistry.d.ts +5 -0
  230. package/dist/resources/derivedIndexRegistry.js +68 -0
  231. package/dist/resources/derivedIndexRegistry.js.map +1 -0
  232. package/dist/resources/derivedIndexRuntime.d.ts +215 -0
  233. package/dist/resources/derivedIndexRuntime.js +2027 -0
  234. package/dist/resources/derivedIndexRuntime.js.map +1 -0
  235. package/dist/resources/graphql.d.ts +1 -1
  236. package/dist/resources/graphql.js +52 -16
  237. package/dist/resources/graphql.js.map +1 -1
  238. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.d.ts +103 -9
  239. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js +854 -41
  240. package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js.map +1 -1
  241. package/dist/resources/indexes/hnswDerivedIndex.d.ts +67 -0
  242. package/dist/resources/indexes/hnswDerivedIndex.js +464 -0
  243. package/dist/resources/indexes/hnswDerivedIndex.js.map +1 -0
  244. package/dist/resources/indexes/hnswPlaneBinding.d.ts +65 -0
  245. package/dist/resources/indexes/hnswPlaneBinding.js +91 -0
  246. package/dist/resources/indexes/hnswPlaneBinding.js.map +1 -0
  247. package/dist/resources/longLivedTransactions.d.ts +71 -0
  248. package/dist/resources/longLivedTransactions.js +358 -0
  249. package/dist/resources/longLivedTransactions.js.map +1 -0
  250. package/dist/resources/models/backendRegistry.d.ts +26 -0
  251. package/dist/resources/models/backendRegistry.js +60 -2
  252. package/dist/resources/models/backendRegistry.js.map +1 -1
  253. package/dist/resources/models/bootstrap.d.ts +33 -1
  254. package/dist/resources/models/bootstrap.js +416 -31
  255. package/dist/resources/models/bootstrap.js.map +1 -1
  256. package/dist/resources/nodeIdMapping.d.ts +5 -0
  257. package/dist/resources/nodeIdMapping.js +49 -0
  258. package/dist/resources/nodeIdMapping.js.map +1 -1
  259. package/dist/resources/recordLock.d.ts +123 -0
  260. package/dist/resources/recordLock.js +315 -0
  261. package/dist/resources/recordLock.js.map +1 -0
  262. package/dist/resources/recordLockCoordinator.d.ts +557 -0
  263. package/dist/resources/recordLockCoordinator.js +2565 -0
  264. package/dist/resources/recordLockCoordinator.js.map +1 -0
  265. package/dist/resources/replayLogs.d.ts +14 -1
  266. package/dist/resources/replayLogs.js +157 -24
  267. package/dist/resources/replayLogs.js.map +1 -1
  268. package/dist/resources/replayLogsGuards.d.ts +94 -7
  269. package/dist/resources/replayLogsGuards.js +111 -7
  270. package/dist/resources/replayLogsGuards.js.map +1 -1
  271. package/dist/resources/replicatedApplyFailure.d.ts +16 -0
  272. package/dist/resources/replicatedApplyFailure.js +63 -0
  273. package/dist/resources/replicatedApplyFailure.js.map +1 -0
  274. package/dist/resources/scheduler/scheduler.js +3 -3
  275. package/dist/resources/scheduler/scheduler.js.map +1 -1
  276. package/dist/resources/search.d.ts +10 -4
  277. package/dist/resources/search.js +283 -37
  278. package/dist/resources/search.js.map +1 -1
  279. package/dist/resources/tracked.d.ts +5 -1
  280. package/dist/resources/tracked.js +74 -23
  281. package/dist/resources/tracked.js.map +1 -1
  282. package/dist/resources/transactionBroadcast.d.ts +1 -1
  283. package/dist/resources/transactionBroadcast.js +2 -2
  284. package/dist/resources/transactionBroadcast.js.map +1 -1
  285. package/dist/security/auth.js +61 -30
  286. package/dist/security/auth.js.map +1 -1
  287. package/dist/security/authn/oidc/claims.d.ts +22 -0
  288. package/dist/security/authn/oidc/claims.js +71 -0
  289. package/dist/security/authn/oidc/claims.js.map +1 -0
  290. package/dist/security/authn/oidc/identityToken.d.ts +27 -0
  291. package/dist/security/authn/oidc/identityToken.js +111 -0
  292. package/dist/security/authn/oidc/identityToken.js.map +1 -0
  293. package/dist/security/authn/oidc/jwks.d.ts +25 -0
  294. package/dist/security/authn/oidc/jwks.js +261 -0
  295. package/dist/security/authn/oidc/jwks.js.map +1 -0
  296. package/dist/security/authn/oidc/providers/generic.d.ts +13 -0
  297. package/dist/security/authn/oidc/providers/generic.js +34 -0
  298. package/dist/security/authn/oidc/providers/generic.js.map +1 -0
  299. package/dist/security/authn/oidc/providers/githubActions.d.ts +11 -0
  300. package/dist/security/authn/oidc/providers/githubActions.js +129 -0
  301. package/dist/security/authn/oidc/providers/githubActions.js.map +1 -0
  302. package/dist/security/authn/oidc/providers/index.d.ts +37 -0
  303. package/dist/security/authn/oidc/providers/index.js +24 -0
  304. package/dist/security/authn/oidc/providers/index.js.map +1 -0
  305. package/dist/security/authn/oidc/tokenExchange.d.ts +12 -0
  306. package/dist/security/authn/oidc/tokenExchange.js +306 -0
  307. package/dist/security/authn/oidc/tokenExchange.js.map +1 -0
  308. package/dist/security/authn/oidc/trustPolicyOperations.d.ts +49 -0
  309. package/dist/security/authn/oidc/trustPolicyOperations.js +358 -0
  310. package/dist/security/authn/oidc/trustPolicyOperations.js.map +1 -0
  311. package/dist/security/authn/oidc/types.d.ts +38 -0
  312. package/dist/security/authn/oidc/types.js +6 -0
  313. package/dist/security/authn/oidc/types.js.map +1 -0
  314. package/dist/security/certificateVerification/index.js +40 -11
  315. package/dist/security/certificateVerification/index.js.map +1 -1
  316. package/dist/security/certificateVerification/trustedIssuers.d.ts +24 -0
  317. package/dist/security/certificateVerification/trustedIssuers.js +79 -0
  318. package/dist/security/certificateVerification/trustedIssuers.js.map +1 -0
  319. package/dist/security/certificateVerification/types.d.ts +1 -0
  320. package/dist/security/credentialProvenance.d.ts +35 -0
  321. package/dist/security/credentialProvenance.js +51 -0
  322. package/dist/security/credentialProvenance.js.map +1 -0
  323. package/dist/security/credentialRejection.d.ts +4 -0
  324. package/dist/security/credentialRejection.js +24 -0
  325. package/dist/security/credentialRejection.js.map +1 -0
  326. package/dist/security/deferredAuthentication.d.ts +36 -0
  327. package/dist/security/deferredAuthentication.js +70 -0
  328. package/dist/security/deferredAuthentication.js.map +1 -0
  329. package/dist/security/impersonation.d.ts +21 -0
  330. package/dist/security/impersonation.js +108 -9
  331. package/dist/security/impersonation.js.map +1 -1
  332. package/dist/security/jsLoader.d.ts +6 -0
  333. package/dist/security/jsLoader.js +77 -15
  334. package/dist/security/jsLoader.js.map +1 -1
  335. package/dist/security/keys.js +301 -71
  336. package/dist/security/keys.js.map +1 -1
  337. package/dist/security/operationScope.d.ts +21 -0
  338. package/dist/security/operationScope.js +36 -0
  339. package/dist/security/operationScope.js.map +1 -0
  340. package/dist/security/permissionsTranslator.js +21 -0
  341. package/dist/security/permissionsTranslator.js.map +1 -1
  342. package/dist/security/tokenAuthentication.d.ts +19 -1
  343. package/dist/security/tokenAuthentication.js +191 -10
  344. package/dist/security/tokenAuthentication.js.map +1 -1
  345. package/dist/security/user.js +4 -3
  346. package/dist/security/user.js.map +1 -1
  347. package/dist/server/DurableSubscriptionsSession.d.ts +2 -2
  348. package/dist/server/DurableSubscriptionsSession.js +67 -10
  349. package/dist/server/DurableSubscriptionsSession.js.map +1 -1
  350. package/dist/server/REST.js +106 -2
  351. package/dist/server/REST.js.map +1 -1
  352. package/dist/server/graphqlQuerying.js +4 -0
  353. package/dist/server/graphqlQuerying.js.map +1 -1
  354. package/dist/server/http.d.ts +16 -1
  355. package/dist/server/http.js +122 -17
  356. package/dist/server/http.js.map +1 -1
  357. package/dist/server/itc/serverHandlers.js +8 -1
  358. package/dist/server/itc/serverHandlers.js.map +1 -1
  359. package/dist/server/jobs/jobProcess.js +6 -2
  360. package/dist/server/jobs/jobProcess.js.map +1 -1
  361. package/dist/server/jobs/jobs.js +4 -1
  362. package/dist/server/jobs/jobs.js.map +1 -1
  363. package/dist/server/liveSubscriptionAuth.d.ts +26 -4
  364. package/dist/server/liveSubscriptionAuth.js +105 -39
  365. package/dist/server/liveSubscriptionAuth.js.map +1 -1
  366. package/dist/server/loadRootComponents.js +49 -10
  367. package/dist/server/loadRootComponents.js.map +1 -1
  368. package/dist/server/mqtt.d.ts +2 -0
  369. package/dist/server/mqtt.js +165 -30
  370. package/dist/server/mqtt.js.map +1 -1
  371. package/dist/server/nodeName.d.ts +2 -0
  372. package/dist/server/nodeName.js +107 -23
  373. package/dist/server/nodeName.js.map +1 -1
  374. package/dist/server/serverHelpers/Headers.d.ts +27 -0
  375. package/dist/server/serverHelpers/Headers.js +145 -1
  376. package/dist/server/serverHelpers/Headers.js.map +1 -1
  377. package/dist/server/serverHelpers/NodeAdapterResponse.d.ts +48 -0
  378. package/dist/server/serverHelpers/NodeAdapterResponse.js +220 -0
  379. package/dist/server/serverHelpers/NodeAdapterResponse.js.map +1 -0
  380. package/dist/server/serverHelpers/Request.d.ts +5 -10
  381. package/dist/server/serverHelpers/Request.js +38 -136
  382. package/dist/server/serverHelpers/Request.js.map +1 -1
  383. package/dist/server/serverHelpers/contentTypes.d.ts +11 -0
  384. package/dist/server/serverHelpers/contentTypes.js +221 -40
  385. package/dist/server/serverHelpers/contentTypes.js.map +1 -1
  386. package/dist/server/serverHelpers/deployValidationState.d.ts +3 -0
  387. package/dist/server/serverHelpers/deployValidationState.js +9 -19
  388. package/dist/server/serverHelpers/deployValidationState.js.map +1 -1
  389. package/dist/server/serverHelpers/operationAuthorizationState.d.ts +12 -0
  390. package/dist/server/serverHelpers/operationAuthorizationState.js +24 -2
  391. package/dist/server/serverHelpers/operationAuthorizationState.js.map +1 -1
  392. package/dist/server/serverHelpers/registeredOperations.d.ts +5 -4
  393. package/dist/server/serverHelpers/registeredOperations.js +74 -21
  394. package/dist/server/serverHelpers/registeredOperations.js.map +1 -1
  395. package/dist/server/serverHelpers/requestSanitization.d.ts +11 -0
  396. package/dist/server/serverHelpers/requestSanitization.js +20 -0
  397. package/dist/server/serverHelpers/requestSanitization.js.map +1 -0
  398. package/dist/server/serverHelpers/serverHandlers.js +6 -3
  399. package/dist/server/serverHelpers/serverHandlers.js.map +1 -1
  400. package/dist/server/serverHelpers/serverUtilities.d.ts +18 -0
  401. package/dist/server/serverHelpers/serverUtilities.js +178 -29
  402. package/dist/server/serverHelpers/serverUtilities.js.map +1 -1
  403. package/dist/server/serverHelpers/sharedMessageEncoding.d.ts +67 -0
  404. package/dist/server/serverHelpers/sharedMessageEncoding.js +280 -0
  405. package/dist/server/serverHelpers/sharedMessageEncoding.js.map +1 -0
  406. package/dist/server/serverHelpers/uwsServer.js +19 -1
  407. package/dist/server/serverHelpers/uwsServer.js.map +1 -1
  408. package/dist/server/static.js +24 -28
  409. package/dist/server/static.js.map +1 -1
  410. package/dist/server/storageReclamation.d.ts +5 -0
  411. package/dist/server/storageReclamation.js +17 -1
  412. package/dist/server/storageReclamation.js.map +1 -1
  413. package/dist/server/threads/isolatedApplications.d.ts +47 -0
  414. package/dist/server/threads/isolatedApplications.js +171 -0
  415. package/dist/server/threads/isolatedApplications.js.map +1 -0
  416. package/dist/server/threads/itc.d.ts +7 -2
  417. package/dist/server/threads/itc.js +5 -1
  418. package/dist/server/threads/itc.js.map +1 -1
  419. package/dist/server/threads/logRotationTransport.d.ts +1 -0
  420. package/dist/server/threads/logRotationTransport.js +33 -0
  421. package/dist/server/threads/logRotationTransport.js.map +1 -0
  422. package/dist/server/threads/manageThreads.d.ts +83 -3
  423. package/dist/server/threads/manageThreads.js +769 -75
  424. package/dist/server/threads/manageThreads.js.map +1 -1
  425. package/dist/server/threads/socketRouter.d.ts +1 -0
  426. package/dist/server/threads/socketRouter.js +277 -31
  427. package/dist/server/threads/socketRouter.js.map +1 -1
  428. package/dist/server/threads/threadHeapMemory.d.ts +2 -0
  429. package/dist/server/threads/threadHeapMemory.js +31 -0
  430. package/dist/server/threads/threadHeapMemory.js.map +1 -0
  431. package/dist/server/threads/threadServer.js +76 -22
  432. package/dist/server/threads/threadServer.js.map +1 -1
  433. package/dist/sqlEngine/config.d.ts +1 -3
  434. package/dist/sqlEngine/config.js +19 -16
  435. package/dist/sqlEngine/config.js.map +1 -1
  436. package/dist/sqlTranslator/index.d.ts +1 -1
  437. package/dist/sqlTranslator/index.js +30 -7
  438. package/dist/sqlTranslator/index.js.map +1 -1
  439. package/dist/upgrade/directives/5-3-0.d.ts +7 -0
  440. package/dist/upgrade/directives/5-3-0.js +148 -0
  441. package/dist/upgrade/directives/5-3-0.js.map +1 -0
  442. package/dist/upgrade/directives/directivesController.js +2 -1
  443. package/dist/upgrade/directives/directivesController.js.map +1 -1
  444. package/dist/utility/OperationFunctionCaller.js +2 -1
  445. package/dist/utility/OperationFunctionCaller.js.map +1 -1
  446. package/dist/utility/common_utils.d.ts +16 -0
  447. package/dist/utility/common_utils.js +32 -6
  448. package/dist/utility/common_utils.js.map +1 -1
  449. package/dist/utility/componentNames.d.ts +8 -0
  450. package/dist/utility/componentNames.js +12 -1
  451. package/dist/utility/componentNames.js.map +1 -1
  452. package/dist/utility/environment/environmentManager.js +3 -6
  453. package/dist/utility/environment/environmentManager.js.map +1 -1
  454. package/dist/utility/environment/systemInformation.d.ts +1 -0
  455. package/dist/utility/environment/systemInformation.js +1 -0
  456. package/dist/utility/environment/systemInformation.js.map +1 -1
  457. package/dist/utility/errors/commonErrors.d.ts +2 -0
  458. package/dist/utility/errors/commonErrors.js +2 -0
  459. package/dist/utility/errors/commonErrors.js.map +1 -1
  460. package/dist/utility/errors/hdbError.d.ts +33 -0
  461. package/dist/utility/errors/hdbError.js +58 -1
  462. package/dist/utility/errors/hdbError.js.map +1 -1
  463. package/dist/utility/globalSchema.d.ts +18 -0
  464. package/dist/utility/hdbTerms.d.ts +18 -0
  465. package/dist/utility/hdbTerms.js +20 -2
  466. package/dist/utility/hdbTerms.js.map +1 -1
  467. package/dist/utility/logging/harper_logger.d.ts +2 -0
  468. package/dist/utility/logging/harper_logger.js +286 -30
  469. package/dist/utility/logging/harper_logger.js.map +1 -1
  470. package/dist/utility/logging/logGenerationCoordinator.d.ts +35 -0
  471. package/dist/utility/logging/logGenerationCoordinator.js +184 -0
  472. package/dist/utility/logging/logGenerationCoordinator.js.map +1 -0
  473. package/dist/utility/logging/logRotation.d.ts +46 -0
  474. package/dist/utility/logging/logRotation.js +365 -0
  475. package/dist/utility/logging/logRotation.js.map +1 -0
  476. package/dist/utility/logging/logRotator.d.ts +1 -1
  477. package/dist/utility/logging/logRotator.js +192 -85
  478. package/dist/utility/logging/logRotator.js.map +1 -1
  479. package/dist/utility/nodeIdentity.d.ts +9 -0
  480. package/dist/utility/nodeIdentity.js +58 -0
  481. package/dist/utility/nodeIdentity.js.map +1 -0
  482. package/dist/utility/npmUtilities.js +11 -7
  483. package/dist/utility/npmUtilities.js.map +1 -1
  484. package/dist/utility/operationPermissions.d.ts +3 -1
  485. package/dist/utility/operationPermissions.js +16 -1
  486. package/dist/utility/operationPermissions.js.map +1 -1
  487. package/dist/utility/operation_authorization.d.ts +10 -7
  488. package/dist/utility/operation_authorization.js +212 -41
  489. package/dist/utility/operation_authorization.js.map +1 -1
  490. package/dist/utility/watchPath.d.ts +29 -0
  491. package/dist/utility/watchPath.js +68 -0
  492. package/dist/utility/watchPath.js.map +1 -0
  493. package/dist/utility/watcherFallback.d.ts +41 -0
  494. package/dist/utility/watcherFallback.js +153 -0
  495. package/dist/utility/watcherFallback.js.map +1 -1
  496. package/dist/validation/configValidator.d.ts +12 -0
  497. package/dist/validation/configValidator.js +205 -75
  498. package/dist/validation/configValidator.js.map +1 -1
  499. package/dist/validation/installValidator.js +12 -0
  500. package/dist/validation/installValidator.js.map +1 -1
  501. package/dist/validation/validationWrapper.d.ts +11 -0
  502. package/dist/validation/validationWrapper.js +16 -3
  503. package/dist/validation/validationWrapper.js.map +1 -1
  504. package/index.ts +8 -0
  505. package/json/systemSchema.json +55 -0
  506. package/npm-shrinkwrap.json +286 -194
  507. package/package.json +15 -7
  508. package/resources/DESIGN.md +219 -52
  509. package/resources/DatabaseTransaction.ts +657 -52
  510. package/resources/LMDBTransaction.ts +46 -6
  511. package/resources/PrimaryRocksDatabase.ts +46 -7
  512. package/resources/RecordEncoder.ts +124 -9
  513. package/resources/RequestTarget.ts +2 -0
  514. package/resources/Resource.ts +114 -22
  515. package/resources/ResourceInterface.ts +31 -0
  516. package/resources/RocksIndexStore.ts +30 -9
  517. package/resources/RocksTransactionLogStore.ts +188 -51
  518. package/resources/Table.ts +1960 -301
  519. package/resources/analytics/write.ts +10 -3
  520. package/resources/auditStore.ts +647 -32
  521. package/resources/blob.ts +1029 -110
  522. package/resources/branchDatabase.ts +941 -0
  523. package/resources/crdt.ts +76 -12
  524. package/resources/dataLoader.ts +3 -4
  525. package/resources/databases.ts +1584 -320
  526. package/resources/defineTable.ts +18 -2
  527. package/resources/derivedIndexRegistry.ts +56 -0
  528. package/resources/derivedIndexRuntime.ts +2292 -0
  529. package/resources/graphql.ts +72 -17
  530. package/resources/indexes/HierarchicalNavigableSmallWorld.ts +911 -48
  531. package/resources/indexes/hnswDerivedIndex.ts +531 -0
  532. package/resources/indexes/hnswPlaneBinding.ts +174 -0
  533. package/resources/longLivedTransactions.ts +360 -0
  534. package/resources/models/backendRegistry.ts +84 -2
  535. package/resources/models/bootstrap.ts +473 -28
  536. package/resources/nodeIdMapping.ts +50 -0
  537. package/resources/recordLock.ts +419 -0
  538. package/resources/recordLockCoordinator.ts +3043 -0
  539. package/resources/replayLogs.ts +152 -26
  540. package/resources/replayLogsGuards.ts +171 -8
  541. package/resources/replicatedApplyFailure.ts +77 -0
  542. package/resources/scheduler/scheduler.ts +4 -4
  543. package/resources/search.ts +288 -46
  544. package/resources/tracked.ts +73 -22
  545. package/resources/transactionBroadcast.ts +3 -3
  546. package/security/auth.ts +68 -29
  547. package/security/authn/oidc/claims.ts +72 -0
  548. package/security/authn/oidc/identityToken.ts +129 -0
  549. package/security/authn/oidc/jwks.ts +260 -0
  550. package/security/authn/oidc/providers/generic.ts +40 -0
  551. package/security/authn/oidc/providers/githubActions.ts +137 -0
  552. package/security/authn/oidc/providers/index.ts +52 -0
  553. package/security/authn/oidc/tokenExchange.ts +300 -0
  554. package/security/authn/oidc/trustPolicyOperations.ts +343 -0
  555. package/security/authn/oidc/types.ts +41 -0
  556. package/security/certificateVerification/index.ts +54 -13
  557. package/security/certificateVerification/trustedIssuers.ts +76 -0
  558. package/security/certificateVerification/types.ts +1 -0
  559. package/security/credentialProvenance.ts +47 -0
  560. package/security/credentialRejection.ts +22 -0
  561. package/security/deferredAuthentication.ts +71 -0
  562. package/security/impersonation.ts +117 -12
  563. package/security/jsLoader.ts +83 -18
  564. package/security/keys.ts +298 -72
  565. package/security/operationScope.ts +33 -0
  566. package/security/permissionsTranslator.js +23 -0
  567. package/security/tokenAuthentication.ts +233 -12
  568. package/security/user.ts +4 -3
  569. package/server/DESIGN.md +194 -16
  570. package/server/DurableSubscriptionsSession.ts +71 -11
  571. package/server/REST.ts +115 -4
  572. package/server/graphqlQuerying.ts +4 -0
  573. package/server/http.ts +133 -20
  574. package/server/itc/serverHandlers.js +8 -1
  575. package/server/jobs/jobProcess.ts +8 -2
  576. package/server/jobs/jobs.ts +4 -1
  577. package/server/liveSubscriptionAuth.ts +129 -46
  578. package/server/loadRootComponents.js +50 -8
  579. package/server/mqtt.ts +179 -38
  580. package/server/nodeName.ts +103 -21
  581. package/server/serverHelpers/Headers.ts +135 -0
  582. package/server/serverHelpers/NodeAdapterResponse.ts +221 -0
  583. package/server/serverHelpers/Request.ts +33 -131
  584. package/server/serverHelpers/contentTypes.ts +217 -36
  585. package/server/serverHelpers/deployValidationState.ts +24 -13
  586. package/server/serverHelpers/operationAuthorizationState.ts +34 -3
  587. package/server/serverHelpers/registeredOperations.ts +79 -22
  588. package/server/serverHelpers/requestSanitization.ts +15 -0
  589. package/server/serverHelpers/serverHandlers.js +6 -3
  590. package/server/serverHelpers/serverUtilities.ts +232 -40
  591. package/server/serverHelpers/sharedMessageEncoding.ts +307 -0
  592. package/server/serverHelpers/uwsServer.ts +17 -2
  593. package/server/static.ts +23 -29
  594. package/server/storageReclamation.ts +15 -2
  595. package/server/threads/isolatedApplications.ts +157 -0
  596. package/server/threads/itc.js +11 -1
  597. package/server/threads/logRotationTransport.ts +40 -0
  598. package/server/threads/manageThreads.js +771 -66
  599. package/server/threads/socketRouter.ts +291 -30
  600. package/server/threads/threadHeapMemory.ts +26 -0
  601. package/server/threads/threadServer.js +73 -22
  602. package/sqlTranslator/index.ts +31 -8
  603. package/studio/web/assets/{Chat-4RrB5134.js → Chat-D3j-1yY1.js} +1 -1
  604. package/studio/web/assets/{FloatingChat-omlNMDcJ.js → FloatingChat-BxJGYcfB.js} +3 -3
  605. package/studio/web/assets/{apiToken-Bke3wvfZ.js → apiToken-CT55oWOe.js} +1 -1
  606. package/studio/web/assets/{applications-DvFDYJgK.js → applications-D9Ct9_vm.js} +1 -1
  607. package/studio/web/assets/{cssMode-C1vRa7zh.js → cssMode-DV8H7VwA.js} +1 -1
  608. package/studio/web/assets/{editor-3XRWEDWX.js → editor-uatc0unt.js} +1 -1
  609. package/studio/web/assets/{html-CTY5tdMr.js → html-Bm6D6paN.js} +1 -1
  610. package/studio/web/assets/{htmlMode-CG1vSD9t.js → htmlMode-CEn7tpLG.js} +1 -1
  611. package/studio/web/assets/{index-Dfpeofdu.js → index-BIXW6Pu4.js} +5 -5
  612. package/studio/web/assets/{index.lazy-B1VOIv-t.js → index.lazy-UI7L-Vrk.js} +1 -1
  613. package/studio/web/assets/{javascript-CJeJzGnI.js → javascript-CJ0G3AFZ.js} +1 -1
  614. package/studio/web/assets/{jsonMode-CYPBwM82.js → jsonMode-DQADAYEa.js} +1 -1
  615. package/studio/web/assets/{languageServices-IKH4GUHl.js → languageServices-CAQJXWcI.js} +1 -1
  616. package/studio/web/assets/{lspLanguageFeatures-BC8_gxKG.js → lspLanguageFeatures-CCQ8P5sY.js} +1 -1
  617. package/studio/web/assets/{notifications-BfKBpYcq.js → notifications-BbxTU6Aw.js} +1 -1
  618. package/studio/web/assets/{notifications-DFbArTfC.js → notifications-Cvb3P1lB.js} +1 -1
  619. package/studio/web/assets/{profile-Q4-T6c-S.js → profile-Yyb7gsvL.js} +1 -1
  620. package/studio/web/assets/{regions-CtkV0xje.js → regions-OgjGHlU5.js} +1 -1
  621. package/studio/web/assets/{register-1ZZuMsiA.js → register-6qwNEOY3.js} +2 -2
  622. package/studio/web/assets/{setComponentFile-ZWLcWv5X.js → setComponentFile-BilDMtgB.js} +1 -1
  623. package/studio/web/assets/{setup-DWprJyJy.js → setup-J6qJ7OIU.js} +2 -2
  624. package/studio/web/assets/{status--aNm8isn.js → status-0RWGcfyD.js} +1 -1
  625. package/studio/web/assets/{toggleHighContrast-Cq_lt3XD.js → toggleHighContrast-BIn-vErT.js} +1 -1
  626. package/studio/web/assets/{tsMode-pjgytARx.js → tsMode-DgUXku4d.js} +1 -1
  627. package/studio/web/assets/{typescript-Cdg0mqUh.js → typescript-C9orXcsM.js} +1 -1
  628. package/studio/web/assets/{useEntityRestURL-RZhaY8Rn.js → useEntityRestURL-BEoXXbUB.js} +1 -1
  629. package/studio/web/assets/{workers-BgoXIqQe.js → workers-JVzSDmgx.js} +1 -1
  630. package/studio/web/assets/{xml-BwSeDMiP.js → xml-Cq-S8S4X.js} +1 -1
  631. package/studio/web/assets/{yaml-DotCUG5l.js → yaml-sfoRdh1M.js} +1 -1
  632. package/studio/web/index.html +1 -1
  633. package/upgrade/directives/5-3-0.ts +132 -0
  634. package/upgrade/directives/directivesController.ts +2 -1
  635. package/utility/OperationFunctionCaller.ts +2 -1
  636. package/utility/common_utils.ts +30 -5
  637. package/utility/componentNames.ts +12 -0
  638. package/utility/environment/environmentManager.ts +3 -7
  639. package/utility/environment/systemInformation.ts +7 -0
  640. package/utility/errors/commonErrors.ts +4 -0
  641. package/utility/errors/hdbError.ts +57 -0
  642. package/utility/hdbTerms.ts +19 -0
  643. package/utility/logging/harper_logger.ts +278 -26
  644. package/utility/logging/logGenerationCoordinator.ts +196 -0
  645. package/utility/logging/logRotation.ts +367 -0
  646. package/utility/logging/logRotator.ts +213 -81
  647. package/utility/nodeIdentity.ts +45 -0
  648. package/utility/npmUtilities.ts +12 -8
  649. package/utility/operationPermissions.ts +18 -1
  650. package/utility/operation_authorization.ts +231 -42
  651. package/utility/watchPath.ts +63 -0
  652. package/utility/watcherFallback.ts +148 -0
  653. package/validation/configValidator.ts +215 -75
  654. package/validation/installValidator.ts +15 -0
  655. package/validation/validationWrapper.ts +18 -4
@@ -25,13 +25,26 @@
25
25
  import type { Logger } from '../utility/logging/logger.ts';
26
26
  import * as fs from 'fs-extra';
27
27
  import * as path from 'node:path';
28
+ import { isMainThread } from 'node:worker_threads';
28
29
  import * as crypto from 'node:crypto';
29
30
  import { cloneDeep } from 'lodash';
30
31
  import { getBackupDirPath } from './configHelpers.ts';
31
- import { atomicWriteFile } from './configUtils.ts';
32
+ import { atomicWriteFile, renameWithRetry } from './configUtils.ts';
32
33
  import * as hdbTerms from '../utility/hdbTerms.ts';
33
34
 
34
35
  const STATE_FILE_NAME = '.harper-config-state.json';
36
+ // Staged beside the confirmed state while a config-file write is in flight, then renamed over it.
37
+ // Per-process, because every CLI invocation and worker runs this and one shared name would let one
38
+ // clear another's in-flight commit. See DESIGN.md, boot-path config persistence.
39
+ const PENDING_STATE_PREFIX = '.harper-config-state.pending.';
40
+ const PENDING_STATE_SUFFIX = '.json';
41
+ const pendingStateFileName = () => `${PENDING_STATE_PREFIX}${process.pid}${PENDING_STATE_SUFFIX}`;
42
+ // Recovery from a recycled pid only has to be eventual, and deleting a slow-but-live writer's
43
+ // sidecar is the worse error - it strands that writer's config file against an unpromoted state. So
44
+ // the age-out is far longer than a commit (three synchronous steps) could ever legitimately take:
45
+ // long enough that a stalled writer or clock skew between containers sharing a volume cannot reach
46
+ // it, short enough that leaked wreckage does not suspend drift detection indefinitely.
47
+ const PENDING_STATE_STALE_MS = 60 * 60 * 1000;
35
48
 
36
49
  /**
37
50
  * Get logger instance with tag - lazy loaded to avoid circular dependencies
@@ -546,15 +559,7 @@ function parseConfigEnvVar(envVarValue: string | undefined, envVarName: string):
546
559
  function loadConfigState(rootPath: string): ConfigState {
547
560
  const statePath = path.join(getBackupDirPath(rootPath), STATE_FILE_NAME);
548
561
 
549
- if (!fs.existsSync(statePath)) {
550
- return {
551
- version: '1.0',
552
- sources: {},
553
- originalValues: {},
554
- emptyScopeOriginals: {},
555
- snapshots: {},
556
- };
557
- }
562
+ if (!fs.existsSync(statePath)) return freshConfigState();
558
563
 
559
564
  try {
560
565
  const state = fs.readJsonSync(statePath) as ConfigState;
@@ -573,20 +578,85 @@ function loadConfigState(rootPath: string): ConfigState {
573
578
  // If state file is corrupted, start fresh
574
579
  const logger = getLogger();
575
580
  logger.warn(`Failed to load config state file, starting fresh: ${(error as Error).message}`);
576
- return {
577
- version: '1.0',
578
- sources: {},
579
- originalValues: {},
580
- emptyScopeOriginals: {},
581
- snapshots: {},
582
- };
581
+ return freshConfigState();
583
582
  }
584
583
  }
585
584
 
585
+ /**
586
+ * Clear a sidecar left by an interrupted commit, reporting whether one was there. The caller skips
587
+ * drift detection for that boot: it cannot tell a manual user edit from the write that was in
588
+ * flight, and calling it an edit hands those paths to 'user' for good.
589
+ */
590
+ function takeInterruptedCommit(rootPath: string): boolean {
591
+ const backupDir = getBackupDirPath(rootPath);
592
+ let entries: string[];
593
+ try {
594
+ entries = fs.readdirSync(backupDir);
595
+ } catch {
596
+ return false;
597
+ }
598
+ let interrupted = false;
599
+ for (const entry of entries) {
600
+ if (!entry.startsWith(PENDING_STATE_PREFIX) || !entry.endsWith(PENDING_STATE_SUFFIX)) continue;
601
+ const pid = Number(entry.slice(PENDING_STATE_PREFIX.length, -PENDING_STATE_SUFFIX.length));
602
+ const entryPath = path.join(backupDir, entry);
603
+ if (pid !== process.pid && isProcessAlive(pid) && !isStale(entryPath)) {
604
+ // A live owner is mid-commit, so its sidecar is not wreckage to clear - but the pair it is
605
+ // halfway through is no more comparable than an interrupted one, so drift detection is off
606
+ // for this boot either way.
607
+ interrupted = true;
608
+ continue;
609
+ }
610
+ try {
611
+ fs.removeSync(entryPath);
612
+ } catch (error) {
613
+ // Keep drift detection on rather than disabling it every boot over a sidecar we cannot clear
614
+ getLogger().warn(`Could not remove an interrupted env config commit (${entry}): ${(error as Error).message}`);
615
+ continue;
616
+ }
617
+ interrupted = true;
618
+ }
619
+ if (interrupted) getLogger().warn('An env config commit was interrupted; skipping drift detection for this boot');
620
+ return interrupted;
621
+ }
622
+
623
+ function isStale(entryPath: string): boolean {
624
+ try {
625
+ return Date.now() - fs.statSync(entryPath).mtimeMs > PENDING_STATE_STALE_MS;
626
+ } catch {
627
+ return false;
628
+ }
629
+ }
630
+
631
+ function isProcessAlive(pid: number): boolean {
632
+ if (!Number.isInteger(pid) || pid <= 0) return false;
633
+ try {
634
+ process.kill(pid, 0);
635
+ return true;
636
+ } catch (error) {
637
+ return (error as NodeJS.ErrnoException).code === 'EPERM';
638
+ }
639
+ }
640
+
641
+ function freshConfigState(): ConfigState {
642
+ return {
643
+ version: '1.0',
644
+ sources: {},
645
+ originalValues: {},
646
+ emptyScopeOriginals: {},
647
+ snapshots: {},
648
+ };
649
+ }
650
+
586
651
  /**
587
652
  * Save configuration state to file
588
653
  */
589
- function saveConfigState(rootPath: string, state: ConfigState): void {
654
+ function serializeConfigState(state: ConfigState): string {
655
+ return JSON.stringify(state, null, 2) + '\n';
656
+ }
657
+
658
+ // Returns true when the file was rewritten, false when it already held this state.
659
+ function saveConfigState(rootPath: string, state: ConfigState): boolean {
590
660
  const backupDir = getBackupDirPath(rootPath);
591
661
  const statePath = path.join(backupDir, STATE_FILE_NAME);
592
662
 
@@ -595,7 +665,49 @@ function saveConfigState(rootPath: string, state: ConfigState): void {
595
665
 
596
666
  // Atomic write: a torn state file resets to fresh on the next load, losing every
597
667
  // restoration record — the blast radius is user config-file content
598
- atomicWriteFile(statePath, JSON.stringify(state, null, 2) + '\n');
668
+ return atomicWriteFile(statePath, serializeConfigState(state), { skipIfUnchanged: true });
669
+ }
670
+
671
+ function configStateMatchesDisk(rootPath: string, state: ConfigState): boolean {
672
+ try {
673
+ const statePath = path.join(getBackupDirPath(rootPath), STATE_FILE_NAME);
674
+ return fs.readFileSync(statePath, 'utf8') === serializeConfigState(state);
675
+ } catch {
676
+ return false;
677
+ }
678
+ }
679
+
680
+ function stageConfigState(rootPath: string, state: ConfigState): boolean {
681
+ const backupDir = getBackupDirPath(rootPath);
682
+ fs.ensureDirSync(backupDir);
683
+ return atomicWriteFile(path.join(backupDir, pendingStateFileName()), serializeConfigState(state));
684
+ }
685
+
686
+ // A rename, so an exhausted volume cannot refuse it and leave the config file described by nothing.
687
+
688
+ export function commitStagedConfigState(rootPath: string): boolean {
689
+ const backupDir = getBackupDirPath(rootPath);
690
+ const pendingPath = path.join(backupDir, pendingStateFileName());
691
+ try {
692
+ renameWithRetry(pendingPath, path.join(backupDir, STATE_FILE_NAME));
693
+ return true;
694
+ } catch (error) {
695
+ // Loud: the config file is already on disk, so the confirmed state now describes values it no
696
+ // longer has, and the next boot reads that difference as a manual user edit.
697
+ getLogger().error(`Could not promote the staged env config state at ${pendingPath}: ${(error as Error).message}`);
698
+ return false;
699
+ }
700
+ }
701
+
702
+ // Drops the staged state for a config-file write that did not happen; the confirmed record stays.
703
+
704
+ export function discardConfigState(rootPath: string): void {
705
+ const pendingPath = path.join(getBackupDirPath(rootPath), pendingStateFileName());
706
+ try {
707
+ fs.removeSync(pendingPath);
708
+ } catch (error) {
709
+ getLogger().warn(`Could not remove the staged env config state at ${pendingPath}: ${(error as Error).message}`);
710
+ }
599
711
  }
600
712
 
601
713
  /**
@@ -957,20 +1069,49 @@ export function applyRuntimeEnvConfig(
957
1069
  rootPath: string,
958
1070
  options: { isInstall?: boolean } = {}
959
1071
  ): ConfigObject {
1072
+ const { config, commitState } = prepareRuntimeEnvConfig(fileConfig, rootPath, options);
1073
+ commitState();
1074
+ return config;
1075
+ }
1076
+
1077
+ /**
1078
+ * Apply the env layers and hand the state writes back to the caller, so a caller that also persists
1079
+ * the merged config file can commit the pair as a unit (#847): saveState() stages the new state
1080
+ * beside the confirmed one, confirmConfigWritten() renames it over the confirmed one after the
1081
+ * config file lands, and discardConfigState() drops the staged copy if that write never happens.
1082
+ */
1083
+ export function prepareRuntimeEnvConfig(
1084
+ fileConfig: ConfigObject,
1085
+ rootPath: string,
1086
+ options: { isInstall?: boolean } = {}
1087
+ ): {
1088
+ config: ConfigObject;
1089
+ saveState: () => boolean;
1090
+ confirmConfigWritten: () => boolean;
1091
+ commitState: () => boolean;
1092
+ } {
960
1093
  const defaultEnvValue = process.env.HARPER_DEFAULT_CONFIG;
961
1094
  const configEnvValue = process.env.HARPER_CONFIG;
962
1095
  const setEnvValue = process.env.HARPER_SET_CONFIG;
963
1096
 
964
- // Load existing state
1097
+ // Load existing state. Only the main thread persists, so only the main thread has wreckage to
1098
+ // clear - and a worker shares its pid, so letting one scan would delete the main thread's
1099
+ // in-flight sidecar as if it were last boot's.
1100
+ const interruptedCommit = isMainThread && takeInterruptedCommit(rootPath);
965
1101
  const state = loadConfigState(rootPath);
966
1102
 
967
1103
  // No env vars set and no previous state, nothing to do
968
1104
  if (!defaultEnvValue && !configEnvValue && !setEnvValue && Object.keys(state.snapshots).length === 0) {
969
- return fileConfig;
1105
+ return { config: fileConfig, saveState: () => false, confirmConfigWritten: () => false, commitState: () => false };
970
1106
  }
971
1107
 
972
- // Detect drift (user manual edits) - only at runtime, not install
973
- if (!options.isInstall) {
1108
+ // Detect drift (user manual edits) - only at runtime, not install, not on a boot that found an
1109
+ // interrupted commit (where a difference could equally be the write that was in flight), and only
1110
+ // on the main thread: a worker never owns the state, and one re-deriving inside the main thread's
1111
+ // commit window would call its half-written config file a user edit and drop the env-supplied
1112
+ // value for itself alone - serving different config than its siblings, with nothing on disk to
1113
+ // show why.
1114
+ if (!options.isInstall && !interruptedCommit && isMainThread) {
974
1115
  const driftedPaths = detectConfigDrift(fileConfig, state);
975
1116
  for (const path of driftedPaths) {
976
1117
  state.sources[path] = 'user';
@@ -998,8 +1139,10 @@ export function applyRuntimeEnvConfig(
998
1139
  processEnvVar(fileConfig, state, 'HARPER_CONFIG', 'HARPER_CONFIG', options);
999
1140
  processEnvVar(fileConfig, state, 'HARPER_SET_CONFIG', 'HARPER_SET_CONFIG', options);
1000
1141
 
1001
- // Save updated state
1002
- saveConfigState(rootPath, state);
1003
-
1004
- return fileConfig;
1142
+ return {
1143
+ config: fileConfig,
1144
+ saveState: () => (configStateMatchesDisk(rootPath, state) ? false : stageConfigState(rootPath, state)),
1145
+ confirmConfigWritten: () => commitStagedConfigState(rootPath),
1146
+ commitState: () => saveConfigState(rootPath, state),
1147
+ };
1005
1148
  }
@@ -0,0 +1,34 @@
1
+ import { parse } from 'yaml';
2
+
3
+ // yaml's prettyErrors frames the offending source lines into `message`, and a config file holds
4
+ // credentials. Neither the cause nor the original stack is carried for the same reason.
5
+ export class ConfigParseError extends Error {
6
+ constructor(filePath: string, error: unknown) {
7
+ const { name, code, linePos } = (error ?? {}) as {
8
+ name?: string;
9
+ code?: string;
10
+ linePos?: { line: number; col: number }[];
11
+ };
12
+ const at = linePos?.[0] ? ` at line ${linePos[0].line}, column ${linePos[0].col}` : '';
13
+ super(`Unable to parse the Harper configuration file at ${filePath}: ${code ?? name ?? 'parse failure'}${at}`);
14
+ this.name = 'ConfigParseError';
15
+ }
16
+ }
17
+
18
+ export function parseConfigFile(contents: string, filePath: string): any {
19
+ try {
20
+ // yaml routes warnings through `process.emitWarning` rather than a throw, so a framed
21
+ // warning would reach stderr with the config's own source lines in it, around this scrub.
22
+ return parse(contents, { logLevel: 'error' });
23
+ } catch (error) {
24
+ // Only yaml's own parse errors frame the source into `message`. Anything else is a fault in
25
+ // the parser, where the message is the whole of the debugging context.
26
+ if (!isYamlParseError(error)) throw error;
27
+ throw new ConfigParseError(filePath, error);
28
+ }
29
+ }
30
+
31
+ function isYamlParseError(error: unknown): boolean {
32
+ const { name, linePos } = (error ?? {}) as { name?: string; linePos?: unknown };
33
+ return linePos !== undefined || name === 'YAMLParseError';
34
+ }
@@ -0,0 +1,44 @@
1
+ import { readFileSync } from 'node:fs';
2
+
3
+ // Why root config reads must not be async, and why this budget is shared rather than per call:
4
+ // see "Root config watchers must read synchronously" in DESIGN.md (harper#2191).
5
+ const READ_RETRY_BUDGET_MS = 500;
6
+ const READ_RETRY_INITIAL_DELAY_MS = 10;
7
+ const READ_RETRY_MAX_DELAY_MS = 100;
8
+ const readRetrySleepBuffer = new Int32Array(new SharedArrayBuffer(4));
9
+ const retryDeadlines = new Map<string, number>();
10
+
11
+ // A caller that already owns a retry ladder passes `waitForLock` false, so one lock costs one
12
+ // blocking window in total rather than one per rung.
13
+ export function readConfigFileSync(filePath: string, waitForLock: boolean = true): string {
14
+ let delayMs = READ_RETRY_INITIAL_DELAY_MS;
15
+ while (true) {
16
+ try {
17
+ const contents = readFileSync(filePath, 'utf-8');
18
+ retryDeadlines.delete(filePath);
19
+ return contents;
20
+ } catch (error) {
21
+ const remainingBudgetMs = waitForLock && isSharingViolation(error) ? remainingRetryBudgetMs(filePath) : 0;
22
+ if (remainingBudgetMs <= 0) throw error;
23
+ Atomics.wait(readRetrySleepBuffer, 0, 0, Math.min(delayMs, remainingBudgetMs));
24
+ delayMs = Math.min(delayMs * 2, READ_RETRY_MAX_DELAY_MS);
25
+ }
26
+ }
27
+ }
28
+
29
+ function isSharingViolation(error: unknown): boolean {
30
+ if (process.platform !== 'win32') return false;
31
+ const code = (error as { code?: string } | null)?.code;
32
+ return code === 'EPERM' || code === 'EACCES' || code === 'EBUSY';
33
+ }
34
+
35
+ function remainingRetryBudgetMs(filePath: string): number {
36
+ const now = performance.now();
37
+ let deadline = retryDeadlines.get(filePath);
38
+ // A deadline more than one budget past its expiry belongs to an earlier burst, not this one.
39
+ if (deadline === undefined || now - deadline > READ_RETRY_BUDGET_MS) {
40
+ deadline = now + READ_RETRY_BUDGET_MS;
41
+ retryDeadlines.set(filePath, deadline);
42
+ }
43
+ return deadline - now;
44
+ }
@@ -0,0 +1,59 @@
1
+ // See DESIGN.md, "`ready` means the watcher is armed". Platform is a parameter so a test on any
2
+ // host can pin the darwin value, rather than only observing its own.
3
+ export function armGraceMs(platform: string = process.platform): number {
4
+ return platform === 'darwin' ? 20 : 0;
5
+ }
6
+
7
+ const ARM_GRACE_MS = armGraceMs();
8
+
9
+ /**
10
+ * The gate a config watcher opens when its chokidar watcher is really watching: the initial scan
11
+ * has finished *and* the platform's kernel-side warm-up has had its grace. Shared by
12
+ * `RootConfigWatcher` and `OptionsWatcher` because both read the config synchronously, which is
13
+ * what exposes the unarmed window in the first place.
14
+ */
15
+ export class ArmGate {
16
+ #armed: boolean = false;
17
+ #timer: NodeJS.Timeout | undefined;
18
+ #graceMs: number;
19
+
20
+ // Taken as an argument, not read from the module constant, so the timer branch below is
21
+ // reachable from a host whose own platform has no grace — unit tests are ubuntu-only.
22
+ constructor(graceMs: number = ARM_GRACE_MS) {
23
+ this.#graceMs = graceMs;
24
+ }
25
+
26
+ get armed(): boolean {
27
+ return this.#armed;
28
+ }
29
+
30
+ // Synchronous where the platform needs no grace, so a watcher with no warm-up to wait out
31
+ // keeps reading inside chokidar's own dispatch.
32
+ arm(onArmed: () => void): void {
33
+ if (this.#armed || this.#timer) return;
34
+ if (!this.#graceMs) {
35
+ this.#armed = true;
36
+ onArmed();
37
+ return;
38
+ }
39
+ this.#timer = setTimeout(() => {
40
+ this.#timer = undefined;
41
+ this.#armed = true;
42
+ onArmed();
43
+ }, this.#graceMs);
44
+ }
45
+
46
+ // Drops a grace still counting down, for a watcher that is closing.
47
+ cancel(): void {
48
+ clearTimeout(this.#timer);
49
+ this.#timer = undefined;
50
+ }
51
+
52
+ // A replacement watcher has its own scan and its own unarmed window, so the gate arms again
53
+ // with it: for a file that is *absent* when the replacement scans, chokidar reports `ready` and
54
+ // nothing else, and the arming re-read is the only thing that would notice.
55
+ reset(): void {
56
+ this.cancel();
57
+ this.#armed = false;
58
+ }
59
+ }
@@ -172,6 +172,10 @@
172
172
  ]
173
173
  },
174
174
  "maxHeapMemory": { "type": "number", "description": "Heap memory limit per thread (MB)." },
175
+ "maxIsolated": {
176
+ "type": "integer",
177
+ "description": "Most applications marked isolated that get a dedicated worker thread; the rest fail to load. Default 8."
178
+ },
175
179
  "heapSnapshotNearLimit": { "type": "boolean", "description": "Take a heap snapshot when near the heap limit." },
176
180
  "preload": {
177
181
  "oneOf": [{ "type": "string" }, { "type": "array", "items": { "type": "string" } }],
@@ -519,6 +523,10 @@
519
523
  "type": "string",
520
524
  "description": "Max write queue time before rejecting (e.g. '45s')."
521
525
  },
526
+ "longTransactionReportThreshold": {
527
+ "type": ["string", "number"],
528
+ "description": "How old a RocksDB transaction handle must be before it is reported in the log (e.g. '5m'). A handle this old can hold write intents that park other writers' commits and pin a read snapshot. Set to 0 to disable the reporting. Default: '5m'"
529
+ },
522
530
  "noReadAhead": { "type": "boolean", "description": "Advise OS to not read ahead. Default: false" },
523
531
  "randomAccessFields": {
524
532
  "type": "boolean",
@@ -534,6 +542,31 @@
534
542
  "oneOf": [{ "type": "string" }, { "type": "array", "items": { "type": "string" } }],
535
543
  "description": "Path or array of paths for blob storage. Default: <rootPath>/blobs"
536
544
  },
545
+ "blobs": {
546
+ "type": "object",
547
+ "description": "File-backed blob storage settings.",
548
+ "properties": {
549
+ "compression": {
550
+ "type": "object",
551
+ "description": "Opt-in compression for newly written file-backed blobs, keyed by content type: an exact type ('application/json'), a wildcard ('text/*'), or 'default'. Absent means no compression. Each entry is false (never compress the type) or an object { codec, threshold }: codec currently only 'deflate' (the default); threshold is the minimum content size in bytes to compress (default 8192). Matching precedence is exact type, then 'type/*', then 'default'. Types that are already compressed (application/gzip, application/zip, application/zstd, image/*, video/*, audio/*) ship as false and stay uncompressed unless explicitly overridden. Blobs streamed without a known size are not compressed, and a threshold below 8192 only affects streamed writes — buffers under 8KB are stored inline in the record (covered by record-level compression) and never reach blob files. Applies to new writes only; existing blob files are never rewritten.",
552
+ "propertyNames": { "pattern": "^([\\w.+-]+/(\\*|[\\w.+-]+)|default)$" },
553
+ "additionalProperties": {
554
+ "oneOf": [
555
+ { "const": false },
556
+ {
557
+ "type": "object",
558
+ "properties": {
559
+ "codec": { "const": "deflate" },
560
+ "threshold": { "type": "number", "minimum": 0 }
561
+ },
562
+ "additionalProperties": false
563
+ }
564
+ ]
565
+ }
566
+ }
567
+ },
568
+ "additionalProperties": false
569
+ },
537
570
  "blobReadTimeout": {
538
571
  "type": "number",
539
572
  "description": "Max time (ms) a blob read will wait for an in-progress write to finish before failing with a 503, rather than holding the connection. Default: 20000"