@weborigami/origami 0.0.59 → 0.0.61
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/exports/exports.js +3 -7
- package/package.json +4 -4
- package/src/builtins/@breakpoint.js +12 -0
- package/src/builtins/@cache.js +3 -6
- package/src/builtins/@concat.js +3 -4
- package/src/builtins/@config.js +3 -12
- package/src/builtins/@constructor.js +3 -7
- package/src/builtins/@copy.js +2 -2
- package/src/builtins/@crawl.js +4 -6
- package/src/builtins/@debug.js +5 -6
- package/src/builtins/@deepMap.js +2 -2
- package/src/builtins/@deepMapFn.js +2 -2
- package/src/builtins/@deepMerge.js +3 -18
- package/src/builtins/@deepReverse.js +1 -3
- package/src/builtins/@deepTakeFn.js +5 -6
- package/src/builtins/@defineds.js +4 -7
- package/src/builtins/@document.js +2 -2
- package/src/builtins/@exceptions.js +1 -5
- package/src/builtins/@explore.js +15 -14
- package/src/builtins/@files.js +4 -6
- package/src/builtins/@filter.js +3 -6
- package/src/builtins/@fnTree.js +8 -22
- package/src/builtins/@globs.js +3 -6
- package/src/builtins/@groupFn.js +7 -8
- package/src/builtins/@help.js +2 -2
- package/src/builtins/@http.js +2 -2
- package/src/builtins/@https.js +2 -2
- package/src/builtins/@if.js +2 -2
- package/src/builtins/@image/format.js +2 -2
- package/src/builtins/@image/formatFn.js +6 -3
- package/src/builtins/@image/resize.js +2 -2
- package/src/builtins/@image/resizeFn.js +6 -3
- package/src/builtins/@inherited.js +2 -2
- package/src/builtins/@inline.js +5 -9
- package/src/builtins/@inners.js +0 -1
- package/src/builtins/@invoke.js +4 -7
- package/src/builtins/@json.js +3 -3
- package/src/builtins/@map.js +2 -2
- package/src/builtins/@mapFn.js +9 -10
- package/src/builtins/@match.js +17 -16
- package/src/builtins/@mdHtml.js +7 -1
- package/src/builtins/@merge.js +3 -18
- package/src/builtins/@once.js +2 -2
- package/src/builtins/@ori.js +12 -8
- package/src/builtins/@pack.js +2 -2
- package/src/builtins/@package.js +4 -8
- package/src/builtins/@paginateFn.js +1 -6
- package/src/builtins/@perf.js +2 -2
- package/src/builtins/@project.js +31 -22
- package/src/builtins/@reverse.js +1 -3
- package/src/builtins/@rss.js +78 -24
- package/src/builtins/@serve.js +2 -2
- package/src/builtins/@sitemap.js +4 -1
- package/src/builtins/@sortFn.js +6 -7
- package/src/builtins/@string.js +2 -2
- package/src/builtins/@takeFn.js +5 -6
- package/src/builtins/@treeHttp.js +2 -2
- package/src/builtins/@treeHttps.js +2 -2
- package/src/builtins/@unpack.js +2 -2
- package/src/builtins/@watch.js +5 -12
- package/src/builtins/@yaml.js +3 -3
- package/src/builtins/ori_handler.js +3 -3
- package/src/builtins/~.js +3 -3
- package/src/cli/cli.js +6 -19
- package/src/common/ConstantTree.js +1 -0
- package/src/common/ExplorableSiteTransform.js +9 -12
- package/src/common/documentObject.js +2 -2
- package/src/common/processUnpackedContent.js +12 -18
- package/src/common/utilities.js +2 -3
- package/src/misc/OriCommandTransform.js +1 -9
- package/src/misc/assertTreeIsDefined.d.ts +1 -0
- package/src/misc/assertTreeIsDefined.js +7 -0
- package/src/misc/getTreeArgument.js +11 -12
- package/src/misc/origamiHighlightDefinition.js +36 -0
- package/src/server/server.js +3 -10
- package/src/builtins/@arrowsMap.js +0 -25
- package/src/builtins/@scope/extend.js +0 -22
- package/src/builtins/@scope/get.js +0 -25
- package/src/builtins/@scope/invoke.js +0 -22
- package/src/builtins/@scope/set.js +0 -25
- package/src/common/addValueKeyToScope.js +0 -23
- package/src/misc/assertScopeIsDefined.js +0 -7
package/src/builtins/@help.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** @typedef {import("@weborigami/types").AsyncTree} AsyncTree */
|
|
2
2
|
import child_process from "node:child_process";
|
|
3
|
-
import
|
|
3
|
+
import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
|
|
4
4
|
|
|
5
5
|
const groupUrls = {
|
|
6
6
|
"@cache": "https://weborigami.org/language/@cache.html",
|
|
@@ -15,7 +15,7 @@ const groupUrls = {
|
|
|
15
15
|
* @param {string} [name]
|
|
16
16
|
*/
|
|
17
17
|
export default async function help(name) {
|
|
18
|
-
|
|
18
|
+
assertTreeIsDefined(this, "help");
|
|
19
19
|
let url;
|
|
20
20
|
const scope = this;
|
|
21
21
|
if (scope && name) {
|
package/src/builtins/@http.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ops } from "@weborigami/language";
|
|
2
|
-
import
|
|
2
|
+
import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Retrieve the indicated web resource via HTTP.
|
|
@@ -11,7 +11,7 @@ import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
|
|
|
11
11
|
* @param {...string} keys
|
|
12
12
|
*/
|
|
13
13
|
export default async function http(host, ...keys) {
|
|
14
|
-
|
|
14
|
+
assertTreeIsDefined(this, "http");
|
|
15
15
|
return ops.http.call(this, host, ...keys);
|
|
16
16
|
}
|
|
17
17
|
|
package/src/builtins/@https.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ops } from "@weborigami/language";
|
|
2
|
-
import
|
|
2
|
+
import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Retrieve the indicated web resource via HTTPS.
|
|
@@ -11,7 +11,7 @@ import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
|
|
|
11
11
|
* @param {...string} keys
|
|
12
12
|
*/
|
|
13
13
|
export default async function https(host, ...keys) {
|
|
14
|
-
|
|
14
|
+
assertTreeIsDefined(this, "https");
|
|
15
15
|
return ops.https.call(this, host, ...keys);
|
|
16
16
|
}
|
|
17
17
|
|
package/src/builtins/@if.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** @typedef {import("@weborigami/types").AsyncTree} AsyncTree */
|
|
2
2
|
import { Tree } from "@weborigami/async-tree";
|
|
3
|
-
import
|
|
3
|
+
import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @this {AsyncTree|null}
|
|
@@ -9,7 +9,7 @@ import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
|
|
|
9
9
|
* @param {any} [falseResult]
|
|
10
10
|
*/
|
|
11
11
|
export default async function ifCommand(value, trueResult, falseResult) {
|
|
12
|
-
|
|
12
|
+
assertTreeIsDefined(this, "if");
|
|
13
13
|
let condition = await value;
|
|
14
14
|
if (Tree.isAsyncTree(condition)) {
|
|
15
15
|
const keys = Array.from(await condition.keys());
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import assertTreeIsDefined from "../../misc/assertTreeIsDefined.js";
|
|
2
2
|
import imageFormatFn from "./formatFn.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -13,6 +13,6 @@ import imageFormatFn from "./formatFn.js";
|
|
|
13
13
|
* @param {any} options
|
|
14
14
|
*/
|
|
15
15
|
export default async function imageFormat(input, format, options) {
|
|
16
|
-
|
|
16
|
+
assertTreeIsDefined(this, "image/format");
|
|
17
17
|
return imageFormatFn.call(this, format, options)(input);
|
|
18
18
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import sharp from "sharp";
|
|
2
|
-
import
|
|
2
|
+
import assertTreeIsDefined from "../../misc/assertTreeIsDefined.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Return a function that transforms an input image to a different format.
|
|
@@ -10,6 +10,9 @@ import assertScopeIsDefined from "../../misc/assertScopeIsDefined.js";
|
|
|
10
10
|
* @param {any} options
|
|
11
11
|
*/
|
|
12
12
|
export default function imageFormatFn(format, options) {
|
|
13
|
-
|
|
14
|
-
return (buffer) =>
|
|
13
|
+
assertTreeIsDefined(this, "image/formatFn");
|
|
14
|
+
return (buffer) =>
|
|
15
|
+
buffer instanceof Uint8Array || buffer instanceof ArrayBuffer
|
|
16
|
+
? sharp(buffer).toFormat(format, options).toBuffer()
|
|
17
|
+
: undefined;
|
|
15
18
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import assertTreeIsDefined from "../../misc/assertTreeIsDefined.js";
|
|
2
2
|
import imageResizeFn from "./resizeFn.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -9,6 +9,6 @@ import imageResizeFn from "./resizeFn.js";
|
|
|
9
9
|
* @param {import("sharp").ResizeOptions} options
|
|
10
10
|
*/
|
|
11
11
|
export default async function resize(input, options) {
|
|
12
|
-
|
|
12
|
+
assertTreeIsDefined(this, "image/resize");
|
|
13
13
|
return imageResizeFn.call(this, options)(input);
|
|
14
14
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import sharp from "sharp";
|
|
2
|
-
import
|
|
2
|
+
import assertTreeIsDefined from "../../misc/assertTreeIsDefined.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Return a function that resizes an image.
|
|
@@ -8,7 +8,10 @@ import assertScopeIsDefined from "../../misc/assertScopeIsDefined.js";
|
|
|
8
8
|
* @param {import("sharp").ResizeOptions} options
|
|
9
9
|
*/
|
|
10
10
|
export default function imageResizeFn(options) {
|
|
11
|
-
|
|
11
|
+
assertTreeIsDefined(this, "image/resizeFn");
|
|
12
12
|
// Include `rotate()` to auto-rotate according to EXIF data.
|
|
13
|
-
return (buffer) =>
|
|
13
|
+
return (buffer) =>
|
|
14
|
+
buffer instanceof Uint8Array || buffer instanceof ArrayBuffer
|
|
15
|
+
? sharp(buffer).rotate().resize(options).toBuffer()
|
|
16
|
+
: undefined;
|
|
14
17
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** @typedef {import("@weborigami/types").AsyncTree} AsyncTree */
|
|
2
2
|
import { ops } from "@weborigami/language";
|
|
3
|
-
import
|
|
3
|
+
import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Return the inherited value (if any) for the indicated key.
|
|
@@ -9,7 +9,7 @@ import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
|
|
|
9
9
|
* @this {AsyncTree|null}
|
|
10
10
|
*/
|
|
11
11
|
export default async function inherited(key) {
|
|
12
|
-
|
|
12
|
+
assertTreeIsDefined(this, "inherited");
|
|
13
13
|
return ops.inherited.call(this, key);
|
|
14
14
|
}
|
|
15
15
|
|
package/src/builtins/@inline.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isUnpackable, symbols } from "@weborigami/async-tree";
|
|
2
2
|
import { compile } from "@weborigami/language";
|
|
3
3
|
import documentObject from "../common/documentObject.js";
|
|
4
4
|
import { toString } from "../common/utilities.js";
|
|
5
|
-
import
|
|
5
|
+
import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
|
|
6
6
|
import fileTypeOrigami from "./ori_handler.js";
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -16,7 +16,7 @@ import fileTypeOrigami from "./ori_handler.js";
|
|
|
16
16
|
* @param {StringLike} input
|
|
17
17
|
*/
|
|
18
18
|
export default async function inline(input) {
|
|
19
|
-
|
|
19
|
+
assertTreeIsDefined(this, "inline");
|
|
20
20
|
|
|
21
21
|
// Get the input text and any attached front matter.
|
|
22
22
|
if (isUnpackable(input)) {
|
|
@@ -25,12 +25,8 @@ export default async function inline(input) {
|
|
|
25
25
|
const inputIsDocument = input["@text"] !== undefined;
|
|
26
26
|
const origami = inputIsDocument ? input["@text"] : toString(input);
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
// Construct a temporary parent that has the right scope.
|
|
31
|
-
parent = new ObjectTree({});
|
|
32
|
-
parent.scope = this;
|
|
33
|
-
}
|
|
28
|
+
const parent =
|
|
29
|
+
/** @type {any} */ (input).parent ?? input[symbols.parent] ?? this;
|
|
34
30
|
|
|
35
31
|
// If the input document is a plain object, include it in scope for the
|
|
36
32
|
// evaluated expression.
|
package/src/builtins/@inners.js
CHANGED
|
@@ -12,7 +12,6 @@ import getTreeArgument from "../misc/getTreeArgument.js";
|
|
|
12
12
|
export default async function inners(treelike) {
|
|
13
13
|
const tree = await getTreeArgument(this, arguments, treelike, "@inners");
|
|
14
14
|
|
|
15
|
-
/** @type {AsyncTree} */
|
|
16
15
|
const result = {
|
|
17
16
|
async get(key) {
|
|
18
17
|
const value = await tree.get(key);
|
package/src/builtins/@invoke.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { isUnpackable } from "@weborigami/async-tree";
|
|
2
|
-
import
|
|
3
|
-
import builtins from "./@builtins.js";
|
|
2
|
+
import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* Invoke the given text as an Origami function.
|
|
@@ -24,9 +23,8 @@ import builtins from "./@builtins.js";
|
|
|
24
23
|
* @this {import("@weborigami/types").AsyncTree|null}
|
|
25
24
|
*/
|
|
26
25
|
export default async function invoke(fn) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if (arguments.length > 0 && fn === undefined) {
|
|
26
|
+
assertTreeIsDefined(this, "invoke");
|
|
27
|
+
if (fn === undefined) {
|
|
30
28
|
throw new Error(
|
|
31
29
|
"An Origami function was called with an initial argument, but its value is undefined."
|
|
32
30
|
);
|
|
@@ -34,6 +32,5 @@ export default async function invoke(fn) {
|
|
|
34
32
|
if (isUnpackable(fn)) {
|
|
35
33
|
fn = await fn.unpack();
|
|
36
34
|
}
|
|
37
|
-
|
|
38
|
-
return typeof fn === "function" ? fn.call(scope) : fn;
|
|
35
|
+
return typeof fn === "function" ? fn.call(this) : fn;
|
|
39
36
|
}
|
package/src/builtins/@json.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** @typedef {import("@weborigami/types").AsyncTree} AsyncTree */
|
|
2
2
|
import { isUnpackable, toPlainValue } from "@weborigami/async-tree";
|
|
3
|
-
import
|
|
3
|
+
import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Render the given object in JSON format.
|
|
@@ -9,14 +9,14 @@ import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
|
|
|
9
9
|
* @param {any} [obj]
|
|
10
10
|
*/
|
|
11
11
|
export default async function json(obj) {
|
|
12
|
-
|
|
12
|
+
assertTreeIsDefined(this, "json");
|
|
13
13
|
// A fragment of the logic from getTreeArgument.js
|
|
14
14
|
if (arguments.length > 0 && obj === undefined) {
|
|
15
15
|
throw new Error(
|
|
16
16
|
"An Origami function was called with an initial argument, but its value is undefined."
|
|
17
17
|
);
|
|
18
18
|
}
|
|
19
|
-
obj = obj ??
|
|
19
|
+
obj = obj ?? this;
|
|
20
20
|
if (obj === undefined) {
|
|
21
21
|
return undefined;
|
|
22
22
|
}
|
package/src/builtins/@map.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
|
|
2
2
|
import mapFn from "./@mapFn.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -14,6 +14,6 @@ import mapFn from "./@mapFn.js";
|
|
|
14
14
|
* @param {ValueKeyFn|TreeMapOptions} operation
|
|
15
15
|
*/
|
|
16
16
|
export default function map(source, operation) {
|
|
17
|
-
|
|
17
|
+
assertTreeIsDefined(this, "map");
|
|
18
18
|
return mapFn.call(this, operation)(source);
|
|
19
19
|
}
|
package/src/builtins/@mapFn.js
CHANGED
|
@@ -4,9 +4,8 @@ import {
|
|
|
4
4
|
keyFunctionsForExtensions,
|
|
5
5
|
mapFn,
|
|
6
6
|
} from "@weborigami/async-tree";
|
|
7
|
-
import { Scope } from "@weborigami/language";
|
|
8
7
|
import { toFunction } from "../common/utilities.js";
|
|
9
|
-
import
|
|
8
|
+
import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
|
|
10
9
|
|
|
11
10
|
/**
|
|
12
11
|
* Return a function that transforms a tree of keys and values to a new tree of
|
|
@@ -21,8 +20,8 @@ import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
|
|
|
21
20
|
* @param {ValueKeyFn|TreeMapOptions} operation
|
|
22
21
|
*/
|
|
23
22
|
export default function mapFnBuiltin(operation) {
|
|
24
|
-
|
|
25
|
-
const
|
|
23
|
+
assertTreeIsDefined(this, "map");
|
|
24
|
+
const tree = this;
|
|
26
25
|
|
|
27
26
|
// Identify whether the map instructions take the form of a value function or
|
|
28
27
|
// a dictionary of options.
|
|
@@ -63,11 +62,11 @@ export default function mapFnBuiltin(operation) {
|
|
|
63
62
|
let extendedValueFn;
|
|
64
63
|
if (valueFn) {
|
|
65
64
|
const resolvedValueFn = toFunction(valueFn);
|
|
66
|
-
// Have the value function run in this
|
|
67
|
-
extendedValueFn = resolvedValueFn.bind(
|
|
65
|
+
// Have the value function run in this tree.
|
|
66
|
+
extendedValueFn = resolvedValueFn.bind(tree);
|
|
68
67
|
}
|
|
69
68
|
|
|
70
|
-
// Extend the
|
|
69
|
+
// Extend the key functions to run in this tree.
|
|
71
70
|
let extendedKeyFn;
|
|
72
71
|
let extendedInverseKeyFn;
|
|
73
72
|
if (extension) {
|
|
@@ -83,7 +82,7 @@ export default function mapFnBuiltin(operation) {
|
|
|
83
82
|
async function scopedKeyFn(sourceKey, tree) {
|
|
84
83
|
const sourceValue = await tree.get(sourceKey);
|
|
85
84
|
const resultKey = await resolvedKeyFn.call(
|
|
86
|
-
|
|
85
|
+
tree,
|
|
87
86
|
sourceValue,
|
|
88
87
|
sourceKey,
|
|
89
88
|
tree
|
|
@@ -110,8 +109,8 @@ export default function mapFnBuiltin(operation) {
|
|
|
110
109
|
|
|
111
110
|
return (treelike) => {
|
|
112
111
|
const mapped = fn(treelike);
|
|
113
|
-
|
|
114
|
-
return
|
|
112
|
+
mapped.parent = tree;
|
|
113
|
+
return mapped;
|
|
115
114
|
};
|
|
116
115
|
}
|
|
117
116
|
|
package/src/builtins/@match.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { Tree } from "@weborigami/async-tree";
|
|
2
|
-
import
|
|
3
|
-
import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
|
|
1
|
+
import { ObjectTree, Tree } from "@weborigami/async-tree";
|
|
2
|
+
import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* Return a tree with the indicated keys (if provided).
|
|
@@ -20,13 +19,13 @@ import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
|
|
|
20
19
|
* @typedef {import("@weborigami/async-tree").Treelike} Treelike
|
|
21
20
|
* @typedef {import("../../index.ts").Invocable} Invocable
|
|
22
21
|
*
|
|
22
|
+
* @this {AsyncTree|null}
|
|
23
23
|
* @param {string|RegExp} pattern
|
|
24
24
|
* @param {Invocable} resultFn
|
|
25
25
|
* @param {Treelike} [keys]
|
|
26
|
-
* @this {AsyncTree|null}
|
|
27
26
|
*/
|
|
28
27
|
export default function match(pattern, resultFn, keys = []) {
|
|
29
|
-
|
|
28
|
+
assertTreeIsDefined(this, "match");
|
|
30
29
|
let regex;
|
|
31
30
|
if (typeof pattern === "string") {
|
|
32
31
|
// Convert the simple pattern format into a regular expression.
|
|
@@ -41,11 +40,9 @@ export default function match(pattern, resultFn, keys = []) {
|
|
|
41
40
|
throw new Error(`match(): Unsupported pattern`);
|
|
42
41
|
}
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
const scope = this;
|
|
43
|
+
const tree = this;
|
|
46
44
|
|
|
47
|
-
|
|
48
|
-
let result = {
|
|
45
|
+
const result = {
|
|
49
46
|
async get(key) {
|
|
50
47
|
const keyMatch = regex.exec(key);
|
|
51
48
|
if (!keyMatch) {
|
|
@@ -63,15 +60,20 @@ export default function match(pattern, resultFn, keys = []) {
|
|
|
63
60
|
// If the pattern contained named wildcards, extend the scope. It appears
|
|
64
61
|
// that the `groups` property of a match is *not* a real plain object, so
|
|
65
62
|
// we have to make one.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
63
|
+
let target;
|
|
64
|
+
if (keyMatch.groups) {
|
|
65
|
+
target = new ObjectTree(
|
|
66
|
+
Object.fromEntries(Object.entries(keyMatch.groups))
|
|
67
|
+
);
|
|
68
|
+
target.parent = tree;
|
|
69
|
+
} else {
|
|
70
|
+
target = tree;
|
|
71
|
+
}
|
|
70
72
|
|
|
71
73
|
// Invoke the result function with the extended scope.
|
|
72
74
|
let value;
|
|
73
75
|
if (typeof resultFn === "function") {
|
|
74
|
-
value = await resultFn.call(
|
|
76
|
+
value = await resultFn.call(target);
|
|
75
77
|
} else {
|
|
76
78
|
value = Object.create(resultFn);
|
|
77
79
|
}
|
|
@@ -80,11 +82,10 @@ export default function match(pattern, resultFn, keys = []) {
|
|
|
80
82
|
},
|
|
81
83
|
|
|
82
84
|
async keys() {
|
|
83
|
-
return typeof keys === "function" ? await keys.call(
|
|
85
|
+
return typeof keys === "function" ? await keys.call(tree) : keys;
|
|
84
86
|
},
|
|
85
87
|
};
|
|
86
88
|
|
|
87
|
-
result = Scope.treeWithScope(result, this);
|
|
88
89
|
return result;
|
|
89
90
|
}
|
|
90
91
|
|
package/src/builtins/@mdHtml.js
CHANGED
|
@@ -6,6 +6,9 @@ import { markedHighlight } from "marked-highlight";
|
|
|
6
6
|
import { markedSmartypants } from "marked-smartypants";
|
|
7
7
|
import documentObject from "../common/documentObject.js";
|
|
8
8
|
import { replaceExtension, toString } from "../common/utilities.js";
|
|
9
|
+
import origamiHighlightDefinition from "../misc/origamiHighlightDefinition.js";
|
|
10
|
+
|
|
11
|
+
highlight.registerLanguage("ori", origamiHighlightDefinition);
|
|
9
12
|
|
|
10
13
|
marked.use(
|
|
11
14
|
markedGfmHeadingId(),
|
|
@@ -39,7 +42,10 @@ export default async function mdHtml(input) {
|
|
|
39
42
|
input = await input.unpack();
|
|
40
43
|
}
|
|
41
44
|
const inputIsDocument = input["@text"] !== undefined;
|
|
42
|
-
const markdown =
|
|
45
|
+
const markdown = toString(input);
|
|
46
|
+
if (markdown === null) {
|
|
47
|
+
throw new Error("@mdHtml: The provided input couldn't be treated as text.");
|
|
48
|
+
}
|
|
43
49
|
const html = marked(markdown);
|
|
44
50
|
return inputIsDocument ? documentObject(html, input) : html;
|
|
45
51
|
}
|
package/src/builtins/@merge.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { isPlainObject, isUnpackable, merge } from "@weborigami/async-tree";
|
|
2
|
-
import
|
|
3
|
-
import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
|
|
2
|
+
import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
|
|
4
3
|
|
|
5
4
|
/**
|
|
6
5
|
* Create a tree that's the result of merging the given trees.
|
|
@@ -12,7 +11,7 @@ import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
|
|
|
12
11
|
* @param {(Treelike|null)[]} trees
|
|
13
12
|
*/
|
|
14
13
|
export default async function treeMerge(...trees) {
|
|
15
|
-
|
|
14
|
+
assertTreeIsDefined(this, "merge");
|
|
16
15
|
|
|
17
16
|
// Filter out null or undefined trees.
|
|
18
17
|
/** @type {Treelike[]}
|
|
@@ -36,22 +35,8 @@ export default async function treeMerge(...trees) {
|
|
|
36
35
|
return merge(...unpacked);
|
|
37
36
|
}
|
|
38
37
|
|
|
39
|
-
// If a tree can take a scope, give it one that includes the other trees and
|
|
40
|
-
// the current scope.
|
|
41
|
-
const scopedTrees = unpacked.map((tree) => {
|
|
42
|
-
const otherTrees = unpacked.filter((g) => g !== tree);
|
|
43
|
-
const scope = new Scope(...otherTrees, this);
|
|
44
|
-
// Each tree will be included first in its own scope.
|
|
45
|
-
return Scope.treeWithScope(tree, scope);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
38
|
// Merge the trees.
|
|
49
|
-
const result = merge(...
|
|
50
|
-
|
|
51
|
-
// Give the overall mixed tree a scope that includes the component trees and
|
|
52
|
-
// the current scope.
|
|
53
|
-
/** @type {any} */ (result).scope = new Scope(result, this);
|
|
54
|
-
|
|
39
|
+
const result = merge(...unpacked);
|
|
55
40
|
return result;
|
|
56
41
|
}
|
|
57
42
|
|
package/src/builtins/@once.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
|
|
2
2
|
|
|
3
3
|
const fnPromiseMap = new WeakMap();
|
|
4
4
|
|
|
@@ -10,7 +10,7 @@ const fnPromiseMap = new WeakMap();
|
|
|
10
10
|
* @param {Function} fn
|
|
11
11
|
*/
|
|
12
12
|
export default async function once(fn) {
|
|
13
|
-
|
|
13
|
+
assertTreeIsDefined(this, "once");
|
|
14
14
|
if (!fnPromiseMap.has(fn)) {
|
|
15
15
|
fnPromiseMap.set(fn, fn.call(this));
|
|
16
16
|
}
|
package/src/builtins/@ori.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
Tree,
|
|
3
|
+
getRealmObjectPrototype,
|
|
4
|
+
toString,
|
|
5
|
+
} from "@weborigami/async-tree";
|
|
2
6
|
import { compile } from "@weborigami/language";
|
|
3
7
|
import builtins from "../builtins/@builtins.js";
|
|
4
8
|
import { toYaml } from "../common/serialize.js";
|
|
5
|
-
import
|
|
9
|
+
import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
|
|
6
10
|
|
|
7
11
|
const TypedArray = Object.getPrototypeOf(Uint8Array);
|
|
8
12
|
|
|
@@ -19,23 +23,23 @@ export default async function ori(
|
|
|
19
23
|
expression,
|
|
20
24
|
options = { formatResult: true }
|
|
21
25
|
) {
|
|
22
|
-
|
|
26
|
+
assertTreeIsDefined(this, "ori");
|
|
23
27
|
|
|
24
28
|
// In case expression has come from a file, cast it to a string.
|
|
25
|
-
expression =
|
|
29
|
+
expression = toString(expression);
|
|
26
30
|
|
|
27
|
-
//
|
|
28
|
-
|
|
31
|
+
// Run in the context of `this` if defined, otherwise use the builtins.
|
|
32
|
+
const tree = this ?? builtins;
|
|
29
33
|
|
|
30
34
|
// Parse
|
|
31
35
|
const fn = compile.expression(expression);
|
|
32
36
|
|
|
33
37
|
// Execute
|
|
34
|
-
let result = await fn.call(
|
|
38
|
+
let result = await fn.call(tree);
|
|
35
39
|
|
|
36
40
|
// If result was a function, execute it.
|
|
37
41
|
if (typeof result === "function") {
|
|
38
|
-
result = await result.call(
|
|
42
|
+
result = await result.call(tree);
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
return options.formatResult ? await formatResult(result) : result;
|
package/src/builtins/@pack.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @typedef {import("@weborigami/types").AsyncTree} AsyncTree
|
|
@@ -8,6 +8,6 @@ import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
|
|
|
8
8
|
* @returns
|
|
9
9
|
*/
|
|
10
10
|
export default function pack(obj) {
|
|
11
|
-
|
|
11
|
+
assertTreeIsDefined(this, "pack");
|
|
12
12
|
return obj?.pack?.();
|
|
13
13
|
}
|
package/src/builtins/@package.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { Tree, keysFromPath } from "@weborigami/async-tree";
|
|
2
|
-
import { Scope } from "@weborigami/language";
|
|
1
|
+
import { Tree, keysFromPath, scope } from "@weborigami/async-tree";
|
|
3
2
|
import project from "./@project.js";
|
|
4
3
|
|
|
5
4
|
/**
|
|
@@ -7,11 +6,8 @@ import project from "./@project.js";
|
|
|
7
6
|
* @param {string[]} keys
|
|
8
7
|
*/
|
|
9
8
|
export default async function packageBuiltin(...keys) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const projectRoot = await project.call(null);
|
|
13
|
-
scope = Scope.getScope(projectRoot);
|
|
14
|
-
}
|
|
9
|
+
const parent = this ?? (await project.call(null));
|
|
10
|
+
const parentScope = scope(parent);
|
|
15
11
|
|
|
16
12
|
const packageKeys = [keys.shift()];
|
|
17
13
|
if (packageKeys[0]?.startsWith("@")) {
|
|
@@ -21,7 +17,7 @@ export default async function packageBuiltin(...keys) {
|
|
|
21
17
|
|
|
22
18
|
const packageRoot = await Tree.traverse(
|
|
23
19
|
// @ts-ignore
|
|
24
|
-
|
|
20
|
+
parentScope,
|
|
25
21
|
"node_modules",
|
|
26
22
|
...packageKeys
|
|
27
23
|
);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Tree } from "@weborigami/async-tree";
|
|
2
|
-
import { Scope } from "@weborigami/language";
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
4
|
* Return a new grouping of the treelike's values into "pages" of the specified
|
|
@@ -12,7 +11,6 @@ import { Scope } from "@weborigami/language";
|
|
|
12
11
|
* @param {number} [size=10]
|
|
13
12
|
*/
|
|
14
13
|
export default function paginateFn(size = 10) {
|
|
15
|
-
const scope = this;
|
|
16
14
|
/**
|
|
17
15
|
* @param {Treelike} [treelike]
|
|
18
16
|
*/
|
|
@@ -21,7 +19,7 @@ export default function paginateFn(size = 10) {
|
|
|
21
19
|
const keys = Array.from(await tree.keys());
|
|
22
20
|
const pageCount = Math.ceil(keys.length / size);
|
|
23
21
|
|
|
24
|
-
|
|
22
|
+
return {
|
|
25
23
|
async get(pageKey) {
|
|
26
24
|
// Note: page numbers are 1-based.
|
|
27
25
|
const pageNumber = Number(pageKey);
|
|
@@ -54,8 +52,5 @@ export default function paginateFn(size = 10) {
|
|
|
54
52
|
return Array.from({ length: pageCount }, (_, index) => index + 1);
|
|
55
53
|
},
|
|
56
54
|
};
|
|
57
|
-
|
|
58
|
-
const scoped = Scope.treeWithScope(result, scope);
|
|
59
|
-
return scoped;
|
|
60
55
|
};
|
|
61
56
|
}
|
package/src/builtins/@perf.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Return the number of milliseconds required to execute the given function the
|
|
@@ -8,7 +8,7 @@ import assertScopeIsDefined from "../misc/assertScopeIsDefined.js";
|
|
|
8
8
|
* @param {Function} fn
|
|
9
9
|
*/
|
|
10
10
|
export default async function perf(fn, count = 1) {
|
|
11
|
-
|
|
11
|
+
assertTreeIsDefined(this, "perf");
|
|
12
12
|
const start = performance.now();
|
|
13
13
|
for (let i = 0; i < count; i++) {
|
|
14
14
|
await fn.call(this);
|