@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,8 +1,7 @@
1
1
  import { RocksDatabase } from '@harperfast/rocksdb-js';
2
2
  export type AuditRecord = {
3
3
  version: number;
4
- recordVersion?: number;
5
- localTime: number;
4
+ txnLogKey: number;
6
5
  type: string;
7
6
  encodedRecord?: Buffer;
8
7
  extendedType?: number;
@@ -47,6 +46,16 @@ export declare const AUDIT_STORE_OPTIONS: {
47
46
  };
48
47
  export declare let auditRetention: number;
49
48
  export declare function openAuditStore(rootStore: any): any;
49
+ /**
50
+ * Whether `entry` is the very write `auditRecord` describes. Write identity is (origin node, log key),
51
+ * never the record version: a version is legitimately non-unique, so a version match can name a
52
+ * different write and authorize destroying live state (a tombstone, a still-referenced blob).
53
+ *
54
+ * On LMDB this is exact — the audit-store key IS the record's `txnLogKey`. On RocksDB a record stores
55
+ * its version in the compatibility word and keeps a divergent log key in `additionalAuditRefs`.
56
+ * Absent identity answers false. The direction is deliberate: uncertainty retains.
57
+ */
58
+ export declare function isAuditEntryWrite(entry: any, auditRecord: AuditRecord): boolean;
50
59
  export declare function removeAuditEntry(auditStore: any, auditRecord: AuditRecord): Promise<void>;
51
60
  export declare function getLastRemoved(auditStore: any): number;
52
61
  export declare function setAuditRetention(retentionTime: any, defaultDelay?: number): void;
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.Decoder = exports.LOCAL_ONLY = exports.HAS_ADDITIONAL_AUDIT_REFS = exports.HAS_BLOBS = exports.HAS_EXPIRATION_EXTENDED_TYPE = exports.HAS_ORIGINATING_OPERATION = exports.HAS_PREVIOUS_RESIDENCY_ID = exports.HAS_CURRENT_RESIDENCY_ID = exports.REMOTE_SEQUENCE_UPDATE = exports.ACTION_64_BIT = exports.ACTION_32_BIT = exports.auditRetention = exports.AUDIT_STORE_OPTIONS = exports.transactionKeyEncoder = exports.ENTRY_DATAVIEW = void 0;
37
37
  exports.openAuditStore = openAuditStore;
38
+ exports.isAuditEntryWrite = isAuditEntryWrite;
38
39
  exports.removeAuditEntry = removeAuditEntry;
39
40
  exports.getLastRemoved = getLastRemoved;
40
41
  exports.setAuditRetention = setAuditRetention;
@@ -127,8 +128,22 @@ const MAX_CLEANUP_DELAY = 2 ** 31 - 1;
127
128
  // mint latch keyed per (table, type) so one entry type can't silence another's producer stack
128
129
  const warnedBodylessMints = new Set();
129
130
  const warnedBodylessTables = new Set();
131
+ // legacy-format latches, mirroring the bodyless ones above: a range scan over millions of pre-#2247
132
+ // entries must not turn a recovered read into a log flood. Recovery latches per table (the table is
133
+ // known by then); an undecodable header has no table, so it latches once per process.
134
+ const warnedRecoveredTables = new Set();
135
+ let warnedUndecodableHeader = false;
136
+ // keyed per (table, type) like warnedBodylessMints, so one entry type cannot silence another's stack
137
+ const warnedPendingPreviousVersion = new Set();
130
138
  const FLOAT_TARGET = new Float64Array(1);
131
139
  const FLOAT_BUFFER = new Uint8Array(FLOAT_TARGET.buffer);
140
+ /** Last resort on a detached path: a failing log sink must not itself become an unhandled rejection. */
141
+ function warnContained(message, error) {
142
+ try {
143
+ harperLogger.warn(message, error);
144
+ }
145
+ catch { }
146
+ }
132
147
  let DEFAULT_AUDIT_CLEANUP_DELAY = 10000; // default delay of 10 seconds
133
148
  let timestampErrored = false;
134
149
  function openAuditStore(rootStore) {
@@ -145,14 +160,15 @@ function openAuditStore(rootStore) {
145
160
  if (!auditStore) {
146
161
  // this means we are creating a new audit store. Initialize with the last removed timestamp (we don't want to put this in legacy audit logs since we don't know if they have had deletions or not).
147
162
  auditStore = rootStore.openDB(terms_ts_1.AUDIT_STORE_NAME, exports.AUDIT_STORE_OPTIONS);
148
- updateLastRemoved(auditStore, 1);
163
+ // this open path is synchronous, so nothing downstream can own the write's rejection
164
+ updateLastRemoved(auditStore, 1)?.catch?.((error) => warnContained('Error initializing the audit log last-removed marker', error));
149
165
  }
150
166
  const superGetRange = auditStore.getRange.bind(auditStore);
151
167
  auditStore.getRange = function (options) {
152
168
  if (options.values === false)
153
169
  return superGetRange(options); // getKeys shouldn't be modified
154
170
  return superGetRange(options).map(({ key, value }) => {
155
- value.key = value.localTime = key;
171
+ value.key = value.txnLogKey = key;
156
172
  return value;
157
173
  });
158
174
  };
@@ -168,6 +184,8 @@ function openAuditStore(rootStore) {
168
184
  return {
169
185
  remove() {
170
186
  delete deleteCallbacks[tableId];
187
+ if (auditStore.tableStores[tableId] === table)
188
+ delete auditStore.tableStores[tableId];
171
189
  },
172
190
  };
173
191
  };
@@ -177,7 +195,15 @@ function openAuditStore(rootStore) {
177
195
  let pendingCleanupResolve = null;
178
196
  let lastCleanupResolution;
179
197
  let cleanupPriority = 0;
180
- let auditCleanupDelay = DEFAULT_AUDIT_CLEANUP_DELAY;
198
+ auditStore.auditCleanupDelay = DEFAULT_AUDIT_CLEANUP_DELAY;
199
+ let cleanupStopped = false;
200
+ // a last-removed marker whose write failed, retried on later passes: dropping it would leave
201
+ // getLastRemoved() reporting a boundary the entries behind it have already been deleted past
202
+ let pendingLastRemoved;
203
+ const isRocksAuditStore = auditStore instanceof RocksTransactionLogStore_ts_1.RocksTransactionLogStore;
204
+ // A pass yields, so the store can be closed underneath it. Every touch of the environment after a
205
+ // resume — cursor advance, cursor release, marker write, re-arm — has to re-check.
206
+ const storeClosing = () => auditStore.rootStore.status === 'closed' || auditStore.rootStore.status === 'closing';
181
207
  (0, storageReclamation_ts_1.onStorageReclamation)(rootStore.path, (priority) => {
182
208
  cleanupPriority = priority; // update the priority
183
209
  if (priority) {
@@ -188,29 +214,24 @@ function openAuditStore(rootStore) {
188
214
  /**
189
215
  * Schedules a pass of the audit cleanup loop. The returned promise fulfills once the pass that
190
216
  * serves this call has finished, so callers (notably tests) can await completion instead of
191
- * guessing a delay. Two things it does not promise: a pass removes at most
217
+ * guessing a delay. Two things it does not promise: an LMDB pass removes at most
192
218
  * MAX_DELETES_PER_CLEANUP entries before rescheduling itself, so fulfillment means "that pass
193
219
  * finished", not "the audit log is fully pruned"; and a pass that failed logs and fulfills rather
194
220
  * than rejecting, since this promise doubles as the loop's serialization barrier.
195
221
  */
196
222
  function scheduleAuditCleanup(newCleanupDelay) {
197
223
  // Skip audit cleanup/purge in read-only mode
198
- if ((0, databases_ts_1.isReadOnlyMode)())
224
+ if (cleanupStopped || (0, databases_ts_1.isReadOnlyMode)())
199
225
  return Promise.resolve();
200
- if (auditStore instanceof RocksTransactionLogStore_ts_1.RocksTransactionLogStore) {
201
- auditStore.rootStore.purgeLogs({
202
- before: Date.now() - exports.auditRetention / (1 + cleanupPriority * cleanupPriority),
203
- });
204
- return Promise.resolve();
205
- }
206
226
  if (newCleanupDelay)
207
- auditCleanupDelay = newCleanupDelay;
227
+ auditStore.auditCleanupDelay = newCleanupDelay;
208
228
  // the pass we are about to cancel has not started, so its callers are handed over to this one
209
229
  const supersededResolve = pendingCleanupResolve;
210
230
  clearTimeout(pendingCleanup);
211
231
  const resolution = new Promise((resolve) => {
212
232
  pendingCleanupResolve = resolve;
213
- pendingCleanup = setTimeout(async () => {
233
+ const runCleanupPass = async () => {
234
+ pendingCleanup = null;
214
235
  pendingCleanupResolve = null; // started, so a later schedule can no longer cancel this pass
215
236
  // claim the serialization slot before yielding: assigning it after the await lets every
216
237
  // pass released by the same resolution run concurrently over the same range
@@ -218,73 +239,151 @@ function openAuditStore(rootStore) {
218
239
  lastCleanupResolution = resolution;
219
240
  await previousCleanup;
220
241
  // query for audit entries that are old
221
- if (auditStore.rootStore.status === 'closed' || auditStore.rootStore.status === 'closing') {
242
+ if (cleanupStopped || storeClosing()) {
222
243
  // nothing to clean up and nothing to reschedule, but leaving `resolution` pending would
223
244
  // wedge the loop permanently: it is now the resolution every later pass awaits
224
245
  resolve();
225
246
  return;
226
247
  }
248
+ const passCleanupPriority = cleanupPriority;
227
249
  let deleted = 0;
228
250
  let lastKey;
229
251
  try {
230
- for (const auditRecord of auditStore.getRange({
231
- start: 1, // must not be zero or it will be interpreted as null and overlap with symbols in search
232
- snapshot: false,
233
- end: Date.now() - exports.auditRetention / (1 + cleanupPriority * cleanupPriority), // remove up until the audit retention time, reducing audit retention time if cleanup is higher priority
234
- })) {
252
+ if (isRocksAuditStore) {
253
+ auditStore.rootStore.purgeLogs({
254
+ before: Date.now() - exports.auditRetention / (1 + passCleanupPriority * passCleanupPriority),
255
+ });
256
+ }
257
+ else {
258
+ // Driven explicitly rather than with for-of: this loop suspends on the awaits below, and a
259
+ // close landing mid-pass closes the env under it. for-of calls next() before the body, so a
260
+ // check inside the body advances the cursor first — the guard has to precede every next().
261
+ const entries = auditStore
262
+ .getRange({
263
+ start: 1, // must not be zero or it will be interpreted as null and overlap with symbols in search
264
+ snapshot: false,
265
+ end: Date.now() - exports.auditRetention / (1 + passCleanupPriority * passCleanupPriority), // remove up until the audit retention time, reducing audit retention time if cleanup is higher priority
266
+ })[Symbol.iterator]();
235
267
  try {
236
- // awaited so a rejection (not just a synchronous throw) is caught here instead of
237
- // escaping as an unhandled rejection once a later iteration's promise replaces this one
238
- await removeAuditEntry(auditStore, auditRecord);
239
- }
240
- catch (error) {
241
- harperLogger.warn('Error removing audit entry', error);
268
+ while (!cleanupStopped && !storeClosing()) {
269
+ const entry = entries.next();
270
+ if (entry.done)
271
+ break;
272
+ const auditRecord = entry.value;
273
+ try {
274
+ // awaited so a rejection (not just a synchronous throw) is caught here instead of
275
+ // escaping as an unhandled rejection once a later iteration's promise replaces this one
276
+ await removeAuditEntry(auditStore, auditRecord);
277
+ }
278
+ catch (error) {
279
+ harperLogger.warn('Error removing audit entry', error);
280
+ }
281
+ lastKey = auditRecord.key;
282
+ await new Promise(setImmediate);
283
+ if (++deleted >= MAX_DELETES_PER_CLEANUP) {
284
+ // limit the amount we cleanup per event turn so we don't use too much memory/CPU
285
+ auditStore.auditCleanupDelay = 10; // and keep trying very soon
286
+ break;
287
+ }
288
+ }
242
289
  }
243
- lastKey = auditRecord.key;
244
- await new Promise(setImmediate);
245
- if (++deleted >= MAX_DELETES_PER_CLEANUP) {
246
- // limit the amount we cleanup per event turn so we don't use too much memory/CPU
247
- auditCleanupDelay = 10; // and keep trying very soon
248
- break;
290
+ finally {
291
+ // for-of released the underlying cursor on break; an explicit loop owes that itself.
292
+ // Skipped only once the root is closing: releasing a cursor into a closed env reaches
293
+ // native code, while a retirement that leaves the env open still owes the release.
294
+ if (!storeClosing())
295
+ entries.return?.();
249
296
  }
250
297
  }
251
298
  }
252
299
  catch (error) {
253
- // the timer callback is detached, so anything escaping here lands as an unhandled
254
- // rejection instead of a log line — and skips the reschedule below with it
300
+ // a failed scan is a log line, not a retired loop: the bookkeeping and reschedule below
301
+ // still run
255
302
  harperLogger.warn('Error during audit log cleanup', error);
256
303
  }
257
304
  finally {
258
- // resolve() first and unconditionally: updateLastRemoved() below can throw
259
- // synchronously if the store transitions to closing/closed mid-pass, and a throw
260
- // from the rest of this block must not skip settling `resolution` — that's the
261
- // serialization barrier every later pass awaits, and never settling it wedges the
262
- // cleanup loop for the life of the store.
263
- resolve();
264
- if (deleted === 0) {
265
- // if we didn't delete anything, we can increase the delay (double until we get to one tenth of
266
- // the retention time). Plain arithmetic, not `<<`/`>>`: those coerce to int32, so a
267
- // sub-millisecond retention collapsed the delay to 0 permanently (0 << 1 is 0), and a
268
- // retention over ~248 days grows it past 2^31 where halving it wraps negative.
269
- auditCleanupDelay = Math.max(1, Math.min(auditCleanupDelay * 2, exports.auditRetention / 10, MAX_CLEANUP_DELAY));
305
+ try {
306
+ if (isRocksAuditStore) {
307
+ // eligibility only changes on rotation/flush, so the LMDB backoff — keyed on a per-entry
308
+ // delete count — would only rescan the same segments
309
+ auditStore.auditCleanupDelay = Math.max(DEFAULT_AUDIT_CLEANUP_DELAY, Math.min(exports.auditRetention / (1 + cleanupPriority * cleanupPriority) / 10, MAX_CLEANUP_DELAY));
310
+ }
311
+ else {
312
+ if (deleted === 0) {
313
+ // if we didn't delete anything, we can increase the delay (double until we get to one tenth of
314
+ // the retention time). Plain arithmetic, not `<<`/`>>`: those coerce to int32, so a
315
+ // sub-millisecond retention collapsed the delay to 0 permanently (0 << 1 is 0), and a
316
+ // retention over ~248 days grows it past 2^31 where halving it wraps negative.
317
+ auditStore.auditCleanupDelay = Math.max(1, Math.min(auditStore.auditCleanupDelay * 2, exports.auditRetention / 10, MAX_CLEANUP_DELAY));
318
+ }
319
+ else {
320
+ pendingLastRemoved = lastKey;
321
+ // and do updates faster
322
+ if (auditStore.auditCleanupDelay > 100)
323
+ auditStore.auditCleanupDelay = auditStore.auditCleanupDelay / 2;
324
+ }
325
+ // skipped when the store was retired or closed mid-pass — this writes to the audit
326
+ // store — and carried to the next pass instead, so a failed write is not lost
327
+ if (pendingLastRemoved !== undefined && !cleanupStopped && !storeClosing()) {
328
+ const marker = pendingLastRemoved;
329
+ try {
330
+ // awaited so the barrier below covers the write, and so a rejection is logged
331
+ // here rather than escaping the detached timer callback
332
+ await updateLastRemoved(auditStore, marker);
333
+ if (pendingLastRemoved === marker)
334
+ pendingLastRemoved = undefined;
335
+ }
336
+ catch (error) {
337
+ harperLogger.warn('Error recording the last removed audit entry', error);
338
+ }
339
+ }
340
+ }
270
341
  }
271
- else {
272
- // if we did delete something, update our updates since timestamp
273
- updateLastRemoved(auditStore, lastKey);
274
- // and do updates faster
275
- if (auditCleanupDelay > 100)
276
- auditCleanupDelay = auditCleanupDelay / 2;
342
+ finally {
343
+ // settled and re-armed whatever the bookkeeping above threw: this promise is both the
344
+ // serialization barrier every later pass awaits and the drain barrier
345
+ // stopAuditCleanup() hands its callers, so never settling it wedges both
346
+ resolve();
347
+ // both conjuncts are backstops, not the ownership rule — see DESIGN.md: the arming
348
+ // sites already restrict Rocks to the last worker
349
+ if (!cleanupStopped &&
350
+ !storeClosing() &&
351
+ (!isRocksAuditStore || ((0, manageThreads_js_1.getWorkerIndex)() === (0, manageThreads_js_1.getWorkerCount)() - 1 && !pendingCleanupResolve))) {
352
+ scheduleAuditCleanup();
353
+ }
277
354
  }
278
- scheduleAuditCleanup();
279
355
  }
280
356
  // we can run this pretty frequently since there is very little overhead to these queries
281
- }, auditCleanupDelay).unref();
357
+ };
358
+ pendingCleanup = setTimeout(() => {
359
+ // nothing owns the timer callback's promise, so anything the pass lets escape — including a
360
+ // throw from the logging inside its own containment — would land as an unhandled rejection
361
+ runCleanupPass().catch((error) => {
362
+ warnContained('Error during audit log cleanup', error);
363
+ resolve();
364
+ });
365
+ }, auditStore.auditCleanupDelay).unref();
282
366
  });
283
367
  if (supersededResolve)
284
368
  resolution.then(supersededResolve);
285
369
  return resolution;
286
370
  }
287
371
  auditStore.scheduleAuditCleanup = scheduleAuditCleanup;
372
+ /**
373
+ * Retires the cleanup loop for good, and returns a drain barrier: the promise settles once the pass
374
+ * that was already running has finished. Retirement alone only stops the loop admitting more work —
375
+ * a pass suspended inside `await removeAuditEntry()` still has a write queued whose DBI the native
376
+ * writer consumes later, so a caller that closes or unlinks stores must await this first. The
377
+ * synchronous teardown paths cannot; the in-pass status checks are what covers them.
378
+ */
379
+ auditStore.stopAuditCleanup = function () {
380
+ cleanupStopped = true;
381
+ clearTimeout(pendingCleanup);
382
+ pendingCleanup = null;
383
+ pendingCleanupResolve?.();
384
+ pendingCleanupResolve = null;
385
+ return lastCleanupResolution ?? Promise.resolve();
386
+ };
288
387
  if ((0, manageThreads_js_1.getWorkerIndex)() === (0, manageThreads_js_1.getWorkerCount)() - 1) {
289
388
  scheduleAuditCleanup();
290
389
  }
@@ -299,20 +398,46 @@ function openAuditStore(rootStore) {
299
398
  }
300
399
  return auditStore;
301
400
  }
401
+ /**
402
+ * Whether `entry` is the very write `auditRecord` describes. Write identity is (origin node, log key),
403
+ * never the record version: a version is legitimately non-unique, so a version match can name a
404
+ * different write and authorize destroying live state (a tombstone, a still-referenced blob).
405
+ *
406
+ * On LMDB this is exact — the audit-store key IS the record's `txnLogKey`. On RocksDB a record stores
407
+ * its version in the compatibility word and keeps a divergent log key in `additionalAuditRefs`.
408
+ * Absent identity answers false. The direction is deliberate: uncertainty retains.
409
+ */
410
+ function isAuditEntryWrite(entry, auditRecord) {
411
+ if (entry == null || auditRecord.txnLogKey == null)
412
+ return false;
413
+ const auditNodeId = auditRecord.nodeId ?? 0;
414
+ return ((entry.localTime === auditRecord.txnLogKey && (entry.nodeId ?? 0) === auditNodeId) ||
415
+ entry.additionalAuditRefs?.some((ref) => ref.version === auditRecord.txnLogKey && (ref.nodeId ?? 0) === auditNodeId) === true);
416
+ }
302
417
  function removeAuditEntry(auditStore, auditRecord) {
418
+ let tombstoneRemoval;
303
419
  if (auditRecord.type === 'delete') {
304
420
  // if this is a delete, we remove the delete entry from the primary table
305
- // at the same time so the audit table the primary table are in sync, assuming the entry matches this audit record version
421
+ // at the same time so the audit table the primary table are in sync, assuming the entry is still
422
+ // the record state this audit record wrote
306
423
  const tableId = auditRecord.tableId;
307
424
  const primaryStore = auditStore.tableStores[auditRecord.tableId];
308
- if (primaryStore?.getEntry(auditRecord.recordId)?.version === auditRecord.version)
309
- auditStore.deleteCallbacks?.[tableId]?.(auditRecord.recordId, auditRecord.version);
425
+ const tombstone = primaryStore?.getEntry(auditRecord.recordId);
426
+ if (isAuditEntryWrite(tombstone, auditRecord))
427
+ // a failed tombstone removal doesn't mean the audit entry removal failed — only
428
+ // auditStore.remove() below decides this function's outcome
429
+ tombstoneRemoval = new Promise((resolve) => {
430
+ resolve(auditStore.deleteCallbacks?.[tableId]?.(auditRecord.recordId, tombstone.version));
431
+ }).catch((error) => {
432
+ harperLogger.warn('Error removing deleted record while removing its audit entry', error);
433
+ });
310
434
  }
311
- return auditStore.remove(auditRecord.key);
435
+ const auditRemoval = auditStore.remove(auditRecord.key);
436
+ return tombstoneRemoval ? Promise.all([tombstoneRemoval, auditRemoval]).then(() => undefined) : auditRemoval;
312
437
  }
313
438
  function updateLastRemoved(auditStore, lastKey) {
314
439
  FLOAT_TARGET[0] = lastKey;
315
- auditStore.put(Symbol.for('last-removed'), FLOAT_BUFFER);
440
+ return auditStore.put(Symbol.for('last-removed'), FLOAT_BUFFER);
316
441
  }
317
442
  function getLastRemoved(auditStore) {
318
443
  const lastRemoved = auditStore.get(Symbol.for('last-removed'));
@@ -395,13 +520,65 @@ const EVENT_TYPES = {
395
520
  remoteSequenceUpdate: exports.REMOTE_SEQUENCE_UPDATE,
396
521
  [exports.REMOTE_SEQUENCE_UPDATE]: 'remoteSequenceUpdate',
397
522
  };
523
+ /**
524
+ * The LMDB audit entry states the presence of its leading 8-byte previousVersion field with that
525
+ * field's own first byte. The same test is what harperdb 4.x's reader uses and what both versions'
526
+ * replication senders use to strip the field before framing an entry for the wire, so it is a
527
+ * cross-version contract, not a local convention: a field written with any other leading byte is
528
+ * skipped by every reader and shifts action/nodeId/tableId/recordId/version by 8. See harper#2247.
529
+ */
530
+ const PREVIOUS_VERSION_FIRST_BYTE = 66;
531
+ /**
532
+ * Which first bytes can begin an action, and so cannot be a previousVersion field. Derived from what
533
+ * the encoding can express, not from the types defined today: nibbles 9-15 are reserved for future
534
+ * entry types, and a peer one version ahead must keep decoding rather than look corrupt here.
535
+ */
536
+ const ACTION_FIRST_BYTE = new Uint8Array(256);
537
+ // single-byte form; 0 is not an entry type, so a zero low nibble cannot start one
538
+ for (let firstByte = 1; firstByte <= (HAS_RECORD | HAS_PARTIAL_RECORD | 0xf); firstByte++) {
539
+ if (firstByte & 0xf)
540
+ ACTION_FIRST_BYTE[firstByte] = 1;
541
+ }
542
+ // extended form, written as `action | extendedType | 0xc0000000`; 0xff is the five-byte readInt form
543
+ for (let firstByte = 0xc0; firstByte < 0xff; firstByte++)
544
+ ACTION_FIRST_BYTE[firstByte] = 1;
545
+ let knownActionFlags;
546
+ /**
547
+ * Whether an action word decodes wholly into what this version understands. Consulted only to accept
548
+ * or reject a legacy prefix recovery — never to validate a normally-framed entry, where an unknown
549
+ * future flag must stay forwards-compatible rather than corrupt. The mask is built on first use
550
+ * because HAS_STRUCTURE_UPDATE crosses the RecordEncoder import cycle: read at module scope it
551
+ * resolves to undefined whenever RecordEncoder is the cycle's entry, silently dropping that bit.
552
+ */
553
+ function isDecodableAction(action) {
554
+ knownActionFlags ??=
555
+ 0xf |
556
+ HAS_RECORD |
557
+ HAS_PARTIAL_RECORD |
558
+ RecordEncoder_ts_1.HAS_STRUCTURE_UPDATE |
559
+ exports.HAS_CURRENT_RESIDENCY_ID |
560
+ exports.HAS_PREVIOUS_RESIDENCY_ID |
561
+ exports.HAS_ORIGINATING_OPERATION |
562
+ exports.HAS_EXPIRATION_EXTENDED_TYPE |
563
+ exports.HAS_BLOBS |
564
+ exports.HAS_ADDITIONAL_AUDIT_REFS |
565
+ exports.LOCAL_ONLY;
566
+ return (action & 0xf) !== 0 && !(action & ~knownActionFlags);
567
+ }
398
568
  const ORIGINATING_OPERATIONS = {
399
569
  insert: 1,
400
570
  update: 2,
401
571
  upsert: 3,
572
+ // `put` must be persisted, not inferred: the physical write type is also `put` for an `upsert`
573
+ // that happened to create a record, so the history readers cannot tell the two apart from the
574
+ // type alone. Without an id here the originating operation decoded as undefined, the readers fell
575
+ // back to the physical type, and replication catch-up replayed a `put` as an `upsert` — patching
576
+ // the replica and RETAINING attributes the source had removed.
577
+ put: 4,
402
578
  1: 'insert',
403
579
  2: 'update',
404
580
  3: 'upsert',
581
+ 4: 'put',
405
582
  };
406
583
  /**
407
584
  * Creates a binary audit entry
@@ -434,14 +611,42 @@ function createAuditEntry(auditRecord, start = 0) {
434
611
  }
435
612
  action &= ~HAS_RECORD;
436
613
  }
437
- let position = start + 1;
438
- if (previousVersion) {
439
- if (previousVersion > 1)
614
+ let hasPreviousVersion;
615
+ if (start > 0) {
616
+ // RocksTransactionLogStore states presence with its own prelude flag, derived from this same
617
+ // truthiness, so this container's field stays unconditional and its value is unconstrained.
618
+ hasPreviousVersion = !!previousVersion;
619
+ if (hasPreviousVersion)
440
620
  exports.ENTRY_DATAVIEW.setFloat64(start, previousVersion);
441
- else
442
- ENTRY_HEADER.set(RecordEncoder_ts_1.PREVIOUS_TIMESTAMP_PLACEHOLDER, start);
443
- position = start + 9;
444
621
  }
622
+ else if (previousVersion == null || previousVersion === 0) {
623
+ // absence is stated, not inferred from truthiness: NaN is falsy and would otherwise be
624
+ // silently dropped rather than rejected below
625
+ hasPreviousVersion = false;
626
+ }
627
+ else if (previousVersion === RecordEncoder_ts_1.PENDING_LOCAL_TIME) {
628
+ // The previous entry has no log position yet, and a format whose presence signal is the value's
629
+ // own first byte cannot express "to be filled in at commit". The superseded code deferred to
630
+ // lmdb-js's instructed-write substitution, which resolves to 2.0 whenever no previous time was
631
+ // recorded — the unreadable entry behind harper-pro#737. It resolved correctly when one was, so
632
+ // this trades a lost link on that path for never minting the unreadable form. Not a throw: a
633
+ // pending previous is a producer state, unlike a value the format cannot hold.
634
+ hasPreviousVersion = false;
635
+ if (!warnedPendingPreviousVersion.has(`${tableId}:${type}`)) {
636
+ warnedPendingPreviousVersion.add(`${tableId}:${type}`);
637
+ warnContained(`Audit entry (${type}) for record ${recordId} in table ${tableId} has a pending previous version; recording it without a previous-version link`, new Error('pending audit previousVersion'));
638
+ }
639
+ }
640
+ else {
641
+ exports.ENTRY_DATAVIEW.setFloat64(start, previousVersion);
642
+ if (ENTRY_HEADER[start] !== PREVIOUS_VERSION_FIRST_BYTE) {
643
+ throw new Error(`Audit entry previousVersion ${previousVersion} for record ${recordId} in table ${tableId} is not representable. ` +
644
+ 'The LMDB audit format signals this field with its own leading 0x42 byte, so only values in [2**33, 2**49) can be written; ' +
645
+ 'writing any other value produces an entry every reader parses 8 bytes off.');
646
+ }
647
+ hasPreviousVersion = true;
648
+ }
649
+ let position = start + (hasPreviousVersion ? 9 : 1);
445
650
  if (extendedType) {
446
651
  if (extendedType & 0xff) {
447
652
  throw new Error('Illegal extended type');
@@ -483,10 +688,11 @@ function createAuditEntry(auditRecord, start = 0) {
483
688
  writeValue(user);
484
689
  else
485
690
  ENTRY_HEADER[position++] = 0;
691
+ const actionPosition = start + (hasPreviousVersion ? 8 : 0);
486
692
  if (extendedType)
487
- exports.ENTRY_DATAVIEW.setUint32(start + (previousVersion ? 8 : 0), action | extendedType | 0xc0000000);
693
+ exports.ENTRY_DATAVIEW.setUint32(actionPosition, action | extendedType | 0xc0000000);
488
694
  else
489
- ENTRY_HEADER[start + (previousVersion ? 8 : 0)] = action;
695
+ ENTRY_HEADER[actionPosition] = action;
490
696
  const header = ENTRY_HEADER.subarray(0, position);
491
697
  if (encodedRecord) {
492
698
  return Buffer.concat([header, encodedRecord]);
@@ -549,13 +755,42 @@ function readAuditEntry(buffer, start = 0, end = undefined) {
549
755
  (buffer.decoder = new Decoder(buffer.buffer, buffer.byteOffset, buffer.byteLength));
550
756
  decoder.position = start;
551
757
  let previousVersion;
552
- if (buffer[decoder.position] == 66) {
553
- // 66 is the first byte in a date double.
758
+ let entryStart = start;
759
+ const firstByte = buffer[start];
760
+ if (firstByte === PREVIOUS_VERSION_FIRST_BYTE) {
554
761
  previousVersion = decoder.readFloat64();
555
762
  }
763
+ else if (ACTION_FIRST_BYTE[firstByte] !== 1) {
764
+ // Written before the writer enforced the leading-0x42 contract (harper#2247): the field is
765
+ // physically here but does not announce itself, so the action sits 8 bytes further on.
766
+ // Recover only when the bytes cannot be anything else, and never for the RocksDB container,
767
+ // whose prelude flag already consumed its previousVersion before this offset.
768
+ if (start !== 0 || start + 9 > buffer.byteLength || ACTION_FIRST_BYTE[buffer[start + 8]] !== 1) {
769
+ return corruptEntry(buffer, start, end, firstByte);
770
+ }
771
+ // > 1 is exactly what the superseded writer's own guard could emit, the tightest available
772
+ // bound on "these bytes really are an old previousVersion"
773
+ if (!(decoder.getFloat64(start) > 1))
774
+ return corruptEntry(buffer, start, end, firstByte);
775
+ entryStart = decoder.position = start + 8;
776
+ // The value itself is dropped, not reported. It cannot lead with 0x42 (that is the branch
777
+ // above), and audit keys carry the same constraint, so it could never have addressed a
778
+ // retrievable entry; reporting it would only feed an unrepresentable value back to
779
+ // createAuditEntry through the resolveRecord re-mint in RecordEncoder, which now rejects it.
780
+ }
556
781
  const action = decoder.readInt();
782
+ if (entryStart !== start && !isDecodableAction(action)) {
783
+ return corruptEntry(buffer, start, end, firstByte);
784
+ }
557
785
  const nodeId = decoder.readInt();
558
786
  const tableId = decoder.readInt();
787
+ if (entryStart !== start && !warnedRecoveredTables.has(tableId)) {
788
+ warnedRecoveredTables.add(tableId);
789
+ warnContained('Audit entry carries an unannounced previousVersion field; recovering its field offsets', {
790
+ tableId,
791
+ firstByte,
792
+ });
793
+ }
559
794
  let length = decoder.readInt();
560
795
  // A corrupt length field (e.g., a 0xff-prefixed uint32) would otherwise push
561
796
  // decoder.position hundreds of megabytes past the buffer; the next readFloat64
@@ -625,7 +860,6 @@ function readAuditEntry(buffer, start = 0, end = undefined) {
625
860
  return buffer.subarray(recordIdStart, recordIdEnd);
626
861
  },
627
862
  version,
628
- recordVersion: version,
629
863
  previousVersion,
630
864
  get user() {
631
865
  try {
@@ -639,10 +873,14 @@ function readAuditEntry(buffer, start = 0, end = undefined) {
639
873
  }
640
874
  },
641
875
  get encoded() {
642
- return start ? buffer.subarray(start, end) : buffer;
876
+ // On a recovered entry this drops the unannounced prefix, so a replication sender —
877
+ // which strips by the same leading-0x42 test and frames by encoded.length — forwards a
878
+ // clean entry instead of passing the same misparse to the next hop.
879
+ return entryStart ? buffer.subarray(entryStart, end) : buffer;
643
880
  },
644
881
  get size() {
645
- return start !== undefined && end !== undefined ? end - start : buffer.byteLength;
882
+ // only the recovered prefix is discounted; every other case keeps its existing basis
883
+ return (end !== undefined ? end - start : buffer.byteLength) - (entryStart - start);
646
884
  },
647
885
  getValue(store, fullRecord, auditTime) {
648
886
  if (action & HAS_RECORD || (action & HAS_PARTIAL_RECORD && !fullRecord)) {
@@ -687,6 +925,22 @@ function readAuditEntry(buffer, start = 0, end = undefined) {
687
925
  return createCorruptAuditSentinel(buffer, start, end);
688
926
  }
689
927
  }
928
+ /**
929
+ * Reject a header whose first byte can be neither an action nor a previousVersion field. Returns the
930
+ * sentinel directly rather than throwing into readAuditEntry's catch, whose error log is not
931
+ * contained: a throwing log sink there would escape the decoder and stall the iteration it runs in.
932
+ */
933
+ function corruptEntry(buffer, start, end, firstByte) {
934
+ if (!warnedUndecodableHeader) {
935
+ warnedUndecodableHeader = true;
936
+ warnContained('Audit entry header begins with neither an action nor a previousVersion; treating as corrupt', {
937
+ firstByte,
938
+ // the 8 prefix bytes plus the action byte: the classifying bytes, stopping before the recordId
939
+ header: Buffer.from(buffer.subarray(start, Math.min(start + 9, buffer.byteLength))).toString('hex'),
940
+ });
941
+ }
942
+ return createCorruptAuditSentinel(buffer, start, end);
943
+ }
690
944
  /**
691
945
  * Build a structurally complete audit record for an entry that failed to decode. The fields
692
946
  * mirror the happy-path shape so downstream consumers that access (e.g.) `getValue` or the