@zentto/platform-client 0.1.0 → 0.3.0

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 (54) hide show
  1. package/README.md +89 -2
  2. package/dist/auth/client.d.ts +132 -0
  3. package/dist/auth/client.d.ts.map +1 -0
  4. package/dist/auth/client.js +157 -0
  5. package/dist/auth/client.js.map +1 -0
  6. package/dist/auth/index.d.ts +2 -0
  7. package/dist/auth/index.d.ts.map +1 -0
  8. package/dist/auth/index.js +2 -0
  9. package/dist/auth/index.js.map +1 -0
  10. package/dist/cache/client.d.ts +113 -0
  11. package/dist/cache/client.d.ts.map +1 -0
  12. package/dist/cache/client.js +87 -0
  13. package/dist/cache/client.js.map +1 -0
  14. package/dist/cache/index.d.ts +2 -0
  15. package/dist/cache/index.d.ts.map +1 -0
  16. package/dist/cache/index.js +2 -0
  17. package/dist/cache/index.js.map +1 -0
  18. package/dist/events/client.d.ts +94 -0
  19. package/dist/events/client.d.ts.map +1 -0
  20. package/dist/events/client.js +208 -0
  21. package/dist/events/client.js.map +1 -0
  22. package/dist/events/envelope.d.ts +28 -0
  23. package/dist/events/envelope.d.ts.map +1 -0
  24. package/dist/events/envelope.js +38 -0
  25. package/dist/events/envelope.js.map +1 -0
  26. package/dist/events/index.d.ts +3 -0
  27. package/dist/events/index.d.ts.map +1 -0
  28. package/dist/events/index.js +3 -0
  29. package/dist/events/index.js.map +1 -0
  30. package/dist/index.d.ts +5 -0
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +9 -6
  33. package/dist/index.js.map +1 -1
  34. package/dist/internal/circuit.d.ts +33 -0
  35. package/dist/internal/circuit.d.ts.map +1 -0
  36. package/dist/internal/circuit.js +73 -0
  37. package/dist/internal/circuit.js.map +1 -0
  38. package/dist/internal/errors.d.ts +57 -0
  39. package/dist/internal/errors.d.ts.map +1 -0
  40. package/dist/internal/errors.js +96 -0
  41. package/dist/internal/errors.js.map +1 -0
  42. package/dist/internal/http.d.ts +59 -0
  43. package/dist/internal/http.d.ts.map +1 -0
  44. package/dist/internal/http.js +95 -0
  45. package/dist/internal/http.js.map +1 -0
  46. package/dist/landing/client.d.ts +50 -0
  47. package/dist/landing/client.d.ts.map +1 -0
  48. package/dist/landing/client.js +46 -0
  49. package/dist/landing/client.js.map +1 -0
  50. package/dist/landing/index.d.ts +2 -0
  51. package/dist/landing/index.d.ts.map +1 -0
  52. package/dist/landing/index.js +2 -0
  53. package/dist/landing/index.js.map +1 -0
  54. package/package.json +27 -2
