diff --git a/src/create-type.js b/src/create-type.js index d8538e5..22cbb21 100644 --- a/src/create-type.js +++ b/src/create-type.js @@ -1,5 +1,6 @@ "use strict"; +const events = require("events"); const mapObj = require("map-obj"); const typeRules = require("./type-rules"); @@ -50,14 +51,17 @@ module.exports = function createType(name, schema) { } }; - let proto = Object.create(protoProperties, propertyDescriptors); + let proto = Object.create(events.EventEmitter.prototype, propertyDescriptors); + Object.assign(proto, protoProperties); + let schemaKeys = getSchemaKeys(schema); let factory = function createInstance(instanceProps) { factory._isUsed = true; let instance = Object.create(proto); - instance._data = {}; + events.EventEmitter.call(instance); + instance._data = {}; /* FIXME: Is this not a deopt, because it breaks monomorphism? */ // for (let key of factory._schemaKeys) { // if (instanceProps[key] != null) { @@ -135,7 +139,7 @@ module.exports = function createType(name, schema) { factory.deserialize = function (data, deserializer) { hashAllTypes(); - + return deserialize(this, JSON.parse(data), typeMap, { deserializer: deserializer }); diff --git a/test/events.js b/test/events.js new file mode 100644 index 0000000..c218d51 --- /dev/null +++ b/test/events.js @@ -0,0 +1,39 @@ +"use strict"; + +const expect = require("chai").expect; + +const dm = require("../src"); + +let User = dm.createType("User", { + name: dm.string(), + messages: dm.setOf(dm.string()), + addMessage: dm.guard([dm.string()], dm.nothing(), function (message) { + this.messages.add(message); + this.emit("message:added", message); + }) +}); + +describe("events", () => { + it("should behave like an EventEmitter", () => { + let joe = User({ + name: "Joe", + messages: new Set() + }); + + let messageCounter = 0; + + joe.addListener("message:added", (message) => { + messageCounter += 1; + }); + + joe.addMessage("Hello world!"); + + expect(messageCounter).to.equal(1); + + joe.removeAllListeners("message:added"); + + joe.addMessage("This should not fire a handler"); + + expect(messageCounter).to.equal(1); + }); +});