@weborigami/origami 0.6.16 → 0.7.0-beta.1

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.
@@ -4,7 +4,7 @@ import {
4
4
  setParent,
5
5
  Tree,
6
6
  } from "@weborigami/async-tree";
7
- import { evaluate, OrigamiFileMap, projectGlobals } from "@weborigami/language";
7
+ import { evaluate, getGlobalsForTree } from "@weborigami/language";
8
8
  import debugTransform from "./debugTransform.js";
9
9
 
10
10
  // So we can distinguish different trees in the debugger
@@ -16,18 +16,22 @@ let version = 0;
16
16
  *
17
17
  * @param {Object} options
18
18
  * @param {string} options.expression
19
- * @param {string} options.parentPath
19
+ * @param {import("@weborigami/language").OrigamiFileMap} options.parent
20
20
  */
21
21
  export default async function expressionTree(options) {
22
- const { expression, parentPath } = options;
22
+ const { expression, parent } = options;
23
23
 
24
- const parent = new OrigamiFileMap(parentPath);
25
- const globals = await projectGlobals(parent);
24
+ const globals = getGlobalsForTree(parent);
25
+
26
+ const source = {
27
+ text: expression,
28
+ cachePath: "_tree",
29
+ };
26
30
 
27
31
  let maplike;
28
32
  try {
29
33
  // Evaluate the expression
30
- maplike = await evaluate(expression, { globals, mode: "shell", parent });
34
+ maplike = await evaluate(source, { globals, mode: "shell", parent });
31
35
  if (isUnpackable(maplike)) {
32
36
  maplike = await maplike.unpack();
33
37
  }
@@ -1,5 +1,5 @@
1
1
  import { trailingSlash, Tree } from "@weborigami/async-tree";
2
- import { evaluate, projectGlobals } from "@weborigami/language";
2
+ import { evaluate, getGlobalsForTree } from "@weborigami/language";
3
3
  import debugTransform from "./debugTransform.js";
4
4
 
5
5
  const mapParentToResult = new WeakMap();
@@ -16,7 +16,7 @@ const mapParentToResult = new WeakMap();
16
16
  * counter to force reevaluation of the same expression.
17
17
  */
18
18
  export default async function oriEval(parent) {
19
- const globals = await projectGlobals(parent);
19
+ const globals = getGlobalsForTree(parent);
20
20
  return async (key) => {
21
21
  const normalizedKey = trailingSlash.remove(key);
22
22
  let result = mapParentToResult.get(parent);
package/src/dev/dev.js CHANGED
@@ -18,5 +18,6 @@ export { default as log } from "./log.js";
18
18
  export { default as serve } from "./serve.js";
19
19
  export { default as stdin } from "./stdin.js";
20
20
  export { default as svg } from "./svg.js";
21
+ export { default as syscache } from "./syscache.js";
21
22
  export { default as version } from "./version.js";
22
23
  export { default as watch } from "./watch.js";
@@ -44,6 +44,7 @@ async function getScopeData(scope) {
44
44
  async function loadTemplate() {
45
45
  const folderPath = path.resolve(fileURLToPath(import.meta.url), "..");
46
46
  const folder = new OrigamiFileMap(folderPath);
47
+ await folder.initializeGlobals();
47
48
  const templateFile = await folder.get("explore.ori");
48
49
  const template = await Handlers.ori_handler.unpack(templateFile, {
49
50
  parent: folder,
package/src/dev/help.yaml CHANGED
@@ -13,12 +13,12 @@ Dev:
13
13
  clear:
14
14
  args: (tree)
15
15
  description: Remove all values from the tree (alias of Tree.clear)
16
- crawl:
17
- args: (tree, base)
18
- description: A tree of a site's discoverable resources
19
16
  copy:
20
17
  args: (source, target)
21
18
  description: Copy the source tree to the target
19
+ crawl:
20
+ args: (tree, base)
21
+ description: A tree of a site's discoverable resources
22
22
  debug:
23
23
  args: (tree)
24
24
  description: Add debug features to the tree
@@ -63,11 +63,20 @@ Origami:
63
63
  document:
64
64
  args: (text, [data])
65
65
  description: Create a document object with the text and data
66
+ domObject:
67
+ args: (dom)
68
+ description: Convert a DOM tree to a plain JavaScript object
66
69
  extension:
67
70
  description: Helpers for working with file extensions
68
71
  fetch:
69
72
  args: (url, options)
70
73
  description: Fetch a resource from a URL with support for extensions
74
+ hash:
75
+ args: (data)
76
+ description: A hex string hash of the data
77
+ htmlDom:
78
+ args: (html)
79
+ description: Parse HTML into a DOM tree
71
80
  htmlEscape:
72
81
  args: (text)
73
82
  description: Escape HTML entities in the text
@@ -79,9 +88,6 @@ Origami:
79
88
  inline:
80
89
  args: (text)
81
90
  description: Inline Origami expressions found in the text
82
- htmlParse:
83
- args: (html)
84
- description: Parse HTML into a plain JavaScript object
85
91
  json:
86
92
  args: (obj)
87
93
  description: Render the object in JSON format
@@ -99,9 +105,9 @@ Origami:
99
105
  description: The outline structure of the markdown document
100
106
  naturalOrder:
101
107
  description: A comparison function for natural sort order
102
- once:
103
- args: (fn)
104
- description: Run the function only once, return the same result
108
+ # once:
109
+ # args: (fn)
110
+ # description: Run the function only once, return the same result
105
111
  ori:
106
112
  args: (text)
107
113
  description: Evaluate the text as an Origami expression
@@ -110,6 +116,12 @@ Origami:
110
116
  description: POST the given data to the URL
111
117
  projectRoot:
112
118
  description: The root folder for the current Origami project
119
+ randomFrom:
120
+ args: (data)
121
+ description: Returns a random value based on the data
122
+ randomsFrom:
123
+ args: (data)
124
+ description: Returns a function to produce random values based on the data
113
125
  redirect:
114
126
  args: (url, options)
115
127
  description: Redirect to the given URL
@@ -139,12 +151,15 @@ Origami:
139
151
  toFunction:
140
152
  args: (obj)
141
153
  description: Coerce a tree or packed function definition to a function
154
+ tsv:
155
+ args: (tree)
156
+ description: Render the tree as a TSV file
142
157
  unpack:
143
158
  args: (buffer)
144
159
  description: Unpack the buffer into a usable form
145
- xmlParse:
160
+ xmlDom:
146
161
  args: (xml)
147
- description: Parse XML into a plain JavaScript object
162
+ description: Parse XML into a DOM tree
148
163
  yaml:
149
164
  args: (obj)
150
165
  description: Render the object in YAML format
@@ -193,6 +208,9 @@ Tree:
193
208
  clear:
194
209
  args: (map)
195
210
  description: Remove all values from the map
211
+ combine:
212
+ args: (tree1, tree2, combineFn)
213
+ description: Pairwise application of combineFn to the trees' values
196
214
  concat:
197
215
  args: (...trees)
198
216
  description: Merge trees, renumbering numeric keys
@@ -0,0 +1,56 @@
1
+ import { activeProjectRoot, systemCache, volatile } from "@weborigami/language";
2
+ import path from "node:path";
3
+ import * as YAMLModule from "yaml";
4
+
5
+ // The "yaml" package doesn't seem to provide a default export that the browser can
6
+ // recognize, so we have to handle two ways to accommodate Node and the browser.
7
+ // @ts-ignore
8
+ const YAML = YAMLModule.default ?? YAMLModule.YAML;
9
+
10
+ export default function syscache() {
11
+ const projectRoot = activeProjectRoot.get();
12
+
13
+ /** @type {any} */
14
+ const entries = [...systemCache.entries()].map(([path, entry]) => {
15
+ const result = {};
16
+ if (entry.downstreams) {
17
+ result.downstreams = preferRelativePaths(projectRoot, entry.downstreams);
18
+ }
19
+ if (entry.upstreams) {
20
+ result.upstreams = preferRelativePaths(projectRoot, entry.upstreams);
21
+ }
22
+ return [preferRelativePath(projectRoot, path), result];
23
+ });
24
+
25
+ // Sort the entries by key
26
+ entries.sort(([keyA], [keyB]) => keyA.localeCompare(keyB));
27
+
28
+ const result = volatile(new Map(entries));
29
+
30
+ // When served, render as YAML and preserve trailing slashes
31
+ Object.defineProperty(result, "pack", {
32
+ configurable: true,
33
+ enumerable: false,
34
+ get() {
35
+ return () => volatile(YAML.stringify(result));
36
+ },
37
+ });
38
+
39
+ return result;
40
+ }
41
+
42
+ function preferRelativePath(projectRoot, inputPath) {
43
+ if (!path.isAbsolute(inputPath)) {
44
+ return inputPath;
45
+ }
46
+ const prefix = `${projectRoot.path}${path.sep}`;
47
+ if (!inputPath.startsWith(prefix)) {
48
+ return inputPath;
49
+ }
50
+ const relativePath = inputPath.slice(prefix.length);
51
+ return relativePath;
52
+ }
53
+
54
+ function preferRelativePaths(projectRoot, paths) {
55
+ return Array.from(paths).map((path) => preferRelativePath(projectRoot, path));
56
+ }
@@ -1,5 +1,5 @@
1
1
  import { symbols, toString } from "@weborigami/async-tree";
2
- import xmlParse from "../origami/xmlParse.js";
2
+ import xmlParse from "../origami/xmlDom.js";
3
3
 
4
4
  export default {
5
5
  mediaType: "application/xml",
@@ -1,17 +1,29 @@
1
+ import { isUnpackable } from "@weborigami/async-tree";
2
+
1
3
  const ELEMENT_NODE = 1;
2
4
  const TEXT_NODE = 3;
3
5
  const CDATA_SECTION_NODE = 4;
4
6
  const DOCUMENT_NODE = 9;
5
7
  const DOCUMENT_FRAGMENT_NODE = 11;
6
8
 
7
- export default function domNodeToObject(node) {
9
+ /**
10
+ * Given a DOM node, return a plain object representation of it.
11
+ */
12
+ export default async function domObject(input) {
13
+ if (isUnpackable(input)) {
14
+ input = await input.unpack();
15
+ }
16
+ return nodeObject(input);
17
+ }
18
+
19
+ function nodeObject(node) {
8
20
  switch (node.nodeType) {
9
21
  case DOCUMENT_NODE:
10
22
  return {
11
23
  name: "#document",
12
24
  children: [...node.childNodes]
13
25
  .filter((child) => !isWhitespaceOnly(child))
14
- .map(domNodeToObject),
26
+ .map(nodeObject),
15
27
  };
16
28
 
17
29
  case DOCUMENT_FRAGMENT_NODE:
@@ -19,7 +31,7 @@ export default function domNodeToObject(node) {
19
31
  name: "#document-fragment",
20
32
  children: [...node.childNodes]
21
33
  .filter((child) => !isWhitespaceOnly(child))
22
- .map(domNodeToObject),
34
+ .map(nodeObject),
23
35
  };
24
36
 
25
37
  case ELEMENT_NODE: {
@@ -55,7 +67,7 @@ export default function domNodeToObject(node) {
55
67
  result.text = text;
56
68
  }
57
69
  } else if (relevantChildren.length > 0) {
58
- result.children = relevantChildren.map(domNodeToObject);
70
+ result.children = relevantChildren.map(nodeObject);
59
71
  }
60
72
 
61
73
  return result;
@@ -1,22 +1 @@
1
- import { args } from "@weborigami/async-tree";
2
- import { handleExtension } from "@weborigami/language";
3
-
4
- /**
5
- * Extend the JavaScript `fetch` function to implicity return an ArrayBuffer
6
- * with an unpack() method if the resource has a known file extension.
7
- */
8
- export default async function fetchBuiltin(resource, options, state) {
9
- resource = args.string(resource, "Origami.fetch");
10
- const response = await fetch(resource, options);
11
- if (!response.ok) {
12
- return undefined;
13
- }
14
-
15
- const value = await response.arrayBuffer();
16
-
17
- const url = new URL(resource);
18
- const key = url.pathname;
19
-
20
- return handleExtension(value, key, state?.parent);
21
- }
22
- fetchBuiltin.needsState = true;
1
+ export { fetchAndHandleExtension as default } from "@weborigami/language";
@@ -0,0 +1,17 @@
1
+ import hashBytes from "../common/hashBytes.js";
2
+
3
+ /**
4
+ * Given string or Uint8Array data, return a hex-encoded hash of that data.
5
+ *
6
+ * @typedef {import("@weborigami/async-tree").Stringlike} Stringlike
7
+ *
8
+ * @param {Uint8Array|Stringlike} data
9
+ */
10
+ export default function hash(data) {
11
+ const bytes = hashBytes(data);
12
+ const text = Array.from(bytes)
13
+ .slice(0, 20) // Limit to first 20 bytes (160 bits) for a shorter hash string
14
+ .map((byte) => byte.toString(16).padStart(2, "0"))
15
+ .join("");
16
+ return text;
17
+ }
@@ -0,0 +1,21 @@
1
+ import { args } from "@weborigami/async-tree";
2
+ import loadJsDom from "../common/loadJsDom.js";
3
+
4
+ /**
5
+ * Return the DOM structure for the given HTML.
6
+ *
7
+ * @param {import("@weborigami/async-tree").Stringlike} html
8
+ */
9
+ export default async function htmlDom(html) {
10
+ html = args.stringlike(html, "Origami.htmlDom");
11
+ const { JSDOM } = await loadJsDom();
12
+ let dom = JSDOM.fragment(html);
13
+ if (
14
+ (dom.nodeType === 9 || dom.nodeType === 11) &&
15
+ dom.children.length === 1
16
+ ) {
17
+ // Document or DocumentFragment with a single child: return the child
18
+ dom = dom.children[0];
19
+ }
20
+ return dom;
21
+ }
@@ -1,22 +1,15 @@
1
1
  import { args } from "@weborigami/async-tree";
2
- import loadJsDom from "../common/loadJsDom.js";
3
- import domNodeToObject from "./domNodeToObject.js";
2
+ import htmlDom from "./htmlDom.js";
4
3
 
5
4
  /**
6
- * Return the DOM structure for the given HTML as a plain object.
5
+ * Return the DOM structure for the given HTML.
7
6
  *
8
7
  * @param {import("@weborigami/async-tree").Stringlike} html
9
8
  */
10
9
  export default async function htmlParse(html) {
10
+ console.warn("Origami.htmlParse is deprecated. Use Origami.htmlDom instead.");
11
+
11
12
  html = args.stringlike(html, "Origami.htmlParse");
12
- const { JSDOM } = await loadJsDom();
13
- const dom = JSDOM.fragment(html);
14
- let object = domNodeToObject(dom);
15
- if (
16
- (object.name === "#document" || object.name === "#document-fragment") &&
17
- object.children.length === 1
18
- ) {
19
- object = object.children[0];
20
- }
21
- return object;
13
+ const dom = await htmlDom(html);
14
+ return dom;
22
15
  }
@@ -55,4 +55,5 @@ export default async function mdHtml(input) {
55
55
 
56
56
  mdHtml.key = (sourceValue, sourceKey) =>
57
57
  extension.replace(sourceKey, ".md", ".html");
58
+ mdHtml.key.needsSourceValue = false;
58
59
  mdHtml.inverseKey = (resultKey) => extension.replace(resultKey, ".html", ".md");
@@ -1,4 +1,4 @@
1
- import { args } from "@weborigami/async-tree";
1
+ import { args, interop } from "@weborigami/async-tree";
2
2
 
3
3
  const fnPromiseMap = new Map();
4
4
  const codePromiseMap = new Map();
@@ -9,6 +9,9 @@ const codePromiseMap = new Map();
9
9
  * @param {Function} fn
10
10
  */
11
11
  export default async function once(fn) {
12
+ interop.warn(
13
+ `Now that Origami caches most results, Origami.once is no longer needed and will be removed in a future release. If you believe you have a need for it, please mention your use case in the Origami chat.`,
14
+ );
12
15
  fn = args.fn(fn, "Origami.once");
13
16
  const code = /** @type {any} */ (fn).code;
14
17
  if (code) {
@@ -1,5 +1,10 @@
1
- import { Tree, args, getRealmObjectPrototype } from "@weborigami/async-tree";
2
- import { compile, projectGlobals } from "@weborigami/language";
1
+ import {
2
+ args,
3
+ assignPropertyDescriptors,
4
+ getRealmObjectPrototype,
5
+ Tree,
6
+ } from "@weborigami/async-tree";
7
+ import { compile, getGlobalsForTree } from "@weborigami/language";
3
8
  import { toYaml } from "../common/serialize.js";
4
9
  import * as dev from "../dev/dev.js";
5
10
 
@@ -17,18 +22,12 @@ export default async function ori(expression, options = {}) {
17
22
 
18
23
  expression = args.stringlike(expression, "Origami.ori");
19
24
 
20
- // Add Dev builtins as top-level globals
21
- const globals = {
22
- ...(await projectGlobals(parent)),
23
- ...dev,
24
- };
25
+ // Add Dev builtins as top-level globals; avoid invoking getters
26
+ const globals = assignPropertyDescriptors({}, getGlobalsForTree(parent), dev);
25
27
 
26
- // Compile the expression. Avoid caching scope references so that, e.g.,
27
- // passing a function to the `watch` builtin will always look the current
28
- // value of things in scope.
28
+ // Compile the expression
29
29
  const fn = compile.expression(expression, {
30
30
  globals,
31
- enableCaching: false,
32
31
  mode: "shell",
33
32
  parent,
34
33
  });
@@ -3,7 +3,10 @@ export { default as help } from "../dev/help.js"; // Alias
3
3
  export { default as basename } from "./basename.js";
4
4
  export { default as csv } from "./csv.js";
5
5
  export { default as document } from "./document.js";
6
+ export { default as domObject } from "./domObject.js";
6
7
  export { default as fetch } from "./fetch.js";
8
+ export { default as hash } from "./hash.js";
9
+ export { default as htmlDom } from "./htmlDom.js";
7
10
  export { default as htmlEscape } from "./htmlEscape.js";
8
11
  export { default as htmlParse } from "./htmlParse.js";
9
12
  export { default as format } from "./image/format.js";
@@ -21,8 +24,9 @@ export { default as once } from "./once.js";
21
24
  export { default as ori } from "./ori.js";
22
25
  export { default as pack } from "./pack.js";
23
26
  export { default as post } from "./post.js";
24
- export { default as project } from "./project.js";
25
27
  export { default as projectRoot } from "./projectRoot.js";
28
+ export { default as randomFrom } from "./randomFrom.js";
29
+ export { default as randomsFrom } from "./randomsFrom.js";
26
30
  export { default as redirect } from "./redirect.js";
27
31
  export { default as repeat } from "./repeat.js";
28
32
  export { default as rss } from "./rss.js";
@@ -34,6 +38,8 @@ export { default as static } from "./static.js";
34
38
  export { default as string } from "./string.js";
35
39
  export { default as tsv } from "./tsv.js";
36
40
  export { default as unpack } from "./unpack.js";
41
+ export { default as volatile } from "./volatile.js";
42
+ export { default as xmlDom } from "./xmlDom.js";
37
43
  export { default as xmlParse } from "./xmlParse.js";
38
44
  export { default as yaml } from "./yaml.js";
39
45
  export { default as yamlParse } from "./yamlParse.js";
@@ -0,0 +1,15 @@
1
+ import hashBytes from "../common/hashBytes.js";
2
+
3
+ /**
4
+ * Given a block of seed data, derive a pseudo-random 32-bit integer.
5
+ *
6
+ * @typedef {import("@weborigami/async-tree").Stringlike} Stringlike
7
+ *
8
+ * @param {Uint8Array|Stringlike} data
9
+ * @return {number}
10
+ */
11
+ export default function randomFrom(data) {
12
+ // Extract the first 32-bit integer from the hash to use as the random number
13
+ const hash = hashBytes(data);
14
+ return hash.readUInt32LE(0);
15
+ }
@@ -0,0 +1,65 @@
1
+ import hashBytes from "../common/hashBytes.js";
2
+
3
+ /**
4
+ * Given a block of seed data, return a function that produces a sequence of
5
+ * pseudo-random 32-bit integers.
6
+ *
7
+ * @typedef {import("@weborigami/async-tree").Stringlike} Stringlike
8
+ *
9
+ * @param {Uint8Array|Stringlike} data
10
+ * @return {function(): number}
11
+ */
12
+ export default function randomsFrom(data) {
13
+ const hash = hashBytes(data);
14
+
15
+ // Extract four 32-bit integers from the hash to use as the initial state of
16
+ // the pseudo-random number generator
17
+ const a = hash.readUInt32LE(0);
18
+ const b = hash.readUInt32LE(4);
19
+ const c = hash.readUInt32LE(8);
20
+ const d = hash.readUInt32LE(12);
21
+
22
+ const prng = xoshiro128ss(a, b, c, d);
23
+ return prng;
24
+ }
25
+
26
+ // Rotate left (circular left shift) for 32-bit integers
27
+ function rotl(x, k) {
28
+ return ((x << k) | (x >>> (32 - k))) >>> 0;
29
+ }
30
+
31
+ /**
32
+ * Pseudo-random number generator based on the xoshiro128** algorithm. See
33
+ * the 256-bit variant: https://en.wikipedia.org/wiki/Xorshift#xoshiro256**
34
+ *
35
+ * Unlike a typical implementation, this directly returns a 32-bit integer
36
+ * instead of a float.
37
+ *
38
+ * @param {number} a
39
+ * @param {number} b
40
+ * @param {number} c
41
+ * @param {number} d
42
+ * @returns {function(): number}
43
+ */
44
+ function xoshiro128ss(a, b, c, d) {
45
+ let s0 = a >>> 0;
46
+ let s1 = b >>> 0;
47
+ let s2 = c >>> 0;
48
+ let s3 = d >>> 0;
49
+
50
+ return function () {
51
+ const result = (rotl(Math.imul(s1, 5), 7) * 9) >>> 0;
52
+
53
+ const t = (s1 << 9) >>> 0;
54
+
55
+ s2 ^= s0;
56
+ s3 ^= s1;
57
+ s1 ^= s2;
58
+ s0 ^= s3;
59
+
60
+ s2 ^= t;
61
+ s3 = rotl(s3, 11);
62
+
63
+ return result;
64
+ };
65
+ }
@@ -0,0 +1 @@
1
+ export { volatile as default } from "@weborigami/language";
@@ -0,0 +1,32 @@
1
+ import { args } from "@weborigami/async-tree";
2
+ import loadJsDom from "../common/loadJsDom.js";
3
+
4
+ let parser;
5
+
6
+ /**
7
+ * Return the DOM for the given XML.
8
+ *
9
+ * @param {import("@weborigami/async-tree").Stringlike} xml
10
+ */
11
+ export default async function xmlDom(xml) {
12
+ xml = args.stringlike(xml, "Origami.xmlDom");
13
+ const parser = await getParser();
14
+ let dom = parser.parseFromString(xml, "application/xml");
15
+ if (
16
+ (dom.nodeType === 9 || dom.nodeType === 11) &&
17
+ dom.children.length === 1
18
+ ) {
19
+ // Document or DocumentFragment with a single child: return the child
20
+ dom = dom.children[0];
21
+ }
22
+ return dom;
23
+ }
24
+
25
+ async function getParser() {
26
+ if (!parser) {
27
+ const { JSDOM } = await loadJsDom();
28
+ const dom = new JSDOM();
29
+ parser = new dom.window.DOMParser();
30
+ }
31
+ return parser;
32
+ }
@@ -1,33 +1,15 @@
1
1
  import { args } from "@weborigami/async-tree";
2
- import loadJsDom from "../common/loadJsDom.js";
3
- import domNodeToObject from "./domNodeToObject.js";
4
-
5
- let parser;
2
+ import xmlDom from "./xmlDom.js";
6
3
 
7
4
  /**
8
- * Return the DOM for the given XML as a plain object.
5
+ * Return the DOM structure for the given XML.
9
6
  *
10
7
  * @param {import("@weborigami/async-tree").Stringlike} xml
11
8
  */
12
9
  export default async function xmlParse(xml) {
13
- xml = args.stringlike(xml, "Origami.xmlParse");
14
- const parser = await getParser();
15
- const dom = parser.parseFromString(xml, "application/xml");
16
- let object = domNodeToObject(dom);
17
- if (
18
- (object.name === "#document" || object.name === "#document-fragment") &&
19
- object.children.length === 1
20
- ) {
21
- object = object.children[0];
22
- }
23
- return object;
24
- }
10
+ console.warn("Origami.xmlParse is deprecated. Use Origami.xmlDom instead.");
25
11
 
26
- async function getParser() {
27
- if (!parser) {
28
- const { JSDOM } = await loadJsDom();
29
- const dom = new JSDOM();
30
- parser = new dom.window.DOMParser();
31
- }
32
- return parser;
12
+ xml = args.stringlike(xml, "Origami.xmlParse");
13
+ const dom = await xmlDom(xml);
14
+ return dom;
33
15
  }