@adatechnology/meta-whatsapp-module 0.2.0-rc.14 → 0.2.0-rc.15

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/dist/index.cjs CHANGED
@@ -22,10 +22,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
22
22
  var index_exports = {};
23
23
  __export(index_exports, {
24
24
  CreateFlowGraphUseCase: () => CreateFlowGraphUseCase,
25
+ DEFAULT_FLOW_GRAPH_CACHE_TTL_SECONDS: () => DEFAULT_FLOW_GRAPH_CACHE_TTL_SECONDS,
25
26
  DeleteConversationUseCase: () => DeleteConversationUseCase,
26
27
  DeleteFlowGraphUseCase: () => DeleteFlowGraphUseCase,
27
28
  DocumentRepository: () => DocumentRepository,
28
29
  ExportConversationUseCase: () => ExportConversationUseCase,
30
+ FlowGraphCache: () => FlowGraphCache,
29
31
  FlowGraphRepository: () => FlowGraphRepository,
30
32
  FlowInterpreter: () => FlowInterpreter,
31
33
  FlowMediaRepository: () => FlowMediaRepository,
@@ -627,12 +629,21 @@ var FlowGraphRepository = class {
627
629
  __name(this, "FlowGraphRepository");
628
630
  }
629
631
  db;
630
- constructor(db) {
632
+ cache;
633
+ // Cache opcional: sem ele o repositório se comporta exatamente como antes, lendo sempre do
634
+ // banco. É o host que decide se quer cachear e com qual provedor (ver CacheInterface).
635
+ constructor(db, cache) {
631
636
  this.db = db;
637
+ this.cache = cache;
632
638
  }
633
639
  async get(companyId, key) {
640
+ const cached = await this.cache?.read(companyId, key);
641
+ if (cached) return cached;
634
642
  const [row] = await this.db.select().from(flowGraphs).where((0, import_drizzle_orm4.and)((0, import_drizzle_orm4.eq)(flowGraphs.companyId, companyId), (0, import_drizzle_orm4.eq)(flowGraphs.key, key))).limit(1);
635
- return row ? toContractGraph(row) : void 0;
643
+ if (!row) return void 0;
644
+ const graph = toContractGraph(row);
645
+ await this.cache?.write(companyId, graph);
646
+ return graph;
636
647
  }
637
648
  async list(companyId) {
638
649
  const rows = await this.db.select().from(flowGraphs).where((0, import_drizzle_orm4.eq)(flowGraphs.companyId, companyId));
@@ -662,7 +673,9 @@ var FlowGraphRepository = class {
662
673
  showInMenu: graph.showInMenu ?? false,
663
674
  menuOptionLabel: graph.menuOptionLabel
664
675
  }).returning();
665
- return toContractGraph(created);
676
+ const createdGraph = toContractGraph(created);
677
+ await this.cache?.invalidate(companyId, createdGraph.key);
678
+ return createdGraph;
666
679
  }
667
680
  // Lock otimista: a escrita só aplica se `expectedVersion` ainda bater com o que está salvo —
668
681
  // senão, alguém mais salvou entretanto e o editor precisa recarregar (ver comentário no schema).
@@ -676,10 +689,12 @@ var FlowGraphRepository = class {
676
689
  updatedAt: /* @__PURE__ */ new Date()
677
690
  }).where((0, import_drizzle_orm4.and)((0, import_drizzle_orm4.eq)(flowGraphs.companyId, companyId), (0, import_drizzle_orm4.eq)(flowGraphs.key, graph.key), (0, import_drizzle_orm4.eq)(flowGraphs.version, expectedVersion))).returning();
678
691
  if (rows.length === 0) throw new OptimisticLockError(graph.key);
692
+ await this.cache?.invalidate(companyId, graph.key);
679
693
  return toContractGraph(rows[0]);
680
694
  }
681
695
  async delete(companyId, key) {
682
696
  await this.db.delete(flowGraphs).where((0, import_drizzle_orm4.and)((0, import_drizzle_orm4.eq)(flowGraphs.companyId, companyId), (0, import_drizzle_orm4.eq)(flowGraphs.key, key)));
697
+ await this.cache?.invalidate(companyId, key);
683
698
  }
684
699
  // T4.2 — GetLiveFlowPositions: agrega sessões ativas por (flowKey, currentNodeId), lendo as
