trpc-rabbitmq
Version:
tRPC adapter for RabbitMQ
110 lines • 5.03 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.rmqLink = void 0;
const client_1 = require("@trpc/client");
const observable_1 = require("@trpc/server/observable");
const amqp = __importStar(require("amqp-connection-manager"));
const crypto_1 = require("crypto");
const events_1 = __importDefault(require("events"));
const REPLY_QUEUE = 'amq.rabbitmq.reply-to';
const rmqLink = (opts) => {
return runtime => {
const { url, queue, durable } = opts;
const responseEmitter = new events_1.default();
responseEmitter.setMaxListeners(0);
const connection = amqp.connect(url);
const channel = connection.createChannel({
setup: async (channel) => {
await channel.assertQueue(queue, { durable });
await channel.consume(REPLY_QUEUE, msg => {
if (!msg)
return;
responseEmitter.emit(msg.properties.correlationId, JSON.parse(msg.content.toString('utf-8')));
}, { noAck: true });
}
});
const sendToQueue = async (message) => new Promise(resolve => {
const correlationId = (0, crypto_1.randomUUID)();
responseEmitter.once(correlationId, resolve);
void channel.sendToQueue(queue, Buffer.from(JSON.stringify(message)), {
correlationId,
replyTo: REPLY_QUEUE
});
});
return ({ op }) => {
return (0, observable_1.observable)(observer => {
const { id, type, path } = op;
try {
const input = runtime.transformer.serialize(op.input);
const onMessage = (message) => {
if (!('trpc' in message))
return;
const { trpc } = message;
if (!trpc)
return;
if (!('id' in trpc) || trpc.id === null || trpc.id === undefined)
return;
if (id !== trpc.id)
return;
if ('error' in trpc) {
const error = runtime.transformer.deserialize(trpc.error);
observer.error(client_1.TRPCClientError.from(Object.assign(Object.assign({}, trpc), { error })));
return;
}
observer.next({
result: Object.assign(Object.assign({}, trpc.result), ((!trpc.result.type || trpc.result.type === 'data') && {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
data: runtime.transformer.deserialize(trpc.result.data)
}))
});
observer.complete();
};
sendToQueue({
trpc: {
id,
method: type,
params: { path, input }
}
})
.then(onMessage)
.catch(cause => {
observer.error(new client_1.TRPCClientError(cause instanceof Error ? cause.message : 'Unknown error'));
});
}
catch (cause) {
observer.error(new client_1.TRPCClientError(cause instanceof Error ? cause.message : 'Unknown error'));
}
// eslint-disable-next-line @typescript-eslint/no-empty-function
return () => { };
});
};
};
};
exports.rmqLink = rmqLink;
//# sourceMappingURL=index.js.map