serverless-offline-msk
Version:
A serverless offline plugin that enables AWS MSK events
108 lines (105 loc) • 2.62 kB
JavaScript
"use strict";
var invoke = require("es5-ext/function/invoke")
, assign = require("es5-ext/object/assign")
, isValue = require("es5-ext/object/is-value")
, forEach = require("es5-ext/object/for-each")
, deferred = require("deferred")
, dirname = require("path").dirname;
// eslint-disable-next-line no-empty-function
var FindRoot = function () {};
FindRoot.prototype = {
known: false,
close: function () {
if (this.promises) {
forEach(this.promises, invoke("close"));
this.known = true;
delete this.promises;
}
if (!this.promise.resolved) {
this.reject(new Error("Find root action cancelled"));
}
},
onvalue: function (value) {
if (this.known) {
return;
}
if (value) {
this.known = true;
if (this.watch && this.promise.resolved) {
this.promise.value = this.path;
this.promise.emit("change", this.path);
} else {
this.resolve(this.path);
}
} else {
this.down();
}
},
next: function () {
var isRoot;
isRoot = this.isRoot(this.path);
if (this.watch) {
this.promises[this.path] = isRoot;
isRoot.on("change", this.onevent);
}
isRoot.done(this.onvalue);
},
down: function () {
var dir = dirname(this.path);
if (dir === this.path) {
this.known = true;
this.path = "";
if (this.watch && this.promise.resolved) {
this.promise.value = null;
this.promise.emit("change", null);
} else {
this.resolve(null);
}
return;
}
this.path = dir;
this.next();
},
onevent: function (value, path) {
var dir;
if (value) {
if (!isValue(path)) throw new TypeError("Path must be provided");
this.path = path;
dir = dirname(path);
while (this.promises[dir]) {
this.promises[dir].close();
delete this.promises[dir];
dir = dirname(dir);
}
this.known = true;
// Race condition may occur, double check
if (this.promise.value !== this.path) {
this.promise.value = this.path;
this.promise.emit("change", this.path);
}
} else {
if (!this.known || path !== this.path) {
return;
}
this.known = false;
this.down();
}
}
};
module.exports = function (isRoot, path/*, options*/) {
var findRoot, options;
options = arguments[2];
findRoot = new FindRoot();
findRoot.isRoot = isRoot;
findRoot.path = path;
findRoot.onvalue = findRoot.onvalue.bind(findRoot);
findRoot.onevent = findRoot.onevent.bind(findRoot);
assign(findRoot, deferred());
findRoot.watch = options && options.watch;
if (findRoot.watch) {
findRoot.promises = {};
findRoot.promise.close = findRoot.close.bind(findRoot);
}
findRoot.next();
return findRoot.promise;
};