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