Socket
Socket
Sign inDemoInstall

edifice-facade

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

edifice-facade - npm Package Compare versions

Comparing version 0.2.0 to 0.3.0

.c9/.nakignore

63

lib/facade.js

@@ -1,40 +0,37 @@

var util = require("util"),
EventEmitter = require("events").EventEmitter;
module.exports = Facade;
Facade.Facade = Facade;
util.inherits(Facade, EventEmitter);
module.exports.Facade = Facade;
function Facade(core, permissions) {
function Facade(core, actions, listeners) {
var thisFacade = this;
// Pass this to all events so that this facade knows its own events.
var identifier = new FacadeIdentifier();
actions = actions || [];
listeners = listeners || [];
permissions = permissions || {};
pipeEvents(actions, this, core);
pipeEvents(listeners, core, this).forEach(function (fn) {
// so that core can find events by facade
fn.facade = thisFacade;
this.emit = function (eventName) {
if (permissions.emit && permissions.emit.indexOf(eventName) === -1) {
throw new Error("Event '" + eventName + "' not in 'emit' array");
}
core.emit.apply(
core, Array.from(arguments).concat(identifier));
};
this.on = function (eventName, cb) {
if (permissions.on && permissions.on.indexOf(eventName) === -1) {
throw new Error("Event '" + eventName + "' not in 'on' array");
}
core.on(eventName, function () {
var idFlag;
if (arguments[arguments.length - 1] === identifier) {
return;
}
if (arguments[arguments.length - 1] instanceof FacadeIdentifier) {
idFlag = -1;
}
cb.apply(null, Array.from(arguments).slice(0, idFlag));
});
};
}
function pipeEvents(eventList, origin, destination) {
return eventList.map(function (event) {
origin.on(event, handler);
return handler;
function handler() {
var backup = origin.listeners(event);
// prevent infinite recursion
origin.removeAllListeners(event);
destination.emit.apply(destination,
Array.prototype.concat.apply([event], arguments));
// restore backup
backup.forEach(function (listener) {
origin.on(event, listener);
});
}
});
}
// Make all identifiers instances of the same class so that they can be
// identified and stripped out of events.
function FacadeIdentifier () {}
{
"name": "edifice-facade",
"version": "0.2.0",
"version": "0.3.0",
"description": "Create facades to separate modules in your application",

@@ -32,5 +32,4 @@ "main": "lib/facade.js",

"grunt-contrib-watch": "~0.6.1",
"jshint": "~2.5.0",
"clone": "~0.1.11"
"jshint": "~2.5.0"
}
}
edifice-facade
==============
Create facades to separate modules in your application
Create facades to separate modules in your application.
Facades rely on a core which can be as simple as an EventEmitter. They separate
modules from each other, so that the modules communicate with each other using
events.
modules from each other, and the modules communicate using events. It also
enhances internal application security, ensuring nothing has more in scope than
it needs.
````
````js
var EventEmitter = require("events").EventEmitter,

@@ -16,13 +17,49 @@ Facade = require("edifice-facade");

var fileInterfaceFacade = new Facade(core,
['fileDataRead', 'fileWritten'], // permitted actions
['newInputData'] // permitted listeners
);
var userInterfaceFacade = new Facade(core,
['newInputData'],
['fileDataRead', 'fileWritten']
);
var timerFacade = new Facade(core);
var userInterfaceFacade = new Facade(core);
````
Now pass these facades to your `fileInterface` and `userInterface`, so they
Now pass these facades to your `timer` and `userInterface`, so they
don't need to have each other or the core itself in scope.
````js
function userInterface(facade) {
timerUserEntry.onchange = function () {
facade.emit('timerValueChange', this.value);
};
facade.on('timerValueChange', function (timerVal) {
timerUserEntry.value = timerVal;
});
}
````
Facades don't respond to their own events, only events from other facades,
allowing the same data to be updated and read my multiple sources, while
preventing loops or awkward if statements.
Module permissions
------------------
Facades can be restricted in what events they can send and receive.
````js
var fileSystemFacade = new Facade(core, {
emit : ['writeSuccess', 'fileContents'],
on : ['save', 'read']
});
// This line will throw an error, as fileSystemFacade doesn't have receive (on)
// permissions on userInteraction.
fileSystemFacade.on('userInteraction', function () { ... });
// This line will also throw, as fileSystemFacade doesn't have send (emit)
// permissions on save. It should be doing the saving!
fileSystemFacade.emit('save', data);
````
Why the name edifice-facade?
----------------------------
I originally planned on making a module called edifice as the core, then
realised the core could just be a plain old EventEmitter. So ediface is no more.
License
-------
MIT.
var clone = require("clone"),
EventEmitter = require("events").EventEmitter,
expect = require("expect.js"),
injectr = require("injectr"),
pretendr = require("pretendr");
EventEmitter = require("events").EventEmitter,
expect = require("expect.js"),
injectr = require("injectr"),
pretendr = require("pretendr");
describe("Facade", function () {
var Facade,
mockCore,
core,
coreListener;
var Facade,
core,
coreListener;
beforeEach(function () {
core = new EventEmitter();
coreListener = pretendr(function () {});
core.on("a", coreListener.mock);
});
describe("#emit", function () {
beforeEach(function () {
core = new EventEmitter();
coreListener = pretendr(function () {});
core.on("a", coreListener.mock);
Facade = injectr("../lib/facade.js").Facade;
});
it("inherits EventEmitter", function () {
var requires;
requires = pretendr({
util : {
inherits : function () {}
},
events : {
EventEmitter : function () {}
}
});
Facade = injectr("../lib/facade.js", requires.mock).Facade;
expect(requires.util.inherits.calls).to.have.length(1);
expect(requires.util.inherits.calls[0].args)
.to.have.property(0, Facade)
.and.to.have.property(1, requires.events.EventEmitter.mock);
it("passes events to the core", function () {
var facade = new Facade(core);
facade.emit("a");
expect(coreListener.calls).to.have.length(1);
});
it("makes the array properties optional", function () {
Facade = injectr("../lib/facade.js").Facade;
expect(function () {
new Facade(new EventEmitter());
}).to.not.throwException();
it("passes arguments to the core", function () {
var eventData = [{}, {}, {}],
facade = new Facade(core);
facade.emit("a", eventData[0], eventData[1], eventData[2]);
expect(coreListener.calls[0].args[0]).to.equal(eventData[0]);
expect(coreListener.calls[0].args[1]).to.equal(eventData[1]);
expect(coreListener.calls[0].args[2]).to.equal(eventData[2]);
});
describe("#emit", function () {
beforeEach(function () {
Facade = injectr("../lib/facade.js").Facade;
});
it("passes emits to the core for listed actions", function () {
var eventData = {},
facade = new Facade(core, ["a"], []);
facade.emit("a", eventData);
expect(coreListener.calls).to.have.length(1);
expect(coreListener.calls[0].args)
.to.have.property(0, eventData);
});
it("passes emits to the core with no data", function () {
var facade = new Facade(core, ["a"], []);
facade.emit("a");
expect(coreListener.calls).to.have.length(1);
expect(coreListener.calls[0].args).to.have.length(0);
});
it("doesn't emit multiple times", function () {
var facade = new Facade(core, ["a"], ["a"]),
listener = pretendr(function () {});
facade.on("a", listener.mock);
facade.emit("a", {});
expect(coreListener.calls).to.have.length(1);
expect(listener.calls).to.have.length(1);
});
it("doesn't disrupt the listeners on itself", function () {
var e,
facade = new Facade(core, ["a"], ["a", "b"]);
["a", "a", "b"].forEach(function (e) {
facade.on(e, function () {});
});
e = clone(facade._events);
facade.emit("a");
expect(facade._events).to.eql(e);
});
it("doesn't pass emits of non-listed actions", function () {
var facade = new Facade(core, ["c"], []);
facade.emit("a", {});
expect(coreListener.calls).to.have.length(0);
});
it("passes multiple arguments to the core", function () {
var facade = new Facade(core, ["a"], []);
facade.emit("a", "b", "c");
expect(coreListener.calls).to.have.length(1);
expect(coreListener.calls[0].args)
.to.have.property(0, "b")
.and.to.have.property(1, "c");
});
it("throws an error when events aren't in the emit array", function () {
var facade = new Facade(core, {
emit : []
});
expect(function () {
facade.emit('a');
}).to.throwError(/Event 'a' not in 'emit' array/);
});
describe("#on", function () {
beforeEach(function () {
Facade = injectr("../lib/facade.js").Facade;
mockCore = pretendr({
on : function () {},
emit : function () {}
});
});
it("passes handlers to the core for listed listeners", function () {
var fn = pretendr(function () {}),
facade = new Facade(core, [], ["b"]);
facade.on("b", fn.mock);
expect(core.listeners("b")).to.have.length(1);
core.emit("b", "foo");
expect(fn.calls).to.have.length(1);
expect(fn.calls[0].args).to.have.property(0, "foo");
});
it("doesn't pass handlers for non-listed listeners", function () {
var facade = new Facade(core, [], ["b"]),
listener = pretendr(function () {});
facade.on("c", listener.mock);
core.emit("c");
expect(listener.calls).to.have.length(0);
});
it("adds the facade as a property of the handler", function () {
var facade = new Facade(core, [], ["b"]);
facade.on("b", function () {});
expect(core.listeners("b")[0])
.to.have.property("facade", facade);
});
it("doesn't throw an error when events are in the emit array", function () {
var facade = new Facade(core, {
emit : ['a']
});
expect(function () {
facade.emit('a');
}).not.to.throwError();
});
});
});
describe("#on", function () {
var listener;
beforeEach(function () {
Facade = injectr("../lib/facade.js").Facade;
listener = pretendr(function () {});
});
it("listens for events on the core", function () {
var facade = new Facade(core);
facade.on('b', listener.mock);
core.emit('b');
expect(listener.calls).to.have.length(1);
});
it("does not listen for events created by own emit", function () {
var facade = new Facade(core);
facade.on('c', listener.mock);
facade.emit('c');
expect(listener.calls).to.have.length(0);
});
it("has arguments passed from the core", function () {
var arg = {},
facade = new Facade(core);
facade.on('c', listener.mock);
core.emit('c', arg);
expect(listener.calls[0].args[0]).to.equal(arg);
});
it("throws an error when events aren't in the 'on' array", function () {
var facade = new Facade(core, {
on : []
});
expect(function () {
facade.on('a');
}).to.throwError(/Event 'a' not in 'on' array/);
});
it("doesn't throw an error when events are in the 'on' array", function () {
var facade = new Facade(core, {
on : ['a']
});
expect(function () {
facade.on('a');
}).not.to.throwError();
});
});
describe("pair of facades", function () {
var facades,
listener;
beforeEach(function () {
Facade = injectr("../lib/facade.js").Facade;
listener = pretendr(function () {});
facades = [new Facade(core), new Facade(core)];
});
it("will pass arguments exactly between them", function () {
var args = [{}, [], '3'];
facades[0].on('a', listener.mock);
facades[1].emit('a', args[0], args[1], args[2]);
expect(listener.calls[0].args)
.to.have.length(args.length)
.and.to.have.property(0, args[0])
.and.to.have.property(1, args[1])
.and.to.have.property(2, args[2]);
});
});
});

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc