@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,86 @@
1
+ import { Scope } from '../components/Scope.ts';
2
+ import { dirname } from 'path';
3
+
4
+ function isResource(value: any) {
5
+ return (
6
+ value &&
7
+ (typeof value.get === 'function' ||
8
+ typeof value.put === 'function' ||
9
+ typeof value.post === 'function' ||
10
+ typeof value.delete === 'function')
11
+ );
12
+ }
13
+
14
+ /**
15
+ * Error thrown when a JavaScript resource module fails to load
16
+ */
17
+ export class ResourceLoadError extends Error {
18
+ public readonly filePath: string;
19
+ public readonly cause?: Error;
20
+
21
+ constructor(filePath: string, cause?: Error) {
22
+ super(`Failed to load resource module ${filePath}${cause ? `: ${cause.message}` : ''}`);
23
+ this.name = 'ResourceLoadError';
24
+ this.filePath = filePath;
25
+ this.cause = cause;
26
+ }
27
+ }
28
+
29
+ /**
30
+ * This plugin loads JavaScript files and registers their exports as resources.
31
+ *
32
+ * The export can be the default export and will be assigned to the root URL path.
33
+ *
34
+ * Otherwise, the name of the export will be used.
35
+ *
36
+ * After loading the JavaScript code using the secure import, it adds it to the global `resources` map.
37
+ *
38
+ * Once a file has been loaded it cannot be unloaded without a restart.
39
+ *
40
+ * Thus, this plugin only handle files as they are added (`add` event). All other events result in a restart request.
41
+ *
42
+ */
43
+ export async function handleApplication(scope: Scope) {
44
+ scope.handleEntry(async function handleResourceEntry(entryEvent) {
45
+ if (entryEvent.entryType !== 'file') {
46
+ scope.logger.warn(
47
+ `jsResource plugin cannot handle entry type ${entryEvent.entryType}. Modify the 'files' option in ${scope.configFilePath} to only include files.`
48
+ );
49
+ return;
50
+ }
51
+
52
+ if (entryEvent.eventType !== 'add') {
53
+ scope.requestRestart();
54
+ return;
55
+ }
56
+
57
+ try {
58
+ const resourceModule: any = await scope.import(entryEvent.absolutePath);
59
+ const root = dirname(entryEvent.urlPath).replace(/\\/g, '/').replace(/^\/$/, '');
60
+ if (isResource(resourceModule.default)) {
61
+ // register the resource
62
+ scope.resources.set(root, resourceModule.default);
63
+ scope.logger.debug?.(`Registered root resource: ${root}`);
64
+ }
65
+ recurseForResources(scope, resourceModule, root);
66
+ } catch (error) {
67
+ // Rethrow with more context
68
+ throw new ResourceLoadError(entryEvent.absolutePath, error);
69
+ }
70
+ });
71
+ }
72
+
73
+ function recurseForResources(scope: Scope, resourceModule: any, prefix: string) {
74
+ for (const name in resourceModule) {
75
+ // check each of the module exports to see if it implements a Resource handler
76
+ const exported = resourceModule[name];
77
+ const resourcePath = `${prefix}/${name}`;
78
+ if (isResource(exported)) {
79
+ // expose as an endpoint
80
+ scope.resources.set(resourcePath, exported);
81
+ scope.logger.debug?.(`Registered resource: ${resourcePath}`);
82
+ } else if (typeof exported === 'object') {
83
+ recurseForResources(scope, exported, resourcePath);
84
+ }
85
+ }
86
+ }
@@ -0,0 +1,22 @@
1
+ import { parse } from 'dotenv';
2
+ import logger from '../utility/logging/harper_logger.js';
3
+
4
+ export function start({ override }: { override: boolean }) {
5
+ return {
6
+ handleFile: (contents, _, filePath) => {
7
+ logger.debug(`Loading env file: ${filePath}`);
8
+ for (const [key, value] of Object.entries(parse(contents))) {
9
+ if (process.env[key] !== undefined) {
10
+ logger.warn(`Environment variable conflict: ${key} from ${filePath} is already set on process.env`);
11
+ if (override) {
12
+ logger.debug(`override option enabled. overriding environment variable: ${key}`);
13
+ } else {
14
+ continue;
15
+ }
16
+ }
17
+
18
+ process.env[key] = value;
19
+ }
20
+ },
21
+ };
22
+ }
@@ -0,0 +1,18 @@
1
+ import { Resource } from './Resource.ts';
2
+ export function start({ resources }) {
3
+ resources.set('login', Login);
4
+ resources.loginPath = (request) => {
5
+ return '/login?redirect=' + encodeURIComponent(request.url);
6
+ };
7
+ }
8
+ class Login extends Resource {
9
+ static async get(_id, _body, _request) {
10
+ // TODO: Return a login page
11
+ }
12
+ static async post(_id, body, request) {
13
+ const { username, password } = body;
14
+ return {
15
+ data: await request.login(username, password),
16
+ };
17
+ }
18
+ }
@@ -0,0 +1,409 @@
1
+ import { packageJson } from '../utility/packageUtils.js';
2
+ import { Resources } from './Resources.ts';
3
+ import { Resource } from './Resource.ts';
4
+
5
+ const OPENAPI_VERSION = '3.0.3';
6
+ // Maps graphql primitive types to open api types
7
+ const DATA_TYPES = {
8
+ Int: 'integer',
9
+ Float: 'number',
10
+ Long: 'integer',
11
+ ID: 'string',
12
+ String: 'string',
13
+ Boolean: 'boolean',
14
+ Date: 'string',
15
+ Bytes: 'string',
16
+ BigInt: 'integer',
17
+ };
18
+
19
+ const SCHEMA_COMP_REF = '#/components/schemas/';
20
+ const DESCRIPTION_200 = 'successful operation';
21
+
22
+ export function generateJsonApi(resources: Resources, serverHttpURL: string) {
23
+ const api = {
24
+ openapi: OPENAPI_VERSION,
25
+ info: {
26
+ title: 'Harper HTTP REST interface',
27
+ version: packageJson.version,
28
+ },
29
+ servers: [
30
+ {
31
+ description: 'REST API',
32
+ url: serverHttpURL,
33
+ },
34
+ ],
35
+ paths: {},
36
+ components: {
37
+ schemas: {},
38
+ securitySchemes: {
39
+ basicAuth: {
40
+ type: 'http',
41
+ scheme: 'basic',
42
+ },
43
+ bearerAuth: {
44
+ type: 'http',
45
+ scheme: 'bearer',
46
+ bearerFormat: 'JWT',
47
+ },
48
+ },
49
+ },
50
+ };
51
+
52
+ const security = [
53
+ {
54
+ basicAuth: [],
55
+ bearerAuth: [],
56
+ },
57
+ ];
58
+
59
+ const includeDefinitionInSchema = (def) => {
60
+ if (def.type && !api.components.schemas[def.type]) {
61
+ // Immediately define the type so we don't get caught in infinite recursions, until...
62
+ api.components.schemas[def.type] = {};
63
+ const defProps: Record<string, unknown> = {};
64
+ const defRequired: string[] = [];
65
+ for (const prop of def.properties) {
66
+ if (DATA_TYPES[prop.type]) {
67
+ defProps[prop.name] = new Type(DATA_TYPES[prop.type], prop.type);
68
+ } else if (prop.properties) {
69
+ defProps[prop.name] = new Ref(prop.type);
70
+ includeDefinitionInSchema(prop);
71
+ } else if (prop.elements?.properties) {
72
+ defProps[prop.name] = new ArrayRef(prop.elements.type);
73
+ includeDefinitionInSchema(prop.elements);
74
+ }
75
+ if (prop.nullable === false) {
76
+ defRequired.push(prop.name);
77
+ }
78
+ }
79
+ // ... down here we actually define the value for the new type.
80
+ api.components.schemas[def.type] = new ResourceSchema(defProps, !def.sealed, defRequired);
81
+ }
82
+ };
83
+
84
+ for (const [, resource] of resources) {
85
+ // skip invalid and error resources
86
+ if (!resource.path || resource.Resource.isError) continue;
87
+
88
+ const { path } = resource;
89
+ const strippedPath = path.split('/').pop(); // strip any namespace from path
90
+ let { attributes, sealed } = resource.Resource;
91
+ const { prototype, primaryKey = 'id' } = resource.Resource;
92
+ if (!attributes && resources.allTypes.has(resource.path)) {
93
+ const possibleType = resources.allTypes.get(resource.path);
94
+ sealed = possibleType.sealed;
95
+ attributes = possibleType.properties;
96
+ }
97
+ if (!primaryKey) continue;
98
+ const props = {};
99
+ const queryParamsArray = [];
100
+ const resourceRequired: string[] = [];
101
+
102
+ if (attributes) {
103
+ for (const { type, name, elements, relationship, definition, nullable } of attributes) {
104
+ const def = definition ?? elements?.definition;
105
+ if (def) {
106
+ includeDefinitionInSchema(def);
107
+ }
108
+
109
+ if (nullable === false) {
110
+ resourceRequired.push(name);
111
+ }
112
+ if (relationship) {
113
+ if (type === 'array') {
114
+ props[name] = { type: 'array', items: { $ref: SCHEMA_COMP_REF + elements.type } };
115
+ } else {
116
+ props[name] = { $ref: SCHEMA_COMP_REF + type };
117
+ }
118
+ } else {
119
+ if (def) {
120
+ if (type === 'array') {
121
+ props[name] = { type: 'array', items: { $ref: SCHEMA_COMP_REF + def.type } };
122
+ } else {
123
+ props[name] = { $ref: SCHEMA_COMP_REF + def.type };
124
+ }
125
+ } else if (type === 'array') {
126
+ if (elements.type === 'Any') {
127
+ props[name] = { type: 'array', items: { format: elements.type } };
128
+ } else {
129
+ props[name] = { type: 'array', items: new Type(DATA_TYPES[elements.type], elements.type) };
130
+ }
131
+ } else if (type === 'Any') {
132
+ props[name] = { format: type };
133
+ } else {
134
+ props[name] = new Type(DATA_TYPES[type], type);
135
+ }
136
+ }
137
+ queryParamsArray.push(new Parameter(name, 'query', props[name]));
138
+ }
139
+ }
140
+
141
+ const propsArray = Object.keys(props);
142
+ const primaryKeyParam = new Parameter(primaryKey, 'path', { type: 'string', format: 'ID' });
143
+ primaryKeyParam.required = true;
144
+ primaryKeyParam.description = 'primary key of record';
145
+ const propertyParamPath = new Parameter('property', 'path', { enum: propsArray });
146
+ propertyParamPath.required = true;
147
+ api.components.schemas[strippedPath] = new ResourceSchema(props, !sealed, resourceRequired);
148
+
149
+ const hasPost = prototype.post !== Resource.prototype.post || prototype.update;
150
+ const hasPut = typeof prototype.put === 'function';
151
+ const hasGet = typeof prototype.get === 'function';
152
+ const hasDelete = typeof prototype.delete === 'function';
153
+ const hasPatch = typeof prototype.patch === 'function';
154
+
155
+ const url = `/${path}/`;
156
+ if (!api.paths[url]) {
157
+ api.paths[url] = {};
158
+ }
159
+
160
+ // API for path structure /my-resource/
161
+ if (hasPost) {
162
+ api.paths[url].post = new Post(
163
+ strippedPath,
164
+ security,
165
+ {
166
+ '200': new Response200(
167
+ { $ref: SCHEMA_COMP_REF + strippedPath },
168
+ {
169
+ Location: {
170
+ description: 'primary key of new record',
171
+ schema: {
172
+ type: 'string',
173
+ format: 'ID',
174
+ },
175
+ },
176
+ }
177
+ ),
178
+ },
179
+ 'create a new record auto-assigning a primary key'
180
+ );
181
+ }
182
+
183
+ api.paths[url].options = new Options(
184
+ queryParamsArray,
185
+ security,
186
+ { '200': new ResponseOptions200() },
187
+ 'retrieve information about the communication options available for a target resource or the server as a whole, without performing any resource action'
188
+ );
189
+
190
+ if (hasGet) {
191
+ api.paths[url].get = new Get(
192
+ queryParamsArray,
193
+ security,
194
+ { '200': new Response200({ type: 'array', items: { $ref: SCHEMA_COMP_REF + strippedPath } }) },
195
+ 'search for records by the specified property name and value pairs'
196
+ );
197
+ }
198
+
199
+ if (hasDelete) {
200
+ api.paths[url].delete = new Delete(
201
+ queryParamsArray,
202
+ security,
203
+ 'delete all the records that match the provided query',
204
+ {
205
+ '204': new Response204(),
206
+ }
207
+ );
208
+ }
209
+
210
+ // API for path structure /my-resource/<record-id>
211
+ const urlById = '/' + path + '/{' + primaryKey + '}';
212
+ if (!api.paths[urlById]) {
213
+ api.paths[urlById] = {};
214
+ }
215
+
216
+ api.paths[urlById].options = new Options(
217
+ queryParamsArray,
218
+ security,
219
+ { '200': new ResponseOptions200() },
220
+ 'retrieve information about the communication options available for a target resource or the server as a whole, without performing any resource action'
221
+ );
222
+
223
+ if (hasGet) {
224
+ api.paths[urlById].get = new Get(
225
+ [primaryKeyParam],
226
+ security,
227
+ { '200': new Response200({ $ref: SCHEMA_COMP_REF + strippedPath }) },
228
+ 'retrieve a record by its primary key'
229
+ );
230
+ }
231
+
232
+ if (hasPut) {
233
+ api.paths[urlById].put = new Put(
234
+ [primaryKeyParam],
235
+ security,
236
+ strippedPath,
237
+ { '200': new Response200({ $ref: SCHEMA_COMP_REF + strippedPath }) },
238
+ "create or update the record with the URL path that maps to the record's primary key"
239
+ );
240
+ }
241
+
242
+ if (hasPatch) {
243
+ api.paths[urlById].patch = new Patch(
244
+ [primaryKeyParam],
245
+ security,
246
+ strippedPath,
247
+ { '200': new Response200({ $ref: SCHEMA_COMP_REF + strippedPath }) },
248
+ "patch the record with the URL path that maps to the record's primary key"
249
+ );
250
+ }
251
+
252
+ if (hasDelete) {
253
+ api.paths[urlById].delete = new Delete(
254
+ [primaryKeyParam],
255
+ security,
256
+ 'delete a record with the given primary key',
257
+ {
258
+ '204': new Response204(),
259
+ }
260
+ );
261
+ }
262
+
263
+ // API for path structure /my-resource/<record-id>.property
264
+ if (hasGet && propertyParamPath.schema.enum.length > 0) {
265
+ const urlByProperty = `/${path}/{${primaryKey}}.{property}`;
266
+ if (!api.paths[urlByProperty]) {
267
+ api.paths[urlByProperty] = {};
268
+ }
269
+ api.paths[urlByProperty].get = new Get(
270
+ [primaryKeyParam, propertyParamPath],
271
+ security,
272
+ {
273
+ '200': new Response200({ enum: propsArray }),
274
+ },
275
+
276
+ 'used to retrieve the specified property of the specified record'
277
+ );
278
+ }
279
+ }
280
+
281
+ for (const [, value] of resources.allTypes) {
282
+ includeDefinitionInSchema(value);
283
+ if (value.sealed && api.components.schemas[value.type].additionalProperties) {
284
+ api.components.schemas[value.type].additionalProperties = false;
285
+ }
286
+ }
287
+
288
+ return api;
289
+ }
290
+
291
+ function Post(path, security, responses, description) {
292
+ this.description = description;
293
+ this.requestBody = {
294
+ content: {
295
+ 'application/json': {
296
+ schema: {
297
+ $ref: SCHEMA_COMP_REF + path,
298
+ },
299
+ },
300
+ },
301
+ };
302
+
303
+ this.security = security;
304
+ this.responses = responses;
305
+ }
306
+
307
+ function Get(parameters, security, responses, description) {
308
+ this.description = description;
309
+ this.parameters = parameters;
310
+ this.security = security;
311
+ this.responses = responses;
312
+ }
313
+
314
+ function Options(parameters, security, responses, description) {
315
+ this.description = description;
316
+ this.parameters = parameters;
317
+ this.security = security;
318
+ this.responses = responses;
319
+ }
320
+
321
+ function ResponseOptions200() {
322
+ this.description = DESCRIPTION_200;
323
+ this.headers = {};
324
+ this.content = {};
325
+ }
326
+
327
+ function Response200(schema, headers?: any) {
328
+ this.description = DESCRIPTION_200;
329
+ this.content = {
330
+ 'application/json': {
331
+ schema,
332
+ },
333
+ };
334
+ this.headers = headers;
335
+ }
336
+
337
+ function Response204() {
338
+ this.description = 'successfully processed request, no content returned to client';
339
+ }
340
+
341
+ function Put(parameters, security, path, responses, description) {
342
+ this.description = description;
343
+ this.parameters = parameters;
344
+ this.security = security;
345
+ this.requestBody = {
346
+ content: {
347
+ 'application/json': {
348
+ schema: {
349
+ $ref: SCHEMA_COMP_REF + path,
350
+ },
351
+ },
352
+ },
353
+ };
354
+ this.responses = responses;
355
+ }
356
+
357
+ function Patch(parameters, security, path, responses, description) {
358
+ this.description = description;
359
+ this.parameters = parameters;
360
+ this.security = security;
361
+ this.requestBody = {
362
+ content: {
363
+ 'application/json': {
364
+ schema: {
365
+ $ref: SCHEMA_COMP_REF + path,
366
+ },
367
+ },
368
+ },
369
+ };
370
+ this.responses = responses;
371
+ }
372
+
373
+ function Delete(parameters, security, description, responses) {
374
+ this.description = description;
375
+ this.parameters = parameters;
376
+ this.security = security;
377
+ this.responses = responses;
378
+ }
379
+
380
+ function ResourceSchema(properties, additionalProperties?: boolean, required?: string[]) {
381
+ this.type = 'object';
382
+ this.properties = properties;
383
+ this.additionalProperties = additionalProperties;
384
+ this.required = required;
385
+ }
386
+
387
+ function Type(type, format) {
388
+ this.type = type;
389
+ if (type === 'string' || type === 'number' || type === 'integer') {
390
+ if (format !== 'String') {
391
+ this.format = format;
392
+ }
393
+ }
394
+ }
395
+
396
+ function Ref(ref: string) {
397
+ this.$ref = `#/components/schemas/${ref}`;
398
+ }
399
+
400
+ function ArrayRef(ref: string) {
401
+ this.type = 'array';
402
+ this.items = new Ref(ref);
403
+ }
404
+
405
+ function Parameter(name, i, type) {
406
+ this.name = name;
407
+ this.in = i;
408
+ this.schema = type;
409
+ }
@@ -0,0 +1,8 @@
1
+ import { packageJson } from '../utility/packageUtils.js';
2
+
3
+ export function getRegistrationInfo() {
4
+ return {
5
+ version: packageJson.version,
6
+ deprecated: true,
7
+ };
8
+ }
@@ -0,0 +1,136 @@
1
+ import { RocksDatabase, Transaction as RocksTransaction } from '@harperfast/rocksdb-js';
2
+ import { Resource } from './Resource.ts';
3
+ import type { Context } from './ResourceInterface.ts';
4
+ import * as logger from '../utility/logging/harper_logger.js';
5
+ import { DatabaseTransaction } from './DatabaseTransaction.ts';
6
+ import { RocksTransactionLogStore } from './RocksTransactionLogStore.ts';
7
+ import { isMainThread } from 'node:worker_threads';
8
+ import { RequestTarget } from './RequestTarget.ts';
9
+
10
+ let warnedReplayHappening = false;
11
+ export function replayLogs(rootStore: RocksDatabase, tables: any): Promise<void> {
12
+ if (!isMainThread) return; // ideally we don't do it like this, but for now this is predictable
13
+ return new Promise((resolve) => {
14
+ const acquired = rootStore.tryLock('replayLogs', async () => {
15
+ resolve();
16
+ });
17
+ if (!acquired) return;
18
+ const tableById = new Map<number, typeof Resource>();
19
+ for (const tableName in tables) {
20
+ const table = tables[tableName];
21
+ tableById.set(table.tableId, table);
22
+ }
23
+ // replay all the logs
24
+ let transaction: DatabaseTransaction;
25
+ let lastTimestamp = 0;
26
+ let writes = 0;
27
+ const txnLog: RocksTransactionLogStore = rootStore.auditStore;
28
+ for (const auditRecord of txnLog.getRange({ startFromLastFlushed: true, readUncommitted: true })) {
29
+ const { type, tableId, nodeId, recordId, version, residencyId, expiresAt, originatingOperation, username } =
30
+ auditRecord;
31
+ try {
32
+ const Table = tableById.get(tableId);
33
+ if (!Table) continue;
34
+ const context: Context = { nodeId, alreadyLogged: true, version, expiresAt, user: { name: username } };
35
+ const { primaryStore } = Table;
36
+ const target = new RequestTarget();
37
+ target.id = null;
38
+ const tableInstance = Table.getResource(target, context, {});
39
+ // TODO: If this throws an error due to being unable to access structures, we need to iterate through
40
+ // other transaction logs to get the latest structure. Ultimately we may have to skip records
41
+ if (!warnedReplayHappening) {
42
+ warnedReplayHappening = true;
43
+ console.warn('Harper was not properly shutdown, replaying transaction logs to synchronize database');
44
+ }
45
+ const record = auditRecord.getValue(primaryStore);
46
+ if (lastTimestamp !== version) {
47
+ lastTimestamp = version;
48
+ try {
49
+ // commit the last transaction since we are starting a new one
50
+ transaction?.directCommitSync();
51
+ } catch (error) {
52
+ logger.error('Error committing replay transaction', error);
53
+ }
54
+ transaction = new DatabaseTransaction();
55
+ transaction.db = primaryStore;
56
+ transaction.timestamp = version;
57
+ // we treat this as a retry, because it is (and we want to skip validation and writing to the transaction log)
58
+ transaction.retries = 1;
59
+ }
60
+ context.transaction = transaction;
61
+ const options = { context, residencyId, nodeId, originatingOperation };
62
+ writes++;
63
+ switch (type) {
64
+ case 'put':
65
+ tableInstance._writeUpdate(recordId, record, true, options);
66
+ tableInstance.save(); // requires an explicit save
67
+ break;
68
+ case 'patch':
69
+ tableInstance._writeUpdate(recordId, record, false, options);
70
+ tableInstance.save(); // requires an explicit save
71
+ break;
72
+ case 'message':
73
+ tableInstance._writePublish(recordId, record, options);
74
+ break;
75
+ case 'relocate':
76
+ tableInstance._writeRelocate(recordId, options);
77
+ break;
78
+ case 'delete':
79
+ tableInstance._writeDelete(recordId, options);
80
+ break;
81
+ case 'invalidate':
82
+ tableInstance._writeInvalidate(recordId, record, options);
83
+ break;
84
+ case 'structures': {
85
+ const rocksTransaction = new RocksTransaction(primaryStore.store);
86
+ const structuresAsBinary = auditRecord.getBinaryValue(primaryStore);
87
+ const updatedStructures = structuresAsBinary ? primaryStore.decoder.decode(structuresAsBinary) : undefined;
88
+ const existingStructures = primaryStore.getSync(Symbol.for('structures'), {
89
+ transaction: rocksTransaction,
90
+ });
91
+ if (existingStructures) {
92
+ if (existingStructures instanceof Array) {
93
+ if (updatedStructures.length < existingStructures.length) {
94
+ logger.warn(
95
+ `Found ${existingStructures.length} structures in audit store, but ${updatedStructures.length} in replay log. Using ${updatedStructures.length} structures.`
96
+ );
97
+ }
98
+ } else {
99
+ if (existingStructures.get('named').length > updatedStructures.get('named').length) {
100
+ logger.warn(
101
+ `Found named ${existingStructures.length} structures in audit store, but ${updatedStructures.length} in replay log. Using named ${updatedStructures.length} structures.`
102
+ );
103
+ }
104
+ if (existingStructures.get('typed').length > updatedStructures.get('typed').length) {
105
+ logger.warn(
106
+ `Found named ${existingStructures.length} structures in audit store, but ${updatedStructures.length} in replay log. Using named ${updatedStructures.length} structures.`
107
+ );
108
+ }
109
+ }
110
+ }
111
+ primaryStore.putSync(Symbol.for('structures'), asBinary(structuresAsBinary), {
112
+ transaction: rocksTransaction,
113
+ });
114
+ rocksTransaction.commitSync();
115
+ primaryStore.decoder.structure = updatedStructures;
116
+ }
117
+ }
118
+ } catch (err) {
119
+ logger.error(`Error writing from replay of log`, err, {
120
+ version,
121
+ });
122
+ }
123
+ }
124
+ try {
125
+ transaction?.directCommitSync();
126
+ } catch (error) {
127
+ logger.error('Error committing replay transaction', error);
128
+ }
129
+ if (writes > 0) logger.warn(`Replayed ${writes} records in ${rootStore.databaseName} database`);
130
+ // we never actually release the lock because we only want to ever run one time
131
+ // rootStore.unlock('replayLogs');
132
+ });
133
+ }
134
+ function asBinary(buffer) {
135
+ return { ['\x10binary-data\x02']: buffer };
136
+ }