@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.
- package/bin/BinObjects.js +17 -0
- package/bin/cliOperations.js +157 -0
- package/bin/copyDb.ts +280 -0
- package/bin/harper.js +156 -0
- package/bin/install.js +15 -0
- package/bin/lite.js +5 -0
- package/bin/restart.js +201 -0
- package/bin/run.js +409 -0
- package/bin/status.js +65 -0
- package/bin/stop.js +22 -0
- package/bin/upgrade.js +134 -0
- package/components/Application.ts +646 -0
- package/components/ApplicationScope.ts +49 -0
- package/components/Component.ts +53 -0
- package/components/ComponentV1.ts +342 -0
- package/components/DEFAULT_CONFIG.ts +18 -0
- package/components/EntryHandler.ts +227 -0
- package/components/Logger.ts +14 -0
- package/components/OptionsWatcher.ts +354 -0
- package/components/PluginModule.ts +6 -0
- package/components/Scope.ts +329 -0
- package/components/componentLoader.ts +529 -0
- package/components/deriveCommonPatternBase.ts +31 -0
- package/components/deriveGlobOptions.ts +44 -0
- package/components/deriveURLPath.ts +57 -0
- package/components/operations.js +658 -0
- package/components/operationsValidation.js +246 -0
- package/components/packageComponent.ts +39 -0
- package/components/requestRestart.ts +26 -0
- package/components/resolveBaseURLPath.ts +38 -0
- package/components/status/ComponentStatus.ts +110 -0
- package/components/status/ComponentStatusRegistry.ts +251 -0
- package/components/status/api.ts +153 -0
- package/components/status/crossThread.ts +405 -0
- package/components/status/errors.ts +152 -0
- package/components/status/index.ts +44 -0
- package/components/status/internal.ts +65 -0
- package/components/status/registry.ts +12 -0
- package/components/status/types.ts +96 -0
- package/config/RootConfigWatcher.ts +59 -0
- package/config/configHelpers.ts +11 -0
- package/config/configUtils.js +967 -0
- package/config/harperConfigEnvVars.ts +641 -0
- package/dataLayer/CreateAttributeObject.js +25 -0
- package/dataLayer/CreateTableObject.js +11 -0
- package/dataLayer/DataLayerObjects.js +43 -0
- package/dataLayer/DeleteBeforeObject.js +22 -0
- package/dataLayer/DeleteObject.js +25 -0
- package/dataLayer/DropAttributeObject.js +11 -0
- package/dataLayer/GetBackupObject.js +22 -0
- package/dataLayer/InsertObject.js +24 -0
- package/dataLayer/ReadAuditLogObject.js +24 -0
- package/dataLayer/SQLSearch.js +1335 -0
- package/dataLayer/SearchByConditionsObject.js +61 -0
- package/dataLayer/SearchByHashObject.js +21 -0
- package/dataLayer/SearchObject.js +45 -0
- package/dataLayer/SqlSearchObject.js +14 -0
- package/dataLayer/UpdateObject.js +23 -0
- package/dataLayer/UpsertObject.js +23 -0
- package/dataLayer/bulkLoad.js +813 -0
- package/dataLayer/dataObjects/BulkLoadObjects.js +27 -0
- package/dataLayer/dataObjects/UpsertObject.js +23 -0
- package/dataLayer/delete.js +164 -0
- package/dataLayer/export.js +381 -0
- package/dataLayer/getBackup.js +40 -0
- package/dataLayer/harperBridge/BridgeMethods.js +81 -0
- package/dataLayer/harperBridge/ResourceBridge.ts +633 -0
- package/dataLayer/harperBridge/bridgeUtility/insertUpdateReturnObj.js +28 -0
- package/dataLayer/harperBridge/bridgeUtility/insertUpdateValidate.js +88 -0
- package/dataLayer/harperBridge/harperBridge.js +21 -0
- package/dataLayer/harperBridge/lmdbBridge/LMDBBridge.js +119 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js +19 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateAttribute.js +112 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateRecords.js +67 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateSchema.js +31 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbCreateTable.js +94 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDeleteAuditLogsBefore.js +98 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDeleteRecords.js +89 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDropAttribute.js +109 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDropSchema.js +107 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbDropTable.js +137 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbFlush.js +35 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbGetBackup.js +111 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbGetDataByHash.js +28 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbGetDataByValue.js +29 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbReadAuditLog.js +207 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbSearchByConditions.js +156 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbSearchByHash.js +21 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbSearchByValue.js +30 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbTransaction.js +19 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbUpdateRecords.js +64 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/lmdbUpsertRecords.js +70 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBCreateAttributeObject.js +22 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBDeleteTransactionObject.js +23 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBInsertTransactionObject.js +22 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBTransactionObject.js +23 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBUpdateTransactionObject.js +24 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/LMDBUpsertTransactionObject.js +24 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/TableSizeObject.js +25 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializeHashSearch.js +21 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/initializePaths.js +157 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbCheckForNewAttributes.js +94 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbCreateTransactionsAuditEnvironment.js +39 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbGetTableSize.js +34 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbProcessRows.js +100 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbSearch.js +371 -0
- package/dataLayer/harperBridge/lmdbBridge/lmdbUtility/lmdbWriteTransaction.js +109 -0
- package/dataLayer/hdbInfoController.js +254 -0
- package/dataLayer/insert.js +266 -0
- package/dataLayer/readAuditLog.js +59 -0
- package/dataLayer/schema.js +366 -0
- package/dataLayer/schemaDescribe.js +289 -0
- package/dataLayer/search.js +60 -0
- package/dataLayer/transaction.js +17 -0
- package/dataLayer/update.js +124 -0
- package/dist/components/Logger.d.ts +12 -0
- package/dist/components/Logger.js +3 -0
- package/dist/components/Logger.js.map +1 -0
- package/dist/components/Scope.d.ts +14 -4
- package/dist/components/Scope.js +18 -10
- package/dist/components/Scope.js.map +1 -1
- package/dist/components/componentLoader.js +16 -9
- package/dist/components/componentLoader.js.map +1 -1
- package/dist/components/operations.js +2 -2
- package/dist/components/operations.js.map +1 -1
- package/dist/config/configUtils.d.ts +1 -1
- package/dist/config/configUtils.js +1 -1
- package/dist/config/configUtils.js.map +1 -1
- package/dist/dataLayer/CreateTableObject.d.ts +2 -2
- package/dist/dataLayer/CreateTableObject.js +2 -2
- package/dist/dataLayer/CreateTableObject.js.map +1 -1
- package/dist/dataLayer/delete.d.ts +1 -1
- package/dist/dataLayer/schema.js +6 -5
- package/dist/dataLayer/schema.js.map +1 -1
- package/dist/dataLayer/schemaDescribe.js +1 -1
- package/dist/dataLayer/schemaDescribe.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/resources/DatabaseTransaction.d.ts +1 -1
- package/dist/resources/IterableEventQueue.d.ts +1 -1
- package/dist/resources/LMDBTransaction.d.ts +5 -1
- package/dist/resources/Resource.d.ts +1 -1
- package/dist/resources/RocksIndexStore.d.ts +3 -3
- package/dist/resources/RocksTransactionLogStore.d.ts +6 -3
- package/dist/resources/Table.d.ts +15 -6
- package/dist/resources/Table.js +4 -1
- package/dist/resources/Table.js.map +1 -1
- package/dist/resources/analytics/read.js +32 -22
- package/dist/resources/analytics/read.js.map +1 -1
- package/dist/resources/analytics/write.js +3 -6
- package/dist/resources/analytics/write.js.map +1 -1
- package/dist/resources/auditStore.d.ts +3 -3
- package/dist/resources/blob.d.ts +25 -2
- package/dist/resources/databases.d.ts +12 -2
- package/dist/resources/databases.js +22 -19
- package/dist/resources/databases.js.map +1 -1
- package/dist/resources/search.js +11 -5
- package/dist/resources/search.js.map +1 -1
- package/dist/resources/transaction.d.ts +2 -1
- package/dist/security/auth.js +1 -1
- package/dist/security/auth.js.map +1 -1
- package/dist/security/cryptoHash.d.ts +2 -2
- package/dist/security/jsLoader.js +243 -66
- package/dist/security/jsLoader.js.map +1 -1
- package/dist/security/keys.js +4 -5
- package/dist/security/keys.js.map +1 -1
- package/dist/security/user.js +3 -3
- package/dist/security/user.js.map +1 -1
- package/dist/server/REST.js +16 -2
- package/dist/server/REST.js.map +1 -1
- package/dist/server/Server.d.ts +2 -1
- package/dist/server/Server.js.map +1 -1
- package/dist/server/fastifyRoutes/plugins/hdbCore.d.ts +6 -1
- package/dist/server/fastifyRoutes.js +2 -0
- package/dist/server/fastifyRoutes.js.map +1 -1
- package/dist/server/http.js +12 -6
- package/dist/server/http.js.map +1 -1
- package/dist/server/jobs/JobObject.d.ts +3 -3
- package/dist/server/loadRootComponents.js +1 -0
- package/dist/server/loadRootComponents.js.map +1 -1
- package/dist/server/operationsServer.js +3 -1
- package/dist/server/operationsServer.js.map +1 -1
- package/dist/server/serverHelpers/JSONStream.d.ts +3 -3
- package/dist/server/serverHelpers/Request.d.ts +5 -5
- package/dist/server/serverHelpers/requestTimePlugin.d.ts +1 -1
- package/dist/server/threads/manageThreads.d.ts +2 -2
- package/dist/server/threads/manageThreads.js +50 -35
- package/dist/server/threads/manageThreads.js.map +1 -1
- package/dist/server/threads/socketRouter.d.ts +1 -1
- package/dist/sqlTranslator/deleteTranslator.d.ts +1 -1
- package/dist/utility/AWS/AWSConnector.d.ts +3 -2
- package/dist/utility/common_utils.d.ts +3 -3
- package/dist/utility/environment/systemInformation.d.ts +1 -0
- package/dist/utility/functions/date/dateFunctions.d.ts +11 -11
- package/dist/utility/globalSchema.d.ts +1 -1
- package/dist/utility/hdbTerms.d.ts +3 -0
- package/dist/utility/hdbTerms.js +3 -0
- package/dist/utility/hdbTerms.js.map +1 -1
- package/dist/utility/installation.d.ts +2 -4
- package/dist/utility/installation.js.map +1 -1
- package/dist/utility/lmdb/commonUtility.d.ts +1 -0
- package/dist/utility/lmdb/deleteUtility.d.ts +1 -0
- package/dist/utility/lmdb/environmentUtility.d.ts +1 -0
- package/dist/utility/lmdb/searchUtility.d.ts +2 -1
- package/dist/utility/lmdb/writeUtility.d.ts +1 -0
- package/dist/utility/logging/harper_logger.d.ts +6 -6
- package/dist/utility/processManagement/processManagement.d.ts +1 -1
- package/dist/utility/processManagement/servicesConfig.d.ts +12 -6
- package/dist/validation/common_validators.d.ts +4 -3
- package/dist/validation/configValidator.d.ts +3 -2
- package/index.d.ts +56 -0
- package/index.js +41 -0
- package/json/systemSchema.json +373 -0
- package/launchServiceScripts/launchHarperDB.js +3 -0
- package/launchServiceScripts/utility/checkNodeVersion.js +15 -0
- package/package.json +21 -3
- package/resources/DatabaseTransaction.ts +378 -0
- package/resources/ErrorResource.ts +57 -0
- package/resources/IterableEventQueue.ts +94 -0
- package/resources/LMDBTransaction.ts +349 -0
- package/resources/RecordEncoder.ts +702 -0
- package/resources/RequestTarget.ts +134 -0
- package/resources/Resource.ts +789 -0
- package/resources/ResourceInterface.ts +221 -0
- package/resources/ResourceInterfaceV2.ts +53 -0
- package/resources/ResourceV2.ts +67 -0
- package/resources/Resources.ts +162 -0
- package/resources/RocksIndexStore.ts +70 -0
- package/resources/RocksTransactionLogStore.ts +352 -0
- package/resources/Table.ts +4527 -0
- package/resources/analytics/hostnames.ts +72 -0
- package/resources/analytics/metadata.ts +10 -0
- package/resources/analytics/read.ts +252 -0
- package/resources/analytics/write.ts +803 -0
- package/resources/auditStore.ts +556 -0
- package/resources/blob.ts +1268 -0
- package/resources/crdt.ts +125 -0
- package/resources/dataLoader.ts +527 -0
- package/resources/databases.ts +1290 -0
- package/resources/graphql.ts +221 -0
- package/resources/indexes/HierarchicalNavigableSmallWorld.ts +638 -0
- package/resources/indexes/customIndexes.ts +7 -0
- package/resources/indexes/vector.ts +38 -0
- package/resources/jsResource.ts +86 -0
- package/resources/loadEnv.ts +22 -0
- package/resources/login.ts +18 -0
- package/resources/openApi.ts +409 -0
- package/resources/registrationDeprecated.ts +8 -0
- package/resources/replayLogs.ts +136 -0
- package/resources/roles.ts +98 -0
- package/resources/search.ts +1301 -0
- package/resources/tracked.ts +584 -0
- package/resources/transaction.ts +89 -0
- package/resources/transactionBroadcast.ts +258 -0
- package/security/auth.ts +376 -0
- package/security/certificateVerification/certificateVerificationSource.ts +84 -0
- package/security/certificateVerification/configValidation.ts +107 -0
- package/security/certificateVerification/crlVerification.ts +623 -0
- package/security/certificateVerification/index.ts +121 -0
- package/security/certificateVerification/ocspVerification.ts +148 -0
- package/security/certificateVerification/pkijs-ed25519-patch.ts +188 -0
- package/security/certificateVerification/types.ts +128 -0
- package/security/certificateVerification/verificationConfig.ts +138 -0
- package/security/certificateVerification/verificationUtils.ts +447 -0
- package/security/cryptoHash.js +42 -0
- package/security/data_objects/PermissionAttributeResponseObject.js +15 -0
- package/security/data_objects/PermissionResponseObject.js +115 -0
- package/security/data_objects/PermissionTableResponseObject.js +20 -0
- package/security/fastifyAuth.js +169 -0
- package/security/impersonation.ts +160 -0
- package/security/jsLoader.ts +716 -0
- package/security/keys.js +948 -0
- package/security/permissionsTranslator.js +300 -0
- package/security/role.js +218 -0
- package/security/tokenAuthentication.ts +228 -0
- package/security/user.ts +449 -0
- package/server/DurableSubscriptionsSession.ts +503 -0
- package/server/REST.ts +407 -0
- package/server/Server.ts +89 -0
- package/server/fastifyRoutes/helpers/getCORSOptions.js +36 -0
- package/server/fastifyRoutes/helpers/getHeaderTimeoutConfig.js +15 -0
- package/server/fastifyRoutes/helpers/getServerOptions.js +33 -0
- package/server/fastifyRoutes/plugins/hdbCore.js +39 -0
- package/server/fastifyRoutes.ts +205 -0
- package/server/graphqlQuerying.ts +700 -0
- package/server/http.ts +640 -0
- package/server/itc/serverHandlers.js +161 -0
- package/server/itc/utility/ITCEventObject.js +10 -0
- package/server/jobs/JobObject.js +24 -0
- package/server/jobs/jobProcess.js +69 -0
- package/server/jobs/jobRunner.js +162 -0
- package/server/jobs/jobs.js +304 -0
- package/server/loadRootComponents.js +44 -0
- package/server/mqtt.ts +485 -0
- package/server/nodeName.ts +75 -0
- package/server/operationsServer.ts +313 -0
- package/server/serverHelpers/Headers.ts +108 -0
- package/server/serverHelpers/JSONStream.ts +269 -0
- package/server/serverHelpers/OperationFunctionObject.ts +13 -0
- package/server/serverHelpers/Request.ts +158 -0
- package/server/serverHelpers/contentTypes.ts +637 -0
- package/server/serverHelpers/requestTimePlugin.js +57 -0
- package/server/serverHelpers/serverHandlers.js +148 -0
- package/server/serverHelpers/serverUtilities.ts +473 -0
- package/server/serverRegistry.ts +8 -0
- package/server/static.ts +187 -0
- package/server/status/definitions.ts +37 -0
- package/server/status/index.ts +125 -0
- package/server/storageReclamation.ts +93 -0
- package/server/threads/itc.js +89 -0
- package/server/threads/manageThreads.js +594 -0
- package/server/threads/socketRouter.ts +360 -0
- package/server/threads/threadServer.js +279 -0
- package/server/throttle.ts +73 -0
- package/sqlTranslator/SelectValidator.js +330 -0
- package/sqlTranslator/alasqlFunctionImporter.js +62 -0
- package/sqlTranslator/deleteTranslator.js +67 -0
- package/sqlTranslator/index.js +242 -0
- package/sqlTranslator/sql_statement_bucket.js +472 -0
- package/static/defaultConfig.yaml +3 -0
- package/studio/web/HDBDogOnly.svg +78 -0
- package/studio/web/assets/PPRadioGrotesk-Bold-DDaUYG8E.woff +0 -0
- package/studio/web/assets/fa-brands-400-CEJbCg16.woff +0 -0
- package/studio/web/assets/fa-brands-400-CSYNqBb_.ttf +0 -0
- package/studio/web/assets/fa-brands-400-DnkPfk3o.eot +0 -0
- package/studio/web/assets/fa-brands-400-UxlILjvJ.woff2 +0 -0
- package/studio/web/assets/fa-brands-400-cH1MgKbP.svg +3717 -0
- package/studio/web/assets/fa-regular-400-BhTwtT8w.eot +0 -0
- package/studio/web/assets/fa-regular-400-D1vz6WBx.ttf +0 -0
- package/studio/web/assets/fa-regular-400-DFnMcJPd.woff +0 -0
- package/studio/web/assets/fa-regular-400-DGzu1beS.woff2 +0 -0
- package/studio/web/assets/fa-regular-400-gwj8Pxq-.svg +801 -0
- package/studio/web/assets/fa-solid-900-B4ZZ7kfP.svg +5034 -0
- package/studio/web/assets/fa-solid-900-B6Axprfb.eot +0 -0
- package/studio/web/assets/fa-solid-900-BUswJgRo.woff2 +0 -0
- package/studio/web/assets/fa-solid-900-DOXgCApm.woff +0 -0
- package/studio/web/assets/fa-solid-900-mxuxnBEa.ttf +0 -0
- package/studio/web/assets/index-BTgXJX9d.js +235 -0
- package/studio/web/assets/index-BTgXJX9d.js.map +1 -0
- package/studio/web/assets/index-C-GXfcup.js +37 -0
- package/studio/web/assets/index-C-GXfcup.js.map +1 -0
- package/studio/web/assets/index-PFlNdimM.js +2 -0
- package/studio/web/assets/index-PFlNdimM.js.map +1 -0
- package/studio/web/assets/index-Y2g_iFpU.css +1 -0
- package/studio/web/assets/index-jiPwkrsB.css +1 -0
- package/studio/web/assets/index.lazy-C3TJZJ4o.js +266 -0
- package/studio/web/assets/index.lazy-C3TJZJ4o.js.map +1 -0
- package/studio/web/assets/profiler-DotzgiCJ.js +2 -0
- package/studio/web/assets/profiler-DotzgiCJ.js.map +1 -0
- package/studio/web/assets/react-redux-VxUEx_mU.js +6 -0
- package/studio/web/assets/react-redux-VxUEx_mU.js.map +1 -0
- package/studio/web/assets/startRecording-B_9J9Csd.js +3 -0
- package/studio/web/assets/startRecording-B_9J9Csd.js.map +1 -0
- package/studio/web/fabric-signup-background.webp +0 -0
- package/studio/web/fabric-signup-text.png +0 -0
- package/studio/web/favicon_purple.png +0 -0
- package/studio/web/github-icon.svg +15 -0
- package/studio/web/harper-fabric_black.png +0 -0
- package/studio/web/harper-fabric_white.png +0 -0
- package/studio/web/harper-studio_white.png +0 -0
- package/studio/web/index.html +16 -0
- package/studio/web/running.css +148 -0
- package/studio/web/running.html +147 -0
- package/studio/web/running.js +111 -0
- package/upgrade/UpgradeObjects.js +13 -0
- package/upgrade/directives/directivesController.js +90 -0
- package/upgrade/directivesManager.js +139 -0
- package/upgrade/upgradePrompt.js +124 -0
- package/upgrade/upgradeUtilities.js +28 -0
- package/utility/AWS/AWSConnector.js +29 -0
- package/utility/OperationFunctionCaller.js +63 -0
- package/utility/assignCmdEnvVariables.js +62 -0
- package/utility/common_utils.js +867 -0
- package/utility/environment/environmentManager.js +208 -0
- package/utility/environment/systemInformation.js +355 -0
- package/utility/errors/commonErrors.js +267 -0
- package/utility/errors/hdbError.js +146 -0
- package/utility/functions/date/dateFunctions.js +65 -0
- package/utility/functions/geo.js +355 -0
- package/utility/functions/sql/alaSQLExtension.js +104 -0
- package/utility/globalSchema.js +35 -0
- package/utility/hdbTerms.ts +819 -0
- package/utility/install/checkJWTTokensExist.js +62 -0
- package/utility/install/harperdb.conf +15 -0
- package/utility/install/harperdb.service +14 -0
- package/utility/install/installer.js +635 -0
- package/utility/installation.ts +30 -0
- package/utility/lmdb/DBIDefinition.js +20 -0
- package/utility/lmdb/DeleteRecordsResponseObject.js +25 -0
- package/utility/lmdb/InsertRecordsResponseObject.js +22 -0
- package/utility/lmdb/OpenDBIObject.js +31 -0
- package/utility/lmdb/OpenEnvironmentObject.js +41 -0
- package/utility/lmdb/UpdateRecordsResponseObject.js +25 -0
- package/utility/lmdb/UpsertRecordsResponseObject.js +22 -0
- package/utility/lmdb/cleanLMDBMap.js +65 -0
- package/utility/lmdb/commonUtility.js +119 -0
- package/utility/lmdb/deleteUtility.js +128 -0
- package/utility/lmdb/environmentUtility.js +477 -0
- package/utility/lmdb/searchCursorFunctions.js +187 -0
- package/utility/lmdb/searchUtility.js +918 -0
- package/utility/lmdb/terms.js +57 -0
- package/utility/lmdb/writeUtility.js +407 -0
- package/utility/logging/harper_logger.js +876 -0
- package/utility/logging/logRotator.js +157 -0
- package/utility/logging/logger.ts +24 -0
- package/utility/logging/readLog.js +355 -0
- package/utility/logging/transactionLog.js +57 -0
- package/utility/mount_hdb.js +59 -0
- package/utility/npmUtilities.js +102 -0
- package/utility/operationPermissions.ts +112 -0
- package/utility/operation_authorization.js +836 -0
- package/utility/packageUtils.js +55 -0
- package/utility/password.ts +99 -0
- package/utility/processManagement/processManagement.js +187 -0
- package/utility/processManagement/servicesConfig.js +56 -0
- package/utility/scripts/restartHdb.js +24 -0
- package/utility/scripts/user_data.sh +13 -0
- package/utility/signalling.js +36 -0
- package/utility/terms/certificates.js +81 -0
- package/utility/when.ts +20 -0
- package/v1.d.ts +39 -0
- package/v1.js +41 -0
- package/v2.d.ts +39 -0
- package/v2.js +41 -0
- package/validation/bulkDeleteValidator.js +24 -0
- package/validation/check_permissions.js +19 -0
- package/validation/common_validators.js +95 -0
- package/validation/configValidator.js +331 -0
- package/validation/deleteValidator.js +15 -0
- package/validation/fileLoadValidator.js +153 -0
- package/validation/insertValidator.js +40 -0
- package/validation/installValidator.js +37 -0
- package/validation/readLogValidator.js +64 -0
- package/validation/role_validation.js +320 -0
- package/validation/schemaMetadataValidator.js +42 -0
- package/validation/searchValidator.js +166 -0
- package/validation/statusValidator.ts +66 -0
- package/validation/transactionLogValidator.js +33 -0
- package/validation/user_validation.js +55 -0
- package/validation/validationWrapper.js +105 -0
- package/dist/resources/analytics/profile.d.ts +0 -2
- package/dist/resources/analytics/profile.js +0 -144
- 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
|
+
};
|