@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/defineTable.ts
CHANGED
|
@@ -27,6 +27,8 @@
|
|
|
27
27
|
|
|
28
28
|
import { table, type Table } from './databases.ts';
|
|
29
29
|
import { attributeToFragment } from './jsonSchemaTypes.ts';
|
|
30
|
+
import type { RecordLockOptions } from './recordLock.ts';
|
|
31
|
+
import type { WritableRecord } from './ResourceInterface.ts';
|
|
30
32
|
|
|
31
33
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
32
34
|
// Field model — phantom-typed Field. Flags are set via GETTER PROPERTIES (no call):
|
|
@@ -235,6 +237,7 @@ interface TypedVerbs<S extends Shape> {
|
|
|
235
237
|
post(record: InsertOf<S>, context?: any): MaybePromise<unknown>;
|
|
236
238
|
patch(id: IdOf<S>, changes: PatchOf<S>, context?: any): MaybePromise<unknown>;
|
|
237
239
|
update(id: IdOf<S>, updates?: PatchOf<S>, context?: any): MaybePromise<InstanceOf<S>>;
|
|
240
|
+
lock(id: IdOf<S>, options?: RecordLockOptions, context?: any): Promise<WritableRecord<InstanceOf<S>>>;
|
|
238
241
|
delete(id: IdOf<S>, context?: any): MaybePromise<unknown>;
|
|
239
242
|
search(query?: any, context?: any): AsyncIterable<ReadVariant<S>>;
|
|
240
243
|
query(query?: any, context?: any): AsyncIterable<ReadVariant<S>>;
|
|
@@ -248,7 +251,7 @@ interface TypedVerbs<S extends Shape> {
|
|
|
248
251
|
*/
|
|
249
252
|
export type TableHandle<S extends Shape = Shape> = Omit<
|
|
250
253
|
Table,
|
|
251
|
-
'get' | 'put' | 'post' | 'patch' | 'update' | 'delete' | 'search' | 'query'
|
|
254
|
+
'get' | 'put' | 'post' | 'patch' | 'update' | 'lock' | 'delete' | 'search' | 'query'
|
|
252
255
|
> &
|
|
253
256
|
TypedVerbs<S> & {
|
|
254
257
|
// phantom projection carriers — discovery surface, zero runtime cost
|
|
@@ -400,8 +403,21 @@ function compileTypeDef(name: string, shape: Shape, options: DefineTableOptions)
|
|
|
400
403
|
* index changes) through the same evolution path GraphQL reloads take.
|
|
401
404
|
*/
|
|
402
405
|
export function defineTable<S extends Shape>(name: string, shape: S, options: DefineTableOptions = {}): TableHandle<S> {
|
|
406
|
+
return defineTableUsing(table, name, shape, options);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* `defineTable` through a specific table factory: the one a branched application's scope hands out
|
|
411
|
+
* (`scopedTableFactory`), so the table lands in its branch. Internal -- the public entry is `defineTable`.
|
|
412
|
+
*/
|
|
413
|
+
export function defineTableUsing<S extends Shape>(
|
|
414
|
+
tableFactory: typeof table,
|
|
415
|
+
name: string,
|
|
416
|
+
shape: S,
|
|
417
|
+
options: DefineTableOptions = {}
|
|
418
|
+
): TableHandle<S> {
|
|
403
419
|
const typeDef = compileTypeDef(name, shape, options);
|
|
404
|
-
const tableClass =
|
|
420
|
+
const tableClass = tableFactory(typeDef);
|
|
405
421
|
typeDef.tableClass = tableClass;
|
|
406
422
|
return tableClass as TableHandle<S>;
|
|
407
423
|
}
|
package/resources/graphql.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { dirname } from 'path';
|
|
2
2
|
import { Script } from 'node:vm';
|
|
3
|
-
import { table } from './databases.ts';
|
|
3
|
+
import { scopedTableFactory, table } from './databases.ts';
|
|
4
4
|
import { getWorkerIndex } from '../server/threads/manageThreads.js';
|
|
5
5
|
import { Resources } from './Resources.ts';
|
|
6
6
|
import type { NamedTypeNode, StringValueNode, ValueNode } from 'graphql';
|
|
7
|
-
import { once } from 'node:events';
|
|
8
7
|
import { ClientError } from '../utility/errors/hdbError.ts';
|
|
9
8
|
import { attributeToFragment, type JsonSchemaFragment } from './jsonSchemaTypes.ts';
|
|
10
9
|
import harperLogger from '../utility/logging/harper_logger.ts';
|
|
@@ -63,7 +62,7 @@ server.knownGraphQLDirectives.push(
|
|
|
63
62
|
*/
|
|
64
63
|
export function handleApplication(scope: import('../components/Scope.ts').Scope) {
|
|
65
64
|
let initialLoadComplete = false;
|
|
66
|
-
|
|
65
|
+
scope.handleEntry(async (entry) => {
|
|
67
66
|
if (initialLoadComplete) {
|
|
68
67
|
scope.requestRestart();
|
|
69
68
|
return;
|
|
@@ -75,19 +74,56 @@ export function handleApplication(scope: import('../components/Scope.ts').Scope)
|
|
|
75
74
|
return;
|
|
76
75
|
}
|
|
77
76
|
|
|
78
|
-
await processGraphQLSchema(
|
|
77
|
+
await processGraphQLSchema(
|
|
78
|
+
(entry as any).contents,
|
|
79
|
+
entry.urlPath,
|
|
80
|
+
entry.absolutePath,
|
|
81
|
+
scope.resources,
|
|
82
|
+
scopedTableFactory(scope.applicationScope?.branches),
|
|
83
|
+
scope.logger
|
|
84
|
+
);
|
|
79
85
|
});
|
|
80
|
-
|
|
81
|
-
|
|
86
|
+
// Settles with the load's real outcome, so a diagnosed failure is not left for the loader's watchdog
|
|
87
|
+
// to report while it holds the plugin-wide load lock (#1917). The flag advances either way: a schema
|
|
88
|
+
// corrected afterwards belongs on the restart path.
|
|
89
|
+
return scope.waitForInitialLoads().finally(() => {
|
|
82
90
|
initialLoadComplete = true;
|
|
83
91
|
});
|
|
84
|
-
return initialLoadPromise;
|
|
85
92
|
}
|
|
86
93
|
|
|
87
|
-
|
|
94
|
+
function describeLocation(loc: { startToken?: { line: number; column: number } } | undefined) {
|
|
95
|
+
const token = loc?.startToken;
|
|
96
|
+
return token ? `line ${token.line}, column ${token.column}` : 'an unknown location';
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async function processGraphQLSchema(
|
|
100
|
+
gqlContent,
|
|
101
|
+
urlPath,
|
|
102
|
+
filePath,
|
|
103
|
+
resources,
|
|
104
|
+
declareTable: typeof table = table,
|
|
105
|
+
logger: { warn?: (...args: any[]) => void; error?: (...args: any[]) => void } = harperLogger
|
|
106
|
+
) {
|
|
88
107
|
// lazy load the graphql package so we don't load it for users that don't use graphql
|
|
89
|
-
const { parse, Source, Kind } = await import('graphql');
|
|
90
|
-
|
|
108
|
+
const { parse, Source, Kind, specifiedDirectives } = await import('graphql');
|
|
109
|
+
let ast;
|
|
110
|
+
try {
|
|
111
|
+
ast = parse(new Source(gqlContent.toString(), filePath));
|
|
112
|
+
} catch (error) {
|
|
113
|
+
// GraphQLError.toString() is the only rendering carrying the source excerpt and caret; `.stack`,
|
|
114
|
+
// which the logger prefers, points at Harper internals. It stays out of the thrown message: a
|
|
115
|
+
// failed component's ErrorResource message becomes the REST problem title.
|
|
116
|
+
logger.error?.(`Invalid GraphQL schema in ${filePath}:\n${error}`);
|
|
117
|
+
throw new Error(`Invalid GraphQL schema${urlPath ? ` at ${urlPath}` : ''}`);
|
|
118
|
+
}
|
|
119
|
+
// Spec-defined and schema-declared directives are not unknown just because Harper ignores them.
|
|
120
|
+
const recognizedDirectives = new Set([
|
|
121
|
+
...server.knownGraphQLDirectives,
|
|
122
|
+
...specifiedDirectives.map((directive) => directive.name),
|
|
123
|
+
]);
|
|
124
|
+
for (const definition of ast.definitions) {
|
|
125
|
+
if (definition.kind === Kind.DIRECTIVE_DEFINITION) recognizedDirectives.add(definition.name.value);
|
|
126
|
+
}
|
|
91
127
|
const types = new Map();
|
|
92
128
|
const tables = [];
|
|
93
129
|
// we begin by iterating through the definitions in the AST to get the types and convert them
|
|
@@ -112,6 +148,7 @@ async function processGraphQLSchema(gqlContent, urlPath, filePath, resources) {
|
|
|
112
148
|
// @table is the canonical schema-defined declaration; pass the flag explicitly so
|
|
113
149
|
// the existing-Table re-assert in databases.ts::table() fires on every reload.
|
|
114
150
|
typeDef.schemaDefined = true;
|
|
151
|
+
typeDef.schemaRelationshipsDefined = true;
|
|
115
152
|
if (typeDef.schema) typeDef.database = typeDef.schema;
|
|
116
153
|
if (!typeDef.table) typeDef.table = typeName;
|
|
117
154
|
if (typeDef.audit) typeDef.audit = typeDef.audit !== 'false';
|
|
@@ -168,7 +205,10 @@ async function processGraphQLSchema(gqlContent, urlPath, filePath, resources) {
|
|
|
168
205
|
for (const directive of field.directives) {
|
|
169
206
|
const directiveName = directive.name.value;
|
|
170
207
|
if (directiveName === 'primaryKey') {
|
|
171
|
-
if (hasPrimaryKey)
|
|
208
|
+
if (hasPrimaryKey)
|
|
209
|
+
logger.warn?.(
|
|
210
|
+
`Can not define two attributes as a primary key, at ${describeLocation(directive.loc)} in ${filePath}`
|
|
211
|
+
);
|
|
172
212
|
else {
|
|
173
213
|
property.isPrimaryKey = true;
|
|
174
214
|
hasPrimaryKey = true;
|
|
@@ -244,8 +284,10 @@ async function processGraphQLSchema(gqlContent, urlPath, filePath, resources) {
|
|
|
244
284
|
authorizedRoles.push((arg.value as StringValueNode).value);
|
|
245
285
|
}
|
|
246
286
|
}
|
|
247
|
-
} else if (
|
|
248
|
-
|
|
287
|
+
} else if (!recognizedDirectives.has(directiveName)) {
|
|
288
|
+
logger.warn?.(
|
|
289
|
+
`@${directiveName} is an unknown field directive, at ${describeLocation(directive.loc)} in ${filePath}`
|
|
290
|
+
);
|
|
249
291
|
}
|
|
250
292
|
}
|
|
251
293
|
// @embed targets a vector column and auto-indexes it with HNSW; resolved after all
|
|
@@ -302,19 +344,31 @@ async function processGraphQLSchema(gqlContent, urlPath, filePath, resources) {
|
|
|
302
344
|
} else if (property.type === 'array') connectPropertyType(property.elements);
|
|
303
345
|
else if (!PRIMITIVE_TYPES.includes(property.type)) {
|
|
304
346
|
if (getWorkerIndex() === 0)
|
|
305
|
-
|
|
347
|
+
logger.error?.(
|
|
306
348
|
`The type ${property.type} is unknown at line ${property.location.line}, column ${property.location.column}, in ${filePath}`
|
|
307
349
|
);
|
|
308
350
|
}
|
|
309
351
|
}
|
|
310
352
|
for (const typeDef of types.values()) {
|
|
311
|
-
for (const property of typeDef.attributes)
|
|
353
|
+
for (const property of typeDef.attributes) {
|
|
354
|
+
connectPropertyType(property);
|
|
355
|
+
const relationshipType = property.definition || property.elements?.definition;
|
|
356
|
+
if (property.relationship && relationshipType?.table) {
|
|
357
|
+
Object.defineProperty(property, 'relationshipReference', {
|
|
358
|
+
value: {
|
|
359
|
+
database: relationshipType.database || 'data',
|
|
360
|
+
table: relationshipType.table,
|
|
361
|
+
},
|
|
362
|
+
configurable: true,
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
}
|
|
312
366
|
}
|
|
313
367
|
// any tables that are defined in the schema can now be registered
|
|
314
368
|
for (const typeDef of tables) {
|
|
315
369
|
// with graphql database definitions, this is a declaration that the table should exist and that it
|
|
316
370
|
// should be created if it does not exist
|
|
317
|
-
typeDef.tableClass =
|
|
371
|
+
typeDef.tableClass = declareTable(typeDef);
|
|
318
372
|
if (getWorkerIndex() === 0) {
|
|
319
373
|
// Post-Phase-2: typeDef.properties is the canonical Record (no .find); read the Array form.
|
|
320
374
|
const pk = (typeDef.attributes as any[])?.find((p) => p.isPrimaryKey)?.name ?? 'id';
|
|
@@ -209,6 +209,10 @@ export class HierarchicalNavigableSmallWorld {
|
|
|
209
209
|
// a value of 1 is extremely aggressive.
|
|
210
210
|
optimizeRouting = 0.5;
|
|
211
211
|
nodesVisitedCount = 0;
|
|
212
|
+
// Test seam: source of randomness for level assignment. Tests that assert exact result-set
|
|
213
|
+
// equality across search strategies replace this with a seeded PRNG so the graph shape is
|
|
214
|
+
// reproducible; greedy routing legitimately diverges on rare unlucky graphs otherwise.
|
|
215
|
+
random: () => number = Math.random;
|
|
212
216
|
// Visit-budget multiplier for predicate-aware traversal (#1241). Under-filled filtered searches
|
|
213
217
|
// stop after the resolved budget ef * filterExpansion visits; automatic search ef contributes at
|
|
214
218
|
// most AUTO_EF_MAX, while explicit schema/query ef remains authoritative. A filter that fills its
|
|
@@ -337,7 +341,7 @@ export class HierarchicalNavigableSmallWorld {
|
|
|
337
341
|
const storedScale = q ? q.scale : undefined;
|
|
338
342
|
let entryPoint = entryPointId && this.safeGetSync(entryPointId, options);
|
|
339
343
|
if (entryPoint == null) {
|
|
340
|
-
const level = Math.floor(-Math.log(
|
|
344
|
+
const level = Math.min(Math.floor(-Math.log(this.random()) * this.mL), MAX_LEVEL);
|
|
341
345
|
const node = {
|
|
342
346
|
vector: storedVector,
|
|
343
347
|
scale: storedScale,
|
|
@@ -358,7 +362,7 @@ export class HierarchicalNavigableSmallWorld {
|
|
|
358
362
|
}
|
|
359
363
|
|
|
360
364
|
// Generate random level for this new element
|
|
361
|
-
const level = oldNode.level ?? Math.min(Math.floor(-Math.log(
|
|
365
|
+
const level = oldNode.level ?? Math.min(Math.floor(-Math.log(this.random()) * this.mL), MAX_LEVEL);
|
|
362
366
|
let currentLevel = entryPoint.level;
|
|
363
367
|
if (level > currentLevel) {
|
|
364
368
|
// if we are at a higher level, make this the new entry point
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
import { isMainThread, threadId } from 'node:worker_threads';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { registryStatus } from '@harperfast/rocksdb-js';
|
|
4
|
+
import { logger } from '../utility/logging/logger.ts';
|
|
5
|
+
import { CONFIG_PARAMS } from '../utility/hdbTerms.ts';
|
|
6
|
+
import * as envMngr from '../utility/environment/environmentManager.ts';
|
|
7
|
+
import { convertToMS, prettyDuration } from '../utility/common_utils.ts';
|
|
8
|
+
|
|
9
|
+
const DEFAULT_REPORT_THRESHOLD_MS = 300000;
|
|
10
|
+
const SWEEP_INTERVAL_MS = 60000;
|
|
11
|
+
// One line per over-age handle would, against a large leak, block the main thread's socket routing
|
|
12
|
+
// for as long as it took to format them. The per-handle backoff below rotates the cap over the whole
|
|
13
|
+
// set across passes, so every holder is still named eventually.
|
|
14
|
+
export const MAX_LONG_LIVED_TRANSACTION_REPORTS_PER_PASS = 10;
|
|
15
|
+
const MAX_HOLDER_CANDIDATES = 3;
|
|
16
|
+
// The sweep prunes against the handles it just enumerated; the attribution map has no such
|
|
17
|
+
// enumeration, so its entries expire instead. Far longer than a sweep interval, so a still-live
|
|
18
|
+
// holder keeps its backoff.
|
|
19
|
+
const ATTRIBUTION_STATE_TTL_MS = 3600000;
|
|
20
|
+
// The prune is O(map) and the monitor calls reportLongLivedHolder once per over-threshold transaction
|
|
21
|
+
// per tick, so pruning per call is O(N^2) in exactly the leak this reporting exists to describe.
|
|
22
|
+
const ATTRIBUTION_PRUNE_INTERVAL_MS = 60000;
|
|
23
|
+
|
|
24
|
+
type RegistryStatusFn = typeof registryStatus;
|
|
25
|
+
let registryStatusFn: RegistryStatusFn | undefined = typeof registryStatus === 'function' ? registryStatus : undefined;
|
|
26
|
+
|
|
27
|
+
// Report state is keyed by database path AND native id: rocksdb-js allocates transaction ids per
|
|
28
|
+
// database descriptor, so two databases routinely both have id 2, and a reopen restarts the counter.
|
|
29
|
+
type ReportState = { nextReportAgeMs: number; lastAgeMs: number; touchedAt: number };
|
|
30
|
+
const sweepReports = new Map<string, ReportState>();
|
|
31
|
+
const attributionReports = new Map<string, ReportState>();
|
|
32
|
+
let sweepTimer: NodeJS.Timeout | undefined;
|
|
33
|
+
let invalidThresholdWarned = false;
|
|
34
|
+
let missingDetailsWarned = false;
|
|
35
|
+
let lastAttributionPruneAt = 0;
|
|
36
|
+
let thresholdInEffectMs = -1;
|
|
37
|
+
|
|
38
|
+
function reportKey(databasePath: string | undefined, nativeId: number, openedAt?: number): string {
|
|
39
|
+
return `${databasePath ?? '?'} ${nativeId}${openedAt == null ? '' : ` ${openedAt}`}`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Record this observation of a handle and return its report state. A shrinking age means the id was
|
|
44
|
+
* reused by a reopened descriptor, so the previous holder's backoff must not suppress the new one.
|
|
45
|
+
*/
|
|
46
|
+
function observeHandle(
|
|
47
|
+
reports: Map<string, ReportState>,
|
|
48
|
+
key: string,
|
|
49
|
+
ageMs: number,
|
|
50
|
+
thresholdMs: number
|
|
51
|
+
): ReportState {
|
|
52
|
+
let state = reports.get(key);
|
|
53
|
+
if (state && ageMs < state.lastAgeMs) state = undefined;
|
|
54
|
+
if (!state) {
|
|
55
|
+
state = { nextReportAgeMs: thresholdMs, lastAgeMs: ageMs, touchedAt: 0 };
|
|
56
|
+
reports.set(key, state);
|
|
57
|
+
}
|
|
58
|
+
state.lastAgeMs = ageMs;
|
|
59
|
+
state.touchedAt = Date.now();
|
|
60
|
+
return state;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Drop the accrued backoff when the configured threshold changes, so a handle already under
|
|
65
|
+
* observation is re-measured against the new one. Without this, `nextReportAgeMs` keeps whatever it
|
|
66
|
+
* was given at first observation: lowering the threshold during an incident would not bring a
|
|
67
|
+
* silent handle's first report forward, and raising it would not quiet one. Reporting each live
|
|
68
|
+
* holder once more at the new threshold is what an operator who just changed it is asking for.
|
|
69
|
+
*/
|
|
70
|
+
function rebaseIfThresholdChanged(thresholdMs: number): void {
|
|
71
|
+
if (thresholdMs === thresholdInEffectMs) return;
|
|
72
|
+
thresholdInEffectMs = thresholdMs;
|
|
73
|
+
sweepReports.clear();
|
|
74
|
+
attributionReports.clear();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Apply a live threshold at the start of every reporting pass, including one that finds no eligible
|
|
79
|
+
* holder. Otherwise a threshold raised above a holder's age leaves its old attribution backoff in
|
|
80
|
+
* place when the threshold is lowered again.
|
|
81
|
+
*/
|
|
82
|
+
export function rebaseLongLivedTransactionReports(thresholdMs: number): void {
|
|
83
|
+
rebaseIfThresholdChanged(thresholdMs);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Push this handle's next report out to twice its current age, so one held for hours produces a
|
|
88
|
+
* handful of lines rather than one per pass. Called only where a line was actually emitted: advancing
|
|
89
|
+
* it for a handle the per-pass cap skipped would silence that handle without ever naming it.
|
|
90
|
+
*/
|
|
91
|
+
function markReported(state: ReportState, ageMs: number): void {
|
|
92
|
+
state.nextReportAgeMs = ageMs * 2;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* How old a native transaction handle must be before it is reported, in ms; 0 disables every surface
|
|
97
|
+
* here. Read per pass rather than cached so a live config reload takes effect. A value that cannot
|
|
98
|
+
* be a duration falls back to the default instead of silently disabling reporting.
|
|
99
|
+
*/
|
|
100
|
+
export function getReportThresholdMs(): number {
|
|
101
|
+
const configured = envMngr.get(CONFIG_PARAMS.STORAGE_LONGTRANSACTIONREPORTTHRESHOLD);
|
|
102
|
+
if (configured == null) return DEFAULT_REPORT_THRESHOLD_MS;
|
|
103
|
+
// convertToMS returns 0 for anything that is neither string nor number, which YAML hands us for
|
|
104
|
+
// `yes`/`no` (booleans) and for an object left by a config merge — indistinguishable from the
|
|
105
|
+
// documented 0 that disables reporting, so it would silently switch off what the operator configured.
|
|
106
|
+
const ms = typeof configured === 'string' || typeof configured === 'number' ? convertToMS(configured) : NaN;
|
|
107
|
+
if (ms === 0) return 0;
|
|
108
|
+
if (!Number.isFinite(ms) || ms < 0) {
|
|
109
|
+
if (!invalidThresholdWarned) {
|
|
110
|
+
invalidThresholdWarned = true;
|
|
111
|
+
logger.warn?.(
|
|
112
|
+
`Invalid storage.longTransactionReportThreshold "${configured}"; using default ${DEFAULT_REPORT_THRESHOLD_MS}ms`
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
return DEFAULT_REPORT_THRESHOLD_MS;
|
|
116
|
+
}
|
|
117
|
+
return ms;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Report every native transaction handle in the process-global rocksdb-js registry that has been open
|
|
122
|
+
* past the threshold — including handles no `DatabaseTransaction` owns, which is the one class of
|
|
123
|
+
* holder no other surface can see (harper#2471). The registry spans worker threads, so this runs on
|
|
124
|
+
* the main thread only; a per-thread sweep would report each handle once per worker.
|
|
125
|
+
*/
|
|
126
|
+
export function runLongLivedTransactionSweep(): void {
|
|
127
|
+
try {
|
|
128
|
+
const thresholdMs = getReportThresholdMs();
|
|
129
|
+
rebaseLongLivedTransactionReports(thresholdMs);
|
|
130
|
+
if (thresholdMs === 0 || !registryStatusFn) return;
|
|
131
|
+
const status = registryStatusFn();
|
|
132
|
+
const seen = new Set<string>();
|
|
133
|
+
const due: { path: string | undefined; id: number; ageMs: number; state: ReportState }[] = [];
|
|
134
|
+
let missingDetails = false;
|
|
135
|
+
for (const database of status) {
|
|
136
|
+
const details = database.transactionDetails;
|
|
137
|
+
if (!details) {
|
|
138
|
+
missingDetails = true;
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
for (const handle of details) {
|
|
142
|
+
if (handle.ageMs < thresholdMs) continue;
|
|
143
|
+
const key = reportKey(database.path, handle.id);
|
|
144
|
+
seen.add(key);
|
|
145
|
+
const state = observeHandle(sweepReports, key, handle.ageMs, thresholdMs);
|
|
146
|
+
if (handle.ageMs >= state.nextReportAgeMs)
|
|
147
|
+
due.push({ path: database.path, id: handle.id, ageMs: handle.ageMs, state });
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
for (const key of sweepReports.keys()) if (!seen.has(key)) sweepReports.delete(key);
|
|
151
|
+
if (missingDetails && !missingDetailsWarned) {
|
|
152
|
+
missingDetailsWarned = true;
|
|
153
|
+
logger.warn?.(
|
|
154
|
+
'Long-lived transaction reporting is degraded: the installed @harperfast/rocksdb-js does not expose registryStatus().transactionDetails (requires 2.8.0)'
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
if (due.length === 0) return;
|
|
158
|
+
due.sort((a, b) => b.ageMs - a.ageMs);
|
|
159
|
+
for (const handle of due.slice(0, MAX_LONG_LIVED_TRANSACTION_REPORTS_PER_PASS)) {
|
|
160
|
+
markReported(handle.state, handle.ageMs);
|
|
161
|
+
logger.warn?.(
|
|
162
|
+
`Long-lived RocksDB transaction handle: id ${handle.id} has been open for ${prettyDuration(handle.ageMs)} on database ${handle.path ?? '?'}. ` +
|
|
163
|
+
`A handle this old can hold write intents that park other writers' commits, and may pin a read snapshot that blocks version reclamation.`
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
if (due.length > MAX_LONG_LIVED_TRANSACTION_REPORTS_PER_PASS) {
|
|
167
|
+
logger.warn?.(
|
|
168
|
+
`${due.length - MAX_LONG_LIVED_TRANSACTION_REPORTS_PER_PASS} further RocksDB transaction handle(s) are open past the ${prettyDuration(thresholdMs)} reporting threshold and were not listed individually.`
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
} catch (error) {
|
|
172
|
+
logger.error?.('Error sweeping for long-lived transaction handles', error);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Start the periodic sweep. Armed unconditionally on the main thread — the pass itself honors a live
|
|
178
|
+
* threshold change, including one that disables it — and idempotent because the thread startup path
|
|
179
|
+
* that calls it can run more than once.
|
|
180
|
+
*/
|
|
181
|
+
export function startLongLivedTransactionReporting(): void {
|
|
182
|
+
if (!isMainThread || sweepTimer) return;
|
|
183
|
+
if (!registryStatusFn) {
|
|
184
|
+
logger.debug?.('Long-lived transaction reporting unavailable; @harperfast/rocksdb-js exposes no registryStatus()');
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
sweepTimer = setInterval(runLongLivedTransactionSweep, SWEEP_INTERVAL_MS).unref();
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export type LongLivedHolder = {
|
|
191
|
+
databasePath: string | undefined;
|
|
192
|
+
nativeId: number;
|
|
193
|
+
openedAt: number;
|
|
194
|
+
ageMs: number;
|
|
195
|
+
databaseName?: string;
|
|
196
|
+
tableName?: string;
|
|
197
|
+
// A thunk, not a number: the caller's count walks the whole staged write set, and the backoff below
|
|
198
|
+
// suppresses most ticks — the #2471 shape is a transaction holding a large write set for hours, so
|
|
199
|
+
// paying for that walk on every suppressed tick is the one cost this reporting must not add.
|
|
200
|
+
countPendingWrites: () => number;
|
|
201
|
+
states: string[];
|
|
202
|
+
timeoutBudget?: number;
|
|
203
|
+
startedFrom?: { resourceName: string; method: string };
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
export type LongLivedHolderReportBudget = {
|
|
207
|
+
remaining: number;
|
|
208
|
+
skipped: number;
|
|
209
|
+
thresholdMs: number;
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
export function createLongLivedHolderReportBudget(thresholdMs: number): LongLivedHolderReportBudget {
|
|
213
|
+
return { remaining: MAX_LONG_LIVED_TRANSACTION_REPORTS_PER_PASS, skipped: 0, thresholdMs };
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export function finishLongLivedHolderReports(reportBudget: LongLivedHolderReportBudget): void {
|
|
217
|
+
if (reportBudget.skipped === 0) return;
|
|
218
|
+
try {
|
|
219
|
+
logger.warn?.(
|
|
220
|
+
`${reportBudget.skipped} further Harper transaction holder(s) are open past the ${prettyDuration(reportBudget.thresholdMs)} reporting threshold and were deferred.`
|
|
221
|
+
);
|
|
222
|
+
} catch {}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Report a handle this thread owns, with the attribution the registry sweep cannot supply. The native
|
|
227
|
+
* id is the join key between the two: the sweep names an id, this names who holds it and which state
|
|
228
|
+
* kept the open-transaction monitor from reaping it (harper#2471). Never throws — the monitor
|
|
229
|
+
* interval that calls it has no handler.
|
|
230
|
+
*/
|
|
231
|
+
export function reportLongLivedHolder(holder: LongLivedHolder, reportBudget?: LongLivedHolderReportBudget): void {
|
|
232
|
+
try {
|
|
233
|
+
if (!registryStatusFn) return;
|
|
234
|
+
const thresholdMs = reportBudget?.thresholdMs ?? getReportThresholdMs();
|
|
235
|
+
rebaseLongLivedTransactionReports(thresholdMs);
|
|
236
|
+
if (thresholdMs === 0) return;
|
|
237
|
+
const now = Date.now();
|
|
238
|
+
if (now - lastAttributionPruneAt >= ATTRIBUTION_PRUNE_INTERVAL_MS) {
|
|
239
|
+
lastAttributionPruneAt = now;
|
|
240
|
+
const expiredBefore = now - ATTRIBUTION_STATE_TTL_MS;
|
|
241
|
+
for (const [key, state] of attributionReports)
|
|
242
|
+
if (state.touchedAt < expiredBefore) attributionReports.delete(key);
|
|
243
|
+
}
|
|
244
|
+
const state = observeHandle(
|
|
245
|
+
attributionReports,
|
|
246
|
+
reportKey(holder.databasePath, holder.nativeId, holder.openedAt),
|
|
247
|
+
holder.ageMs,
|
|
248
|
+
thresholdMs
|
|
249
|
+
);
|
|
250
|
+
if (holder.ageMs < state.nextReportAgeMs) return;
|
|
251
|
+
if (reportBudget && reportBudget.remaining <= 0) {
|
|
252
|
+
reportBudget.skipped++;
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
markReported(state, holder.ageMs);
|
|
256
|
+
if (reportBudget) reportBudget.remaining--;
|
|
257
|
+
const table = holder.tableName ? `.${holder.tableName}` : '';
|
|
258
|
+
logger.warn?.(
|
|
259
|
+
`Harper transaction has held RocksDB transaction ${holder.nativeId} for ${prettyDuration(holder.ageMs)} ` +
|
|
260
|
+
`on thread ${threadId}, database ${holder.databaseName ?? '?'}${table} (${holder.databasePath ?? '?'}), ` +
|
|
261
|
+
`holding ${holder.countPendingWrites()} staged write(s), state: ${holder.states.join('+')}` +
|
|
262
|
+
(holder.timeoutBudget ? `, open-transaction budget ${holder.timeoutBudget}ms` : '') +
|
|
263
|
+
(holder.startedFrom?.resourceName
|
|
264
|
+
? `, started from ${holder.startedFrom.resourceName}${holder.startedFrom.method ? '.' + holder.startedFrom.method : ''}`
|
|
265
|
+
: '') +
|
|
266
|
+
'. It is not being reaped by the open-transaction monitor; the state tells you why.'
|
|
267
|
+
);
|
|
268
|
+
} catch (error) {
|
|
269
|
+
logger.debug?.('Failed to report a long-lived transaction holder', error);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* The live handles that could be holding the write intent a stuck commit is parked on, as a sentence
|
|
275
|
+
* to append to that commit's log. A handle on another database is offered too, labelled with its path:
|
|
276
|
+
* the verification table is one process-global slot array whose hash mixes in the database id, so a
|
|
277
|
+
* holder in `system` or `oauth` collides with — and parks — a `data` commit at the same rate two `data`
|
|
278
|
+
* keys do. Rank puts the stuck commit's own database first, then age. Age only ranks: a coordinated
|
|
279
|
+
* retry parks on whichever transaction holds the slot when the commit reaches it, which can be younger
|
|
280
|
+
* than the commit itself, so filtering by age could drop the real holder.
|
|
281
|
+
* Returns '' rather than throwing — the caller's own 503 must survive a failure here.
|
|
282
|
+
*/
|
|
283
|
+
export function describeHolderCandidates(
|
|
284
|
+
databasePath: string | undefined,
|
|
285
|
+
excludeNativeId: number | undefined
|
|
286
|
+
): string {
|
|
287
|
+
if (!databasePath || !registryStatusFn) return '';
|
|
288
|
+
try {
|
|
289
|
+
if (getReportThresholdMs() === 0) return '';
|
|
290
|
+
const target = resolve(databasePath);
|
|
291
|
+
const candidates: { id: number; ageMs: number; sameDatabase: boolean; path: string | undefined }[] = [];
|
|
292
|
+
let targetSeen = false;
|
|
293
|
+
let targetHasDetails = false;
|
|
294
|
+
for (const database of registryStatusFn()) {
|
|
295
|
+
// An entry with no path can never be the target, and resolve() would throw on it — which,
|
|
296
|
+
// inside this loop, would drop the candidate list for every database rather than just this one.
|
|
297
|
+
const sameDatabase = database.path != null && resolve(database.path) === target;
|
|
298
|
+
const details = database.transactionDetails;
|
|
299
|
+
if (sameDatabase) {
|
|
300
|
+
targetSeen = true;
|
|
301
|
+
if (details) targetHasDetails = true;
|
|
302
|
+
}
|
|
303
|
+
if (!details) continue;
|
|
304
|
+
for (const handle of details)
|
|
305
|
+
if (!sameDatabase || handle.id !== excludeNativeId)
|
|
306
|
+
candidates.push({ id: handle.id, ageMs: handle.ageMs, sameDatabase, path: database.path });
|
|
307
|
+
}
|
|
308
|
+
if (!targetHasDetails) {
|
|
309
|
+
// A database with no other handles is normal; no entry at all means the join between a store's
|
|
310
|
+
// path and the registry's path has drifted, which is the one worth telling an operator apart.
|
|
311
|
+
logger.debug?.(
|
|
312
|
+
targetSeen
|
|
313
|
+
? `Registry entry for ${target} exposes no transactionDetails; only other databases' handles can be offered as holder candidates for its stuck commit`
|
|
314
|
+
: `No registry entry for ${target}; only other databases' handles can be offered as holder candidates for its stuck commit`
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
if (candidates.length === 0) return '';
|
|
318
|
+
candidates.sort((a, b) => Number(b.sameDatabase) - Number(a.sameDatabase) || b.ageMs - a.ageMs);
|
|
319
|
+
const shortlist = candidates.slice(0, MAX_HOLDER_CANDIDATES);
|
|
320
|
+
// Ranking this database first and then capping can bury the one candidate the cross-database
|
|
321
|
+
// search exists to surface: a busy database routinely has MAX_HOLDER_CANDIDATES handles of its
|
|
322
|
+
// own, so a foreign holder would only ever appear inside the "and N more" count. Give the oldest
|
|
323
|
+
// one the last slot instead.
|
|
324
|
+
if (shortlist.length === MAX_HOLDER_CANDIDATES && shortlist.every((candidate) => candidate.sameDatabase)) {
|
|
325
|
+
const foreign = candidates.find((candidate) => !candidate.sameDatabase);
|
|
326
|
+
if (foreign) shortlist[MAX_HOLDER_CANDIDATES - 1] = foreign;
|
|
327
|
+
}
|
|
328
|
+
const named = shortlist
|
|
329
|
+
.map(
|
|
330
|
+
(candidate) =>
|
|
331
|
+
`${candidate.id} (open ${prettyDuration(candidate.ageMs)}${candidate.sameDatabase ? '' : ` on ${candidate.path ?? '?'}`})`
|
|
332
|
+
)
|
|
333
|
+
.join(', ');
|
|
334
|
+
return (
|
|
335
|
+
` Live transaction handles, any of which could hold the write intent this commit is parked on ` +
|
|
336
|
+
`(the verification table is one process-global slot array, so a handle on another database can hold it), ` +
|
|
337
|
+
`this database first, oldest first: ${named}` +
|
|
338
|
+
(candidates.length > MAX_HOLDER_CANDIDATES ? `, and ${candidates.length - MAX_HOLDER_CANDIDATES} more.` : '.')
|
|
339
|
+
);
|
|
340
|
+
} catch {
|
|
341
|
+
return '';
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
export function setRegistryStatusForTests(fn?: RegistryStatusFn): void {
|
|
346
|
+
registryStatusFn = fn;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
export function resetLongLivedTransactionReportsForTests(): void {
|
|
350
|
+
sweepReports.clear();
|
|
351
|
+
attributionReports.clear();
|
|
352
|
+
invalidThresholdWarned = false;
|
|
353
|
+
missingDetailsWarned = false;
|
|
354
|
+
lastAttributionPruneAt = 0;
|
|
355
|
+
thresholdInEffectMs = -1;
|
|
356
|
+
if (sweepTimer) {
|
|
357
|
+
clearInterval(sweepTimer);
|
|
358
|
+
sweepTimer = undefined;
|
|
359
|
+
}
|
|
360
|
+
}
|