@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,584 @@
1
+ import { ClientError } from '../utility/errors/hdbError.js';
2
+ import * as crdtOperations from './crdt.ts';
3
+ import { Blob } from './blob.ts';
4
+
5
+ function getChanges(target) {
6
+ let changes = target.getChanges();
7
+ if (!changes) {
8
+ changes = Object.create(null);
9
+ target._setChanges(changes);
10
+ }
11
+ return changes;
12
+ }
13
+ /**
14
+ * A tracked class cacheable, (potentially) frozen read-only record, designed to facilitate record updates,
15
+ * and tracks property (and sub-object/array) changes so that on commit, any property changes can be written as part of
16
+ * the commit. This will also track specific updates so can record information in CRDTs.
17
+ */
18
+ /**
19
+ * assignObjectAccessors add methods to the prototype of the provided Target class to make
20
+ * it a tracked object.
21
+ * @param Target Class to add accessors to
22
+ * @param typeDef Type definition for determining property
23
+ */
24
+ export function assignTrackedAccessors(Target, typeDef, useFullPropertyProxy = false) {
25
+ const prototype = Target.prototype;
26
+ const descriptors = {};
27
+ const attributes = typeDef.attributes || typeDef.properties || [];
28
+ for (const attribute of attributes) {
29
+ const name = attribute.name;
30
+ let set;
31
+ let descriptor;
32
+ if (attribute.resolve) {
33
+ descriptor = {
34
+ get() {
35
+ return attribute.resolve(this, this.getContext?.());
36
+ },
37
+ set(related) {
38
+ return attribute.set(this, related);
39
+ },
40
+ configurable: true,
41
+ };
42
+ } else {
43
+ switch (attribute.type) {
44
+ case 'String':
45
+ set = function (value) {
46
+ if (!(typeof value === 'string' || (value == null && attribute.nullable !== false)))
47
+ throw new ClientError(`${name} must be a string, attempt to assign ${value}`);
48
+ getChanges(this)[name] = value;
49
+ };
50
+ break;
51
+ case 'ID':
52
+ set = function (value) {
53
+ if (
54
+ !(
55
+ typeof value === 'string' ||
56
+ (value?.length > 0 && value.every?.((value) => typeof value === 'string')) ||
57
+ (value == null && attribute.nullable !== false)
58
+ )
59
+ )
60
+ throw new ClientError(`${name} must be a string, attempt to assign ${value}`);
61
+ getChanges(this)[name] = value;
62
+ };
63
+ break;
64
+ case 'Float':
65
+ case 'Number':
66
+ set = function (value) {
67
+ const scalarValue = value?.__op__ ? value.value : value;
68
+ if (!(typeof scalarValue === 'number' || (value == null && attribute.nullable !== false)))
69
+ throw new ClientError(`${name} must be a number, attempt to assign ${scalarValue}`);
70
+ getChanges(this)[name] = value;
71
+ };
72
+ break;
73
+ case 'Int':
74
+ set = function (value) {
75
+ let scalarValue = value?.__op__ ? value.value : value;
76
+ if (!(scalarValue >> 0 === scalarValue || (value == null && attribute.nullable !== false))) {
77
+ if (typeof scalarValue === 'number' && Math.abs((scalarValue >> 0) - scalarValue) <= 1) {
78
+ // if it just needs to be rounded, do the conversion without complaining
79
+ scalarValue = Math.round(scalarValue);
80
+ if (value?.__op__) value.value = scalarValue;
81
+ else value = scalarValue;
82
+ } else
83
+ throw new ClientError(
84
+ `${name} must be an integer between -2147483648 and 2147483647, attempt to assign ${value}`
85
+ );
86
+ }
87
+ getChanges(this)[name] = value;
88
+ };
89
+ break;
90
+ case 'Long':
91
+ set = function (value) {
92
+ let scalarValue = value?.__op__ ? value.value : value;
93
+ if (
94
+ !(
95
+ (Math.round(scalarValue) === value && Math.abs(scalarValue) <= 9007199254740992) ||
96
+ (value == null && attribute.nullable !== false)
97
+ )
98
+ ) {
99
+ if (typeof scalarValue === 'number' && Math.abs(scalarValue) <= 9007199254740992) {
100
+ // if it just needs to be rounded, do the conversion without complaining
101
+ scalarValue = Math.round(scalarValue);
102
+ if (value?.__op__) value.value = scalarValue;
103
+ else value = scalarValue;
104
+ } else
105
+ throw new ClientError(
106
+ `${name} must be an integer between -9007199254740992 and 9007199254740992, attempt to assign ${value}`
107
+ );
108
+ }
109
+ getChanges(this)[name] = value;
110
+ };
111
+ break;
112
+ case 'BigInt':
113
+ set = function (value) {
114
+ let scalarValue = value?.__op__ ? value.value : value;
115
+ if (!(typeof scalarValue === 'bigint' || (value == null && attribute.nullable !== false))) {
116
+ if (typeof scalarValue === 'string' || typeof scalarValue === 'number') {
117
+ scalarValue = BigInt(scalarValue);
118
+ if (value?.__op__) value.value = scalarValue;
119
+ else value = scalarValue;
120
+ } else throw new ClientError(`${name} must be a number, attempt to assign ${value}`);
121
+ }
122
+ getChanges(this)[name] = value;
123
+ };
124
+ break;
125
+ case 'Boolean':
126
+ set = function (value) {
127
+ if (!(typeof value === 'boolean' || (value == null && attribute.nullable !== false)))
128
+ throw new ClientError(`${name} must be a boolean, attempt to assign ${value}`);
129
+ getChanges(this)[name] = value;
130
+ };
131
+ break;
132
+ case 'Date':
133
+ set = function (value) {
134
+ if (!(value instanceof Date || (value == null && attribute.nullable !== false))) {
135
+ if (typeof value === 'string' || typeof value === 'number') value = new Date(value);
136
+ else throw new ClientError(`${name} must be a Date, attempt to assign ${value}`);
137
+ }
138
+ getChanges(this)[name] = value;
139
+ };
140
+ break;
141
+ case 'Bytes':
142
+ set = function (value) {
143
+ if (!(value instanceof Uint8Array || (value == null && attribute.nullable !== false)))
144
+ throw new ClientError(`${name} must be a Buffer or Uint8Array, attempt to assign ${value}`);
145
+ getChanges(this)[name] = value;
146
+ };
147
+ break;
148
+ case 'Blob':
149
+ set = function (value) {
150
+ if (!(value instanceof Blob || (value == null && attribute.nullable !== false)))
151
+ throw new ClientError(`${name} must be a Blob, attempt to assign ${value}`);
152
+ getChanges(this)[name] = value;
153
+ };
154
+ break;
155
+ case 'Any':
156
+ case undefined:
157
+ set = function (value) {
158
+ getChanges(this)[name] = value;
159
+ };
160
+ break;
161
+ default: // for all user defined types, they must at least be an object
162
+ set = function (value) {
163
+ if (!(typeof value === 'object' || (value == null && attribute.nullable !== false)))
164
+ throw new ClientError(`${name} must be an object, attempt to assign ${value}`);
165
+ getChanges(this)[name] = value;
166
+ };
167
+ }
168
+ descriptor = {
169
+ get() {
170
+ let changes = this.getChanges?.();
171
+ if (changes && name in changes) {
172
+ const value = changes[name];
173
+ if (value?.__op__) {
174
+ const sourceValue = this.getRecord()?.[name];
175
+ return value.update(sourceValue);
176
+ }
177
+ return value;
178
+ }
179
+ const sourceValue = this.getRecord()?.[name];
180
+ if (sourceValue && typeof sourceValue === 'object') {
181
+ const updatedValue = trackObject(sourceValue, attribute);
182
+ if (updatedValue) {
183
+ if (!changes) {
184
+ this._setChanges((changes = Object.create(null)));
185
+ }
186
+ return (changes[name] = updatedValue);
187
+ }
188
+ }
189
+ return sourceValue;
190
+ },
191
+ set,
192
+ enumerable: true,
193
+ configurable: true, // we need to be able to reconfigure these as schemas change (attributes can be added/removed at runtime)
194
+ };
195
+ }
196
+ descriptor.get.isAttribute = true;
197
+ descriptors[name] = descriptor;
198
+ if (
199
+ !(name in prototype) ||
200
+ // this means that we are re-defining an attribute accessor (which is fine)
201
+ Object.getOwnPropertyDescriptor(prototype, name)?.get?.isAttribute
202
+ ) {
203
+ Object.defineProperty(prototype, name, descriptor);
204
+ }
205
+ }
206
+ setMethod('getProperty', function (name) {
207
+ const descriptor = descriptors[name];
208
+ if (descriptor) {
209
+ return descriptor.get.call(this);
210
+ }
211
+ const changes = this.getChanges();
212
+ if (changes?.[name] !== undefined) return changes[name];
213
+ return this.getRecord()?.[name];
214
+ });
215
+ setMethod('set', function (name, value) {
216
+ const descriptor = descriptors[name];
217
+ if (descriptor) return descriptor.set.call(this, value);
218
+ if (typeDef.sealed) throw new ClientError('Can not add a property to a sealed table schema');
219
+ getChanges(this)[name] = value;
220
+ });
221
+ setMethod('deleteProperty', function (name) {
222
+ getChanges(this)[name] = undefined;
223
+ });
224
+ setMethod('toJSON', function () {
225
+ const changes = this.getChanges?.();
226
+ let copiedSource;
227
+ for (const key in changes) {
228
+ // copy the source first so we have properties in the right order and can override them
229
+ if (!copiedSource) copiedSource = { ...this.getRecord() };
230
+ let value = changes[key];
231
+ if (value?.__op__) {
232
+ const sourceValue = copiedSource[key];
233
+ value = value.update(sourceValue);
234
+ }
235
+ copiedSource[key] = value; // let recursive calls to toJSON handle sub-objects
236
+ }
237
+ const keys = Object.keys(this); // we use Object.keys because it is expected that the many inherited enumerables would slow a for-in loop down
238
+ if (keys.length > 0) {
239
+ if (!copiedSource) copiedSource = { ...this.getRecord() };
240
+ Object.assign(copiedSource, this);
241
+ }
242
+ return copiedSource || this.getRecord();
243
+ });
244
+ if (!prototype.get) setMethod('get', prototype.getProperty);
245
+ if (!prototype.delete) setMethod('delete', prototype.deleteProperty);
246
+ if (!prototype.then) setMethod('then', null); // this is a shortcut to avoid the proxy for then, which is called frequently to determine if an object is a promise
247
+ function setMethod(name, method) {
248
+ Object.defineProperty(prototype, name, {
249
+ value: method,
250
+ configurable: true,
251
+ });
252
+ }
253
+ // walk the prototype chain and set the prototype of the last object to the proxy that forwards to get
254
+ let lastPrototype = prototype;
255
+ do {
256
+ const nextPrototype = Object.getPrototypeOf(lastPrototype);
257
+ if (nextPrototype === Object.prototype) {
258
+ Object.setPrototypeOf(lastPrototype, useFullPropertyProxy ? fullPropertyProxy : getOnMissingProperty);
259
+ break;
260
+ }
261
+ lastPrototype = nextPrototype;
262
+ } while (lastPrototype && lastPrototype !== getOnMissingProperty && lastPrototype !== fullPropertyProxy);
263
+ }
264
+ const ObjectPrototype = Object.prototype;
265
+ // Here we define a proxy that will handle any missing property access as a getter, that will attempt
266
+ // get the property value from the tracked object's changes or record. This is set as a prototype of
267
+ // any tracked objects (including Table/Resource instances), so that any property access will be
268
+ // intercepted by the proxy and the value will be returned from the changes or record.
269
+ const getOnMissingProperty = new Proxy({}, { get: getProxiedProperty });
270
+ const fullPropertyProxy = new Proxy({}, { get: getProxiedProperty, set: setProxiedProperty });
271
+ function getProxiedProperty(target, name, receiver) {
272
+ if (typeof name === 'string') {
273
+ if (name === 'then' || name === 'getRecord' || name === 'getChanges') return undefined; // shortcut
274
+ if (ObjectPrototype[name]) return ObjectPrototype[name];
275
+ let changes = receiver.getChanges?.();
276
+ if (changes && name in changes) {
277
+ return changes[name];
278
+ }
279
+ const sourceValue = receiver.getRecord?.()?.[name];
280
+ if (sourceValue && typeof sourceValue === 'object') {
281
+ const updatedValue = trackObject(sourceValue);
282
+ if (updatedValue) {
283
+ if (!changes) {
284
+ changes = Object.create(null);
285
+ receiver._setChanges(changes);
286
+ }
287
+ changes[name] = updatedValue;
288
+ return updatedValue;
289
+ }
290
+ }
291
+ return sourceValue;
292
+ }
293
+ }
294
+ function setProxiedProperty(target: any, name: string | symbol, value, receiver) {
295
+ if (typeof name === 'string') {
296
+ let changes = receiver.getChanges?.();
297
+ if (!changes) {
298
+ changes = {};
299
+ receiver._setChanges(changes);
300
+ }
301
+ changes[name] = value;
302
+ } else {
303
+ Object.defineProperty(receiver, name, { value, configurable: true, writable: true });
304
+ }
305
+ return true;
306
+ }
307
+
308
+ function trackObject(sourceObject: any, typeDef?: any) {
309
+ // lazily instantiate in case of recursive structures
310
+ let TrackedObject;
311
+ switch (sourceObject.constructor) {
312
+ case Object:
313
+ if (typeDef) {
314
+ TrackedObject = typeDef.TrackedObject;
315
+ if (!TrackedObject) {
316
+ typeDef.TrackedObject = TrackedObject = class extends GenericTrackedObject {};
317
+ assignTrackedAccessors(TrackedObject, typeDef);
318
+ }
319
+ return new TrackedObject(sourceObject);
320
+ } else {
321
+ return new GenericTrackedObject(sourceObject);
322
+ }
323
+ case Array:
324
+ const trackedArray = new TrackedArray(sourceObject.length, sourceObject);
325
+ for (let i = 0, l = sourceObject.length; i < l; i++) {
326
+ let element = sourceObject[i];
327
+ if (element && typeof element === 'object') element = trackObject(element, typeDef?.elements);
328
+ trackedArray[i] = element;
329
+ }
330
+ return trackedArray;
331
+ // any other objects (like Date) are left unchanged
332
+ default:
333
+ return sourceObject;
334
+ }
335
+ }
336
+ export class GenericTrackedObject<T extends object = any> {
337
+ #record: T;
338
+ #changes: Partial<T>;
339
+ constructor(sourceObject?: GenericTrackedObject<T> | T) {
340
+ if ((sourceObject as GenericTrackedObject<T>)?.getRecord)
341
+ throw new Error('Can not track an already tracked object, check for circular references');
342
+ this.#record = sourceObject;
343
+ }
344
+ getRecord(): T {
345
+ return this.#record;
346
+ }
347
+ setRecord(record: T) {
348
+ this.#record = record;
349
+ }
350
+ getChanges() {
351
+ return this.#changes;
352
+ }
353
+ _setChanges(changes: Partial<T>) {
354
+ this.#changes = changes;
355
+ }
356
+ }
357
+ assignTrackedAccessors(GenericTrackedObject, {}, true);
358
+ /**
359
+ * Collapse the changed and transitive and source/record data into single object that
360
+ * can be directly serialized. Performed recursively
361
+ * @param target
362
+ * @returns
363
+ */
364
+ export function collapseData(target) {
365
+ const changes = target.getChanges?.();
366
+ let copiedSource;
367
+ for (const key in changes) {
368
+ // copy the source first so we have properties in the right order and can override them
369
+ if (!copiedSource) copiedSource = target.getRecord ? { ...target.getRecord() } : {};
370
+ let value = changes[key];
371
+ if (value && typeof value === 'object') {
372
+ if (value.__op__) {
373
+ const sourceValue = copiedSource[key];
374
+ value = value.update(sourceValue);
375
+ } else value = collapseData(value);
376
+ }
377
+ copiedSource[key] = value;
378
+ }
379
+ const keys = Object.keys(target); // we use Object.keys because it is expected that the many inherited enumerables would slow a for-in loop down
380
+ if (keys.length > 0) {
381
+ if (!copiedSource) copiedSource = target.getRecord ? { ...target.getRecord() } : {};
382
+ Object.assign(copiedSource, target);
383
+ }
384
+ return copiedSource || target.getRecord?.() || target;
385
+ }
386
+ const hasOwnProperty = Object.prototype.hasOwnProperty;
387
+ /**
388
+ * Collapse the changed data and source/record data into single object
389
+ * that is frozen and suitable for storage and caching
390
+ * @param target
391
+ * @returns
392
+ */
393
+ export function updateAndFreeze(target, changes = target.getChanges?.()) {
394
+ let mergedUpdatedObject: any;
395
+ if (!target) return changes;
396
+ if (target.getRecord && target.constructor === Array && !Object.isFrozen(target)) {
397
+ // a tracked array, by default we can freeze the tracked array itself
398
+ mergedUpdatedObject = target;
399
+ for (let i = 0, l = target.length; i < l; i++) {
400
+ let value = target[i];
401
+ if (value && typeof value === 'object') {
402
+ const newValue = updateAndFreeze(value);
403
+ if (newValue !== value && mergedUpdatedObject === target) {
404
+ // if we need to make any changes to the user's array, we make a copy so we don't modify
405
+ // an array that the user may be using with transient properties
406
+ mergedUpdatedObject = target.slice(0);
407
+ }
408
+ value = newValue;
409
+ }
410
+ mergedUpdatedObject[i] = value;
411
+ }
412
+ return Object.freeze(mergedUpdatedObject);
413
+ }
414
+ // copy the changes into the merged updated object
415
+ for (const key in changes) {
416
+ // copy the source first so we have properties in the right order and can override them
417
+ if (!mergedUpdatedObject) mergedUpdatedObject = { ...(target.getRecord ? target.getRecord() : target) };
418
+ let value = changes[key];
419
+ if (value && typeof value === 'object') {
420
+ if (value.__op__) {
421
+ const operation = crdtOperations[value?.__op__];
422
+ if (!operation) throw new Error('Invalid CRDT operation ' + value.__op__);
423
+ else operation(mergedUpdatedObject, key, value);
424
+ continue;
425
+ } else value = updateAndFreeze(value);
426
+ }
427
+ mergedUpdatedObject[key] = value;
428
+ }
429
+ // now copy any properties on the instances itself to the merged updated object
430
+ if (!Array.isArray(target) && target.getRecord) {
431
+ for (const key in target) {
432
+ if (hasOwnProperty.call(target, key)) {
433
+ if (!mergedUpdatedObject) mergedUpdatedObject = { ...target.getRecord() };
434
+ mergedUpdatedObject[key] = target[key];
435
+ }
436
+ }
437
+ }
438
+ return mergedUpdatedObject ? Object.freeze(mergedUpdatedObject) : target.getRecord ? target.getRecord() : target;
439
+ }
440
+ /**
441
+ * Determine if any changes have been made to this tracked object
442
+ * @param target
443
+ * @returns
444
+ */
445
+ export function hasChanges(target) {
446
+ const source = target.getRecord?.();
447
+ if (source === undefined) return true; // if no original source then it is always a change
448
+ if (target.constructor === Array) {
449
+ if (!source) return true;
450
+ if (target[HAS_ARRAY_CHANGES]) return true;
451
+ if (target.length !== source.length) return true;
452
+ for (let i = 0, l = target.length; i < l; i++) {
453
+ const sourceValue = source[i];
454
+ const targetValue = target[i];
455
+ if (sourceValue && targetValue?.getRecord?.() === sourceValue) {
456
+ if (hasChanges(targetValue)) return true;
457
+ } else return true;
458
+ }
459
+ } else {
460
+ const changes = target.getChanges?.();
461
+ if (changes && !source) return true;
462
+ for (const key in changes) {
463
+ const value = changes[key];
464
+ if (value && typeof value === 'object') {
465
+ const sourceValue = source[key];
466
+ // could just be a copy, need to check
467
+ if (sourceValue && value.getRecord?.() === sourceValue) {
468
+ if (hasChanges(value)) return true;
469
+ } else return true;
470
+ } else return true;
471
+ }
472
+ }
473
+ return false;
474
+ }
475
+
476
+ const HAS_ARRAY_CHANGES = Symbol.for('has-array-changes');
477
+ class TrackedArray extends Array {
478
+ #record: any;
479
+ [HAS_ARRAY_CHANGES]: boolean;
480
+ constructor(length, record) {
481
+ super(length);
482
+ this.#record = record;
483
+ }
484
+ getRecord() {
485
+ return this.#record;
486
+ }
487
+ splice(...args) {
488
+ this[HAS_ARRAY_CHANGES] = true;
489
+ return super.splice(...args);
490
+ }
491
+ push(...args) {
492
+ this[HAS_ARRAY_CHANGES] = true;
493
+ return super.push(...args);
494
+ }
495
+ pop() {
496
+ this[HAS_ARRAY_CHANGES] = true;
497
+ return super.pop();
498
+ }
499
+ unshift(...args) {
500
+ this[HAS_ARRAY_CHANGES] = true;
501
+ return super.unshift(...args);
502
+ }
503
+ shift() {
504
+ this[HAS_ARRAY_CHANGES] = true;
505
+ return super.shift();
506
+ }
507
+ }
508
+ TrackedArray.prototype.constructor = Array; // this makes type checks easier/faster (and we want it to be Array like too)
509
+
510
+ // Copy a record into a resource, using copy-on-write for nested objects/arrays
511
+ export function copyRecord(record, targetResource, attributes) {
512
+ targetResource.setRecord(record);
513
+ for (const attribute of attributes) {
514
+ // do not override existing methods
515
+ if (targetResource[attribute] === undefined) {
516
+ const value = record[attribute];
517
+ // use copy-on-write for sub-objects
518
+ if (typeof value === 'object' && value) setSubObject(targetResource, attribute, value);
519
+ // primitives can be directly copied
520
+ else targetResource[attribute] = value;
521
+ }
522
+ }
523
+ }
524
+ export const NOT_COPIED_YET = {};
525
+ let copyEnabled = true;
526
+ function setSubObject(targetResource, key, storedValue) {
527
+ let value = NOT_COPIED_YET;
528
+ Object.defineProperty(targetResource, key, {
529
+ get() {
530
+ if (value === NOT_COPIED_YET && copyEnabled) {
531
+ switch (storedValue.constructor) {
532
+ case Object:
533
+ copyRecord(storedValue, (value = new UpdatableObject()));
534
+ break;
535
+ case Array:
536
+ copyArray(storedValue, (value = new UpdatableArray()));
537
+ break;
538
+ default:
539
+ value = storedValue;
540
+ }
541
+ }
542
+ return value;
543
+ },
544
+ set(newValue) {
545
+ value = newValue;
546
+ },
547
+ enumerable: true,
548
+ configurable: true,
549
+ });
550
+ }
551
+ export function withoutCopying(callback) {
552
+ copyEnabled = false;
553
+ const result = callback();
554
+ copyEnabled = true;
555
+ return result;
556
+ }
557
+ class UpdatableObject {
558
+ // eventually provide CRDT functions here like add, subtract
559
+ }
560
+ class UpdatableArray extends Array {
561
+ // eventually provide CRDT tracking for push, unshift, pop, etc.
562
+ }
563
+ function copyArray(storedArray, targetArray) {
564
+ for (let i = 0, l = storedArray.length; i < l; i++) {
565
+ let value = storedArray[i];
566
+ // copy sub-objects (it assumed we don't really need to lazily access entries in an array,
567
+ // if an array is accessed, probably all elements in array will be accessed
568
+ if (typeof value === 'object' && value) {
569
+ if (value.constructor === Object) copyRecord(value, (value = new UpdatableObject()));
570
+ else if (value.constructor === Array) copyArray(value, (value = new UpdatableArray()));
571
+ }
572
+ targetArray[i] = value;
573
+ }
574
+ }
575
+ export class Addition {
576
+ __op__ = 'add';
577
+ value: any;
578
+ constructor(value) {
579
+ this.value = value;
580
+ }
581
+ update(previousValue) {
582
+ return (+previousValue || 0) + this.value;
583
+ }
584
+ }
@@ -0,0 +1,89 @@
1
+ import type { Context } from './ResourceInterface.ts';
2
+ import { _assignPackageExport } from '../globals.js';
3
+ import { DatabaseTransaction, type Transaction, TRANSACTION_STATE } from './DatabaseTransaction.ts';
4
+ import { AsyncLocalStorage } from 'async_hooks';
5
+
6
+ export function transaction<T>(context: Context, callback: (transaction: Transaction) => T): T;
7
+ export function transaction<T>(callback: (transaction: Transaction) => T): T;
8
+ export const contextStorage = new AsyncLocalStorage<Context>();
9
+
10
+ /**
11
+ * Start and run a new transaction. This can be called with a request to hold the transaction, or a new request object will be created
12
+ * @param ctx
13
+ * @param callback
14
+ * @returns
15
+ */
16
+ export function transaction<T>(
17
+ ctx: Context | ((transaction: Transaction) => T),
18
+ callback?: (transaction: Transaction) => T
19
+ ): T {
20
+ let context: Context;
21
+ let asyncStorageContext;
22
+ if (typeof ctx === 'function') {
23
+ // optional first argument, handle case of no request
24
+ callback = ctx;
25
+ asyncStorageContext = contextStorage.getStore();
26
+ context = asyncStorageContext ?? {};
27
+ } else {
28
+ // request argument included, but null or undefined, so maybe create a new one
29
+ context = ctx ?? (asyncStorageContext = contextStorage.getStore()) ?? {};
30
+ }
31
+
32
+ if (typeof callback !== 'function') {
33
+ throw new TypeError('Callback function must be provided to transaction');
34
+ }
35
+ if (context?.transaction?.open === TRANSACTION_STATE.OPEN && typeof callback === 'function') {
36
+ return callback(context.transaction); // nothing to be done, already in open transaction
37
+ }
38
+
39
+ const transaction = new DatabaseTransaction();
40
+ context.transaction = transaction;
41
+ if (context.timestamp) transaction.timestamp = context.timestamp;
42
+ if (context.replicatedConfirmation) transaction.replicatedConfirmation = context.replicatedConfirmation;
43
+ transaction.setContext(context);
44
+
45
+ // create a resource cache so that multiple requests to the same resource return the same resource
46
+ if (!context.resourceCache) context.resourceCache = [];
47
+ let result;
48
+ try {
49
+ result =
50
+ context.isExplicit || asyncStorageContext
51
+ ? callback(transaction)
52
+ : contextStorage.run(context, () => callback(transaction));
53
+ if (result?.then) {
54
+ return result.then(onComplete, onError);
55
+ }
56
+ } catch (error) {
57
+ onError(error);
58
+ }
59
+ return onComplete(result);
60
+ // when the transaction function completes, run this to commit the transaction
61
+ function onComplete(result) {
62
+ const committed = transaction.commit({ doneWriting: true });
63
+ if (committed.then) {
64
+ return committed.then(() => {
65
+ return result;
66
+ });
67
+ } else {
68
+ return result;
69
+ }
70
+ }
71
+ // if the transaction function throws an error, we abort
72
+ function onError(error) {
73
+ transaction.abort();
74
+ throw error;
75
+ }
76
+ }
77
+
78
+ _assignPackageExport('transaction', transaction);
79
+
80
+ transaction.commit = function (contextSource) {
81
+ const transaction = (contextSource.getContext?.() || contextSource)?.transaction;
82
+ if (!transaction) throw new Error('No active transaction is available to commit');
83
+ return transaction.commit();
84
+ };
85
+ transaction.abort = function (contextSource) {
86
+ const transaction = (contextSource.getContext?.() || contextSource)?.transaction;
87
+ if (!transaction) throw new Error('No active transaction is available to abort');
88
+ return transaction.abort();
89
+ };