@ductape/sdk 0.1.153 → 0.1.155

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/api/services/productsApi.service.d.ts +31 -0
  2. package/dist/api/services/productsApi.service.js +14 -0
  3. package/dist/api/services/productsApi.service.js.map +1 -1
  4. package/dist/api/urls.d.ts +1 -0
  5. package/dist/api/urls.js +5 -4
  6. package/dist/api/urls.js.map +1 -1
  7. package/dist/database/actions/output-contract.d.ts +46 -0
  8. package/dist/database/actions/output-contract.js +139 -0
  9. package/dist/database/actions/output-contract.js.map +1 -0
  10. package/dist/database/databases.service.d.ts +2 -2
  11. package/dist/database/databases.service.js.map +1 -1
  12. package/dist/database/index.d.ts +3 -1
  13. package/dist/database/index.js +5 -2
  14. package/dist/database/index.js.map +1 -1
  15. package/dist/database/types/action.interface.d.ts +26 -5
  16. package/dist/features/feature-executor.js +9 -0
  17. package/dist/features/feature-executor.js.map +1 -1
  18. package/dist/features/features.service.js +24 -3
  19. package/dist/features/features.service.js.map +1 -1
  20. package/dist/features/types/features.types.d.ts +29 -5
  21. package/dist/features/types/features.types.js.map +1 -1
  22. package/dist/index.d.ts +42 -1
  23. package/dist/index.js +159 -4
  24. package/dist/index.js.map +1 -1
  25. package/dist/processor/services/processor.service.d.ts +2 -2
  26. package/dist/products/bootstrap-cache.d.ts +8 -0
  27. package/dist/products/bootstrap-cache.js +27 -0
  28. package/dist/products/bootstrap-cache.js.map +1 -1
  29. package/dist/products/services/products.service.d.ts +1 -0
  30. package/dist/products/services/products.service.js +58 -9
  31. package/dist/products/services/products.service.js.map +1 -1
  32. package/dist/tsconfig.tsbuildinfo +1 -1
  33. package/dist/types/index.types.d.ts +9 -0
  34. package/dist/types/index.types.js.map +1 -1
  35. package/dist/types/productsBuilder.types.d.ts +16 -0
  36. package/dist/types/productsBuilder.types.js.map +1 -1
  37. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -232,6 +232,8 @@ export type { PortableJsonSchema, IPortableFunctionContext, IPortableFunctionCon
232
232
  export { AgentsService, AgentError, agentsService } from './agents';
233
233
  export { AgentExecutor, AgentContext, ToolRegistry, MemoryManager, createLLMProvider, AnthropicProvider, OpenAIProvider, VectorServiceAdapter, createVectorStoreAdapter, createPineconeAdapter, createQdrantAdapter, createWeaviateAdapter, createMemoryAdapter, } from './agents';
234
234
  export type { IAgentServiceConfig, IDefineAgentOptions, IDefinedAgent, IRunAgentOptions, IAgentExecutionResult, IDispatchAgentOptions, IDispatchAgentResult, ISendAgentSignalOptions, IAgentStatusOptions, IAgentState, IListAgentExecutionsOptions, IAgentExecutionListResult, IAgentTool, IAgentToolSchema, IToolParam, IToolCallResult, ILLMConfig, LLMProvider, IAgentMemoryConfig, IAgentTerminationConfig, IAgentStreamEvent, IAgentToolContext, IConversationMessage, ITokenUsage, AgentStatus, IHumanInLoopConfig, IApprovalRequest, IApprovalResponse, IMultiAgentWorkflow, MultiAgentMode, } from './agents';
235
+ export { deriveDatabaseActionOutputContract, validateDatabaseActionOutput } from './database';
236
+ export type { IActionResult, IQueryActionResult, IInsertActionResult, IUpdateActionResult, IDeleteActionResult, IRawActionResult, IDatabaseActionSchemaNode, IDatabaseActionOutputContract, IDatabaseActionOutputValidation, IDatabaseTableColumnMetadata, } from './database';
235
237
  export { StorageService, StorageError } from './storage';
236
238
  export { uploadBlobToCloud, downloadBlobFromCloud, deleteBlobFromCloud, listBlobsInCloud, generateSignedUrl, } from './storage';
237
239
  export type { IStorageServiceConfig, IUploadOptions, IDownloadOptions, IDeleteOptions, IListFilesOptions, ISignedUrlOptions, IStorageResult, IDownloadResult, IDeleteResult as IStorageDeleteResult, IListFilesResult, ISignedUrlResult, IStorageDispatchOptions, IStorageDispatchResult, IStorageProviderConfig, IStorageFileInfo, } from './storage';
@@ -307,6 +309,17 @@ export default class Ductape implements IDuctape {
307
309
  private jobsQueue;
308
310
  private healthCheckQueue;
309
311
  private healthCheckUpdaterQueue;
312
+ private runtimeSyncEnabled;
313
+ private runtimePollIntervalMs;
314
+ private runtimePollJitter;
315
+ private runtimeMaxBackoffMs;
316
+ private runtimeManifest?;
317
+ private runtimeLastRefreshAt?;
318
+ private runtimeLastError?;
319
+ private runtimePollTimer?;
320
+ private runtimeRefreshInFlight?;
321
+ private authInFlight?;
322
+ private runtimeClosed;
310
323
  /** Register and inspect portable application functions used by Feature JSON. */
311
324
  functions: {
312
325
  register: <T extends IPortableFunctionContract>(contract: T) => import("./features").PortableFunctionClient<T>;
@@ -333,7 +346,7 @@ export default class Ductape implements IDuctape {
333
346
  * This is separate from monitor() which sets up job queues
334
347
  */
335
348
  private connectCacheRedis;
336
- constructor({ accessKey, redis_url, product, env, local, ip_address, language }: IDuctapeInit);
349
+ constructor({ accessKey, redis_url, product, env, local, ip_address, language, runtime_sync }: IDuctapeInit);
337
350
  private loadBullMQ;
338
351
  /**
339
352
  * Connects to Redis and initializes job and health check queues and workers.
@@ -4326,6 +4339,34 @@ export default class Ductape implements IDuctape {
4326
4339
  publish: () => Promise<void>;
4327
4340
  };
4328
4341
  private initUserAuth;
4342
+ private performUserAuth;
4343
+ private runtimeAuth;
4344
+ private applyRuntimeSnapshot;
4345
+ private scheduleRuntimePoll;
4346
+ private pollRuntimeManifest;
4347
+ private refreshRuntimeSnapshot;
4348
+ /** Force a full product runtime refresh and atomically replace bootstrap cache entries. */
4349
+ ready(): Promise<void>;
4350
+ /** Force a full product runtime refresh and atomically replace bootstrap cache entries. */
4351
+ refreshRuntime(): Promise<void>;
4352
+ /** Observe the local product runtime snapshot without exposing cached configuration or secrets. */
4353
+ runtimeSnapshotStatus(): {
4354
+ enabled: boolean;
4355
+ product: string;
4356
+ env: string;
4357
+ manifest: {
4358
+ runtimeRevision: string;
4359
+ databaseRevision: string;
4360
+ connectionRevision: string;
4361
+ secretRevision: string;
4362
+ assetRevision: string;
4363
+ };
4364
+ lastRefreshAt: number;
4365
+ lastError: string;
4366
+ refreshing: boolean;
4367
+ };
4368
+ /** Stop background synchronization and release SDK-owned background resources. */
4369
+ close(): Promise<void>;
4329
4370
  private createNewLogger;
4330
4371
  /** Shared auth + client context fields for service constructors. */
4331
4372
  private builderInit;
package/dist/index.js CHANGED
@@ -50,9 +50,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
50
50
  return (mod && mod.__esModule) ? mod : { "default": mod };
51
51
  };
52
52
  Object.defineProperty(exports, "__esModule", { value: true });
53
- exports.StorageError = exports.StorageService = exports.createMemoryAdapter = exports.createWeaviateAdapter = exports.createQdrantAdapter = exports.createPineconeAdapter = exports.createVectorStoreAdapter = exports.VectorServiceAdapter = exports.OpenAIProvider = exports.AnthropicProvider = exports.createLLMProvider = exports.MemoryManager = exports.ToolRegistry = exports.AgentContext = exports.AgentExecutor = exports.agentsService = exports.AgentError = exports.AgentsService = exports.verifyInvocationSignature = exports.PORTABLE_FUNCTION_HTTP_PATH = exports.handlePortableFunctionHttpRequest = exports.PortableFunctionError = exports.PortableFunctionsRegistry = exports.portableFunctions = exports.defineFunctions = exports.defineFunction = exports.FeatureExecutor = exports.createFeature = exports.FeatureBuilder = exports.featureService = exports.FeatureCompilationError = exports.FeatureError = exports.FeatureService = exports.GraphAdapterFactory = exports.MemgraphAdapter = exports.ArangoDBAdapter = exports.NeptuneAdapter = exports.Neo4jAdapter = exports.BaseGraphAdapter = exports.GraphError = exports.GraphSortOrder = exports.GraphFeature = exports.GraphErrorType = exports.GraphTransactionStatus = exports.GraphIsolationLevel = exports.NodeConstraintType = exports.NodeIndexType = exports.TraversalDirection = exports.GraphType = exports.GraphService = void 0;
54
- exports.containsSecretReferences = exports.isSecretReference = exports.SecretResolutionError = exports.SecretRevokedError = exports.SecretExpiredError = exports.SecretEnvironmentError = exports.SecretScopeError = exports.SecretNotFoundError = exports.SECRET_PATTERN_GLOBAL = exports.SECRET_PATTERN = exports.SecretsService = exports.VectorFeature = exports.VectorErrorType = exports.VectorIndexType = exports.DistanceMetric = exports.VectorDBType = exports.MemoryAdapter = exports.WeaviateAdapter = exports.QdrantAdapter = exports.PineconeAdapter = exports.BaseVectorAdapter = exports.VectorError = exports.VectorDatabaseService = exports.SmsProvider = exports.PushNotificationProvider = exports.NotificationChannelType = exports.notificationsService = exports.NotificationsService = exports.getSqsQueueUrl = exports.isValidSqsUrl = exports.parseEventString = exports.loadBrokerService = exports.GooglePubSubService = exports.RedisService = exports.SQSService = exports.KafkaService = exports.RabbitMQService = exports.BrokerError = exports.BrokersService = exports.CacheLogger = exports.cacheLogger = exports.CacheError = exports.CacheService = exports.SessionError = exports.SessionsService = exports.generateSignedUrl = exports.listBlobsInCloud = exports.deleteBlobFromCloud = exports.downloadBlobFromCloud = exports.uploadBlobToCloud = void 0;
55
- exports.getAssetSchemas = exports.buildVpcConnectorRelayWebSocketUrl = exports.parseTcpEndpointFromUrl = exports.buildVpcConnectorTunnelAdapterOptions = exports.openVpcConnectorTunnelStream = exports.resolveCloudLinkedEnvConfig = exports.resolveCloudLinkedConfig = exports.CloudError = exports.CloudService = exports.mightContainSecrets = exports.findAllSecretReferences = exports.extractSecretKeys = void 0;
53
+ exports.validateDatabaseActionOutput = exports.deriveDatabaseActionOutputContract = exports.createMemoryAdapter = exports.createWeaviateAdapter = exports.createQdrantAdapter = exports.createPineconeAdapter = exports.createVectorStoreAdapter = exports.VectorServiceAdapter = exports.OpenAIProvider = exports.AnthropicProvider = exports.createLLMProvider = exports.MemoryManager = exports.ToolRegistry = exports.AgentContext = exports.AgentExecutor = exports.agentsService = exports.AgentError = exports.AgentsService = exports.verifyInvocationSignature = exports.PORTABLE_FUNCTION_HTTP_PATH = exports.handlePortableFunctionHttpRequest = exports.PortableFunctionError = exports.PortableFunctionsRegistry = exports.portableFunctions = exports.defineFunctions = exports.defineFunction = exports.FeatureExecutor = exports.createFeature = exports.FeatureBuilder = exports.featureService = exports.FeatureCompilationError = exports.FeatureError = exports.FeatureService = exports.GraphAdapterFactory = exports.MemgraphAdapter = exports.ArangoDBAdapter = exports.NeptuneAdapter = exports.Neo4jAdapter = exports.BaseGraphAdapter = exports.GraphError = exports.GraphSortOrder = exports.GraphFeature = exports.GraphErrorType = exports.GraphTransactionStatus = exports.GraphIsolationLevel = exports.NodeConstraintType = exports.NodeIndexType = exports.TraversalDirection = exports.GraphType = exports.GraphService = void 0;
54
+ exports.SecretResolutionError = exports.SecretRevokedError = exports.SecretExpiredError = exports.SecretEnvironmentError = exports.SecretScopeError = exports.SecretNotFoundError = exports.SECRET_PATTERN_GLOBAL = exports.SECRET_PATTERN = exports.SecretsService = exports.VectorFeature = exports.VectorErrorType = exports.VectorIndexType = exports.DistanceMetric = exports.VectorDBType = exports.MemoryAdapter = exports.WeaviateAdapter = exports.QdrantAdapter = exports.PineconeAdapter = exports.BaseVectorAdapter = exports.VectorError = exports.VectorDatabaseService = exports.SmsProvider = exports.PushNotificationProvider = exports.NotificationChannelType = exports.notificationsService = exports.NotificationsService = exports.getSqsQueueUrl = exports.isValidSqsUrl = exports.parseEventString = exports.loadBrokerService = exports.GooglePubSubService = exports.RedisService = exports.SQSService = exports.KafkaService = exports.RabbitMQService = exports.BrokerError = exports.BrokersService = exports.CacheLogger = exports.cacheLogger = exports.CacheError = exports.CacheService = exports.SessionError = exports.SessionsService = exports.generateSignedUrl = exports.listBlobsInCloud = exports.deleteBlobFromCloud = exports.downloadBlobFromCloud = exports.uploadBlobToCloud = exports.StorageError = exports.StorageService = void 0;
55
+ exports.getAssetSchemas = exports.buildVpcConnectorRelayWebSocketUrl = exports.parseTcpEndpointFromUrl = exports.buildVpcConnectorTunnelAdapterOptions = exports.openVpcConnectorTunnelStream = exports.resolveCloudLinkedEnvConfig = exports.resolveCloudLinkedConfig = exports.CloudError = exports.CloudService = exports.mightContainSecrets = exports.findAllSecretReferences = exports.extractSecretKeys = exports.containsSecretReferences = exports.isSecretReference = void 0;
56
56
  const appApi_service_1 = require("./api/services/appApi.service");
57
57
  const userApi_service_1 = require("./api/services/userApi.service");
58
58
  const workspaceApi_service_1 = require("./api/services/workspaceApi.service");
@@ -66,6 +66,7 @@ const runtime_defaults_1 = require("./runtime/runtime-defaults");
66
66
  const healthcheck_cache_key_1 = require("./resilience/healthcheck-cache-key");
67
67
  const enums_1 = require("./types/enums");
68
68
  const productsApi_service_1 = require("./api/services/productsApi.service");
69
+ const bootstrap_cache_1 = require("./products/bootstrap-cache");
69
70
  const imports_service_1 = __importDefault(require("./imports/imports.service"));
70
71
  const processor_service_1 = __importDefault(require("./processor/services/processor.service"));
71
72
  const logs_service_1 = __importDefault(require("./logs/logs.service"));
@@ -351,6 +352,10 @@ Object.defineProperty(exports, "createPineconeAdapter", { enumerable: true, get:
351
352
  Object.defineProperty(exports, "createQdrantAdapter", { enumerable: true, get: function () { return agents_3.createQdrantAdapter; } });
352
353
  Object.defineProperty(exports, "createWeaviateAdapter", { enumerable: true, get: function () { return agents_3.createWeaviateAdapter; } });
353
354
  Object.defineProperty(exports, "createMemoryAdapter", { enumerable: true, get: function () { return agents_3.createMemoryAdapter; } });
355
+ // Database Action result contracts and static contract utilities.
356
+ var database_2 = require("./database");
357
+ Object.defineProperty(exports, "deriveDatabaseActionOutputContract", { enumerable: true, get: function () { return database_2.deriveDatabaseActionOutputContract; } });
358
+ Object.defineProperty(exports, "validateDatabaseActionOutput", { enumerable: true, get: function () { return database_2.validateDatabaseActionOutput; } });
354
359
  // Re-export Storage module types and classes
355
360
  var storage_2 = require("./storage");
356
361
  Object.defineProperty(exports, "StorageService", { enumerable: true, get: function () { return storage_2.StorageService; } });
@@ -496,7 +501,8 @@ class Ductape {
496
501
  console.warn(`[Ductape] Redis unavailable (${reason}); using in-memory bootstrap cache.`);
497
502
  }
498
503
  }
499
- constructor({ accessKey, redis_url, product, env, local, ip_address, language }) {
504
+ constructor({ accessKey, redis_url, product, env, local, ip_address, language, runtime_sync }) {
505
+ var _a, _b, _c;
500
506
  this.productBuilders = new Map();
501
507
  this.appBuilders = new Map();
502
508
  // Cached service instances (lazily initialized after auth)
@@ -519,6 +525,11 @@ class Ductape {
519
525
  this._brokersService = null;
520
526
  /** Prevent every lazy service factory from retrying a Redis URL that already failed. */
521
527
  this.redisCacheUnavailable = false;
528
+ this.runtimeSyncEnabled = true;
529
+ this.runtimePollIntervalMs = 30000;
530
+ this.runtimePollJitter = 0.2;
531
+ this.runtimeMaxBackoffMs = 300000;
532
+ this.runtimeClosed = false;
522
533
  /** Register and inspect portable application functions used by Feature JSON. */
523
534
  this.functions = {
524
535
  register: (contract) => functions_1.portableFunctions.register(contract),
@@ -5436,8 +5447,20 @@ class Ductape {
5436
5447
  this.workspaceApi = new workspaceApi_service_1.WorkspaceApiService(this.environment);
5437
5448
  this.productsApi = new productsApi_service_1.ProductsApiService(this.environment);
5438
5449
  this.redis_url = redis_url;
5450
+ this.runtimeSyncEnabled = runtime_sync !== false && Boolean(productTag && envSlug);
5451
+ if (runtime_sync && typeof runtime_sync === 'object') {
5452
+ this.runtimePollIntervalMs = Math.max(5000, (_a = runtime_sync.interval_ms) !== null && _a !== void 0 ? _a : 30000);
5453
+ this.runtimePollJitter = Math.max(0, Math.min(1, (_b = runtime_sync.jitter) !== null && _b !== void 0 ? _b : 0.2));
5454
+ this.runtimeMaxBackoffMs = Math.max(this.runtimePollIntervalMs, (_c = runtime_sync.max_backoff_ms) !== null && _c !== void 0 ? _c : 300000);
5455
+ }
5439
5456
  // Services are lazily initialized via factory methods (createNewDatabaseService, etc.)
5440
5457
  // This ensures initUserAuth() is called before service creation
5458
+ if (this.runtimeSyncEnabled) {
5459
+ this.authInFlight = this.performUserAuth(false).finally(() => { this.authInFlight = undefined; });
5460
+ this.authInFlight.catch((error) => {
5461
+ this.runtimeLastError = error instanceof Error ? error.message : String(error);
5462
+ });
5463
+ }
5441
5464
  return this; //createDeepProxy(this, this.environment) as this;
5442
5465
  }
5443
5466
  async loadBullMQ() {
@@ -5705,9 +5728,17 @@ class Ductape {
5705
5728
  return this.api;
5706
5729
  }
5707
5730
  async initUserAuth(subCheck = true) {
5731
+ if (this.authInFlight)
5732
+ return await this.authInFlight;
5733
+ this.authInFlight = this.performUserAuth(subCheck).finally(() => { this.authInFlight = undefined; });
5734
+ return await this.authInFlight;
5735
+ }
5736
+ async performUserAuth(subCheck = true) {
5708
5737
  var _a, _b;
5709
5738
  // Skip if already authenticated with valid credentials
5710
5739
  if (this.token && this.public_key) {
5740
+ if (this.runtimeSyncEnabled && !this.runtimeManifest)
5741
+ await this.refreshRuntimeSnapshot(true);
5711
5742
  return;
5712
5743
  }
5713
5744
  // Only reset if we need to re-authenticate
@@ -5738,6 +5769,15 @@ class Ductape {
5738
5769
  // Don't throw - private key is only needed for secrets encryption
5739
5770
  }
5740
5771
  }
5772
+ if (this.runtimeSyncEnabled && !this.runtimeClosed) {
5773
+ try {
5774
+ await this.refreshRuntimeSnapshot(true);
5775
+ }
5776
+ catch (error) {
5777
+ this.runtimeLastError = error instanceof Error ? error.message : String(error);
5778
+ this.scheduleRuntimePoll(1);
5779
+ }
5780
+ }
5741
5781
  }
5742
5782
  catch (e) {
5743
5783
  const error = ((_b = (_a = e.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.errors) || e.message || 'Unknown error';
@@ -5745,6 +5785,121 @@ class Ductape {
5745
5785
  throw new Error(error);
5746
5786
  }
5747
5787
  }
5788
+ runtimeAuth() {
5789
+ return {
5790
+ token: this.token,
5791
+ public_key: this.public_key,
5792
+ user_id: this.user_id,
5793
+ workspace_id: this.workspace_id,
5794
+ access_key: this.accessKey,
5795
+ };
5796
+ }
5797
+ applyRuntimeSnapshot(response) {
5798
+ if (!(response === null || response === void 0 ? void 0 : response.snapshot))
5799
+ return;
5800
+ const scope = `${this.workspace_id}:${response.snapshot.product_tag}:${response.snapshot.env_slug}`;
5801
+ (0, bootstrap_cache_1.primeRuntimeBootstrapCache)(this.workspace_id, scope, response.snapshot.entries);
5802
+ this.runtimeManifest = response.manifest;
5803
+ this.runtimeLastRefreshAt = Date.now();
5804
+ this.runtimeLastError = undefined;
5805
+ }
5806
+ scheduleRuntimePoll(failureCount = 0) {
5807
+ var _a, _b;
5808
+ if (!this.runtimeSyncEnabled || this.runtimeClosed)
5809
+ return;
5810
+ if (this.runtimePollTimer)
5811
+ clearTimeout(this.runtimePollTimer);
5812
+ const exponential = Math.min(this.runtimeMaxBackoffMs, this.runtimePollIntervalMs * Math.pow(2, failureCount));
5813
+ const jitter = exponential * this.runtimePollJitter * ((Math.random() * 2) - 1);
5814
+ this.runtimePollTimer = setTimeout(() => {
5815
+ this.pollRuntimeManifest(failureCount).catch(() => undefined);
5816
+ }, Math.max(1000, Math.round(exponential + jitter)));
5817
+ (_b = (_a = this.runtimePollTimer).unref) === null || _b === void 0 ? void 0 : _b.call(_a);
5818
+ }
5819
+ async pollRuntimeManifest(failureCount) {
5820
+ var _a, _b;
5821
+ if (!this.defaultProduct || !this.defaultEnv || this.runtimeClosed)
5822
+ return;
5823
+ try {
5824
+ const manifestResponse = await this.productsApi.bootstrapRuntime({
5825
+ product_tag: this.defaultProduct,
5826
+ env_slug: this.defaultEnv,
5827
+ manifest_only: true,
5828
+ etag: (_a = this.runtimeManifest) === null || _a === void 0 ? void 0 : _a.runtimeRevision,
5829
+ }, this.runtimeAuth());
5830
+ if (manifestResponse && manifestResponse.manifest.runtimeRevision !== ((_b = this.runtimeManifest) === null || _b === void 0 ? void 0 : _b.runtimeRevision)) {
5831
+ await this.refreshRuntimeSnapshot(true);
5832
+ }
5833
+ else if (this.defaultProduct && this.defaultEnv) {
5834
+ (0, bootstrap_cache_1.touchRuntimeBootstrapCache)(`${this.workspace_id}:${this.defaultProduct}:${this.defaultEnv}`);
5835
+ }
5836
+ this.runtimeLastError = undefined;
5837
+ this.scheduleRuntimePoll(0);
5838
+ }
5839
+ catch (error) {
5840
+ this.runtimeLastError = error instanceof Error ? error.message : String(error);
5841
+ this.scheduleRuntimePoll(Math.min(failureCount + 1, 8));
5842
+ }
5843
+ }
5844
+ async refreshRuntimeSnapshot(force = false) {
5845
+ if (!this.runtimeSyncEnabled || !this.defaultProduct || !this.defaultEnv || this.runtimeClosed)
5846
+ return;
5847
+ if (this.runtimeRefreshInFlight)
5848
+ return await this.runtimeRefreshInFlight;
5849
+ this.runtimeRefreshInFlight = (async () => {
5850
+ var _a;
5851
+ const response = await this.productsApi.bootstrapRuntime(Object.assign({ product_tag: this.defaultProduct, env_slug: this.defaultEnv }, (force ? {} : { etag: (_a = this.runtimeManifest) === null || _a === void 0 ? void 0 : _a.runtimeRevision })), this.runtimeAuth());
5852
+ if (response)
5853
+ this.applyRuntimeSnapshot(response);
5854
+ this.scheduleRuntimePoll(0);
5855
+ })().finally(() => { this.runtimeRefreshInFlight = undefined; });
5856
+ return await this.runtimeRefreshInFlight;
5857
+ }
5858
+ /** Force a full product runtime refresh and atomically replace bootstrap cache entries. */
5859
+ async ready() {
5860
+ await this.initUserAuth(false);
5861
+ }
5862
+ /** Force a full product runtime refresh and atomically replace bootstrap cache entries. */
5863
+ async refreshRuntime() {
5864
+ await this.initUserAuth(false);
5865
+ await this.refreshRuntimeSnapshot(true);
5866
+ }
5867
+ /** Observe the local product runtime snapshot without exposing cached configuration or secrets. */
5868
+ runtimeSnapshotStatus() {
5869
+ return {
5870
+ enabled: this.runtimeSyncEnabled,
5871
+ product: this.defaultProduct,
5872
+ env: this.defaultEnv,
5873
+ manifest: this.runtimeManifest ? Object.assign({}, this.runtimeManifest) : undefined,
5874
+ lastRefreshAt: this.runtimeLastRefreshAt,
5875
+ lastError: this.runtimeLastError,
5876
+ refreshing: Boolean(this.runtimeRefreshInFlight),
5877
+ };
5878
+ }
5879
+ /** Stop background synchronization and release SDK-owned background resources. */
5880
+ async close() {
5881
+ var _a;
5882
+ this.runtimeClosed = true;
5883
+ if (this.runtimePollTimer)
5884
+ clearTimeout(this.runtimePollTimer);
5885
+ this.runtimePollTimer = undefined;
5886
+ await ((_a = this.runtimeRefreshInFlight) === null || _a === void 0 ? void 0 : _a.catch(() => undefined));
5887
+ const resources = [this.jobsWorker, this.healthCheckWorker, this.healthCheckUpdaterWorker,
5888
+ this.jobsQueue, this.healthCheckQueue, this.healthCheckUpdaterQueue];
5889
+ await Promise.all(resources.filter(Boolean).map((resource) => { var _a; return Promise.resolve((_a = resource.close) === null || _a === void 0 ? void 0 : _a.call(resource)).catch(() => undefined); }));
5890
+ if (this.redisClient) {
5891
+ try {
5892
+ await this.redisClient.quit();
5893
+ }
5894
+ catch (_b) {
5895
+ try {
5896
+ this.redisClient.disconnect(false);
5897
+ }
5898
+ catch ( /* best effort */_c) { /* best effort */ }
5899
+ }
5900
+ this.redisClient = undefined;
5901
+ }
5902
+ }
5748
5903
  createNewLogger(product_id, app_id) {
5749
5904
  return new logs_service_1.default(Object.assign(Object.assign({}, this.builderInit()), { product_id,
5750
5905
  app_id }));