@rocketmq/core 0.1.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.
@@ -0,0 +1,21 @@
1
+
2
+
3
+ > @rocketmq/core@0.1.0 build /home/edilson/learnspace/rocketmq-broker/rocketmq.js/packages/core
4
+ > tsup
5
+
6
+ CLI Building entry: src/index.ts
7
+ CLI Using tsconfig: tsconfig.json
8
+ CLI tsup v8.5.1
9
+ CLI Using tsup config: /home/edilson/learnspace/rocketmq-broker/rocketmq.js/packages/core/tsup.config.ts
10
+ CLI Target: es2022
11
+ CLI Cleaning output folder
12
+ ESM Build start
13
+ CJS Build start
14
+ CJS dist/index.cjs 11.01 KB
15
+ CJS ⚡️ Build success in 14ms
16
+ ESM dist/index.js 9.47 KB
17
+ ESM ⚡️ Build success in 15ms
18
+ DTS Build start
19
+ DTS ⚡️ Build success in 521ms
20
+ DTS dist/index.d.ts 6.69 KB
21
+ DTS dist/index.d.cts 6.69 KB
package/dist/index.cjs ADDED
@@ -0,0 +1,385 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ ConnectionError: () => ConnectionError,
24
+ ConsumeError: () => ConsumeError,
25
+ Field: () => import_schema2.Field,
26
+ PublishError: () => PublishError,
27
+ QueueError: () => QueueError,
28
+ QueueHandle: () => QueueHandle,
29
+ RocketMQ: () => RocketMQ,
30
+ RocketMQError: () => RocketMQError,
31
+ Schema: () => import_schema2.Schema,
32
+ SchemaError: () => SchemaError,
33
+ SerializationError: () => SerializationError,
34
+ TimeoutError: () => TimeoutError,
35
+ connect: () => connect
36
+ });
37
+ module.exports = __toCommonJS(index_exports);
38
+ var import_schema2 = require("@rocketmq/schema");
39
+
40
+ // src/client.ts
41
+ var import_amqp = require("@rocketmq/amqp");
42
+ var import_protobuf2 = require("@rocketmq/protobuf");
43
+ var import_schema = require("@rocketmq/schema");
44
+ var import_serializer = require("@rocketmq/serializer");
45
+
46
+ // src/errors.ts
47
+ var RocketMQError = class extends Error {
48
+ constructor(message, cause) {
49
+ super(message, { cause });
50
+ this.name = "RocketMQError";
51
+ }
52
+ };
53
+ var ConnectionError = class extends RocketMQError {
54
+ constructor(message, cause) {
55
+ super(message, cause);
56
+ this.name = "ConnectionError";
57
+ }
58
+ };
59
+ var QueueError = class extends RocketMQError {
60
+ constructor(message, cause) {
61
+ super(message, cause);
62
+ this.name = "QueueError";
63
+ }
64
+ };
65
+ var PublishError = class extends RocketMQError {
66
+ constructor(queue, cause) {
67
+ super(`Failed to publish to '${queue}'`, cause);
68
+ this.queue = queue;
69
+ this.name = "PublishError";
70
+ }
71
+ queue;
72
+ };
73
+ var ConsumeError = class extends RocketMQError {
74
+ constructor(message, cause) {
75
+ super(message, cause);
76
+ this.name = "ConsumeError";
77
+ }
78
+ };
79
+ var SerializationError = class extends RocketMQError {
80
+ constructor(message, cause) {
81
+ super(message, cause);
82
+ this.name = "SerializationError";
83
+ }
84
+ };
85
+ var SchemaError = class extends RocketMQError {
86
+ constructor(message, cause) {
87
+ super(message, cause);
88
+ this.name = "SchemaError";
89
+ }
90
+ };
91
+ var TimeoutError = class extends RocketMQError {
92
+ constructor(message, cause) {
93
+ super(message, cause);
94
+ this.name = "TimeoutError";
95
+ }
96
+ };
97
+
98
+ // src/queue-handle.ts
99
+ var import_protobuf = require("@rocketmq/protobuf");
100
+ var QueueHandle = class {
101
+ constructor(queueName, channel, registry, serializer) {
102
+ this.queueName = queueName;
103
+ this.channel = channel;
104
+ this.registry = registry;
105
+ this.serializer = serializer;
106
+ }
107
+ queueName;
108
+ channel;
109
+ registry;
110
+ serializer;
111
+ /**
112
+ * Publishes a typed payload to this queue.
113
+ *
114
+ * Pipeline: serialize → send. Validation is broker-side.
115
+ */
116
+ send(payload, opts) {
117
+ try {
118
+ const buf = this.serializer.serialize(payload);
119
+ return this.channel.sendToQueue(this.queueName, buf, {
120
+ contentType: this.serializer.contentType,
121
+ persistent: true,
122
+ ...opts
123
+ });
124
+ } catch (err) {
125
+ throw new PublishError(this.queueName, err);
126
+ }
127
+ }
128
+ /**
129
+ * Subscribes to this queue with typed message handling.
130
+ *
131
+ * Sends the consumer's proto definition to the broker via AMQP
132
+ * arguments so the broker can verify schema subset compatibility.
133
+ * Malformed messages are logged but not re-thrown to keep the loop alive.
134
+ */
135
+ async consume(handler, opts) {
136
+ const consumerArgs = this.buildConsumerSchemaArgs();
137
+ try {
138
+ const reply = await this.channel.consume(
139
+ this.queueName,
140
+ (raw) => {
141
+ if (!raw) return;
142
+ try {
143
+ const body = this.serializer.deserialize(raw.content);
144
+ handler(body, raw);
145
+ } catch (err) {
146
+ console.error(`[rocketmq] deserialization error on queue '${this.queueName}':`, err);
147
+ }
148
+ },
149
+ {
150
+ ...opts,
151
+ arguments: {
152
+ ...opts?.arguments,
153
+ ...consumerArgs
154
+ }
155
+ }
156
+ );
157
+ return reply.consumerTag;
158
+ } catch (err) {
159
+ throw new ConsumeError(`Failed to consume from queue '${this.queueName}'`, err);
160
+ }
161
+ }
162
+ /** Builds AMQP arguments for consumer schema subset checking. */
163
+ buildConsumerSchemaArgs() {
164
+ const meta = this.registry.lookup(this.queueName);
165
+ if (!meta) return {};
166
+ try {
167
+ const proto = (0, import_protobuf.toProto)(meta.ctor);
168
+ return {
169
+ "x-consumer-schema": proto,
170
+ "x-consumer-schema-message": meta.name
171
+ };
172
+ } catch {
173
+ return {};
174
+ }
175
+ }
176
+ };
177
+
178
+ // src/client.ts
179
+ async function connect(opts = {}) {
180
+ const url = opts.url ?? "amqp://guest:guest@localhost:5672";
181
+ const serializer = opts.serializer ?? new import_serializer.JsonSerializer();
182
+ try {
183
+ const conn = await import_amqp.AmqpConnection.connect(url);
184
+ const ch = await conn.createChannel();
185
+ return new RocketMQ(conn, ch, import_schema.defaultRegistry, serializer);
186
+ } catch (err) {
187
+ throw new ConnectionError(`Failed to connect to ${url}`, err);
188
+ }
189
+ }
190
+ var RocketMQ = class {
191
+ constructor(conn, ch, registry, serializer) {
192
+ this.conn = conn;
193
+ this.ch = ch;
194
+ this.registry = registry;
195
+ this.serializer = serializer;
196
+ }
197
+ conn;
198
+ ch;
199
+ registry;
200
+ serializer;
201
+ /** Exposes the raw AmqpChannel for event listeners (e.g. broker errors). */
202
+ get channel() {
203
+ return this.ch;
204
+ }
205
+ /**
206
+ * Creates a typed queue handle bound to a schema class.
207
+ *
208
+ * Declares the queue with schema metadata in AMQP arguments so the
209
+ * broker compiles and validates messages. Returns a QueueHandle<T>
210
+ * for type-safe send/consume.
211
+ */
212
+ async queue(name, schema, opts) {
213
+ await this.assertQueue(name, schema, opts);
214
+ return new QueueHandle(name, this.ch, this.registry, this.serializer);
215
+ }
216
+ /**
217
+ * Declares a queue with an optional schema class.
218
+ *
219
+ * When a schema is provided the proto3 definition is sent as AMQP
220
+ * queue arguments (`x-schema`, `x-schema-type`, `x-schema-message`)
221
+ * so the broker compiles and validates messages inline.
222
+ */
223
+ async assertQueue(name, schema, opts) {
224
+ if (!schema) {
225
+ return this.ch.assertQueue(name, opts);
226
+ }
227
+ const proto = (0, import_protobuf2.toProto)(schema);
228
+ const fields = import_schema.defaultRegistry.getFields(schema);
229
+ const subject = import_schema.defaultRegistry.getSubject(schema);
230
+ this.registry.register(name, {
231
+ ctor: schema,
232
+ name: schema.name,
233
+ subject,
234
+ fields: [...fields]
235
+ });
236
+ const schemaArgs = {
237
+ "x-schema": proto,
238
+ "x-schema-type": "protobuf",
239
+ "x-schema-message": schema.name
240
+ };
241
+ try {
242
+ return await this.ch.assertQueue(name, {
243
+ ...opts,
244
+ arguments: {
245
+ ...opts?.arguments,
246
+ ...schemaArgs
247
+ }
248
+ });
249
+ } catch (err) {
250
+ throw new QueueError(`Failed to assert queue '${name}'`, err);
251
+ }
252
+ }
253
+ /** Declares an exchange (passthrough to AMQP layer). */
254
+ async assertExchange(name, type, opts) {
255
+ return this.ch.assertExchange(name, type, opts);
256
+ }
257
+ /** Binds a queue to an exchange (passthrough to AMQP layer). */
258
+ async bindQueue(queue, exchange, routingKey) {
259
+ return this.ch.bindQueue(queue, exchange, routingKey);
260
+ }
261
+ /**
262
+ * Publishes a JSON message directly to a queue (untyped path).
263
+ *
264
+ * Prefer `mq.queue("name", Schema).send()` for type safety.
265
+ * Validation is handled broker-side via the queue's compiled schema.
266
+ */
267
+ sendToQueue(queue, payload, opts) {
268
+ try {
269
+ const buf = this.serializer.serialize(payload);
270
+ return this.ch.sendToQueue(queue, buf, {
271
+ contentType: this.serializer.contentType,
272
+ persistent: true,
273
+ ...opts
274
+ });
275
+ } catch (err) {
276
+ throw new PublishError(queue, err);
277
+ }
278
+ }
279
+ /**
280
+ * Publishes a JSON message to an exchange with a routing key.
281
+ */
282
+ publish(exchange, routingKey, payload, opts) {
283
+ try {
284
+ const buf = this.serializer.serialize(payload);
285
+ return this.ch.publish(exchange, routingKey, buf, {
286
+ contentType: this.serializer.contentType,
287
+ persistent: true,
288
+ ...opts
289
+ });
290
+ } catch (err) {
291
+ throw new PublishError(`exchange:${exchange} routingKey:${routingKey}`, err);
292
+ }
293
+ }
294
+ /**
295
+ * Subscribes to a queue with JSON deserialization.
296
+ *
297
+ * When a schema was registered via `assertQueue(name, Schema)`,
298
+ * the consumer's proto definition is sent to the broker for subset
299
+ * checking — the broker rejects consumers expecting fields the
300
+ * queue's schema doesn't define.
301
+ *
302
+ * Usage:
303
+ * await mq.assertQueue("orders", Order);
304
+ * await mq.consume("orders", (msg) => console.log(msg));
305
+ */
306
+ async consume(queue, handler, opts) {
307
+ const consumerArgs = this.buildConsumerSchemaArgs(queue);
308
+ try {
309
+ const reply = await this.ch.consume(
310
+ queue,
311
+ (msg) => {
312
+ if (!msg) return;
313
+ try {
314
+ const body = this.serializer.deserialize(msg.content);
315
+ handler(body, msg);
316
+ } catch (err) {
317
+ console.error(`[rocketmq] deserialization error on queue '${queue}':`, err);
318
+ }
319
+ },
320
+ {
321
+ ...opts,
322
+ arguments: {
323
+ ...opts?.arguments,
324
+ ...consumerArgs
325
+ }
326
+ }
327
+ );
328
+ return reply.consumerTag;
329
+ } catch (err) {
330
+ throw new ConsumeError(`Failed to consume from queue '${queue}'`, err);
331
+ }
332
+ }
333
+ /**
334
+ * Builds AMQP arguments for consumer schema compatibility checking.
335
+ *
336
+ * Returns `x-consumer-schema` + `x-consumer-schema-message` if the
337
+ * queue has a registered schema, otherwise an empty object.
338
+ */
339
+ buildConsumerSchemaArgs(queue) {
340
+ const meta = this.registry.lookup(queue);
341
+ if (!meta) return {};
342
+ try {
343
+ const proto = (0, import_protobuf2.toProto)(meta.ctor);
344
+ return {
345
+ "x-consumer-schema": proto,
346
+ "x-consumer-schema-message": meta.name
347
+ };
348
+ } catch {
349
+ return {};
350
+ }
351
+ }
352
+ /** Acknowledges a message. */
353
+ ack(msg) {
354
+ this.ch.ack(msg);
355
+ }
356
+ /** Negative-acknowledges a message. */
357
+ nack(msg, requeue) {
358
+ this.ch.nack(msg, requeue);
359
+ }
360
+ /** Sets prefetch count on the channel. */
361
+ async prefetch(count) {
362
+ await this.ch.prefetch(count);
363
+ }
364
+ /** Closes channel and connection. */
365
+ async close() {
366
+ await this.ch.close();
367
+ await this.conn.close();
368
+ }
369
+ };
370
+ // Annotate the CommonJS export names for ESM import in node:
371
+ 0 && (module.exports = {
372
+ ConnectionError,
373
+ ConsumeError,
374
+ Field,
375
+ PublishError,
376
+ QueueError,
377
+ QueueHandle,
378
+ RocketMQ,
379
+ RocketMQError,
380
+ Schema,
381
+ SchemaError,
382
+ SerializationError,
383
+ TimeoutError,
384
+ connect
385
+ });
@@ -0,0 +1,160 @@
1
+ import { SchemaRegistry } from '@rocketmq/schema';
2
+ export { Field, FieldMeta, ProtoType, Schema, SchemaEntry } from '@rocketmq/schema';
3
+ import { Serializer } from '@rocketmq/serializer';
4
+ export { Serializer } from '@rocketmq/serializer';
5
+ import * as _rocketmq_amqp from '@rocketmq/amqp';
6
+ import { AmqpChannel, PublishOptions, ConsumeMessage, ConsumeOptions, AmqpConnection, AssertQueueOptions, AssertQueueReply, AssertExchangeOptions, AssertExchangeReply, EmptyReply } from '@rocketmq/amqp';
7
+ export { ConsumeMessage } from '@rocketmq/amqp';
8
+
9
+ /**
10
+ * Typed queue handle — the core DX innovation.
11
+ *
12
+ * Wraps a queue name with its schema and serializer so every send()
13
+ * and consume() call is type-safe at compile time. Runtime validation
14
+ * is delegated to the broker's compiled proto schema.
15
+ *
16
+ * Usage:
17
+ * const orders = mq.queue("orders", Order);
18
+ * await orders.send({ id: "1", customerId: "c1", qty: 5 });
19
+ * await orders.consume((msg) => console.log(msg.id));
20
+ */
21
+
22
+ declare class QueueHandle<T> {
23
+ private readonly queueName;
24
+ private readonly channel;
25
+ private readonly registry;
26
+ private readonly serializer;
27
+ constructor(queueName: string, channel: AmqpChannel, registry: SchemaRegistry, serializer: Serializer);
28
+ /**
29
+ * Publishes a typed payload to this queue.
30
+ *
31
+ * Pipeline: serialize → send. Validation is broker-side.
32
+ */
33
+ send(payload: T, opts?: PublishOptions): boolean;
34
+ /**
35
+ * Subscribes to this queue with typed message handling.
36
+ *
37
+ * Sends the consumer's proto definition to the broker via AMQP
38
+ * arguments so the broker can verify schema subset compatibility.
39
+ * Malformed messages are logged but not re-thrown to keep the loop alive.
40
+ */
41
+ consume(handler: (msg: T, raw: ConsumeMessage) => void, opts?: ConsumeOptions): Promise<string>;
42
+ /** Builds AMQP arguments for consumer schema subset checking. */
43
+ private buildConsumerSchemaArgs;
44
+ }
45
+
46
+ interface RocketOptions {
47
+ /** AMQP connection URL. Default: amqp://guest:guest@localhost:5672 */
48
+ url?: string;
49
+ /** Custom serializer. Default: JsonSerializer. */
50
+ serializer?: Serializer;
51
+ }
52
+ /** Opens a connection + channel ready for schema-aware operations. */
53
+ declare function connect(opts?: RocketOptions): Promise<RocketMQ>;
54
+ declare class RocketMQ {
55
+ private readonly conn;
56
+ private readonly ch;
57
+ private readonly registry;
58
+ private readonly serializer;
59
+ constructor(conn: AmqpConnection, ch: AmqpChannel, registry: SchemaRegistry, serializer: Serializer);
60
+ /** Exposes the raw AmqpChannel for event listeners (e.g. broker errors). */
61
+ get channel(): AmqpChannel;
62
+ /**
63
+ * Creates a typed queue handle bound to a schema class.
64
+ *
65
+ * Declares the queue with schema metadata in AMQP arguments so the
66
+ * broker compiles and validates messages. Returns a QueueHandle<T>
67
+ * for type-safe send/consume.
68
+ */
69
+ queue<T>(name: string, schema: new (...args: unknown[]) => T, opts?: AssertQueueOptions): Promise<QueueHandle<T>>;
70
+ /**
71
+ * Declares a queue with an optional schema class.
72
+ *
73
+ * When a schema is provided the proto3 definition is sent as AMQP
74
+ * queue arguments (`x-schema`, `x-schema-type`, `x-schema-message`)
75
+ * so the broker compiles and validates messages inline.
76
+ */
77
+ assertQueue(name: string, schema?: Function, opts?: AssertQueueOptions): Promise<AssertQueueReply>;
78
+ /** Declares an exchange (passthrough to AMQP layer). */
79
+ assertExchange(name: string, type: string, opts?: AssertExchangeOptions): Promise<AssertExchangeReply>;
80
+ /** Binds a queue to an exchange (passthrough to AMQP layer). */
81
+ bindQueue(queue: string, exchange: string, routingKey: string): Promise<EmptyReply>;
82
+ /**
83
+ * Publishes a JSON message directly to a queue (untyped path).
84
+ *
85
+ * Prefer `mq.queue("name", Schema).send()` for type safety.
86
+ * Validation is handled broker-side via the queue's compiled schema.
87
+ */
88
+ sendToQueue(queue: string, payload: Record<string, unknown>, opts?: PublishOptions): boolean;
89
+ /**
90
+ * Publishes a JSON message to an exchange with a routing key.
91
+ */
92
+ publish(exchange: string, routingKey: string, payload: Record<string, unknown>, opts?: PublishOptions): boolean;
93
+ /**
94
+ * Subscribes to a queue with JSON deserialization.
95
+ *
96
+ * When a schema was registered via `assertQueue(name, Schema)`,
97
+ * the consumer's proto definition is sent to the broker for subset
98
+ * checking — the broker rejects consumers expecting fields the
99
+ * queue's schema doesn't define.
100
+ *
101
+ * Usage:
102
+ * await mq.assertQueue("orders", Order);
103
+ * await mq.consume("orders", (msg) => console.log(msg));
104
+ */
105
+ consume<T = Record<string, unknown>>(queue: string, handler: (msg: T, raw: ConsumeMessage) => void, opts?: _rocketmq_amqp.ConsumeOptions): Promise<string>;
106
+ /**
107
+ * Builds AMQP arguments for consumer schema compatibility checking.
108
+ *
109
+ * Returns `x-consumer-schema` + `x-consumer-schema-message` if the
110
+ * queue has a registered schema, otherwise an empty object.
111
+ */
112
+ private buildConsumerSchemaArgs;
113
+ /** Acknowledges a message. */
114
+ ack(msg: ConsumeMessage): void;
115
+ /** Negative-acknowledges a message. */
116
+ nack(msg: ConsumeMessage, requeue?: boolean): void;
117
+ /** Sets prefetch count on the channel. */
118
+ prefetch(count: number): Promise<void>;
119
+ /** Closes channel and connection. */
120
+ close(): Promise<void>;
121
+ }
122
+
123
+ /**
124
+ * Error hierarchy for the RocketMQ SDK.
125
+ *
126
+ * Every error includes the offending context (queue name, schema name, etc.)
127
+ * and preserves the original cause via the standard `cause` property.
128
+ *
129
+ * Usage:
130
+ * try { ... } catch (err) {
131
+ * if (err instanceof PublishError) console.error(err.queue);
132
+ * }
133
+ */
134
+ declare class RocketMQError extends Error {
135
+ constructor(message: string, cause?: unknown);
136
+ }
137
+ declare class ConnectionError extends RocketMQError {
138
+ constructor(message: string, cause?: unknown);
139
+ }
140
+ declare class QueueError extends RocketMQError {
141
+ constructor(message: string, cause?: unknown);
142
+ }
143
+ declare class PublishError extends RocketMQError {
144
+ readonly queue: string;
145
+ constructor(queue: string, cause?: unknown);
146
+ }
147
+ declare class ConsumeError extends RocketMQError {
148
+ constructor(message: string, cause?: unknown);
149
+ }
150
+ declare class SerializationError extends RocketMQError {
151
+ constructor(message: string, cause?: unknown);
152
+ }
153
+ declare class SchemaError extends RocketMQError {
154
+ constructor(message: string, cause?: unknown);
155
+ }
156
+ declare class TimeoutError extends RocketMQError {
157
+ constructor(message: string, cause?: unknown);
158
+ }
159
+
160
+ export { ConnectionError, ConsumeError, PublishError, QueueError, QueueHandle, RocketMQ, RocketMQError, type RocketOptions, SchemaError, SerializationError, TimeoutError, connect };