@ductape/sdk 0.1.113 → 0.1.115

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 (46) hide show
  1. package/dist/api/services/processorApi.service.d.ts +2 -0
  2. package/dist/api/services/processorApi.service.js +51 -0
  3. package/dist/api/services/processorApi.service.js.map +1 -1
  4. package/dist/api/services/productsApi.service.d.ts +7 -1
  5. package/dist/api/services/productsApi.service.js.map +1 -1
  6. package/dist/api/urls.d.ts +1 -0
  7. package/dist/api/urls.js +5 -4
  8. package/dist/api/urls.js.map +1 -1
  9. package/dist/context/execution-context.d.ts +37 -0
  10. package/dist/context/execution-context.js +38 -0
  11. package/dist/context/execution-context.js.map +1 -0
  12. package/dist/context/index.d.ts +1 -0
  13. package/dist/context/index.js +18 -0
  14. package/dist/context/index.js.map +1 -0
  15. package/dist/database/adapters/mongodb.adapter.js +7 -7
  16. package/dist/database/adapters/mongodb.adapter.js.map +1 -1
  17. package/dist/database/databases.service.d.ts +4 -0
  18. package/dist/database/databases.service.js +7 -1
  19. package/dist/database/databases.service.js.map +1 -1
  20. package/dist/features/feature-executor.d.ts +10 -0
  21. package/dist/features/feature-executor.js +113 -35
  22. package/dist/features/feature-executor.js.map +1 -1
  23. package/dist/features/features.service.d.ts +16 -1
  24. package/dist/features/features.service.js +87 -26
  25. package/dist/features/features.service.js.map +1 -1
  26. package/dist/features/types/features.types.d.ts +8 -2
  27. package/dist/features/types/features.types.js.map +1 -1
  28. package/dist/functions/functions.runtime.js +25 -1
  29. package/dist/functions/functions.runtime.js.map +1 -1
  30. package/dist/functions/types.d.ts +6 -0
  31. package/dist/functions/types.js.map +1 -1
  32. package/dist/index.d.ts +2 -1
  33. package/dist/index.js +4 -0
  34. package/dist/index.js.map +1 -1
  35. package/dist/products/bootstrap-cache.js +7 -2
  36. package/dist/products/bootstrap-cache.js.map +1 -1
  37. package/dist/products/services/products.service.d.ts +2 -2
  38. package/dist/products/services/products.service.js +36 -1
  39. package/dist/products/services/products.service.js.map +1 -1
  40. package/dist/products/utils/functions.utils.d.ts +1 -1
  41. package/dist/sessions/sessions.helper.js +13 -1
  42. package/dist/sessions/sessions.helper.js.map +1 -1
  43. package/dist/tsconfig.tsbuildinfo +1 -1
  44. package/dist/types/processor.types.d.ts +15 -0
  45. package/dist/types/processor.types.js.map +1 -1
  46. package/package.json +2 -2
@@ -18,6 +18,11 @@ function hashFeatureSteps(steps) {
18
18
  const stable = [...steps].sort((a, b) => a.step_tag.localeCompare(b.step_tag));
19
19
  return (0, crypto_1.createHash)('sha256').update(JSON.stringify(stable)).digest('hex').slice(0, 16);
20
20
  }