@@ -0,0 +1,94 @@
1
+ /**
2
+ * EventBusClient — producer + consumer de eventos Zentto sobre Kafka.
3
+ *
4
+ * `kafkajs` es una dependencia OPCIONAL. El paquete es zero-deps para callers
5
+ * que no usan eventos. Si un caller importa este submódulo sin kafkajs
6
+ * instalado, el constructor lanza con un mensaje claro.
7
+ *
8
+ * Uso:
9
+ * import { EventBusClient } from "@zentto/platform-client/events";
10
+ *
11
+ * const bus = new EventBusClient({
12
+ * brokers: ["kafka:9092"],
13
+ * source: "zentto-hotel",
14
+ * tenantCode: "ACME",
15
+ * });
16
+ *
17
+ * // Producer
18
+ * await bus.connect();
19
+ * await bus.publish({ eventType: "hotel.reservation.confirmed", data: {...} });
20
+ *
21
+ * // Consumer (otro proceso)
22
+ * bus.on("crm.lead.created", async (evt) => { ... });
23
+ * bus.on(/crm\..+/, async (evt) => { ... });
24
+ * await bus.start();
25
+ */
26
+ import { type EventEnvelope } from "./envelope.js";
27
+ export interface EventBusConfig {
28
+ brokers: string[];
29
+ source: string;
30
+ /** TenantCode por default para `publish`. Override por-llamada con `.publish({ tenantCode })`. */
31
+ tenantCode: string;
32
+ clientId?: string;
33
+ groupId?: string;
34
+ /** Log level: default "warn". */
35
+ logLevel?: "debug" | "info" | "warn" | "error" | "nothing";
36
+ /** Dedup por eventId. Default: en memoria con TTL 10min. */
37
+ dedup?: EventDedup;
38
+ onError?: (err: Error, ctx: {
39
+ where: string;
40
+ topic?: string;
41
+ eventId?: string;
42
+ }) => void;
43
+ }
44
+ export interface EventDedup {
45
+ seen(eventId: string): Promise<boolean>;
46
+ mark(eventId: string): Promise<void>;
47
+ }
48
+ type Handler = (evt: EventEnvelope, raw: {
49
+ topic: string;
50
+ partition: number;
51
+ offset: string;
52
+ }) => Promise<void> | void;
53
+ export declare class EventBusClient {
54
+ private readonly cfg;
55
+ private readonly subs;
56
+ private producer;
57
+ private consumer;
58
+ private started;
59
+ private connected;
60
+ constructor(cfg: EventBusConfig);
61
+ connect(): Promise<void>;
62
+ disconnect(): Promise<void>;
63
+ publish<T>(params: {
64
+ eventType: string;
65
+ data: T;
66
+ tenantCode?: string;
67
+ tenantId?: number;
68
+ correlationId?: string;
69
+ version?: number;
70
+ eventId?: string;
71
+ }): Promise<EventEnvelope<T>>;
72
+ on(pattern: string | RegExp, handler: Handler): void;
73
+ start(opts?: {
74
+ fromBeginning?: boolean;
75
+ topics?: (string | RegExp)[];
76
+ }): Promise<void>;
77
+ }
78
+ export declare class InMemoryDedup implements EventDedup {
79
+ private readonly ttlMs;
80
+ private readonly seenAt;
81
+ constructor(ttlMs?: number);
82
+ seen(eventId: string): Promise<boolean>;
83
+ mark(eventId: string): Promise<void>;
84
+ private sweep;
85
+ }
86
+ /**
87
+ * Factory desde env vars:
88
+ * KAFKA_BROKERS — CSV (obligatoria)
89
+ * ZENTTO_SERVICE_NAME — source (obligatoria)
90
+ * ZENTTO_TENANT_CODE — tenantCode default
91
+ */
92
+ export declare function eventsFromEnv(overrides?: Partial<EventBusConfig>): EventBusClient;
93
+ export {};
94
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/events/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,208 @@
1
+ /**
2
+ * EventBusClient — producer + consumer de eventos Zentto sobre Kafka.
3
+ *
4
+ * `kafkajs` es una dependencia OPCIONAL. El paquete es zero-deps para callers
5
+ * que no usan eventos. Si un caller importa este submódulo sin kafkajs
6
+ * instalado, el constructor lanza con un mensaje claro.
7
+ *
8
+ * Uso:
9
+ * import { EventBusClient } from "@zentto/platform-client/events";
10
+ *
11
+ * const bus = new EventBusClient({
12
+ * brokers: ["kafka:9092"],
13
+ * source: "zentto-hotel",
14
+ * tenantCode: "ACME",
15
+ * });
16
+ *
17
+ * // Producer
18
+ * await bus.connect();
19
+ * await bus.publish({ eventType: "hotel.reservation.confirmed", data: {...} });
20
+ *
21
+ * // Consumer (otro proceso)
22
+ * bus.on("crm.lead.created", async (evt) => { ... });
23
+ * bus.on(/crm\..+/, async (evt) => { ... });
24
+ * await bus.start();
25
+ */
26
+ import { buildEnvelope, topicName } from "./envelope.js";
27
+ export class EventBusClient {
28
+ cfg;
29
+ subs = [];
30
+ producer;
31
+ consumer;
32
+ started = false;
33
+ connected = false;
34
+ constructor(cfg) {
35
+ this.cfg = {
36
+ clientId: `zentto-${cfg.source}-${process.pid}`,
37
+ groupId: `zentto-${cfg.source}`,
38
+ logLevel: "warn",
39
+ dedup: new InMemoryDedup(),
40
+ onError: () => { },
41
+ ...cfg,
42
+ };
43
+ }
44
+ // ── Lifecycle ────────────────────────────────────────────────────────────
45
+ async connect() {
46
+ if (this.connected)
47
+ return;
48
+ const { Kafka } = await loadKafka();
49
+ const kafka = new Kafka({
50
+ clientId: this.cfg.clientId,
51
+ brokers: this.cfg.brokers,
52
+ logLevel: mapLogLevel(this.cfg.logLevel),
53
+ retry: { initialRetryTime: 2000, retries: 5 },
54
+ });
55
+ this.producer = kafka.producer({ idempotent: true, maxInFlightRequests: 1 });
56
+ this.consumer = kafka.consumer({ groupId: this.cfg.groupId });
57
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
58
+ await this.producer.connect();
59
+ this.connected = true;
60
+ }
61
+ async disconnect() {
62
+ if (!this.connected)
63
+ return;
64
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
65
+ if (this.producer)
66
+ await this.producer.disconnect().catch(() => { });
67
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
68
+ if (this.consumer && this.started)
69
+ await this.consumer.disconnect().catch(() => { });
70
+ this.connected = false;
71
+ this.started = false;
72
+ }
73
+ // ── Producer ─────────────────────────────────────────────────────────────
74
+ async publish(params) {
75
+ if (!this.connected)
76
+ await this.connect();
77
+ const tenantCode = (params.tenantCode ?? this.cfg.tenantCode).toUpperCase();
78
+ const envelope = buildEnvelope({
79
+ eventType: params.eventType,
80
+ tenantCode,
81
+ tenantId: params.tenantId,
82
+ source: this.cfg.source,
83
+ data: params.data,
84
+ version: params.version,
85
+ correlationId: params.correlationId,
86
+ eventId: params.eventId,
87
+ });
88
+ const topic = topicName(tenantCode, params.eventType);
89
+ try {
90
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
91
+ await this.producer.send({
92
+ topic,
93
+ messages: [{ key: tenantCode, value: JSON.stringify(envelope) }],
94
+ });
95
+ }
96
+ catch (err) {
97
+ this.cfg.onError(err, { where: "publish", topic, eventId: envelope.eventId });
98
+ throw err;
99
+ }
100
+ return envelope;
101
+ }
102
+ // ── Consumer ─────────────────────────────────────────────────────────────
103
+ on(pattern, handler) {
104
+ this.subs.push({ pattern, handler });
105
+ }
106
+ async start(opts) {
107
+ if (this.started)
108
+ return;
109
+ if (!this.connected)
110
+ await this.connect();
111
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
112
+ const consumer = this.consumer;
113
+ await consumer.connect();
114
+ const topics = opts?.topics ?? [/^zentto\..+/];
115
+ for (const t of topics) {
116
+ await consumer.subscribe({ topic: t, fromBeginning: opts?.fromBeginning ?? false });
117
+ }
118
+ await consumer.run({
119
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
120
+ eachMessage: async ({ topic, partition, message }) => {
121
+ const raw = message.value?.toString("utf-8");
122
+ if (!raw)
123
+ return;
124
+ let envelope;
125
+ try {
126
+ envelope = JSON.parse(raw);
127
+ }
128
+ catch (err) {
129
+ this.cfg.onError(err, { where: "decode", topic });
130
+ return;
131
+ }
132
+ // Dedup
133
+ if (await this.cfg.dedup.seen(envelope.eventId))
134
+ return;
135
+ await this.cfg.dedup.mark(envelope.eventId);
136
+ // Dispatch a handlers que matcheen el eventType o el topic
137
+ for (const sub of this.subs) {
138
+ const ok = typeof sub.pattern === "string"
139
+ ? envelope.eventType === sub.pattern || topic === sub.pattern
140
+ : sub.pattern.test(envelope.eventType) || sub.pattern.test(topic);
141
+ if (!ok)
142
+ continue;
143
+ try {
144
+ await sub.handler(envelope, { topic, partition, offset: message.offset });
145
+ }
146
+ catch (err) {
147
+ this.cfg.onError(err, { where: "handler", topic, eventId: envelope.eventId });
148
+ }
149
+ }
150
+ },
151
+ });
152
+ this.started = true;
153
+ }
154
+ }
155
+ // ── Dedup in-memory (default) ───────────────────────────────────────────────
156
+ export class InMemoryDedup {
157
+ ttlMs;
158
+ seenAt = new Map();
159
+ constructor(ttlMs = 10 * 60 * 1000) {
160
+ this.ttlMs = ttlMs;
161
+ }
162
+ async seen(eventId) {
163
+ this.sweep();
164
+ return this.seenAt.has(eventId);
165
+ }
166
+ async mark(eventId) {
167
+ this.seenAt.set(eventId, Date.now());
168
+ }
169
+ sweep() {
170
+ const cutoff = Date.now() - this.ttlMs;
171
+ for (const [k, t] of this.seenAt) {
172
+ if (t < cutoff)
173
+ this.seenAt.delete(k);
174
+ }
175
+ }
176
+ }
177
+ // ── Kafka loading (optional dep) ────────────────────────────────────────────
178
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
179
+ async function loadKafka() {
180
+ try {
181
+ // optional peer dep — resolve dinámico para no requerir tipos/install.
182
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
183
+ const mod = await import(/* @vite-ignore */ "kafkajs");
184
+ return { Kafka: mod.Kafka };
185
+ }
186
+ catch (err) {
187
+ throw new Error("EventBusClient requires `kafkajs` to be installed.\n" +
188
+ "Run: npm install kafkajs\n" +
189
+ "(kafkajs es una optional dependency de @zentto/platform-client — se carga solo si importás el submódulo /events)");
190
+ }
191
+ }
192
+ function mapLogLevel(l) {
193
+ // kafkajs logLevel: NOTHING=0, ERROR=1, WARN=2, INFO=4, DEBUG=5
194
+ return { nothing: 0, error: 1, warn: 2, info: 4, debug: 5 }[l] ?? 2;
195
+ }
196
+ /**
197
+ * Factory desde env vars:
198
+ * KAFKA_BROKERS — CSV (obligatoria)
199
+ * ZENTTO_SERVICE_NAME — source (obligatoria)
200
+ * ZENTTO_TENANT_CODE — tenantCode default
201
+ */
202
+ export function eventsFromEnv(overrides) {
203
+ const brokers = (process.env.KAFKA_BROKERS ?? "").split(",").map((s) => s.trim()).filter(Boolean);
204
+ const source = process.env.ZENTTO_SERVICE_NAME ?? "unknown-service";
205
+ const tenantCode = process.env.ZENTTO_TENANT_CODE ?? "ZENTTO";
206
+ return new EventBusClient({ brokers, source, tenantCode, ...overrides });
207
+ }
208
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/events/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Envelope estándar para eventos del bus Zentto.
3
+ * Ver docs/wiki/15-event-bus.md en zentto-web.
4
+ */
5
+ export interface EventEnvelope<T = unknown> {
6
+ eventId: string;
7
+ eventType: string;
8
+ tenantCode: string;
9
+ tenantId?: number;
10
+ timestamp: string;
11
+ source: string;
12
+ correlationId?: string;
13
+ data: T;
14
+ version: number;
15
+ }
16
+ export declare function buildEnvelope<T>(params: {
17
+ eventType: string;
18
+ tenantCode: string;
19
+ tenantId?: number;
20
+ source: string;
21
+ data: T;
22
+ version?: number;
23
+ correlationId?: string;
24
+ eventId?: string;
25
+ timestamp?: string;
26
+ }): EventEnvelope<T>;
27
+ export declare function topicName(tenantCode: string, eventType: string): string;
28
+ //# sourceMappingURL=envelope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../../src/events/envelope.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,aAAa,CAAC,CAAC,GAAG,OAAO;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,CAAC,CAAC;IACR,OAAO,EAAE,MAAM,CAAC;CACjB;AAkBD,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,CAAC,CAAC;IACR,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,aAAa,CAAC,CAAC,CAAC,CAYnB;AAED,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEvE"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Envelope estándar para eventos del bus Zentto.
3
+ * Ver docs/wiki/15-event-bus.md en zentto-web.
4
+ */
5
+ function uuid() {
6
+ // RFC 4122 v4 — sin dependencias
7
+ const bytes = new Uint8Array(16);
8
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
+ const g = globalThis;
10
+ if (g.crypto?.getRandomValues) {
11
+ g.crypto.getRandomValues(bytes);
12
+ }
13
+ else {
14
+ for (let i = 0; i < 16; i++)
15
+ bytes[i] = Math.floor(Math.random() * 256);
16
+ }
17
+ bytes[6] = (bytes[6] & 0x0f) | 0x40;
18
+ bytes[8] = (bytes[8] & 0x3f) | 0x80;
19
+ const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
20
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
21
+ }
22
+ export function buildEnvelope(params) {
23
+ return {
24
+ eventId: params.eventId ?? `evt_${uuid()}`,
25
+ eventType: params.eventType,
26
+ tenantCode: params.tenantCode.toUpperCase(),
27
+ tenantId: params.tenantId,
28
+ timestamp: params.timestamp ?? new Date().toISOString(),
29
+ source: params.source,
30
+ correlationId: params.correlationId,
31
+ data: params.data,
32
+ version: params.version ?? 1,
33
+ };
34
+ }
35
+ export function topicName(tenantCode, eventType) {
36
+ return `zentto.${tenantCode.toLowerCase()}.${eventType}`;
37
+ }
38
+ //# sourceMappingURL=envelope.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"envelope.js","sourceRoot":"","sources":["../../src/events/envelope.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAcH,SAAS,IAAI;IACX,iCAAiC;IACjC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IACjC,8DAA8D;IAC9D,MAAM,CAAC,GAAQ,UAAiB,CAAC;IACjC,IAAI,CAAC,CAAC,MAAM,EAAE,eAAe,EAAE,CAAC;QAC9B,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;SAAM,CAAC;QACN,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE;YAAE,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC;IAC1E,CAAC;IACD,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IACpC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IACpC,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC/E,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;AAC7G,CAAC;AAED,MAAM,UAAU,aAAa,CAAI,MAUhC;IACC,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,OAAO,IAAI,EAAE,EAAE;QAC1C,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,WAAW,EAAE;QAC3C,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACvD,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,aAAa,EAAE,MAAM,CAAC,aAAa;QACnC,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,CAAC;KAC7B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,UAAkB,EAAE,SAAiB;IAC7D,OAAO,UAAU,UAAU,CAAC,WAAW,EAAE,IAAI,SAAS,EAAE,CAAC;AAC3D,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from "./envelope.js";
2
+ export * from "./client.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/events/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from "./envelope.js";
2
+ export * from "./client.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/events/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,aAAa,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,7 @@
1
1
  export * as notify from "./notify/index.js";
