textlane 0.0.0-stage → 0.1.0

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.
Files changed (42) hide show
  1. package/LICENSE.md +9 -0
  2. package/README.md +80 -2
  3. package/build/actions/addon/resolve.d.ts +7 -0
  4. package/build/actions/addon/resolve.js +22 -0
  5. package/build/actions/attacher/check.d.ts +3 -0
  6. package/build/actions/attacher/check.js +5 -0
  7. package/build/actions/host/call.d.ts +13 -0
  8. package/build/actions/host/call.js +47 -0
  9. package/build/actions/options/merge.d.ts +5 -0
  10. package/build/actions/options/merge.js +29 -0
  11. package/build/actions/pluggable/map.d.ts +8 -0
  12. package/build/actions/pluggable/map.js +29 -0
  13. package/build/actions/run/finish.d.ts +12 -0
  14. package/build/actions/run/finish.js +52 -0
  15. package/build/actions/transformer/check.d.ts +3 -0
  16. package/build/actions/transformer/check.js +5 -0
  17. package/build/generated/html.d.ts +250 -0
  18. package/build/generated/html.js +74 -0
  19. package/build/generated/md.d.ts +333 -0
  20. package/build/generated/md.js +94 -0
  21. package/build/generated/mdx.d.ts +28 -0
  22. package/build/generated/mdx.js +8 -0
  23. package/build/generated/nl.d.ts +99 -0
  24. package/build/generated/nl.js +62 -0
  25. package/build/index.d.ts +18 -0
  26. package/build/index.js +27 -0
  27. package/build/models/addon.d.ts +35 -0
  28. package/build/models/addon.js +2 -0
  29. package/build/models/file.d.ts +52 -0
  30. package/build/models/file.js +2 -0
  31. package/build/models/host.d.ts +7 -0
  32. package/build/models/host.js +2 -0
  33. package/build/models/plugin.d.ts +26 -0
  34. package/build/models/plugin.js +2 -0
  35. package/build/models/processor.d.ts +39 -0
  36. package/build/models/processor.js +154 -0
  37. package/build/models/vfile.d.ts +52 -0
  38. package/build/models/vfile.js +164 -0
  39. package/build/settings.d.ts +14 -0
  40. package/build/settings.js +17 -0
  41. package/package.json +43 -4
  42. package/skills/textlane-usage/SKILL.md +146 -0
