|
1 | | -var util = require('../../util'); |
2 | | -var EventEmitter = require('events').EventEmitter; |
3 | | - |
4 | | -var EVENTS = [ |
5 | | - 'create', |
6 | | - 'del', |
7 | | - 'destroy', |
8 | | - 'load', |
9 | | - 'op' |
10 | | -]; |
11 | | - |
12 | | -module.exports = DocPresenceEmitter; |
13 | | - |
14 | | -function DocPresenceEmitter() { |
15 | | - this._docs = Object.create(null); |
16 | | - this._forwarders = Object.create(null); |
17 | | - this._emitters = Object.create(null); |
18 | | -} |
19 | | - |
20 | | -DocPresenceEmitter.prototype.addEventListener = function(doc, event, listener) { |
21 | | - this._registerDoc(doc); |
22 | | - var emitter = util.dig(this._emitters, doc.collection, doc.id); |
23 | | - emitter.on(event, listener); |
24 | | -}; |
25 | | - |
26 | | -DocPresenceEmitter.prototype.removeEventListener = function(doc, event, listener) { |
27 | | - var emitter = util.dig(this._emitters, doc.collection, doc.id); |
28 | | - if (!emitter) return; |
29 | | - emitter.off(event, listener); |
30 | | - // We'll always have at least one, because of the destroy listener |
31 | | - if (emitter._eventsCount === 1) this._unregisterDoc(doc); |
32 | | -}; |
33 | | - |
34 | | -DocPresenceEmitter.prototype._registerDoc = function(doc) { |
35 | | - var alreadyRegistered = true; |
36 | | - util.digOrCreate(this._docs, doc.collection, doc.id, function() { |
37 | | - alreadyRegistered = false; |
38 | | - return doc; |
39 | | - }); |
40 | | - |
41 | | - if (alreadyRegistered) return; |
42 | | - |
43 | | - var emitter = util.digOrCreate(this._emitters, doc.collection, doc.id, function() { |
44 | | - var e = new EventEmitter(); |
45 | | - // Set a high limit to avoid unnecessary warnings, but still |
46 | | - // retain some degree of memory leak detection |
47 | | - e.setMaxListeners(1000); |
48 | | - return e; |
49 | | - }); |
50 | | - |
51 | | - var self = this; |
52 | | - EVENTS.forEach(function(event) { |
53 | | - var forwarder = util.digOrCreate(self._forwarders, doc.collection, doc.id, event, function() { |
54 | | - return emitter.emit.bind(emitter, event); |
55 | | - }); |
56 | | - |
57 | | - doc.on(event, forwarder); |
58 | | - }); |
59 | | - |
60 | | - this.addEventListener(doc, 'destroy', this._unregisterDoc.bind(this, doc)); |
61 | | -}; |
62 | | - |
63 | | -DocPresenceEmitter.prototype._unregisterDoc = function(doc) { |
64 | | - var forwarders = util.dig(this._forwarders, doc.collection, doc.id); |
65 | | - for (var event in forwarders) { |
66 | | - doc.off(event, forwarders[event]); |
67 | | - } |
68 | | - |
69 | | - var emitter = util.dig(this._emitters, doc.collection, doc.id); |
70 | | - emitter.removeAllListeners(); |
71 | | - |
72 | | - util.digAndRemove(this._forwarders, doc.collection, doc.id); |
73 | | - util.digAndRemove(this._emitters, doc.collection, doc.id); |
74 | | - util.digAndRemove(this._docs, doc.collection, doc.id); |
75 | | -}; |
| 1 | +import util = require('../../util'); |
| 2 | +import { EventEmitter } from 'events'; |
| 3 | + |
| 4 | +var EVENTS = [ |
| 5 | + 'create', |
| 6 | + 'del', |
| 7 | + 'destroy', |
| 8 | + 'load', |
| 9 | + 'op' |
| 10 | +]; |
| 11 | + |
| 12 | +export = DocPresenceEmitter; |
| 13 | + |
| 14 | +class DocPresenceEmitter { |
| 15 | + _docs; |
| 16 | + _forwarders; |
| 17 | + _emitters; |
| 18 | + |
| 19 | + constructor() { |
| 20 | + this._docs = Object.create(null); |
| 21 | + this._forwarders = Object.create(null); |
| 22 | + this._emitters = Object.create(null); |
| 23 | + } |
| 24 | + |
| 25 | + addEventListener(doc, event, listener) { |
| 26 | + this._registerDoc(doc); |
| 27 | + var emitter = util.dig(this._emitters, doc.collection, doc.id); |
| 28 | + emitter.on(event, listener); |
| 29 | + } |
| 30 | + |
| 31 | + removeEventListener(doc, event, listener) { |
| 32 | + var emitter = util.dig(this._emitters, doc.collection, doc.id); |
| 33 | + if (!emitter) return; |
| 34 | + emitter.off(event, listener); |
| 35 | + // We'll always have at least one, because of the destroy listener |
| 36 | + if (emitter._eventsCount === 1) this._unregisterDoc(doc); |
| 37 | + } |
| 38 | + |
| 39 | + _registerDoc(doc) { |
| 40 | + var alreadyRegistered = true; |
| 41 | + util.digOrCreate(this._docs, doc.collection, doc.id, function() { |
| 42 | + alreadyRegistered = false; |
| 43 | + return doc; |
| 44 | + }); |
| 45 | + |
| 46 | + if (alreadyRegistered) return; |
| 47 | + |
| 48 | + var emitter = util.digOrCreate(this._emitters, doc.collection, doc.id, function() { |
| 49 | + var e = new EventEmitter(); |
| 50 | + // Set a high limit to avoid unnecessary warnings, but still |
| 51 | + // retain some degree of memory leak detection |
| 52 | + e.setMaxListeners(1000); |
| 53 | + return e; |
| 54 | + }); |
| 55 | + |
| 56 | + var self = this; |
| 57 | + EVENTS.forEach(function(event) { |
| 58 | + var forwarder = util.digOrCreate(self._forwarders, doc.collection, doc.id, event, function() { |
| 59 | + return emitter.emit.bind(emitter, event); |
| 60 | + }); |
| 61 | + |
| 62 | + doc.on(event, forwarder); |
| 63 | + }); |
| 64 | + |
| 65 | + this.addEventListener(doc, 'destroy', this._unregisterDoc.bind(this, doc)); |
| 66 | + } |
| 67 | + |
| 68 | + _unregisterDoc(doc) { |
| 69 | + var forwarders = util.dig(this._forwarders, doc.collection, doc.id); |
| 70 | + for (var event in forwarders) { |
| 71 | + doc.off(event, forwarders[event]); |
| 72 | + } |
| 73 | + |
| 74 | + var emitter = util.dig(this._emitters, doc.collection, doc.id); |
| 75 | + emitter.removeAllListeners(); |
| 76 | + |
| 77 | + util.digAndRemove(this._forwarders, doc.collection, doc.id); |
| 78 | + util.digAndRemove(this._emitters, doc.collection, doc.id); |
| 79 | + util.digAndRemove(this._docs, doc.collection, doc.id); |
| 80 | + } |
| 81 | +} |
0 commit comments