2
+ export * as auth from "./auth/index.js";
3
+ export * as cache from "./cache/index.js";
4
+ export * as landing from "./landing/index.js";
5
+ export * as events from "./events/index.js";
6
+ export * from "./internal/errors.js";
2
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAG5C,cAAc,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -1,8 +1,11 @@
1
- // Barrel del platform-client. Cada submódulo expone su propia API; acá
2
- // re-exportamos en namespaces para llamadas tipo `platform.notify.email.send(...)`.
1
+ // Barrel de @zentto/platform-client. Un submódulo por servicio de plataforma.
2
+ // Uso: `import { notify } from "@zentto/platform-client"` o import directo
3
+ // del subpath `@zentto/platform-client/notify`.
3
4
  export * as notify from "./notify/index.js";
4
- // Placeholders se llenan cuando se migren cache/auth/landing al mismo patrón.
5
- // export * as cache from "./cache/index.js";
6
- // export * as auth from "./auth/index.js";
7
- // export * as landing from "./landing/index.js";
5
+ export * as auth from "./auth/index.js";
6
+ export * as cache from "./cache/index.js";
7
+ export * as landing from "./landing/index.js";
8
+ export * as events from "./events/index.js";
9
+ // Tipos de error compartidos (útiles para `instanceof` en callers).
10
+ export * from "./internal/errors.js";
8
11
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,oFAAoF;AAEpF,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAE5C,gFAAgF;AAChF,6CAA6C;AAC7C,2CAA2C;AAC3C,iDAAiD"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,2EAA2E;AAC3E,gDAAgD;AAEhD,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,kBAAkB,CAAC;AAC1C,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAE5C,oEAAoE;AACpE,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Circuit breaker minimal — un breaker por (baseUrl, path-prefix).
3
+ *
4
+ * Estados:
5
+ * closed → pasa tráfico. Cuenta fallos consecutivos.
6
+ * open → rechaza inmediato. Despeja tras cooldown.
7
+ * half → deja pasar 1 request de prueba. Si falla, vuelve a open.
8
+ * Si pasa, vuelve a closed.
9
+ *
10
+ * Evita cascade failures cuando un servicio upstream se cae.
11
+ */
12
+ export interface CircuitOptions {
13
+ /** Fallos consecutivos antes de abrir. Default 5. */
14
+ failureThreshold?: number;
15
+ /** Tiempo en open antes de probar half. Default 30s. */
16
+ cooldownMs?: number;
17
+ }
18
+ type State = "closed" | "open" | "half";
19
+ export declare class CircuitBreaker {
20
+ private readonly failureThreshold;
21
+ private readonly cooldownMs;
22
+ private readonly slots;
23
+ constructor(opts?: CircuitOptions);
24
+ private slot;
25
+ /** Llamado antes de disparar un request. Retorna false si el circuito está abierto. */
26
+ allow(key: string): boolean;
27
+ recordSuccess(key: string): void;
28
+ recordFailure(key: string): void;
29
+ /** Sólo para tests/debug. */
30
+ _state(key: string): State;
31
+ }
32
+ export {};
33
+ //# sourceMappingURL=circuit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circuit.d.ts","sourceRoot":"","sources":["../../src/internal/circuit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,cAAc;IAC7B,qDAAqD;IACrD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,KAAK,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;AASxC,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA2B;gBAErC,IAAI,GAAE,cAAmB;IAKrC,OAAO,CAAC,IAAI;IASZ,uFAAuF;IACvF,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAiB3B,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAOhC,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAehC,6BAA6B;IAC7B,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK;CAG3B"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Circuit breaker minimal — un breaker por (baseUrl, path-prefix).
3
+ *
4
+ * Estados:
5
+ * closed → pasa tráfico. Cuenta fallos consecutivos.
6
+ * open → rechaza inmediato. Despeja tras cooldown.
7
+ * half → deja pasar 1 request de prueba. Si falla, vuelve a open.
8
+ * Si pasa, vuelve a closed.
9
+ *
10
+ * Evita cascade failures cuando un servicio upstream se cae.
11
+ */
12
+ export class CircuitBreaker {
13
+ failureThreshold;
14
+ cooldownMs;
15
+ slots = new Map();
16
+ constructor(opts = {}) {
17
+ this.failureThreshold = Math.max(1, opts.failureThreshold ?? 5);
18
+ this.cooldownMs = Math.max(1000, opts.cooldownMs ?? 30_000);
19
+ }
20
+ slot(key) {
21
+ let s = this.slots.get(key);
22
+ if (!s) {
23
+ s = { state: "closed", consecutiveFailures: 0, openedAt: 0, halfInFlight: false };
24
+ this.slots.set(key, s);
25
+ }
26
+ return s;
27
+ }
28
+ /** Llamado antes de disparar un request. Retorna false si el circuito está abierto. */
29
+ allow(key) {
30
+ const s = this.slot(key);
31
+ if (s.state === "closed")
32
+ return true;
33
+ if (s.state === "open") {
34
+ if (Date.now() - s.openedAt >= this.cooldownMs) {
35
+ s.state = "half";
36
+ s.halfInFlight = false;
37
+ }
38
+ else {
39
+ return false;
40
+ }
41
+ }
42
+ // half: solo 1 in-flight a la vez
43
+ if (s.halfInFlight)
44
+ return false;
45
+ s.halfInFlight = true;
46
+ return true;
47
+ }
48
+ recordSuccess(key) {
49
+ const s = this.slot(key);
50
+ s.consecutiveFailures = 0;
51
+ s.halfInFlight = false;
52
+ s.state = "closed";
53
+ }
54
+ recordFailure(key) {
55
+ const s = this.slot(key);
56
+ s.consecutiveFailures++;
57
+ s.halfInFlight = false;
58
+ if (s.state === "half") {
59
+ s.state = "open";
60
+ s.openedAt = Date.now();
61
+ return;
62
+ }
63
+ if (s.consecutiveFailures >= this.failureThreshold) {
64
+ s.state = "open";
65
+ s.openedAt = Date.now();
66
+ }
67
+ }
68
+ /** Sólo para tests/debug. */
69
+ _state(key) {
70
+ return this.slot(key).state;
71
+ }
72
+ }
73
+ //# sourceMappingURL=circuit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"circuit.js","sourceRoot":"","sources":["../../src/internal/circuit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAkBH,MAAM,OAAO,cAAc;IACR,gBAAgB,CAAS;IACzB,UAAU,CAAS;IACnB,KAAK,GAAG,IAAI,GAAG,EAAgB,CAAC;IAEjD,YAAY,OAAuB,EAAE;QACnC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,gBAAgB,IAAI,CAAC,CAAC,CAAC;QAChE,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,CAAC;IAC9D,CAAC;IAEO,IAAI,CAAC,GAAW;QACtB,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,mBAAmB,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;YAClF,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACzB,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,uFAAuF;IACvF,KAAK,CAAC,GAAW;QACf,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,CAAC,CAAC,KAAK,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACtC,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;YACvB,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBAC/C,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC;gBACjB,CAAC,CAAC,YAAY,GAAG,KAAK,CAAC;YACzB,CAAC;iBAAM,CAAC;gBACN,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QACD,kCAAkC;QAClC,IAAI,CAAC,CAAC,YAAY;YAAE,OAAO,KAAK,CAAC;QACjC,CAAC,CAAC,YAAY,GAAG,IAAI,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,aAAa,CAAC,GAAW;QACvB,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC,CAAC,mBAAmB,GAAG,CAAC,CAAC;QAC1B,CAAC,CAAC,YAAY,GAAG,KAAK,CAAC;QACvB,CAAC,CAAC,KAAK,GAAG,QAAQ,CAAC;IACrB,CAAC;IAED,aAAa,CAAC,GAAW;QACvB,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC,CAAC,mBAAmB,EAAE,CAAC;QACxB,CAAC,CAAC,YAAY,GAAG,KAAK,CAAC;QACvB,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;YACvB,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC;YACjB,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,CAAC,mBAAmB,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACnD,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC;YACjB,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,6BAA6B;IAC7B,MAAM,CAAC,GAAW;QAChB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;IAC9B,CAAC;CACF"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Jerarquía de errores tipados del SDK.
3
+ *
4
+ * El SDK NO lanza por default (mantiene shape best-effort `{ ok, error }`).
5
+ * Estos errores se usan:
6
+ * a) En `result.errorInstance` para callers que quieran `instanceof`.
7
+ * b) Opcionalmente en modo `throwOnError: true` (futuro).
8
+ *
9
+ * La jerarquía permite reaccionar fino:
10
+ * if (err instanceof RateLimitedError) backoff();
11
+ * if (err instanceof AuthError) redirectToLogin();
12
+ */
13
+ export declare class PlatformError extends Error {
14
+ readonly status?: number;
15
+ readonly path?: string;
16
+ readonly attempt?: number;
17
+ constructor(message: string, opts?: {
18
+ status?: number;
19
+ path?: string;
20
+ attempt?: number;
21
+ cause?: unknown;
22
+ });
23
+ }
24
+ /** 4xx 401/403 — token inválido/expirado, scope faltante. */
25
+ export declare class AuthError extends PlatformError {
26
+ constructor(message: string, opts?: ConstructorParameters<typeof PlatformError>[1]);
27
+ }
28
+ /** 4xx 400/422 — body mal formado, campos faltantes. */
29
+ export declare class ValidationError extends PlatformError {
30
+ constructor(message: string, opts?: ConstructorParameters<typeof PlatformError>[1]);
31
+ }
32
+ /** 4xx 404 — recurso no existe. */
33
+ export declare class NotFoundError extends PlatformError {
34
+ constructor(message: string, opts?: ConstructorParameters<typeof PlatformError>[1]);
35
+ }
36
+ /** 4xx 429 — rate limited upstream. */
37
+ export declare class RateLimitedError extends PlatformError {
38
+ readonly retryAfterSec?: number;
39
+ constructor(message: string, opts?: ConstructorParameters<typeof PlatformError>[1] & {
40
+ retryAfterSec?: number;
41
+ });
42
+ }
43
+ /** 5xx — error del servicio upstream. Normalmente reintentable. */
44
+ export declare class ServiceError extends PlatformError {
45
+ constructor(message: string, opts?: ConstructorParameters<typeof PlatformError>[1]);
46
+ }
47
+ /** Errores de red (timeout, DNS, connection reset). Reintentables. */
48
+ export declare class NetworkError extends PlatformError {
49
+ constructor(message: string, opts?: ConstructorParameters<typeof PlatformError>[1]);
50
+ }
51
+ /** Circuit breaker abierto — upstream fallando demasiado. */
52
+ export declare class CircuitOpenError extends PlatformError {
53
+ constructor(message: string, opts?: ConstructorParameters<typeof PlatformError>[1]);
54
+ }
55
+ /** Mapea HTTP status + contexto a un error tipado. */
56
+ export declare function mapHttpError(status: number | undefined, body: Record<string, unknown>, path: string, attempt: number): PlatformError;
57
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/internal/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;gBAEd,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAQ1G;AAED,6DAA6D;AAC7D,qBAAa,SAAU,SAAQ,aAAa;gBAC9B,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC;CAInF;AAED,wDAAwD;AACxD,qBAAa,eAAgB,SAAQ,aAAa;gBACpC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC;CAInF;AAED,mCAAmC;AACnC,qBAAa,aAAc,SAAQ,aAAa;gBAClC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC;CAInF;AAED,uCAAuC;AACvC,qBAAa,gBAAiB,SAAQ,aAAa;IACjD,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;gBACpB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE;CAKhH;AAED,mEAAmE;AACnE,qBAAa,YAAa,SAAQ,aAAa;gBACjC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC;CAInF;AAED,sEAAsE;AACtE,qBAAa,YAAa,SAAQ,aAAa;gBACjC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC;CAInF;AAED,6DAA6D;AAC7D,qBAAa,gBAAiB,SAAQ,aAAa;gBACrC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,qBAAqB,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC;CAInF;AAED,sDAAsD;AACtD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,aAAa,CAYpI"}