@weborigami/origami 0.0.70 → 0.0.71-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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weborigami/origami",
3
- "version": "0.0.70",
3
+ "version": "0.0.71-beta.1",
4
4
  "description": "Web Origami language, CLI, framework, and server",
5
5
  "type": "module",
6
6
  "repository": {
@@ -17,9 +17,9 @@
17
17
  "typescript": "5.6.2"
18
18
  },
19
19
  "dependencies": {
20
- "@weborigami/async-tree": "0.0.70",
21
- "@weborigami/language": "0.0.70",
22
- "@weborigami/types": "0.0.70",
20
+ "@weborigami/async-tree": "0.0.71-beta.1",
21
+ "@weborigami/language": "0.0.71-beta.1",
22
+ "@weborigami/types": "0.0.71-beta.1",
23
23
  "exif-parser": "0.1.12",
24
24
  "graphviz-wasm": "3.0.2",
25
25
  "highlight.js": "11.10.0",
@@ -22,42 +22,40 @@ export default async function index(treelike) {
22
22
  for (const key of filtered) {
23
23
  const keyText = String(key);
24
24
  // Simple key.
25
- const link = `<li><a href="${keyText}">${keyText}</a></li>`;
25
+ const link = ` <li><a href="${keyText}">${keyText}</a></li>`;
26
26
  links.push(link);
27
27
  }
28
28
 
29
29
  const heading = tree[keySymbol] ?? "Index";
30
- const list = `
31
- <h1>${heading.trim()}</h1>
32
- <ul>\n${links.join("\n").trim()}\n</ul>
33
- `;
30
+ const list = ` <ul>\n${links.join("\n")}\n </ul>`;
34
31
 
35
- const html = `
36
- <!DOCTYPE html>
37
- <html lang="en">
38
- <head>
39
- <meta charset="utf-8" />
40
- <meta name="viewport" content="width=device-width,initial-scale=1" />
41
- <style>
42
- li {
43
- margin-bottom: 0.20em;
44
- }
32
+ const html = `<!DOCTYPE html>
33
+ <html lang="en">
34
+ <head>
35
+ <meta charset="utf-8">
36
+ <meta name="viewport" content="width=device-width,initial-scale=1">
37
+ <style>
38
+ li {
39
+ margin-bottom: 0.20em;
40
+ }
45
41
 
46
- a {
47
- text-decoration: none;
48
- }
49
- a:hover {
50
- text-decoration: revert;
51
- }
52
- </style>
53
- </head>
54
- <body>
55
- ${list.trim()}
56
- </body>
57
- </html>`;
42
+ a {
43
+ text-decoration: none;
44
+ }
45
+ a:hover {
46
+ text-decoration: revert;
47
+ }
48
+ </style>
49
+ </head>
50
+ <body>
51
+ <h1>${heading.trim()}</h1>
52
+ ${list}
53
+ </body>
54
+ </html>
55
+ `;
58
56
 
59
57
  /** @type {any} */
60
- const result = new String(html.trim());
58
+ const result = new String(html);
61
59
  result.unpack = () => tree;
62
60
  return result;
63
61
  }
@@ -1,4 +1,4 @@
1
- import { ObjectTree, Tree } from "@weborigami/async-tree";
1
+ import { Tree } from "@weborigami/async-tree";
2
2
  import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
3
3
 
4
4
  /**
@@ -12,8 +12,7 @@ import assertTreeIsDefined from "../misc/assertTreeIsDefined.js";
12
12
  * The pattern can also be a JavaScript regular expression.
13
13
  *
14
14
  * If a key is requested, match against the given pattern and, if matches,
15
- * incorporate the matched pattern's wildcard values into the scope and invoke
16
- * the indicated function to produce a result.
15
+ * invokes the given function with an object containing the matched values.
17
16
  *
18
17
  * @typedef {import("@weborigami/types").AsyncTree} AsyncTree
19
18
  * @typedef {import("@weborigami/async-tree").Treelike} Treelike
@@ -57,23 +56,13 @@ export default function match(pattern, resultFn, keys = []) {
57
56
  return resultFn;
58
57
  }
59
58
 
60
- // If the pattern contained named wildcards, extend the scope. It appears
61
- // that the `groups` property of a match is *not* a real plain object, so
62
- // we have to make one.
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
- }
59
+ // Copy the `groups` property to a real object
60
+ const matches = { ...keyMatch.groups };
72
61
 
73
62
  // Invoke the result function with the extended scope.
74
63
  let value;
75
64
  if (typeof resultFn === "function") {
76
- value = await resultFn.call(target);
65
+ value = await resultFn.call(this, matches);
77
66
  } else {
78
67
  value = Object.create(resultFn);
79
68
  }
@@ -3,6 +3,7 @@ import {
3
3
  toString as asyncTreeToString,
4
4
  isPlainObject,
5
5
  isUnpackable,
6
+ trailingSlash,
6
7
  } from "@weborigami/async-tree";
7
8
 
8
9
  // Return true if the text appears to contain non-printable binary characters;
@@ -37,6 +38,8 @@ export const keySymbol = Symbol("key");
37
38
  * period), replace that extension with the result extension (which again should
38
39
  * generally include a period). Otherwise, return the key as is.
39
40
  *
41
+ * If the key ends in a trailing slash, that will be preserved in the result.
42
+ *
40
43
  * @param {string} key
41
44
  * @param {string} sourceExtension
42
45
  * @param {string} resultExtension
@@ -44,11 +47,16 @@ export const keySymbol = Symbol("key");
44
47
  export function replaceExtension(key, sourceExtension, resultExtension) {
45
48
  if (!key) {
46
49
  return undefined;
47
- } else if (!key.endsWith(sourceExtension)) {
48
- return key;
49
- } else {
50
- return key.slice(0, -sourceExtension.length) + resultExtension;
51
50
  }
51
+
52
+ const normalizedKey = trailingSlash.remove(key);
53
+ if (!normalizedKey.endsWith(sourceExtension)) {
54
+ return normalizedKey;
55
+ }
56
+
57
+ const replaced =
58
+ normalizedKey.slice(0, -sourceExtension.length) + resultExtension;
59
+ return trailingSlash.toggle(replaced, trailingSlash.has(key));
52
60
  }
53
61
 
54
62
  /**