21
+ // Shared across every ProductBuilder/service in this Node process. Bootstrap keys
22
+ // already include workspace + product/env/component scope, so instance-local maps
23
+ // only caused duplicate calls when Features delegated to Database/Graph/etc.
24
+ const processBootstrapCache = new Map();
25
+ const processBootstrapInFlight = new Map();
21
26
  /**
22
27
  * Tiered bootstrap response cache: in-memory first, optional Redis (encrypted with workspace key).
23
28
  * Keys: domain:workspaceId:product:env:tag…
@@ -27,8 +32,8 @@ class BootstrapCache {
27
32
  this.workspaceId = workspaceId;
28
33
  this.redisClient = redisClient;
29
34
  this.encryptionKey = encryptionKey;
30
- this.internal = new Map();
31
- this.inFlight = new Map();
35
+ this.internal = processBootstrapCache;
36
+ this.inFlight = processBootstrapInFlight;
32
37
  }
33
38
  async get(key) {
34
39
  const now = Date.now();
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap-cache.js","sourceRoot":"","sources":["../../src/products/bootstrap-cache.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bootstrap-cache.js","sourceRoot":"","sources":["../../src/products/bootstrap-cache.ts"],"names":[],"mappings":"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"}
@@ -131,7 +131,7 @@ export interface IProductsBuilderService {
131
131
  fetchHealthcheck(access_tag: string, tag: string): Promise<IProductAppHealth | null>;
132
132
  fetchHealthchecks(access_tag: string): Promise<Array<IProductAppHealth>>;
133
133
  fetchProductHealthchecks(): Promise<Array<IProductAppHealth>>;
134
- createFeature(data: Partial<IProductFeature>, throwErrorIfExists?: boolean): Promise<void>;
134
+ createFeature(data: Partial<IProductFeature>, throwErrorIfExists?: boolean): Promise<IProductFeature>;
135
135
  updateFeature(tag: string, data: Partial<IProductFeature>): Promise<void>;
136
136
  fetchFeature(tag: string): Promise<IProductFeature | null>;
137
137
  fetchFeatures(): Promise<Array<IProductFeature>>;
@@ -579,7 +579,7 @@ export default class ProductsBuilderService implements IProductsBuilderService {
579
579
  fetchJobs(): Promise<Array<IProductJobs>>;
580
580
  fetchJob(tag: string): Promise<IProductJobs | null>;
581
581
  deleteJob(tag: string): Promise<void>;
582
- createFeature(data: Partial<IProductFeature>, throwErrorIfExists?: boolean): Promise<void>;
582
+ createFeature(data: Partial<IProductFeature>, throwErrorIfExists?: boolean): Promise<IProductFeature>;
583
583
  updateFeature(tag: string, data: Partial<IProductFeature>): Promise<void>;
584
584
  fetchFeatures(): Promise<Array<IProductFeature>>;
585
585
  fetchFeature(tag: string): Promise<IProductFeature | null>;
@@ -699,16 +699,39 @@ class ProductsBuilderService {
699
699
  try {
700
700
  const auth = this.getUserAccess();
701
701
  return await this.cachedBootstrap('workflow', [params.product_tag, params.env_slug, (0, bootstrap_cache_1.hashFeatureSteps)(params.steps)], async () => {
702
+ var _a;
702
703
  const result = await this.productApi.bootstrapFeature(Object.assign(Object.assign({}, params), { workspace_id: auth.workspace_id }), auth);
703
704
  if (result && typeof result === 'object') {
704
705
  for (const stepTag of Object.keys(result)) {
705
706
  const data = result[stepTag];
707
+ const step = params.steps.find((candidate) => candidate.step_tag === stepTag);
706
708
  if (data === null || data === void 0 ? void 0 : data.product_id) {
707
709
  this.product_id = data.product_id;
708
710
  }
709
711
  if ((data === null || data === void 0 ? void 0 : data.notification) && (data === null || data === void 0 ? void 0 : data.private_key)) {
710
712
  result[stepTag] = Object.assign(Object.assign({}, data), { notification: this.decryptNotificationChannelConfigs(data.notification, data.private_key) });
711
713
  }
714
+ if (step && data != null) {
715
+ const domain = step.type === 'quota' || step.type === 'fallback'
716
+ ? 'resilience'
717
+ : step.type;
718
+ const parts = step.type === 'action'
719
+ ? [params.product_tag, step.access_tag, params.env_slug, step.action_tag]
720
+ : step.type === 'notification'
721
+ ? [params.product_tag, params.env_slug, step.notification_tag, step.message_tag]
722
+ : step.type === 'storage'
723
+ ? [params.product_tag, params.env_slug, step.storage_tag]
724
+ : step.type === 'database'
725
+ ? [params.product_tag, params.env_slug, step.database_tag]
726
+ : step.type === 'broker'
727
+ ? [params.product_tag, params.env_slug, step.broker_tag, (_a = step.topic_tag) !== null && _a !== void 0 ? _a : '']
728
+ : step.type === 'graph'
729
+ ? [params.product_tag, params.env_slug, step.graph_tag]
730
+ : step.type === 'vector'
731
+ ? [params.product_tag, params.env_slug, step.vector_tag]
732
+ : [params.product_tag, params.env_slug, step.type, step.component_tag];
733
+ this.bootstrapCache.set((0, bootstrap_cache_1.buildBootstrapCacheKey)(domain, this.workspace_id, parts), data);
734
+ }
712
735
  }
713
736
  }
714
737
  return result !== null && result !== void 0 ? result : {};
@@ -5069,7 +5092,8 @@ class ProductsBuilderService {
5069
5092
  // ==================== WORKFLOW CRUD METHODS ====================
5070
5093
  async createFeature(data, throwErrorIfExists = false) {
5071
5094
  try {
5072
- if (!(await this.fetchFeature(data.tag))) {
5095
+ const existing = await this.fetchFeature(data.tag);
5096
+ if (!existing) {
5073
5097
  // Validate required fields
5074
5098
  if (!data.name || !data.tag) {
5075
5099
  throw new Error('Feature requires name and tag');
@@ -5084,10 +5108,21 @@ class ProductsBuilderService {
5084
5108
  }
5085
5109
  }
5086
5110
  await this.productApi.updateProduct(this.product_id, Object.assign(Object.assign({}, data), { component: enums_1.ProductComponents.FEATURE, action: enums_1.RequestAction.CREATE }), this.getUserAccess());
5111
+ // A successful mutation response is insufficient: execution and Workbench
5112
+ // use the catalogue read API. Confirm that exact path can observe the write.
5113
+ for (let attempt = 0; attempt < 5; attempt += 1) {
5114
+ const persisted = await this.fetchFeature(data.tag);
5115
+ if (persisted)
5116
+ return persisted;
5117
+ if (attempt < 4)
5118
+ await new Promise((resolve) => setTimeout(resolve, 50 * (attempt + 1)));
5119
+ }
5120
+ throw new Error(`Feature catalogue write was acknowledged but ${data.tag} could not be read back`);
5087
5121
  }
5088
5122
  else {
5089
5123
  if (throwErrorIfExists)
5090
5124
  throw new Error(`Feature already exists`);
5125
+ return existing;
5091
5126
  }
5092
5127
  }
5093
5128
  catch (e) {