2021-10-20 04:35:39 +08:00
|
|
|
/*
|
|
|
|
This class allows other parts of the code to get called when an event (insert/update/delete) occurs in a server-side published cursor.
|
|
|
|
|
|
|
|
In implementation time it was created for the publisher ( meteor live data hooks ) notify the listener ( LocalCollectionSynchronizer ) about the events.
|
|
|
|
|
|
|
|
*/
|
|
|
|
class CollectionEventsBroker {
|
|
|
|
static getKey(msg, updates) {
|
|
|
|
// the msg.msg has the collection event,
|
|
|
|
// see the collection hooks event object for more information
|
|
|
|
return `/${msg.collection}/${msg.msg}/`;
|
|
|
|
// TODO: also process the updates object
|
|
|
|
}
|
|
|
|
|
|
|
|
constructor() {
|
|
|
|
this.callbacks = {};
|
|
|
|
}
|
|
|
|
|
|
|
|
addListener(collection, event, callback) {
|
|
|
|
try {
|
|
|
|
const index = CollectionEventsBroker.getKey({ collection, msg: event });
|
|
|
|
const TheresCallback = this.callbacks[index];
|
|
|
|
if (TheresCallback) {
|
2022-09-21 22:03:21 +08:00
|
|
|
console.log('There is already an associated callback for this event');
|
|
|
|
return true;
|
2021-10-20 04:35:39 +08:00
|
|
|
}
|
|
|
|
this.callbacks[index] = callback;
|
|
|
|
return true;
|
|
|
|
} catch (err) {
|
|
|
|
console.error(err);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
dispatchEvent(msg, updates) {
|
|
|
|
try {
|
|
|
|
const msgIndex = CollectionEventsBroker.getKey(msg, updates);
|
|
|
|
const { fields } = msg;
|
|
|
|
const callback = this.callbacks[msgIndex];
|
|
|
|
if (callback) {
|
|
|
|
callback({ ...fields, referenceId: msg.id });
|
|
|
|
}
|
|
|
|
} catch (error) {
|
|
|
|
console.error('Error:', error);
|
|
|
|
}
|
|
|
|
// TODO: also process the updates object
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const collectionEventsBroker = new CollectionEventsBroker();
|
|
|
|
|
|
|
|
export const liveDataEventBrokerInitializer = () => {
|
|
|
|
Meteor.connection._processOneDataMessage = function (msg, updates) {
|
|
|
|
try {
|
|
|
|
const messageType = msg.msg;
|
|
|
|
let col = null;
|
|
|
|
if (msg.collection && msg.collection.indexOf('stream-cursor') === -1) {
|
|
|
|
col = Meteor.connection._stores[msg.collection]?._getCollection();
|
|
|
|
}
|
|
|
|
collectionEventsBroker.dispatchEvent(msg, updates);
|
|
|
|
// msg is one of ['added', 'changed', 'removed', 'ready', 'updated']
|
|
|
|
if (messageType === 'added') {
|
|
|
|
if (!col || !col.onAdded || col.onAdded(msg, updates)) {
|
|
|
|
this._process_added(msg, updates);
|
|
|
|
}
|
|
|
|
} else if (messageType === 'changed') {
|
|
|
|
if (!col || !col.onChanged || col.onChanged(msg, updates)) {
|
|
|
|
this._process_changed(msg, updates);
|
|
|
|
}
|
|
|
|
} else if (messageType === 'removed') {
|
|
|
|
if (!col || !col.onRemoved || col.onRemoved(msg, updates)) {
|
|
|
|
this._process_removed(msg, updates);
|
|
|
|
}
|
|
|
|
} else if (messageType === 'ready') {
|
|
|
|
if (!col || !col.onReady || col.onReady(msg, updates)) {
|
|
|
|
this._process_ready(msg, updates);
|
|
|
|
}
|
|
|
|
} else if (messageType === 'updated') {
|
|
|
|
if (!col || !col.onUpdated || col.onUpdated(msg, updates)) {
|
|
|
|
this._process_updated(msg, updates);
|
|
|
|
}
|
|
|
|
} else if (messageType === 'nosub') {
|
|
|
|
// ignore this
|
|
|
|
} else {
|
|
|
|
Meteor._debug('discarding unknown livedata data message type', msg);
|
|
|
|
}
|
|
|
|
} catch (err) {
|
|
|
|
console.error('Error when calling hooks', err);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
export default collectionEventsBroker;
|