@harperfast/harper 5.2.9 → 5.3.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent/mcpTools.ts +1 -1
- package/agent/session.ts +25 -14
- package/bin/cliOperations.ts +46 -9
- package/bin/copyDb.ts +282 -59
- package/bin/deploySetup.ts +16 -5
- package/bin/harper.ts +1 -1
- package/bin/help.ts +4 -1
- package/bin/lite.ts +4 -1
- package/bin/restart.ts +59 -3
- package/bin/run.ts +6 -11
- package/bin/upgrade.js +7 -3
- package/bin/workloadIdentity.ts +119 -0
- package/components/Application.ts +2414 -242
- package/components/ApplicationScope.ts +8 -0
- package/components/EntryHandler.ts +59 -39
- package/components/OptionsWatcher.ts +150 -74
- package/components/RuntimeModuleTracker.ts +38 -7
- package/components/Scope.ts +37 -15
- package/components/awaitRestart.ts +84 -0
- package/components/componentLoader.ts +340 -30
- package/components/componentPreparationLock.ts +16 -5
- package/components/mcp/adapters/harperHttp.ts +4 -0
- package/components/mcp/listChanged.ts +4 -0
- package/components/mcp/toolRegistry.ts +2 -0
- package/components/mcp/tools/operations.ts +9 -0
- package/components/mcp/tools/schemas/operationDescriptions.ts +2 -2
- package/components/operations.js +270 -78
- package/components/operationsValidation.js +49 -1
- package/components/status/ComponentStatusRegistry.ts +59 -0
- package/config/RootConfigWatcher.ts +80 -34
- package/config/configUtils.ts +291 -34
- package/config/harperConfigEnvVars.ts +170 -27
- package/config-root.schema.json +29 -0
- package/dataLayer/blobBackup.ts +160 -50
- package/dataLayer/delete.ts +6 -1
- package/dataLayer/harperBridge/ResourceBridge.ts +52 -8
- package/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js +3 -1
- package/dataLayer/hdbInfoController.ts +34 -1
- package/dataLayer/insert.ts +44 -1
- package/dataLayer/rocksdbBackup.ts +53 -10
- package/dataLayer/schema.ts +11 -1
- package/dataLayer/schemaDescribe.ts +8 -1
- package/dist/agent/mcpTools.js +1 -1
- package/dist/agent/mcpTools.js.map +1 -1
- package/dist/agent/session.d.ts +22 -0
- package/dist/agent/session.js +26 -15
- package/dist/agent/session.js.map +1 -1
- package/dist/bin/cliOperations.js +48 -9
- package/dist/bin/cliOperations.js.map +1 -1
- package/dist/bin/copyDb.d.ts +12 -1
- package/dist/bin/copyDb.js +248 -60
- package/dist/bin/copyDb.js.map +1 -1
- package/dist/bin/deploySetup.d.ts +2 -0
- package/dist/bin/deploySetup.js +11 -3
- package/dist/bin/deploySetup.js.map +1 -1
- package/dist/bin/harper.js +1 -1
- package/dist/bin/harper.js.map +1 -1
- package/dist/bin/help.js +4 -1
- package/dist/bin/help.js.map +1 -1
- package/dist/bin/lite.js +4 -1
- package/dist/bin/lite.js.map +1 -1
- package/dist/bin/restart.js +54 -5
- package/dist/bin/restart.js.map +1 -1
- package/dist/bin/run.js +4 -10
- package/dist/bin/run.js.map +1 -1
- package/dist/bin/upgrade.js +4 -3
- package/dist/bin/upgrade.js.map +1 -1
- package/dist/bin/workloadIdentity.d.ts +18 -0
- package/dist/bin/workloadIdentity.js +100 -0
- package/dist/bin/workloadIdentity.js.map +1 -0
- package/dist/components/Application.d.ts +139 -16
- package/dist/components/Application.js +2215 -267
- package/dist/components/Application.js.map +1 -1
- package/dist/components/ApplicationScope.d.ts +8 -0
- package/dist/components/ApplicationScope.js +7 -0
- package/dist/components/ApplicationScope.js.map +1 -1
- package/dist/components/EntryHandler.js +26 -10
- package/dist/components/EntryHandler.js.map +1 -1
- package/dist/components/OptionsWatcher.d.ts +1 -0
- package/dist/components/OptionsWatcher.js +141 -74
- package/dist/components/OptionsWatcher.js.map +1 -1
- package/dist/components/RuntimeModuleTracker.js +40 -6
- package/dist/components/RuntimeModuleTracker.js.map +1 -1
- package/dist/components/Scope.js +38 -13
- package/dist/components/Scope.js.map +1 -1
- package/dist/components/awaitRestart.d.ts +33 -0
- package/dist/components/awaitRestart.js +61 -0
- package/dist/components/awaitRestart.js.map +1 -0
- package/dist/components/componentLoader.d.ts +38 -1
- package/dist/components/componentLoader.js +279 -22
- package/dist/components/componentLoader.js.map +1 -1
- package/dist/components/componentPreparationLock.d.ts +5 -0
- package/dist/components/componentPreparationLock.js +14 -6
- package/dist/components/componentPreparationLock.js.map +1 -1
- package/dist/components/mcp/adapters/harperHttp.js +4 -0
- package/dist/components/mcp/adapters/harperHttp.js.map +1 -1
- package/dist/components/mcp/listChanged.js +5 -0
- package/dist/components/mcp/listChanged.js.map +1 -1
- package/dist/components/mcp/toolRegistry.d.ts +1 -0
- package/dist/components/mcp/toolRegistry.js.map +1 -1
- package/dist/components/mcp/tools/operations.d.ts +5 -0
- package/dist/components/mcp/tools/operations.js +9 -0
- package/dist/components/mcp/tools/operations.js.map +1 -1
- package/dist/components/mcp/tools/schemas/operationDescriptions.js +2 -2
- package/dist/components/mcp/tools/schemas/operationDescriptions.js.map +1 -1
- package/dist/components/operations.js +231 -77
- package/dist/components/operations.js.map +1 -1
- package/dist/components/operationsValidation.js +49 -1
- package/dist/components/operationsValidation.js.map +1 -1
- package/dist/components/status/ComponentStatusRegistry.d.ts +0 -4
- package/dist/components/status/ComponentStatusRegistry.js +63 -0
- package/dist/components/status/ComponentStatusRegistry.js.map +1 -1
- package/dist/config/RootConfigWatcher.d.ts +7 -1
- package/dist/config/RootConfigWatcher.js +64 -27
- package/dist/config/RootConfigWatcher.js.map +1 -1
- package/dist/config/configUtils.d.ts +9 -1
- package/dist/config/configUtils.js +254 -33
- package/dist/config/configUtils.js.map +1 -1
- package/dist/config/harperConfigEnvVars.d.ts +16 -0
- package/dist/config/harperConfigEnvVars.js +162 -25
- package/dist/config/harperConfigEnvVars.js.map +1 -1
- package/dist/dataLayer/blobBackup.d.ts +49 -20
- package/dist/dataLayer/blobBackup.js +139 -50
- package/dist/dataLayer/blobBackup.js.map +1 -1
- package/dist/dataLayer/delete.js +1 -1
- package/dist/dataLayer/delete.js.map +1 -1
- package/dist/dataLayer/harperBridge/ResourceBridge.d.ts +14 -1
- package/dist/dataLayer/harperBridge/ResourceBridge.js +51 -10
- package/dist/dataLayer/harperBridge/ResourceBridge.js.map +1 -1
- package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.d.ts +3 -1
- package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js +3 -1
- package/dist/dataLayer/harperBridge/lmdbBridge/lmdbMethods/DeleteAuditLogsBeforeResults.js.map +1 -1
- package/dist/dataLayer/hdbInfoController.d.ts +10 -0
- package/dist/dataLayer/hdbInfoController.js +30 -1
- package/dist/dataLayer/hdbInfoController.js.map +1 -1
- package/dist/dataLayer/insert.d.ts +9 -1
- package/dist/dataLayer/insert.js +30 -0
- package/dist/dataLayer/insert.js.map +1 -1
- package/dist/dataLayer/rocksdbBackup.d.ts +2 -2
- package/dist/dataLayer/rocksdbBackup.js +45 -8
- package/dist/dataLayer/rocksdbBackup.js.map +1 -1
- package/dist/dataLayer/schema.js +8 -0
- package/dist/dataLayer/schema.js.map +1 -1
- package/dist/dataLayer/schemaDescribe.js +8 -1
- package/dist/dataLayer/schemaDescribe.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/json/systemSchema.json +52 -0
- package/dist/resources/DatabaseTransaction.d.ts +55 -0
- package/dist/resources/DatabaseTransaction.js +459 -45
- package/dist/resources/DatabaseTransaction.js.map +1 -1
- package/dist/resources/LMDBTransaction.js +22 -4
- package/dist/resources/LMDBTransaction.js.map +1 -1
- package/dist/resources/PrimaryRocksDatabase.d.ts +1 -0
- package/dist/resources/PrimaryRocksDatabase.js +29 -0
- package/dist/resources/PrimaryRocksDatabase.js.map +1 -1
- package/dist/resources/RecordEncoder.d.ts +20 -0
- package/dist/resources/RecordEncoder.js +94 -9
- package/dist/resources/RecordEncoder.js.map +1 -1
- package/dist/resources/RequestTarget.d.ts +2 -0
- package/dist/resources/RequestTarget.js.map +1 -1
- package/dist/resources/Resource.js +20 -11
- package/dist/resources/Resource.js.map +1 -1
- package/dist/resources/ResourceInterface.d.ts +20 -1
- package/dist/resources/ResourceInterface.js.map +1 -1
- package/dist/resources/RocksIndexStore.d.ts +6 -1
- package/dist/resources/RocksIndexStore.js +24 -9
- package/dist/resources/RocksIndexStore.js.map +1 -1
- package/dist/resources/RocksTransactionLogStore.d.ts +14 -1
- package/dist/resources/RocksTransactionLogStore.js +57 -17
- package/dist/resources/RocksTransactionLogStore.js.map +1 -1
- package/dist/resources/Table.d.ts +112 -8
- package/dist/resources/Table.js +1073 -191
- package/dist/resources/Table.js.map +1 -1
- package/dist/resources/auditStore.d.ts +11 -2
- package/dist/resources/auditStore.js +325 -71
- package/dist/resources/auditStore.js.map +1 -1
- package/dist/resources/blob.d.ts +129 -9
- package/dist/resources/blob.js +992 -114
- package/dist/resources/blob.js.map +1 -1
- package/dist/resources/branchDatabase.d.ts +48 -0
- package/dist/resources/branchDatabase.js +892 -0
- package/dist/resources/branchDatabase.js.map +1 -0
- package/dist/resources/crdt.js +50 -12
- package/dist/resources/crdt.js.map +1 -1
- package/dist/resources/databases.d.ts +150 -0
- package/dist/resources/databases.js +1200 -239
- package/dist/resources/databases.js.map +1 -1
- package/dist/resources/defineTable.d.ts +10 -2
- package/dist/resources/defineTable.js +9 -1
- package/dist/resources/defineTable.js.map +1 -1
- package/dist/resources/graphql.d.ts +1 -1
- package/dist/resources/graphql.js +50 -15
- package/dist/resources/graphql.js.map +1 -1
- package/dist/resources/indexes/HierarchicalNavigableSmallWorld.d.ts +1 -0
- package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js +6 -2
- package/dist/resources/indexes/HierarchicalNavigableSmallWorld.js.map +1 -1
- package/dist/resources/longLivedTransactions.d.ts +71 -0
- package/dist/resources/longLivedTransactions.js +358 -0
- package/dist/resources/longLivedTransactions.js.map +1 -0
- package/dist/resources/models/backendRegistry.d.ts +26 -0
- package/dist/resources/models/backendRegistry.js +60 -2
- package/dist/resources/models/backendRegistry.js.map +1 -1
- package/dist/resources/models/bootstrap.d.ts +33 -1
- package/dist/resources/models/bootstrap.js +416 -31
- package/dist/resources/models/bootstrap.js.map +1 -1
- package/dist/resources/recordLock.d.ts +80 -0
- package/dist/resources/recordLock.js +184 -0
- package/dist/resources/recordLock.js.map +1 -0
- package/dist/resources/replayLogs.d.ts +14 -1
- package/dist/resources/replayLogs.js +152 -24
- package/dist/resources/replayLogs.js.map +1 -1
- package/dist/resources/replayLogsGuards.d.ts +94 -7
- package/dist/resources/replayLogsGuards.js +111 -7
- package/dist/resources/replayLogsGuards.js.map +1 -1
- package/dist/resources/search.js +158 -6
- package/dist/resources/search.js.map +1 -1
- package/dist/resources/transactionBroadcast.d.ts +1 -1
- package/dist/resources/transactionBroadcast.js +2 -2
- package/dist/resources/transactionBroadcast.js.map +1 -1
- package/dist/security/auth.js +61 -30
- package/dist/security/auth.js.map +1 -1
- package/dist/security/authn/oidc/claims.d.ts +22 -0
- package/dist/security/authn/oidc/claims.js +71 -0
- package/dist/security/authn/oidc/claims.js.map +1 -0
- package/dist/security/authn/oidc/identityToken.d.ts +27 -0
- package/dist/security/authn/oidc/identityToken.js +111 -0
- package/dist/security/authn/oidc/identityToken.js.map +1 -0
- package/dist/security/authn/oidc/jwks.d.ts +25 -0
- package/dist/security/authn/oidc/jwks.js +261 -0
- package/dist/security/authn/oidc/jwks.js.map +1 -0
- package/dist/security/authn/oidc/providers/generic.d.ts +13 -0
- package/dist/security/authn/oidc/providers/generic.js +34 -0
- package/dist/security/authn/oidc/providers/generic.js.map +1 -0
- package/dist/security/authn/oidc/providers/githubActions.d.ts +11 -0
- package/dist/security/authn/oidc/providers/githubActions.js +129 -0
- package/dist/security/authn/oidc/providers/githubActions.js.map +1 -0
- package/dist/security/authn/oidc/providers/index.d.ts +37 -0
- package/dist/security/authn/oidc/providers/index.js +24 -0
- package/dist/security/authn/oidc/providers/index.js.map +1 -0
- package/dist/security/authn/oidc/tokenExchange.d.ts +12 -0
- package/dist/security/authn/oidc/tokenExchange.js +306 -0
- package/dist/security/authn/oidc/tokenExchange.js.map +1 -0
- package/dist/security/authn/oidc/trustPolicyOperations.d.ts +49 -0
- package/dist/security/authn/oidc/trustPolicyOperations.js +358 -0
- package/dist/security/authn/oidc/trustPolicyOperations.js.map +1 -0
- package/dist/security/authn/oidc/types.d.ts +38 -0
- package/dist/security/authn/oidc/types.js +6 -0
- package/dist/security/authn/oidc/types.js.map +1 -0
- package/dist/security/certificateVerification/index.js +40 -11
- package/dist/security/certificateVerification/index.js.map +1 -1
- package/dist/security/certificateVerification/trustedIssuers.d.ts +24 -0
- package/dist/security/certificateVerification/trustedIssuers.js +79 -0
- package/dist/security/certificateVerification/trustedIssuers.js.map +1 -0
- package/dist/security/certificateVerification/types.d.ts +1 -0
- package/dist/security/credentialProvenance.d.ts +35 -0
- package/dist/security/credentialProvenance.js +51 -0
- package/dist/security/credentialProvenance.js.map +1 -0
- package/dist/security/credentialRejection.d.ts +4 -0
- package/dist/security/credentialRejection.js +24 -0
- package/dist/security/credentialRejection.js.map +1 -0
- package/dist/security/deferredAuthentication.d.ts +36 -0
- package/dist/security/deferredAuthentication.js +70 -0
- package/dist/security/deferredAuthentication.js.map +1 -0
- package/dist/security/impersonation.d.ts +21 -0
- package/dist/security/impersonation.js +108 -9
- package/dist/security/impersonation.js.map +1 -1
- package/dist/security/jsLoader.d.ts +6 -0
- package/dist/security/jsLoader.js +75 -15
- package/dist/security/jsLoader.js.map +1 -1
- package/dist/security/keys.js +301 -71
- package/dist/security/keys.js.map +1 -1
- package/dist/security/operationScope.d.ts +21 -0
- package/dist/security/operationScope.js +36 -0
- package/dist/security/operationScope.js.map +1 -0
- package/dist/security/permissionsTranslator.js +21 -0
- package/dist/security/permissionsTranslator.js.map +1 -1
- package/dist/security/tokenAuthentication.d.ts +19 -1
- package/dist/security/tokenAuthentication.js +191 -10
- package/dist/security/tokenAuthentication.js.map +1 -1
- package/dist/security/user.js +4 -3
- package/dist/security/user.js.map +1 -1
- package/dist/server/DurableSubscriptionsSession.d.ts +2 -2
- package/dist/server/DurableSubscriptionsSession.js +67 -10
- package/dist/server/DurableSubscriptionsSession.js.map +1 -1
- package/dist/server/REST.js +73 -0
- package/dist/server/REST.js.map +1 -1
- package/dist/server/graphqlQuerying.js +4 -0
- package/dist/server/graphqlQuerying.js.map +1 -1
- package/dist/server/http.d.ts +11 -0
- package/dist/server/http.js +88 -15
- package/dist/server/http.js.map +1 -1
- package/dist/server/itc/serverHandlers.js +8 -1
- package/dist/server/itc/serverHandlers.js.map +1 -1
- package/dist/server/jobs/jobProcess.js +6 -2
- package/dist/server/jobs/jobProcess.js.map +1 -1
- package/dist/server/jobs/jobs.js +4 -1
- package/dist/server/jobs/jobs.js.map +1 -1
- package/dist/server/liveSubscriptionAuth.d.ts +26 -4
- package/dist/server/liveSubscriptionAuth.js +105 -39
- package/dist/server/liveSubscriptionAuth.js.map +1 -1
- package/dist/server/loadRootComponents.js +49 -10
- package/dist/server/loadRootComponents.js.map +1 -1
- package/dist/server/mqtt.d.ts +2 -0
- package/dist/server/mqtt.js +165 -30
- package/dist/server/mqtt.js.map +1 -1
- package/dist/server/nodeName.d.ts +2 -0
- package/dist/server/nodeName.js +107 -23
- package/dist/server/nodeName.js.map +1 -1
- package/dist/server/serverHelpers/Headers.d.ts +25 -0
- package/dist/server/serverHelpers/Headers.js +139 -1
- package/dist/server/serverHelpers/Headers.js.map +1 -1
- package/dist/server/serverHelpers/contentTypes.d.ts +9 -0
- package/dist/server/serverHelpers/contentTypes.js +32 -25
- package/dist/server/serverHelpers/contentTypes.js.map +1 -1
- package/dist/server/serverHelpers/deployValidationState.d.ts +3 -0
- package/dist/server/serverHelpers/deployValidationState.js +9 -19
- package/dist/server/serverHelpers/deployValidationState.js.map +1 -1
- package/dist/server/serverHelpers/operationAuthorizationState.d.ts +12 -0
- package/dist/server/serverHelpers/operationAuthorizationState.js +24 -2
- package/dist/server/serverHelpers/operationAuthorizationState.js.map +1 -1
- package/dist/server/serverHelpers/registeredOperations.d.ts +5 -4
- package/dist/server/serverHelpers/registeredOperations.js +74 -21
- package/dist/server/serverHelpers/registeredOperations.js.map +1 -1
- package/dist/server/serverHelpers/requestSanitization.d.ts +11 -0
- package/dist/server/serverHelpers/requestSanitization.js +20 -0
- package/dist/server/serverHelpers/requestSanitization.js.map +1 -0
- package/dist/server/serverHelpers/serverHandlers.js +6 -3
- package/dist/server/serverHelpers/serverHandlers.js.map +1 -1
- package/dist/server/serverHelpers/serverUtilities.d.ts +18 -0
- package/dist/server/serverHelpers/serverUtilities.js +90 -20
- package/dist/server/serverHelpers/serverUtilities.js.map +1 -1
- package/dist/server/serverHelpers/sharedMessageEncoding.d.ts +67 -0
- package/dist/server/serverHelpers/sharedMessageEncoding.js +280 -0
- package/dist/server/serverHelpers/sharedMessageEncoding.js.map +1 -0
- package/dist/server/serverHelpers/uwsServer.js +19 -1
- package/dist/server/serverHelpers/uwsServer.js.map +1 -1
- package/dist/server/static.js +24 -28
- package/dist/server/static.js.map +1 -1
- package/dist/server/storageReclamation.d.ts +12 -0
- package/dist/server/storageReclamation.js +26 -0
- package/dist/server/storageReclamation.js.map +1 -1
- package/dist/server/threads/itc.d.ts +7 -2
- package/dist/server/threads/itc.js +5 -1
- package/dist/server/threads/itc.js.map +1 -1
- package/dist/server/threads/manageThreads.d.ts +26 -3
- package/dist/server/threads/manageThreads.js +517 -65
- package/dist/server/threads/manageThreads.js.map +1 -1
- package/dist/server/threads/socketRouter.js +89 -26
- package/dist/server/threads/socketRouter.js.map +1 -1
- package/dist/server/threads/threadHeapMemory.d.ts +2 -0
- package/dist/server/threads/threadHeapMemory.js +31 -0
- package/dist/server/threads/threadHeapMemory.js.map +1 -0
- package/dist/server/threads/threadServer.js +46 -15
- package/dist/server/threads/threadServer.js.map +1 -1
- package/dist/sqlEngine/config.d.ts +1 -3
- package/dist/sqlEngine/config.js +19 -16
- package/dist/sqlEngine/config.js.map +1 -1
- package/dist/sqlTranslator/index.d.ts +1 -1
- package/dist/sqlTranslator/index.js +30 -7
- package/dist/sqlTranslator/index.js.map +1 -1
- package/dist/upgrade/directives/5-3-0.d.ts +7 -0
- package/dist/upgrade/directives/5-3-0.js +148 -0
- package/dist/upgrade/directives/5-3-0.js.map +1 -0
- package/dist/upgrade/directives/directivesController.js +2 -1
- package/dist/upgrade/directives/directivesController.js.map +1 -1
- package/dist/utility/OperationFunctionCaller.js +2 -1
- package/dist/utility/OperationFunctionCaller.js.map +1 -1
- package/dist/utility/common_utils.d.ts +16 -0
- package/dist/utility/common_utils.js +32 -6
- package/dist/utility/common_utils.js.map +1 -1
- package/dist/utility/componentNames.d.ts +8 -0
- package/dist/utility/componentNames.js +12 -1
- package/dist/utility/componentNames.js.map +1 -1
- package/dist/utility/environment/environmentManager.js +3 -6
- package/dist/utility/environment/environmentManager.js.map +1 -1
- package/dist/utility/environment/systemInformation.d.ts +1 -0
- package/dist/utility/environment/systemInformation.js +1 -0
- package/dist/utility/environment/systemInformation.js.map +1 -1
- package/dist/utility/errors/commonErrors.d.ts +2 -0
- package/dist/utility/errors/commonErrors.js +2 -0
- package/dist/utility/errors/commonErrors.js.map +1 -1
- package/dist/utility/errors/hdbError.d.ts +17 -0
- package/dist/utility/errors/hdbError.js +30 -1
- package/dist/utility/errors/hdbError.js.map +1 -1
- package/dist/utility/globalSchema.d.ts +18 -0
- package/dist/utility/hdbTerms.d.ts +16 -0
- package/dist/utility/hdbTerms.js +18 -2
- package/dist/utility/hdbTerms.js.map +1 -1
- package/dist/utility/logging/harper_logger.d.ts +2 -0
- package/dist/utility/logging/harper_logger.js +91 -14
- package/dist/utility/logging/harper_logger.js.map +1 -1
- package/dist/utility/logging/logRotator.js +76 -49
- package/dist/utility/logging/logRotator.js.map +1 -1
- package/dist/utility/nodeIdentity.d.ts +9 -0
- package/dist/utility/nodeIdentity.js +58 -0
- package/dist/utility/nodeIdentity.js.map +1 -0
- package/dist/utility/npmUtilities.js +9 -7
- package/dist/utility/npmUtilities.js.map +1 -1
- package/dist/utility/operationPermissions.d.ts +3 -1
- package/dist/utility/operationPermissions.js +16 -1
- package/dist/utility/operationPermissions.js.map +1 -1
- package/dist/utility/operation_authorization.d.ts +10 -7
- package/dist/utility/operation_authorization.js +212 -41
- package/dist/utility/operation_authorization.js.map +1 -1
- package/dist/utility/watchPath.d.ts +29 -0
- package/dist/utility/watchPath.js +68 -0
- package/dist/utility/watchPath.js.map +1 -0
- package/dist/utility/watcherFallback.d.ts +86 -0
- package/dist/utility/watcherFallback.js +278 -1
- package/dist/utility/watcherFallback.js.map +1 -1
- package/dist/validation/configValidator.d.ts +12 -0
- package/dist/validation/configValidator.js +199 -72
- package/dist/validation/configValidator.js.map +1 -1
- package/dist/validation/installValidator.js +12 -0
- package/dist/validation/installValidator.js.map +1 -1
- package/dist/validation/validationWrapper.d.ts +11 -0
- package/dist/validation/validationWrapper.js +16 -3
- package/dist/validation/validationWrapper.js.map +1 -1
- package/index.ts +2 -0
- package/json/systemSchema.json +52 -0
- package/npm-shrinkwrap.json +196 -194
- package/package.json +7 -6
- package/resources/DESIGN.md +114 -52
- package/resources/DatabaseTransaction.ts +521 -43
- package/resources/LMDBTransaction.ts +26 -4
- package/resources/PrimaryRocksDatabase.ts +28 -1
- package/resources/RecordEncoder.ts +103 -8
- package/resources/RequestTarget.ts +2 -0
- package/resources/Resource.ts +17 -9
- package/resources/ResourceInterface.ts +23 -0
- package/resources/RocksIndexStore.ts +30 -9
- package/resources/RocksTransactionLogStore.ts +78 -21
- package/resources/Table.ts +1110 -159
- package/resources/auditStore.ts +331 -73
- package/resources/blob.ts +1029 -110
- package/resources/branchDatabase.ts +941 -0
- package/resources/crdt.ts +76 -12
- package/resources/databases.ts +1310 -252
- package/resources/defineTable.ts +18 -2
- package/resources/graphql.ts +70 -16
- package/resources/indexes/HierarchicalNavigableSmallWorld.ts +6 -2
- package/resources/longLivedTransactions.ts +360 -0
- package/resources/models/backendRegistry.ts +84 -2
- package/resources/models/bootstrap.ts +473 -28
- package/resources/recordLock.ts +253 -0
- package/resources/replayLogs.ts +147 -26
- package/resources/replayLogsGuards.ts +171 -8
- package/resources/search.ts +154 -7
- package/resources/transactionBroadcast.ts +3 -3
- package/security/auth.ts +68 -29
- package/security/authn/oidc/claims.ts +72 -0
- package/security/authn/oidc/identityToken.ts +129 -0
- package/security/authn/oidc/jwks.ts +260 -0
- package/security/authn/oidc/providers/generic.ts +40 -0
- package/security/authn/oidc/providers/githubActions.ts +137 -0
- package/security/authn/oidc/providers/index.ts +52 -0
- package/security/authn/oidc/tokenExchange.ts +300 -0
- package/security/authn/oidc/trustPolicyOperations.ts +343 -0
- package/security/authn/oidc/types.ts +41 -0
- package/security/certificateVerification/index.ts +54 -13
- package/security/certificateVerification/trustedIssuers.ts +76 -0
- package/security/certificateVerification/types.ts +1 -0
- package/security/credentialProvenance.ts +47 -0
- package/security/credentialRejection.ts +22 -0
- package/security/deferredAuthentication.ts +71 -0
- package/security/impersonation.ts +117 -12
- package/security/jsLoader.ts +81 -18
- package/security/keys.ts +298 -72
- package/security/operationScope.ts +33 -0
- package/security/permissionsTranslator.js +23 -0
- package/security/tokenAuthentication.ts +233 -12
- package/security/user.ts +4 -3
- package/server/DESIGN.md +183 -16
- package/server/DurableSubscriptionsSession.ts +71 -11
- package/server/REST.ts +79 -1
- package/server/graphqlQuerying.ts +4 -0
- package/server/http.ts +99 -18
- package/server/itc/serverHandlers.js +8 -1
- package/server/jobs/jobProcess.ts +8 -2
- package/server/jobs/jobs.ts +4 -1
- package/server/liveSubscriptionAuth.ts +129 -46
- package/server/loadRootComponents.js +50 -8
- package/server/mqtt.ts +179 -38
- package/server/nodeName.ts +103 -21
- package/server/serverHelpers/Headers.ts +131 -0
- package/server/serverHelpers/contentTypes.ts +29 -21
- package/server/serverHelpers/deployValidationState.ts +24 -13
- package/server/serverHelpers/operationAuthorizationState.ts +34 -3
- package/server/serverHelpers/registeredOperations.ts +79 -22
- package/server/serverHelpers/requestSanitization.ts +15 -0
- package/server/serverHelpers/serverHandlers.js +6 -3
- package/server/serverHelpers/serverUtilities.ts +104 -31
- package/server/serverHelpers/sharedMessageEncoding.ts +307 -0
- package/server/serverHelpers/uwsServer.ts +17 -2
- package/server/static.ts +23 -29
- package/server/storageReclamation.ts +23 -0
- package/server/threads/itc.js +11 -1
- package/server/threads/manageThreads.js +526 -56
- package/server/threads/socketRouter.ts +81 -26
- package/server/threads/threadHeapMemory.ts +26 -0
- package/server/threads/threadServer.js +43 -15
- package/sqlTranslator/index.ts +31 -8
- package/studio/web/assets/Chat-BnCBegQz.js +2267 -0
- package/studio/web/assets/FloatingChat-CoDW1ySS.js +23 -0
- package/studio/web/assets/{abnfDiagram-VCTEODGH-C0_BAZyO.js → abnfDiagram-VCTEODGH-B0BebmD2.js} +1 -1
- package/studio/web/assets/{alertDialog-DIHt7Z0r.js → alertDialog-CQyAJJhl.js} +1 -1
- package/studio/web/assets/{apiToken-c3Rd-w6g.js → apiToken-Bwk5BLXW.js} +1 -1
- package/studio/web/assets/applications-DHxGi7JH.js +296 -0
- package/studio/web/assets/architecture-7GRP2DOG-LB-MLAAb.js +1 -0
- package/studio/web/assets/{architectureDiagram-5GKGNRK7-BWzrASgm.js → architectureDiagram-5GKGNRK7-7SW3GD-K.js} +1 -1
- package/studio/web/assets/authStore-C3Nfubqr.js +3 -0
- package/studio/web/assets/{blockDiagram-NRAW4CY4-BdJX9Khj.js → blockDiagram-I7D4REHJ-BqguiadH.js} +2 -2
- package/studio/web/assets/{button-DhiX-njv.js → button-BIsUKRZq.js} +2 -2
- package/studio/web/assets/{c4Diagram-UCG6FXSJ-CI6MzGmQ.js → c4Diagram-7LVT6UL2-LBNf8t_X.js} +1 -1
- package/studio/web/assets/channel-yictG-U-.js +1 -0
- package/studio/web/assets/{chevron-up-Df2c8uoU.js → chevron-up-DtKGqDn3.js} +1 -1
- package/studio/web/assets/{chunk-TEH6E4GO-P87k5mNi.js → chunk-4HAMMTFA-DWtTut21.js} +1 -1
- package/studio/web/assets/{chunk-75Z2AOVW-BT8tVmks.js → chunk-75Z2AOVW-QGQD6th2.js} +1 -1
- package/studio/web/assets/{chunk-DU6HZSFF-9kAOOmI6.js → chunk-DU6HZSFF-Chq20Ba5.js} +1 -1
- package/studio/web/assets/{chunk-F27PBJKO-BW7ao8AY.js → chunk-F27PBJKO-BVA5EPhV.js} +1 -1
- package/studio/web/assets/{chunk-GMAD6QVW-BNyXpoQO.js → chunk-GMAD6QVW-BeS7S07A.js} +1 -1
- package/studio/web/assets/{chunk-OBVCFTLP-D4wWOqDQ.js → chunk-GVQU2GXP-sbwVIQ8i.js} +1 -1
- package/studio/web/assets/{chunk-G27WJ6UU-COyLMcgK.js → chunk-IMKFNOWR-Bnh3tAVd.js} +1 -1
- package/studio/web/assets/{chunk-JQ64N6SF-Cyz1IeLf.js → chunk-L3NEJ4N5-COfUyKII.js} +1 -1
- package/studio/web/assets/chunk-OSK3NFVY-ByciRftO.js +10 -0
- package/studio/web/assets/{chunk-P2QGCYS3-DmIFY4d7.js → chunk-P2QGCYS3-CP1VhG_c.js} +1 -1
- package/studio/web/assets/{chunk-POPQ4Y6H-BPrvMyKz.js → chunk-POPQ4Y6H-ClWhhkwW.js} +1 -1
- package/studio/web/assets/{chunk-PWAF6VOD-2zB6IW9i.js → chunk-PWAF6VOD-1z1THyS5.js} +1 -1
- package/studio/web/assets/{chunk-RHFEMEQ7-2FgyI8YU.js → chunk-SHT3W25Y-LpQkMsah.js} +2 -2
- package/studio/web/assets/{chunk-SVP7TREG-FwtbH2QC.js → chunk-SVP7TREG-jtdAHw0S.js} +1 -1
- package/studio/web/assets/{chunk-LCL6LL3I-HOzK_ppE.js → chunk-TICWLB2K-VOwzetX-.js} +1 -1
- package/studio/web/assets/classDiagram-ZZMXUADV-VaEwSy_g.js +1 -0
- package/studio/web/assets/classDiagram-v2-VYDZK3BY-VaEwSy_g.js +1 -0
- package/studio/web/assets/{createLucideIcon-BKGPfjm2.js → createLucideIcon-CzW9508A.js} +1 -1
- package/studio/web/assets/{cssMode-CEN2mzSA.js → cssMode-s0cWI-_M.js} +1 -1
- package/studio/web/assets/{cynefin-OW5HDTMX-BRkpLFQV.js → cynefin-OW5HDTMX-BbdbCvub.js} +1 -1
- package/studio/web/assets/{cynefinDiagram-5FMLGOSQ-CHT1DaX6.js → cynefinDiagram-5FMLGOSQ-TP-aIqbt.js} +1 -1
- package/studio/web/assets/{dagre-3AP2YEHR-DpUXBh63.js → dagre-GXQ25YYZ-DShnGpGo.js} +1 -1
- package/studio/web/assets/{diagram-S7CK7UJ4-BuymVFZT.js → diagram-S7CK7UJ4-aoCVTtcy.js} +1 -1
- package/studio/web/assets/{diagram-UQ7AKVKN-CyP148RM.js → diagram-UQ7AKVKN-DglXtQ6x.js} +1 -1
- package/studio/web/assets/{diagram-VSXAHHWV-CoCAg3M9.js → diagram-VSXAHHWV-fhEdmkwM.js} +1 -1
- package/studio/web/assets/{diagram-VX7I27RA-BpOqCFca.js → diagram-VX7I27RA-DccVJet6.js} +1 -1
- package/studio/web/assets/{diagram-Z3DM3KII-Bfpw7Vbj.js → diagram-Z3DM3KII-D-RyJJb7.js} +1 -1
- package/studio/web/assets/{dialog-CBf0Mr1d.js → dialog-Cn2uWgD4.js} +1 -1
- package/studio/web/assets/{dist-lkA3O3eM.js → dist-DP8UjMB_.js} +1 -1
- package/studio/web/assets/{download-BtTOBem-.js → download-B5T5r7ss.js} +1 -1
- package/studio/web/assets/{ebnfDiagram-PWID7BFC-DS_6aWqL.js → ebnfDiagram-PWID7BFC-DJGpIpz_.js} +1 -1
- package/studio/web/assets/{editor-D8oDeCTL.js → editor-DNcRHK54.js} +1 -1
- package/studio/web/assets/{erDiagram-SSCWMZ5O-DJNk6Fgw.js → erDiagram-RLTQ6QDP-CIfNlgkC.js} +1 -1
- package/studio/web/assets/eventmodeling-NTZA5JFV-CLxnp2CR.js +1 -0
- package/studio/web/assets/flowDiagram-HODETNUW-BIbhmz9f.js +1 -0
- package/studio/web/assets/{ganttDiagram-EL5Y4UJY-2pOExxMY.js → ganttDiagram-EL5Y4UJY-BxToTzzD.js} +1 -1
- package/studio/web/assets/{getAnalytics-D4LKGeVy.js → getAnalytics-GHK8ORfM.js} +1 -1
- package/studio/web/assets/{gitGraph-4MIJSDKK-CH5ZxwzF.js → gitGraph-4MIJSDKK-D2s2w8lE.js} +1 -1
- package/studio/web/assets/{gitGraphDiagram-WWUBYQGX-DVIsIhbO.js → gitGraphDiagram-WWUBYQGX-Dwntd4-x.js} +1 -1
- package/studio/web/assets/{html-u3vOg7LJ.js → html-Bdssedlg.js} +1 -1
- package/studio/web/assets/{htmlMode-DyO31v-P.js → htmlMode-CoDlJ3fw.js} +1 -1
- package/studio/web/assets/{index-Cxj2_wsl.css → index-7RMEgVG1.css} +1 -1
- package/studio/web/assets/index-D6sxmFLR.js +824 -0
- package/studio/web/assets/index.lazy-tmU5BS8s.js +2 -0
- package/studio/web/assets/{info-A6RAGUB7-CPQfTnaG.js → info-A6RAGUB7-DYjkvb0C.js} +1 -1
- package/studio/web/assets/{infoDiagram-RXCK75RN-DlwLYlwm.js → infoDiagram-27XIBGKW-Bnp1FJE5.js} +1 -1
- package/studio/web/assets/{ishikawaDiagram-5VMMS53U-BRXRp29U.js → ishikawaDiagram-5VMMS53U-D9Xh2r6X.js} +1 -1
- package/studio/web/assets/{javascript-CUvxOyTC.js → javascript-B8meVSTH.js} +1 -1
- package/studio/web/assets/{journeyDiagram-EYS64GPL-B0ou8k0n.js → journeyDiagram-3NMN7TZE-CokIi6ll.js} +2 -2
- package/studio/web/assets/{jsonMode-f_IwbF3D.js → jsonMode-DpIPd35T.js} +1 -1
- package/studio/web/assets/{kanban-definition-3QL26DDD-uYg7iYzp.js → kanban-definition-UXKFOSKX-CukSFJfX.js} +1 -1
- package/studio/web/assets/{languageServices-DXtZ6rEF.js → languageServices-C_5FMJzQ.js} +1 -1
- package/studio/web/assets/{lspLanguageFeatures-B4pCF1zO.js → lspLanguageFeatures-BIzNBzPK.js} +1 -1
- package/studio/web/assets/{mermaid-parser.core-Ck-fC8b7.js → mermaid-parser.core-BlEsOWNO.js} +3 -3
- package/studio/web/assets/{mermaid.core-CP8aNNYm.js → mermaid.core-BlkGaMIH.js} +5 -5
- package/studio/web/assets/{mindmap-definition-FBJOCRG2-CgTZ-rit.js → mindmap-definition-YA3MSWOX-IprMc_0j.js} +1 -1
- package/studio/web/assets/{notifications-D3tIQ4sg.js → notifications-CQf18QKb.js} +1 -1
- package/studio/web/assets/notifications-CvZivSbh.js +1 -0
- package/studio/web/assets/{packet-AYTQ26CC-DEyoPtPb.js → packet-AYTQ26CC-Bi3V04Zi.js} +1 -1
- package/studio/web/assets/{pegDiagram-XKGWAZYB-DrD-7sD9.js → pegDiagram-XKGWAZYB-BNuPDLZY.js} +1 -1
- package/studio/web/assets/{pie-WAS4IAKB-wjj-EI1d.js → pie-WAS4IAKB-_6DoDbng.js} +1 -1
- package/studio/web/assets/{pieDiagram-E7YTZNPT-GntqDCzv.js → pieDiagram-E7YTZNPT-DqNb6Ht2.js} +1 -1
- package/studio/web/assets/{profile-DZWU7MgT.js → profile-DdOwtntb.js} +1 -1
- package/studio/web/assets/{quadrantDiagram-AXDQQJYC-0UeqXQGd.js → quadrantDiagram-AXDQQJYC-BGH9E2YR.js} +1 -1
- package/studio/web/assets/{radar-RG4KPBEZ-DFSA5h7k.js → radar-RG4KPBEZ-DDdVczcL.js} +1 -1
- package/studio/web/assets/{railroad-74A4TZTK-CaOUG9wR.js → railroad-74A4TZTK-BJUP4Jds.js} +1 -1
- package/studio/web/assets/railroad-abnf-HS5TGJTU-Bm3L1L0h.js +1 -0
- package/studio/web/assets/railroad-ebnf-LZEXJU2U-CKzLGlkw.js +1 -0
- package/studio/web/assets/railroad-peg-WCYAUIDC-S8xLjslx.js +1 -0
- package/studio/web/assets/{railroadDiagram-O6MQD6OU-yHUELZaV.js → railroadDiagram-O6MQD6OU-DGTPh2KZ.js} +1 -1
- package/studio/web/assets/{regions-CkyurXzE.js → regions-n69fwagr.js} +1 -1
- package/studio/web/assets/{register-BUyhWjBO.js → register-PfWTCXWB.js} +3 -3
- package/studio/web/assets/{requirementDiagram-EFPCY7ZU-DNEGFjuW.js → requirementDiagram-BXWQKSXE-BJnO6uLz.js} +1 -1
- package/studio/web/assets/{sankeyDiagram-P5KCCOFB-DpyAmSVR.js → sankeyDiagram-P5KCCOFB-0vSOdymH.js} +1 -1
- package/studio/web/assets/{sequenceDiagram-WJ2MYXX4-TyaT7xNk.js → sequenceDiagram-WJ2MYXX4-hETizDWE.js} +1 -1
- package/studio/web/assets/{setComponentFile-CeyKSZAa.js → setComponentFile-Bg6O7X0S.js} +1 -1
- package/studio/web/assets/{setup-D2kn7cAA.js → setup-CUx_aUDl.js} +2 -2
- package/studio/web/assets/{stateDiagram-HBIQ2CUA-CeEdTArZ.js → stateDiagram-D77RDMKH-CdYQ_KtC.js} +1 -1
- package/studio/web/assets/stateDiagram-v2-MP3YSRHH-CdKuzQMT.js +1 -0
- package/studio/web/assets/status-D7BVKqX9.js +61 -0
- package/studio/web/assets/{swimlanes-XN3QIQJK-B54FmF46.js → swimlanes-42K2YHIH-B8cHIpU4.js} +1 -1
- package/studio/web/assets/swimlanesDiagram-VR7AAH4N-DmOSJwaH.js +8 -0
- package/studio/web/assets/{tabs-B_G5zscN.js → tabs-BrHu7gJi.js} +1 -1
- package/studio/web/assets/{timeline-definition-24CTP7MA-D-a9ujbo.js → timeline-definition-24CTP7MA-BJWYSXqF.js} +1 -1
- package/studio/web/assets/{toggleHighContrast-C0UW6rI2.js → toggleHighContrast-DBSyXzMr.js} +1 -1
- package/studio/web/assets/{treeView-Q6P3EWNA-CrW_6JnS.js → treeView-Q6P3EWNA-qxe_v6CQ.js} +1 -1
- package/studio/web/assets/{treemap-WGGIJYW6-BxyYLdP_.js → treemap-WGGIJYW6-dDo97XXF.js} +1 -1
- package/studio/web/assets/{tsMode-DBC0zmDx.js → tsMode-BByKCjBS.js} +1 -1
- package/studio/web/assets/{typescript-DApRQir3.js → typescript-DDLnLpw9.js} +1 -1
- package/studio/web/assets/{useEntityRestURL-DB6JStU1.js → useEntityRestURL-31CHGaHk.js} +1 -1
- package/studio/web/assets/{useLocalStorage-Dtj1QS8_.js → useLocalStorage-BqMR3D8_.js} +1 -1
- package/studio/web/assets/vendor-core-c2JRRJpV.js +58 -0
- package/studio/web/assets/vendor-datadog-CLUcJXOo.js +6 -0
- package/studio/web/assets/{vendor-react-Dyj4O3HE.js → vendor-react-CJV_K1u4.js} +1 -1
- package/studio/web/assets/vendor-tanstack-DxzraizX.js +1 -0
- package/studio/web/assets/{vendor-ui-vhu-UHhF.js → vendor-ui-BUjK0h8a.js} +2 -2
- package/studio/web/assets/{vennDiagram-4TSXK5OY-Cy7s7Mpy.js → vennDiagram-4TSXK5OY-A3i-lCdl.js} +1 -1
- package/studio/web/assets/{wardley-WFR3VGLG-BeBL35g2.js → wardley-WFR3VGLG-B0ik-_6g.js} +1 -1
- package/studio/web/assets/{wardleyDiagram-VM6X3IG4-BylmIGSg.js → wardleyDiagram-VM6X3IG4-CjrkKWUR.js} +1 -1
- package/studio/web/assets/{workers-C0bFIedw.js → workers-pR3jRY9D.js} +1 -1
- package/studio/web/assets/x-DIzaLEdK.js +1 -0
- package/studio/web/assets/{xml-HWd01lU-.js → xml-2iRnMhQO.js} +1 -1
- package/studio/web/assets/{xychartDiagram-S5SC5T6Z-CoKALMXr.js → xychartDiagram-S5SC5T6Z-Biok4GYV.js} +1 -1
- package/studio/web/assets/{yaml-CIH0Nt-h.js → yaml-Bf92gJpd.js} +1 -1
- package/studio/web/index.html +14 -14
- package/upgrade/directives/5-3-0.ts +132 -0
- package/upgrade/directives/directivesController.ts +2 -1
- package/utility/OperationFunctionCaller.ts +2 -1
- package/utility/common_utils.ts +30 -5
- package/utility/componentNames.ts +12 -0
- package/utility/environment/environmentManager.ts +3 -7
- package/utility/environment/systemInformation.ts +7 -0
- package/utility/errors/commonErrors.ts +4 -0
- package/utility/errors/hdbError.ts +29 -0
- package/utility/hdbTerms.ts +17 -0
- package/utility/logging/harper_logger.ts +87 -14
- package/utility/logging/logRotator.ts +72 -45
- package/utility/nodeIdentity.ts +45 -0
- package/utility/npmUtilities.ts +10 -8
- package/utility/operationPermissions.ts +18 -1
- package/utility/operation_authorization.ts +231 -42
- package/utility/watchPath.ts +63 -0
- package/utility/watcherFallback.ts +270 -0
- package/validation/configValidator.ts +209 -72
- package/validation/installValidator.ts +15 -0
- package/validation/validationWrapper.ts +18 -4
- package/studio/web/assets/Chat-JpO8EtUu.js +0 -2067
- package/studio/web/assets/FloatingChat-Bcj3xSZu.js +0 -23
- package/studio/web/assets/applications-ByqLRKyZ.js +0 -296
- package/studio/web/assets/architecture-7GRP2DOG-DNdx5tEU.js +0 -1
- package/studio/web/assets/authStore-qKmCZcaf.js +0 -3
- package/studio/web/assets/channel-DtCV8PTL.js +0 -1
- package/studio/web/assets/chunk-R7TYR2AO-Irip67yr.js +0 -10
- package/studio/web/assets/classDiagram-DTDB5LWJ-DbO_dCNE.js +0 -1
- package/studio/web/assets/classDiagram-v2-JRS7N3AN-DbO_dCNE.js +0 -1
- package/studio/web/assets/eventmodeling-NTZA5JFV-5jbe4A5P.js +0 -1
- package/studio/web/assets/flowDiagram-A5DVABFB-Dp9Ezlow.js +0 -1
- package/studio/web/assets/index-aSt5tY-L.js +0 -824
- package/studio/web/assets/index.lazy-B9jiPwT8.js +0 -2
- package/studio/web/assets/notifications-CUoYgU98.js +0 -1
- package/studio/web/assets/railroad-abnf-HS5TGJTU-Bc0Qi0WH.js +0 -1
- package/studio/web/assets/railroad-ebnf-LZEXJU2U-G8rVVZ2C.js +0 -1
- package/studio/web/assets/railroad-peg-WCYAUIDC-CrehKBhC.js +0 -1
- package/studio/web/assets/stateDiagram-v2-4QOOHH4V-D4tuw9Su.js +0 -1
- package/studio/web/assets/status-D7Xn5ePA.js +0 -61
- package/studio/web/assets/swimlanesDiagram-VK2B7HYN-XOhmNEvq.js +0 -8
- package/studio/web/assets/vendor-core-RCcadM3e.js +0 -73
- package/studio/web/assets/vendor-datadog-BRv-mOv1.js +0 -6
- package/studio/web/assets/vendor-tanstack-BiFWSB3W.js +0 -1
- package/studio/web/assets/x-B9o9hsep.js +0 -1
- /package/studio/web/assets/{sizeCapture-X5ZJPWSS-B0uUizjq.js → sizeCapture-INFHLROL-B0uUizjq.js} +0 -0
package/resources/auditStore.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { AUDIT_STORE_NAME } from '../utility/lmdb/terms.ts';
|
|
|
4
4
|
import { CONFIG_PARAMS } from '../utility/hdbTerms.ts';
|
|
5
5
|
import { getWorkerIndex, getWorkerCount } from '../server/threads/manageThreads.js';
|
|
6
6
|
import { convertToMS } from '../utility/common_utils.ts';
|
|
7
|
-
import {
|
|
7
|
+
import { LAST_TIMESTAMP_PLACEHOLDER, HAS_STRUCTURE_UPDATE, PENDING_LOCAL_TIME } from './RecordEncoder.ts';
|
|
8
8
|
import * as harperLogger from '../utility/logging/harper_logger.ts';
|
|
9
9
|
import { getRecordAtTime } from './crdt.ts';
|
|
10
10
|
import { decodeFromDatabase } from './blob.ts';
|
|
@@ -33,9 +33,8 @@ import { isReadOnlyMode } from './databases.ts';
|
|
|
33
33
|
initSync();
|
|
34
34
|
|
|
35
35
|
export type AuditRecord = {
|
|
36
|
-
version: number;
|
|
37
|
-
|
|
38
|
-
localTime: number; // log position: LMDB audit-store key; RocksDB transaction-log timestamp
|
|
36
|
+
version: number; // the record's own version: LWW ordering, @updatedTime, ETag
|
|
37
|
+
txnLogKey: number; // position in the origin's transaction log
|
|
39
38
|
type: string;
|
|
40
39
|
encodedRecord?: Buffer;
|
|
41
40
|
extendedType?: number;
|
|
@@ -116,8 +115,22 @@ const MAX_CLEANUP_DELAY = 2 ** 31 - 1;
|
|
|
116
115
|
// mint latch keyed per (table, type) so one entry type can't silence another's producer stack
|
|
117
116
|
const warnedBodylessMints = new Set<string>();
|
|
118
117
|
const warnedBodylessTables = new Set<number>();
|
|
118
|
+
// legacy-format latches, mirroring the bodyless ones above: a range scan over millions of pre-#2247
|
|
119
|
+
// entries must not turn a recovered read into a log flood. Recovery latches per table (the table is
|
|
120
|
+
// known by then); an undecodable header has no table, so it latches once per process.
|
|
121
|
+
const warnedRecoveredTables = new Set<number>();
|
|
122
|
+
let warnedUndecodableHeader = false;
|
|
123
|
+
// keyed per (table, type) like warnedBodylessMints, so one entry type cannot silence another's stack
|
|
124
|
+
const warnedPendingPreviousVersion = new Set<string>();
|
|
119
125
|
const FLOAT_TARGET = new Float64Array(1);
|
|
120
126
|
const FLOAT_BUFFER = new Uint8Array(FLOAT_TARGET.buffer);
|
|
127
|
+
|
|
128
|
+
/** Last resort on a detached path: a failing log sink must not itself become an unhandled rejection. */
|
|
129
|
+
function warnContained(message: string, error: unknown) {
|
|
130
|
+
try {
|
|
131
|
+
harperLogger.warn(message, error);
|
|
132
|
+
} catch {}
|
|
133
|
+
}
|
|
121
134
|
let DEFAULT_AUDIT_CLEANUP_DELAY = 10000; // default delay of 10 seconds
|
|
122
135
|
let timestampErrored = false;
|
|
123
136
|
export function openAuditStore(rootStore) {
|
|
@@ -133,13 +146,16 @@ export function openAuditStore(rootStore) {
|
|
|
133
146
|
if (!auditStore) {
|
|
134
147
|
// this means we are creating a new audit store. Initialize with the last removed timestamp (we don't want to put this in legacy audit logs since we don't know if they have had deletions or not).
|
|
135
148
|
auditStore = rootStore.openDB(AUDIT_STORE_NAME, AUDIT_STORE_OPTIONS);
|
|
136
|
-
|
|
149
|
+
// this open path is synchronous, so nothing downstream can own the write's rejection
|
|
150
|
+
updateLastRemoved(auditStore, 1)?.catch?.((error) =>
|
|
151
|
+
warnContained('Error initializing the audit log last-removed marker', error)
|
|
152
|
+
);
|
|
137
153
|
}
|
|
138
154
|
const superGetRange = auditStore.getRange.bind(auditStore);
|
|
139
155
|
auditStore.getRange = function (options) {
|
|
140
156
|
if (options.values === false) return superGetRange(options); // getKeys shouldn't be modified
|
|
141
157
|
return superGetRange(options).map(({ key, value }) => {
|
|
142
|
-
value.key = value.
|
|
158
|
+
value.key = value.txnLogKey = key;
|
|
143
159
|
return value;
|
|
144
160
|
});
|
|
145
161
|
};
|
|
@@ -155,6 +171,7 @@ export function openAuditStore(rootStore) {
|
|
|
155
171
|
return {
|
|
156
172
|
remove() {
|
|
157
173
|
delete deleteCallbacks[tableId];
|
|
174
|
+
if (auditStore.tableStores[tableId] === table) delete auditStore.tableStores[tableId];
|
|
158
175
|
},
|
|
159
176
|
};
|
|
160
177
|
};
|
|
@@ -164,7 +181,15 @@ export function openAuditStore(rootStore) {
|
|
|
164
181
|
let pendingCleanupResolve: (() => void) | null = null;
|
|
165
182
|
let lastCleanupResolution: Promise<void>;
|
|
166
183
|
let cleanupPriority = 0;
|
|
167
|
-
|
|
184
|
+
auditStore.auditCleanupDelay = DEFAULT_AUDIT_CLEANUP_DELAY;
|
|
185
|
+
let cleanupStopped = false;
|
|
186
|
+
// a last-removed marker whose write failed, retried on later passes: dropping it would leave
|
|
187
|
+
// getLastRemoved() reporting a boundary the entries behind it have already been deleted past
|
|
188
|
+
let pendingLastRemoved: number | undefined;
|
|
189
|
+
const isRocksAuditStore = auditStore instanceof RocksTransactionLogStore;
|
|
190
|
+
// A pass yields, so the store can be closed underneath it. Every touch of the environment after a
|
|
191
|
+
// resume — cursor advance, cursor release, marker write, re-arm — has to re-check.
|
|
192
|
+
const storeClosing = () => auditStore.rootStore.status === 'closed' || auditStore.rootStore.status === 'closing';
|
|
168
193
|
onStorageReclamation(rootStore.path, (priority) => {
|
|
169
194
|
cleanupPriority = priority; // update the priority
|
|
170
195
|
if (priority) {
|
|
@@ -175,28 +200,23 @@ export function openAuditStore(rootStore) {
|
|
|
175
200
|
/**
|
|
176
201
|
* Schedules a pass of the audit cleanup loop. The returned promise fulfills once the pass that
|
|
177
202
|
* serves this call has finished, so callers (notably tests) can await completion instead of
|
|
178
|
-
* guessing a delay. Two things it does not promise:
|
|
203
|
+
* guessing a delay. Two things it does not promise: an LMDB pass removes at most
|
|
179
204
|
* MAX_DELETES_PER_CLEANUP entries before rescheduling itself, so fulfillment means "that pass
|
|
180
205
|
* finished", not "the audit log is fully pruned"; and a pass that failed logs and fulfills rather
|
|
181
206
|
* than rejecting, since this promise doubles as the loop's serialization barrier.
|
|
182
207
|
*/
|
|
183
208
|
function scheduleAuditCleanup(newCleanupDelay?: number): Promise<void> {
|
|
184
209
|
// Skip audit cleanup/purge in read-only mode
|
|
185
|
-
if (isReadOnlyMode()) return Promise.resolve();
|
|
186
|
-
if (auditStore instanceof RocksTransactionLogStore) {
|
|
187
|
-
auditStore.rootStore.purgeLogs({
|
|
188
|
-
before: Date.now() - auditRetention / (1 + cleanupPriority * cleanupPriority),
|
|
189
|
-
});
|
|
190
|
-
return Promise.resolve();
|
|
191
|
-
}
|
|
210
|
+
if (cleanupStopped || isReadOnlyMode()) return Promise.resolve();
|
|
192
211
|
|
|
193
|
-
if (newCleanupDelay) auditCleanupDelay = newCleanupDelay;
|
|
212
|
+
if (newCleanupDelay) auditStore.auditCleanupDelay = newCleanupDelay;
|
|
194
213
|
// the pass we are about to cancel has not started, so its callers are handed over to this one
|
|
195
214
|
const supersededResolve = pendingCleanupResolve;
|
|
196
215
|
clearTimeout(pendingCleanup);
|
|
197
216
|
const resolution = new Promise<void>((resolve) => {
|
|
198
217
|
pendingCleanupResolve = resolve;
|
|
199
|
-
|
|
218
|
+
const runCleanupPass = async () => {
|
|
219
|
+
pendingCleanup = null;
|
|
200
220
|
pendingCleanupResolve = null; // started, so a later schedule can no longer cancel this pass
|
|
201
221
|
// claim the serialization slot before yielding: assigning it after the await lets every
|
|
202
222
|
// pass released by the same resolution run concurrently over the same range
|
|
@@ -204,67 +224,146 @@ export function openAuditStore(rootStore) {
|
|
|
204
224
|
lastCleanupResolution = resolution;
|
|
205
225
|
await previousCleanup;
|
|
206
226
|
// query for audit entries that are old
|
|
207
|
-
if (
|
|
227
|
+
if (cleanupStopped || storeClosing()) {
|
|
208
228
|
// nothing to clean up and nothing to reschedule, but leaving `resolution` pending would
|
|
209
229
|
// wedge the loop permanently: it is now the resolution every later pass awaits
|
|
210
230
|
resolve();
|
|
211
231
|
return;
|
|
212
232
|
}
|
|
233
|
+
const passCleanupPriority = cleanupPriority;
|
|
213
234
|
let deleted = 0;
|
|
214
235
|
let lastKey: any;
|
|
215
236
|
try {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
}
|
|
237
|
+
if (isRocksAuditStore) {
|
|
238
|
+
auditStore.rootStore.purgeLogs({
|
|
239
|
+
before: Date.now() - auditRetention / (1 + passCleanupPriority * passCleanupPriority),
|
|
240
|
+
});
|
|
241
|
+
} else {
|
|
242
|
+
// Driven explicitly rather than with for-of: this loop suspends on the awaits below, and a
|
|
243
|
+
// close landing mid-pass closes the env under it. for-of calls next() before the body, so a
|
|
244
|
+
// check inside the body advances the cursor first — the guard has to precede every next().
|
|
245
|
+
const entries = auditStore
|
|
246
|
+
.getRange({
|
|
247
|
+
start: 1, // must not be zero or it will be interpreted as null and overlap with symbols in search
|
|
248
|
+
snapshot: false,
|
|
249
|
+
end: Date.now() - auditRetention / (1 + passCleanupPriority * passCleanupPriority), // remove up until the audit retention time, reducing audit retention time if cleanup is higher priority
|
|
250
|
+
})
|
|
251
|
+
[Symbol.iterator]();
|
|
221
252
|
try {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
253
|
+
while (!cleanupStopped && !storeClosing()) {
|
|
254
|
+
const entry = entries.next();
|
|
255
|
+
if (entry.done) break;
|
|
256
|
+
const auditRecord = entry.value;
|
|
257
|
+
try {
|
|
258
|
+
// awaited so a rejection (not just a synchronous throw) is caught here instead of
|
|
259
|
+
// escaping as an unhandled rejection once a later iteration's promise replaces this one
|
|
260
|
+
await removeAuditEntry(auditStore, auditRecord);
|
|
261
|
+
} catch (error) {
|
|
262
|
+
harperLogger.warn('Error removing audit entry', error);
|
|
263
|
+
}
|
|
264
|
+
lastKey = auditRecord.key;
|
|
265
|
+
await new Promise(setImmediate);
|
|
266
|
+
if (++deleted >= MAX_DELETES_PER_CLEANUP) {
|
|
267
|
+
// limit the amount we cleanup per event turn so we don't use too much memory/CPU
|
|
268
|
+
auditStore.auditCleanupDelay = 10; // and keep trying very soon
|
|
269
|
+
break;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
} finally {
|
|
273
|
+
// for-of released the underlying cursor on break; an explicit loop owes that itself.
|
|
274
|
+
// Skipped only once the root is closing: releasing a cursor into a closed env reaches
|
|
275
|
+
// native code, while a retirement that leaves the env open still owes the release.
|
|
276
|
+
if (!storeClosing()) entries.return?.();
|
|
234
277
|
}
|
|
235
278
|
}
|
|
236
279
|
} catch (error) {
|
|
237
|
-
//
|
|
238
|
-
//
|
|
280
|
+
// a failed scan is a log line, not a retired loop: the bookkeeping and reschedule below
|
|
281
|
+
// still run
|
|
239
282
|
harperLogger.warn('Error during audit log cleanup', error);
|
|
240
283
|
} finally {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
284
|
+
try {
|
|
285
|
+
if (isRocksAuditStore) {
|
|
286
|
+
// eligibility only changes on rotation/flush, so the LMDB backoff — keyed on a per-entry
|
|
287
|
+
// delete count — would only rescan the same segments
|
|
288
|
+
auditStore.auditCleanupDelay = Math.max(
|
|
289
|
+
DEFAULT_AUDIT_CLEANUP_DELAY,
|
|
290
|
+
Math.min(auditRetention / (1 + cleanupPriority * cleanupPriority) / 10, MAX_CLEANUP_DELAY)
|
|
291
|
+
);
|
|
292
|
+
} else {
|
|
293
|
+
if (deleted === 0) {
|
|
294
|
+
// if we didn't delete anything, we can increase the delay (double until we get to one tenth of
|
|
295
|
+
// the retention time). Plain arithmetic, not `<<`/`>>`: those coerce to int32, so a
|
|
296
|
+
// sub-millisecond retention collapsed the delay to 0 permanently (0 << 1 is 0), and a
|
|
297
|
+
// retention over ~248 days grows it past 2^31 where halving it wraps negative.
|
|
298
|
+
auditStore.auditCleanupDelay = Math.max(
|
|
299
|
+
1,
|
|
300
|
+
Math.min(auditStore.auditCleanupDelay * 2, auditRetention / 10, MAX_CLEANUP_DELAY)
|
|
301
|
+
);
|
|
302
|
+
} else {
|
|
303
|
+
pendingLastRemoved = lastKey;
|
|
304
|
+
// and do updates faster
|
|
305
|
+
if (auditStore.auditCleanupDelay > 100) auditStore.auditCleanupDelay = auditStore.auditCleanupDelay / 2;
|
|
306
|
+
}
|
|
307
|
+
// skipped when the store was retired or closed mid-pass — this writes to the audit
|
|
308
|
+
// store — and carried to the next pass instead, so a failed write is not lost
|
|
309
|
+
if (pendingLastRemoved !== undefined && !cleanupStopped && !storeClosing()) {
|
|
310
|
+
const marker = pendingLastRemoved;
|
|
311
|
+
try {
|
|
312
|
+
// awaited so the barrier below covers the write, and so a rejection is logged
|
|
313
|
+
// here rather than escaping the detached timer callback
|
|
314
|
+
await updateLastRemoved(auditStore, marker);
|
|
315
|
+
if (pendingLastRemoved === marker) pendingLastRemoved = undefined;
|
|
316
|
+
} catch (error) {
|
|
317
|
+
harperLogger.warn('Error recording the last removed audit entry', error);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
} finally {
|
|
322
|
+
// settled and re-armed whatever the bookkeeping above threw: this promise is both the
|
|
323
|
+
// serialization barrier every later pass awaits and the drain barrier
|
|
324
|
+
// stopAuditCleanup() hands its callers, so never settling it wedges both
|
|
325
|
+
resolve();
|
|
326
|
+
// both conjuncts are backstops, not the ownership rule — see DESIGN.md: the arming
|
|
327
|
+
// sites already restrict Rocks to the last worker
|
|
328
|
+
if (
|
|
329
|
+
!cleanupStopped &&
|
|
330
|
+
!storeClosing() &&
|
|
331
|
+
(!isRocksAuditStore || (getWorkerIndex() === getWorkerCount() - 1 && !pendingCleanupResolve))
|
|
332
|
+
) {
|
|
333
|
+
scheduleAuditCleanup();
|
|
334
|
+
}
|
|
258
335
|
}
|
|
259
|
-
scheduleAuditCleanup();
|
|
260
336
|
}
|
|
261
337
|
// we can run this pretty frequently since there is very little overhead to these queries
|
|
262
|
-
}
|
|
338
|
+
};
|
|
339
|
+
pendingCleanup = setTimeout(() => {
|
|
340
|
+
// nothing owns the timer callback's promise, so anything the pass lets escape — including a
|
|
341
|
+
// throw from the logging inside its own containment — would land as an unhandled rejection
|
|
342
|
+
runCleanupPass().catch((error) => {
|
|
343
|
+
warnContained('Error during audit log cleanup', error);
|
|
344
|
+
resolve();
|
|
345
|
+
});
|
|
346
|
+
}, auditStore.auditCleanupDelay).unref();
|
|
263
347
|
});
|
|
264
348
|
if (supersededResolve) resolution.then(supersededResolve);
|
|
265
349
|
return resolution;
|
|
266
350
|
}
|
|
267
351
|
auditStore.scheduleAuditCleanup = scheduleAuditCleanup;
|
|
352
|
+
/**
|
|
353
|
+
* Retires the cleanup loop for good, and returns a drain barrier: the promise settles once the pass
|
|
354
|
+
* that was already running has finished. Retirement alone only stops the loop admitting more work —
|
|
355
|
+
* a pass suspended inside `await removeAuditEntry()` still has a write queued whose DBI the native
|
|
356
|
+
* writer consumes later, so a caller that closes or unlinks stores must await this first. The
|
|
357
|
+
* synchronous teardown paths cannot; the in-pass status checks are what covers them.
|
|
358
|
+
*/
|
|
359
|
+
auditStore.stopAuditCleanup = function (): Promise<void> {
|
|
360
|
+
cleanupStopped = true;
|
|
361
|
+
clearTimeout(pendingCleanup);
|
|
362
|
+
pendingCleanup = null;
|
|
363
|
+
pendingCleanupResolve?.();
|
|
364
|
+
pendingCleanupResolve = null;
|
|
365
|
+
return lastCleanupResolution ?? Promise.resolve();
|
|
366
|
+
};
|
|
268
367
|
if (getWorkerIndex() === getWorkerCount() - 1) {
|
|
269
368
|
scheduleAuditCleanup();
|
|
270
369
|
}
|
|
@@ -282,21 +381,51 @@ export function openAuditStore(rootStore) {
|
|
|
282
381
|
return auditStore;
|
|
283
382
|
}
|
|
284
383
|
|
|
384
|
+
/**
|
|
385
|
+
* Whether `entry` is the very write `auditRecord` describes. Write identity is (origin node, log key),
|
|
386
|
+
* never the record version: a version is legitimately non-unique, so a version match can name a
|
|
387
|
+
* different write and authorize destroying live state (a tombstone, a still-referenced blob).
|
|
388
|
+
*
|
|
389
|
+
* On LMDB this is exact — the audit-store key IS the record's `txnLogKey`. On RocksDB a record stores
|
|
390
|
+
* its version in the compatibility word and keeps a divergent log key in `additionalAuditRefs`.
|
|
391
|
+
* Absent identity answers false. The direction is deliberate: uncertainty retains.
|
|
392
|
+
*/
|
|
393
|
+
export function isAuditEntryWrite(entry: any, auditRecord: AuditRecord): boolean {
|
|
394
|
+
if (entry == null || auditRecord.txnLogKey == null) return false;
|
|
395
|
+
const auditNodeId = auditRecord.nodeId ?? 0;
|
|
396
|
+
return (
|
|
397
|
+
(entry.localTime === auditRecord.txnLogKey && (entry.nodeId ?? 0) === auditNodeId) ||
|
|
398
|
+
entry.additionalAuditRefs?.some(
|
|
399
|
+
(ref) => ref.version === auditRecord.txnLogKey && (ref.nodeId ?? 0) === auditNodeId
|
|
400
|
+
) === true
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
|
|
285
404
|
export function removeAuditEntry(auditStore: any, auditRecord: AuditRecord): Promise<void> {
|
|
405
|
+
let tombstoneRemoval: Promise<void> | undefined;
|
|
286
406
|
if (auditRecord.type === 'delete') {
|
|
287
407
|
// if this is a delete, we remove the delete entry from the primary table
|
|
288
|
-
// at the same time so the audit table the primary table are in sync, assuming the entry
|
|
408
|
+
// at the same time so the audit table the primary table are in sync, assuming the entry is still
|
|
409
|
+
// the record state this audit record wrote
|
|
289
410
|
const tableId = auditRecord.tableId;
|
|
290
411
|
const primaryStore = auditStore.tableStores[auditRecord.tableId];
|
|
291
|
-
|
|
292
|
-
|
|
412
|
+
const tombstone = primaryStore?.getEntry(auditRecord.recordId);
|
|
413
|
+
if (isAuditEntryWrite(tombstone, auditRecord))
|
|
414
|
+
// a failed tombstone removal doesn't mean the audit entry removal failed — only
|
|
415
|
+
// auditStore.remove() below decides this function's outcome
|
|
416
|
+
tombstoneRemoval = new Promise<void>((resolve) => {
|
|
417
|
+
resolve(auditStore.deleteCallbacks?.[tableId]?.(auditRecord.recordId, tombstone.version));
|
|
418
|
+
}).catch((error) => {
|
|
419
|
+
harperLogger.warn('Error removing deleted record while removing its audit entry', error);
|
|
420
|
+
});
|
|
293
421
|
}
|
|
294
|
-
|
|
422
|
+
const auditRemoval = auditStore.remove(auditRecord.key);
|
|
423
|
+
return tombstoneRemoval ? Promise.all([tombstoneRemoval, auditRemoval]).then(() => undefined) : auditRemoval;
|
|
295
424
|
}
|
|
296
425
|
|
|
297
426
|
function updateLastRemoved(auditStore, lastKey) {
|
|
298
427
|
FLOAT_TARGET[0] = lastKey;
|
|
299
|
-
auditStore.put(Symbol.for('last-removed'), FLOAT_BUFFER);
|
|
428
|
+
return auditStore.put(Symbol.for('last-removed'), FLOAT_BUFFER);
|
|
300
429
|
}
|
|
301
430
|
|
|
302
431
|
export function getLastRemoved(auditStore) {
|
|
@@ -381,13 +510,63 @@ const EVENT_TYPES = {
|
|
|
381
510
|
remoteSequenceUpdate: REMOTE_SEQUENCE_UPDATE,
|
|
382
511
|
[REMOTE_SEQUENCE_UPDATE]: 'remoteSequenceUpdate',
|
|
383
512
|
};
|
|
513
|
+
/**
|
|
514
|
+
* The LMDB audit entry states the presence of its leading 8-byte previousVersion field with that
|
|
515
|
+
* field's own first byte. The same test is what harperdb 4.x's reader uses and what both versions'
|
|
516
|
+
* replication senders use to strip the field before framing an entry for the wire, so it is a
|
|
517
|
+
* cross-version contract, not a local convention: a field written with any other leading byte is
|
|
518
|
+
* skipped by every reader and shifts action/nodeId/tableId/recordId/version by 8. See harper#2247.
|
|
519
|
+
*/
|
|
520
|
+
const PREVIOUS_VERSION_FIRST_BYTE = 66;
|
|
521
|
+
/**
|
|
522
|
+
* Which first bytes can begin an action, and so cannot be a previousVersion field. Derived from what
|
|
523
|
+
* the encoding can express, not from the types defined today: nibbles 9-15 are reserved for future
|
|
524
|
+
* entry types, and a peer one version ahead must keep decoding rather than look corrupt here.
|
|
525
|
+
*/
|
|
526
|
+
const ACTION_FIRST_BYTE = new Uint8Array(256);
|
|
527
|
+
// single-byte form; 0 is not an entry type, so a zero low nibble cannot start one
|
|
528
|
+
for (let firstByte = 1; firstByte <= (HAS_RECORD | HAS_PARTIAL_RECORD | 0xf); firstByte++) {
|
|
529
|
+
if (firstByte & 0xf) ACTION_FIRST_BYTE[firstByte] = 1;
|
|
530
|
+
}
|
|
531
|
+
// extended form, written as `action | extendedType | 0xc0000000`; 0xff is the five-byte readInt form
|
|
532
|
+
for (let firstByte = 0xc0; firstByte < 0xff; firstByte++) ACTION_FIRST_BYTE[firstByte] = 1;
|
|
533
|
+
let knownActionFlags: number | undefined;
|
|
534
|
+
/**
|
|
535
|
+
* Whether an action word decodes wholly into what this version understands. Consulted only to accept
|
|
536
|
+
* or reject a legacy prefix recovery — never to validate a normally-framed entry, where an unknown
|
|
537
|
+
* future flag must stay forwards-compatible rather than corrupt. The mask is built on first use
|
|
538
|
+
* because HAS_STRUCTURE_UPDATE crosses the RecordEncoder import cycle: read at module scope it
|
|
539
|
+
* resolves to undefined whenever RecordEncoder is the cycle's entry, silently dropping that bit.
|
|
540
|
+
*/
|
|
541
|
+
function isDecodableAction(action: number) {
|
|
542
|
+
knownActionFlags ??=
|
|
543
|
+
0xf |
|
|
544
|
+
HAS_RECORD |
|
|
545
|
+
HAS_PARTIAL_RECORD |
|
|
546
|
+
HAS_STRUCTURE_UPDATE |
|
|
547
|
+
HAS_CURRENT_RESIDENCY_ID |
|
|
548
|
+
HAS_PREVIOUS_RESIDENCY_ID |
|
|
549
|
+
HAS_ORIGINATING_OPERATION |
|
|
550
|
+
HAS_EXPIRATION_EXTENDED_TYPE |
|
|
551
|
+
HAS_BLOBS |
|
|
552
|
+
HAS_ADDITIONAL_AUDIT_REFS |
|
|
553
|
+
LOCAL_ONLY;
|
|
554
|
+
return (action & 0xf) !== 0 && !(action & ~knownActionFlags);
|
|
555
|
+
}
|
|
384
556
|
const ORIGINATING_OPERATIONS = {
|
|
385
557
|
insert: 1,
|
|
386
558
|
update: 2,
|
|
387
559
|
upsert: 3,
|
|
560
|
+
// `put` must be persisted, not inferred: the physical write type is also `put` for an `upsert`
|
|
561
|
+
// that happened to create a record, so the history readers cannot tell the two apart from the
|
|
562
|
+
// type alone. Without an id here the originating operation decoded as undefined, the readers fell
|
|
563
|
+
// back to the physical type, and replication catch-up replayed a `put` as an `upsert` — patching
|
|
564
|
+
// the replica and RETAINING attributes the source had removed.
|
|
565
|
+
put: 4,
|
|
388
566
|
1: 'insert',
|
|
389
567
|
2: 'update',
|
|
390
568
|
3: 'upsert',
|
|
569
|
+
4: 'put',
|
|
391
570
|
};
|
|
392
571
|
|
|
393
572
|
/**
|
|
@@ -439,12 +618,43 @@ export function createAuditEntry(auditRecord: AuditRecord, start = 0) {
|
|
|
439
618
|
}
|
|
440
619
|
action &= ~HAS_RECORD;
|
|
441
620
|
}
|
|
442
|
-
let
|
|
443
|
-
if (
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
621
|
+
let hasPreviousVersion: boolean;
|
|
622
|
+
if (start > 0) {
|
|
623
|
+
// RocksTransactionLogStore states presence with its own prelude flag, derived from this same
|
|
624
|
+
// truthiness, so this container's field stays unconditional and its value is unconstrained.
|
|
625
|
+
hasPreviousVersion = !!previousVersion;
|
|
626
|
+
if (hasPreviousVersion) ENTRY_DATAVIEW.setFloat64(start, previousVersion);
|
|
627
|
+
} else if (previousVersion == null || previousVersion === 0) {
|
|
628
|
+
// absence is stated, not inferred from truthiness: NaN is falsy and would otherwise be
|
|
629
|
+
// silently dropped rather than rejected below
|
|
630
|
+
hasPreviousVersion = false;
|
|
631
|
+
} else if (previousVersion === PENDING_LOCAL_TIME) {
|
|
632
|
+
// The previous entry has no log position yet, and a format whose presence signal is the value's
|
|
633
|
+
// own first byte cannot express "to be filled in at commit". The superseded code deferred to
|
|
634
|
+
// lmdb-js's instructed-write substitution, which resolves to 2.0 whenever no previous time was
|
|
635
|
+
// recorded — the unreadable entry behind harper-pro#737. It resolved correctly when one was, so
|
|
636
|
+
// this trades a lost link on that path for never minting the unreadable form. Not a throw: a
|
|
637
|
+
// pending previous is a producer state, unlike a value the format cannot hold.
|
|
638
|
+
hasPreviousVersion = false;
|
|
639
|
+
if (!warnedPendingPreviousVersion.has(`${tableId}:${type}`)) {
|
|
640
|
+
warnedPendingPreviousVersion.add(`${tableId}:${type}`);
|
|
641
|
+
warnContained(
|
|
642
|
+
`Audit entry (${type}) for record ${recordId} in table ${tableId} has a pending previous version; recording it without a previous-version link`,
|
|
643
|
+
new Error('pending audit previousVersion')
|
|
644
|
+
);
|
|
645
|
+
}
|
|
646
|
+
} else {
|
|
647
|
+
ENTRY_DATAVIEW.setFloat64(start, previousVersion);
|
|
648
|
+
if (ENTRY_HEADER[start] !== PREVIOUS_VERSION_FIRST_BYTE) {
|
|
649
|
+
throw new Error(
|
|
650
|
+
`Audit entry previousVersion ${previousVersion} for record ${recordId} in table ${tableId} is not representable. ` +
|
|
651
|
+
'The LMDB audit format signals this field with its own leading 0x42 byte, so only values in [2**33, 2**49) can be written; ' +
|
|
652
|
+
'writing any other value produces an entry every reader parses 8 bytes off.'
|
|
653
|
+
);
|
|
654
|
+
}
|
|
655
|
+
hasPreviousVersion = true;
|
|
447
656
|
}
|
|
657
|
+
let position = start + (hasPreviousVersion ? 9 : 1);
|
|
448
658
|
if (extendedType) {
|
|
449
659
|
if (extendedType & 0xff) {
|
|
450
660
|
throw new Error('Illegal extended type');
|
|
@@ -483,8 +693,9 @@ export function createAuditEntry(auditRecord: AuditRecord, start = 0) {
|
|
|
483
693
|
|
|
484
694
|
if (user) writeValue(user);
|
|
485
695
|
else ENTRY_HEADER[position++] = 0;
|
|
486
|
-
|
|
487
|
-
|
|
696
|
+
const actionPosition = start + (hasPreviousVersion ? 8 : 0);
|
|
697
|
+
if (extendedType) ENTRY_DATAVIEW.setUint32(actionPosition, action | extendedType | 0xc0000000);
|
|
698
|
+
else ENTRY_HEADER[actionPosition] = action;
|
|
488
699
|
const header = ENTRY_HEADER.subarray(0, position);
|
|
489
700
|
if (encodedRecord) {
|
|
490
701
|
return Buffer.concat([header, encodedRecord]);
|
|
@@ -542,13 +753,40 @@ export function readAuditEntry(buffer: Uint8Array, start = 0, end = undefined):
|
|
|
542
753
|
((buffer as any).decoder = new Decoder(buffer.buffer, buffer.byteOffset, buffer.byteLength));
|
|
543
754
|
decoder.position = start;
|
|
544
755
|
let previousVersion;
|
|
545
|
-
|
|
546
|
-
|
|
756
|
+
let entryStart = start;
|
|
757
|
+
const firstByte = buffer[start];
|
|
758
|
+
if (firstByte === PREVIOUS_VERSION_FIRST_BYTE) {
|
|
547
759
|
previousVersion = decoder.readFloat64();
|
|
760
|
+
} else if (ACTION_FIRST_BYTE[firstByte] !== 1) {
|
|
761
|
+
// Written before the writer enforced the leading-0x42 contract (harper#2247): the field is
|
|
762
|
+
// physically here but does not announce itself, so the action sits 8 bytes further on.
|
|
763
|
+
// Recover only when the bytes cannot be anything else, and never for the RocksDB container,
|
|
764
|
+
// whose prelude flag already consumed its previousVersion before this offset.
|
|
765
|
+
if (start !== 0 || start + 9 > buffer.byteLength || ACTION_FIRST_BYTE[buffer[start + 8]] !== 1) {
|
|
766
|
+
return corruptEntry(buffer, start, end, firstByte);
|
|
767
|
+
}
|
|
768
|
+
// > 1 is exactly what the superseded writer's own guard could emit, the tightest available
|
|
769
|
+
// bound on "these bytes really are an old previousVersion"
|
|
770
|
+
if (!(decoder.getFloat64(start) > 1)) return corruptEntry(buffer, start, end, firstByte);
|
|
771
|
+
entryStart = decoder.position = start + 8;
|
|
772
|
+
// The value itself is dropped, not reported. It cannot lead with 0x42 (that is the branch
|
|
773
|
+
// above), and audit keys carry the same constraint, so it could never have addressed a
|
|
774
|
+
// retrievable entry; reporting it would only feed an unrepresentable value back to
|
|
775
|
+
// createAuditEntry through the resolveRecord re-mint in RecordEncoder, which now rejects it.
|
|
548
776
|
}
|
|
549
777
|
const action = decoder.readInt();
|
|
778
|
+
if (entryStart !== start && !isDecodableAction(action)) {
|
|
779
|
+
return corruptEntry(buffer, start, end, firstByte);
|
|
780
|
+
}
|
|
550
781
|
const nodeId = decoder.readInt();
|
|
551
782
|
const tableId = decoder.readInt();
|
|
783
|
+
if (entryStart !== start && !warnedRecoveredTables.has(tableId)) {
|
|
784
|
+
warnedRecoveredTables.add(tableId);
|
|
785
|
+
warnContained('Audit entry carries an unannounced previousVersion field; recovering its field offsets', {
|
|
786
|
+
tableId,
|
|
787
|
+
firstByte,
|
|
788
|
+
});
|
|
789
|
+
}
|
|
552
790
|
let length = decoder.readInt();
|
|
553
791
|
// A corrupt length field (e.g., a 0xff-prefixed uint32) would otherwise push
|
|
554
792
|
// decoder.position hundreds of megabytes past the buffer; the next readFloat64
|
|
@@ -621,7 +859,6 @@ export function readAuditEntry(buffer: Uint8Array, start = 0, end = undefined):
|
|
|
621
859
|
return buffer.subarray(recordIdStart, recordIdEnd);
|
|
622
860
|
},
|
|
623
861
|
version,
|
|
624
|
-
recordVersion: version,
|
|
625
862
|
previousVersion,
|
|
626
863
|
get user() {
|
|
627
864
|
try {
|
|
@@ -634,10 +871,14 @@ export function readAuditEntry(buffer: Uint8Array, start = 0, end = undefined):
|
|
|
634
871
|
}
|
|
635
872
|
},
|
|
636
873
|
get encoded() {
|
|
637
|
-
|
|
874
|
+
// On a recovered entry this drops the unannounced prefix, so a replication sender —
|
|
875
|
+
// which strips by the same leading-0x42 test and frames by encoded.length — forwards a
|
|
876
|
+
// clean entry instead of passing the same misparse to the next hop.
|
|
877
|
+
return entryStart ? buffer.subarray(entryStart, end) : buffer;
|
|
638
878
|
},
|
|
639
879
|
get size() {
|
|
640
|
-
|
|
880
|
+
// only the recovered prefix is discounted; every other case keeps its existing basis
|
|
881
|
+
return (end !== undefined ? end - start : buffer.byteLength) - (entryStart - start);
|
|
641
882
|
},
|
|
642
883
|
getValue(store, fullRecord?, auditTime?) {
|
|
643
884
|
if (action & HAS_RECORD || (action & HAS_PARTIAL_RECORD && !fullRecord)) {
|
|
@@ -686,6 +927,23 @@ export function readAuditEntry(buffer: Uint8Array, start = 0, end = undefined):
|
|
|
686
927
|
}
|
|
687
928
|
}
|
|
688
929
|
|
|
930
|
+
/**
|
|
931
|
+
* Reject a header whose first byte can be neither an action nor a previousVersion field. Returns the
|
|
932
|
+
* sentinel directly rather than throwing into readAuditEntry's catch, whose error log is not
|
|
933
|
+
* contained: a throwing log sink there would escape the decoder and stall the iteration it runs in.
|
|
934
|
+
*/
|
|
935
|
+
function corruptEntry(buffer: Uint8Array, start: number, end: number | undefined, firstByte: number): AuditRecord {
|
|
936
|
+
if (!warnedUndecodableHeader) {
|
|
937
|
+
warnedUndecodableHeader = true;
|
|
938
|
+
warnContained('Audit entry header begins with neither an action nor a previousVersion; treating as corrupt', {
|
|
939
|
+
firstByte,
|
|
940
|
+
// the 8 prefix bytes plus the action byte: the classifying bytes, stopping before the recordId
|
|
941
|
+
header: Buffer.from(buffer.subarray(start, Math.min(start + 9, buffer.byteLength))).toString('hex'),
|
|
942
|
+
});
|
|
943
|
+
}
|
|
944
|
+
return createCorruptAuditSentinel(buffer, start, end);
|
|
945
|
+
}
|
|
946
|
+
|
|
689
947
|
/**
|
|
690
948
|
* Build a structurally complete audit record for an entry that failed to decode. The fields
|
|
691
949
|
* mirror the happy-path shape so downstream consumers that access (e.g.) `getValue` or the
|