@harperfast/harper 5.0.0-alpha.10 → 5.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (444) hide show
  1. package/bin/BinObjects.js +17 -0
  2. package/bin/cliOperations.js +157 -0
  3. package/bin/copyDb.ts +280 -0
  4. package/bin/harper.js +156 -0
  5. package/bin/install.js +15 -0
  6. package/bin/lite.js +5 -0
  7. package/bin/restart.js +201 -0
  8. package/bin/run.js +409 -0
  9. package/bin/status.js +65 -0
  10. package/bin/stop.js +22 -0
  11. package/bin/upgrade.js +134 -0
  12. package/components/Application.ts +646 -0
  13. package/components/ApplicationScope.ts +49 -0
  14. package/components/Component.ts +53 -0
  15. package/components/ComponentV1.ts +342 -0
  16. package/components/DEFAULT_CONFIG.ts +18 -0
  17. package/components/EntryHandler.ts +227 -0
  18. package/components/Logger.ts +14 -0
  19. package/components/OptionsWatcher.ts +354 -0
  20. package/components/PluginModule.ts +6 -0
  21. package/components/Scope.ts +329 -0
  22. package/components/componentLoader.ts +529 -0
  23. package/components/deriveCommonPatternBase.ts +31 -0
  24. package/components/deriveGlobOptions.ts +44 -0
  25. package/components/deriveURLPath.ts +57 -0
  26. package/components/operations.js +658 -0
  27. package/components/operationsValidation.js +246 -0
  28. package/components/packageComponent.ts +39 -0
  29. package/components/requestRestart.ts +26 -0
  30. package/components/resolveBaseURLPath.ts +38 -0
  31. package/components/status/ComponentStatus.ts +110 -0
  32. package/components/status/ComponentStatusRegistry.ts +251 -0
  33. package/components/status/api.ts +153 -0
  34. package/components/status/crossThread.ts +405 -0
  35. package/components/status/errors.ts +152 -0
  36. package/components/status/index.ts +44 -0
  37. package/components/status/internal.ts +65 -0
  38. package/components/status/registry.ts +12 -0
  39. package/components/status/types.ts +96 -0
  40. package/config/RootConfigWatcher.ts +59 -0
  41. package/config/configHelpers.ts +11 -0
  42. package/config/configUtils.js +967 -0
  43. package/config/harperConfigEnvVars.ts +641 -0
  44. package/dataLayer/CreateAttributeObject.js +25 -0
  45. package/dataLayer/CreateTableObject.js +11 -0
  46. package/dataLayer/DataLayerObjects.js +43 -0
  47. package/dataLayer/DeleteBeforeObject.js +22 -0
  48. package/dataLayer/DeleteObject.js +25 -0
  49. package/dataLayer/DropAttributeObject.js +11 -0
  50. package/dataLayer/GetBackupObject.js +22 -0
  51. package/dataLayer/InsertObject.js +24 -0
  52. package/dataLayer/ReadAuditLogObject.js +24 -0
  53. package/dataLayer/SQLSearch.js +1335 -0
  54. package/dataLayer/SearchByConditionsObject.js +61 -0
  55. package/dataLayer/SearchByHashObject.js +21 -0
  56. package/dataLayer/SearchObject.js +45 -0
  57. package/dataLayer/SqlSearchObject.js +14 -0
  58. package/dataLayer/UpdateObject.js +23 -0
  59. package/dataLayer/UpsertObject.js +23 -0
  60. package/dataLayer/bulkLoad.js +813 -0
  61. package/dataLayer/dataObjects/BulkLoadObjects.js +27 -0
  62. package/dataLayer/dataObjects/UpsertObject.js +23 -0
  63. package/dataLayer/delete.js +164 -0
  64. package/dataLayer/export.js +381 -0
  65. package/dataLayer/getBackup.js +40 -0
  66. package/dataLayer/harperBridge/BridgeMethods.js +81 -0
  67. package/dataLayer/harperBridge/ResourceBridge.ts +633 -0
  68. package/dataLayer/harperBridge/bridgeUtility/insertUpdateReturnObj.js +28 -0
  69. package/dataLayer/harperBridge/bridgeUtility/insertUpdateValidate.js +88 -0
  70. package/dataLayer/harperBridge/harperBridge.js +21 -0
  71. package/dataLayer/harperBridge/lmdbBridge/LMDBBridge.js +119 -0
  72. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js +19 -0
  73. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateAttribute.js +112 -0
  74. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateRecords.js +67 -0
  75. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateSchema.js +31 -0
  76. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateTable.js +94 -0
  77. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDeleteAuditLogsBefore.js +98 -0
  78. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDeleteRecords.js +89 -0
  79. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDropAttribute.js +109 -0
  80. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDropSchema.js +107 -0
  81. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDropTable.js +137 -0
  82. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbFlush.js +35 -0
  83. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbGetBackup.js +111 -0
  84. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbGetDataByHash.js +28 -0
  85. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbGetDataByValue.js +29 -0
  86. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbReadAuditLog.js +207 -0
  87. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbSearchByConditions.js +156 -0
  88. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbSearchByHash.js +21 -0
  89. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbSearchByValue.js +30 -0
  90. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbTransaction.js +19 -0
  91. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbUpdateRecords.js +64 -0
  92. package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbUpsertRecords.js +70 -0
  93. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBCreateAttributeObject.js +22 -0
  94. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBDeleteTransactionObject.js +23 -0
  95. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBInsertTransactionObject.js +22 -0
  96. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBTransactionObject.js +23 -0
  97. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBUpdateTransactionObject.js +24 -0
  98. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBUpsertTransactionObject.js +24 -0
  99. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/TableSizeObject.js +25 -0
  100. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializeHashSearch.js +21 -0
  101. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js +157 -0
  102. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbCheckForNewAttributes.js +94 -0
  103. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbCreateTransactionsAuditEnvironment.js +39 -0
  104. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.js +34 -0
  105. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbProcessRows.js +100 -0
  106. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbSearch.js +371 -0
  107. package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbWriteTransaction.js +109 -0
  108. package/dataLayer/hdbInfoController.js +254 -0
  109. package/dataLayer/insert.js +266 -0
  110. package/dataLayer/readAuditLog.js +59 -0
  111. package/dataLayer/schema.js +366 -0
  112. package/dataLayer/schemaDescribe.js +289 -0
  113. package/dataLayer/search.js +60 -0
  114. package/dataLayer/transaction.js +17 -0
  115. package/dataLayer/update.js +124 -0
  116. package/dist/components/Logger.d.ts +12 -0
  117. package/dist/components/Logger.js +3 -0
  118. package/dist/components/Logger.js.map +1 -0
  119. package/dist/components/Scope.d.ts +14 -4
  120. package/dist/components/Scope.js +18 -10
  121. package/dist/components/Scope.js.map +1 -1
  122. package/dist/components/componentLoader.js +16 -9
  123. package/dist/components/componentLoader.js.map +1 -1
  124. package/dist/components/operations.js +2 -2
  125. package/dist/components/operations.js.map +1 -1
  126. package/dist/config/configUtils.d.ts +1 -1
  127. package/dist/config/configUtils.js +1 -1
  128. package/dist/config/configUtils.js.map +1 -1
  129. package/dist/dataLayer/CreateTableObject.d.ts +2 -2
  130. package/dist/dataLayer/CreateTableObject.js +2 -2
  131. package/dist/dataLayer/CreateTableObject.js.map +1 -1
  132. package/dist/dataLayer/delete.d.ts +1 -1
  133. package/dist/dataLayer/schema.js +6 -5
  134. package/dist/dataLayer/schema.js.map +1 -1
  135. package/dist/dataLayer/schemaDescribe.js +1 -1
  136. package/dist/dataLayer/schemaDescribe.js.map +1 -1
  137. package/dist/index.d.ts +1 -1
  138. package/dist/index.js +2 -0
  139. package/dist/index.js.map +1 -1
  140. package/dist/resources/DatabaseTransaction.d.ts +1 -1
  141. package/dist/resources/IterableEventQueue.d.ts +1 -1
  142. package/dist/resources/LMDBTransaction.d.ts +5 -1
  143. package/dist/resources/Resource.d.ts +1 -1
  144. package/dist/resources/RocksIndexStore.d.ts +3 -3
  145. package/dist/resources/RocksTransactionLogStore.d.ts +6 -3
  146. package/dist/resources/Table.d.ts +15 -6
  147. package/dist/resources/Table.js +4 -1
  148. package/dist/resources/Table.js.map +1 -1
  149. package/dist/resources/analytics/read.js +32 -22
  150. package/dist/resources/analytics/read.js.map +1 -1
  151. package/dist/resources/analytics/write.js +3 -6
  152. package/dist/resources/analytics/write.js.map +1 -1
  153. package/dist/resources/auditStore.d.ts +3 -3
  154. package/dist/resources/blob.d.ts +25 -2
  155. package/dist/resources/databases.d.ts +12 -2
  156. package/dist/resources/databases.js +22 -19
  157. package/dist/resources/databases.js.map +1 -1
  158. package/dist/resources/search.js +11 -5
  159. package/dist/resources/search.js.map +1 -1
  160. package/dist/resources/transaction.d.ts +2 -1
  161. package/dist/security/auth.js +1 -1
  162. package/dist/security/auth.js.map +1 -1
  163. package/dist/security/cryptoHash.d.ts +2 -2
  164. package/dist/security/jsLoader.js +243 -66
  165. package/dist/security/jsLoader.js.map +1 -1
  166. package/dist/security/keys.js +4 -5
  167. package/dist/security/keys.js.map +1 -1
  168. package/dist/security/user.js +3 -3
  169. package/dist/security/user.js.map +1 -1
  170. package/dist/server/REST.js +16 -2
  171. package/dist/server/REST.js.map +1 -1
  172. package/dist/server/Server.d.ts +2 -1
  173. package/dist/server/Server.js.map +1 -1
  174. package/dist/server/fastifyRoutes/plugins/hdbCore.d.ts +6 -1
  175. package/dist/server/fastifyRoutes.js +2 -0
  176. package/dist/server/fastifyRoutes.js.map +1 -1
  177. package/dist/server/http.js +12 -6
  178. package/dist/server/http.js.map +1 -1
  179. package/dist/server/jobs/JobObject.d.ts +3 -3
  180. package/dist/server/loadRootComponents.js +1 -0
  181. package/dist/server/loadRootComponents.js.map +1 -1
  182. package/dist/server/operationsServer.js +3 -1
  183. package/dist/server/operationsServer.js.map +1 -1
  184. package/dist/server/serverHelpers/JSONStream.d.ts +3 -3
  185. package/dist/server/serverHelpers/Request.d.ts +5 -5
  186. package/dist/server/serverHelpers/requestTimePlugin.d.ts +1 -1
  187. package/dist/server/threads/manageThreads.d.ts +2 -2
  188. package/dist/server/threads/manageThreads.js +50 -35
  189. package/dist/server/threads/manageThreads.js.map +1 -1
  190. package/dist/server/threads/socketRouter.d.ts +1 -1
  191. package/dist/sqlTranslator/deleteTranslator.d.ts +1 -1
  192. package/dist/utility/AWS/AWSConnector.d.ts +3 -2
  193. package/dist/utility/common_utils.d.ts +3 -3
  194. package/dist/utility/environment/systemInformation.d.ts +1 -0
  195. package/dist/utility/functions/date/dateFunctions.d.ts +11 -11
  196. package/dist/utility/globalSchema.d.ts +1 -1
  197. package/dist/utility/hdbTerms.d.ts +3 -0
  198. package/dist/utility/hdbTerms.js +3 -0
  199. package/dist/utility/hdbTerms.js.map +1 -1
  200. package/dist/utility/installation.d.ts +2 -4
  201. package/dist/utility/installation.js.map +1 -1
  202. package/dist/utility/lmdb/commonUtility.d.ts +1 -0
  203. package/dist/utility/lmdb/deleteUtility.d.ts +1 -0
  204. package/dist/utility/lmdb/environmentUtility.d.ts +1 -0
  205. package/dist/utility/lmdb/searchUtility.d.ts +2 -1
  206. package/dist/utility/lmdb/writeUtility.d.ts +1 -0
  207. package/dist/utility/logging/harper_logger.d.ts +6 -6
  208. package/dist/utility/processManagement/processManagement.d.ts +1 -1
  209. package/dist/utility/processManagement/servicesConfig.d.ts +12 -6
  210. package/dist/validation/common_validators.d.ts +4 -3
  211. package/dist/validation/configValidator.d.ts +3 -2
  212. package/index.d.ts +56 -0
  213. package/index.js +41 -0
  214. package/json/systemSchema.json +373 -0
  215. package/launchServiceScripts/launchHarperDB.js +3 -0
  216. package/launchServiceScripts/utility/checkNodeVersion.js +15 -0
  217. package/package.json +21 -3
  218. package/resources/DatabaseTransaction.ts +378 -0
  219. package/resources/ErrorResource.ts +57 -0
  220. package/resources/IterableEventQueue.ts +94 -0
  221. package/resources/LMDBTransaction.ts +349 -0
  222. package/resources/RecordEncoder.ts +702 -0
  223. package/resources/RequestTarget.ts +134 -0
  224. package/resources/Resource.ts +789 -0
  225. package/resources/ResourceInterface.ts +221 -0
  226. package/resources/ResourceInterfaceV2.ts +53 -0
  227. package/resources/ResourceV2.ts +67 -0
  228. package/resources/Resources.ts +162 -0
  229. package/resources/RocksIndexStore.ts +70 -0
  230. package/resources/RocksTransactionLogStore.ts +352 -0
  231. package/resources/Table.ts +4527 -0
  232. package/resources/analytics/hostnames.ts +72 -0
  233. package/resources/analytics/metadata.ts +10 -0
  234. package/resources/analytics/read.ts +252 -0
  235. package/resources/analytics/write.ts +803 -0
  236. package/resources/auditStore.ts +556 -0
  237. package/resources/blob.ts +1268 -0
  238. package/resources/crdt.ts +125 -0
  239. package/resources/dataLoader.ts +527 -0
  240. package/resources/databases.ts +1290 -0
  241. package/resources/graphql.ts +221 -0
  242. package/resources/indexes/HierarchicalNavigableSmallWorld.ts +638 -0
  243. package/resources/indexes/customIndexes.ts +7 -0
  244. package/resources/indexes/vector.ts +38 -0
  245. package/resources/jsResource.ts +86 -0
  246. package/resources/loadEnv.ts +22 -0
  247. package/resources/login.ts +18 -0
  248. package/resources/openApi.ts +409 -0
  249. package/resources/registrationDeprecated.ts +8 -0
  250. package/resources/replayLogs.ts +136 -0
  251. package/resources/roles.ts +98 -0
  252. package/resources/search.ts +1301 -0
  253. package/resources/tracked.ts +584 -0
  254. package/resources/transaction.ts +89 -0
  255. package/resources/transactionBroadcast.ts +258 -0
  256. package/security/auth.ts +376 -0
  257. package/security/certificateVerification/certificateVerificationSource.ts +84 -0
  258. package/security/certificateVerification/configValidation.ts +107 -0
  259. package/security/certificateVerification/crlVerification.ts +623 -0
  260. package/security/certificateVerification/index.ts +121 -0
  261. package/security/certificateVerification/ocspVerification.ts +148 -0
  262. package/security/certificateVerification/pkijs-ed25519-patch.ts +188 -0
  263. package/security/certificateVerification/types.ts +128 -0
  264. package/security/certificateVerification/verificationConfig.ts +138 -0
  265. package/security/certificateVerification/verificationUtils.ts +447 -0
  266. package/security/cryptoHash.js +42 -0
  267. package/security/data_objects/PermissionAttributeResponseObject.js +15 -0
  268. package/security/data_objects/PermissionResponseObject.js +115 -0
  269. package/security/data_objects/PermissionTableResponseObject.js +20 -0
  270. package/security/fastifyAuth.js +169 -0
  271. package/security/impersonation.ts +160 -0
  272. package/security/jsLoader.ts +716 -0
  273. package/security/keys.js +948 -0
  274. package/security/permissionsTranslator.js +300 -0
  275. package/security/role.js +218 -0
  276. package/security/tokenAuthentication.ts +228 -0
  277. package/security/user.ts +449 -0
  278. package/server/DurableSubscriptionsSession.ts +503 -0
  279. package/server/REST.ts +407 -0
  280. package/server/Server.ts +89 -0
  281. package/server/fastifyRoutes/helpers/getCORSOptions.js +36 -0
  282. package/server/fastifyRoutes/helpers/getHeaderTimeoutConfig.js +15 -0
  283. package/server/fastifyRoutes/helpers/getServerOptions.js +33 -0
  284. package/server/fastifyRoutes/plugins/hdbCore.js +39 -0
  285. package/server/fastifyRoutes.ts +205 -0
  286. package/server/graphqlQuerying.ts +700 -0
  287. package/server/http.ts +640 -0
  288. package/server/itc/serverHandlers.js +161 -0
  289. package/server/itc/utility/ITCEventObject.js +10 -0
  290. package/server/jobs/JobObject.js +24 -0
  291. package/server/jobs/jobProcess.js +69 -0
  292. package/server/jobs/jobRunner.js +162 -0
  293. package/server/jobs/jobs.js +304 -0
  294. package/server/loadRootComponents.js +44 -0
  295. package/server/mqtt.ts +485 -0
  296. package/server/nodeName.ts +75 -0
  297. package/server/operationsServer.ts +313 -0
  298. package/server/serverHelpers/Headers.ts +108 -0
  299. package/server/serverHelpers/JSONStream.ts +269 -0
  300. package/server/serverHelpers/OperationFunctionObject.ts +13 -0
  301. package/server/serverHelpers/Request.ts +158 -0
  302. package/server/serverHelpers/contentTypes.ts +637 -0
  303. package/server/serverHelpers/requestTimePlugin.js +57 -0
  304. package/server/serverHelpers/serverHandlers.js +148 -0
  305. package/server/serverHelpers/serverUtilities.ts +473 -0
  306. package/server/serverRegistry.ts +8 -0
  307. package/server/static.ts +187 -0
  308. package/server/status/definitions.ts +37 -0
  309. package/server/status/index.ts +125 -0
  310. package/server/storageReclamation.ts +93 -0
  311. package/server/threads/itc.js +89 -0
  312. package/server/threads/manageThreads.js +594 -0
  313. package/server/threads/socketRouter.ts +360 -0
  314. package/server/threads/threadServer.js +279 -0
  315. package/server/throttle.ts +73 -0
  316. package/sqlTranslator/SelectValidator.js +330 -0
  317. package/sqlTranslator/alasqlFunctionImporter.js +62 -0
  318. package/sqlTranslator/deleteTranslator.js +67 -0
  319. package/sqlTranslator/index.js +242 -0
  320. package/sqlTranslator/sql_statement_bucket.js +472 -0
  321. package/static/defaultConfig.yaml +3 -0
  322. package/studio/web/HDBDogOnly.svg +78 -0
  323. package/studio/web/assets/PPRadioGrotesk-Bold-DDaUYG8E.woff +0 -0
  324. package/studio/web/assets/fa-brands-400-CEJbCg16.woff +0 -0
  325. package/studio/web/assets/fa-brands-400-CSYNqBb_.ttf +0 -0
  326. package/studio/web/assets/fa-brands-400-DnkPfk3o.eot +0 -0
  327. package/studio/web/assets/fa-brands-400-UxlILjvJ.woff2 +0 -0
  328. package/studio/web/assets/fa-brands-400-cH1MgKbP.svg +3717 -0
  329. package/studio/web/assets/fa-regular-400-BhTwtT8w.eot +0 -0
  330. package/studio/web/assets/fa-regular-400-D1vz6WBx.ttf +0 -0
  331. package/studio/web/assets/fa-regular-400-DFnMcJPd.woff +0 -0
  332. package/studio/web/assets/fa-regular-400-DGzu1beS.woff2 +0 -0
  333. package/studio/web/assets/fa-regular-400-gwj8Pxq-.svg +801 -0
  334. package/studio/web/assets/fa-solid-900-B4ZZ7kfP.svg +5034 -0
  335. package/studio/web/assets/fa-solid-900-B6Axprfb.eot +0 -0
  336. package/studio/web/assets/fa-solid-900-BUswJgRo.woff2 +0 -0
  337. package/studio/web/assets/fa-solid-900-DOXgCApm.woff +0 -0
  338. package/studio/web/assets/fa-solid-900-mxuxnBEa.ttf +0 -0
  339. package/studio/web/assets/index-BTgXJX9d.js +235 -0
  340. package/studio/web/assets/index-BTgXJX9d.js.map +1 -0
  341. package/studio/web/assets/index-C-GXfcup.js +37 -0
  342. package/studio/web/assets/index-C-GXfcup.js.map +1 -0
  343. package/studio/web/assets/index-PFlNdimM.js +2 -0
  344. package/studio/web/assets/index-PFlNdimM.js.map +1 -0
  345. package/studio/web/assets/index-Y2g_iFpU.css +1 -0
  346. package/studio/web/assets/index-jiPwkrsB.css +1 -0
  347. package/studio/web/assets/index.lazy-C3TJZJ4o.js +266 -0
  348. package/studio/web/assets/index.lazy-C3TJZJ4o.js.map +1 -0
  349. package/studio/web/assets/profiler-DotzgiCJ.js +2 -0
  350. package/studio/web/assets/profiler-DotzgiCJ.js.map +1 -0
  351. package/studio/web/assets/react-redux-VxUEx_mU.js +6 -0
  352. package/studio/web/assets/react-redux-VxUEx_mU.js.map +1 -0
  353. package/studio/web/assets/startRecording-B_9J9Csd.js +3 -0
  354. package/studio/web/assets/startRecording-B_9J9Csd.js.map +1 -0
  355. package/studio/web/fabric-signup-background.webp +0 -0
  356. package/studio/web/fabric-signup-text.png +0 -0
  357. package/studio/web/favicon_purple.png +0 -0
  358. package/studio/web/github-icon.svg +15 -0
  359. package/studio/web/harper-fabric_black.png +0 -0
  360. package/studio/web/harper-fabric_white.png +0 -0
  361. package/studio/web/harper-studio_white.png +0 -0
  362. package/studio/web/index.html +16 -0
  363. package/studio/web/running.css +148 -0
  364. package/studio/web/running.html +147 -0
  365. package/studio/web/running.js +111 -0
  366. package/upgrade/UpgradeObjects.js +13 -0
  367. package/upgrade/directives/directivesController.js +90 -0
  368. package/upgrade/directivesManager.js +139 -0
  369. package/upgrade/upgradePrompt.js +124 -0
  370. package/upgrade/upgradeUtilities.js +28 -0
  371. package/utility/AWS/AWSConnector.js +29 -0
  372. package/utility/OperationFunctionCaller.js +63 -0
  373. package/utility/assignCmdEnvVariables.js +62 -0
  374. package/utility/common_utils.js +867 -0
  375. package/utility/environment/environmentManager.js +208 -0
  376. package/utility/environment/systemInformation.js +355 -0
  377. package/utility/errors/commonErrors.js +267 -0
  378. package/utility/errors/hdbError.js +146 -0
  379. package/utility/functions/date/dateFunctions.js +65 -0
  380. package/utility/functions/geo.js +355 -0
  381. package/utility/functions/sql/alaSQLExtension.js +104 -0
  382. package/utility/globalSchema.js +35 -0
  383. package/utility/hdbTerms.ts +819 -0
  384. package/utility/install/checkJWTTokensExist.js +62 -0
  385. package/utility/install/harperdb.conf +15 -0
  386. package/utility/install/harperdb.service +14 -0
  387. package/utility/install/installer.js +635 -0
  388. package/utility/installation.ts +30 -0
  389. package/utility/lmdb/DBIDefinition.js +20 -0
  390. package/utility/lmdb/DeleteRecordsResponseObject.js +25 -0
  391. package/utility/lmdb/InsertRecordsResponseObject.js +22 -0
  392. package/utility/lmdb/OpenDBIObject.js +31 -0
  393. package/utility/lmdb/OpenEnvironmentObject.js +41 -0
  394. package/utility/lmdb/UpdateRecordsResponseObject.js +25 -0
  395. package/utility/lmdb/UpsertRecordsResponseObject.js +22 -0
  396. package/utility/lmdb/cleanLMDBMap.js +65 -0
  397. package/utility/lmdb/commonUtility.js +119 -0
  398. package/utility/lmdb/deleteUtility.js +128 -0
  399. package/utility/lmdb/environmentUtility.js +477 -0
  400. package/utility/lmdb/searchCursorFunctions.js +187 -0
  401. package/utility/lmdb/searchUtility.js +918 -0
  402. package/utility/lmdb/terms.js +57 -0
  403. package/utility/lmdb/writeUtility.js +407 -0
  404. package/utility/logging/harper_logger.js +876 -0
  405. package/utility/logging/logRotator.js +157 -0
  406. package/utility/logging/logger.ts +24 -0
  407. package/utility/logging/readLog.js +355 -0
  408. package/utility/logging/transactionLog.js +57 -0
  409. package/utility/mount_hdb.js +59 -0
  410. package/utility/npmUtilities.js +102 -0
  411. package/utility/operationPermissions.ts +112 -0
  412. package/utility/operation_authorization.js +836 -0
  413. package/utility/packageUtils.js +55 -0
  414. package/utility/password.ts +99 -0
  415. package/utility/processManagement/processManagement.js +187 -0
  416. package/utility/processManagement/servicesConfig.js +56 -0
  417. package/utility/scripts/restartHdb.js +24 -0
  418. package/utility/scripts/user_data.sh +13 -0
  419. package/utility/signalling.js +36 -0
  420. package/utility/terms/certificates.js +81 -0
  421. package/utility/when.ts +20 -0
  422. package/v1.d.ts +39 -0
  423. package/v1.js +41 -0
  424. package/v2.d.ts +39 -0
  425. package/v2.js +41 -0
  426. package/validation/bulkDeleteValidator.js +24 -0
  427. package/validation/check_permissions.js +19 -0
  428. package/validation/common_validators.js +95 -0
  429. package/validation/configValidator.js +331 -0
  430. package/validation/deleteValidator.js +15 -0
  431. package/validation/fileLoadValidator.js +153 -0
  432. package/validation/insertValidator.js +40 -0
  433. package/validation/installValidator.js +37 -0
  434. package/validation/readLogValidator.js +64 -0
  435. package/validation/role_validation.js +320 -0
  436. package/validation/schemaMetadataValidator.js +42 -0
  437. package/validation/searchValidator.js +166 -0
  438. package/validation/statusValidator.ts +66 -0
  439. package/validation/transactionLogValidator.js +33 -0
  440. package/validation/user_validation.js +55 -0
  441. package/validation/validationWrapper.js +105 -0
  442. package/dist/resources/analytics/profile.d.ts +0 -2
  443. package/dist/resources/analytics/profile.js +0 -144
  444. package/dist/resources/analytics/profile.js.map +0 -1