package/LICENSE.md ADDED
@@ -0,0 +1,9 @@
1
+ # The MIT License (MIT)
2
+
3
+ Copyright © 2026 Evgeny Karev
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,81 @@
1
- # Temporary Holding Version
1
+ # Textlane
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Textlane is a Rust-native text processing pipeline: a replacement for unified whose plugins
4
+ run natively, while existing JavaScript plugins can still join the same pipeline. One Rust
5
+ crate ships to crates.io, npm and PyPI at one version.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install textlane
11
+ ```
12
+
13
+ The package carries a prebuilt addon for Linux, macOS and Windows (x64 and arm64)
14
+ through a platform-specific optional dependency; no Rust toolchain is needed.
15
+
16
+ ## Usage
17
+
18
+ A processor chains plugins with `use`, as unified does, then parses, transforms and serializes
19
+ text with `process`. Each language reaches the same crate; plugins are grouped by domain (`md`,
20
+ `html`, `mdx`, `nl`) and named as the pipeline names them.
21
+
22
+ Rust:
23
+
24
+ ```rust
25
+ use textlane::{Processor, html, md};
26
+
27
+ let processor = Processor::new()
28
+ .with(md::Parse::default())
29
+ .with(md::Gfm::default())
30
+ .with(md::ToHtml::default())
31
+ .with(html::Stringify::default())
32
+ .freeze()?;
33
+ assert_eq!(processor.process("# hi")?.value, "<h1>hi</h1>");
34
+ ```
35
+
36
+ Node.js:
37
+
38
+ ```js
39
+ import { textlane } from "textlane"
40
+ import * as html from "textlane/html"
41
+ import * as md from "textlane/md"
42
+
43
+ const file = await textlane()
44
+ .use(md.parse())
45
+ .use(md.gfm())
46
+ .use(md.toHtml({ allowDangerousHtml: true }))
47
+ .use(html.stringify())
48
+ .process("# hi")
49
+ file.value // "<h1>hi</h1>"
50
+ ```
51
+
52
+ Python:
53
+
54
+ ```python
55
+ from textlane import html, md, textlane
56
+
57
+ file = (
58
+ textlane()
59
+ .use(md.parse())
60
+ .use(md.gfm())
61
+ .use(md.to_html({"allowDangerousHtml": True}))
62
+ .use(html.stringify())
63
+ .process("# hi")
64
+ )
65
+ file["value"] # "<h1>hi</h1>"
66
+ ```
67
+
68
+ Node.js and Python also offer `parse`, `run`, `stringify`, `data` and `freeze`, with
69
+ Node.js's `process`/`run` returning a Promise beside `processSync`/`runSync`, and Python's
70
+ returning the result beside the coroutines `aprocess`/`arun`.
71
+ Errors carry the crate's `code`, such as `unknown-plugin`. A JavaScript or Python function
72
+ joins a pipeline as a unified attacher returning a transformer; it cannot add syntax, a parser
73
+ or a compiler.
74
+
75
+ ## Documentation
76
+
77
+ Read the docs at [textlane.dev](https://textlane.dev).
78
+
79
+ ## License
80
+
81
+ MIT.
@@ -0,0 +1,7 @@
1
+ /** Find the textlane addon: the env override first, else the matching platform package. */
2
+ export declare function resolveAddon(props: {
3
+ platform: string;
4
+ arch: string;
5
+ env: Record<string, string | undefined>;
6
+ resolvePackage: (specifier: string) => string;
7
+ }): string;
@@ -0,0 +1,22 @@
1
+ import { ADDON_ENV, PACKAGE_NAME, PLATFORMS } from "../../settings.js";
2
+ /** Find the textlane addon: the env override first, else the matching platform package. */
3
+ export function resolveAddon(props) {
4
+ const override = props.env[ADDON_ENV];
5
+ if (override)
6
+ return override;
7
+ const key = `${props.platform}-${props.arch}`;
8
+ const platform = PLATFORMS[key];
9
+ if (!platform) {
10
+ const supported = Object.keys(PLATFORMS).join(", ");
11
+ throw new Error(`${PACKAGE_NAME} has no addon for ${key}; supported: ${supported}. ` +
12
+ `Set ${ADDON_ENV} to an addon built with cargo to load it anyway.`);
13
+ }
14
+ try {
15
+ return props.resolvePackage(`${platform.packageName}/${platform.addon}`);
16
+ }
17
+ catch {
18
+ throw new Error(`${platform.packageName} is not installed. Reinstall ${PACKAGE_NAME} without ` +
19
+ `--no-optional / --omit=optional so the addon for ${key} comes along.`);
20
+ }
21
+ }
22
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzb2x2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2FjdGlvbnMvYWRkb24vcmVzb2x2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQTtBQUV0RSwyRkFBMkY7QUFDM0YsTUFBTSxVQUFVLFlBQVksQ0FBQyxLQUs1QjtJQUNDLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUE7SUFDckMsSUFBSSxRQUFRO1FBQUUsT0FBTyxRQUFRLENBQUE7SUFFN0IsTUFBTSxHQUFHLEdBQUcsR0FBRyxLQUFLLENBQUMsUUFBUSxJQUFJLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQTtJQUM3QyxNQUFNLFFBQVEsR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUE7SUFDL0IsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ2QsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUE7UUFDbkQsTUFBTSxJQUFJLEtBQUssQ0FDYixHQUFHLFlBQVkscUJBQXFCLEdBQUcsZ0JBQWdCLFNBQVMsSUFBSTtZQUNsRSxPQUFPLFNBQVMsa0RBQWtELENBQ3JFLENBQUE7SUFDSCxDQUFDO0lBQ0QsSUFBSSxDQUFDO1FBQ0gsT0FBTyxLQUFLLENBQUMsY0FBYyxDQUFDLEdBQUcsUUFBUSxDQUFDLFdBQVcsSUFBSSxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQTtJQUMxRSxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsTUFBTSxJQUFJLEtBQUssQ0FDYixHQUFHLFFBQVEsQ0FBQyxXQUFXLGdDQUFnQyxZQUFZLFdBQVc7WUFDNUUsb0RBQW9ELEdBQUcsZUFBZSxDQUN6RSxDQUFBO0lBQ0gsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBRERPTl9FTlYsIFBBQ0tBR0VfTkFNRSwgUExBVEZPUk1TIH0gZnJvbSBcIi4uLy4uL3NldHRpbmdzLnRzXCJcblxuLyoqIEZpbmQgdGhlIHRleHRsYW5lIGFkZG9uOiB0aGUgZW52IG92ZXJyaWRlIGZpcnN0LCBlbHNlIHRoZSBtYXRjaGluZyBwbGF0Zm9ybSBwYWNrYWdlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVBZGRvbihwcm9wczoge1xuICBwbGF0Zm9ybTogc3RyaW5nXG4gIGFyY2g6IHN0cmluZ1xuICBlbnY6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD5cbiAgcmVzb2x2ZVBhY2thZ2U6IChzcGVjaWZpZXI6IHN0cmluZykgPT4gc3RyaW5nXG59KSB7XG4gIGNvbnN0IG92ZXJyaWRlID0gcHJvcHMuZW52W0FERE9OX0VOVl1cbiAgaWYgKG92ZXJyaWRlKSByZXR1cm4gb3ZlcnJpZGVcblxuICBjb25zdCBrZXkgPSBgJHtwcm9wcy5wbGF0Zm9ybX0tJHtwcm9wcy5hcmNofWBcbiAgY29uc3QgcGxhdGZvcm0gPSBQTEFURk9STVNba2V5XVxuICBpZiAoIXBsYXRmb3JtKSB7XG4gICAgY29uc3Qgc3VwcG9ydGVkID0gT2JqZWN0LmtleXMoUExBVEZPUk1TKS5qb2luKFwiLCBcIilcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgJHtQQUNLQUdFX05BTUV9IGhhcyBubyBhZGRvbiBmb3IgJHtrZXl9OyBzdXBwb3J0ZWQ6ICR7c3VwcG9ydGVkfS4gYCArXG4gICAgICAgIGBTZXQgJHtBRERPTl9FTlZ9IHRvIGFuIGFkZG9uIGJ1aWx0IHdpdGggY2FyZ28gdG8gbG9hZCBpdCBhbnl3YXkuYCxcbiAgICApXG4gIH1cbiAgdHJ5IHtcbiAgICByZXR1cm4gcHJvcHMucmVzb2x2ZVBhY2thZ2UoYCR7cGxhdGZvcm0ucGFja2FnZU5hbWV9LyR7cGxhdGZvcm0uYWRkb259YClcbiAgfSBjYXRjaCB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYCR7cGxhdGZvcm0ucGFja2FnZU5hbWV9IGlzIG5vdCBpbnN0YWxsZWQuIFJlaW5zdGFsbCAke1BBQ0tBR0VfTkFNRX0gd2l0aG91dCBgICtcbiAgICAgICAgYC0tbm8tb3B0aW9uYWwgLyAtLW9taXQ9b3B0aW9uYWwgc28gdGhlIGFkZG9uIGZvciAke2tleX0gY29tZXMgYWxvbmcuYCxcbiAgICApXG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,3 @@
1
+ import type { Attacher } from "../../models/plugin.ts";
2
+ /** Whether a pluggable is a JavaScript plugin rather than a native one. */
3
+ export declare function isAttacher(value: unknown): value is Attacher;
@@ -0,0 +1,5 @@
1
+ /** Whether a pluggable is a JavaScript plugin rather than a native one. */
2
+ export function isAttacher(value) {
3
+ return typeof value === "function";
4
+ }
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9hY3Rpb25zL2F0dGFjaGVyL2NoZWNrLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLDJFQUEyRTtBQUMzRSxNQUFNLFVBQVUsVUFBVSxDQUFDLEtBQWM7SUFDdkMsT0FBTyxPQUFPLEtBQUssS0FBSyxVQUFVLENBQUE7QUFDcEMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgQXR0YWNoZXIgfSBmcm9tIFwiLi4vLi4vbW9kZWxzL3BsdWdpbi50c1wiXG5cbi8qKiBXaGV0aGVyIGEgcGx1Z2dhYmxlIGlzIGEgSmF2YVNjcmlwdCBwbHVnaW4gcmF0aGVyIHRoYW4gYSBuYXRpdmUgb25lLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQXR0YWNoZXIodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBBdHRhY2hlciB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIlxufVxuIl19
@@ -0,0 +1,13 @@
1
+ import type { Node } from "../../models/file.ts";
2
+ import type { HostFile } from "../../models/vfile.ts";
3
+ import type { Transformer } from "../../models/plugin.ts";
4
+ /** Run one JavaScript transformer: the tree it returns, or the one it changed in place,
5
+ * directly or through a promise when it finishes later; an `Error` it returns fails the
6
+ * run, as unified's does. */
7
+ export declare function callHost(props: {
8
+ transformer: Transformer;
9
+ tree: Node;
10
+ file: HostFile;
11
+ }): Node | PromiseLike<Node>;
12
+ /** Whether a value is a promise or another thenable. */
13
+ export declare function isThenable(value: unknown): value is PromiseLike<unknown>;
@@ -0,0 +1,47 @@
1
+ /** Run one JavaScript transformer: the tree it returns, or the one it changed in place,
2
+ * directly or through a promise when it finishes later; an `Error` it returns fails the
3
+ * run, as unified's does. */
4
+ export function callHost(props) {
5
+ const transformer = props.transformer;
6
+ if (transformer.length < 3) {
7
+ const result = transformer(props.tree, props.file, () => { });
8
+ if (isThenable(result))
9
+ return result.then(tree => readTree(tree, props.tree));
10
+ return readTree(result, props.tree);
11
+ }
12
+ let settled;
13
+ let settle = (error, tree) => {
14
+ settled = { error, tree };
15
+ };
16
+ const result = transformer(props.tree, props.file, (error, tree) => settle(error, tree));
17
+ if (isThenable(result))
18
+ return result.then(tree => readTree(tree, props.tree));
19
+ if (settled) {
20
+ if (settled.error)
21
+ throw settled.error;
22
+ return readTree(settled.tree, props.tree);
23
+ }
24
+ return new Promise((resolve, reject) => {
25
+ settle = (error, tree) => error ? reject(error) : resolve(readTree(tree, props.tree));
26
+ });
27
+ }
28
+ /** Whether a value is a promise or another thenable. */
29
+ export function isThenable(value) {
30
+ return ((typeof value === "object" || typeof value === "function") &&
31
+ value !== null &&
32
+ "then" in value &&
33
+ typeof value.then === "function");
34
+ }
35
+ // A transformer that changes the tree in place returns nothing: the tree it got goes on
36
+ function readTree(result, tree) {
37
+ if (result instanceof Error)
38
+ throw result;
39
+ return isNode(result) ? result : tree;
40
+ }
41
+ function isNode(value) {
42
+ return (typeof value === "object" &&
43
+ value !== null &&
44
+ "type" in value &&
45
+ typeof value.type === "string");
46
+ }
47
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2FjdGlvbnMvaG9zdC9jYWxsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUlBOzs2QkFFNkI7QUFDN0IsTUFBTSxVQUFVLFFBQVEsQ0FBQyxLQUl4QjtJQUNDLE1BQU0sV0FBVyxHQUFHLEtBQUssQ0FBQyxXQUFXLENBQUE7SUFDckMsSUFBSSxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQzNCLE1BQU0sTUFBTSxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUUsQ0FBQyxDQUFDLENBQUE7UUFDNUQsSUFBSSxVQUFVLENBQUMsTUFBTSxDQUFDO1lBQUUsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQTtRQUM5RSxPQUFPLFFBQVEsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFBO0lBQ3JDLENBQUM7SUFDRCxJQUFJLE9BQXNELENBQUE7SUFDMUQsSUFBSSxNQUFNLEdBQUcsQ0FBQyxLQUFjLEVBQUUsSUFBYSxFQUFFLEVBQUU7UUFDN0MsT0FBTyxHQUFHLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFBO0lBQzNCLENBQUMsQ0FBQTtJQUNELE1BQU0sTUFBTSxHQUFHLFdBQVcsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUE7SUFDeEYsSUFBSSxVQUFVLENBQUMsTUFBTSxDQUFDO1FBQUUsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQTtJQUM5RSxJQUFJLE9BQU8sRUFBRSxDQUFDO1FBQ1osSUFBSSxPQUFPLENBQUMsS0FBSztZQUFFLE1BQU0sT0FBTyxDQUFDLEtBQUssQ0FBQTtRQUN0QyxPQUFPLFFBQVEsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUMzQyxDQUFDO0lBQ0QsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtRQUNyQyxNQUFNLEdBQUcsQ0FBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FDdkIsS0FBSyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFBO0lBQy9ELENBQUMsQ0FBQyxDQUFBO0FBQ0osQ0FBQztBQUVELHdEQUF3RDtBQUN4RCxNQUFNLFVBQVUsVUFBVSxDQUFDLEtBQWM7SUFDdkMsT0FBTyxDQUNMLENBQUMsT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLE9BQU8sS0FBSyxLQUFLLFVBQVUsQ0FBQztRQUMxRCxLQUFLLEtBQUssSUFBSTtRQUNkLE1BQU0sSUFBSSxLQUFLO1FBQ2YsT0FBTyxLQUFLLENBQUMsSUFBSSxLQUFLLFVBQVUsQ0FDakMsQ0FBQTtBQUNILENBQUM7QUFFRCx3RkFBd0Y7QUFDeEYsU0FBUyxRQUFRLENBQUMsTUFBZSxFQUFFLElBQVU7SUFDM0MsSUFBSSxNQUFNLFlBQVksS0FBSztRQUFFLE1BQU0sTUFBTSxDQUFBO0lBQ3pDLE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQTtBQUN2QyxDQUFDO0FBRUQsU0FBUyxNQUFNLENBQUMsS0FBYztJQUM1QixPQUFPLENBQ0wsT0FBTyxLQUFLLEtBQUssUUFBUTtRQUN6QixLQUFLLEtBQUssSUFBSTtRQUNkLE1BQU0sSUFBSSxLQUFLO1FBQ2YsT0FBTyxLQUFLLENBQUMsSUFBSSxLQUFLLFFBQVEsQ0FDL0IsQ0FBQTtBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IE5vZGUgfSBmcm9tIFwiLi4vLi4vbW9kZWxzL2ZpbGUudHNcIlxuaW1wb3J0IHR5cGUgeyBIb3N0RmlsZSB9IGZyb20gXCIuLi8uLi9tb2RlbHMvdmZpbGUudHNcIlxuaW1wb3J0IHR5cGUgeyBUcmFuc2Zvcm1lciB9IGZyb20gXCIuLi8uLi9tb2RlbHMvcGx1Z2luLnRzXCJcblxuLyoqIFJ1biBvbmUgSmF2YVNjcmlwdCB0cmFuc2Zvcm1lcjogdGhlIHRyZWUgaXQgcmV0dXJucywgb3IgdGhlIG9uZSBpdCBjaGFuZ2VkIGluIHBsYWNlLFxuICogZGlyZWN0bHkgb3IgdGhyb3VnaCBhIHByb21pc2Ugd2hlbiBpdCBmaW5pc2hlcyBsYXRlcjsgYW4gYEVycm9yYCBpdCByZXR1cm5zIGZhaWxzIHRoZVxuICogcnVuLCBhcyB1bmlmaWVkJ3MgZG9lcy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjYWxsSG9zdChwcm9wczoge1xuICB0cmFuc2Zvcm1lcjogVHJhbnNmb3JtZXJcbiAgdHJlZTogTm9kZVxuICBmaWxlOiBIb3N0RmlsZVxufSk6IE5vZGUgfCBQcm9taXNlTGlrZTxOb2RlPiB7XG4gIGNvbnN0IHRyYW5zZm9ybWVyID0gcHJvcHMudHJhbnNmb3JtZXJcbiAgaWYgKHRyYW5zZm9ybWVyLmxlbmd0aCA8IDMpIHtcbiAgICBjb25zdCByZXN1bHQgPSB0cmFuc2Zvcm1lcihwcm9wcy50cmVlLCBwcm9wcy5maWxlLCAoKSA9PiB7fSlcbiAgICBpZiAoaXNUaGVuYWJsZShyZXN1bHQpKSByZXR1cm4gcmVzdWx0LnRoZW4odHJlZSA9PiByZWFkVHJlZSh0cmVlLCBwcm9wcy50cmVlKSlcbiAgICByZXR1cm4gcmVhZFRyZWUocmVzdWx0LCBwcm9wcy50cmVlKVxuICB9XG4gIGxldCBzZXR0bGVkOiB7IGVycm9yOiB1bmtub3duOyB0cmVlOiB1bmtub3duIH0gfCB1bmRlZmluZWRcbiAgbGV0IHNldHRsZSA9IChlcnJvcjogdW5rbm93biwgdHJlZTogdW5rbm93bikgPT4ge1xuICAgIHNldHRsZWQgPSB7IGVycm9yLCB0cmVlIH1cbiAgfVxuICBjb25zdCByZXN1bHQgPSB0cmFuc2Zvcm1lcihwcm9wcy50cmVlLCBwcm9wcy5maWxlLCAoZXJyb3IsIHRyZWUpID0+IHNldHRsZShlcnJvciwgdHJlZSkpXG4gIGlmIChpc1RoZW5hYmxlKHJlc3VsdCkpIHJldHVybiByZXN1bHQudGhlbih0cmVlID0+IHJlYWRUcmVlKHRyZWUsIHByb3BzLnRyZWUpKVxuICBpZiAoc2V0dGxlZCkge1xuICAgIGlmIChzZXR0bGVkLmVycm9yKSB0aHJvdyBzZXR0bGVkLmVycm9yXG4gICAgcmV0dXJuIHJlYWRUcmVlKHNldHRsZWQudHJlZSwgcHJvcHMudHJlZSlcbiAgfVxuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIHNldHRsZSA9IChlcnJvciwgdHJlZSkgPT5cbiAgICAgIGVycm9yID8gcmVqZWN0KGVycm9yKSA6IHJlc29sdmUocmVhZFRyZWUodHJlZSwgcHJvcHMudHJlZSkpXG4gIH0pXG59XG5cbi8qKiBXaGV0aGVyIGEgdmFsdWUgaXMgYSBwcm9taXNlIG9yIGFub3RoZXIgdGhlbmFibGUuICovXG5leHBvcnQgZnVuY3Rpb24gaXNUaGVuYWJsZSh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFByb21pc2VMaWtlPHVua25vd24+IHtcbiAgcmV0dXJuIChcbiAgICAodHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiIHx8IHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiKSAmJlxuICAgIHZhbHVlICE9PSBudWxsICYmXG4gICAgXCJ0aGVuXCIgaW4gdmFsdWUgJiZcbiAgICB0eXBlb2YgdmFsdWUudGhlbiA9PT0gXCJmdW5jdGlvblwiXG4gIClcbn1cblxuLy8gQSB0cmFuc2Zvcm1lciB0aGF0IGNoYW5nZXMgdGhlIHRyZWUgaW4gcGxhY2UgcmV0dXJucyBub3RoaW5nOiB0aGUgdHJlZSBpdCBnb3QgZ29lcyBvblxuZnVuY3Rpb24gcmVhZFRyZWUocmVzdWx0OiB1bmtub3duLCB0cmVlOiBOb2RlKSB7XG4gIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBFcnJvcikgdGhyb3cgcmVzdWx0XG4gIHJldHVybiBpc05vZGUocmVzdWx0KSA/IHJlc3VsdCA6IHRyZWVcbn1cblxuZnVuY3Rpb24gaXNOb2RlKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgTm9kZSB7XG4gIHJldHVybiAoXG4gICAgdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmXG4gICAgdmFsdWUgIT09IG51bGwgJiZcbiAgICBcInR5cGVcIiBpbiB2YWx1ZSAmJlxuICAgIHR5cGVvZiB2YWx1ZS50eXBlID09PSBcInN0cmluZ1wiXG4gIClcbn1cbiJdfQ==
@@ -0,0 +1,5 @@
1
+ /** Merge `source` into a copy of `target`, as unified merges a plugin's options: plain
2
+ * objects key by key and arrays index by index, anything else replaced. */
3
+ export declare function mergeOptions(target: unknown, source: unknown): unknown;
4
+ /** Whether `value` is an object literal, not an instance, an array or `null`. */
5
+ export declare function isPlainObject(value: unknown): value is Record<string, unknown>;
@@ -0,0 +1,29 @@
1
+ /** Merge `source` into a copy of `target`, as unified merges a plugin's options: plain
2
+ * objects key by key and arrays index by index, anything else replaced. */
3
+ export function mergeOptions(target, source) {
4
+ if (isPlainObject(source)) {
5
+ const merged = isPlainObject(target) ? { ...target } : {};
6
+ for (const [key, value] of Object.entries(source)) {
7
+ if (value !== undefined)
8
+ merged[key] = mergeOptions(merged[key], value);
9
+ }
10
+ return merged;
11
+ }
12
+ if (Array.isArray(source)) {
13
+ const merged = Array.isArray(target) ? [...target] : [];
14
+ source.forEach((value, index) => {
15
+ if (value !== undefined)
16
+ merged[index] = mergeOptions(merged[index], value);
17
+ });
18
+ return merged;
19
+ }
20
+ return source;
21
+ }
22
+ /** Whether `value` is an object literal, not an instance, an array or `null`. */
23
+ export function isPlainObject(value) {
24
+ if (typeof value !== "object" || value === null)
25
+ return false;
26
+ const prototype = Object.getPrototypeOf(value);
27
+ return prototype === Object.prototype || prototype === null;
28
+ }
29
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVyZ2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9hY3Rpb25zL29wdGlvbnMvbWVyZ2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7MkVBQzJFO0FBQzNFLE1BQU0sVUFBVSxZQUFZLENBQUMsTUFBZSxFQUFFLE1BQWU7SUFDM0QsSUFBSSxhQUFhLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztRQUMxQixNQUFNLE1BQU0sR0FBNEIsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQTtRQUNsRixLQUFLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1lBQ2xELElBQUksS0FBSyxLQUFLLFNBQVM7Z0JBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLFlBQVksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUE7UUFDekUsQ0FBQztRQUNELE9BQU8sTUFBTSxDQUFBO0lBQ2YsQ0FBQztJQUNELElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1FBQzFCLE1BQU0sTUFBTSxHQUFjLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFBO1FBQ2xFLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDOUIsSUFBSSxLQUFLLEtBQUssU0FBUztnQkFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsWUFBWSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQTtRQUM3RSxDQUFDLENBQUMsQ0FBQTtRQUNGLE9BQU8sTUFBTSxDQUFBO0lBQ2YsQ0FBQztJQUNELE9BQU8sTUFBTSxDQUFBO0FBQ2YsQ0FBQztBQUVELGlGQUFpRjtBQUNqRixNQUFNLFVBQVUsYUFBYSxDQUFDLEtBQWM7SUFDMUMsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksS0FBSyxLQUFLLElBQUk7UUFBRSxPQUFPLEtBQUssQ0FBQTtJQUM3RCxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQzlDLE9BQU8sU0FBUyxLQUFLLE1BQU0sQ0FBQyxTQUFTLElBQUksU0FBUyxLQUFLLElBQUksQ0FBQTtBQUM3RCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqIE1lcmdlIGBzb3VyY2VgIGludG8gYSBjb3B5IG9mIGB0YXJnZXRgLCBhcyB1bmlmaWVkIG1lcmdlcyBhIHBsdWdpbidzIG9wdGlvbnM6IHBsYWluXG4gKiBvYmplY3RzIGtleSBieSBrZXkgYW5kIGFycmF5cyBpbmRleCBieSBpbmRleCwgYW55dGhpbmcgZWxzZSByZXBsYWNlZC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZU9wdGlvbnModGFyZ2V0OiB1bmtub3duLCBzb3VyY2U6IHVua25vd24pOiB1bmtub3duIHtcbiAgaWYgKGlzUGxhaW5PYmplY3Qoc291cmNlKSkge1xuICAgIGNvbnN0IG1lcmdlZDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSBpc1BsYWluT2JqZWN0KHRhcmdldCkgPyB7IC4uLnRhcmdldCB9IDoge31cbiAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhzb3VyY2UpKSB7XG4gICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkgbWVyZ2VkW2tleV0gPSBtZXJnZU9wdGlvbnMobWVyZ2VkW2tleV0sIHZhbHVlKVxuICAgIH1cbiAgICByZXR1cm4gbWVyZ2VkXG4gIH1cbiAgaWYgKEFycmF5LmlzQXJyYXkoc291cmNlKSkge1xuICAgIGNvbnN0IG1lcmdlZDogdW5rbm93bltdID0gQXJyYXkuaXNBcnJheSh0YXJnZXQpID8gWy4uLnRhcmdldF0gOiBbXVxuICAgIHNvdXJjZS5mb3JFYWNoKCh2YWx1ZSwgaW5kZXgpID0+IHtcbiAgICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSBtZXJnZWRbaW5kZXhdID0gbWVyZ2VPcHRpb25zKG1lcmdlZFtpbmRleF0sIHZhbHVlKVxuICAgIH0pXG4gICAgcmV0dXJuIG1lcmdlZFxuICB9XG4gIHJldHVybiBzb3VyY2Vcbn1cblxuLyoqIFdoZXRoZXIgYHZhbHVlYCBpcyBhbiBvYmplY3QgbGl0ZXJhbCwgbm90IGFuIGluc3RhbmNlLCBhbiBhcnJheSBvciBgbnVsbGAuICovXG5leHBvcnQgZnVuY3Rpb24gaXNQbGFpbk9iamVjdCh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJvYmplY3RcIiB8fCB2YWx1ZSA9PT0gbnVsbCkgcmV0dXJuIGZhbHNlXG4gIGNvbnN0IHByb3RvdHlwZSA9IE9iamVjdC5nZXRQcm90b3R5cGVPZih2YWx1ZSlcbiAgcmV0dXJuIHByb3RvdHlwZSA9PT0gT2JqZWN0LnByb3RvdHlwZSB8fCBwcm90b3R5cGUgPT09IG51bGxcbn1cbiJdfQ==
@@ -0,0 +1,8 @@
1
+ import type { Attacher } from "../../models/plugin.ts";
2
+ /** A host plugin as the crate knows it, with whether a later use turned it off. */
3
+ export type HostEntry = [{
4
+ host: number;
5
+ }, boolean?];
6
+ /** Replace every attacher in a pluggable, list or preset with its host descriptor, as
7
+ * `register` numbers it, leaving names, descriptors and options as they are. */
8
+ export declare function mapPluggable(value: unknown, register: (attacher: Attacher, parameters: unknown[]) => HostEntry): unknown;
@@ -0,0 +1,29 @@
1
+ import { isAttacher } from "../attacher/check.js";
2
+ /** Replace every attacher in a pluggable, list or preset with its host descriptor, as
3
+ * `register` numbers it, leaving names, descriptors and options as they are. */
4
+ export function mapPluggable(value, register) {
5
+ if (isAttacher(value))
6
+ return register(value, []);
7
+ if (Array.isArray(value))
8
+ return value.map(entry => mapEntry(entry, register));
9
+ return mapPreset(value, register);
10
+ }
11
+ function mapEntry(entry, register) {
12
+ if (isAttacher(entry))
13
+ return register(entry, []);
14
+ if (Array.isArray(entry)) {
15
+ const [attacher, ...parameters] = entry;
16
+ if (isAttacher(attacher))
17
+ return register(attacher, parameters);
18
+ }
19
+ return mapPreset(entry, register);
20
+ }
21
+ function mapPreset(value, register) {
22
+ if (typeof value !== "object" || value === null || !("plugins" in value))
23
+ return value;
24
+ const plugins = Array.isArray(value.plugins)
25
+ ? value.plugins.map(entry => mapEntry(entry, register))
26
+ : value.plugins;
27
+ return { ...value, plugins };
28
+ }
29
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vYWN0aW9ucy9wbHVnZ2FibGUvbWFwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQTtBQUtqRDtnRkFDZ0Y7QUFDaEYsTUFBTSxVQUFVLFlBQVksQ0FDMUIsS0FBYyxFQUNkLFFBQWtFO0lBRWxFLElBQUksVUFBVSxDQUFDLEtBQUssQ0FBQztRQUFFLE9BQU8sUUFBUSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQTtJQUNqRCxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFBO0lBQzlFLE9BQU8sU0FBUyxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQTtBQUNuQyxDQUFDO0FBRUQsU0FBUyxRQUFRLENBQ2YsS0FBYyxFQUNkLFFBQWtFO0lBRWxFLElBQUksVUFBVSxDQUFDLEtBQUssQ0FBQztRQUFFLE9BQU8sUUFBUSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQTtJQUNqRCxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUN6QixNQUFNLENBQUMsUUFBUSxFQUFFLEdBQUcsVUFBVSxDQUFDLEdBQWMsS0FBSyxDQUFBO1FBQ2xELElBQUksVUFBVSxDQUFDLFFBQVEsQ0FBQztZQUFFLE9BQU8sUUFBUSxDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUMsQ0FBQTtJQUNqRSxDQUFDO0lBQ0QsT0FBTyxTQUFTLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFBO0FBQ25DLENBQUM7QUFFRCxTQUFTLFNBQVMsQ0FDaEIsS0FBYyxFQUNkLFFBQWtFO0lBRWxFLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksQ0FBQyxDQUFDLFNBQVMsSUFBSSxLQUFLLENBQUM7UUFBRSxPQUFPLEtBQUssQ0FBQTtJQUN0RixNQUFNLE9BQU8sR0FBWSxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUM7UUFDbkQsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztRQUN2RCxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQTtJQUNqQixPQUFPLEVBQUUsR0FBRyxLQUFLLEVBQUUsT0FBTyxFQUFFLENBQUE7QUFDOUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgQXR0YWNoZXIgfSBmcm9tIFwiLi4vLi4vbW9kZWxzL3BsdWdpbi50c1wiXG5pbXBvcnQgeyBpc0F0dGFjaGVyIH0gZnJvbSBcIi4uL2F0dGFjaGVyL2NoZWNrLnRzXCJcblxuLyoqIEEgaG9zdCBwbHVnaW4gYXMgdGhlIGNyYXRlIGtub3dzIGl0LCB3aXRoIHdoZXRoZXIgYSBsYXRlciB1c2UgdHVybmVkIGl0IG9mZi4gKi9cbmV4cG9ydCB0eXBlIEhvc3RFbnRyeSA9IFt7IGhvc3Q6IG51bWJlciB9LCBib29sZWFuP11cblxuLyoqIFJlcGxhY2UgZXZlcnkgYXR0YWNoZXIgaW4gYSBwbHVnZ2FibGUsIGxpc3Qgb3IgcHJlc2V0IHdpdGggaXRzIGhvc3QgZGVzY3JpcHRvciwgYXNcbiAqIGByZWdpc3RlcmAgbnVtYmVycyBpdCwgbGVhdmluZyBuYW1lcywgZGVzY3JpcHRvcnMgYW5kIG9wdGlvbnMgYXMgdGhleSBhcmUuICovXG5leHBvcnQgZnVuY3Rpb24gbWFwUGx1Z2dhYmxlKFxuICB2YWx1ZTogdW5rbm93bixcbiAgcmVnaXN0ZXI6IChhdHRhY2hlcjogQXR0YWNoZXIsIHBhcmFtZXRlcnM6IHVua25vd25bXSkgPT4gSG9zdEVudHJ5LFxuKTogdW5rbm93biB7XG4gIGlmIChpc0F0dGFjaGVyKHZhbHVlKSkgcmV0dXJuIHJlZ2lzdGVyKHZhbHVlLCBbXSlcbiAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSByZXR1cm4gdmFsdWUubWFwKGVudHJ5ID0+IG1hcEVudHJ5KGVudHJ5LCByZWdpc3RlcikpXG4gIHJldHVybiBtYXBQcmVzZXQodmFsdWUsIHJlZ2lzdGVyKVxufVxuXG5mdW5jdGlvbiBtYXBFbnRyeShcbiAgZW50cnk6IHVua25vd24sXG4gIHJlZ2lzdGVyOiAoYXR0YWNoZXI6IEF0dGFjaGVyLCBwYXJhbWV0ZXJzOiB1bmtub3duW10pID0+IEhvc3RFbnRyeSxcbik6IHVua25vd24ge1xuICBpZiAoaXNBdHRhY2hlcihlbnRyeSkpIHJldHVybiByZWdpc3RlcihlbnRyeSwgW10pXG4gIGlmIChBcnJheS5pc0FycmF5KGVudHJ5KSkge1xuICAgIGNvbnN0IFthdHRhY2hlciwgLi4ucGFyYW1ldGVyc106IHVua25vd25bXSA9IGVudHJ5XG4gICAgaWYgKGlzQXR0YWNoZXIoYXR0YWNoZXIpKSByZXR1cm4gcmVnaXN0ZXIoYXR0YWNoZXIsIHBhcmFtZXRlcnMpXG4gIH1cbiAgcmV0dXJuIG1hcFByZXNldChlbnRyeSwgcmVnaXN0ZXIpXG59XG5cbmZ1bmN0aW9uIG1hcFByZXNldChcbiAgdmFsdWU6IHVua25vd24sXG4gIHJlZ2lzdGVyOiAoYXR0YWNoZXI6IEF0dGFjaGVyLCBwYXJhbWV0ZXJzOiB1bmtub3duW10pID0+IEhvc3RFbnRyeSxcbik6IHVua25vd24ge1xuICBpZiAodHlwZW9mIHZhbHVlICE9PSBcIm9iamVjdFwiIHx8IHZhbHVlID09PSBudWxsIHx8ICEoXCJwbHVnaW5zXCIgaW4gdmFsdWUpKSByZXR1cm4gdmFsdWVcbiAgY29uc3QgcGx1Z2luczogdW5rbm93biA9IEFycmF5LmlzQXJyYXkodmFsdWUucGx1Z2lucylcbiAgICA/IHZhbHVlLnBsdWdpbnMubWFwKGVudHJ5ID0+IG1hcEVudHJ5KGVudHJ5LCByZWdpc3RlcikpXG4gICAgOiB2YWx1ZS5wbHVnaW5zXG4gIHJldHVybiB7IC4uLnZhbHVlLCBwbHVnaW5zIH1cbn1cbiJdfQ==
@@ -0,0 +1,12 @@
1
+ import type { NativeRun } from "../../models/addon.ts";
2
+ import { type HostFile } from "../../models/vfile.ts";
3
+ import type { Host } from "../../models/host.ts";
4
+ /** Run the host plugins a native run pauses at until it finishes; under `sync`, a plugin
5
+ * finishing later fails with `async-in-sync`, as an asynchronous native stage does. */
6
+ export declare function finishRun(props: {
7
+ run: NativeRun<unknown>;
8
+ hosts: Map<number, Host>;
9
+ file: HostFile;
10
+ sync: boolean;
11
+ call: "run" | "process";
12
+ }): void | Promise<void>;
@@ -0,0 +1,52 @@
1
+ import { HostMessage } from "../../models/vfile.js";
2
+ import { callHost, isThenable } from "../host/call.js";
3
+ /** Run the host plugins a native run pauses at until it finishes; under `sync`, a plugin
4
+ * finishing later fails with `async-in-sync`, as an asynchronous native stage does. */
5
+ export function finishRun(props) {
6
+ let sent = props.file.messages.length;
7
+ while (props.run.hosts().length > 0) {
8
+ mirrorMessages();
9
+ const tree = runHosts(props, props.run.hosts(), props.run.tree());
10
+ if (isThenable(tree)) {
11
+ if (props.sync)
12
+ throw asyncError(props.call);
13
+ return Promise.resolve(tree).then(tree => {
14
+ resume(tree);
15
+ return finishRun(props);
16
+ });
17
+ }
18
+ resume(tree);
19
+ }
20
+ // file.messages follows the run's: what native stages reported since, then the plugins'
21
+ function mirrorMessages() {
22
+ const reported = props.run.messages().slice(props.file.messages.length);
23
+ for (const message of reported) {
24
+ props.file.messages.push(HostMessage.fromMessage(message, props.file.path));
25
+ }
26
+ sent = props.file.messages.length;
27
+ }
28
+ function resume(tree) {
29
+ props.run.resume(tree, props.file.messages.slice(sent).map(message => message.toJSON()));
30
+ sent = props.file.messages.length;
31
+ }
32
+ }
33
+ function runHosts(props, ids, tree) {
34
+ for (const [index, id] of ids.entries()) {
35
+ const transformer = props.hosts.get(id)?.transformer;
36
+ if (!transformer)
37
+ continue;
38
+ const result = callHost({ transformer, tree, file: props.file });
39
+ if (isThenable(result)) {
40
+ if (props.sync)
41
+ throw asyncError(props.call);
42
+ return result.then(tree => runHosts(props, ids.slice(index + 1), tree));
43
+ }
44
+ tree = result;
45
+ }
46
+ return tree;
47
+ }
48
+ function asyncError(call) {
49
+ const message = `\`${call}Sync\` finished async. Use \`${call}\` instead`;
50
+ return Object.assign(new Error(message), { code: "async-in-sync" });
51
+ }
52
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmluaXNoLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vYWN0aW9ucy9ydW4vZmluaXNoLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBaUIsV0FBVyxFQUFFLE1BQU0sdUJBQXVCLENBQUE7QUFFbEUsT0FBTyxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQTtBQUV0RDt1RkFDdUY7QUFDdkYsTUFBTSxVQUFVLFNBQVMsQ0FBQyxLQU16QjtJQUNDLElBQUksSUFBSSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQTtJQUNyQyxPQUFPLEtBQUssQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3BDLGNBQWMsRUFBRSxDQUFBO1FBQ2hCLE1BQU0sSUFBSSxHQUFHLFFBQVEsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsRUFBRSxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUE7UUFDakUsSUFBSSxVQUFVLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUNyQixJQUFJLEtBQUssQ0FBQyxJQUFJO2dCQUFFLE1BQU0sVUFBVSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQTtZQUM1QyxPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFO2dCQUN2QyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUE7Z0JBQ1osT0FBTyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUE7WUFDekIsQ0FBQyxDQUFDLENBQUE7UUFDSixDQUFDO1FBQ0QsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFBO0lBQ2QsQ0FBQztJQUVELHdGQUF3RjtJQUN4RixTQUFTLGNBQWM7UUFDckIsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDdkUsS0FBSyxNQUFNLE9BQU8sSUFBSSxRQUFRLEVBQUUsQ0FBQztZQUMvQixLQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFBO1FBQzdFLENBQUM7UUFDRCxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFBO0lBQ25DLENBQUM7SUFFRCxTQUFTLE1BQU0sQ0FBQyxJQUFVO1FBQ3hCLEtBQUssQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUNkLElBQUksRUFDSixLQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQ2pFLENBQUE7UUFDRCxJQUFJLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFBO0lBQ25DLENBQUM7QUFDSCxDQUFDO0FBRUQsU0FBUyxRQUFRLENBQ2YsS0FBZ0YsRUFDaEYsR0FBYSxFQUNiLElBQVU7SUFFVixLQUFLLE1BQU0sQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLElBQUksR0FBRyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUM7UUFDeEMsTUFBTSxXQUFXLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsV0FBVyxDQUFBO1FBQ3BELElBQUksQ0FBQyxXQUFXO1lBQUUsU0FBUTtRQUMxQixNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQTtRQUNoRSxJQUFJLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1lBQ3ZCLElBQUksS0FBSyxDQUFDLElBQUk7Z0JBQUUsTUFBTSxVQUFVLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFBO1lBQzVDLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQTtRQUN6RSxDQUFDO1FBQ0QsSUFBSSxHQUFHLE1BQU0sQ0FBQTtJQUNmLENBQUM7SUFDRCxPQUFPLElBQUksQ0FBQTtBQUNiLENBQUM7QUFFRCxTQUFTLFVBQVUsQ0FBQyxJQUFZO0lBQzlCLE1BQU0sT0FBTyxHQUFHLEtBQUssSUFBSSxnQ0FBZ0MsSUFBSSxZQUFZLENBQUE7SUFDekUsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLGVBQWUsRUFBRSxDQUFDLENBQUE7QUFDckUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgTmF0aXZlUnVuIH0gZnJvbSBcIi4uLy4uL21vZGVscy9hZGRvbi50c1wiXG5pbXBvcnQgdHlwZSB7IE5vZGUgfSBmcm9tIFwiLi4vLi4vbW9kZWxzL2ZpbGUudHNcIlxuaW1wb3J0IHsgdHlwZSBIb3N0RmlsZSwgSG9zdE1lc3NhZ2UgfSBmcm9tIFwiLi4vLi4vbW9kZWxzL3ZmaWxlLnRzXCJcbmltcG9ydCB0eXBlIHsgSG9zdCB9IGZyb20gXCIuLi8uLi9tb2RlbHMvaG9zdC50c1wiXG5pbXBvcnQgeyBjYWxsSG9zdCwgaXNUaGVuYWJsZSB9IGZyb20gXCIuLi9ob3N0L2NhbGwudHNcIlxuXG4vKiogUnVuIHRoZSBob3N0IHBsdWdpbnMgYSBuYXRpdmUgcnVuIHBhdXNlcyBhdCB1bnRpbCBpdCBmaW5pc2hlczsgdW5kZXIgYHN5bmNgLCBhIHBsdWdpblxuICogZmluaXNoaW5nIGxhdGVyIGZhaWxzIHdpdGggYGFzeW5jLWluLXN5bmNgLCBhcyBhbiBhc3luY2hyb25vdXMgbmF0aXZlIHN0YWdlIGRvZXMuICovXG5leHBvcnQgZnVuY3Rpb24gZmluaXNoUnVuKHByb3BzOiB7XG4gIHJ1bjogTmF0aXZlUnVuPHVua25vd24+XG4gIGhvc3RzOiBNYXA8bnVtYmVyLCBIb3N0PlxuICBmaWxlOiBIb3N0RmlsZVxuICBzeW5jOiBib29sZWFuXG4gIGNhbGw6IFwicnVuXCIgfCBcInByb2Nlc3NcIlxufSk6IHZvaWQgfCBQcm9taXNlPHZvaWQ+IHtcbiAgbGV0IHNlbnQgPSBwcm9wcy5maWxlLm1lc3NhZ2VzLmxlbmd0aFxuICB3aGlsZSAocHJvcHMucnVuLmhvc3RzKCkubGVuZ3RoID4gMCkge1xuICAgIG1pcnJvck1lc3NhZ2VzKClcbiAgICBjb25zdCB0cmVlID0gcnVuSG9zdHMocHJvcHMsIHByb3BzLnJ1bi5ob3N0cygpLCBwcm9wcy5ydW4udHJlZSgpKVxuICAgIGlmIChpc1RoZW5hYmxlKHRyZWUpKSB7XG4gICAgICBpZiAocHJvcHMuc3luYykgdGhyb3cgYXN5bmNFcnJvcihwcm9wcy5jYWxsKVxuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0cmVlKS50aGVuKHRyZWUgPT4ge1xuICAgICAgICByZXN1bWUodHJlZSlcbiAgICAgICAgcmV0dXJuIGZpbmlzaFJ1bihwcm9wcylcbiAgICAgIH0pXG4gICAgfVxuICAgIHJlc3VtZSh0cmVlKVxuICB9XG5cbiAgLy8gZmlsZS5tZXNzYWdlcyBmb2xsb3dzIHRoZSBydW4nczogd2hhdCBuYXRpdmUgc3RhZ2VzIHJlcG9ydGVkIHNpbmNlLCB0aGVuIHRoZSBwbHVnaW5zJ1xuICBmdW5jdGlvbiBtaXJyb3JNZXNzYWdlcygpIHtcbiAgICBjb25zdCByZXBvcnRlZCA9IHByb3BzLnJ1bi5tZXNzYWdlcygpLnNsaWNlKHByb3BzLmZpbGUubWVzc2FnZXMubGVuZ3RoKVxuICAgIGZvciAoY29uc3QgbWVzc2FnZSBvZiByZXBvcnRlZCkge1xuICAgICAgcHJvcHMuZmlsZS5tZXNzYWdlcy5wdXNoKEhvc3RNZXNzYWdlLmZyb21NZXNzYWdlKG1lc3NhZ2UsIHByb3BzLmZpbGUucGF0aCkpXG4gICAgfVxuICAgIHNlbnQgPSBwcm9wcy5maWxlLm1lc3NhZ2VzLmxlbmd0aFxuICB9XG5cbiAgZnVuY3Rpb24gcmVzdW1lKHRyZWU6IE5vZGUpIHtcbiAgICBwcm9wcy5ydW4ucmVzdW1lKFxuICAgICAgdHJlZSxcbiAgICAgIHByb3BzLmZpbGUubWVzc2FnZXMuc2xpY2Uoc2VudCkubWFwKG1lc3NhZ2UgPT4gbWVzc2FnZS50b0pTT04oKSksXG4gICAgKVxuICAgIHNlbnQgPSBwcm9wcy5maWxlLm1lc3NhZ2VzLmxlbmd0aFxuICB9XG59XG5cbmZ1bmN0aW9uIHJ1bkhvc3RzKFxuICBwcm9wczogeyBob3N0czogTWFwPG51bWJlciwgSG9zdD47IGZpbGU6IEhvc3RGaWxlOyBzeW5jOiBib29sZWFuOyBjYWxsOiBzdHJpbmcgfSxcbiAgaWRzOiBudW1iZXJbXSxcbiAgdHJlZTogTm9kZSxcbik6IE5vZGUgfCBQcm9taXNlTGlrZTxOb2RlPiB7XG4gIGZvciAoY29uc3QgW2luZGV4LCBpZF0gb2YgaWRzLmVudHJpZXMoKSkge1xuICAgIGNvbnN0IHRyYW5zZm9ybWVyID0gcHJvcHMuaG9zdHMuZ2V0KGlkKT8udHJhbnNmb3JtZXJcbiAgICBpZiAoIXRyYW5zZm9ybWVyKSBjb250aW51ZVxuICAgIGNvbnN0IHJlc3VsdCA9IGNhbGxIb3N0KHsgdHJhbnNmb3JtZXIsIHRyZWUsIGZpbGU6IHByb3BzLmZpbGUgfSlcbiAgICBpZiAoaXNUaGVuYWJsZShyZXN1bHQpKSB7XG4gICAgICBpZiAocHJvcHMuc3luYykgdGhyb3cgYXN5bmNFcnJvcihwcm9wcy5jYWxsKVxuICAgICAgcmV0dXJuIHJlc3VsdC50aGVuKHRyZWUgPT4gcnVuSG9zdHMocHJvcHMsIGlkcy5zbGljZShpbmRleCArIDEpLCB0cmVlKSlcbiAgICB9XG4gICAgdHJlZSA9IHJlc3VsdFxuICB9XG4gIHJldHVybiB0cmVlXG59XG5cbmZ1bmN0aW9uIGFzeW5jRXJyb3IoY2FsbDogc3RyaW5nKSB7XG4gIGNvbnN0IG1lc3NhZ2UgPSBgXFxgJHtjYWxsfVN5bmNcXGAgZmluaXNoZWQgYXN5bmMuIFVzZSBcXGAke2NhbGx9XFxgIGluc3RlYWRgXG4gIHJldHVybiBPYmplY3QuYXNzaWduKG5ldyBFcnJvcihtZXNzYWdlKSwgeyBjb2RlOiBcImFzeW5jLWluLXN5bmNcIiB9KVxufVxuIl19
@@ -0,0 +1,3 @@
1
+ import type { Transformer } from "../../models/plugin.ts";
2
+ /** Whether an attacher returned a transformer rather than nothing. */
3
+ export declare function isTransformer(value: unknown): value is Transformer;
@@ -0,0 +1,5 @@
1
+ /** Whether an attacher returned a transformer rather than nothing. */
2
+ export function isTransformer(value) {
3
+ return typeof value === "function";
4
+ }
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2suanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9hY3Rpb25zL3RyYW5zZm9ybWVyL2NoZWNrLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLHNFQUFzRTtBQUN0RSxNQUFNLFVBQVUsYUFBYSxDQUFDLEtBQWM7SUFDMUMsT0FBTyxPQUFPLEtBQUssS0FBSyxVQUFVLENBQUE7QUFDcEMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgVHJhbnNmb3JtZXIgfSBmcm9tIFwiLi4vLi4vbW9kZWxzL3BsdWdpbi50c1wiXG5cbi8qKiBXaGV0aGVyIGFuIGF0dGFjaGVyIHJldHVybmVkIGEgdHJhbnNmb3JtZXIgcmF0aGVyIHRoYW4gbm90aGluZy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1RyYW5zZm9ybWVyKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgVHJhbnNmb3JtZXIge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcImZ1bmN0aW9uXCJcbn1cbiJdfQ==