UNPKG

@mdfriday/foundry

Version:

The core engine of MDFriday. Convert Markdown and shortcodes into fully themed static sites – Hugo-style, powered by TypeScript.

193 lines 5.81 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.MutableTrees = exports.WalkableTrees = exports.WalkContext = exports.Event = exports.LockType = void 0; exports.validateKey = validateKey; exports.cleanKey = cleanKey; exports.mustValidateKey = mustValidateKey; const radix_1 = require("../radix"); var LockType; (function (LockType) { LockType[LockType["LockTypeNone"] = 0] = "LockTypeNone"; LockType[LockType["LockTypeRead"] = 1] = "LockTypeRead"; LockType[LockType["LockTypeWrite"] = 2] = "LockTypeWrite"; })(LockType || (exports.LockType = LockType = {})); // Event is used to communicate events in the tree. class Event { constructor(name, path, source) { this.stopPropagationFlag = false; this.name = name; this.path = path; this.source = source; } // StopPropagation stops the propagation of the event. stopPropagation() { this.stopPropagationFlag = true; } get shouldStopPropagation() { return this.stopPropagationFlag; } } exports.Event = Event; // WalkContext is passed to the Walk callback. class WalkContext { constructor() { this.dataInitialized = false; this.events = []; this.hooksPost = []; } // AddEventListener adds an event listener to the tree. // Note that the handler func may not add listeners. addEventListener(event, path, handler) { if (!this.eventHandlers) { this.eventHandlers = new Map(); } if (!this.eventHandlers.has(event)) { this.eventHandlers.set(event, []); } // We want to match all above the path, so we need to exclude any similar named siblings. let targetPath = path; if (!targetPath.endsWith('/')) { targetPath += '/'; } this.eventHandlers.get(event).push((e) => { // Propagate events up the tree only. if (e.path.startsWith(targetPath)) { handler(e); } }); } // AddPostHook adds a post hook to the tree. // This will be run after the tree has been walked. addPostHook(handler) { this.hooksPost.push(handler); } data() { if (!this.dataInitialized) { this.dataInstance = { tree: new radix_1.Tree() }; this.dataInitialized = true; } return this.dataInstance; } // SendEvent sends an event up the tree. sendEvent(event) { this.events.push(event); } async handleEvents() { while (this.events.length > 0) { const event = this.events.shift(); if (this.eventHandlers && this.eventHandlers.has(event.name)) { const handlers = this.eventHandlers.get(event.name); // Loop the event handlers in reverse order so // that events created by the handlers themselves will // be picked up further up the tree. for (let i = handlers.length - 1; i >= 0; i--) { handlers[i](event); if (event.shouldStopPropagation) { break; } } } } } async handleEventsAndHooks() { await this.handleEvents(); for (const hook of this.hooksPost) { await hook(); } } } exports.WalkContext = WalkContext; class WalkableTrees { constructor(trees) { this.trees = trees; } walkPrefixRaw(prefix, walker) { for (const tree of this.trees) { tree.walkPrefixRaw(prefix, walker); } } } exports.WalkableTrees = WalkableTrees; class MutableTrees { constructor(trees) { this.trees = trees; } delete(key) { for (const tree of this.trees) { tree.delete(key); } } deleteAll(key) { for (const tree of this.trees) { tree.deleteAll(key); } } async deletePrefix(prefix) { let count = 0; for (const tree of this.trees) { count += await tree.deletePrefix(prefix); } return Promise.resolve(count); } async deletePrefixAll(prefix) { let count = 0; for (const tree of this.trees) { count += await tree.deletePrefixAll(prefix); } return count; } lock(writable) { const commits = this.trees.map(tree => tree.lock(writable)); return () => { for (const commit of commits) { commit(); } }; } canLock() { for (const tree of this.trees) { if (!tree.canLock()) { return false; } } return true; } } exports.MutableTrees = MutableTrees; // ValidateKey returns an error if the key is not valid. function validateKey(key) { if (key === '') { // Root node. return null; } if (key.length < 2) { return new Error(`too short key: "${key}"`); } if (key[0] !== '/') { return new Error(`key must start with '/': "${key}"`); } if (key[key.length - 1] === '/') { return new Error(`key must not end with '/': "${key}"`); } return null; } function cleanKey(key) { if (key === '/') { // The path to the home page is logically "/", // but for technical reasons, it's stored as "". // This allows us to treat the home page as a section, // and a prefix search for "/" will return the home page's descendants. return ''; } return key; } function mustValidateKey(key) { const err = validateKey(key); if (err) { throw err; } return key; } //# sourceMappingURL=support.js.map