@@ -0,0 +1,702 @@
1
+ /**
2
+ * This module is responsible for handling metadata encoding and decoding in database records, which is
3
+ * used for local timestamps (that lmdb-js can assign during a transaction for guaranteed monotonic
4
+ * assignment across threads) and can be used for storing residency information as well. This
5
+ * patches the primary store to properly get the metadata and assign it to the entries.
6
+ */
7
+
8
+ import { Encoder } from 'msgpackr';
9
+ import {
10
+ HAS_PREVIOUS_RESIDENCY_ID,
11
+ HAS_CURRENT_RESIDENCY_ID,
12
+ HAS_EXPIRATION_EXTENDED_TYPE,
13
+ HAS_ORIGINATING_OPERATION,
14
+ HAS_BLOBS,
15
+ ACTION_32_BIT,
16
+ HAS_ADDITIONAL_AUDIT_REFS as HAS_ADDITIONAL_AUDIT_REFS_AUDIT,
17
+ } from './auditStore.ts';
18
+ import * as harperLogger from '../utility/logging/harper_logger.js';
19
+ import './blob.ts';
20
+ import { blobsWereEncoded, decodeFromDatabase, deleteBlobsInObject, encodeBlobsWithFilePath } from './blob.ts';
21
+ import { recordAction } from './analytics/write.ts';
22
+ import { RocksDatabase } from '@harperfast/rocksdb-js';
23
+ import { when } from '../utility/when.ts';
24
+ export type Entry = {
25
+ key: any;
26
+ value: any;
27
+ version: number;
28
+ localTime: number;
29
+ expiresAt: number;
30
+ metadataFlags: number;
31
+ nodeId: number;
32
+ residencyId: number;
33
+ size: number;
34
+ deref?: () => any;
35
+ additionalAuditRefs?: Array<{ version: number; nodeId: number }>;
36
+ };
37
+
38
+ // these are matched by lmdb-js for timestamp replacement. the first byte here is used to xor with the first byte of the date as a double so that it ends up less than 32 for easier identification (otherwise dates start with 66)
39
+ export const TIMESTAMP_PLACEHOLDER = new Uint8Array([1, 1, 1, 1, 4, 0x40, 0, 0]);
40
+ // the first byte here indicates that we use the last timestamp
41
+ export const LAST_TIMESTAMP_PLACEHOLDER = new Uint8Array([1, 1, 1, 1, 1, 0, 0, 0]);
42
+ export const PREVIOUS_TIMESTAMP_PLACEHOLDER = new Uint8Array([1, 1, 1, 1, 3, 0x40, 0, 0]);
43
+ export const NEW_TIMESTAMP_PLACEHOLDER = new Uint8Array([1, 1, 1, 1, 0, 0x40, 0, 0]);
44
+ export const LOCAL_TIMESTAMP = Symbol('local-timestamp');
45
+ export const METADATA = Symbol('metadata');
46
+ export const ENTRY = Symbol('entry');
47
+ const TIMESTAMP_HOLDER = new Uint8Array(8);
48
+ const TIMESTAMP_VIEW = new DataView(TIMESTAMP_HOLDER.buffer, 0, 8);
49
+ export const NO_TIMESTAMP = 0;
50
+ export const TIMESTAMP_ASSIGN_NEW = 0;
51
+ export const TIMESTAMP_ASSIGN_LAST = 1;
52
+ export const TIMESTAMP_ASSIGN_PREVIOUS = 3;
53
+ export const TIMESTAMP_RECORD_PREVIOUS = 4;
54
+ export const HAS_EXPIRATION = 16;
55
+ export const HAS_RESIDENCY_ID = 32;
56
+ export const HAS_NODE_ID = 64;
57
+ export const PENDING_LOCAL_TIME = 1;
58
+ export const HAS_STRUCTURE_UPDATE = 0x100;
59
+ export const HAS_ADDITIONAL_AUDIT_REFS = 0x80;
60
+
61
+ const TRACKED_WRITE_TYPES = new Set(['put', 'patch', 'delete', 'message', 'publish']);
62
+ // For now we use this as the private property mechanism for mapping records to entries.
63
+ // WeakMaps are definitely not the fastest form of private properties, but they are the only
64
+ // way to do this with how the objects are frozen for now.
65
+ export const entryMap = new WeakMap<any, Entry>();
66
+ let lastValueEncoding,
67
+ timestampNextEncoding = 0,
68
+ metadataInNextEncoding = -1,
69
+ expiresAtNextEncoding = -1,
70
+ residencyIdAtNextEncoding = 0,
71
+ nodeIdAtNextEncoding = -1,
72
+ additionalAuditRefsNextEncoding: Array<{ version: number; nodeId: number }> | undefined;
73
+ // tracking metadata with a singleton works better than trying to alter response of getEntry/get and coordinating that across caching layers
74
+ export let lastMetadata: Entry | null = null;
75
+ export class RecordEncoder extends Encoder {
76
+ structureUpdate?: any;
77
+ isRocksDB: boolean;
78
+ name: string;
79
+ constructor(options) {
80
+ options.useBigIntExtension = true;
81
+ /**
82
+ * The base class for records that provides the read-only methods for accessing
83
+ * metadata and will be assigned computed property getters. On its own, these instances
84
+ * are usually frozen, but this can be extended (by the Updatable class) for providing
85
+ * mutation methods.
86
+ */
87
+ class RecordObject {
88
+ getUpdatedTime() {
89
+ return entryMap.get(this)?.version;
90
+ }
91
+ getExpiresAt() {
92
+ return entryMap.get(this)?.expiresAt;
93
+ }
94
+ }
95
+
96
+ options.structPrototype = RecordObject.prototype;
97
+ super(options);
98
+ const superEncode = this.encode;
99
+ this.encode = function (record, options?) {
100
+ // this handles our custom metadata encoding, prefixing the record with metadata, including the local
101
+ // timestamp into the audit record, invalidation status and residency information
102
+ if (timestampNextEncoding || metadataInNextEncoding >= 0) {
103
+ let valueStart = 0;
104
+ const timestamp = timestampNextEncoding;
105
+ if (timestamp) {
106
+ valueStart += 8; // make room for local timestamp
107
+ timestampNextEncoding = 0;
108
+ }
109
+ let metadata = metadataInNextEncoding;
110
+ const expiresAt = expiresAtNextEncoding;
111
+ const residencyId = residencyIdAtNextEncoding;
112
+ const nodeId = nodeIdAtNextEncoding;
113
+ const additionalAuditRefs = additionalAuditRefsNextEncoding;
114
+ if (metadata >= 0) {
115
+ valueStart += 4; // make room for metadata bytes
116
+ metadataInNextEncoding = -1; // reset indicator to mean no metadata
117
+ if (expiresAt >= 0) {
118
+ valueStart += 8; // make room for expiration timestamp
119
+ expiresAtNextEncoding = -1; // reset indicator to mean no expiration
120
+ if (!(metadata & HAS_EXPIRATION)) {
121
+ throw new Error('Expiration included, but not in metadata flags');
122
+ }
123
+ }
124
+ if (residencyId) {
125
+ valueStart += 4; // make room for residency id
126
+ residencyIdAtNextEncoding = 0; // reset indicator to mean no residency id
127
+ if (!(metadata & HAS_RESIDENCY_ID)) {
128
+ throw new Error('Residency id included, but not in metadata flags');
129
+ }
130
+ }
131
+ if (nodeId >= 0) {
132
+ valueStart += 4; // make room for node id
133
+ nodeIdAtNextEncoding = -1; // reset indicator to mean no node id
134
+ if (!(metadata & HAS_NODE_ID)) {
135
+ throw new Error('Node id included, but not in metadata flags');
136
+ }
137
+ }
138
+ if (additionalAuditRefs && additionalAuditRefs.length > 0) {
139
+ valueStart += 1 + additionalAuditRefs.length * 12; // 1 byte for count + 8 bytes version + 4 bytes nodeId per ref
140
+ additionalAuditRefsNextEncoding = undefined;
141
+ }
142
+ }
143
+ const encoded = superEncode.call(this, record, options | 2048 | valueStart); // encode with 8 bytes reserved space for txnId
144
+ lastValueEncoding = encoded.subarray((encoded.start || 0) + valueStart, encoded.end);
145
+ let position = encoded.start || 0;
146
+ const dataView =
147
+ encoded.dataView || (encoded.dataView = new DataView(encoded.buffer, encoded.byteOffset, encoded.byteLength));
148
+ if (timestamp) {
149
+ if (this.isRocksDB) {
150
+ // rocksdb, just store the version directly as the timestamp
151
+ dataView.setFloat64(position, timestamp);
152
+ } else {
153
+ // we apply the special instruction bytes that tell lmdb-js how to assign the timestamp
154
+ TIMESTAMP_PLACEHOLDER[4] = timestamp;
155
+ TIMESTAMP_PLACEHOLDER[5] = timestamp >> 8;
156
+ encoded.set(TIMESTAMP_PLACEHOLDER, position);
157
+ }
158
+ position += 8;
159
+ }
160
+ if (blobsWereEncoded) metadata |= HAS_BLOBS;
161
+ if (additionalAuditRefs && additionalAuditRefs.length > 0) metadata |= HAS_ADDITIONAL_AUDIT_REFS;
162
+ if (metadata >= 0) {
163
+ dataView.setUint32(position, metadata | (ACTION_32_BIT << 24)); // use the extended action byte
164
+ position += 4;
165
+ if (expiresAt >= 0) {
166
+ dataView.setFloat64(position, expiresAt);
167
+ position += 8;
168
+ }
169
+ if (residencyId) {
170
+ dataView.setUint32(position, residencyId);
171
+ position += 4;
172
+ }
173
+ if (nodeId >= 0) {
174
+ dataView.setUint32(position, nodeId);
175
+ position += 4;
176
+ }
177
+ if (additionalAuditRefs && additionalAuditRefs.length > 0) {
178
+ encoded[position++] = additionalAuditRefs.length;
179
+ for (const ref of additionalAuditRefs) {
180
+ dataView.setFloat64(position, ref.version);
181
+ position += 8;
182
+ dataView.setUint32(position, ref.nodeId);
183
+ position += 4;
184
+ }
185
+ }
186
+ }
187
+ return encoded;
188
+ } else {
189
+ lastValueEncoding = superEncode.call(this, record, options);
190
+ return lastValueEncoding;
191
+ }
192
+ };
193
+ const superSaveStructures = this.saveStructures;
194
+ const superGetStructures = this.getStructures;
195
+ this.saveStructures = function (structures, isCompatible): boolean | undefined {
196
+ if (this.isRocksDB) {
197
+ return this.rootStore.transactionSync((txn) => {
198
+ const sharedStructuresKey = [Symbol.for('structures'), this.name];
199
+ const existingStructuresBuffer = txn.getBinarySync(sharedStructuresKey);
200
+ const existingStructures = existingStructuresBuffer ? this.decode(existingStructuresBuffer) : undefined;
201
+ if (typeof isCompatible == 'function') {
202
+ if (!isCompatible(existingStructures)) {
203
+ return false;
204
+ }
205
+ } else if (existingStructures && existingStructures.length !== isCompatible) {
206
+ return false;
207
+ }
208
+ txn.putSync(sharedStructuresKey, structures);
209
+ this.structureUpdate = structures;
210
+ });
211
+ } else {
212
+ const result = superSaveStructures.call(this, structures, isCompatible);
213
+ this.structureUpdate = structures;
214
+ return result;
215
+ }
216
+ };
217
+ this.getStructures = function (): any {
218
+ if (this.isRocksDB) {
219
+ const sharedStructuresKey = [Symbol.for('structures'), this.name];
220
+ const buffer = this.rootStore.getBinarySync(sharedStructuresKey);
221
+ return buffer ? this.decode(buffer) : undefined;
222
+ } else {
223
+ return superGetStructures.call(this);
224
+ }
225
+ };
226
+ }
227
+ decode(buffer, options) {
228
+ lastMetadata = null;
229
+ const start = options?.start || 0;
230
+ const end = options > -1 ? options : options?.end || buffer.length;
231
+ let nextByte = buffer[start];
232
+ let metadataFlags = 0;
233
+ try {
234
+ if ((this.isRocksDB && nextByte === 66) || (nextByte < 32 && end > 2)) {
235
+ // record with metadata
236
+ // this means that the record starts with a local timestamp (that was assigned by lmdb-js).
237
+ // we copy it so we can decode it as float-64; we need to do it first because if structural data
238
+ // is loaded during decoding the buffer can actually mutate
239
+ let position = start;
240
+ let localTime;
241
+ if (this.isRocksDB) {
242
+ buffer.copy(TIMESTAMP_HOLDER, 0, position);
243
+ position += 8;
244
+ localTime = TIMESTAMP_VIEW.getFloat64(0);
245
+ nextByte = buffer[position];
246
+ } else if (nextByte === 2) {
247
+ if (buffer.copy) {
248
+ buffer.copy(TIMESTAMP_HOLDER, 0, position);
249
+ position += 8;
250
+ } else {
251
+ for (let i = 0; i < 8; i++) TIMESTAMP_HOLDER[i] = buffer[position++];
252
+ }
253
+ localTime = getTimestamp();
254
+ nextByte = buffer[position];
255
+ }
256
+ let expiresAt, residencyId, nodeId, additionalAuditRefs;
257
+ if (nextByte < 32) {
258
+ if (nextByte === ACTION_32_BIT) {
259
+ const dataView =
260
+ buffer.dataView || (buffer.dataView = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength));
261
+ metadataFlags = dataView.getUint32(position);
262
+ position += 4;
263
+ } else {
264
+ metadataFlags = nextByte | (buffer[position + 1] << 5);
265
+ position += 2;
266
+ }
267
+ if (metadataFlags & HAS_EXPIRATION) {
268
+ const dataView =
269
+ buffer.dataView || (buffer.dataView = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength));
270
+ expiresAt = dataView.getFloat64(position);
271
+ position += 8;
272
+ }
273
+ if (metadataFlags & HAS_RESIDENCY_ID) {
274
+ // we need to read the residency id
275
+ const dataView =
276
+ buffer.dataView || (buffer.dataView = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength));
277
+ residencyId = dataView.getUint32(position);
278
+ position += 4;
279
+ }
280
+ if (metadataFlags & HAS_NODE_ID) {
281
+ // we need to read the node id
282
+ const dataView =
283
+ buffer.dataView || (buffer.dataView = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength));
284
+ nodeId = dataView.getUint32(position);
285
+ position += 4;
286
+ }
287
+ if (metadataFlags & HAS_ADDITIONAL_AUDIT_REFS) {
288
+ // we need to read the additional audit refs
289
+ const dataView =
290
+ buffer.dataView || (buffer.dataView = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength));
291
+ const count = buffer[position++];
292
+ additionalAuditRefs = [];
293
+ for (let i = 0; i < count; i++) {
294
+ const version = dataView.getFloat64(position);
295
+ position += 8;
296
+ const refNodeId = dataView.getUint32(position);
297
+ position += 4;
298
+ additionalAuditRefs.push({ version, nodeId: refNodeId });
299
+ }
300
+ }
301
+ }
302
+
303
+ const value = decodeFromDatabase(
304
+ () =>
305
+ options?.valueAsBuffer
306
+ ? buffer.subarray(position, end)
307
+ : super.decode(buffer.subarray(position, end), end - position),
308
+ this.rootStore
309
+ );
310
+ lastMetadata = {
311
+ localTime,
312
+ version: localTime,
313
+ [METADATA]: metadataFlags,
314
+ expiresAt,
315
+ residencyId,
316
+ nodeId,
317
+ additionalAuditRefs,
318
+ size: end - start,
319
+ value,
320
+ };
321
+ if (this.isRocksDB) return lastMetadata;
322
+ return value;
323
+ } // else a normal entry
324
+ return options?.valueAsBuffer ? buffer : decodeFromDatabase(() => super.decode(buffer, options), this.rootStore);
325
+ } catch (error) {
326
+ harperLogger.error('Error decoding record', error, 'data: ' + buffer.slice(0, 40).toString('hex'));
327
+ return null;
328
+ }
329
+ }
330
+ }
331
+ function getTimestamp() {
332
+ TIMESTAMP_HOLDER[0] = TIMESTAMP_HOLDER[0] ^ 0x40; // restore the first byte, we xor to differentiate the first byte from structures
333
+ return TIMESTAMP_VIEW.getFloat64(0);
334
+ }
335
+
336
+ export function handleLocalTimeForGets(store, rootStore) {
337
+ const isRocksDB = store instanceof RocksDatabase;
338
+ store.readCount = 0;
339
+ store.cachePuts = false;
340
+ store.rootStore = rootStore;
341
+ store.encoder.rootStore = rootStore;
342
+ store.encoder.isRocksDB = isRocksDB;
343
+ store.decoder = store.encoder;
344
+ const storeGetEntry = store.getEntry;
345
+ const storeGetSync = store.getSync;
346
+ const storeGet = store.get;
347
+
348
+ store.getEntry = function (id, options) {
349
+ store.readCount++;
350
+ lastMetadata = null;
351
+ if (isRocksDB) {
352
+ return when(
353
+ options?.async ? storeGet.call(store, id, options) : storeGetSync.call(store, id, options),
354
+ (entry) => {
355
+ if (entry) {
356
+ if (entry[METADATA]) {
357
+ entry.metadataFlags = entry[METADATA];
358
+ return withEntry(entry);
359
+ } else return { value: entry };
360
+ } else return entry;
361
+ }
362
+ );
363
+ } else {
364
+ let entry: Entry = storeGetEntry.call(this, id, options);
365
+ if (lastMetadata) {
366
+ entry.metadataFlags = lastMetadata[METADATA];
367
+ entry.localTime = lastMetadata.localTime;
368
+ entry.residencyId = lastMetadata.residencyId;
369
+ entry.nodeId = lastMetadata.nodeId;
370
+ entry.additionalAuditRefs = lastMetadata.additionalAuditRefs;
371
+ entry.size = lastMetadata.size;
372
+ if (lastMetadata.expiresAt >= 0) {
373
+ entry.expiresAt = lastMetadata.expiresAt;
374
+ }
375
+ if (isRocksDB) entry.version = lastMetadata.localTime;
376
+ if (entry.value) {
377
+ entryMap.set(entry.value, entry); // allow the record to access the entry
378
+ }
379
+ entry.key = id;
380
+ }
381
+ return entry && withEntry(entry);
382
+ }
383
+ // if we have decoded with metadata, we want to pull it out and assign to this entry
384
+ function withEntry(entry) {
385
+ if (entry.value) {
386
+ if (entry.value.constructor === Object) {
387
+ // if an object was deserialized as a plain object, give it the right prototype for computed properties to be accessible
388
+ const originalValue = entry.value;
389
+ entry.value = new this.encoder.structPrototype.constructor();
390
+ Object.assign(entry.value, originalValue);
391
+ }
392
+ entryMap.set(entry.value, entry); // allow the record to access the entry
393
+ }
394
+ entry.key = id;
395
+ return entry;
396
+ }
397
+ };
398
+
399
+ store.getSync = function (id, options) {
400
+ const entry = store.getEntry(id, options);
401
+ const value = entry?.value;
402
+ if (value) {
403
+ entryMap.set(value, entry);
404
+ }
405
+ return value;
406
+ };
407
+ store.get = function (id, options) {
408
+ return when(store.getEntry(id, { ...options, async: true }), (entry) => {
409
+ const value = entry?.value;
410
+ if (value) {
411
+ entryMap.set(value, entry);
412
+ }
413
+ return value;
414
+ });
415
+ };
416
+
417
+ //store.pendingTimestampUpdates = new Map();
418
+ const storeGetRange = store.getRange;
419
+ store.getRange = function (options) {
420
+ const iterable = storeGetRange.call(this, options);
421
+ if (options.valuesForKey) {
422
+ return iterable.map((value) => value?.value);
423
+ }
424
+ if (options.values === false || options.onlyCount) return iterable;
425
+ return iterable.map((entry) => {
426
+ // if we have metadata, move the metadata to the entry
427
+ if (isRocksDB) {
428
+ if (entry.value?.[METADATA]) {
429
+ entry.metadataFlags = entry.value[METADATA];
430
+ Object.assign(entry, entry.value);
431
+ }
432
+ } else if (lastMetadata) {
433
+ entry.metadataFlags = lastMetadata[METADATA];
434
+ entry.localTime = lastMetadata.localTime;
435
+ if (isRocksDB) entry.version = lastMetadata.localTime;
436
+ entry.residencyId = lastMetadata.residencyId;
437
+ entry.nodeId = lastMetadata.nodeId;
438
+ entry.additionalAuditRefs = lastMetadata.additionalAuditRefs;
439
+ entry.size = lastMetadata.size;
440
+ if (lastMetadata.expiresAt >= 0) entry.expiresAt = lastMetadata.expiresAt;
441
+ lastMetadata = null;
442
+ }
443
+ if (entry.value) {
444
+ if (entry.value.constructor === Object) {
445
+ // if an object was deserialized as a plain object, give it the right prototype for computed properties to be accessible
446
+ const originalValue = entry.value;
447
+ entry.value = new this.encoder.structPrototype.constructor();
448
+ for (const key in originalValue) entry.value[key] = originalValue[key];
449
+ }
450
+ }
451
+ return entry;
452
+ });
453
+ };
454
+
455
+ if (!isRocksDB) {
456
+ // add read transaction tracking
457
+ const txn = store.useReadTransaction();
458
+ txn.done();
459
+ if (!txn.done.isTracked) {
460
+ const Txn = txn.constructor;
461
+ const use = txn.use;
462
+ const done = txn.done;
463
+ Txn.prototype.use = function () {
464
+ if (!this.timerTracked) {
465
+ this.timerTracked = true;
466
+ trackedTxns.push(new WeakRef(this));
467
+ }
468
+ use.call(this);
469
+ };
470
+ Txn.prototype.done = function () {
471
+ done.call(this);
472
+ if (this.isDone) {
473
+ for (let i = 0; i < trackedTxns.length; i++) {
474
+ const txn = trackedTxns[i].deref();
475
+ if (!txn || txn.isDone || txn.isCommitted) {
476
+ trackedTxns.splice(i--, 1);
477
+ }
478
+ }
479
+ }
480
+ };
481
+ Txn.prototype.done.isTracked = true;
482
+ }
483
+ }
484
+
485
+ return store;
486
+ }
487
+ const trackedTxns: WeakRef<any>[] = [];
488
+ setInterval(() => {
489
+ for (let i = 0; i < trackedTxns.length; i++) {
490
+ const txn = trackedTxns[i].deref();
491
+ if (!txn || txn.isDone || txn.isCommitted) trackedTxns.splice(i--, 1);
492
+ else if (txn.notCurrent) {
493
+ if (txn.openTimer) {
494
+ if (txn.openTimer > 3) {
495
+ if (txn.openTimer > 60) {
496
+ harperLogger.error(
497
+ 'Read transaction detected that has been open too long (over 15 minutes), ending transaction',
498
+ txn
499
+ );
500
+ txn.done();
501
+ } else
502
+ harperLogger.error(
503
+ 'Read transaction detected that has been open too long (over one minute), make sure read transactions are quickly closed',
504
+ txn
505
+ );
506
+ }
507
+ txn.openTimer++;
508
+ } else txn.openTimer = 1;
509
+ }
510
+ }
511
+ }, 15000).unref();
512
+ export function recordUpdater(store, tableId, auditStore) {
513
+ return function (
514
+ id,
515
+ record,
516
+ existingEntry,
517
+ newVersion,
518
+ assignMetadata = -1, // when positive, this has a set of metadata flags for the record
519
+ audit?: boolean, // true -> audit this record. false -> do not. null -> retain any audit timestamp
520
+ options?,
521
+ type = 'put',
522
+ resolveRecord?: boolean, // indicates that we are resolving (from source) record that was previously invalidated
523
+ auditRecord?: any
524
+ ) {
525
+ const isRocksDB = store instanceof RocksDatabase;
526
+ // determine if and how we apply the local timestamp
527
+ if (isRocksDB) {
528
+ // with rocksdb, we simplify to just storing the singular version/timestamp
529
+ timestampNextEncoding = newVersion;
530
+ } else if (audit == null)
531
+ // if not auditing, there is no local timestamp to reference
532
+ timestampNextEncoding = NO_TIMESTAMP;
533
+ else if (resolveRecord)
534
+ // preserve existing timestamp, if possible
535
+ timestampNextEncoding = existingEntry?.localTime
536
+ ? TIMESTAMP_RECORD_PREVIOUS | TIMESTAMP_ASSIGN_PREVIOUS
537
+ : NO_TIMESTAMP;
538
+ else
539
+ timestampNextEncoding = audit // for audit, we need it
540
+ ? existingEntry?.localTime // we already have a timestamp, we need to record the previous one in the audit log
541
+ ? TIMESTAMP_RECORD_PREVIOUS | 0x4000
542
+ : TIMESTAMP_ASSIGN_NEW | 0x4000 // or just assign a new one
543
+ : NO_TIMESTAMP;
544
+ const expiresAt = options?.expiresAt;
545
+ if (expiresAt >= 0) assignMetadata |= HAS_EXPIRATION;
546
+ metadataInNextEncoding = assignMetadata;
547
+ expiresAtNextEncoding = expiresAt;
548
+ const putOptions: {
549
+ version: number;
550
+ instructedWrite?: boolean;
551
+ ifVersion?: number;
552
+ } = {
553
+ version: newVersion,
554
+ instructedWrite: timestampNextEncoding > 0,
555
+ transaction: options?.transaction,
556
+ };
557
+ let ifVersion;
558
+ let extendedType = 0;
559
+ try {
560
+ let previousResidencyId = existingEntry?.residencyId;
561
+ const residencyId = options?.residencyId; //getResidency(record, previousResidencyId);
562
+ if (residencyId) {
563
+ residencyIdAtNextEncoding = residencyId;
564
+ metadataInNextEncoding |= HAS_RESIDENCY_ID;
565
+ extendedType |= HAS_CURRENT_RESIDENCY_ID;
566
+ } else residencyIdAtNextEncoding = 0;
567
+ const nodeId = options?.nodeId;
568
+ if (nodeId >= 0) {
569
+ nodeIdAtNextEncoding = nodeId;
570
+ metadataInNextEncoding |= HAS_NODE_ID;
571
+ } else nodeIdAtNextEncoding = -1;
572
+ const additionalAuditRefs = options?.additionalAuditRefs;
573
+ if (additionalAuditRefs && additionalAuditRefs.length > 0) {
574
+ additionalAuditRefsNextEncoding = additionalAuditRefs;
575
+ metadataInNextEncoding |= HAS_ADDITIONAL_AUDIT_REFS;
576
+ } else additionalAuditRefsNextEncoding = undefined;
577
+ const previousAdditionalAuditRefs = existingEntry?.additionalAuditRefs;
578
+ if (previousAdditionalAuditRefs && previousAdditionalAuditRefs.length > 0) {
579
+ extendedType |= HAS_ADDITIONAL_AUDIT_REFS_AUDIT;
580
+ }
581
+ if (previousResidencyId !== residencyId) {
582
+ extendedType |= HAS_PREVIOUS_RESIDENCY_ID;
583
+ if (!previousResidencyId) previousResidencyId = 0;
584
+ }
585
+ if (assignMetadata & HAS_EXPIRATION) extendedType |= HAS_EXPIRATION_EXTENDED_TYPE; // we need to record the expiration in the audit log
586
+ if (options?.originatingOperation) extendedType |= HAS_ORIGINATING_OPERATION;
587
+ // we use resolveRecord outside of transaction, so must explicitly make it conditional
588
+ if (resolveRecord) putOptions.ifVersion = ifVersion = existingEntry?.version ?? null;
589
+ if (existingEntry && existingEntry.value && type !== 'message' && existingEntry.metadataFlags & HAS_BLOBS) {
590
+ // delete the old blobs
591
+ deleteBlobsInObject(existingEntry.value);
592
+ }
593
+ let result: Promise<void>;
594
+ if (record !== undefined) {
595
+ result = encodeBlobsWithFilePath(
596
+ () => (isRocksDB ? store.putSync(id, record, putOptions) : store.put(id, record, putOptions)),
597
+ id,
598
+ store.rootStore
599
+ );
600
+ if (blobsWereEncoded) {
601
+ extendedType |= HAS_BLOBS;
602
+ }
603
+ }
604
+ if (audit) {
605
+ const username = typeof options?.user === 'string' ? options.user : options?.user?.username;
606
+ if (auditRecord) {
607
+ encodeBlobsWithFilePath(() => store.encoder.encode(auditRecord), id, store.rootStore);
608
+ if (blobsWereEncoded) {
609
+ extendedType |= HAS_BLOBS;
610
+ }
611
+ }
612
+ if (store.encoder?.structureUpdate) {
613
+ extendedType |= HAS_STRUCTURE_UPDATE;
614
+ store.encoder.structureUpdate = null;
615
+ }
616
+ const structureVersion = store.encoder.structures.length + (store.encoder.typedStructs?.length ?? 0);
617
+ const nodeId = options?.nodeId ?? server.replication?.getThisNodeId(auditStore) ?? 0;
618
+ const viaNodeId = options?.viaNodeId ?? nodeId;
619
+ if (resolveRecord && existingEntry?.localTime) {
620
+ const replacingId = existingEntry?.localTime;
621
+ const replacingEntry = auditStore.get(replacingId, tableId, id);
622
+ if (replacingEntry) {
623
+ const previousVersion = replacingEntry.previousVersion;
624
+ result = auditStore[isRocksDB ? 'putSync' : 'put'](
625
+ replacingId,
626
+ {
627
+ version: newVersion,
628
+ tableId,
629
+ recordId: id,
630
+ previousVersion,
631
+ nodeId,
632
+ user: username,
633
+ type,
634
+ encodedRecord: lastValueEncoding,
635
+ extendedType,
636
+ residencyId,
637
+ previousResidencyId,
638
+ expiresAt,
639
+ structureVersion,
640
+ previousAdditionalAuditRefs,
641
+ },
642
+ { ifVersion: ifVersion, transaction: options.transaction, nodeId, viaNodeId }
643
+ );
644
+ return result;
645
+ }
646
+ }
647
+ result = auditStore[isRocksDB ? 'putSync' : 'put'](
648
+ record === undefined ? NEW_TIMESTAMP_PLACEHOLDER : LAST_TIMESTAMP_PLACEHOLDER,
649
+ {
650
+ version: newVersion,
651
+ tableId,
652
+ recordId: id,
653
+ previousVersion: store instanceof RocksDatabase ? existingEntry?.version : existingEntry?.localTime ? 1 : 0,
654
+ nodeId,
655
+ user: username,
656
+ type,
657
+ encodedRecord: lastValueEncoding,
658
+ extendedType,
659
+ residencyId,
660
+ previousResidencyId,
661
+ expiresAt,
662
+ structureVersion,
663
+ originatingOperation: options?.originatingOperation,
664
+ previousAdditionalAuditRefs,
665
+ },
666
+ {
667
+ // turn off append flag, as we are concerned this may be related to db corruption issues
668
+ // append: type !== 'invalidate', // for invalidation, we expect the record to be rewritten, so we don't want to necessarily expect pure sequential writes that create full pages
669
+ instructedWrite: true,
670
+ ifVersion,
671
+ transaction: options.transaction,
672
+ nodeId,
673
+ viaNodeId,
674
+ }
675
+ );
676
+ }
677
+ if (options?.tableToTrack && TRACKED_WRITE_TYPES.has(type)) {
678
+ recordAction(lastValueEncoding?.length ?? 1, 'db-write', options.tableToTrack, null);
679
+ }
680
+
681
+ return result;
682
+ } catch (error) {
683
+ error.message += ' id: ' + id + ' options: ' + putOptions;
684
+ throw error;
685
+ }
686
+ };
687
+ }
688
+ export function setAdditionalAuditRefs(refs: Array<{ version: number; nodeId: number }> | undefined) {
689
+ additionalAuditRefsNextEncoding = refs;
690
+ }
691
+ export function removeEntry(store: any, entry: any, existingVersion?: number) {
692
+ if (!entry) return;
693
+ if (entry.value && entry.metadataFlags & HAS_BLOBS) {
694
+ // if it used to have blobs, we need to delete the old blobs
695
+ deleteBlobsInObject(entry.value);
696
+ }
697
+ return store.remove(entry.key, existingVersion);
698
+ }
699
+ export interface RecordObject {
700
+ getUpdatedTime(): number;
701
+ getExpiresAt(): number;
702
+ }