burdy
Version:
Open Source Headless Platform
125 lines (124 loc) • 5.56 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const async_1 = __importDefault(require("async"));
const md5_1 = __importDefault(require("../md5"));
const hookCache = { actions: {}, filters: {}, syncFilters: {} };
const getQueue = (type, key) => {
var _a;
if (!Array.isArray((_a = hookCache === null || hookCache === void 0 ? void 0 : hookCache[type]) === null || _a === void 0 ? void 0 : _a[key])) {
hookCache[type][key] = [];
}
return hookCache[type][key];
};
const uniqueHookGuard = (queue, id) => {
const exists = queue.some((hook) => hook.id === id);
if (exists) {
const message = `Given function id ${id}, already exists. Ensure that you aren't registering hook twice.`;
console.error(message);
// Module hot breaks if error is thrown in top context
if (!(module === null || module === void 0 ? void 0 : module.hot)) {
throw new Error('duplicate_hook');
}
}
};
const Hooks = {
addAction: (key, action, options = {}) => {
var _a;
const id = (_a = options === null || options === void 0 ? void 0 : options.id) !== null && _a !== void 0 ? _a : (0, md5_1.default)(action.toString());
const queue = getQueue('actions', key);
uniqueHookGuard(queue, id);
queue.push({ function: action, id });
},
addFilter: (key, filter, options = { priority: 10 }) => {
var _a, _b;
const id = (_a = options === null || options === void 0 ? void 0 : options.id) !== null && _a !== void 0 ? _a : (0, md5_1.default)(filter.toString());
const priority = (_b = options === null || options === void 0 ? void 0 : options.priority) !== null && _b !== void 0 ? _b : 10;
const queue = getQueue('filters', key);
uniqueHookGuard(queue, id);
queue.push({ function: filter, id, priority });
queue.sort((a, b) => a.priority - b.priority);
},
addSyncFilter: (key, filterSync, options = { priority: 10 }) => {
var _a, _b;
const id = (_a = options === null || options === void 0 ? void 0 : options.id) !== null && _a !== void 0 ? _a : (0, md5_1.default)(filterSync.toString());
const priority = (_b = options === null || options === void 0 ? void 0 : options.priority) !== null && _b !== void 0 ? _b : 10;
const queue = getQueue('syncFilters', key);
uniqueHookGuard(queue, id);
queue.push({ function: filterSync, id, priority });
queue.sort((a, b) => a.priority - b.priority);
},
removeAction: (key, id) => {
const queue = getQueue('actions', key);
const targetIndex = queue.findIndex((hook) => hook.id === id);
if (targetIndex !== -1) {
queue.splice(targetIndex, 1);
}
},
removeFilter: (key, id) => {
const queue = getQueue('filters', key);
const targetIndex = queue.findIndex((hook) => hook.id !== id);
if (targetIndex !== -1) {
queue.splice(targetIndex, 1);
}
},
hasAction: (key, id) => {
const queue = getQueue('filters', key);
return queue.some((hook) => hook.id === id);
},
hasFilter: (key, id) => {
const queue = getQueue('filters', key);
return queue.some((hook) => hook.id === id);
},
doAction: (key, ...args) => __awaiter(void 0, void 0, void 0, function* () {
const queue = getQueue('actions', key);
yield async_1.default.each(queue, (hook, next) => __awaiter(void 0, void 0, void 0, function* () {
try {
yield hook.function(...args);
next();
}
catch (err) {
next(err);
}
}));
}),
applyFilters: (key, ...args) => __awaiter(void 0, void 0, void 0, function* () {
const [first, ...rest] = args;
const queue = getQueue('filters', key);
return async_1.default.reduce(queue, first, (memo, hook, next) => __awaiter(void 0, void 0, void 0, function* () {
try {
const result = yield hook.function(memo, ...rest);
next(null, result);
}
catch (e) {
next(e, memo);
}
}));
}),
applySyncFilters: (key, ...args) => {
const [first, ...rest] = args;
const queue = getQueue('syncFilters', key);
return queue.reduce((memo, hook) => hook.function(memo, ...rest), first);
},
getQueue: (type) => hookCache[type],
clearQueue: (type) => {
hookCache[type] = {};
},
clearAllQueues: () => {
Object.keys(hookCache).forEach((key) => {
hookCache[key] = {};
});
},
};
exports.default = Hooks;