685
700
  // colunas dedicadas gravadas por SessionRepository.setFlowPosition. Agrega no banco (GROUP BY,
@@ -699,6 +714,48 @@ var FlowGraphRepository = class {
699
714
  }
700
715
  };
701
716
 
717
+ // src/repositories/FlowGraphCache.ts
718
+ var KEY_PREFIX = "meta-whatsapp:flow-graph";
719
+ var DEFAULT_FLOW_GRAPH_CACHE_TTL_SECONDS = 300;
720
+ var FlowGraphCache = class {
721
+ static {
722
+ __name(this, "FlowGraphCache");
723
+ }
724
+ provider;
725
+ ttlSeconds;
726
+ constructor(provider, ttlSeconds = DEFAULT_FLOW_GRAPH_CACHE_TTL_SECONDS) {
727
+ this.provider = provider;
728
+ this.ttlSeconds = ttlSeconds;
729
+ }
730
+ // companyId na chave, e não só a flowKey: a chave do fluxo é escolhida por quem edita e se
731
+ // repete entre empresas — 'consorcio' existe em todas — então uma chave sem tenant serviria o
732
+ // grafo de uma empresa para a conversa de outra.
733
+ keyFor(companyId, flowKey) {
734
+ return `${KEY_PREFIX}:${companyId}:${flowKey}`;
735
+ }
736
+ async read(companyId, flowKey) {
737
+ try {
738
+ const cached = await this.provider.get(this.keyFor(companyId, flowKey));
739
+ if (!cached) return void 0;
740
+ return JSON.parse(cached);
741
+ } catch {
742
+ return void 0;
743
+ }
744
+ }
745
+ async write(companyId, graph) {
746
+ try {
747
+ await this.provider.set(this.keyFor(companyId, graph.key), JSON.stringify(graph), this.ttlSeconds);
748
+ } catch {
749
+ }
750
+ }
751
+ async invalidate(companyId, flowKey) {
752
+ try {
753
+ await this.provider.delete(this.keyFor(companyId, flowKey));
754
+ } catch {
755
+ }
756
+ }
757
+ };
758
+
702
759
  // src/repositories/SettingsRepository.ts
703
760
  var import_drizzle_orm5 = require("drizzle-orm");
704
761
  function toContractSettings(row) {
@@ -2083,7 +2140,9 @@ function createMetaWhatsAppModule(params) {
2083
2140
  const sessionRepository = new SessionRepository(db);
2084
2141
  const messageRepository = new MessageRepository(db);
2085
2142
  const settingsRepository = new SettingsRepository(db);
2086
- const flowGraphRepository = new FlowGraphRepository(db);
2143
+ const flowGraphCacheFeature = params.features?.flowGraphCache ?? false;
2144
+ const flowGraphCache = flowGraphCacheFeature && providers.cache ? new FlowGraphCache(providers.cache, typeof flowGraphCacheFeature === "object" ? flowGraphCacheFeature.ttlSeconds ?? DEFAULT_FLOW_GRAPH_CACHE_TTL_SECONDS : DEFAULT_FLOW_GRAPH_CACHE_TTL_SECONDS) : void 0;
2145
+ const flowGraphRepository = new FlowGraphRepository(db, flowGraphCache);
2087
2146
  const documentRepository = new DocumentRepository(db);
2088
2147
  const flowMediaRepository = new FlowMediaRepository(db);
2089
2148
  const logMessage = new LogMessageUseCase(sessionRepository, messageRepository, providers.realtime, providers.moderator);
@@ -2255,10 +2314,12 @@ __name(redeemSseTicket, "redeemSseTicket");
2255
2314
  // Annotate the CommonJS export names for ESM import in node:
2256
2315
  0 && (module.exports = {
2257
2316
  CreateFlowGraphUseCase,
2317
+ DEFAULT_FLOW_GRAPH_CACHE_TTL_SECONDS,
2258
2318
  DeleteConversationUseCase,
2259
2319
  DeleteFlowGraphUseCase,
2260
2320
  DocumentRepository,
2261
2321
  ExportConversationUseCase,
2322
+ FlowGraphCache,
2262
2323
  FlowGraphRepository,
2263
2324
  FlowInterpreter,
2264
2325
  FlowMediaRepository,