forked from sashin/sashinexists
run npm install to generate a package lock
This commit is contained in:
89
node_modules/@weborigami/origami/src/dev/watch.js
generated
vendored
Normal file
89
node_modules/@weborigami/origami/src/dev/watch.js
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
import { Tree } from "@weborigami/async-tree";
|
||||
import { formatError } from "@weborigami/language";
|
||||
import ConstantTree from "../common/ConstantTree.js";
|
||||
import getTreeArgument from "../common/getTreeArgument.js";
|
||||
|
||||
/**
|
||||
* Let a tree (e.g., of files) respond to changes.
|
||||
*
|
||||
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
||||
* @typedef {import("@weborigami/async-tree").Treelike} Treelike
|
||||
* @typedef {import("../../index.ts").Invocable} Invocable
|
||||
*
|
||||
* @this {AsyncTree|null}
|
||||
* @param {Treelike} [treelike]
|
||||
* @param {Invocable} [fn]
|
||||
*/
|
||||
export default async function watch(treelike, fn) {
|
||||
/** @type {any} */
|
||||
const container = await getTreeArgument(
|
||||
this,
|
||||
arguments,
|
||||
treelike,
|
||||
"dev:watch"
|
||||
);
|
||||
|
||||
// Watch the indicated tree.
|
||||
await /** @type {any} */ (container).watch?.();
|
||||
|
||||
if (fn === undefined) {
|
||||
return container;
|
||||
}
|
||||
|
||||
// The caller supplied a function to reevaluate whenever the tree changes.
|
||||
let tree = await evaluateTree(container, fn);
|
||||
|
||||
// We want to return a stable reference to the tree, so we'll use a prototype
|
||||
// chain that will always point to the latest tree. We'll extend the tree's
|
||||
// prototype chain with an empty object, and use that as a handle (pointer to
|
||||
// a pointer) to the tree. This is what we'll return to the caller.
|
||||
const handle = Object.create(tree);
|
||||
|
||||
// Reevaluate the function whenever the tree changes.
|
||||
container.addEventListener?.("change", async () => {
|
||||
const tree = await evaluateTree(container, fn);
|
||||
updateIndirectPointer(handle, tree);
|
||||
});
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
async function evaluateTree(parent, fn) {
|
||||
let tree;
|
||||
let message;
|
||||
let result;
|
||||
try {
|
||||
result = await fn();
|
||||
} catch (/** @type {any} */ error) {
|
||||
message = formatError(error);
|
||||
}
|
||||
tree = result ? Tree.from(result, { parent }) : undefined;
|
||||
if (tree) {
|
||||
return tree;
|
||||
}
|
||||
if (!message) {
|
||||
message = `warning: watch expression did not return a tree`;
|
||||
}
|
||||
console.warn(message);
|
||||
tree = new ConstantTree(message);
|
||||
tree.parent = parent;
|
||||
return tree;
|
||||
}
|
||||
|
||||
// Update an indirect pointer to a target.
|
||||
function updateIndirectPointer(indirect, target) {
|
||||
// Clean the pointer of any named properties or symbols that have been set
|
||||
// directly on it.
|
||||
try {
|
||||
for (const key of Object.getOwnPropertyNames(indirect)) {
|
||||
delete indirect[key];
|
||||
}
|
||||
for (const key of Object.getOwnPropertySymbols(indirect)) {
|
||||
delete indirect[key];
|
||||
}
|
||||
} catch {
|
||||
// Ignore errors.
|
||||
}
|
||||
|
||||
Object.setPrototypeOf(indirect, target);
|
||||
}
|
||||
Reference in New Issue
Block a user