@geekmidas/constructs 4.0.0 → 5.0.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.
- package/CHANGELOG.md +112 -0
- package/dist/{AWSScheduledFunction-COv8bB1v.d.mts → AWSScheduledFunction-1GYwJS7F.d.cts} +4 -4
- package/dist/{AWSScheduledFunction-D9uCAd76.d.cts.map → AWSScheduledFunction-1GYwJS7F.d.cts.map} +1 -1
- package/dist/{AWSScheduledFunction-D-55GfwL.mjs → AWSScheduledFunction-CODxw_vc.mjs} +2 -2
- package/dist/{AWSScheduledFunction-D-55GfwL.mjs.map → AWSScheduledFunction-CODxw_vc.mjs.map} +1 -1
- package/dist/{AWSScheduledFunction-sWwZC9hg.cjs → AWSScheduledFunction-DbkDr8CA.cjs} +3 -3
- package/dist/{AWSScheduledFunction-sWwZC9hg.cjs.map → AWSScheduledFunction-DbkDr8CA.cjs.map} +1 -1
- package/dist/{AWSScheduledFunction-D9uCAd76.d.cts → AWSScheduledFunction-ysaCsdWx.d.mts} +4 -4
- package/dist/{AWSScheduledFunction-COv8bB1v.d.mts.map → AWSScheduledFunction-ysaCsdWx.d.mts.map} +1 -1
- package/dist/{Construct-D0n7QTaI.d.mts → Construct-DCMuYOox.d.mts} +3 -1
- package/dist/{Construct-D0n7QTaI.d.mts.map → Construct-DCMuYOox.d.mts.map} +1 -1
- package/dist/{Construct-CdJY2DJS.mjs → Construct-DD8EaWzh.mjs} +4 -2
- package/dist/{Construct-CdJY2DJS.mjs.map → Construct-DD8EaWzh.mjs.map} +1 -1
- package/dist/{Construct-cjIs74Gb.d.cts → Construct-_1wX7p_Y.d.cts} +3 -1
- package/dist/{Construct-cjIs74Gb.d.cts.map → Construct-_1wX7p_Y.d.cts.map} +1 -1
- package/dist/{Construct-B14miJ6P.cjs → Construct-vXMZJgRp.cjs} +3 -1
- package/dist/{Construct-B14miJ6P.cjs.map → Construct-vXMZJgRp.cjs.map} +1 -1
- package/dist/{Endpoint-D5SChIsU.d.cts → Endpoint-C3-ZyPSL.d.cts} +5 -5
- package/dist/Endpoint-C3-ZyPSL.d.cts.map +1 -0
- package/dist/{Endpoint-C_qxza6z.d.mts → Endpoint-CLPSIl6S.d.mts} +5 -5
- package/dist/Endpoint-CLPSIl6S.d.mts.map +1 -0
- package/dist/{HonoEndpointAdaptor-CWYBGVFQ.mjs → HonoEndpointAdaptor-BwfNyFCi.mjs} +2 -2
- package/dist/{HonoEndpointAdaptor-CWYBGVFQ.mjs.map → HonoEndpointAdaptor-BwfNyFCi.mjs.map} +1 -1
- package/dist/{HonoEndpointAdaptor-C_2jaZ4k.cjs → HonoEndpointAdaptor-CkJENANP.cjs} +4 -4
- package/dist/{HonoEndpointAdaptor-C_2jaZ4k.cjs.map → HonoEndpointAdaptor-CkJENANP.cjs.map} +1 -1
- package/dist/Queue-DaxjwmOQ.d.cts +66 -0
- package/dist/Queue-DaxjwmOQ.d.cts.map +1 -0
- package/dist/Queue-HBDf0fqz.d.mts +66 -0
- package/dist/Queue-HBDf0fqz.d.mts.map +1 -0
- package/dist/{Subscriber-C6YXAmTp.d.cts → Subscriber-B69ngPwl.d.cts} +17 -3
- package/dist/Subscriber-B69ngPwl.d.cts.map +1 -0
- package/dist/{Subscriber-C0v9iOrI.d.mts → Subscriber-D8Xm-86W.d.mts} +17 -3
- package/dist/Subscriber-D8Xm-86W.d.mts.map +1 -0
- package/dist/Topic-C5ZMfveW.d.cts +60 -0
- package/dist/Topic-C5ZMfveW.d.cts.map +1 -0
- package/dist/Topic-DT10AqHk.d.mts +60 -0
- package/dist/Topic-DT10AqHk.d.mts.map +1 -0
- package/dist/adaptors/aws.cjs +109 -5
- package/dist/adaptors/aws.cjs.map +1 -1
- package/dist/adaptors/aws.d.cts +39 -7
- package/dist/adaptors/aws.d.cts.map +1 -1
- package/dist/adaptors/aws.d.mts +39 -7
- package/dist/adaptors/aws.d.mts.map +1 -1
- package/dist/adaptors/aws.mjs +108 -5
- package/dist/adaptors/aws.mjs.map +1 -1
- package/dist/adaptors/hono.cjs +5 -5
- package/dist/adaptors/hono.d.cts +5 -5
- package/dist/adaptors/hono.d.cts.map +1 -1
- package/dist/adaptors/hono.d.mts +5 -5
- package/dist/adaptors/hono.mjs +4 -4
- package/dist/adaptors/testing.cjs +42 -5
- package/dist/adaptors/testing.cjs.map +1 -1
- package/dist/adaptors/testing.d.cts +29 -5
- package/dist/adaptors/testing.d.cts.map +1 -1
- package/dist/adaptors/testing.d.mts +29 -5
- package/dist/adaptors/testing.d.mts.map +1 -1
- package/dist/adaptors/testing.mjs +41 -5
- package/dist/adaptors/testing.mjs.map +1 -1
- package/dist/crons/index.cjs +3 -3
- package/dist/crons/index.d.cts +3 -3
- package/dist/crons/index.d.mts +3 -3
- package/dist/crons/index.mjs +3 -3
- package/dist/endpoints/index.cjs +3 -3
- package/dist/endpoints/index.d.cts +5 -5
- package/dist/endpoints/index.d.mts +3 -3
- package/dist/endpoints/index.mjs +3 -3
- package/dist/functions/index.cjs +2 -2
- package/dist/functions/index.d.cts +2 -2
- package/dist/functions/index.d.mts +2 -2
- package/dist/functions/index.mjs +2 -2
- package/dist/{functions-C9QhxXoP.mjs → functions-Bx9Ac0ea.mjs} +2 -2
- package/dist/{functions-C9QhxXoP.mjs.map → functions-Bx9Ac0ea.mjs.map} +1 -1
- package/dist/{functions-cL1XwEHW.cjs → functions-C8i1kCMM.cjs} +2 -2
- package/dist/{functions-cL1XwEHW.cjs.map → functions-C8i1kCMM.cjs.map} +1 -1
- package/dist/{index-Cg0m0uBN.d.cts → index-D-s9UrHd.d.cts} +6 -6
- package/dist/{index-Cg0m0uBN.d.cts.map → index-D-s9UrHd.d.cts.map} +1 -1
- package/dist/{index-C0XoazSK.d.mts → index-DP6fqv0I.d.mts} +2 -2
- package/dist/{index-C0XoazSK.d.mts.map → index-DP6fqv0I.d.mts.map} +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{lazyAccessors-Bnq67EHR.mjs → lazyAccessors-DhOPJsRT.mjs} +3 -3
- package/dist/lazyAccessors-DhOPJsRT.mjs.map +1 -0
- package/dist/{lazyAccessors-DGqzwC-j.cjs → lazyAccessors-DmTG8sQH.cjs} +3 -3
- package/dist/lazyAccessors-DmTG8sQH.cjs.map +1 -0
- package/dist/{processAudits-BmjKsnF7.cjs → processAudits-CKjjivyz.cjs} +2 -2
- package/dist/{processAudits-BmjKsnF7.cjs.map → processAudits-CKjjivyz.cjs.map} +1 -1
- package/dist/queue/index.cjs +127 -0
- package/dist/queue/index.cjs.map +1 -0
- package/dist/queue/index.d.cts +45 -0
- package/dist/queue/index.d.cts.map +1 -0
- package/dist/queue/index.d.mts +44 -0
- package/dist/queue/index.d.mts.map +1 -0
- package/dist/queue/index.mjs +125 -0
- package/dist/queue/index.mjs.map +1 -0
- package/dist/subscribers/index.cjs +21 -3
- package/dist/subscribers/index.cjs.map +1 -1
- package/dist/subscribers/index.d.cts +18 -4
- package/dist/subscribers/index.d.cts.map +1 -1
- package/dist/subscribers/index.d.mts +16 -2
- package/dist/subscribers/index.d.mts.map +1 -1
- package/dist/subscribers/index.mjs +21 -3
- package/dist/subscribers/index.mjs.map +1 -1
- package/dist/topic/index.cjs +94 -0
- package/dist/topic/index.cjs.map +1 -0
- package/dist/topic/index.d.cts +32 -0
- package/dist/topic/index.d.cts.map +1 -0
- package/dist/topic/index.d.mts +32 -0
- package/dist/topic/index.d.mts.map +1 -0
- package/dist/topic/index.mjs +92 -0
- package/dist/topic/index.mjs.map +1 -0
- package/package.json +33 -13
- package/src/Construct.ts +2 -0
- package/src/adaptors/aws.ts +1 -0
- package/src/adaptors/testing.ts +1 -0
- package/src/endpoints/Endpoint.ts +16 -10
- package/src/queue/AWSLambdaQueueAdaptor.ts +162 -0
- package/src/queue/Queue.ts +128 -0
- package/src/queue/QueueBuilder.ts +115 -0
- package/src/queue/TestQueueAdaptor.ts +63 -0
- package/src/queue/__tests__/QueueBuilder.spec.ts +137 -0
- package/src/queue/index.ts +12 -0
- package/src/subscribers/Subscriber.ts +7 -0
- package/src/subscribers/SubscriberBuilder.ts +36 -0
- package/src/topic/Topic.ts +103 -0
- package/src/topic/TopicBuilder.ts +51 -0
- package/src/topic/__tests__/TopicBuilder.spec.ts +82 -0
- package/src/topic/index.ts +11 -0
- package/tsdown.config.ts +2 -0
- package/dist/Endpoint-C_qxza6z.d.mts.map +0 -1
- package/dist/Endpoint-D5SChIsU.d.cts.map +0 -1
- package/dist/Subscriber-C0v9iOrI.d.mts.map +0 -1
- package/dist/Subscriber-C6YXAmTp.d.cts.map +0 -1
- package/dist/lazyAccessors-Bnq67EHR.mjs.map +0 -1
- package/dist/lazyAccessors-DGqzwC-j.cjs.map +0 -1
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { Construct, ConstructType } from "../Construct-DD8EaWzh.mjs";
|
|
2
|
+
import { ConsoleLogger, DEFAULT_LOGGER } from "@geekmidas/logger/console";
|
|
3
|
+
import { environmentCase } from "@geekmidas/envkit";
|
|
4
|
+
import { Publisher } from "@geekmidas/events";
|
|
5
|
+
|
|
6
|
+
//#region src/queue/Queue.ts
|
|
7
|
+
const DEFAULT_LOGGER$1 = new ConsoleLogger();
|
|
8
|
+
/**
|
|
9
|
+
* A queue worker — a point-to-point SQS-style queue and its single consumer.
|
|
10
|
+
* Unlike a `Subscriber` (topic fan-out, filtered by `subscribedEvents`), a queue
|
|
11
|
+
* drains every message of its one `message` type. Build one with `q` (see
|
|
12
|
+
* `QueueBuilder`); `gkm build` discovers it into the manifest's `queues` field.
|
|
13
|
+
*
|
|
14
|
+
* The producer side is {@link Queue.publisher} — a ready-to-inject `Service`
|
|
15
|
+
* that any endpoint/function drops into `.services([...])` to send messages.
|
|
16
|
+
*/
|
|
17
|
+
var Queue = class extends Construct {
|
|
18
|
+
__IS_QUEUE__ = true;
|
|
19
|
+
static isQueue(obj) {
|
|
20
|
+
return Boolean(obj && obj.__IS_QUEUE__ === true && obj.type === ConstructType.Queue);
|
|
21
|
+
}
|
|
22
|
+
constructor(name, handler, messageSchema, timeout = 3e4, services = [], logger = DEFAULT_LOGGER$1, batchSize, fifo) {
|
|
23
|
+
super(ConstructType.Queue, logger, services, [], void 0, void 0, timeout);
|
|
24
|
+
this.name = name;
|
|
25
|
+
this.handler = handler;
|
|
26
|
+
this.messageSchema = messageSchema;
|
|
27
|
+
this.timeout = timeout;
|
|
28
|
+
this.services = services;
|
|
29
|
+
this.logger = logger;
|
|
30
|
+
this.batchSize = batchSize;
|
|
31
|
+
this.fifo = fifo;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* The producer side — a `Service` exposing an `EventPublisher` typed to this
|
|
35
|
+
* queue's message. Inject it via `.services([queue.publisher])`; the handler
|
|
36
|
+
* then calls `services.<name>Publisher.publish([{ type, payload }])`.
|
|
37
|
+
*
|
|
38
|
+
* It reads `<NAME>_PUBLISHER_CONNECTION_STRING` and builds the transport from
|
|
39
|
+
* the URL protocol — `pgboss://` locally, `sqs://` deployed — so the same
|
|
40
|
+
* code publishes to Postgres in dev and SQS in prod. Because it's a `Service`,
|
|
41
|
+
* `Construct.getEnvironment()` sniffs it, so the env requirement flows into
|
|
42
|
+
* the manifest and infra links exactly this queue with least privilege.
|
|
43
|
+
*/
|
|
44
|
+
get publisher() {
|
|
45
|
+
const envVar = `${environmentCase(this.name)}_PUBLISHER_CONNECTION_STRING`;
|
|
46
|
+
return {
|
|
47
|
+
serviceName: `${this.name}Publisher`,
|
|
48
|
+
async register({ envParser }) {
|
|
49
|
+
const { connectionString } = envParser.create((get) => ({ connectionString: get(envVar).string() })).parse();
|
|
50
|
+
return Publisher.fromConnectionString(connectionString);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
//#endregion
|
|
57
|
+
//#region src/queue/QueueBuilder.ts
|
|
58
|
+
/**
|
|
59
|
+
* Builds a {@link Queue} worker — `q.queue('orders').services([db]).message(schema).handle(fn)`.
|
|
60
|
+
* Services are an array (sniffed for required env vars); `message` is the typed
|
|
61
|
+
* job payload; `handle` is the single consumer. The queue name is captured as a
|
|
62
|
+
* literal so `queue.publisher` is typed to `{ type: '<name>', payload }`.
|
|
63
|
+
*/
|
|
64
|
+
var QueueBuilder = class {
|
|
65
|
+
_name;
|
|
66
|
+
_messageSchema;
|
|
67
|
+
_timeout = 3e4;
|
|
68
|
+
_batchSize;
|
|
69
|
+
_fifo;
|
|
70
|
+
_services = [];
|
|
71
|
+
_logger = DEFAULT_LOGGER;
|
|
72
|
+
/** The queue name — drives the infra queue and its `<NAME>_*` env vars. */
|
|
73
|
+
queue(name) {
|
|
74
|
+
this._name = name;
|
|
75
|
+
return this;
|
|
76
|
+
}
|
|
77
|
+
timeout(timeout) {
|
|
78
|
+
this._timeout = timeout;
|
|
79
|
+
return this;
|
|
80
|
+
}
|
|
81
|
+
/** SQS event-source batch size (deployed). */
|
|
82
|
+
batchSize(batchSize) {
|
|
83
|
+
this._batchSize = batchSize;
|
|
84
|
+
return this;
|
|
85
|
+
}
|
|
86
|
+
/** Mark the queue as FIFO (deployed). */
|
|
87
|
+
fifo(fifo = true) {
|
|
88
|
+
this._fifo = fifo;
|
|
89
|
+
return this;
|
|
90
|
+
}
|
|
91
|
+
services(services) {
|
|
92
|
+
this._services = [...this._services, ...services];
|
|
93
|
+
return this;
|
|
94
|
+
}
|
|
95
|
+
logger(logger) {
|
|
96
|
+
this._logger = logger;
|
|
97
|
+
return this;
|
|
98
|
+
}
|
|
99
|
+
/** The typed message (job) payload the queue carries. */
|
|
100
|
+
message(schema) {
|
|
101
|
+
this._messageSchema = schema;
|
|
102
|
+
return this;
|
|
103
|
+
}
|
|
104
|
+
handle(fn) {
|
|
105
|
+
if (!this._name) throw new Error("Queue requires a name — call .queue(name) before .handle().");
|
|
106
|
+
if (!this._messageSchema) throw new Error("Queue requires a message schema — call .message(schema) before .handle().");
|
|
107
|
+
const queue = new Queue(this._name, fn, this._messageSchema, this._timeout, this._services, this._logger, this._batchSize, this._fifo);
|
|
108
|
+
this._name = void 0;
|
|
109
|
+
this._messageSchema = void 0;
|
|
110
|
+
this._timeout = 3e4;
|
|
111
|
+
this._batchSize = void 0;
|
|
112
|
+
this._fifo = void 0;
|
|
113
|
+
this._services = [];
|
|
114
|
+
this._logger = DEFAULT_LOGGER;
|
|
115
|
+
return queue;
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
//#endregion
|
|
120
|
+
//#region src/queue/index.ts
|
|
121
|
+
const q = new QueueBuilder();
|
|
122
|
+
|
|
123
|
+
//#endregion
|
|
124
|
+
export { Queue, QueueBuilder, q };
|
|
125
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["DEFAULT_LOGGER","obj: unknown","name: TName","handler: QueueHandler<TMessage, TServices, TLogger>","messageSchema: TMessage","timeout: number","services: TServices","logger: TLogger","batchSize?: number","fifo?: boolean","name: T","timeout: number","batchSize: number","services: T","logger: T","schema: T","fn: QueueHandler<NonNullable<TMessage>, TServices, TLogger>"],"sources":["../../src/queue/Queue.ts","../../src/queue/QueueBuilder.ts","../../src/queue/index.ts"],"sourcesContent":["import { environmentCase } from '@geekmidas/envkit';\nimport {\n\ttype EventPublisher,\n\ttype EventPublisherConnectionString,\n\ttype PublishableMessage,\n\tPublisher,\n} from '@geekmidas/events';\nimport type { Logger } from '@geekmidas/logger';\nimport { ConsoleLogger } from '@geekmidas/logger/console';\nimport type { InferStandardSchema } from '@geekmidas/schema';\nimport type { Service, ServiceRecord } from '@geekmidas/services';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { Construct, ConstructType } from '../Construct';\n\nconst DEFAULT_LOGGER = new ConsoleLogger() as unknown as Logger;\n\n/**\n * The wire message a queue carries: `{ type: <queue name>, payload: <message> }`.\n * The producer publishes this shape and the worker receives the `payload`s as\n * its `messages`. Typing `type` to the queue name keeps the publisher fully\n * typed and lets pg-boss (local) / SQS (deployed) route by name.\n */\nexport type QueueMessage<\n\tTName extends string,\n\tTMessage extends StandardSchemaV1,\n> = PublishableMessage<TName, InferStandardSchema<TMessage>>;\n\n/**\n * A queue worker — a point-to-point SQS-style queue and its single consumer.\n * Unlike a `Subscriber` (topic fan-out, filtered by `subscribedEvents`), a queue\n * drains every message of its one `message` type. Build one with `q` (see\n * `QueueBuilder`); `gkm build` discovers it into the manifest's `queues` field.\n *\n * The producer side is {@link Queue.publisher} — a ready-to-inject `Service`\n * that any endpoint/function drops into `.services([...])` to send messages.\n */\nexport class Queue<\n\tTName extends string = string,\n\tTMessage extends StandardSchemaV1 = StandardSchemaV1,\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n> extends Construct<TLogger, string, undefined, undefined, TServices> {\n\t__IS_QUEUE__ = true;\n\n\tstatic isQueue(\n\t\tobj: unknown,\n\t): obj is Queue<string, StandardSchemaV1, Service[], Logger> {\n\t\treturn Boolean(\n\t\t\tobj &&\n\t\t\t\t(obj as { __IS_QUEUE__?: boolean }).__IS_QUEUE__ === true &&\n\t\t\t\t(obj as Construct).type === ConstructType.Queue,\n\t\t);\n\t}\n\n\tconstructor(\n\t\tpublic readonly name: TName,\n\t\tpublic readonly handler: QueueHandler<TMessage, TServices, TLogger>,\n\t\tpublic readonly messageSchema: TMessage,\n\t\tpublic override readonly timeout: number = 30000,\n\t\tpublic override readonly services: TServices = [] as unknown as TServices,\n\t\tpublic override readonly logger: TLogger = DEFAULT_LOGGER as TLogger,\n\t\t/** SQS event-source batch size (deployed). */\n\t\tpublic readonly batchSize?: number,\n\t\t/** Whether the queue is FIFO (deployed). */\n\t\tpublic readonly fifo?: boolean,\n\t) {\n\t\tsuper(\n\t\t\tConstructType.Queue,\n\t\t\tlogger,\n\t\t\tservices,\n\t\t\t[],\n\t\t\tundefined,\n\t\t\tundefined,\n\t\t\ttimeout,\n\t\t);\n\t}\n\n\t/**\n\t * The producer side — a `Service` exposing an `EventPublisher` typed to this\n\t * queue's message. Inject it via `.services([queue.publisher])`; the handler\n\t * then calls `services.<name>Publisher.publish([{ type, payload }])`.\n\t *\n\t * It reads `<NAME>_PUBLISHER_CONNECTION_STRING` and builds the transport from\n\t * the URL protocol — `pgboss://` locally, `sqs://` deployed — so the same\n\t * code publishes to Postgres in dev and SQS in prod. Because it's a `Service`,\n\t * `Construct.getEnvironment()` sniffs it, so the env requirement flows into\n\t * the manifest and infra links exactly this queue with least privilege.\n\t */\n\tget publisher(): Service<\n\t\t`${TName}Publisher`,\n\t\tEventPublisher<QueueMessage<TName, TMessage>>\n\t> {\n\t\tconst envVar = `${environmentCase(this.name)}_PUBLISHER_CONNECTION_STRING`;\n\t\treturn {\n\t\t\tserviceName: `${this.name}Publisher`,\n\t\t\tasync register({ envParser }) {\n\t\t\t\tconst { connectionString } = envParser\n\t\t\t\t\t.create((get) => ({\n\t\t\t\t\t\tconnectionString: get(envVar).string(),\n\t\t\t\t\t}))\n\t\t\t\t\t.parse();\n\n\t\t\t\treturn Publisher.fromConnectionString<QueueMessage<TName, TMessage>>(\n\t\t\t\t\tconnectionString as EventPublisherConnectionString,\n\t\t\t\t);\n\t\t\t},\n\t\t};\n\t}\n}\n\n/** The context a queue handler receives — a batch of typed messages. */\nexport type QueueContext<\n\tTMessage extends StandardSchemaV1,\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n> = {\n\tmessages: InferStandardSchema<TMessage>[];\n\tservices: ServiceRecord<TServices>;\n\tlogger: TLogger;\n};\n\nexport type QueueHandler<\n\tTMessage extends StandardSchemaV1,\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n> = (\n\tctx: QueueContext<TMessage, TServices, TLogger>,\n) => unknown | Promise<unknown>;\n","import type { Logger } from '@geekmidas/logger';\nimport { DEFAULT_LOGGER } from '@geekmidas/logger/console';\nimport type { Service } from '@geekmidas/services';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { Queue, type QueueHandler } from './Queue';\n\n/**\n * Builds a {@link Queue} worker — `q.queue('orders').services([db]).message(schema).handle(fn)`.\n * Services are an array (sniffed for required env vars); `message` is the typed\n * job payload; `handle` is the single consumer. The queue name is captured as a\n * literal so `queue.publisher` is typed to `{ type: '<name>', payload }`.\n */\nexport class QueueBuilder<\n\tTName extends string = string,\n\tTMessage extends StandardSchemaV1 | undefined = undefined,\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n> {\n\tprivate _name?: string;\n\tprivate _messageSchema?: TMessage;\n\tprivate _timeout = 30000;\n\tprivate _batchSize?: number;\n\tprivate _fifo?: boolean;\n\tprivate _services: TServices = [] as Service[] as TServices;\n\tprivate _logger: TLogger = DEFAULT_LOGGER as TLogger;\n\n\t/** The queue name — drives the infra queue and its `<NAME>_*` env vars. */\n\tqueue<T extends string>(\n\t\tname: T,\n\t): QueueBuilder<T, TMessage, TServices, TLogger> {\n\t\tthis._name = name;\n\t\treturn this as unknown as QueueBuilder<T, TMessage, TServices, TLogger>;\n\t}\n\n\ttimeout(timeout: number): this {\n\t\tthis._timeout = timeout;\n\t\treturn this;\n\t}\n\n\t/** SQS event-source batch size (deployed). */\n\tbatchSize(batchSize: number): this {\n\t\tthis._batchSize = batchSize;\n\t\treturn this;\n\t}\n\n\t/** Mark the queue as FIFO (deployed). */\n\tfifo(fifo = true): this {\n\t\tthis._fifo = fifo;\n\t\treturn this;\n\t}\n\n\tservices<T extends Service[]>(\n\t\tservices: T,\n\t): QueueBuilder<TName, TMessage, [...TServices, ...T], TLogger> {\n\t\tthis._services = [...this._services, ...services] as unknown as TServices;\n\t\treturn this as unknown as QueueBuilder<\n\t\t\tTName,\n\t\t\tTMessage,\n\t\t\t[...TServices, ...T],\n\t\t\tTLogger\n\t\t>;\n\t}\n\n\tlogger<T extends Logger>(\n\t\tlogger: T,\n\t): QueueBuilder<TName, TMessage, TServices, T> {\n\t\tthis._logger = logger as unknown as TLogger;\n\t\treturn this as unknown as QueueBuilder<TName, TMessage, TServices, T>;\n\t}\n\n\t/** The typed message (job) payload the queue carries. */\n\tmessage<T extends StandardSchemaV1>(\n\t\tschema: T,\n\t): QueueBuilder<TName, T, TServices, TLogger> {\n\t\tthis._messageSchema = schema as unknown as TMessage;\n\t\treturn this as unknown as QueueBuilder<TName, T, TServices, TLogger>;\n\t}\n\n\thandle(\n\t\tfn: QueueHandler<NonNullable<TMessage>, TServices, TLogger>,\n\t): Queue<TName, NonNullable<TMessage>, TServices, TLogger> {\n\t\tif (!this._name) {\n\t\t\tthrow new Error(\n\t\t\t\t'Queue requires a name — call .queue(name) before .handle().',\n\t\t\t);\n\t\t}\n\t\tif (!this._messageSchema) {\n\t\t\tthrow new Error(\n\t\t\t\t'Queue requires a message schema — call .message(schema) before .handle().',\n\t\t\t);\n\t\t}\n\n\t\tconst queue = new Queue<TName, NonNullable<TMessage>, TServices, TLogger>(\n\t\t\tthis._name as TName,\n\t\t\tfn,\n\t\t\tthis._messageSchema as NonNullable<TMessage>,\n\t\t\tthis._timeout,\n\t\t\tthis._services,\n\t\t\tthis._logger,\n\t\t\tthis._batchSize,\n\t\t\tthis._fifo,\n\t\t);\n\n\t\t// Reset builder state to prevent pollution across reuse.\n\t\tthis._name = undefined;\n\t\tthis._messageSchema = undefined;\n\t\tthis._timeout = 30000;\n\t\tthis._batchSize = undefined;\n\t\tthis._fifo = undefined;\n\t\tthis._services = [] as Service[] as TServices;\n\t\tthis._logger = DEFAULT_LOGGER as TLogger;\n\n\t\treturn queue;\n\t}\n}\n","export {\n\tQueue,\n\ttype QueueContext,\n\ttype QueueHandler,\n\ttype QueueMessage,\n} from './Queue';\n\nimport { QueueBuilder } from './QueueBuilder';\n\nexport { QueueBuilder } from './QueueBuilder';\n\nexport const q = new QueueBuilder();\n"],"mappings":";;;;;;AAcA,MAAMA,mBAAiB,IAAI;;;;;;;;;;AAsB3B,IAAa,QAAb,cAKU,UAA4D;CACrE,eAAe;CAEf,OAAO,QACNC,KAC4D;AAC5D,SAAO,QACN,OACE,IAAmC,iBAAiB,QACpD,IAAkB,SAAS,cAAc,MAC3C;CACD;CAED,YACiBC,MACAC,SACAC,eACSC,UAAkB,KAClBC,WAAsB,CAAE,GACxBC,SAAkBP,kBAE3BQ,WAEAC,MACf;AACD,QACC,cAAc,OACd,QACA,UACA,CAAE,mBAGF,QACA;EAnBe;EACA;EACA;EACS;EACA;EACA;EAET;EAEA;CAWhB;;;;;;;;;;;;CAaD,IAAI,YAGF;EACD,MAAM,UAAU,EAAE,gBAAgB,KAAK,KAAK,CAAC;AAC7C,SAAO;GACN,cAAc,EAAE,KAAK,KAAK;GAC1B,MAAM,SAAS,EAAE,WAAW,EAAE;IAC7B,MAAM,EAAE,kBAAkB,GAAG,UAC3B,OAAO,CAAC,SAAS,EACjB,kBAAkB,IAAI,OAAO,CAAC,QAAQ,CACtC,GAAE,CACF,OAAO;AAET,WAAO,UAAU,qBAChB,iBACA;GACD;EACD;CACD;AACD;;;;;;;;;;AChGD,IAAa,eAAb,MAKE;CACD,AAAQ;CACR,AAAQ;CACR,AAAQ,WAAW;CACnB,AAAQ;CACR,AAAQ;CACR,AAAQ,YAAuB,CAAE;CACjC,AAAQ,UAAmB;;CAG3B,MACCC,MACgD;AAChD,OAAK,QAAQ;AACb,SAAO;CACP;CAED,QAAQC,SAAuB;AAC9B,OAAK,WAAW;AAChB,SAAO;CACP;;CAGD,UAAUC,WAAyB;AAClC,OAAK,aAAa;AAClB,SAAO;CACP;;CAGD,KAAK,OAAO,MAAY;AACvB,OAAK,QAAQ;AACb,SAAO;CACP;CAED,SACCC,UAC+D;AAC/D,OAAK,YAAY,CAAC,GAAG,KAAK,WAAW,GAAG,QAAS;AACjD,SAAO;CAMP;CAED,OACCC,QAC8C;AAC9C,OAAK,UAAU;AACf,SAAO;CACP;;CAGD,QACCC,QAC6C;AAC7C,OAAK,iBAAiB;AACtB,SAAO;CACP;CAED,OACCC,IAC0D;AAC1D,OAAK,KAAK,MACT,OAAM,IAAI,MACT;AAGF,OAAK,KAAK,eACT,OAAM,IAAI,MACT;EAIF,MAAM,QAAQ,IAAI,MACjB,KAAK,OACL,IACA,KAAK,gBACL,KAAK,UACL,KAAK,WACL,KAAK,SACL,KAAK,YACL,KAAK;AAIN,OAAK;AACL,OAAK;AACL,OAAK,WAAW;AAChB,OAAK;AACL,OAAK;AACL,OAAK,YAAY,CAAE;AACnB,OAAK,UAAU;AAEf,SAAO;CACP;AACD;;;;ACvGD,MAAa,IAAI,IAAI"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_Construct = require('../Construct-
|
|
1
|
+
const require_Construct = require('../Construct-vXMZJgRp.cjs');
|
|
2
2
|
const __geekmidas_logger_console = require_Construct.__toESM(require("@geekmidas/logger/console"));
|
|
3
3
|
|
|
4
4
|
//#region src/subscribers/Subscriber.ts
|
|
@@ -8,7 +8,7 @@ var Subscriber = class extends require_Construct.Construct {
|
|
|
8
8
|
static isSubscriber(obj) {
|
|
9
9
|
return Boolean(obj && obj.__IS_SUBSCRIBER__ === true && obj.type === require_Construct.ConstructType.Subscriber);
|
|
10
10
|
}
|
|
11
|
-
constructor(handler, timeout = 3e4, _subscribedEvents, outputSchema, services = [], logger = DEFAULT_LOGGER$1, publisherService) {
|
|
11
|
+
constructor(handler, timeout = 3e4, _subscribedEvents, outputSchema, services = [], logger = DEFAULT_LOGGER$1, publisherService, topicName) {
|
|
12
12
|
super(require_Construct.ConstructType.Subscriber, logger, services, [], publisherService, outputSchema);
|
|
13
13
|
this.handler = handler;
|
|
14
14
|
this.timeout = timeout;
|
|
@@ -17,6 +17,7 @@ var Subscriber = class extends require_Construct.Construct {
|
|
|
17
17
|
this.services = services;
|
|
18
18
|
this.logger = logger;
|
|
19
19
|
this.publisherService = publisherService;
|
|
20
|
+
this.topicName = topicName;
|
|
20
21
|
}
|
|
21
22
|
get subscribedEvents() {
|
|
22
23
|
return this._subscribedEvents;
|
|
@@ -32,9 +33,25 @@ var SubscriberBuilder = class {
|
|
|
32
33
|
_services = [];
|
|
33
34
|
_logger = __geekmidas_logger_console.DEFAULT_LOGGER;
|
|
34
35
|
_publisher;
|
|
36
|
+
_topicName;
|
|
35
37
|
constructor() {
|
|
36
38
|
this._timeout = 3e4;
|
|
37
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* Bind this subscriber to a {@link Topic} — the preferred way to type and wire
|
|
42
|
+
* a fan-out consumer. It supplies the subscribable event types (and their
|
|
43
|
+
* payloads) from the topic's contract and records the binding for the manifest,
|
|
44
|
+
* so infra wires the SNS subscription.
|
|
45
|
+
*
|
|
46
|
+
* Prefer this over typing via a hand-written publisher service: a consumer does
|
|
47
|
+
* not publish, so binding a topic does *not* require the topic's publisher
|
|
48
|
+
* connection string (least privilege). Use `.publisher(...)` only when the
|
|
49
|
+
* subscriber actually publishes follow-up events.
|
|
50
|
+
*/
|
|
51
|
+
topic(topic) {
|
|
52
|
+
this._topicName = topic.name;
|
|
53
|
+
return this;
|
|
54
|
+
}
|
|
38
55
|
timeout(timeout) {
|
|
39
56
|
this._timeout = timeout;
|
|
40
57
|
return this;
|
|
@@ -61,10 +78,11 @@ var SubscriberBuilder = class {
|
|
|
61
78
|
return this;
|
|
62
79
|
}
|
|
63
80
|
handle(fn) {
|
|
64
|
-
const subscriber = new Subscriber(fn, this._timeout, this._subscribedEvents, this.outputSchema, this._services, this._logger, this._publisher);
|
|
81
|
+
const subscriber = new Subscriber(fn, this._timeout, this._subscribedEvents, this.outputSchema, this._services, this._logger, this._publisher, this._topicName);
|
|
65
82
|
this._services = [];
|
|
66
83
|
this._logger = __geekmidas_logger_console.DEFAULT_LOGGER;
|
|
67
84
|
this._publisher = void 0;
|
|
85
|
+
this._topicName = void 0;
|
|
68
86
|
this._subscribedEvents = [];
|
|
69
87
|
this._timeout = 3e4;
|
|
70
88
|
this.outputSchema = void 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["DEFAULT_LOGGER","ConsoleLogger","Construct","obj: any","ConstructType","handler: SubscriberHandler<\n\t\t\tTEventPublisher,\n\t\t\tTSubscribedEvents,\n\t\t\tTServices,\n\t\t\tTLogger,\n\t\t\tOutSchema\n\t\t>","timeout: number","_subscribedEvents?: TSubscribedEvents","outputSchema?: OutSchema","services: TServices","logger: TLogger","publisherService?: Service<\n\t\t\tTEventPublisherServiceName,\n\t\t\tTEventPublisher\n\t\t>","DEFAULT_LOGGER","timeout: number","schema: T","services: T","logger: T","publisher: Service<TName, T>","event: TEvent","fn: SubscriberHandler<\n\t\t\tTEventPublisher,\n\t\t\tTSubscribedEvents,\n\t\t\tTServices,\n\t\t\tTLogger,\n\t\t\tOutSchema\n\t\t>"],"sources":["../../src/subscribers/Subscriber.ts","../../src/subscribers/SubscriberBuilder.ts","../../src/subscribers/index.ts"],"sourcesContent":["import type {\n\tEventPublisher,\n\tExtractPublisherMessage,\n} from '@geekmidas/events';\nimport type { Logger } from '@geekmidas/logger';\nimport { ConsoleLogger } from '@geekmidas/logger/console';\nimport type { InferStandardSchema } from '@geekmidas/schema';\nimport type { Service, ServiceRecord } from '@geekmidas/services';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { Construct, ConstructType } from '../Construct';\n\nconst DEFAULT_LOGGER = new ConsoleLogger() as any;\n\n// Helper type to extract payload types for subscribed events\ntype ExtractEventPayloads<\n\tTPublisher extends EventPublisher<any> | undefined,\n\tTEventTypes extends any[],\n> = TPublisher extends EventPublisher<any>\n\t? Extract<ExtractPublisherMessage<TPublisher>, { type: TEventTypes[number] }>\n\t: never;\n\nexport class Subscriber<\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n\tOutSchema extends StandardSchemaV1 | undefined = undefined,\n\tTEventPublisher extends EventPublisher<any> | undefined = undefined,\n\tTEventPublisherServiceName extends string = string,\n\tTSubscribedEvents extends\n\t\tExtractPublisherMessage<TEventPublisher>['type'][] = ExtractPublisherMessage<TEventPublisher>['type'][],\n> extends Construct<\n\tTLogger,\n\tTEventPublisherServiceName,\n\tTEventPublisher,\n\tOutSchema,\n\tTServices\n> {\n\t__IS_SUBSCRIBER__ = true;\n\n\tstatic isSubscriber(\n\t\tobj: any,\n\t): obj is Subscriber<any, any, any, any, any, any> {\n\t\treturn Boolean(\n\t\t\tobj &&\n\t\t\t\tobj.__IS_SUBSCRIBER__ === true &&\n\t\t\t\tobj.type === ConstructType.Subscriber,\n\t\t);\n\t}\n\n\tconstructor(\n\t\tpublic readonly handler: SubscriberHandler<\n\t\t\tTEventPublisher,\n\t\t\tTSubscribedEvents,\n\t\t\tTServices,\n\t\t\tTLogger,\n\t\t\tOutSchema\n\t\t>,\n\t\tpublic override readonly timeout: number = 30000,\n\t\tprotected _subscribedEvents?: TSubscribedEvents,\n\t\tpublic override readonly outputSchema?: OutSchema,\n\t\tpublic override readonly services: TServices = [] as unknown as TServices,\n\t\tpublic override readonly logger: TLogger = DEFAULT_LOGGER as TLogger,\n\t\tpublic override readonly publisherService?: Service<\n\t\t\tTEventPublisherServiceName,\n\t\t\tTEventPublisher\n\t\t>,\n\t) {\n\t\tsuper(\n\t\t\tConstructType.Subscriber,\n\t\t\tlogger,\n\t\t\tservices,\n\t\t\t[],\n\t\t\tpublisherService,\n\t\t\toutputSchema,\n\t\t);\n\t}\n\n\tget subscribedEvents(): TSubscribedEvents | undefined {\n\t\treturn this._subscribedEvents;\n\t}\n}\n\n// Handler type for subscribers that receives an array of events\nexport type SubscriberHandler<\n\tTEventPublisher extends EventPublisher<any> | undefined,\n\tTSubscribedEvents extends ExtractPublisherMessage<TEventPublisher>['type'][],\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n\tOutSchema extends StandardSchemaV1 | undefined = undefined,\n> = (\n\tctx: SubscriberContext<\n\t\tTEventPublisher,\n\t\tTSubscribedEvents,\n\t\tTServices,\n\t\tTLogger\n\t>,\n) => OutSchema extends StandardSchemaV1\n\t? InferStandardSchema<OutSchema> | Promise<InferStandardSchema<OutSchema>>\n\t: any | Promise<any>;\n\n// Context type for subscriber handlers\nexport type SubscriberContext<\n\tTEventPublisher extends EventPublisher<any> | undefined,\n\tTSubscribedEvents extends ExtractPublisherMessage<TEventPublisher>['type'][],\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n> = {\n\tevents: ExtractEventPayloads<TEventPublisher, TSubscribedEvents>[];\n\tservices: ServiceRecord<TServices>;\n\tlogger: TLogger;\n};\n","import type {\n\tEventPublisher,\n\tExtractPublisherMessage,\n} from '@geekmidas/events';\nimport type { Logger } from '@geekmidas/logger';\nimport { DEFAULT_LOGGER } from '@geekmidas/logger/console';\nimport type { Service } from '@geekmidas/services';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { Subscriber, type SubscriberHandler } from './Subscriber';\n\nexport class SubscriberBuilder<\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n\tOutSchema extends StandardSchemaV1 | undefined = undefined,\n\tTEventPublisher extends EventPublisher<any> | undefined = undefined,\n\tTEventPublisherServiceName extends string = string,\n\tTSubscribedEvents extends any[] = [],\n> {\n\tprivate _subscribedEvents: TSubscribedEvents = [] as any;\n\tprivate _timeout?: number;\n\tprivate outputSchema?: OutSchema;\n\tprivate _services: TServices = [] as Service[] as TServices;\n\tprivate _logger: TLogger = DEFAULT_LOGGER;\n\tprivate _publisher?: Service<TEventPublisherServiceName, TEventPublisher>;\n\n\tconstructor() {\n\t\tthis._timeout = 30000; // Default timeout\n\t}\n\n\ttimeout(timeout: number): this {\n\t\tthis._timeout = timeout;\n\t\treturn this;\n\t}\n\n\toutput<T extends StandardSchemaV1>(\n\t\tschema: T,\n\t): SubscriberBuilder<\n\t\tTServices,\n\t\tTLogger,\n\t\tT,\n\t\tTEventPublisher,\n\t\tTEventPublisherServiceName,\n\t\tTSubscribedEvents\n\t> {\n\t\tthis.outputSchema = schema as unknown as OutSchema;\n\t\treturn this as any;\n\t}\n\n\tservices<T extends Service[]>(\n\t\tservices: T,\n\t): SubscriberBuilder<\n\t\t[...TServices, ...T],\n\t\tTLogger,\n\t\tOutSchema,\n\t\tTEventPublisher,\n\t\tTEventPublisherServiceName,\n\t\tTSubscribedEvents\n\t> {\n\t\tthis._services = [...this._services, ...services] as any;\n\t\treturn this as any;\n\t}\n\n\tlogger<T extends Logger>(\n\t\tlogger: T,\n\t): SubscriberBuilder<\n\t\tTServices,\n\t\tT,\n\t\tOutSchema,\n\t\tTEventPublisher,\n\t\tTEventPublisherServiceName,\n\t\tTSubscribedEvents\n\t> {\n\t\tthis._logger = logger as unknown as TLogger;\n\t\treturn this as any;\n\t}\n\n\tpublisher<T extends EventPublisher<any>, TName extends string>(\n\t\tpublisher: Service<TName, T>,\n\t): SubscriberBuilder<\n\t\tTServices,\n\t\tTLogger,\n\t\tOutSchema,\n\t\tT,\n\t\tTName,\n\t\tTSubscribedEvents\n\t> {\n\t\tthis._publisher = publisher as any;\n\t\treturn this as any;\n\t}\n\n\tsubscribe<\n\t\tTEvent extends TEventPublisher extends EventPublisher<any>\n\t\t\t?\n\t\t\t\t\t| ExtractPublisherMessage<TEventPublisher>['type']\n\t\t\t\t\t| ExtractPublisherMessage<TEventPublisher>['type'][]\n\t\t\t: never,\n\t>(\n\t\tevent: TEvent,\n\t): SubscriberBuilder<\n\t\tTServices,\n\t\tTLogger,\n\t\tOutSchema,\n\t\tTEventPublisher,\n\t\tTEventPublisherServiceName,\n\t\tTEvent extends any[]\n\t\t\t? [...TSubscribedEvents, ...TEvent]\n\t\t\t: [...TSubscribedEvents, TEvent]\n\t> {\n\t\tconst eventsToAdd = Array.isArray(event) ? event : [event];\n\t\tthis._subscribedEvents = [...this._subscribedEvents, ...eventsToAdd] as any;\n\t\treturn this as any;\n\t}\n\n\thandle(\n\t\tfn: SubscriberHandler<\n\t\t\tTEventPublisher,\n\t\t\tTSubscribedEvents,\n\t\t\tTServices,\n\t\t\tTLogger,\n\t\t\tOutSchema\n\t\t>,\n\t): Subscriber<\n\t\tTServices,\n\t\tTLogger,\n\t\tOutSchema,\n\t\tTEventPublisher,\n\t\tTEventPublisherServiceName,\n\t\tTSubscribedEvents\n\t> {\n\t\tconst subscriber = new Subscriber(\n\t\t\tfn,\n\t\t\tthis._timeout,\n\t\t\tthis._subscribedEvents,\n\t\t\tthis.outputSchema,\n\t\t\tthis._services,\n\t\t\tthis._logger,\n\t\t\tthis._publisher,\n\t\t);\n\n\t\t// Reset builder state after creating the subscriber to prevent pollution\n\t\tthis._services = [] as Service[] as TServices;\n\t\tthis._logger = DEFAULT_LOGGER;\n\t\tthis._publisher = undefined;\n\t\tthis._subscribedEvents = [] as any;\n\t\tthis._timeout = 30000; // Reset to default\n\t\tthis.outputSchema = undefined;\n\n\t\treturn subscriber;\n\t}\n}\n","import { SubscriberBuilder } from './SubscriberBuilder';\n\nexport { Subscriber } from './Subscriber';\nexport { SubscriberBuilder };\n\nexport const s = new SubscriberBuilder();\n"],"mappings":";;;;AAWA,MAAMA,mBAAiB,IAAIC;AAU3B,IAAa,aAAb,cAQUC,4BAMR;CACD,oBAAoB;CAEpB,OAAO,aACNC,KACkD;AAClD,SAAO,QACN,OACC,IAAI,sBAAsB,QAC1B,IAAI,SAASC,gCAAc,WAC5B;CACD;CAED,YACiBC,SAOSC,UAAkB,KACjCC,mBACeC,cACAC,WAAsB,CAAE,GACxBC,SAAkBV,kBAClBW,kBAIxB;AACD,QACCP,gCAAc,YACd,QACA,UACA,CAAE,GACF,kBACA,aACA;EAxBe;EAOS;EACf;EACe;EACA;EACA;EACA;CAazB;CAED,IAAI,mBAAkD;AACrD,SAAO,KAAK;CACZ;AACD;;;;ACrED,IAAa,oBAAb,MAOE;CACD,AAAQ,oBAAuC,CAAE;CACjD,AAAQ;CACR,AAAQ;CACR,AAAQ,YAAuB,CAAE;CACjC,AAAQ,UAAmBQ;CAC3B,AAAQ;CAER,cAAc;AACb,OAAK,WAAW;CAChB;CAED,QAAQC,SAAuB;AAC9B,OAAK,WAAW;AAChB,SAAO;CACP;CAED,OACCC,QAQC;AACD,OAAK,eAAe;AACpB,SAAO;CACP;CAED,SACCC,UAQC;AACD,OAAK,YAAY,CAAC,GAAG,KAAK,WAAW,GAAG,QAAS;AACjD,SAAO;CACP;CAED,OACCC,QAQC;AACD,OAAK,UAAU;AACf,SAAO;CACP;CAED,UACCC,WAQC;AACD,OAAK,aAAa;AAClB,SAAO;CACP;CAED,UAOCC,OAUC;EACD,MAAM,cAAc,MAAM,QAAQ,MAAM,GAAG,QAAQ,CAAC,KAAM;AAC1D,OAAK,oBAAoB,CAAC,GAAG,KAAK,mBAAmB,GAAG,WAAY;AACpE,SAAO;CACP;CAED,OACCC,IAcC;EACD,MAAM,aAAa,IAAI,WACtB,IACA,KAAK,UACL,KAAK,mBACL,KAAK,cACL,KAAK,WACL,KAAK,SACL,KAAK;AAIN,OAAK,YAAY,CAAE;AACnB,OAAK,UAAUP;AACf,OAAK;AACL,OAAK,oBAAoB,CAAE;AAC3B,OAAK,WAAW;AAChB,OAAK;AAEL,SAAO;CACP;AACD;;;;AChJD,MAAa,IAAI,IAAI"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["DEFAULT_LOGGER","ConsoleLogger","Construct","obj: any","ConstructType","handler: SubscriberHandler<\n\t\t\tTEventPublisher,\n\t\t\tTSubscribedEvents,\n\t\t\tTServices,\n\t\t\tTLogger,\n\t\t\tOutSchema\n\t\t>","timeout: number","_subscribedEvents?: TSubscribedEvents","outputSchema?: OutSchema","services: TServices","logger: TLogger","publisherService?: Service<\n\t\t\tTEventPublisherServiceName,\n\t\t\tTEventPublisher\n\t\t>","topicName?: string","DEFAULT_LOGGER","topic: Topic<TName, TEvents>","timeout: number","schema: T","services: T","logger: T","publisher: Service<TName, T>","event: TEvent","fn: SubscriberHandler<\n\t\t\tTEventPublisher,\n\t\t\tTSubscribedEvents,\n\t\t\tTServices,\n\t\t\tTLogger,\n\t\t\tOutSchema\n\t\t>"],"sources":["../../src/subscribers/Subscriber.ts","../../src/subscribers/SubscriberBuilder.ts","../../src/subscribers/index.ts"],"sourcesContent":["import type {\n\tEventPublisher,\n\tExtractPublisherMessage,\n} from '@geekmidas/events';\nimport type { Logger } from '@geekmidas/logger';\nimport { ConsoleLogger } from '@geekmidas/logger/console';\nimport type { InferStandardSchema } from '@geekmidas/schema';\nimport type { Service, ServiceRecord } from '@geekmidas/services';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { Construct, ConstructType } from '../Construct';\n\nconst DEFAULT_LOGGER = new ConsoleLogger() as any;\n\n// Helper type to extract payload types for subscribed events\ntype ExtractEventPayloads<\n\tTPublisher extends EventPublisher<any> | undefined,\n\tTEventTypes extends any[],\n> = TPublisher extends EventPublisher<any>\n\t? Extract<ExtractPublisherMessage<TPublisher>, { type: TEventTypes[number] }>\n\t: never;\n\nexport class Subscriber<\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n\tOutSchema extends StandardSchemaV1 | undefined = undefined,\n\tTEventPublisher extends EventPublisher<any> | undefined = undefined,\n\tTEventPublisherServiceName extends string = string,\n\tTSubscribedEvents extends\n\t\tExtractPublisherMessage<TEventPublisher>['type'][] = ExtractPublisherMessage<TEventPublisher>['type'][],\n> extends Construct<\n\tTLogger,\n\tTEventPublisherServiceName,\n\tTEventPublisher,\n\tOutSchema,\n\tTServices\n> {\n\t__IS_SUBSCRIBER__ = true;\n\n\tstatic isSubscriber(\n\t\tobj: any,\n\t): obj is Subscriber<any, any, any, any, any, any> {\n\t\treturn Boolean(\n\t\t\tobj &&\n\t\t\t\tobj.__IS_SUBSCRIBER__ === true &&\n\t\t\t\tobj.type === ConstructType.Subscriber,\n\t\t);\n\t}\n\n\tconstructor(\n\t\tpublic readonly handler: SubscriberHandler<\n\t\t\tTEventPublisher,\n\t\t\tTSubscribedEvents,\n\t\t\tTServices,\n\t\t\tTLogger,\n\t\t\tOutSchema\n\t\t>,\n\t\tpublic override readonly timeout: number = 30000,\n\t\tprotected _subscribedEvents?: TSubscribedEvents,\n\t\tpublic override readonly outputSchema?: OutSchema,\n\t\tpublic override readonly services: TServices = [] as unknown as TServices,\n\t\tpublic override readonly logger: TLogger = DEFAULT_LOGGER as TLogger,\n\t\tpublic override readonly publisherService?: Service<\n\t\t\tTEventPublisherServiceName,\n\t\t\tTEventPublisher\n\t\t>,\n\t\t/**\n\t\t * The name of the {@link Topic} this subscriber binds to (via\n\t\t * `s.topic(topic)`), recorded for the manifest so infra wires the SNS\n\t\t * subscription. Undefined when the subscriber's events are typed from a\n\t\t * (hand-written) publisher instead.\n\t\t */\n\t\tpublic readonly topicName?: string,\n\t) {\n\t\tsuper(\n\t\t\tConstructType.Subscriber,\n\t\t\tlogger,\n\t\t\tservices,\n\t\t\t[],\n\t\t\tpublisherService,\n\t\t\toutputSchema,\n\t\t);\n\t}\n\n\tget subscribedEvents(): TSubscribedEvents | undefined {\n\t\treturn this._subscribedEvents;\n\t}\n}\n\n// Handler type for subscribers that receives an array of events\nexport type SubscriberHandler<\n\tTEventPublisher extends EventPublisher<any> | undefined,\n\tTSubscribedEvents extends ExtractPublisherMessage<TEventPublisher>['type'][],\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n\tOutSchema extends StandardSchemaV1 | undefined = undefined,\n> = (\n\tctx: SubscriberContext<\n\t\tTEventPublisher,\n\t\tTSubscribedEvents,\n\t\tTServices,\n\t\tTLogger\n\t>,\n) => OutSchema extends StandardSchemaV1\n\t? InferStandardSchema<OutSchema> | Promise<InferStandardSchema<OutSchema>>\n\t: any | Promise<any>;\n\n// Context type for subscriber handlers\nexport type SubscriberContext<\n\tTEventPublisher extends EventPublisher<any> | undefined,\n\tTSubscribedEvents extends ExtractPublisherMessage<TEventPublisher>['type'][],\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n> = {\n\tevents: ExtractEventPayloads<TEventPublisher, TSubscribedEvents>[];\n\tservices: ServiceRecord<TServices>;\n\tlogger: TLogger;\n};\n","import type {\n\tEventPublisher,\n\tExtractPublisherMessage,\n} from '@geekmidas/events';\nimport type { Logger } from '@geekmidas/logger';\nimport { DEFAULT_LOGGER } from '@geekmidas/logger/console';\nimport type { Service } from '@geekmidas/services';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport type { Topic, TopicEvents, TopicMessage } from '../topic/Topic';\nimport { Subscriber, type SubscriberHandler } from './Subscriber';\n\nexport class SubscriberBuilder<\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n\tOutSchema extends StandardSchemaV1 | undefined = undefined,\n\tTEventPublisher extends EventPublisher<any> | undefined = undefined,\n\tTEventPublisherServiceName extends string = string,\n\tTSubscribedEvents extends any[] = [],\n> {\n\tprivate _subscribedEvents: TSubscribedEvents = [] as any;\n\tprivate _timeout?: number;\n\tprivate outputSchema?: OutSchema;\n\tprivate _services: TServices = [] as Service[] as TServices;\n\tprivate _logger: TLogger = DEFAULT_LOGGER;\n\tprivate _publisher?: Service<TEventPublisherServiceName, TEventPublisher>;\n\tprivate _topicName?: string;\n\n\tconstructor() {\n\t\tthis._timeout = 30000; // Default timeout\n\t}\n\n\t/**\n\t * Bind this subscriber to a {@link Topic} — the preferred way to type and wire\n\t * a fan-out consumer. It supplies the subscribable event types (and their\n\t * payloads) from the topic's contract and records the binding for the manifest,\n\t * so infra wires the SNS subscription.\n\t *\n\t * Prefer this over typing via a hand-written publisher service: a consumer does\n\t * not publish, so binding a topic does *not* require the topic's publisher\n\t * connection string (least privilege). Use `.publisher(...)` only when the\n\t * subscriber actually publishes follow-up events.\n\t */\n\ttopic<TName extends string, TEvents extends TopicEvents>(\n\t\ttopic: Topic<TName, TEvents>,\n\t): SubscriberBuilder<\n\t\tTServices,\n\t\tTLogger,\n\t\tOutSchema,\n\t\tEventPublisher<TopicMessage<TEvents>>,\n\t\tTEventPublisherServiceName,\n\t\tTSubscribedEvents\n\t> {\n\t\tthis._topicName = topic.name;\n\t\treturn this as unknown as SubscriberBuilder<\n\t\t\tTServices,\n\t\t\tTLogger,\n\t\t\tOutSchema,\n\t\t\tEventPublisher<TopicMessage<TEvents>>,\n\t\t\tTEventPublisherServiceName,\n\t\t\tTSubscribedEvents\n\t\t>;\n\t}\n\n\ttimeout(timeout: number): this {\n\t\tthis._timeout = timeout;\n\t\treturn this;\n\t}\n\n\toutput<T extends StandardSchemaV1>(\n\t\tschema: T,\n\t): SubscriberBuilder<\n\t\tTServices,\n\t\tTLogger,\n\t\tT,\n\t\tTEventPublisher,\n\t\tTEventPublisherServiceName,\n\t\tTSubscribedEvents\n\t> {\n\t\tthis.outputSchema = schema as unknown as OutSchema;\n\t\treturn this as any;\n\t}\n\n\tservices<T extends Service[]>(\n\t\tservices: T,\n\t): SubscriberBuilder<\n\t\t[...TServices, ...T],\n\t\tTLogger,\n\t\tOutSchema,\n\t\tTEventPublisher,\n\t\tTEventPublisherServiceName,\n\t\tTSubscribedEvents\n\t> {\n\t\tthis._services = [...this._services, ...services] as any;\n\t\treturn this as any;\n\t}\n\n\tlogger<T extends Logger>(\n\t\tlogger: T,\n\t): SubscriberBuilder<\n\t\tTServices,\n\t\tT,\n\t\tOutSchema,\n\t\tTEventPublisher,\n\t\tTEventPublisherServiceName,\n\t\tTSubscribedEvents\n\t> {\n\t\tthis._logger = logger as unknown as TLogger;\n\t\treturn this as any;\n\t}\n\n\tpublisher<T extends EventPublisher<any>, TName extends string>(\n\t\tpublisher: Service<TName, T>,\n\t): SubscriberBuilder<\n\t\tTServices,\n\t\tTLogger,\n\t\tOutSchema,\n\t\tT,\n\t\tTName,\n\t\tTSubscribedEvents\n\t> {\n\t\tthis._publisher = publisher as any;\n\t\treturn this as any;\n\t}\n\n\tsubscribe<\n\t\tTEvent extends TEventPublisher extends EventPublisher<any>\n\t\t\t?\n\t\t\t\t\t| ExtractPublisherMessage<TEventPublisher>['type']\n\t\t\t\t\t| ExtractPublisherMessage<TEventPublisher>['type'][]\n\t\t\t: never,\n\t>(\n\t\tevent: TEvent,\n\t): SubscriberBuilder<\n\t\tTServices,\n\t\tTLogger,\n\t\tOutSchema,\n\t\tTEventPublisher,\n\t\tTEventPublisherServiceName,\n\t\tTEvent extends any[]\n\t\t\t? [...TSubscribedEvents, ...TEvent]\n\t\t\t: [...TSubscribedEvents, TEvent]\n\t> {\n\t\tconst eventsToAdd = Array.isArray(event) ? event : [event];\n\t\tthis._subscribedEvents = [...this._subscribedEvents, ...eventsToAdd] as any;\n\t\treturn this as any;\n\t}\n\n\thandle(\n\t\tfn: SubscriberHandler<\n\t\t\tTEventPublisher,\n\t\t\tTSubscribedEvents,\n\t\t\tTServices,\n\t\t\tTLogger,\n\t\t\tOutSchema\n\t\t>,\n\t): Subscriber<\n\t\tTServices,\n\t\tTLogger,\n\t\tOutSchema,\n\t\tTEventPublisher,\n\t\tTEventPublisherServiceName,\n\t\tTSubscribedEvents\n\t> {\n\t\tconst subscriber = new Subscriber(\n\t\t\tfn,\n\t\t\tthis._timeout,\n\t\t\tthis._subscribedEvents,\n\t\t\tthis.outputSchema,\n\t\t\tthis._services,\n\t\t\tthis._logger,\n\t\t\tthis._publisher,\n\t\t\tthis._topicName,\n\t\t);\n\n\t\t// Reset builder state after creating the subscriber to prevent pollution\n\t\tthis._services = [] as Service[] as TServices;\n\t\tthis._logger = DEFAULT_LOGGER;\n\t\tthis._publisher = undefined;\n\t\tthis._topicName = undefined;\n\t\tthis._subscribedEvents = [] as any;\n\t\tthis._timeout = 30000; // Reset to default\n\t\tthis.outputSchema = undefined;\n\n\t\treturn subscriber;\n\t}\n}\n","import { SubscriberBuilder } from './SubscriberBuilder';\n\nexport { Subscriber } from './Subscriber';\nexport { SubscriberBuilder };\n\nexport const s = new SubscriberBuilder();\n"],"mappings":";;;;AAWA,MAAMA,mBAAiB,IAAIC;AAU3B,IAAa,aAAb,cAQUC,4BAMR;CACD,oBAAoB;CAEpB,OAAO,aACNC,KACkD;AAClD,SAAO,QACN,OACC,IAAI,sBAAsB,QAC1B,IAAI,SAASC,gCAAc,WAC5B;CACD;CAED,YACiBC,SAOSC,UAAkB,KACjCC,mBACeC,cACAC,WAAsB,CAAE,GACxBC,SAAkBV,kBAClBW,kBAUTC,WACf;AACD,QACCR,gCAAc,YACd,QACA,UACA,CAAE,GACF,kBACA,aACA;EA/Be;EAOS;EACf;EACe;EACA;EACA;EACA;EAUT;CAUhB;CAED,IAAI,mBAAkD;AACrD,SAAO,KAAK;CACZ;AACD;;;;AC3ED,IAAa,oBAAb,MAOE;CACD,AAAQ,oBAAuC,CAAE;CACjD,AAAQ;CACR,AAAQ;CACR,AAAQ,YAAuB,CAAE;CACjC,AAAQ,UAAmBS;CAC3B,AAAQ;CACR,AAAQ;CAER,cAAc;AACb,OAAK,WAAW;CAChB;;;;;;;;;;;;CAaD,MACCC,OAQC;AACD,OAAK,aAAa,MAAM;AACxB,SAAO;CAQP;CAED,QAAQC,SAAuB;AAC9B,OAAK,WAAW;AAChB,SAAO;CACP;CAED,OACCC,QAQC;AACD,OAAK,eAAe;AACpB,SAAO;CACP;CAED,SACCC,UAQC;AACD,OAAK,YAAY,CAAC,GAAG,KAAK,WAAW,GAAG,QAAS;AACjD,SAAO;CACP;CAED,OACCC,QAQC;AACD,OAAK,UAAU;AACf,SAAO;CACP;CAED,UACCC,WAQC;AACD,OAAK,aAAa;AAClB,SAAO;CACP;CAED,UAOCC,OAUC;EACD,MAAM,cAAc,MAAM,QAAQ,MAAM,GAAG,QAAQ,CAAC,KAAM;AAC1D,OAAK,oBAAoB,CAAC,GAAG,KAAK,mBAAmB,GAAG,WAAY;AACpE,SAAO;CACP;CAED,OACCC,IAcC;EACD,MAAM,aAAa,IAAI,WACtB,IACA,KAAK,UACL,KAAK,mBACL,KAAK,cACL,KAAK,WACL,KAAK,SACL,KAAK,YACL,KAAK;AAIN,OAAK,YAAY,CAAE;AACnB,OAAK,UAAUR;AACf,OAAK;AACL,OAAK;AACL,OAAK,oBAAoB,CAAE;AAC3B,OAAK,WAAW;AAChB,OAAK;AAEL,SAAO;CACP;AACD;;;;ACpLD,MAAa,IAAI,IAAI"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import "../Construct-
|
|
2
|
-
import { Subscriber, SubscriberHandler } from "../Subscriber-
|
|
1
|
+
import "../Construct-_1wX7p_Y.cjs";
|
|
2
|
+
import { Subscriber, SubscriberHandler } from "../Subscriber-B69ngPwl.cjs";
|
|
3
|
+
import { Topic, TopicEvents, TopicMessage } from "../Topic-C5ZMfveW.cjs";
|
|
3
4
|
import { EventPublisher, ExtractPublisherMessage } from "@geekmidas/events";
|
|
4
|
-
import * as
|
|
5
|
+
import * as _geekmidas_logger3 from "@geekmidas/logger";
|
|
5
6
|
import { Logger } from "@geekmidas/logger";
|
|
6
7
|
import { Service } from "@geekmidas/services";
|
|
7
8
|
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
@@ -14,7 +15,20 @@ declare class SubscriberBuilder<TServices extends Service[] = [], TLogger extend
|
|
|
14
15
|
private _services;
|
|
15
16
|
private _logger;
|
|
16
17
|
private _publisher?;
|
|
18
|
+
private _topicName?;
|
|
17
19
|
constructor();
|
|
20
|
+
/**
|
|
21
|
+
* Bind this subscriber to a {@link Topic} — the preferred way to type and wire
|
|
22
|
+
* a fan-out consumer. It supplies the subscribable event types (and their
|
|
23
|
+
* payloads) from the topic's contract and records the binding for the manifest,
|
|
24
|
+
* so infra wires the SNS subscription.
|
|
25
|
+
*
|
|
26
|
+
* Prefer this over typing via a hand-written publisher service: a consumer does
|
|
27
|
+
* not publish, so binding a topic does *not* require the topic's publisher
|
|
28
|
+
* connection string (least privilege). Use `.publisher(...)` only when the
|
|
29
|
+
* subscriber actually publishes follow-up events.
|
|
30
|
+
*/
|
|
31
|
+
topic<TName extends string, TEvents extends TopicEvents>(topic: Topic<TName, TEvents>): SubscriberBuilder<TServices, TLogger, OutSchema, EventPublisher<TopicMessage<TEvents>>, TEventPublisherServiceName, TSubscribedEvents>;
|
|
18
32
|
timeout(timeout: number): this;
|
|
19
33
|
output<T extends StandardSchemaV1>(schema: T): SubscriberBuilder<TServices, TLogger, T, TEventPublisher, TEventPublisherServiceName, TSubscribedEvents>;
|
|
20
34
|
services<T extends Service[]>(services: T): SubscriberBuilder<[...TServices, ...T], TLogger, OutSchema, TEventPublisher, TEventPublisherServiceName, TSubscribedEvents>;
|
|
@@ -26,7 +40,7 @@ declare class SubscriberBuilder<TServices extends Service[] = [], TLogger extend
|
|
|
26
40
|
//# sourceMappingURL=SubscriberBuilder.d.ts.map
|
|
27
41
|
//#endregion
|
|
28
42
|
//#region src/subscribers/index.d.ts
|
|
29
|
-
declare const s: SubscriberBuilder<[],
|
|
43
|
+
declare const s: SubscriberBuilder<[], _geekmidas_logger3.Logger, undefined, undefined, string, []>;
|
|
30
44
|
//# sourceMappingURL=index.d.ts.map
|
|
31
45
|
|
|
32
46
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/subscribers/SubscriberBuilder.ts","../../src/subscribers/index.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/subscribers/SubscriberBuilder.ts","../../src/subscribers/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;cAWa,oCACM,gCACF,SAAS,0BACP,kEACM;;;;EAJZ,QAAA,SAAA;EAAiB,QAAA,OAAA;EAAA,QACX,UAAA;EAAO,QACT,UAAA;EAAM,WAAG,CAAA;EAAM;;;;;;;;;;;EAmCH,KAA3B,CAAA,cAAA,MAAA,EAAA,gBAN2C,WAM3C,CAAA,CAAA,KAAA,EALO,KAKP,CALa,KAKb,EALoB,OAKpB,CAAA,CAAA,EAJE,iBAIF,CAHA,SAGA,EAFA,OAEA,EADA,SACA,EAAA,cAAA,CAAe,YAAf,CAA4B,OAA5B,CAAA,CAAA,EACA,0BADA,EAEA,iBAFA,CAAA;EAAc,OACd,CAAA,OAAA,EAAA,MAAA,CAAA,EAAA,IAAA;EAA0B,MAC1B,CAAA,UAkBgB,gBAlBhB,CAAA,CAAA,MAAA,EAmBQ,CAnBR,CAAA,EAoBE,iBApBF,CAqBA,SArBA,EAsBA,OAtBA,EAuBA,CAvBA,EAwBA,eAxBA,EAyBA,0BAzBA,EA0BA,iBA1BA,CAAA;EAAiB,QANf,CAAA,UAsCgB,OAtChB,EAAA,CAAA,CAAA,QAAA,EAuCQ,CAvCR,CAAA,EAwCA,iBAxCA,CAAA,CAwBc,GAiBZ,SAjBY,EACR,GAgBU,CAhBV,CAAC,EAiBT,OAfA,EAgBA,SAhBA,EAiBA,eAjBA,EAkBA,0BAlBA,EAmBA,iBAnBA,CAAA;EAAS,MACT,CAAA,UAwBgB,MAxBhB,CAAA,CAAA,MAAA,EAyBQ,CAzBR,CAAA,EA0BE,iBA1BF,CA2BA,SA3BA,EA4BA,CA5BA,EA6BA,SA7BA,EA8BA,eA9BA,EA+BA,0BA/BA,EAgCA,iBAhCA,CAAA;EAAO,SACP,CAAA,UAqCmB,cArCnB,CAAA,GAAA,CAAA,EAAA,cAAA,MAAA,CAAA,CAAA,SAAA,EAsCW,OAtCX,CAsCmB,KAtCnB,EAsC0B,CAtC1B,CAAA,CAAA,EAuCE,iBAvCF,CAwCA,SAxCA,EAyCA,OAzCA,EA0CA,SA1CA,EA2CA,CA3CA,EA4CA,KA5CA,EA6CA,iBA7CA,CAAA;EAAC,SACD,CAAA,gBAmDe,eAnDf,SAmDuC,cAnDvC,CAAA,GAAA,CAAA,GAqDK,uBArDL,CAqD6B,eArD7B,CAAA,CAAA,MAAA,CAAA,GAsDK,uBAtDL,CAsD6B,eAtD7B,CAAA,CAAA,MAAA,CAAA,EAAA,GAAA,KAAA,EAAA,CAAA,KAAA,EAyDO,MAzDP,CAAA,EA0DE,iBA1DF,CA2DA,SA3DA,EA4DA,OA5DA,EA6DA,SA7DA,EA8DA,eA9DA,EA+DA,0BA/DA,EAgEA,MAhEA,SAAA,GAAA,EAAA,GAAA,CAAA,GAiEO,iBAjEP,EAAA,GAiE6B,MAjE7B,CAAA,GAAA,CAAA,GAkEO,iBAlEP,EAkE0B,MAlE1B,CAAA,CAAA;EAAe,MACf,CAAA,EAAA,EAyEI,iBAzEJ,CA0EC,eA1ED,EA2EC,iBA3ED,EA4EC,SA5ED,EA6EC,OA7ED,EA8EC,SA9ED,CAAA,CAAA,EAgFE,UAhFF,CAiFA,SAjFA,EAkFA,OAlFA,EAmFA,SAnFA,EAoFA,eApFA,EAqFA,0BArFA,EAsFA,iBAtFA,CAAA;;;;;cCtEW,GAAC,sBAA0B,kBAAA,CAA1B,MAAA"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import "../Construct-
|
|
2
|
-
import { Subscriber, SubscriberHandler } from "../Subscriber-
|
|
1
|
+
import "../Construct-DCMuYOox.mjs";
|
|
2
|
+
import { Subscriber, SubscriberHandler } from "../Subscriber-D8Xm-86W.mjs";
|
|
3
|
+
import { Topic, TopicEvents, TopicMessage } from "../Topic-DT10AqHk.mjs";
|
|
3
4
|
import { Service } from "@geekmidas/services";
|
|
4
5
|
import { EventPublisher, ExtractPublisherMessage } from "@geekmidas/events";
|
|
5
6
|
import { Logger as Logger$1 } from "@geekmidas/logger";
|
|
@@ -13,7 +14,20 @@ declare class SubscriberBuilder<TServices extends Service[] = [], TLogger extend
|
|
|
13
14
|
private _services;
|
|
14
15
|
private _logger;
|
|
15
16
|
private _publisher?;
|
|
17
|
+
private _topicName?;
|
|
16
18
|
constructor();
|
|
19
|
+
/**
|
|
20
|
+
* Bind this subscriber to a {@link Topic} — the preferred way to type and wire
|
|
21
|
+
* a fan-out consumer. It supplies the subscribable event types (and their
|
|
22
|
+
* payloads) from the topic's contract and records the binding for the manifest,
|
|
23
|
+
* so infra wires the SNS subscription.
|
|
24
|
+
*
|
|
25
|
+
* Prefer this over typing via a hand-written publisher service: a consumer does
|
|
26
|
+
* not publish, so binding a topic does *not* require the topic's publisher
|
|
27
|
+
* connection string (least privilege). Use `.publisher(...)` only when the
|
|
28
|
+
* subscriber actually publishes follow-up events.
|
|
29
|
+
*/
|
|
30
|
+
topic<TName extends string, TEvents extends TopicEvents>(topic: Topic<TName, TEvents>): SubscriberBuilder<TServices, TLogger, OutSchema, EventPublisher<TopicMessage<TEvents>>, TEventPublisherServiceName, TSubscribedEvents>;
|
|
17
31
|
timeout(timeout: number): this;
|
|
18
32
|
output<T extends StandardSchemaV1>(schema: T): SubscriberBuilder<TServices, TLogger, T, TEventPublisher, TEventPublisherServiceName, TSubscribedEvents>;
|
|
19
33
|
services<T extends Service[]>(services: T): SubscriberBuilder<[...TServices, ...T], TLogger, OutSchema, TEventPublisher, TEventPublisherServiceName, TSubscribedEvents>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/subscribers/SubscriberBuilder.ts","../../src/subscribers/index.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/subscribers/SubscriberBuilder.ts","../../src/subscribers/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;cAWa,oCACM,gCACF,WAAS,4BACP,kEACM;;;EAJZ,QAAA,YAAiB;EAAA,QAAA,SAAA;EAAA,QACX,OAAA;EAAO,QACT,UAAA;EAAM,QAAG,UAAA;EAAM,WACb,CAAA;EAAgB;;;;;;;;;;;EAkCnB,KACd,CAAA,cAAA,MAAA,EAAA,gBAP2C,WAO3C,CAAA,CAAA,KAAA,EANO,KAMP,CANa,KAMb,EANoB,OAMpB,CAAA,CAAA,EALE,iBAKF,CAJA,SAIA,EAHA,OAGA,EAFA,SAEA,EADA,cACA,CADe,YACf,CAD4B,OAC5B,CAAA,CAAA,EAAA,0BAAA,EACA,iBADA,CAAA;EAA0B,OAC1B,CAAA,OAAA,EAAA,MAAA,CAAA,EAAA,IAAA;EAAiB,MANf,CAAA,UAwBc,gBAxBd,CAAA,CAAA,MAAA,EAyBM,CAzBN,CAAA,EA0BA,iBA1BA,CA2BF,SA3BE,EA4BF,OA5BE,EA6BF,CA7BE,EA8BF,eA9BE,EA+BF,0BA/BE,EAgCF,iBAhCE,CAAA;EAAiB,QAwBH,CAAA,UAcE,OAdF,EAAA,CAAA,CAAA,QAAA,EAeN,CAfM,CAAA,EAgBd,iBAhBc,CAAA,CACR,GAgBJ,SAhBI,EAER,GAckB,CAdlB,CAAS,EAeT,OAdA,EAeA,SAfA,EAgBA,eAhBA,EAiBA,0BAjBA,EAkBA,iBAlBA,CAAA;EAAO,MACP,CAAA,UAuBgB,QAvBhB,CAAA,CAAA,MAAA,EAwBQ,CAxBR,CAAA,EAyBE,iBAzBF,CA0BA,SA1BA,EA2BA,CA3BA,EA4BA,SA5BA,EA6BA,eA7BA,EA8BA,0BA9BA,EA+BA,iBA/BA,CAAA;EAAC,SACD,CAAA,UAoCmB,cApCnB,CAAA,GAAA,CAAA,EAAA,cAAA,MAAA,CAAA,CAAA,SAAA,EAqCW,OArCX,CAqCmB,KArCnB,EAqC0B,CArC1B,CAAA,CAAA,EAsCE,iBAtCF,CAuCA,SAvCA,EAwCA,OAxCA,EAyCA,SAzCA,EA0CA,CA1CA,EA2CA,KA3CA,EA4CA,iBA5CA,CAAA;EAAe,SACf,CAAA,gBAkDe,eAlDf,SAkDuC,cAlDvC,CAAA,GAAA,CAAA,GAoDK,uBApDL,CAoD6B,eApD7B,CAAA,CAAA,MAAA,CAAA,GAqDK,uBArDL,CAqD6B,eArD7B,CAAA,CAAA,MAAA,CAAA,EAAA,GAAA,KAAA,EAAA,CAAA,KAAA,EAwDO,MAxDP,CAAA,EAyDE,iBAzDF,CA0DA,SA1DA,EA2DA,OA3DA,EA4DA,SA5DA,EA6DA,eA7DA,EA8DA,0BA9DA,EA+DA,MA/DA,SAAA,GAAA,EAAA,GAAA,CAAA,GAgEO,iBAhEP,EAAA,GAgE6B,MAhE7B,CAAA,GAAA,CAAA,GAiEO,iBAjEP,EAiE0B,MAjE1B,CAAA,CAAA;EAA0B,MAC1B,CAAA,EAAA,EAwEI,iBAxEJ,CAyEC,eAzED,EA0EC,iBA1ED,EA2EC,SA3ED,EA4EC,OA5ED,EA6EC,SA7ED,CAAA,CAAA,EA+EE,UA/EF,CAgFA,SAhFA,EAiFA,OAjFA,EAkFA,SAlFA,EAmFA,eAnFA,EAoFA,0BApFA,EAqFA,iBArFA,CAAA;;;;;cCvEW,GAAC,sBAAA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Construct, ConstructType } from "../Construct-
|
|
1
|
+
import { Construct, ConstructType } from "../Construct-DD8EaWzh.mjs";
|
|
2
2
|
import { ConsoleLogger, DEFAULT_LOGGER } from "@geekmidas/logger/console";
|
|
3
3
|
|
|
4
4
|
//#region src/subscribers/Subscriber.ts
|
|
@@ -8,7 +8,7 @@ var Subscriber = class extends Construct {
|
|
|
8
8
|
static isSubscriber(obj) {
|
|
9
9
|
return Boolean(obj && obj.__IS_SUBSCRIBER__ === true && obj.type === ConstructType.Subscriber);
|
|
10
10
|
}
|
|
11
|
-
constructor(handler, timeout = 3e4, _subscribedEvents, outputSchema, services = [], logger = DEFAULT_LOGGER$1, publisherService) {
|
|
11
|
+
constructor(handler, timeout = 3e4, _subscribedEvents, outputSchema, services = [], logger = DEFAULT_LOGGER$1, publisherService, topicName) {
|
|
12
12
|
super(ConstructType.Subscriber, logger, services, [], publisherService, outputSchema);
|
|
13
13
|
this.handler = handler;
|
|
14
14
|
this.timeout = timeout;
|
|
@@ -17,6 +17,7 @@ var Subscriber = class extends Construct {
|
|
|
17
17
|
this.services = services;
|
|
18
18
|
this.logger = logger;
|
|
19
19
|
this.publisherService = publisherService;
|
|
20
|
+
this.topicName = topicName;
|
|
20
21
|
}
|
|
21
22
|
get subscribedEvents() {
|
|
22
23
|
return this._subscribedEvents;
|
|
@@ -32,9 +33,25 @@ var SubscriberBuilder = class {
|
|
|
32
33
|
_services = [];
|
|
33
34
|
_logger = DEFAULT_LOGGER;
|
|
34
35
|
_publisher;
|
|
36
|
+
_topicName;
|
|
35
37
|
constructor() {
|
|
36
38
|
this._timeout = 3e4;
|
|
37
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* Bind this subscriber to a {@link Topic} — the preferred way to type and wire
|
|
42
|
+
* a fan-out consumer. It supplies the subscribable event types (and their
|
|
43
|
+
* payloads) from the topic's contract and records the binding for the manifest,
|
|
44
|
+
* so infra wires the SNS subscription.
|
|
45
|
+
*
|
|
46
|
+
* Prefer this over typing via a hand-written publisher service: a consumer does
|
|
47
|
+
* not publish, so binding a topic does *not* require the topic's publisher
|
|
48
|
+
* connection string (least privilege). Use `.publisher(...)` only when the
|
|
49
|
+
* subscriber actually publishes follow-up events.
|
|
50
|
+
*/
|
|
51
|
+
topic(topic) {
|
|
52
|
+
this._topicName = topic.name;
|
|
53
|
+
return this;
|
|
54
|
+
}
|
|
38
55
|
timeout(timeout) {
|
|
39
56
|
this._timeout = timeout;
|
|
40
57
|
return this;
|
|
@@ -61,10 +78,11 @@ var SubscriberBuilder = class {
|
|
|
61
78
|
return this;
|
|
62
79
|
}
|
|
63
80
|
handle(fn) {
|
|
64
|
-
const subscriber = new Subscriber(fn, this._timeout, this._subscribedEvents, this.outputSchema, this._services, this._logger, this._publisher);
|
|
81
|
+
const subscriber = new Subscriber(fn, this._timeout, this._subscribedEvents, this.outputSchema, this._services, this._logger, this._publisher, this._topicName);
|
|
65
82
|
this._services = [];
|
|
66
83
|
this._logger = DEFAULT_LOGGER;
|
|
67
84
|
this._publisher = void 0;
|
|
85
|
+
this._topicName = void 0;
|
|
68
86
|
this._subscribedEvents = [];
|
|
69
87
|
this._timeout = 3e4;
|
|
70
88
|
this.outputSchema = void 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["DEFAULT_LOGGER","obj: any","handler: SubscriberHandler<\n\t\t\tTEventPublisher,\n\t\t\tTSubscribedEvents,\n\t\t\tTServices,\n\t\t\tTLogger,\n\t\t\tOutSchema\n\t\t>","timeout: number","_subscribedEvents?: TSubscribedEvents","outputSchema?: OutSchema","services: TServices","logger: TLogger","publisherService?: Service<\n\t\t\tTEventPublisherServiceName,\n\t\t\tTEventPublisher\n\t\t>","timeout: number","schema: T","services: T","logger: T","publisher: Service<TName, T>","event: TEvent","fn: SubscriberHandler<\n\t\t\tTEventPublisher,\n\t\t\tTSubscribedEvents,\n\t\t\tTServices,\n\t\t\tTLogger,\n\t\t\tOutSchema\n\t\t>"],"sources":["../../src/subscribers/Subscriber.ts","../../src/subscribers/SubscriberBuilder.ts","../../src/subscribers/index.ts"],"sourcesContent":["import type {\n\tEventPublisher,\n\tExtractPublisherMessage,\n} from '@geekmidas/events';\nimport type { Logger } from '@geekmidas/logger';\nimport { ConsoleLogger } from '@geekmidas/logger/console';\nimport type { InferStandardSchema } from '@geekmidas/schema';\nimport type { Service, ServiceRecord } from '@geekmidas/services';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { Construct, ConstructType } from '../Construct';\n\nconst DEFAULT_LOGGER = new ConsoleLogger() as any;\n\n// Helper type to extract payload types for subscribed events\ntype ExtractEventPayloads<\n\tTPublisher extends EventPublisher<any> | undefined,\n\tTEventTypes extends any[],\n> = TPublisher extends EventPublisher<any>\n\t? Extract<ExtractPublisherMessage<TPublisher>, { type: TEventTypes[number] }>\n\t: never;\n\nexport class Subscriber<\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n\tOutSchema extends StandardSchemaV1 | undefined = undefined,\n\tTEventPublisher extends EventPublisher<any> | undefined = undefined,\n\tTEventPublisherServiceName extends string = string,\n\tTSubscribedEvents extends\n\t\tExtractPublisherMessage<TEventPublisher>['type'][] = ExtractPublisherMessage<TEventPublisher>['type'][],\n> extends Construct<\n\tTLogger,\n\tTEventPublisherServiceName,\n\tTEventPublisher,\n\tOutSchema,\n\tTServices\n> {\n\t__IS_SUBSCRIBER__ = true;\n\n\tstatic isSubscriber(\n\t\tobj: any,\n\t): obj is Subscriber<any, any, any, any, any, any> {\n\t\treturn Boolean(\n\t\t\tobj &&\n\t\t\t\tobj.__IS_SUBSCRIBER__ === true &&\n\t\t\t\tobj.type === ConstructType.Subscriber,\n\t\t);\n\t}\n\n\tconstructor(\n\t\tpublic readonly handler: SubscriberHandler<\n\t\t\tTEventPublisher,\n\t\t\tTSubscribedEvents,\n\t\t\tTServices,\n\t\t\tTLogger,\n\t\t\tOutSchema\n\t\t>,\n\t\tpublic override readonly timeout: number = 30000,\n\t\tprotected _subscribedEvents?: TSubscribedEvents,\n\t\tpublic override readonly outputSchema?: OutSchema,\n\t\tpublic override readonly services: TServices = [] as unknown as TServices,\n\t\tpublic override readonly logger: TLogger = DEFAULT_LOGGER as TLogger,\n\t\tpublic override readonly publisherService?: Service<\n\t\t\tTEventPublisherServiceName,\n\t\t\tTEventPublisher\n\t\t>,\n\t) {\n\t\tsuper(\n\t\t\tConstructType.Subscriber,\n\t\t\tlogger,\n\t\t\tservices,\n\t\t\t[],\n\t\t\tpublisherService,\n\t\t\toutputSchema,\n\t\t);\n\t}\n\n\tget subscribedEvents(): TSubscribedEvents | undefined {\n\t\treturn this._subscribedEvents;\n\t}\n}\n\n// Handler type for subscribers that receives an array of events\nexport type SubscriberHandler<\n\tTEventPublisher extends EventPublisher<any> | undefined,\n\tTSubscribedEvents extends ExtractPublisherMessage<TEventPublisher>['type'][],\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n\tOutSchema extends StandardSchemaV1 | undefined = undefined,\n> = (\n\tctx: SubscriberContext<\n\t\tTEventPublisher,\n\t\tTSubscribedEvents,\n\t\tTServices,\n\t\tTLogger\n\t>,\n) => OutSchema extends StandardSchemaV1\n\t? InferStandardSchema<OutSchema> | Promise<InferStandardSchema<OutSchema>>\n\t: any | Promise<any>;\n\n// Context type for subscriber handlers\nexport type SubscriberContext<\n\tTEventPublisher extends EventPublisher<any> | undefined,\n\tTSubscribedEvents extends ExtractPublisherMessage<TEventPublisher>['type'][],\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n> = {\n\tevents: ExtractEventPayloads<TEventPublisher, TSubscribedEvents>[];\n\tservices: ServiceRecord<TServices>;\n\tlogger: TLogger;\n};\n","import type {\n\tEventPublisher,\n\tExtractPublisherMessage,\n} from '@geekmidas/events';\nimport type { Logger } from '@geekmidas/logger';\nimport { DEFAULT_LOGGER } from '@geekmidas/logger/console';\nimport type { Service } from '@geekmidas/services';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { Subscriber, type SubscriberHandler } from './Subscriber';\n\nexport class SubscriberBuilder<\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n\tOutSchema extends StandardSchemaV1 | undefined = undefined,\n\tTEventPublisher extends EventPublisher<any> | undefined = undefined,\n\tTEventPublisherServiceName extends string = string,\n\tTSubscribedEvents extends any[] = [],\n> {\n\tprivate _subscribedEvents: TSubscribedEvents = [] as any;\n\tprivate _timeout?: number;\n\tprivate outputSchema?: OutSchema;\n\tprivate _services: TServices = [] as Service[] as TServices;\n\tprivate _logger: TLogger = DEFAULT_LOGGER;\n\tprivate _publisher?: Service<TEventPublisherServiceName, TEventPublisher>;\n\n\tconstructor() {\n\t\tthis._timeout = 30000; // Default timeout\n\t}\n\n\ttimeout(timeout: number): this {\n\t\tthis._timeout = timeout;\n\t\treturn this;\n\t}\n\n\toutput<T extends StandardSchemaV1>(\n\t\tschema: T,\n\t): SubscriberBuilder<\n\t\tTServices,\n\t\tTLogger,\n\t\tT,\n\t\tTEventPublisher,\n\t\tTEventPublisherServiceName,\n\t\tTSubscribedEvents\n\t> {\n\t\tthis.outputSchema = schema as unknown as OutSchema;\n\t\treturn this as any;\n\t}\n\n\tservices<T extends Service[]>(\n\t\tservices: T,\n\t): SubscriberBuilder<\n\t\t[...TServices, ...T],\n\t\tTLogger,\n\t\tOutSchema,\n\t\tTEventPublisher,\n\t\tTEventPublisherServiceName,\n\t\tTSubscribedEvents\n\t> {\n\t\tthis._services = [...this._services, ...services] as any;\n\t\treturn this as any;\n\t}\n\n\tlogger<T extends Logger>(\n\t\tlogger: T,\n\t): SubscriberBuilder<\n\t\tTServices,\n\t\tT,\n\t\tOutSchema,\n\t\tTEventPublisher,\n\t\tTEventPublisherServiceName,\n\t\tTSubscribedEvents\n\t> {\n\t\tthis._logger = logger as unknown as TLogger;\n\t\treturn this as any;\n\t}\n\n\tpublisher<T extends EventPublisher<any>, TName extends string>(\n\t\tpublisher: Service<TName, T>,\n\t): SubscriberBuilder<\n\t\tTServices,\n\t\tTLogger,\n\t\tOutSchema,\n\t\tT,\n\t\tTName,\n\t\tTSubscribedEvents\n\t> {\n\t\tthis._publisher = publisher as any;\n\t\treturn this as any;\n\t}\n\n\tsubscribe<\n\t\tTEvent extends TEventPublisher extends EventPublisher<any>\n\t\t\t?\n\t\t\t\t\t| ExtractPublisherMessage<TEventPublisher>['type']\n\t\t\t\t\t| ExtractPublisherMessage<TEventPublisher>['type'][]\n\t\t\t: never,\n\t>(\n\t\tevent: TEvent,\n\t): SubscriberBuilder<\n\t\tTServices,\n\t\tTLogger,\n\t\tOutSchema,\n\t\tTEventPublisher,\n\t\tTEventPublisherServiceName,\n\t\tTEvent extends any[]\n\t\t\t? [...TSubscribedEvents, ...TEvent]\n\t\t\t: [...TSubscribedEvents, TEvent]\n\t> {\n\t\tconst eventsToAdd = Array.isArray(event) ? event : [event];\n\t\tthis._subscribedEvents = [...this._subscribedEvents, ...eventsToAdd] as any;\n\t\treturn this as any;\n\t}\n\n\thandle(\n\t\tfn: SubscriberHandler<\n\t\t\tTEventPublisher,\n\t\t\tTSubscribedEvents,\n\t\t\tTServices,\n\t\t\tTLogger,\n\t\t\tOutSchema\n\t\t>,\n\t): Subscriber<\n\t\tTServices,\n\t\tTLogger,\n\t\tOutSchema,\n\t\tTEventPublisher,\n\t\tTEventPublisherServiceName,\n\t\tTSubscribedEvents\n\t> {\n\t\tconst subscriber = new Subscriber(\n\t\t\tfn,\n\t\t\tthis._timeout,\n\t\t\tthis._subscribedEvents,\n\t\t\tthis.outputSchema,\n\t\t\tthis._services,\n\t\t\tthis._logger,\n\t\t\tthis._publisher,\n\t\t);\n\n\t\t// Reset builder state after creating the subscriber to prevent pollution\n\t\tthis._services = [] as Service[] as TServices;\n\t\tthis._logger = DEFAULT_LOGGER;\n\t\tthis._publisher = undefined;\n\t\tthis._subscribedEvents = [] as any;\n\t\tthis._timeout = 30000; // Reset to default\n\t\tthis.outputSchema = undefined;\n\n\t\treturn subscriber;\n\t}\n}\n","import { SubscriberBuilder } from './SubscriberBuilder';\n\nexport { Subscriber } from './Subscriber';\nexport { SubscriberBuilder };\n\nexport const s = new SubscriberBuilder();\n"],"mappings":";;;;AAWA,MAAMA,mBAAiB,IAAI;AAU3B,IAAa,aAAb,cAQU,UAMR;CACD,oBAAoB;CAEpB,OAAO,aACNC,KACkD;AAClD,SAAO,QACN,OACC,IAAI,sBAAsB,QAC1B,IAAI,SAAS,cAAc,WAC5B;CACD;CAED,YACiBC,SAOSC,UAAkB,KACjCC,mBACeC,cACAC,WAAsB,CAAE,GACxBC,SAAkBP,kBAClBQ,kBAIxB;AACD,QACC,cAAc,YACd,QACA,UACA,CAAE,GACF,kBACA,aACA;EAxBe;EAOS;EACf;EACe;EACA;EACA;EACA;CAazB;CAED,IAAI,mBAAkD;AACrD,SAAO,KAAK;CACZ;AACD;;;;ACrED,IAAa,oBAAb,MAOE;CACD,AAAQ,oBAAuC,CAAE;CACjD,AAAQ;CACR,AAAQ;CACR,AAAQ,YAAuB,CAAE;CACjC,AAAQ,UAAmB;CAC3B,AAAQ;CAER,cAAc;AACb,OAAK,WAAW;CAChB;CAED,QAAQC,SAAuB;AAC9B,OAAK,WAAW;AAChB,SAAO;CACP;CAED,OACCC,QAQC;AACD,OAAK,eAAe;AACpB,SAAO;CACP;CAED,SACCC,UAQC;AACD,OAAK,YAAY,CAAC,GAAG,KAAK,WAAW,GAAG,QAAS;AACjD,SAAO;CACP;CAED,OACCC,QAQC;AACD,OAAK,UAAU;AACf,SAAO;CACP;CAED,UACCC,WAQC;AACD,OAAK,aAAa;AAClB,SAAO;CACP;CAED,UAOCC,OAUC;EACD,MAAM,cAAc,MAAM,QAAQ,MAAM,GAAG,QAAQ,CAAC,KAAM;AAC1D,OAAK,oBAAoB,CAAC,GAAG,KAAK,mBAAmB,GAAG,WAAY;AACpE,SAAO;CACP;CAED,OACCC,IAcC;EACD,MAAM,aAAa,IAAI,WACtB,IACA,KAAK,UACL,KAAK,mBACL,KAAK,cACL,KAAK,WACL,KAAK,SACL,KAAK;AAIN,OAAK,YAAY,CAAE;AACnB,OAAK,UAAU;AACf,OAAK;AACL,OAAK,oBAAoB,CAAE;AAC3B,OAAK,WAAW;AAChB,OAAK;AAEL,SAAO;CACP;AACD;;;;AChJD,MAAa,IAAI,IAAI"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["DEFAULT_LOGGER","obj: any","handler: SubscriberHandler<\n\t\t\tTEventPublisher,\n\t\t\tTSubscribedEvents,\n\t\t\tTServices,\n\t\t\tTLogger,\n\t\t\tOutSchema\n\t\t>","timeout: number","_subscribedEvents?: TSubscribedEvents","outputSchema?: OutSchema","services: TServices","logger: TLogger","publisherService?: Service<\n\t\t\tTEventPublisherServiceName,\n\t\t\tTEventPublisher\n\t\t>","topicName?: string","topic: Topic<TName, TEvents>","timeout: number","schema: T","services: T","logger: T","publisher: Service<TName, T>","event: TEvent","fn: SubscriberHandler<\n\t\t\tTEventPublisher,\n\t\t\tTSubscribedEvents,\n\t\t\tTServices,\n\t\t\tTLogger,\n\t\t\tOutSchema\n\t\t>"],"sources":["../../src/subscribers/Subscriber.ts","../../src/subscribers/SubscriberBuilder.ts","../../src/subscribers/index.ts"],"sourcesContent":["import type {\n\tEventPublisher,\n\tExtractPublisherMessage,\n} from '@geekmidas/events';\nimport type { Logger } from '@geekmidas/logger';\nimport { ConsoleLogger } from '@geekmidas/logger/console';\nimport type { InferStandardSchema } from '@geekmidas/schema';\nimport type { Service, ServiceRecord } from '@geekmidas/services';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { Construct, ConstructType } from '../Construct';\n\nconst DEFAULT_LOGGER = new ConsoleLogger() as any;\n\n// Helper type to extract payload types for subscribed events\ntype ExtractEventPayloads<\n\tTPublisher extends EventPublisher<any> | undefined,\n\tTEventTypes extends any[],\n> = TPublisher extends EventPublisher<any>\n\t? Extract<ExtractPublisherMessage<TPublisher>, { type: TEventTypes[number] }>\n\t: never;\n\nexport class Subscriber<\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n\tOutSchema extends StandardSchemaV1 | undefined = undefined,\n\tTEventPublisher extends EventPublisher<any> | undefined = undefined,\n\tTEventPublisherServiceName extends string = string,\n\tTSubscribedEvents extends\n\t\tExtractPublisherMessage<TEventPublisher>['type'][] = ExtractPublisherMessage<TEventPublisher>['type'][],\n> extends Construct<\n\tTLogger,\n\tTEventPublisherServiceName,\n\tTEventPublisher,\n\tOutSchema,\n\tTServices\n> {\n\t__IS_SUBSCRIBER__ = true;\n\n\tstatic isSubscriber(\n\t\tobj: any,\n\t): obj is Subscriber<any, any, any, any, any, any> {\n\t\treturn Boolean(\n\t\t\tobj &&\n\t\t\t\tobj.__IS_SUBSCRIBER__ === true &&\n\t\t\t\tobj.type === ConstructType.Subscriber,\n\t\t);\n\t}\n\n\tconstructor(\n\t\tpublic readonly handler: SubscriberHandler<\n\t\t\tTEventPublisher,\n\t\t\tTSubscribedEvents,\n\t\t\tTServices,\n\t\t\tTLogger,\n\t\t\tOutSchema\n\t\t>,\n\t\tpublic override readonly timeout: number = 30000,\n\t\tprotected _subscribedEvents?: TSubscribedEvents,\n\t\tpublic override readonly outputSchema?: OutSchema,\n\t\tpublic override readonly services: TServices = [] as unknown as TServices,\n\t\tpublic override readonly logger: TLogger = DEFAULT_LOGGER as TLogger,\n\t\tpublic override readonly publisherService?: Service<\n\t\t\tTEventPublisherServiceName,\n\t\t\tTEventPublisher\n\t\t>,\n\t\t/**\n\t\t * The name of the {@link Topic} this subscriber binds to (via\n\t\t * `s.topic(topic)`), recorded for the manifest so infra wires the SNS\n\t\t * subscription. Undefined when the subscriber's events are typed from a\n\t\t * (hand-written) publisher instead.\n\t\t */\n\t\tpublic readonly topicName?: string,\n\t) {\n\t\tsuper(\n\t\t\tConstructType.Subscriber,\n\t\t\tlogger,\n\t\t\tservices,\n\t\t\t[],\n\t\t\tpublisherService,\n\t\t\toutputSchema,\n\t\t);\n\t}\n\n\tget subscribedEvents(): TSubscribedEvents | undefined {\n\t\treturn this._subscribedEvents;\n\t}\n}\n\n// Handler type for subscribers that receives an array of events\nexport type SubscriberHandler<\n\tTEventPublisher extends EventPublisher<any> | undefined,\n\tTSubscribedEvents extends ExtractPublisherMessage<TEventPublisher>['type'][],\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n\tOutSchema extends StandardSchemaV1 | undefined = undefined,\n> = (\n\tctx: SubscriberContext<\n\t\tTEventPublisher,\n\t\tTSubscribedEvents,\n\t\tTServices,\n\t\tTLogger\n\t>,\n) => OutSchema extends StandardSchemaV1\n\t? InferStandardSchema<OutSchema> | Promise<InferStandardSchema<OutSchema>>\n\t: any | Promise<any>;\n\n// Context type for subscriber handlers\nexport type SubscriberContext<\n\tTEventPublisher extends EventPublisher<any> | undefined,\n\tTSubscribedEvents extends ExtractPublisherMessage<TEventPublisher>['type'][],\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n> = {\n\tevents: ExtractEventPayloads<TEventPublisher, TSubscribedEvents>[];\n\tservices: ServiceRecord<TServices>;\n\tlogger: TLogger;\n};\n","import type {\n\tEventPublisher,\n\tExtractPublisherMessage,\n} from '@geekmidas/events';\nimport type { Logger } from '@geekmidas/logger';\nimport { DEFAULT_LOGGER } from '@geekmidas/logger/console';\nimport type { Service } from '@geekmidas/services';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport type { Topic, TopicEvents, TopicMessage } from '../topic/Topic';\nimport { Subscriber, type SubscriberHandler } from './Subscriber';\n\nexport class SubscriberBuilder<\n\tTServices extends Service[] = [],\n\tTLogger extends Logger = Logger,\n\tOutSchema extends StandardSchemaV1 | undefined = undefined,\n\tTEventPublisher extends EventPublisher<any> | undefined = undefined,\n\tTEventPublisherServiceName extends string = string,\n\tTSubscribedEvents extends any[] = [],\n> {\n\tprivate _subscribedEvents: TSubscribedEvents = [] as any;\n\tprivate _timeout?: number;\n\tprivate outputSchema?: OutSchema;\n\tprivate _services: TServices = [] as Service[] as TServices;\n\tprivate _logger: TLogger = DEFAULT_LOGGER;\n\tprivate _publisher?: Service<TEventPublisherServiceName, TEventPublisher>;\n\tprivate _topicName?: string;\n\n\tconstructor() {\n\t\tthis._timeout = 30000; // Default timeout\n\t}\n\n\t/**\n\t * Bind this subscriber to a {@link Topic} — the preferred way to type and wire\n\t * a fan-out consumer. It supplies the subscribable event types (and their\n\t * payloads) from the topic's contract and records the binding for the manifest,\n\t * so infra wires the SNS subscription.\n\t *\n\t * Prefer this over typing via a hand-written publisher service: a consumer does\n\t * not publish, so binding a topic does *not* require the topic's publisher\n\t * connection string (least privilege). Use `.publisher(...)` only when the\n\t * subscriber actually publishes follow-up events.\n\t */\n\ttopic<TName extends string, TEvents extends TopicEvents>(\n\t\ttopic: Topic<TName, TEvents>,\n\t): SubscriberBuilder<\n\t\tTServices,\n\t\tTLogger,\n\t\tOutSchema,\n\t\tEventPublisher<TopicMessage<TEvents>>,\n\t\tTEventPublisherServiceName,\n\t\tTSubscribedEvents\n\t> {\n\t\tthis._topicName = topic.name;\n\t\treturn this as unknown as SubscriberBuilder<\n\t\t\tTServices,\n\t\t\tTLogger,\n\t\t\tOutSchema,\n\t\t\tEventPublisher<TopicMessage<TEvents>>,\n\t\t\tTEventPublisherServiceName,\n\t\t\tTSubscribedEvents\n\t\t>;\n\t}\n\n\ttimeout(timeout: number): this {\n\t\tthis._timeout = timeout;\n\t\treturn this;\n\t}\n\n\toutput<T extends StandardSchemaV1>(\n\t\tschema: T,\n\t): SubscriberBuilder<\n\t\tTServices,\n\t\tTLogger,\n\t\tT,\n\t\tTEventPublisher,\n\t\tTEventPublisherServiceName,\n\t\tTSubscribedEvents\n\t> {\n\t\tthis.outputSchema = schema as unknown as OutSchema;\n\t\treturn this as any;\n\t}\n\n\tservices<T extends Service[]>(\n\t\tservices: T,\n\t): SubscriberBuilder<\n\t\t[...TServices, ...T],\n\t\tTLogger,\n\t\tOutSchema,\n\t\tTEventPublisher,\n\t\tTEventPublisherServiceName,\n\t\tTSubscribedEvents\n\t> {\n\t\tthis._services = [...this._services, ...services] as any;\n\t\treturn this as any;\n\t}\n\n\tlogger<T extends Logger>(\n\t\tlogger: T,\n\t): SubscriberBuilder<\n\t\tTServices,\n\t\tT,\n\t\tOutSchema,\n\t\tTEventPublisher,\n\t\tTEventPublisherServiceName,\n\t\tTSubscribedEvents\n\t> {\n\t\tthis._logger = logger as unknown as TLogger;\n\t\treturn this as any;\n\t}\n\n\tpublisher<T extends EventPublisher<any>, TName extends string>(\n\t\tpublisher: Service<TName, T>,\n\t): SubscriberBuilder<\n\t\tTServices,\n\t\tTLogger,\n\t\tOutSchema,\n\t\tT,\n\t\tTName,\n\t\tTSubscribedEvents\n\t> {\n\t\tthis._publisher = publisher as any;\n\t\treturn this as any;\n\t}\n\n\tsubscribe<\n\t\tTEvent extends TEventPublisher extends EventPublisher<any>\n\t\t\t?\n\t\t\t\t\t| ExtractPublisherMessage<TEventPublisher>['type']\n\t\t\t\t\t| ExtractPublisherMessage<TEventPublisher>['type'][]\n\t\t\t: never,\n\t>(\n\t\tevent: TEvent,\n\t): SubscriberBuilder<\n\t\tTServices,\n\t\tTLogger,\n\t\tOutSchema,\n\t\tTEventPublisher,\n\t\tTEventPublisherServiceName,\n\t\tTEvent extends any[]\n\t\t\t? [...TSubscribedEvents, ...TEvent]\n\t\t\t: [...TSubscribedEvents, TEvent]\n\t> {\n\t\tconst eventsToAdd = Array.isArray(event) ? event : [event];\n\t\tthis._subscribedEvents = [...this._subscribedEvents, ...eventsToAdd] as any;\n\t\treturn this as any;\n\t}\n\n\thandle(\n\t\tfn: SubscriberHandler<\n\t\t\tTEventPublisher,\n\t\t\tTSubscribedEvents,\n\t\t\tTServices,\n\t\t\tTLogger,\n\t\t\tOutSchema\n\t\t>,\n\t): Subscriber<\n\t\tTServices,\n\t\tTLogger,\n\t\tOutSchema,\n\t\tTEventPublisher,\n\t\tTEventPublisherServiceName,\n\t\tTSubscribedEvents\n\t> {\n\t\tconst subscriber = new Subscriber(\n\t\t\tfn,\n\t\t\tthis._timeout,\n\t\t\tthis._subscribedEvents,\n\t\t\tthis.outputSchema,\n\t\t\tthis._services,\n\t\t\tthis._logger,\n\t\t\tthis._publisher,\n\t\t\tthis._topicName,\n\t\t);\n\n\t\t// Reset builder state after creating the subscriber to prevent pollution\n\t\tthis._services = [] as Service[] as TServices;\n\t\tthis._logger = DEFAULT_LOGGER;\n\t\tthis._publisher = undefined;\n\t\tthis._topicName = undefined;\n\t\tthis._subscribedEvents = [] as any;\n\t\tthis._timeout = 30000; // Reset to default\n\t\tthis.outputSchema = undefined;\n\n\t\treturn subscriber;\n\t}\n}\n","import { SubscriberBuilder } from './SubscriberBuilder';\n\nexport { Subscriber } from './Subscriber';\nexport { SubscriberBuilder };\n\nexport const s = new SubscriberBuilder();\n"],"mappings":";;;;AAWA,MAAMA,mBAAiB,IAAI;AAU3B,IAAa,aAAb,cAQU,UAMR;CACD,oBAAoB;CAEpB,OAAO,aACNC,KACkD;AAClD,SAAO,QACN,OACC,IAAI,sBAAsB,QAC1B,IAAI,SAAS,cAAc,WAC5B;CACD;CAED,YACiBC,SAOSC,UAAkB,KACjCC,mBACeC,cACAC,WAAsB,CAAE,GACxBC,SAAkBP,kBAClBQ,kBAUTC,WACf;AACD,QACC,cAAc,YACd,QACA,UACA,CAAE,GACF,kBACA,aACA;EA/Be;EAOS;EACf;EACe;EACA;EACA;EACA;EAUT;CAUhB;CAED,IAAI,mBAAkD;AACrD,SAAO,KAAK;CACZ;AACD;;;;AC3ED,IAAa,oBAAb,MAOE;CACD,AAAQ,oBAAuC,CAAE;CACjD,AAAQ;CACR,AAAQ;CACR,AAAQ,YAAuB,CAAE;CACjC,AAAQ,UAAmB;CAC3B,AAAQ;CACR,AAAQ;CAER,cAAc;AACb,OAAK,WAAW;CAChB;;;;;;;;;;;;CAaD,MACCC,OAQC;AACD,OAAK,aAAa,MAAM;AACxB,SAAO;CAQP;CAED,QAAQC,SAAuB;AAC9B,OAAK,WAAW;AAChB,SAAO;CACP;CAED,OACCC,QAQC;AACD,OAAK,eAAe;AACpB,SAAO;CACP;CAED,SACCC,UAQC;AACD,OAAK,YAAY,CAAC,GAAG,KAAK,WAAW,GAAG,QAAS;AACjD,SAAO;CACP;CAED,OACCC,QAQC;AACD,OAAK,UAAU;AACf,SAAO;CACP;CAED,UACCC,WAQC;AACD,OAAK,aAAa;AAClB,SAAO;CACP;CAED,UAOCC,OAUC;EACD,MAAM,cAAc,MAAM,QAAQ,MAAM,GAAG,QAAQ,CAAC,KAAM;AAC1D,OAAK,oBAAoB,CAAC,GAAG,KAAK,mBAAmB,GAAG,WAAY;AACpE,SAAO;CACP;CAED,OACCC,IAcC;EACD,MAAM,aAAa,IAAI,WACtB,IACA,KAAK,UACL,KAAK,mBACL,KAAK,cACL,KAAK,WACL,KAAK,SACL,KAAK,YACL,KAAK;AAIN,OAAK,YAAY,CAAE;AACnB,OAAK,UAAU;AACf,OAAK;AACL,OAAK;AACL,OAAK,oBAAoB,CAAE;AAC3B,OAAK,WAAW;AAChB,OAAK;AAEL,SAAO;CACP;AACD;;;;ACpLD,MAAa,IAAI,IAAI"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
const require_Construct = require('../Construct-vXMZJgRp.cjs');
|
|
2
|
+
const __geekmidas_logger_console = require_Construct.__toESM(require("@geekmidas/logger/console"));
|
|
3
|
+
const __geekmidas_envkit = require_Construct.__toESM(require("@geekmidas/envkit"));
|
|
4
|
+
const __geekmidas_events = require_Construct.__toESM(require("@geekmidas/events"));
|
|
5
|
+
|
|
6
|
+
//#region src/topic/Topic.ts
|
|
7
|
+
const DEFAULT_LOGGER$1 = new __geekmidas_logger_console.ConsoleLogger();
|
|
8
|
+
/**
|
|
9
|
+
* A topic — pub/sub fan-out. Unlike a `Queue` (point-to-point, one consumer), a
|
|
10
|
+
* topic is a *resource* owned by no single handler: it declares the event
|
|
11
|
+
* contract, derives a typed producer (`topic.publisher`), and any number of
|
|
12
|
+
* subscribers (`s.topic(topic)`) bind to it. `gkm build` discovers it into the
|
|
13
|
+
* manifest's `topics` field; infra provisions an SNS topic.
|
|
14
|
+
*
|
|
15
|
+
* This replaces hand-writing a publisher `Service`: the publisher is *derived*
|
|
16
|
+
* from the declared event contract, the same way `Queue` derives its publisher.
|
|
17
|
+
*/
|
|
18
|
+
var Topic = class extends require_Construct.Construct {
|
|
19
|
+
__IS_TOPIC__ = true;
|
|
20
|
+
static isTopic(obj) {
|
|
21
|
+
return Boolean(obj && obj.__IS_TOPIC__ === true && obj.type === require_Construct.ConstructType.Topic);
|
|
22
|
+
}
|
|
23
|
+
constructor(name, eventSchemas, logger = DEFAULT_LOGGER$1) {
|
|
24
|
+
super(require_Construct.ConstructType.Topic, logger, [], []);
|
|
25
|
+
this.name = name;
|
|
26
|
+
this.eventSchemas = eventSchemas;
|
|
27
|
+
}
|
|
28
|
+
/** The event type names this topic carries. */
|
|
29
|
+
get eventTypes() {
|
|
30
|
+
return Object.keys(this.eventSchemas);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The producer side — a `Service` exposing an `EventPublisher` typed to the
|
|
34
|
+
* union of this topic's events. Inject via `.publisher(topic.publisher)` (for
|
|
35
|
+
* declarative `.event(...)`) or `.services([topic.publisher])` (to publish
|
|
36
|
+
* imperatively). Reads `<NAME>_PUBLISHER_CONNECTION_STRING` and selects the
|
|
37
|
+
* transport from the URL protocol — `pgboss://` locally, `sns://` deployed.
|
|
38
|
+
*
|
|
39
|
+
* Because it's a `Service`, the connection-string requirement is sniffed into
|
|
40
|
+
* the manifest of whatever construct injects it (least-privilege linking).
|
|
41
|
+
*/
|
|
42
|
+
get publisher() {
|
|
43
|
+
const envVar = `${(0, __geekmidas_envkit.environmentCase)(this.name)}_PUBLISHER_CONNECTION_STRING`;
|
|
44
|
+
return {
|
|
45
|
+
serviceName: `${this.name}Publisher`,
|
|
46
|
+
async register({ envParser }) {
|
|
47
|
+
const { connectionString } = envParser.create((get) => ({ connectionString: get(envVar).string() })).parse();
|
|
48
|
+
return __geekmidas_events.Publisher.fromConnectionString(connectionString);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
//#endregion
|
|
55
|
+
//#region src/topic/TopicBuilder.ts
|
|
56
|
+
/**
|
|
57
|
+
* Builds a {@link Topic} — `t.topic('users').events({ 'user.created': schema, … })`.
|
|
58
|
+
* The event map is the topic's contract: it types the derived `topic.publisher`
|
|
59
|
+
* and the subscribers that bind via `s.topic(topic)`.
|
|
60
|
+
*/
|
|
61
|
+
var TopicBuilder = class {
|
|
62
|
+
_name;
|
|
63
|
+
_logger = __geekmidas_logger_console.DEFAULT_LOGGER;
|
|
64
|
+
/** The topic name — drives the infra topic and its `<NAME>_*` env vars. */
|
|
65
|
+
topic(name) {
|
|
66
|
+
this._name = name;
|
|
67
|
+
return this;
|
|
68
|
+
}
|
|
69
|
+
logger(logger) {
|
|
70
|
+
this._logger = logger;
|
|
71
|
+
return this;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* The event contract — a map of event type → payload schema. Building the
|
|
75
|
+
* topic requires this; it's what types the publisher and subscribers.
|
|
76
|
+
*/
|
|
77
|
+
events(events) {
|
|
78
|
+
if (!this._name) throw new Error("Topic requires a name — call .topic(name) before .events().");
|
|
79
|
+
const topic = new Topic(this._name, events, this._logger);
|
|
80
|
+
this._name = void 0;
|
|
81
|
+
this._logger = __geekmidas_logger_console.DEFAULT_LOGGER;
|
|
82
|
+
return topic;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
//#endregion
|
|
87
|
+
//#region src/topic/index.ts
|
|
88
|
+
const t = new TopicBuilder();
|
|
89
|
+
|
|
90
|
+
//#endregion
|
|
91
|
+
exports.Topic = Topic;
|
|
92
|
+
exports.TopicBuilder = TopicBuilder;
|
|
93
|
+
exports.t = t;
|
|
94
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["DEFAULT_LOGGER","ConsoleLogger","Construct","obj: unknown","ConstructType","name: TName","eventSchemas: TEvents","logger: Logger","DEFAULT_LOGGER","name: T","logger: Logger","events: T"],"sources":["../../src/topic/Topic.ts","../../src/topic/TopicBuilder.ts","../../src/topic/index.ts"],"sourcesContent":["import { environmentCase } from '@geekmidas/envkit';\nimport {\n\ttype EventPublisher,\n\ttype EventPublisherConnectionString,\n\ttype PublishableMessage,\n\tPublisher,\n} from '@geekmidas/events';\nimport type { Logger } from '@geekmidas/logger';\nimport { ConsoleLogger } from '@geekmidas/logger/console';\nimport type { InferStandardSchema } from '@geekmidas/schema';\nimport type { Service } from '@geekmidas/services';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\nimport { Construct, ConstructType } from '../Construct';\n\nconst DEFAULT_LOGGER = new ConsoleLogger() as unknown as Logger;\n\n/** A topic's event contract — a map of event type → payload schema. */\nexport type TopicEvents = Record<string, StandardSchemaV1>;\n\n/**\n * The union of wire messages a topic carries, derived from its event map:\n * `{ type: 'user.created'; payload: … } | { type: 'user.updated'; payload: … }`.\n */\nexport type TopicMessage<TEvents extends TopicEvents> = {\n\t[K in keyof TEvents & string]: PublishableMessage<\n\t\tK,\n\t\tInferStandardSchema<TEvents[K]>\n\t>;\n}[keyof TEvents & string];\n\n/**\n * A topic — pub/sub fan-out. Unlike a `Queue` (point-to-point, one consumer), a\n * topic is a *resource* owned by no single handler: it declares the event\n * contract, derives a typed producer (`topic.publisher`), and any number of\n * subscribers (`s.topic(topic)`) bind to it. `gkm build` discovers it into the\n * manifest's `topics` field; infra provisions an SNS topic.\n *\n * This replaces hand-writing a publisher `Service`: the publisher is *derived*\n * from the declared event contract, the same way `Queue` derives its publisher.\n */\nexport class Topic<\n\tTName extends string = string,\n\tTEvents extends TopicEvents = TopicEvents,\n> extends Construct {\n\t__IS_TOPIC__ = true;\n\n\tstatic isTopic(obj: unknown): obj is Topic<string, TopicEvents> {\n\t\treturn Boolean(\n\t\t\tobj &&\n\t\t\t\t(obj as { __IS_TOPIC__?: boolean }).__IS_TOPIC__ === true &&\n\t\t\t\t(obj as Construct).type === ConstructType.Topic,\n\t\t);\n\t}\n\n\tconstructor(\n\t\tpublic readonly name: TName,\n\t\t/**\n\t\t * The event contract — a map of event type → payload schema. Named\n\t\t * `eventSchemas` (not `events`) to avoid clashing with `Construct.events`,\n\t\t * which is the array of `MappedEvent`s a construct *publishes*.\n\t\t */\n\t\tpublic readonly eventSchemas: TEvents,\n\t\tlogger: Logger = DEFAULT_LOGGER,\n\t) {\n\t\tsuper(ConstructType.Topic, logger, [], []);\n\t}\n\n\t/** The event type names this topic carries. */\n\tget eventTypes(): (keyof TEvents & string)[] {\n\t\treturn Object.keys(this.eventSchemas) as (keyof TEvents & string)[];\n\t}\n\n\t/**\n\t * The producer side — a `Service` exposing an `EventPublisher` typed to the\n\t * union of this topic's events. Inject via `.publisher(topic.publisher)` (for\n\t * declarative `.event(...)`) or `.services([topic.publisher])` (to publish\n\t * imperatively). Reads `<NAME>_PUBLISHER_CONNECTION_STRING` and selects the\n\t * transport from the URL protocol — `pgboss://` locally, `sns://` deployed.\n\t *\n\t * Because it's a `Service`, the connection-string requirement is sniffed into\n\t * the manifest of whatever construct injects it (least-privilege linking).\n\t */\n\tget publisher(): Service<\n\t\t`${TName}Publisher`,\n\t\tEventPublisher<TopicMessage<TEvents>>\n\t> {\n\t\tconst envVar = `${environmentCase(this.name)}_PUBLISHER_CONNECTION_STRING`;\n\t\treturn {\n\t\t\tserviceName: `${this.name}Publisher`,\n\t\t\tasync register({ envParser }) {\n\t\t\t\tconst { connectionString } = envParser\n\t\t\t\t\t.create((get) => ({\n\t\t\t\t\t\tconnectionString: get(envVar).string(),\n\t\t\t\t\t}))\n\t\t\t\t\t.parse();\n\n\t\t\t\treturn Publisher.fromConnectionString<TopicMessage<TEvents>>(\n\t\t\t\t\tconnectionString as EventPublisherConnectionString,\n\t\t\t\t);\n\t\t\t},\n\t\t};\n\t}\n}\n","import type { Logger } from '@geekmidas/logger';\nimport { DEFAULT_LOGGER } from '@geekmidas/logger/console';\nimport { Topic, type TopicEvents } from './Topic';\n\n/**\n * Builds a {@link Topic} — `t.topic('users').events({ 'user.created': schema, … })`.\n * The event map is the topic's contract: it types the derived `topic.publisher`\n * and the subscribers that bind via `s.topic(topic)`.\n */\nexport class TopicBuilder<\n\tTName extends string = string,\n\tTEvents extends TopicEvents = TopicEvents,\n> {\n\tprivate _name?: string;\n\tprivate _logger: Logger = DEFAULT_LOGGER;\n\n\t/** The topic name — drives the infra topic and its `<NAME>_*` env vars. */\n\ttopic<T extends string>(name: T): TopicBuilder<T, TEvents> {\n\t\tthis._name = name;\n\t\treturn this as unknown as TopicBuilder<T, TEvents>;\n\t}\n\n\tlogger(logger: Logger): this {\n\t\tthis._logger = logger;\n\t\treturn this;\n\t}\n\n\t/**\n\t * The event contract — a map of event type → payload schema. Building the\n\t * topic requires this; it's what types the publisher and subscribers.\n\t */\n\tevents<T extends TopicEvents>(events: T): Topic<TName, T> {\n\t\tif (!this._name) {\n\t\t\tthrow new Error(\n\t\t\t\t'Topic requires a name — call .topic(name) before .events().',\n\t\t\t);\n\t\t}\n\n\t\tconst topic = new Topic<TName, T>(\n\t\t\tthis._name as TName,\n\t\t\tevents,\n\t\t\tthis._logger,\n\t\t);\n\n\t\t// Reset builder state to prevent pollution across reuse.\n\t\tthis._name = undefined;\n\t\tthis._logger = DEFAULT_LOGGER;\n\n\t\treturn topic;\n\t}\n}\n","export {\n\tTopic,\n\ttype TopicEvents,\n\ttype TopicMessage,\n} from './Topic';\n\nimport { TopicBuilder } from './TopicBuilder';\n\nexport { TopicBuilder } from './TopicBuilder';\n\nexport const t = new TopicBuilder();\n"],"mappings":";;;;;;AAcA,MAAMA,mBAAiB,IAAIC;;;;;;;;;;;AA0B3B,IAAa,QAAb,cAGUC,4BAAU;CACnB,eAAe;CAEf,OAAO,QAAQC,KAAiD;AAC/D,SAAO,QACN,OACE,IAAmC,iBAAiB,QACpD,IAAkB,SAASC,gCAAc,MAC3C;CACD;CAED,YACiBC,MAMAC,cAChBC,SAAiBP,kBAChB;AACD,QAAMI,gCAAc,OAAO,QAAQ,CAAE,GAAE,CAAE,EAAC;EAT1B;EAMA;CAIhB;;CAGD,IAAI,aAAyC;AAC5C,SAAO,OAAO,KAAK,KAAK,aAAa;CACrC;;;;;;;;;;;CAYD,IAAI,YAGF;EACD,MAAM,UAAU,EAAE,wCAAgB,KAAK,KAAK,CAAC;AAC7C,SAAO;GACN,cAAc,EAAE,KAAK,KAAK;GAC1B,MAAM,SAAS,EAAE,WAAW,EAAE;IAC7B,MAAM,EAAE,kBAAkB,GAAG,UAC3B,OAAO,CAAC,SAAS,EACjB,kBAAkB,IAAI,OAAO,CAAC,QAAQ,CACtC,GAAE,CACF,OAAO;AAET,WAAO,6BAAU,qBAChB,iBACA;GACD;EACD;CACD;AACD;;;;;;;;;AC7FD,IAAa,eAAb,MAGE;CACD,AAAQ;CACR,AAAQ,UAAkBI;;CAG1B,MAAwBC,MAAmC;AAC1D,OAAK,QAAQ;AACb,SAAO;CACP;CAED,OAAOC,QAAsB;AAC5B,OAAK,UAAU;AACf,SAAO;CACP;;;;;CAMD,OAA8BC,QAA4B;AACzD,OAAK,KAAK,MACT,OAAM,IAAI,MACT;EAIF,MAAM,QAAQ,IAAI,MACjB,KAAK,OACL,QACA,KAAK;AAIN,OAAK;AACL,OAAK,UAAUH;AAEf,SAAO;CACP;AACD;;;;ACxCD,MAAa,IAAI,IAAI"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import "../Construct-_1wX7p_Y.cjs";
|
|
2
|
+
import { Topic, TopicEvents, TopicMessage } from "../Topic-C5ZMfveW.cjs";
|
|
3
|
+
import { Logger } from "@geekmidas/logger";
|
|
4
|
+
|
|
5
|
+
//#region src/topic/TopicBuilder.d.ts
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Builds a {@link Topic} — `t.topic('users').events({ 'user.created': schema, … })`.
|
|
9
|
+
* The event map is the topic's contract: it types the derived `topic.publisher`
|
|
10
|
+
* and the subscribers that bind via `s.topic(topic)`.
|
|
11
|
+
*/
|
|
12
|
+
declare class TopicBuilder<TName extends string = string, TEvents extends TopicEvents = TopicEvents> {
|
|
13
|
+
private _name?;
|
|
14
|
+
private _logger;
|
|
15
|
+
/** The topic name — drives the infra topic and its `<NAME>_*` env vars. */
|
|
16
|
+
topic<T extends string>(name: T): TopicBuilder<T, TEvents>;
|
|
17
|
+
logger(logger: Logger): this;
|
|
18
|
+
/**
|
|
19
|
+
* The event contract — a map of event type → payload schema. Building the
|
|
20
|
+
* topic requires this; it's what types the publisher and subscribers.
|
|
21
|
+
*/
|
|
22
|
+
events<T extends TopicEvents>(events: T): Topic<TName, T>;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=TopicBuilder.d.ts.map
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region src/topic/index.d.ts
|
|
27
|
+
declare const t: TopicBuilder<string, TopicEvents>;
|
|
28
|
+
//# sourceMappingURL=index.d.ts.map
|
|
29
|
+
|
|
30
|
+
//#endregion
|
|
31
|
+
export { Topic, TopicBuilder, TopicEvents, TopicMessage, t };
|
|
32
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/topic/TopicBuilder.ts","../../src/topic/index.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AASA;;AAEiB,cAFJ,YAEI,CAAA,cAAA,MAAA,GAAA,MAAA,EAAA,gBAAA,WAAA,GAAc,WAAd,CAAA,CAAA;EAAW,QAAG,KAAA;EAAW,QAMX,OAAA;EAAC;EAAiB,KAAE,CAAA,UAAA,MAAA,CAAA,CAAA,IAAA,EAApB,CAAoB,CAAA,EAAhB,YAAgB,CAAH,CAAG,EAAA,OAAA,CAAA;EAAO,MAAvB,CAAA,MAAA,EAKnB,MALmB,CAAA,EAAA,IAAA;EAAY;;;;EAcO,MAAE,CAAA,UAAtC,WAAsC,CAAA,CAAA,MAAA,EAAjB,CAAiB,CAAA,EAAb,KAAa,CAAP,KAAO,EAAA,CAAA,CAAA;;AAAR;;;cCrBnC,GAAC,qBAAqB,WAAA"}
|