@ductape/sdk 0.2.3 → 0.2.6

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 (31) hide show
  1. package/dist/apps/utils/input-resolver.d.ts +2 -0
  2. package/dist/apps/utils/input-resolver.js +25 -2
  3. package/dist/apps/utils/input-resolver.js.map +1 -1
  4. package/dist/database/databases.service.js +15 -2
  5. package/dist/database/databases.service.js.map +1 -1
  6. package/dist/imports/imports.types.d.ts +4 -0
  7. package/dist/imports/imports.types.js.map +1 -1
  8. package/dist/imports/repos/postmanV21.repo.js +11 -1
  9. package/dist/imports/repos/postmanV21.repo.js.map +1 -1
  10. package/dist/index.d.ts +24 -0
  11. package/dist/index.js +54 -3
  12. package/dist/index.js.map +1 -1
  13. package/dist/inputs/utils/inputs.utils.create.js +7 -5
  14. package/dist/inputs/utils/inputs.utils.create.js.map +1 -1
  15. package/dist/processor/services/processor.service.d.ts +3 -3
  16. package/dist/processor/services/processor.service.js +10 -1
  17. package/dist/processor/services/processor.service.js.map +1 -1
  18. package/dist/processor/utils/processor.utils.d.ts +1 -0
  19. package/dist/processor/utils/processor.utils.js +31 -0
  20. package/dist/processor/utils/processor.utils.js.map +1 -1
  21. package/dist/products/services/products.service.js +16 -9
  22. package/dist/products/services/products.service.js.map +1 -1
  23. package/dist/resilience/fallback.service.d.ts +6 -0
  24. package/dist/resilience/fallback.service.js +31 -1
  25. package/dist/resilience/fallback.service.js.map +1 -1
  26. package/dist/tsconfig.tsbuildinfo +1 -1
  27. package/dist/types/appBuilder.types.d.ts +2 -0
  28. package/dist/types/index.types.d.ts +2 -0
  29. package/dist/types/index.types.js.map +1 -1
  30. package/dist/types/inputs.types.d.ts +1 -1
  31. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -318,6 +318,9 @@ export default class Ductape implements IDuctape {
318
318
  private runtimeLastError?;
319
319
  private runtimePollTimer?;
320
320
  private runtimeRefreshInFlight?;
321
+ private runtimeWarmupEnabled;
322
+ private runtimeWarmupInFlight?;
323
+ private runtimeWarmupState?;
321
324
  private authInFlight?;
322
325
  private runtimeClosed;
323
326
  /** Register and inspect portable application functions used by Feature JSON. */
@@ -4342,6 +4345,7 @@ export default class Ductape implements IDuctape {
4342
4345
  private performUserAuth;
4343
4346
  private runtimeAuth;
4344
4347
  private applyRuntimeSnapshot;
4348
+ private startRuntimeWarmup;
4345
4349
  private scheduleRuntimePoll;
4346
4350
  private pollRuntimeManifest;
4347
4351
  private refreshRuntimeSnapshot;
@@ -4364,6 +4368,26 @@ export default class Ductape implements IDuctape {
4364
4368
  lastRefreshAt: number;
4365
4369
  lastError: string;
4366
4370
  refreshing: boolean;
4371
+ warmup: {
4372
+ databases: {
4373
+ tag: string;
4374
+ status: "ready" | "failed";
4375
+ durationMs: number;
4376
+ error?: string;
4377
+ }[];
4378
+ warming: boolean;
4379
+ startedAt: number;
4380
+ completedAt?: number;
4381
+ durationMs?: number;
4382
+ } | {
4383
+ warming: boolean;
4384
+ databases: Array<{
4385
+ tag: string;
4386
+ status: "ready" | "failed";
4387
+ durationMs: number;
4388
+ error?: string;
4389
+ }>;
4390
+ };
4367
4391
  };
4368
4392
  /** Stop background synchronization and release SDK-owned background resources. */
4369
4393
  close(): Promise<void>;
package/dist/index.js CHANGED
@@ -530,6 +530,7 @@ class Ductape {
530
530
  this.runtimePollIntervalMs = 30000;
531
531
  this.runtimePollJitter = 0.2;
532
532
  this.runtimeMaxBackoffMs = 300000;
533
+ this.runtimeWarmupEnabled = true;
533
534
  this.runtimeClosed = false;
534
535
  /** Register and inspect portable application functions used by Feature JSON. */
535
536
  this.functions = {
@@ -5453,6 +5454,7 @@ class Ductape {
5453
5454
  this.runtimePollIntervalMs = Math.max(5000, (_a = runtime_sync.interval_ms) !== null && _a !== void 0 ? _a : 30000);
5454
5455
  this.runtimePollJitter = Math.max(0, Math.min(1, (_b = runtime_sync.jitter) !== null && _b !== void 0 ? _b : 0.2));
5455
5456
  this.runtimeMaxBackoffMs = Math.max(this.runtimePollIntervalMs, (_c = runtime_sync.max_backoff_ms) !== null && _c !== void 0 ? _c : 300000);
5457
+ this.runtimeWarmupEnabled = runtime_sync.warm_connections !== false;
5456
5458
  }
5457
5459
  // Services are lazily initialized via factory methods (createNewDatabaseService, etc.)
5458
5460
  // This ensures initUserAuth() is called before service creation
@@ -5799,6 +5801,7 @@ class Ductape {
5799
5801
  var _a, _b, _c, _d, _e, _f, _g;
5800
5802
  if (!(response === null || response === void 0 ? void 0 : response.snapshot))
5801
5803
  return;
5804
+ const previousManifest = this.runtimeManifest;
5802
5805
  const scope = `${this.workspace_id}:${response.snapshot.product_tag}:${response.snapshot.env_slug}`;
5803
5806
  (0, bootstrap_cache_1.primeRuntimeBootstrapCache)(this.workspace_id, scope, response.snapshot.entries);
5804
5807
  const runtimeCredentials = new Map();
@@ -5846,6 +5849,49 @@ class Ductape {
5846
5849
  this.runtimeManifest = response.manifest;
5847
5850
  this.runtimeLastRefreshAt = Date.now();
5848
5851
  this.runtimeLastError = undefined;
5852
+ const databaseTags = [...new Set(response.snapshot.entries
5853
+ .filter((entry) => (entry === null || entry === void 0 ? void 0 : entry.domain) === 'database')
5854
+ .map((entry) => { var _a, _b, _c; return String(((_a = entry === null || entry === void 0 ? void 0 : entry.parts) === null || _a === void 0 ? void 0 : _a[2]) || ((_c = (_b = entry === null || entry === void 0 ? void 0 : entry.data) === null || _b === void 0 ? void 0 : _b.database) === null || _c === void 0 ? void 0 : _c.tag) || '').trim(); })
5855
+ .filter(Boolean))];
5856
+ this.startRuntimeWarmup(databaseTags, Boolean(previousManifest && previousManifest.connectionRevision !== response.manifest.connectionRevision));
5857
+ }
5858
+ startRuntimeWarmup(databaseTags, recycleConnections) {
5859
+ var _a, _b;
5860
+ if (!this.runtimeWarmupEnabled || this.runtimeClosed || !this.defaultProduct || !this.defaultEnv || !databaseTags.length)
5861
+ return;
5862
+ const previous = (_b = (_a = this.runtimeWarmupInFlight) === null || _a === void 0 ? void 0 : _a.catch(() => undefined)) !== null && _b !== void 0 ? _b : Promise.resolve();
5863
+ const warmup = previous.then(async () => {
5864
+ const startedAt = Date.now();
5865
+ this.runtimeWarmupState = { startedAt, databases: [] };
5866
+ const service = await this.createNewDatabaseService();
5867
+ if (recycleConnections)
5868
+ await service.closeAll();
5869
+ const databases = await Promise.all(databaseTags.map(async (tag) => {
5870
+ const start = Date.now();
5871
+ try {
5872
+ await service.connect({ product: this.defaultProduct, env: this.defaultEnv, database: tag });
5873
+ return { tag, status: 'ready', durationMs: Date.now() - start };
5874
+ }
5875
+ catch (error) {
5876
+ return {
5877
+ tag,
5878
+ status: 'failed',
5879
+ durationMs: Date.now() - start,
5880
+ error: error instanceof Error ? error.message : String(error),
5881
+ };
5882
+ }
5883
+ }));
5884
+ const completedAt = Date.now();
5885
+ this.runtimeWarmupState = { startedAt, completedAt, durationMs: completedAt - startedAt, databases };
5886
+ });
5887
+ this.runtimeWarmupInFlight = warmup;
5888
+ warmup.finally(() => {
5889
+ if (this.runtimeWarmupInFlight === warmup)
5890
+ this.runtimeWarmupInFlight = undefined;
5891
+ }).catch(() => undefined);
5892
+ warmup.catch((error) => {
5893
+ this.runtimeLastError = `Runtime connection warm-up failed: ${error instanceof Error ? error.message : String(error)}`;
5894
+ });
5849
5895
  }
5850
5896
  scheduleRuntimePoll(failureCount = 0) {
5851
5897
  var _a, _b;
@@ -5902,11 +5948,13 @@ class Ductape {
5902
5948
  /** Force a full product runtime refresh and atomically replace bootstrap cache entries. */
5903
5949
  async ready() {
5904
5950
  await this.initUserAuth(false);
5951
+ await this.runtimeWarmupInFlight;
5905
5952
  }
5906
5953
  /** Force a full product runtime refresh and atomically replace bootstrap cache entries. */
5907
5954
  async refreshRuntime() {
5908
5955
  await this.initUserAuth(false);
5909
5956
  await this.refreshRuntimeSnapshot(true);
5957
+ await this.runtimeWarmupInFlight;
5910
5958
  }
5911
5959
  /** Observe the local product runtime snapshot without exposing cached configuration or secrets. */
5912
5960
  runtimeSnapshotStatus() {
@@ -5918,16 +5966,19 @@ class Ductape {
5918
5966
  lastRefreshAt: this.runtimeLastRefreshAt,
5919
5967
  lastError: this.runtimeLastError,
5920
5968
  refreshing: Boolean(this.runtimeRefreshInFlight),
5969
+ warmup: this.runtimeWarmupState ? Object.assign(Object.assign({}, this.runtimeWarmupState), { databases: this.runtimeWarmupState.databases.map((database) => (Object.assign({}, database))), warming: Boolean(this.runtimeWarmupInFlight) }) : { warming: Boolean(this.runtimeWarmupInFlight), databases: [] },
5921
5970
  };
5922
5971
  }
5923
5972
  /** Stop background synchronization and release SDK-owned background resources. */
5924
5973
  async close() {
5925
- var _a;
5974
+ var _a, _b, _c;
5926
5975
  this.runtimeClosed = true;
5927
5976
  if (this.runtimePollTimer)
5928
5977
  clearTimeout(this.runtimePollTimer);
5929
5978
  this.runtimePollTimer = undefined;
5930
5979
  await ((_a = this.runtimeRefreshInFlight) === null || _a === void 0 ? void 0 : _a.catch(() => undefined));
5980
+ await ((_b = this.runtimeWarmupInFlight) === null || _b === void 0 ? void 0 : _b.catch(() => undefined));
5981
+ await ((_c = this._databaseService) === null || _c === void 0 ? void 0 : _c.closeAll().catch(() => undefined));
5931
5982
  const resources = [this.jobsWorker, this.healthCheckWorker, this.healthCheckUpdaterWorker,
5932
5983
  this.jobsQueue, this.healthCheckQueue, this.healthCheckUpdaterQueue];
5933
5984
  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); }));
@@ -5935,11 +5986,11 @@ class Ductape {
5935
5986
  try {
5936
5987
  await this.redisClient.quit();
5937
5988
  }
5938
- catch (_b) {
5989
+ catch (_d) {
5939
5990
  try {
5940
5991
  this.redisClient.disconnect(false);
5941
5992
  }
5942
- catch ( /* best effort */_c) { /* best effort */ }
5993
+ catch ( /* best effort */_e) { /* best effort */ }
5943
5994
  }
5944
5995
  this.redisClient = undefined;
5945
5996
  }