diff --git a/README.md b/README.md index eb8062b..0ba9974 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,7 @@ app.configure( ## How it works -![alt tag](https://raw.githubusercontent.com/PedroMD/feathers-sync/master/feathers-sync%20and%20real-time%20events-60.png) +![alt tag](https://raw.githubusercontent.com/PedroMD/feathers-sync/master/feathers-sync.png) ## Caveat: Listening to service events @@ -215,6 +215,6 @@ The `data` for the `sync-in` event should be in the same form as the one that is ## License -Copyright (c) 2021 Feathers contributors +Copyright (c) 2025 Feathers contributors Licensed under the [MIT license](LICENSE). diff --git a/feathers-sync and real-time events-60.png b/feathers-sync.png similarity index 100% rename from feathers-sync and real-time events-60.png rename to feathers-sync.png diff --git a/lib/adapters/redis.js b/lib/adapters/redis.js index cb31a04..d5cca5f 100644 --- a/lib/adapters/redis.js +++ b/lib/adapters/redis.js @@ -1,45 +1,60 @@ -const redis = require('redis') -const debug = require('debug')('feathers-sync:redis') -const core = require('../core') +const redis = require("redis"); +const debug = require("debug")("feathers-sync:redis"); +const core = require("../core"); -module.exports = config => { - return app => { - const { key, serialize, deserialize, redisClient, uri } = config +module.exports = (config) => { + return (app) => { + const { key, serialize, deserialize, redisClient, uri } = config; const options = { url: uri, - ...config.redisOptions - } + ...config.redisOptions, + }; if (!redisClient) { - debug(`Setting up Redis client for ${options.url}`) + debug(`Setting up Redis client for ${options.url}`); } - const pub = redisClient || redis.createClient(options) - const sub = pub.duplicate() + const pub = redisClient || redis.createClient(options); + const sub = pub.duplicate(); + const errorHandlers = pub.listeners("error"); - const msgFromRedisHandler = data => { - debug(`Got ${key} message from Redis`) - app.emit('sync-in', data) + if (errorHandlers.length > 0) { + // If error handlers exists, copy them to sub + errorHandlers.forEach((handler) => { + sub.on("error", handler); + }); + } else { + // If not, make sure both pub and sub has an error handler to avoid unhandled rejections + const defaultErrorHandler = (err) => { + console.error("REDIS ERROR", err); + }; + pub.on("error", defaultErrorHandler); + sub.on("error", defaultErrorHandler); } - app.configure(core) + const msgFromRedisHandler = (data) => { + debug(`Got ${key} message from Redis`); + app.emit("sync-in", data); + }; + + app.configure(core); app.sync = { deserialize, serialize, pub, sub, - type: 'redis', + type: "redis", ready: new Promise((resolve, reject) => { - pub.connect() - sub.connect() - sub.once('ready', resolve) - sub.once('error', reject) - }).then(() => sub.subscribe(key, msgFromRedisHandler, true)) - } + pub.connect(); + sub.connect(); + sub.once("ready", resolve); + sub.once("error", reject); + }).then(() => sub.subscribe(key, msgFromRedisHandler, true)), + }; - app.on('sync-out', data => { - debug(`Publishing key ${key} to Redis`) - pub.publish(key, data) - }) - } -} + app.on("sync-out", (data) => { + debug(`Publishing key ${key} to Redis`); + pub.publish(key, data); + }); + }; +};