astro-lilypond 0.5.2 → 0.6.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 (61) hide show
  1. package/dist/deleteAssets.d.ts +27 -0
  2. package/dist/deleteAssets.d.ts.map +1 -0
  3. package/dist/deleteAssets.js +52 -0
  4. package/dist/deleteAssets.js.map +1 -0
  5. package/dist/index.d.ts +18 -7
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +61 -12
  8. package/dist/index.js.map +1 -1
  9. package/dist/plugins/index.d.ts +1 -1
  10. package/dist/plugins/index.d.ts.map +1 -1
  11. package/dist/plugins/rehype.d.ts +3 -3
  12. package/dist/plugins/rehype.d.ts.map +1 -1
  13. package/dist/plugins/rehype.js +28 -13
  14. package/dist/plugins/rehype.js.map +1 -1
  15. package/dist/plugins/remark.d.ts +3 -3
  16. package/dist/plugins/remark.d.ts.map +1 -1
  17. package/dist/plugins/remark.js +28 -13
  18. package/dist/plugins/remark.js.map +1 -1
  19. package/dist/plugins/satteri.d.ts +3 -3
  20. package/dist/plugins/satteri.d.ts.map +1 -1
  21. package/dist/plugins/satteri.js +30 -9
  22. package/dist/plugins/satteri.js.map +1 -1
  23. package/dist/plugins/types.d.ts +14 -0
  24. package/dist/plugins/types.d.ts.map +1 -1
  25. package/dist/render.d.ts +1 -2
  26. package/dist/render.d.ts.map +1 -1
  27. package/dist/render.js +1 -1
  28. package/dist/render.js.map +1 -1
  29. package/dist/utils/assetsUrlBaseFor.d.ts +7 -0
  30. package/dist/utils/assetsUrlBaseFor.d.ts.map +1 -0
  31. package/dist/utils/assetsUrlBaseFor.js +11 -0
  32. package/dist/utils/assetsUrlBaseFor.js.map +1 -0
  33. package/dist/utils/contentHashFor.d.ts +20 -0
  34. package/dist/utils/contentHashFor.d.ts.map +1 -0
  35. package/dist/utils/contentHashFor.js +21 -0
  36. package/dist/utils/contentHashFor.js.map +1 -0
  37. package/dist/utils/imgTag.d.ts +5 -0
  38. package/dist/utils/imgTag.d.ts.map +1 -0
  39. package/dist/utils/imgTag.js +7 -0
  40. package/dist/utils/imgTag.js.map +1 -0
  41. package/dist/utils/index.d.ts +5 -1
  42. package/dist/utils/index.d.ts.map +1 -1
  43. package/dist/utils/index.js +5 -1
  44. package/dist/utils/index.js.map +1 -1
  45. package/dist/utils/ownAssetFileName.d.ts +12 -0
  46. package/dist/utils/ownAssetFileName.d.ts.map +1 -0
  47. package/dist/utils/ownAssetFileName.js +25 -0
  48. package/dist/utils/ownAssetFileName.js.map +1 -0
  49. package/dist/utils/titleFor.d.ts +8 -0
  50. package/dist/utils/titleFor.d.ts.map +1 -0
  51. package/dist/utils/titleFor.js +19 -0
  52. package/dist/utils/titleFor.js.map +1 -0
  53. package/dist/writeAsset.d.ts +31 -0
  54. package/dist/writeAsset.d.ts.map +1 -0
  55. package/dist/writeAsset.js +29 -0
  56. package/dist/writeAsset.js.map +1 -0
  57. package/package.json +1 -1
  58. package/dist/utils/renderToHtml.d.ts +0 -5
  59. package/dist/utils/renderToHtml.d.ts.map +0 -1
  60. package/dist/utils/renderToHtml.js +0 -12
  61. package/dist/utils/renderToHtml.js.map +0 -1
@@ -0,0 +1,27 @@
1
+ export interface PruneOrphanedAssetsOptions {
2
+ /** Absolute filesystem path to the assets output directory. */
3
+ dir: string;
4
+ /** Filenames (e.g. `"ab12…ef.svg"`) referenced during this build. */
5
+ referenced: ReadonlySet<string>;
6
+ logger?: {
7
+ info: (message: string) => void;
8
+ };
9
+ }
10
+ /** Deletes our content-addressed files under `dir` that weren't referenced this build. */
11
+ export declare function pruneOrphanedAssets(options: PruneOrphanedAssetsOptions): Promise<void>;
12
+ export interface PruneStaleAssetsOptions {
13
+ /** Per-source history of output filenames, keyed by module id or file path. */
14
+ assetsBySource: Map<string, Set<string>>;
15
+ /** Stable identifier for the source these `fileNames` were rendered from. */
16
+ sourceKey: string;
17
+ /** Every output filename this source's current transform pass produced. */
18
+ fileNames: readonly string[];
19
+ /** Absolute filesystem path the files live in. */
20
+ outputDir: string;
21
+ logger?: {
22
+ info: (message: string) => void;
23
+ };
24
+ }
25
+ /** Deletes a source's own previously-rendered files that it no longer produces. */
26
+ export declare function pruneStaleAssets(options: PruneStaleAssetsOptions): Promise<void>;
27
+ //# sourceMappingURL=deleteAssets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deleteAssets.d.ts","sourceRoot":"","sources":["../src/deleteAssets.ts"],"names":[],"mappings":"AAuCA,MAAM,WAAW,0BAA0B;IAC1C,+DAA+D;IAC/D,GAAG,EAAE,MAAM,CAAC;IAEZ,qEAAqE;IACrE,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAEhC,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAC;CAC7C;AAED,0FAA0F;AAC1F,wBAAsB,mBAAmB,CACxC,OAAO,EAAE,0BAA0B,GACjC,OAAO,CAAC,IAAI,CAAC,CAqBf;AAED,MAAM,WAAW,uBAAuB;IACvC,+EAA+E;IAC/E,cAAc,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IAEzC,6EAA6E;IAC7E,SAAS,EAAE,MAAM,CAAC;IAElB,2EAA2E;IAC3E,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAE7B,kDAAkD;IAClD,SAAS,EAAE,MAAM,CAAC;IAElB,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAC;CAC7C;AAED,mFAAmF;AACnF,wBAAsB,gBAAgB,CACrC,OAAO,EAAE,uBAAuB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAkBf"}
@@ -0,0 +1,52 @@
1
+ import { readdir, unlink } from "node:fs/promises";
2
+ import { join, relative } from "node:path";
3
+ import { isOwnAssetFileName } from "./utils/index.js";
4
+ /** Deletes `fileNames` from `dir` and logs a one-line summary. Ignores files that are already gone. */
5
+ async function deleteAssets(options) {
6
+ const { dir, fileNames, reason, context, logger } = options;
7
+ if (fileNames.length === 0)
8
+ return;
9
+ await Promise.all(fileNames.map((name) => unlink(join(dir, name)).catch(() => { })));
10
+ logger?.info(`astro-lilypond: pruned ${fileNames.length} ${reason} asset${fileNames.length === 1 ? "" : "s"} from ${context}`);
11
+ }
12
+ /** Relativizes `path` to the current working directory for log messages. */
13
+ function relativeToCwd(path) {
14
+ return relative(process.cwd(), path) || ".";
15
+ }
16
+ /** Deletes our content-addressed files under `dir` that weren't referenced this build. */
17
+ export async function pruneOrphanedAssets(options) {
18
+ const { dir, referenced, logger } = options;
19
+ let entries;
20
+ try {
21
+ entries = await readdir(dir);
22
+ }
23
+ catch {
24
+ return;
25
+ }
26
+ const orphaned = entries.filter((name) => isOwnAssetFileName(name) && !referenced.has(name));
27
+ await deleteAssets({
28
+ dir,
29
+ fileNames: orphaned,
30
+ reason: "orphaned",
31
+ context: relativeToCwd(dir),
32
+ logger,
33
+ });
34
+ }
35
+ /** Deletes a source's own previously-rendered files that it no longer produces. */
36
+ export async function pruneStaleAssets(options) {
37
+ const { assetsBySource, sourceKey, fileNames, outputDir, logger } = options;
38
+ const next = new Set(fileNames);
39
+ const previous = assetsBySource.get(sourceKey);
40
+ assetsBySource.set(sourceKey, next);
41
+ if (!previous)
42
+ return;
43
+ const stale = [...previous].filter((name) => !next.has(name));
44
+ await deleteAssets({
45
+ dir: outputDir,
46
+ fileNames: stale,
47
+ reason: "stale",
48
+ context: relativeToCwd(sourceKey),
49
+ logger,
50
+ });
51
+ }
52
+ //# sourceMappingURL=deleteAssets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deleteAssets.js","sourceRoot":"","sources":["../src/deleteAssets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAkBtD,uGAAuG;AACvG,KAAK,UAAU,YAAY,CAAC,OAA4B;IACvD,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAC5D,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAEnC,MAAM,OAAO,CAAC,GAAG,CAChB,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,CAChE,CAAC;IAEF,MAAM,EAAE,IAAI,CACX,0BAA0B,SAAS,CAAC,MAAM,IAAI,MAAM,SAAS,SAAS,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,SAAS,OAAO,EAAE,CAChH,CAAC;AACH,CAAC;AAED,4EAA4E;AAC5E,SAAS,aAAa,CAAC,IAAY;IAClC,OAAO,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,IAAI,GAAG,CAAC;AAC7C,CAAC;AAYD,0FAA0F;AAC1F,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACxC,OAAmC;IAEnC,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAE5C,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACJ,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACR,OAAO;IACR,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAC9B,CAAC,IAAI,EAAE,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAC3D,CAAC;IAEF,MAAM,YAAY,CAAC;QAClB,GAAG;QACH,SAAS,EAAE,QAAQ;QACnB,MAAM,EAAE,UAAU;QAClB,OAAO,EAAE,aAAa,CAAC,GAAG,CAAC;QAC3B,MAAM;KACN,CAAC,CAAC;AACJ,CAAC;AAkBD,mFAAmF;AACnF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACrC,OAAgC;IAEhC,MAAM,EAAE,cAAc,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAE5E,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;IAChC,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC/C,cAAc,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAEpC,IAAI,CAAC,QAAQ;QAAE,OAAO;IAEtB,MAAM,KAAK,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAE9D,MAAM,YAAY,CAAC;QAClB,GAAG,EAAE,SAAS;QACd,SAAS,EAAE,KAAK;QAChB,MAAM,EAAE,OAAO;QACf,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC;QACjC,MAAM;KACN,CAAC,CAAC;AACJ,CAAC"}
package/dist/index.d.ts CHANGED
@@ -10,25 +10,36 @@ export interface LilypondOptions extends PluginOptions {
10
10
  */
11
11
  version?: string;
12
12
  /**
13
- * Output format. Defaults to `"svg"`.
14
- *
15
- * - `"svg"` — inline SVG embedded directly in the HTML (default)
16
- * - `"png"` — `<img>` element with a base64 data URI
13
+ * Output format to be written to a file under `outputDir`.
14
+ * @default "svg"
17
15
  */
18
16
  format?: "svg" | "png";
19
17
  /**
20
- * Resolution in DPI (only applies to PNG). Defaults to `144`.
18
+ * Resolution in DPI. Only applies when "format" is "png".
19
+ * @default 144
21
20
  */
22
21
  resolution?: number;
23
22
  /**
24
- * Crop the output tightly to the content bounding box. Defaults to `true`.
23
+ * Crop the output tightly to the content bounding box.
24
+ * @default true
25
25
  */
26
26
  crop?: boolean;
27
27
  /**
28
28
  * Milliseconds to wait for a single `lilypond` invocation before
29
- * aborting it. Defaults to `60000` (60s).
29
+ * aborting it.
30
+ * @default 60000
30
31
  */
31
32
  timeout?: number;
33
+ /**
34
+ * Directory name, relative to Astro's `publicDir`, that rendered assets
35
+ * are written into by both `astro dev` and `astro build`. Filenames are
36
+ * content-addressed, so unchanged scores are reused instead of being
37
+ * re-rendered, and it's safe to commit this directory if you'd like
38
+ * faster rebuilds.
39
+ *
40
+ * @default "_lilypond"
41
+ */
42
+ outputDir?: string;
32
43
  }
33
44
  export default function lilypond(options?: LilypondOptions): AstroIntegration;
34
45
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAE9C,OAAO,EACN,KAAK,aAAa,EAIlB,MAAM,oBAAoB,CAAC;AAa5B,YAAY,EAAE,aAAa,IAAI,qBAAqB,EAAE,CAAC;AAEvD,MAAM,WAAW,eAAgB,SAAQ,aAAa;IACrD;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IACvB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AA2BD,MAAM,CAAC,OAAO,UAAU,QAAQ,CAC/B,OAAO,GAAE,eAAoB,GAC3B,gBAAgB,CAsGlB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAG9C,OAAO,EACN,KAAK,aAAa,EAKlB,MAAM,oBAAoB,CAAC;AAiB5B,YAAY,EAAE,aAAa,IAAI,qBAAqB,EAAE,CAAC;AAEvD,MAAM,WAAW,eAAgB,SAAQ,aAAa;IACrD;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAEvB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AA4CD,MAAM,CAAC,OAAO,UAAU,QAAQ,CAC/B,OAAO,GAAE,eAAoB,GAC3B,gBAAgB,CA2IlB"}
package/dist/index.js CHANGED
@@ -1,8 +1,12 @@
1
1
  import { execFile } from "node:child_process";
2
+ import { join } from "node:path";
3
+ import { fileURLToPath } from "node:url";
2
4
  import { promisify } from "node:util";
5
+ import { pruneOrphanedAssets, pruneStaleAssets } from "./deleteAssets.js";
3
6
  import { rehypePlugin, remarkPlugin, satteriPlugin, } from "./plugins/index.js";
4
7
  import { defaultOptions, render } from "./render.js";
5
- import { includePathsFor, prependVersion, renderToHtml, sourceNameFor, } from "./utils/index.js";
8
+ import { assetsUrlBaseFor, contentHashFor, imgTag, includePathsFor, prependVersion, sourceNameFor, titleFor, } from "./utils/index.js";
9
+ import { writeAsset } from "./writeAsset.js";
6
10
  const execFileAsync = promisify(execFile);
7
11
  const LY_EXTENSIONS = [".ly", ".lilypond", ".ily"];
8
12
  function lyFilePlugin(options) {
@@ -16,21 +20,40 @@ function lyFilePlugin(options) {
16
20
  ? prependVersion(source, options.version)
17
21
  : source;
18
22
  const format = options.format ?? defaultOptions.format;
19
- const buf = await render(src, {
23
+ const resolution = options.resolution ?? defaultOptions.resolution;
24
+ const crop = options.crop ?? defaultOptions.crop;
25
+ const includePaths = includePathsFor(id);
26
+ const sourceName = sourceNameFor(id);
27
+ const title = titleFor(sourceName);
28
+ const hash = contentHashFor({ source: src, format, resolution, crop });
29
+ const fileName = `${hash}.${title}.${format}`;
30
+ const url = await writeAsset({
31
+ hash,
32
+ title,
20
33
  format,
21
- resolution: options.resolution,
22
- crop: options.crop,
23
- timeout: options.timeout,
24
- includePaths: includePathsFor(id),
25
- sourceName: sourceNameFor(id),
34
+ outputDir: options.assetsDir,
35
+ urlBase: options.assetsUrlBase,
36
+ trackAsset: options.trackAsset,
37
+ getBuffer: () => render(src, {
38
+ format,
39
+ resolution: options.resolution,
40
+ crop: options.crop,
41
+ timeout: options.timeout,
42
+ includePaths,
43
+ sourceName,
44
+ }),
26
45
  });
46
+ await options.pruneStaleAssets(id, [fileName]);
27
47
  return {
28
- code: `export default ${JSON.stringify(renderToHtml(buf, format))}`,
48
+ code: `export default ${JSON.stringify(imgTag(url))}`,
29
49
  };
30
50
  },
31
51
  };
32
52
  }
33
53
  export default function lilypond(options = {}) {
54
+ const referencedAssets = new Set();
55
+ const assetsBySource = new Map();
56
+ let assetsDir;
34
57
  return {
35
58
  name: "astro-lilypond",
36
59
  hooks: {
@@ -40,8 +63,25 @@ export default function lilypond(options = {}) {
40
63
  logger?.warn("astro-lilypond: `lilypond` binary not found — LilyPond blocks will render as errors. Install LilyPond and ensure it is on PATH.");
41
64
  }
42
65
  });
66
+ const outputDirName = options.outputDir ?? "_lilypond";
67
+ const assetsUrlBase = assetsUrlBaseFor(config.base, outputDirName);
68
+ const resolvedAssetsDir = join(fileURLToPath(config.publicDir), outputDirName);
69
+ assetsDir = resolvedAssetsDir;
70
+ const resolvedOptions = {
71
+ ...options,
72
+ assetsDir,
73
+ assetsUrlBase,
74
+ trackAsset: (fileName) => referencedAssets.add(fileName),
75
+ pruneStaleAssets: (sourceKey, fileNames) => pruneStaleAssets({
76
+ assetsBySource,
77
+ sourceKey,
78
+ fileNames,
79
+ outputDir: resolvedAssetsDir,
80
+ logger,
81
+ }),
82
+ };
43
83
  updateConfig({
44
- vite: { plugins: [lyFilePlugin(options)] },
84
+ vite: { plugins: [lyFilePlugin(resolvedOptions)] },
45
85
  });
46
86
  const existingProcessor = config.markdown?.processor;
47
87
  if (existingProcessor?.name === "satteri") {
@@ -57,7 +97,7 @@ export default function lilypond(options = {}) {
57
97
  ...existingOptions,
58
98
  mdastPlugins: [
59
99
  ...(existingOptions.mdastPlugins ?? []),
60
- satteriPlugin(options),
100
+ satteriPlugin(resolvedOptions),
61
101
  ],
62
102
  }),
63
103
  },
@@ -78,11 +118,11 @@ export default function lilypond(options = {}) {
78
118
  ...existingOptions,
79
119
  remarkPlugins: [
80
120
  ...(existingOptions.remarkPlugins ?? []),
81
- [remarkPlugin, options],
121
+ [remarkPlugin, resolvedOptions],
82
122
  ],
83
123
  rehypePlugins: [
84
124
  ...(existingOptions.rehypePlugins ?? []),
85
- [rehypePlugin, options],
125
+ [rehypePlugin, resolvedOptions],
86
126
  ],
87
127
  }),
88
128
  },
@@ -101,6 +141,15 @@ export default function lilypond(options = {}) {
101
141
  content: LY_EXTENSIONS.map((ext) => `declare module "*${ext}" {\n const html: string;\n export default html;\n}`).join("\n"),
102
142
  });
103
143
  },
144
+ "astro:build:done": async ({ logger }) => {
145
+ if (!assetsDir)
146
+ return;
147
+ await pruneOrphanedAssets({
148
+ dir: assetsDir,
149
+ referenced: referencedAssets,
150
+ logger,
151
+ });
152
+ },
104
153
  },
105
154
  };
106
155
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  export { rehypePlugin } from "./rehype.js";
2
2
  export { remarkPlugin } from "./remark.js";
3
3
  export { satteriPlugin } from "./satteri.js";
4
- export type { PluginOptions } from "./types.js";
4
+ export type { PluginOptions, ResolvedPluginOptions } from "./types.js";
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,YAAY,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC"}
@@ -1,6 +1,6 @@
1
- import type { PluginOptions } from "./types.js";
2
- export type RehypePluginOptions = PluginOptions;
3
- export declare function rehypePlugin(options?: RehypePluginOptions): (tree: any, file?: {
1
+ import type { ResolvedPluginOptions } from "./types.js";
2
+ export type RehypePluginOptions = ResolvedPluginOptions;
3
+ export declare function rehypePlugin(options: RehypePluginOptions): (tree: any, file?: {
4
4
  path?: string;
5
5
  }) => Promise<void>;
6
6
  //# sourceMappingURL=rehype.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rehype.d.ts","sourceRoot":"","sources":["../../src/plugins/rehype.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAQhD,MAAM,MAAM,mBAAmB,GAAG,aAAa,CAAC;AAIhD,wBAAgB,YAAY,CAC3B,OAAO,GAAE,mBAAwB,GAE/B,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAyDxD"}
1
+ {"version":3,"file":"rehype.d.ts","sourceRoot":"","sources":["../../src/plugins/rehype.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAQxD,MAAM,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AAIxD,wBAAgB,YAAY,CAC3B,OAAO,EAAE,mBAAmB,GAE1B,CAAC,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAyExD"}
@@ -1,13 +1,16 @@
1
1
  import { visit } from "unist-util-visit";
2
2
  import { defaultOptions, render } from "../render.js";
3
- import { includePathsFor, isLilypondLang, prependVersion, renderToHtml, sourceNameFor, } from "../utils/index.js";
3
+ import { contentHashFor, imgTag, includePathsFor, isLilypondLang, prependVersion, sourceNameFor, titleFor, } from "../utils/index.js";
4
+ import { writeAsset } from "../writeAsset.js";
4
5
  // Typed loosely so it's assignable to both RehypePlugin and the unified
5
6
  // Plugin generic regardless of which @types/hast version the host project pins.
6
- export function rehypePlugin(options = {}) {
7
+ export function rehypePlugin(options) {
7
8
  return async (tree, file) => {
8
9
  const promises = [];
10
+ const fileNames = [];
9
11
  const includePaths = includePathsFor(file?.path);
10
12
  const sourceName = sourceNameFor(file?.path);
13
+ const title = titleFor(sourceName);
11
14
  visit(tree, "element", (node, index, parent) => {
12
15
  if (node.tagName !== "pre" ||
13
16
  node.children?.length !== 1 ||
@@ -33,23 +36,35 @@ export function rehypePlugin(options = {}) {
33
36
  ? prependVersion(raw, options.version)
34
37
  : raw;
35
38
  const format = options.format ?? defaultOptions.format;
36
- const promise = render(source, {
39
+ const resolution = options.resolution ?? defaultOptions.resolution;
40
+ const crop = options.crop ?? defaultOptions.crop;
41
+ const hash = contentHashFor({ source, format, resolution, crop });
42
+ fileNames.push(`${hash}.${title}.${format}`);
43
+ const promise = writeAsset({
44
+ hash,
45
+ title,
37
46
  format,
38
- resolution: options.resolution,
39
- crop: options.crop,
40
- timeout: options.timeout,
41
- includePaths,
42
- sourceName,
43
- }).then((buf) => {
44
- const rawNode = {
45
- type: "raw",
46
- value: renderToHtml(buf, format),
47
- };
47
+ outputDir: options.assetsDir,
48
+ urlBase: options.assetsUrlBase,
49
+ trackAsset: options.trackAsset,
50
+ getBuffer: () => render(source, {
51
+ format,
52
+ resolution: options.resolution,
53
+ crop: options.crop,
54
+ timeout: options.timeout,
55
+ includePaths,
56
+ sourceName,
57
+ }),
58
+ }).then((url) => {
59
+ const rawNode = { type: "raw", value: imgTag(url) };
48
60
  parent.children[index] = rawNode;
49
61
  });
50
62
  promises.push(promise);
51
63
  });
52
64
  await Promise.all(promises);
65
+ if (file?.path) {
66
+ await options.pruneStaleAssets(file.path, fileNames);
67
+ }
53
68
  };
54
69
  }
55
70
  //# sourceMappingURL=rehype.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"rehype.js","sourceRoot":"","sources":["../../src/plugins/rehype.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rehype.js","sourceRoot":"","sources":["../../src/plugins/rehype.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import type { Root } from "mdast";
2
2
  import type { Plugin } from "unified";
3
- import type { PluginOptions } from "./types.js";
4
- export type RemarkPluginOptions = PluginOptions;
5
- export declare const remarkPlugin: Plugin<[RemarkPluginOptions?], Root>;
3
+ import type { ResolvedPluginOptions } from "./types.js";
4
+ export type RemarkPluginOptions = ResolvedPluginOptions;
5
+ export declare const remarkPlugin: Plugin<[RemarkPluginOptions], Root>;
6
6
  //# sourceMappingURL=remark.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"remark.d.ts","sourceRoot":"","sources":["../../src/plugins/remark.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,IAAI,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAUtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,MAAM,mBAAmB,GAAG,aAAa,CAAC;AAEhD,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,CAAC,mBAAmB,CAAC,CAAC,EAAE,IAAI,CAoC7D,CAAC"}
1
+ {"version":3,"file":"remark.d.ts","sourceRoot":"","sources":["../../src/plugins/remark.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,IAAI,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAatC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAExD,MAAM,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AAExD,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,CAAC,mBAAmB,CAAC,EAAE,IAAI,CAkD5D,CAAC"}
@@ -1,11 +1,14 @@
1
1
  import { visit } from "unist-util-visit";
2
2
  import { defaultOptions, render } from "../render.js";
3
- import { includePathsFor, isLilypondLang, prependVersion, renderToHtml, sourceNameFor, } from "../utils/index.js";
4
- export const remarkPlugin = (options = {}) => {
3
+ import { contentHashFor, imgTag, includePathsFor, isLilypondLang, prependVersion, sourceNameFor, titleFor, } from "../utils/index.js";
4
+ import { writeAsset } from "../writeAsset.js";
5
+ export const remarkPlugin = (options) => {
5
6
  return async (tree, file) => {
6
7
  const promises = [];
8
+ const fileNames = [];
7
9
  const includePaths = includePathsFor(file?.path);
8
10
  const sourceName = sourceNameFor(file?.path);
11
+ const title = titleFor(sourceName);
9
12
  visit(tree, "code", (node, index, parent) => {
10
13
  if (!isLilypondLang(node.lang) || index === undefined || !parent)
11
14
  return;
@@ -13,23 +16,35 @@ export const remarkPlugin = (options = {}) => {
13
16
  ? prependVersion(node.value, options.version)
14
17
  : node.value;
15
18
  const format = options.format ?? defaultOptions.format;
16
- const promise = render(source, {
19
+ const resolution = options.resolution ?? defaultOptions.resolution;
20
+ const crop = options.crop ?? defaultOptions.crop;
21
+ const hash = contentHashFor({ source, format, resolution, crop });
22
+ fileNames.push(`${hash}.${title}.${format}`);
23
+ const promise = writeAsset({
24
+ hash,
25
+ title,
17
26
  format,
18
- resolution: options.resolution,
19
- crop: options.crop,
20
- timeout: options.timeout,
21
- includePaths,
22
- sourceName,
23
- }).then((buf) => {
24
- const htmlNode = {
25
- type: "html",
26
- value: renderToHtml(buf, format),
27
- };
27
+ outputDir: options.assetsDir,
28
+ urlBase: options.assetsUrlBase,
29
+ trackAsset: options.trackAsset,
30
+ getBuffer: () => render(source, {
31
+ format,
32
+ resolution: options.resolution,
33
+ crop: options.crop,
34
+ timeout: options.timeout,
35
+ includePaths,
36
+ sourceName,
37
+ }),
38
+ }).then((url) => {
39
+ const htmlNode = { type: "html", value: imgTag(url) };
28
40
  parent.children[index] = htmlNode;
29
41
  });
30
42
  promises.push(promise);
31
43
  });
32
44
  await Promise.all(promises);
45
+ if (file?.path) {
46
+ await options.pruneStaleAssets(file.path, fileNames);
47
+ }
33
48
  };
34
49
  };
35
50
  //# sourceMappingURL=remark.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"remark.js","sourceRoot":"","sources":["../../src/plugins/remark.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EACN,eAAe,EACf,cAAc,EACd,cAAc,EACd,YAAY,EACZ,aAAa,GACb,MAAM,mBAAmB,CAAC;AAK3B,MAAM,CAAC,MAAM,YAAY,GAAyC,CACjE,OAAO,GAAG,EAAE,EACX,EAAE;IACH,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;QAC3B,MAAM,QAAQ,GAAoB,EAAE,CAAC;QACrC,MAAM,YAAY,GAAG,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACjD,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAE7C,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YAC3C,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,MAAM;gBAAE,OAAO;YAEzE,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO;gBAC7B,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC;gBAC7C,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;YACd,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,cAAc,CAAC,MAAM,CAAC;YAEvD,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE;gBAC9B,MAAM;gBACN,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,YAAY;gBACZ,UAAU;aACV,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAQ,EAAE;gBACrB,MAAM,QAAQ,GAAS;oBACtB,IAAI,EAAE,MAAM;oBACZ,KAAK,EAAE,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC;iBAChC,CAAC;gBACF,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC;YACnC,CAAC,CAAC,CAAC;YAEH,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC,CAAC,CAAC;QAEH,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC,CAAC;AACH,CAAC,CAAC"}
1
+ {"version":3,"file":"remark.js","sourceRoot":"","sources":["../../src/plugins/remark.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EACN,cAAc,EACd,MAAM,EACN,eAAe,EACf,cAAc,EACd,cAAc,EACd,aAAa,EACb,QAAQ,GACR,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAK9C,MAAM,CAAC,MAAM,YAAY,GAAwC,CAAC,OAAO,EAAE,EAAE;IAC5E,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;QAC3B,MAAM,QAAQ,GAAoB,EAAE,CAAC;QACrC,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,MAAM,YAAY,GAAG,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACjD,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;QAEnC,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YAC3C,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,MAAM;gBAAE,OAAO;YAEzE,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO;gBAC7B,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC;gBAC7C,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;YACd,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,cAAc,CAAC,MAAM,CAAC;YACvD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,cAAc,CAAC,UAAU,CAAC;YACnE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,cAAc,CAAC,IAAI,CAAC;YACjD,MAAM,IAAI,GAAG,cAAc,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;YAClE,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,KAAK,IAAI,MAAM,EAAE,CAAC,CAAC;YAE7C,MAAM,OAAO,GAAG,UAAU,CAAC;gBAC1B,IAAI;gBACJ,KAAK;gBACL,MAAM;gBACN,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,OAAO,EAAE,OAAO,CAAC,aAAa;gBAC9B,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,SAAS,EAAE,GAAG,EAAE,CACf,MAAM,CAAC,MAAM,EAAE;oBACd,MAAM;oBACN,UAAU,EAAE,OAAO,CAAC,UAAU;oBAC9B,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,OAAO,EAAE,OAAO,CAAC,OAAO;oBACxB,YAAY;oBACZ,UAAU;iBACV,CAAC;aACH,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAQ,EAAE;gBACrB,MAAM,QAAQ,GAAS,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC5D,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC;YACnC,CAAC,CAAC,CAAC;YAEH,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC,CAAC,CAAC;QAEH,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAE5B,IAAI,IAAI,EAAE,IAAI,EAAE,CAAC;YAChB,MAAM,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACtD,CAAC;IACF,CAAC,CAAC;AACH,CAAC,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import type { MdastPluginDefinition } from "satteri";
2
- import type { PluginOptions } from "./types.js";
3
- export type SatteriPluginOptions = PluginOptions;
4
- export declare function satteriPlugin(options?: SatteriPluginOptions): MdastPluginDefinition;
2
+ import type { ResolvedPluginOptions } from "./types.js";
3
+ export type SatteriPluginOptions = ResolvedPluginOptions;
4
+ export declare function satteriPlugin(options: SatteriPluginOptions): MdastPluginDefinition;
5
5
  //# sourceMappingURL=satteri.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"satteri.d.ts","sourceRoot":"","sources":["../../src/plugins/satteri.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAuB,MAAM,SAAS,CAAC;AAS1E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,MAAM,oBAAoB,GAAG,aAAa,CAAC;AAEjD,wBAAgB,aAAa,CAC5B,OAAO,GAAE,oBAAyB,GAChC,qBAAqB,CA4BvB"}
1
+ {"version":3,"file":"satteri.d.ts","sourceRoot":"","sources":["../../src/plugins/satteri.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAuB,MAAM,SAAS,CAAC;AAY1E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAExD,MAAM,MAAM,oBAAoB,GAAG,qBAAqB,CAAC;AAEzD,wBAAgB,aAAa,CAC5B,OAAO,EAAE,oBAAoB,GAC3B,qBAAqB,CAmDvB"}
@@ -1,6 +1,7 @@
1
1
  import { defaultOptions, render } from "../render.js";
2
- import { includePathsFor, isLilypondLang, prependVersion, renderToHtml, sourceNameFor, } from "../utils/index.js";
3
- export function satteriPlugin(options = {}) {
2
+ import { contentHashFor, imgTag, includePathsFor, isLilypondLang, prependVersion, sourceNameFor, titleFor, } from "../utils/index.js";
3
+ import { writeAsset } from "../writeAsset.js";
4
+ export function satteriPlugin(options) {
4
5
  return {
5
6
  name: "astro-lilypond",
6
7
  // Returning an mdast Html node (type: 'html') emits the value verbatim.
@@ -13,17 +14,37 @@ export function satteriPlugin(options = {}) {
13
14
  ? prependVersion(node.value, options.version)
14
15
  : node.value;
15
16
  const format = options.format ?? defaultOptions.format;
17
+ const resolution = options.resolution ?? defaultOptions.resolution;
18
+ const crop = options.crop ?? defaultOptions.crop;
16
19
  const includePaths = includePathsFor(ctx.fileURL);
17
20
  const sourceName = sourceNameFor(ctx.fileURL);
18
- const buf = await render(source, {
21
+ const title = titleFor(sourceName);
22
+ const hash = contentHashFor({ source, format, resolution, crop });
23
+ const fileName = `${hash}.${title}.${format}`;
24
+ const url = await writeAsset({
25
+ hash,
26
+ title,
19
27
  format,
20
- resolution: options.resolution,
21
- crop: options.crop,
22
- timeout: options.timeout,
23
- includePaths,
24
- sourceName,
28
+ outputDir: options.assetsDir,
29
+ urlBase: options.assetsUrlBase,
30
+ trackAsset: options.trackAsset,
31
+ getBuffer: () => render(source, {
32
+ format,
33
+ resolution: options.resolution,
34
+ crop: options.crop,
35
+ timeout: options.timeout,
36
+ includePaths,
37
+ sourceName,
38
+ }),
25
39
  });
26
- return { type: "html", value: renderToHtml(buf, format) };
40
+ // Sätteri has no per-file "done" hook, so prune per block instead.
41
+ if (ctx.fileURL) {
42
+ const index = ctx.indexOf(node) ?? "root";
43
+ await options.pruneStaleAssets(`${ctx.fileURL.href}#${index}`, [
44
+ fileName,
45
+ ]);
46
+ }
47
+ return { type: "html", value: imgTag(url) };
27
48
  },
28
49
  };
29
50
  }
@@ -1 +1 @@
1
- {"version":3,"file":"satteri.js","sourceRoot":"","sources":["../../src/plugins/satteri.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EACN,eAAe,EACf,cAAc,EACd,cAAc,EACd,YAAY,EACZ,aAAa,GACb,MAAM,mBAAmB,CAAC;AAK3B,MAAM,UAAU,aAAa,CAC5B,OAAO,GAAyB,EAAE;IAElC,OAAO;QACN,IAAI,EAAE,gBAAgB;QACtB,wEAAwE;QACxE,sEAAsE;QACtE,yEAAyE;QACzE,KAAK,CAAC,IAAI,CACT,IAAoB,EACpB,GAAwB;YAExB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,OAAO,SAAS,CAAC;YACjD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO;gBAC7B,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC;gBAC7C,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;YACd,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,cAAc,CAAC,MAAM,CAAC;YACvD,MAAM,YAAY,GAAG,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAClD,MAAM,UAAU,GAAG,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC9C,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,EAAE;gBAChC,MAAM;gBACN,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,YAAY;gBACZ,UAAU;aACV,CAAC,CAAC;YACH,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC;QAC3D,CAAC;KACD,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"satteri.js","sourceRoot":"","sources":["../../src/plugins/satteri.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EACN,cAAc,EACd,MAAM,EACN,eAAe,EACf,cAAc,EACd,cAAc,EACd,aAAa,EACb,QAAQ,GACR,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAK9C,MAAM,UAAU,aAAa,CAC5B,OAA6B;IAE7B,OAAO;QACN,IAAI,EAAE,gBAAgB;QACtB,wEAAwE;QACxE,sEAAsE;QACtE,yEAAyE;QACzE,KAAK,CAAC,IAAI,CACT,IAAoB,EACpB,GAAwB;YAExB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,OAAO,SAAS,CAAC;YACjD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO;gBAC7B,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC;gBAC7C,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;YACd,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,cAAc,CAAC,MAAM,CAAC;YACvD,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,cAAc,CAAC,UAAU,CAAC;YACnE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,cAAc,CAAC,IAAI,CAAC;YACjD,MAAM,YAAY,GAAG,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAClD,MAAM,UAAU,GAAG,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC9C,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;YACnC,MAAM,IAAI,GAAG,cAAc,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;YAClE,MAAM,QAAQ,GAAG,GAAG,IAAI,IAAI,KAAK,IAAI,MAAM,EAAE,CAAC;YAC9C,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC;gBAC5B,IAAI;gBACJ,KAAK;gBACL,MAAM;gBACN,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,OAAO,EAAE,OAAO,CAAC,aAAa;gBAC9B,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,SAAS,EAAE,GAAG,EAAE,CACf,MAAM,CAAC,MAAM,EAAE;oBACd,MAAM;oBACN,UAAU,EAAE,OAAO,CAAC,UAAU;oBAC9B,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,OAAO,EAAE,OAAO,CAAC,OAAO;oBACxB,YAAY;oBACZ,UAAU;iBACV,CAAC;aACH,CAAC,CAAC;YAEH,mEAAmE;YACnE,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;gBACjB,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC;gBAC1C,MAAM,OAAO,CAAC,gBAAgB,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,KAAK,EAAE,EAAE;oBAC9D,QAAQ;iBACR,CAAC,CAAC;YACJ,CAAC;YAED,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7C,CAAC;KACD,CAAC;AACH,CAAC"}
@@ -5,4 +5,18 @@ export interface PluginOptions {
5
5
  crop?: boolean;
6
6
  timeout?: number;
7
7
  }
8
+ /**
9
+ * `PluginOptions` plus the filesystem/URL details resolved once from Astro's
10
+ * config in `astro:config:setup`. Internal only.
11
+ */
12
+ export interface ResolvedPluginOptions extends PluginOptions {
13
+ /** Absolute filesystem path assets are written into. */
14
+ assetsDir: string;
15
+ /** URL prefix assets are referenced by, e.g. `"/_lilypond"`. */
16
+ assetsUrlBase: string;
17
+ /** Records that a given output filename was referenced during this build. */
18
+ trackAsset: (fileName: string) => void;
19
+ /** Deletes files this source previously produced but no longer does. */
20
+ pruneStaleAssets: (sourceKey: string, fileNames: readonly string[]) => Promise<void>;
21
+ }
8
22
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/plugins/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/plugins/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAsB,SAAQ,aAAa;IAC3D,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAC;IAElB,gEAAgE;IAChE,aAAa,EAAE,MAAM,CAAC;IAEtB,6EAA6E;IAC7E,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAEvC,wEAAwE;IACxE,gBAAgB,EAAE,CACjB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,SAAS,MAAM,EAAE,KACxB,OAAO,CAAC,IAAI,CAAC,CAAC;CACnB"}
package/dist/render.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- declare const FORMATS: readonly ["png", "svg"];
1
+ export declare const FORMATS: readonly ["png", "svg"];
2
2
  export type Format = (typeof FORMATS)[number];
3
3
  export interface RenderOptions {
4
4
  /** Output format. Defaults to `"svg"`. */
@@ -33,5 +33,4 @@ export interface RenderOptions {
33
33
  }
34
34
  export declare const defaultOptions: Required<Omit<RenderOptions, "includePaths" | "sourceName">>;
35
35
  export declare function render(source: string, options?: RenderOptions): Promise<Buffer>;
36
- export {};
37
36
  //# sourceMappingURL=render.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAMA,QAAA,MAAM,OAAO,YAAI,KAAK,EAAE,KAAK,CAAU,CAAC;AAExC,MAAM,MAAM,MAAM,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9C,MAAM,WAAW,aAAa;IAC7B,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAExB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,cAAc,EAAE,QAAQ,CACpC,IAAI,CAAC,aAAa,EAAE,cAAc,GAAG,YAAY,CAAC,CAOlD,CAAC;AAEF,wBAAsB,MAAM,CAC3B,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,aAAkB,GACzB,OAAO,CAAC,MAAM,CAAC,CAqCjB"}
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,OAAO,YAAI,KAAK,EAAE,KAAK,CAAU,CAAC;AAE/C,MAAM,MAAM,MAAM,GAAG,CAAC,OAAO,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9C,MAAM,WAAW,aAAa;IAC7B,0CAA0C;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAExB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,cAAc,EAAE,QAAQ,CACpC,IAAI,CAAC,aAAa,EAAE,cAAc,GAAG,YAAY,CAAC,CAOlD,CAAC;AAEF,wBAAsB,MAAM,CAC3B,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,aAAkB,GACzB,OAAO,CAAC,MAAM,CAAC,CAqCjB"}
package/dist/render.js CHANGED
@@ -3,7 +3,7 @@ import { tmpdir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import { execLilyPond } from "./execLilyPond.js";
5
5
  import { readOutputFile, safeInputFileName } from "./readOutputFile.js";
6
- const FORMATS = ["png", "svg"];
6
+ export const FORMATS = ["png", "svg"];
7
7
  export const defaultOptions = {
8
8
  format: "svg",
9
9
  resolution: 144,
@@ -1 +1 @@
1
- {"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExE,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,KAAK,CAAU,CAAC;AA0CxC,MAAM,CAAC,MAAM,cAAc,GAEvB;IACH,MAAM,EAAE,KAAK;IACb,UAAU,EAAE,GAAG;IACf,UAAU,EAAE,UAAU;IACtB,IAAI,EAAE,IAAI;IACV,OAAO,EAAE,MAAM;CACf,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,MAAM,CAC3B,MAAc,EACd,OAAO,GAAkB,EAAE;IAE3B,MAAM,EACL,MAAM,GAAG,cAAc,CAAC,MAAM,EAC9B,UAAU,GAAG,cAAc,CAAC,UAAU,EACtC,UAAU,GAAG,cAAc,CAAC,UAAU,EACtC,IAAI,GAAG,cAAc,CAAC,IAAI,EAC1B,OAAO,GAAG,cAAc,CAAC,OAAO,EAChC,YAAY,GAAG,EAAE,EACjB,UAAU,GACV,GAAG,OAAO,CAAC;IAEZ,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,4BAA4B,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAC7D,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3D,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAEvC,IAAI,CAAC;QACJ,MAAM,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAE3C,MAAM,YAAY,CAAC;YAClB,UAAU;YACV,MAAM;YACN,UAAU;YACV,IAAI;YACJ,YAAY;YACZ,OAAO;YACP,SAAS;YACT,UAAU;SACV,CAAC,CAAC;QAEH,OAAO,MAAM,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IACvD,CAAC;YAAS,CAAC;QACV,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACjD,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExE,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,KAAK,CAAU,CAAC;AA0C/C,MAAM,CAAC,MAAM,cAAc,GAEvB;IACH,MAAM,EAAE,KAAK;IACb,UAAU,EAAE,GAAG;IACf,UAAU,EAAE,UAAU;IACtB,IAAI,EAAE,IAAI;IACV,OAAO,EAAE,MAAM;CACf,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,MAAM,CAC3B,MAAc,EACd,OAAO,GAAkB,EAAE;IAE3B,MAAM,EACL,MAAM,GAAG,cAAc,CAAC,MAAM,EAC9B,UAAU,GAAG,cAAc,CAAC,UAAU,EACtC,UAAU,GAAG,cAAc,CAAC,UAAU,EACtC,IAAI,GAAG,cAAc,CAAC,IAAI,EAC1B,OAAO,GAAG,cAAc,CAAC,OAAO,EAChC,YAAY,GAAG,EAAE,EACjB,UAAU,GACV,GAAG,OAAO,CAAC;IAEZ,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,GAAG,MAAM,4BAA4B,CAAC,CAAC;IACxD,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;IAC7D,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3D,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAEvC,IAAI,CAAC;QACJ,MAAM,SAAS,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAE3C,MAAM,YAAY,CAAC;YAClB,UAAU;YACV,MAAM;YACN,UAAU;YACV,IAAI;YACJ,YAAY;YACZ,OAAO;YACP,SAAS;YACT,UAAU;SACV,CAAC,CAAC;QAEH,OAAO,MAAM,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IACvD,CAAC;YAAS,CAAC;QACV,MAAM,EAAE,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACjD,CAAC;AACF,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Joins Astro's `base` config with the configured output directory name
3
+ * into a clean URL prefix — no double or missing slashes, no trailing slash
4
+ * — regardless of whether `base` is `"/"`, `"/docs"`, or `"/docs/"`.
5
+ */
6
+ export declare function assetsUrlBaseFor(base: string, outputDirName: string): string;
7
+ //# sourceMappingURL=assetsUrlBaseFor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetsUrlBaseFor.d.ts","sourceRoot":"","sources":["../../src/utils/assetsUrlBaseFor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAI5E"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Joins Astro's `base` config with the configured output directory name
3
+ * into a clean URL prefix — no double or missing slashes, no trailing slash
4
+ * — regardless of whether `base` is `"/"`, `"/docs"`, or `"/docs/"`.
5
+ */
6
+ export function assetsUrlBaseFor(base, outputDirName) {
7
+ const trimmedBase = base.replace(/\/+$/, "");
8
+ const trimmedDir = outputDirName.replace(/^\/+|\/+$/g, "");
9
+ return `${trimmedBase}/${trimmedDir}`;
10
+ }
11
+ //# sourceMappingURL=assetsUrlBaseFor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assetsUrlBaseFor.js","sourceRoot":"","sources":["../../src/utils/assetsUrlBaseFor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,aAAqB;IACnE,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC7C,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IAC3D,OAAO,GAAG,WAAW,IAAI,UAAU,EAAE,CAAC;AACvC,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { Format } from "../render.js";
2
+ export interface ContentHashInput {
3
+ source: string;
4
+ format: Format;
5
+ resolution: number;
6
+ crop: boolean;
7
+ }
8
+ /**
9
+ * Derives a content-addressed hash for a rendered score (the first segment
10
+ * of its `<hash>.<title>.<ext>` filename), so identical source/options reuse
11
+ * the same output file (skipping a redundant `lilypond` invocation) and any
12
+ * change produces a new, cache-safe filename.
13
+ *
14
+ * Deliberately does not cover `\include`d file contents or the `lilypond`
15
+ * binary version — an included file changing, or a LilyPond upgrade,
16
+ * won't bust the cache. Accepted v1 tradeoff; clear the output directory
17
+ * to force a full re-render after either.
18
+ */
19
+ export declare function contentHashFor(input: ContentHashInput): string;
20
+ //# sourceMappingURL=contentHashFor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contentHashFor.d.ts","sourceRoot":"","sources":["../../src/utils/contentHashFor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAI3C,MAAM,WAAW,gBAAgB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,OAAO,CAAC;CACd;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAM9D"}
@@ -0,0 +1,21 @@
1
+ import { createHash } from "node:crypto";
2
+ const HASH_LENGTH = 6;
3
+ /**
4
+ * Derives a content-addressed hash for a rendered score (the first segment
5
+ * of its `<hash>.<title>.<ext>` filename), so identical source/options reuse
6
+ * the same output file (skipping a redundant `lilypond` invocation) and any
7
+ * change produces a new, cache-safe filename.
8
+ *
9
+ * Deliberately does not cover `\include`d file contents or the `lilypond`
10
+ * binary version — an included file changing, or a LilyPond upgrade,
11
+ * won't bust the cache. Accepted v1 tradeoff; clear the output directory
12
+ * to force a full re-render after either.
13
+ */
14
+ export function contentHashFor(input) {
15
+ const { source, format, resolution, crop } = input;
16
+ return createHash("sha256")
17
+ .update(JSON.stringify([source, format, resolution, crop]))
18
+ .digest("hex")
19
+ .slice(0, HASH_LENGTH);
20
+ }
21
+ //# sourceMappingURL=contentHashFor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contentHashFor.js","sourceRoot":"","sources":["../../src/utils/contentHashFor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,MAAM,WAAW,GAAG,CAAC,CAAC;AAStB;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAAC,KAAuB;IACrD,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;IACnD,OAAO,UAAU,CAAC,QAAQ,CAAC;SACzB,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC;SAC1D,MAAM,CAAC,KAAK,CAAC;SACb,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;AACzB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Wraps a rendered score's URL in the `<img>` markup embedded in the page.
3
+ */
4
+ export declare function imgTag(src: string): string;
5
+ //# sourceMappingURL=imgTag.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imgTag.d.ts","sourceRoot":"","sources":["../../src/utils/imgTag.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE1C"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Wraps a rendered score's URL in the `<img>` markup embedded in the page.
3
+ */
4
+ export function imgTag(src) {
5
+ return `<img class="lilypond" src="${src}" alt="">`;
6
+ }
7
+ //# sourceMappingURL=imgTag.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"imgTag.js","sourceRoot":"","sources":["../../src/utils/imgTag.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,UAAU,MAAM,CAAC,GAAW;IACjC,OAAO,8BAA8B,GAAG,WAAW,CAAC;AACrD,CAAC"}
@@ -1,6 +1,10 @@
1
+ export { assetsUrlBaseFor } from "./assetsUrlBaseFor.js";
2
+ export { contentHashFor } from "./contentHashFor.js";
3
+ export { imgTag } from "./imgTag.js";
1
4
  export { includePathsFor } from "./includePathsFor.js";
2
5
  export { isLilypondLang } from "./isLilypondLang.js";
6
+ export { contentTypeFor, isOwnAssetFileName } from "./ownAssetFileName.js";
3
7
  export { prependVersion } from "./prependVersion.js";
4
- export { renderToHtml } from "./renderToHtml.js";
5
8
  export { sourceNameFor } from "./sourceNameFor.js";
9
+ export { titleFor } from "./titleFor.js";
6
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC"}
@@ -1,6 +1,10 @@
1
+ export { assetsUrlBaseFor } from "./assetsUrlBaseFor.js";
2
+ export { contentHashFor } from "./contentHashFor.js";
3
+ export { imgTag } from "./imgTag.js";
1
4
  export { includePathsFor } from "./includePathsFor.js";
2
5
  export { isLilypondLang } from "./isLilypondLang.js";
6
+ export { contentTypeFor, isOwnAssetFileName } from "./ownAssetFileName.js";
3
7
  export { prependVersion } from "./prependVersion.js";
4
- export { renderToHtml } from "./renderToHtml.js";
5
8
  export { sourceNameFor } from "./sourceNameFor.js";
9
+ export { titleFor } from "./titleFor.js";
6
10
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * True for filenames matching our own `<hash>.<title>.<format>` naming —
3
+ * the single source of truth for what counts as one of our own rendered
4
+ * assets, shared by `pruneOrphanedAssets` and the dev asset endpoint.
5
+ */
6
+ export declare function isOwnAssetFileName(name: string): boolean;
7
+ /**
8
+ * The `Content-Type` for one of our own asset filenames, or `undefined` if
9
+ * `fileName` isn't one (see `isOwnAssetFileName`).
10
+ */
11
+ export declare function contentTypeFor(fileName: string): string | undefined;
12
+ //# sourceMappingURL=ownAssetFileName.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ownAssetFileName.d.ts","sourceRoot":"","sources":["../../src/utils/ownAssetFileName.ts"],"names":[],"mappings":"AAWA;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAInE"}
@@ -0,0 +1,25 @@
1
+ import { FORMATS } from "../render.js";
2
+ const CONTENT_TYPES = {
3
+ svg: "image/svg+xml",
4
+ png: "image/png",
5
+ };
6
+ const OWN_ASSET_NAME = new RegExp(`^[0-9a-f]+\\.[a-zA-Z0-9_-]+\\.(?:${FORMATS.join("|")})$`);
7
+ /**
8
+ * True for filenames matching our own `<hash>.<title>.<format>` naming —
9
+ * the single source of truth for what counts as one of our own rendered
10
+ * assets, shared by `pruneOrphanedAssets` and the dev asset endpoint.
11
+ */
12
+ export function isOwnAssetFileName(name) {
13
+ return OWN_ASSET_NAME.test(name);
14
+ }
15
+ /**
16
+ * The `Content-Type` for one of our own asset filenames, or `undefined` if
17
+ * `fileName` isn't one (see `isOwnAssetFileName`).
18
+ */
19
+ export function contentTypeFor(fileName) {
20
+ if (!isOwnAssetFileName(fileName))
21
+ return undefined;
22
+ const format = fileName.slice(fileName.lastIndexOf(".") + 1);
23
+ return CONTENT_TYPES[format];
24
+ }
25
+ //# sourceMappingURL=ownAssetFileName.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ownAssetFileName.js","sourceRoot":"","sources":["../../src/utils/ownAssetFileName.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAe,MAAM,cAAc,CAAC;AAEpD,MAAM,aAAa,GAA2B;IAC7C,GAAG,EAAE,eAAe;IACpB,GAAG,EAAE,WAAW;CAChB,CAAC;AAEF,MAAM,cAAc,GAAG,IAAI,MAAM,CAChC,oCAAoC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CACzD,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC9C,OAAO,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC9C,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC;QAAE,OAAO,SAAS,CAAC;IACpD,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAW,CAAC;IACvE,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Derives a human-readable, filename-safe title from `sourceNameFor()`'s
3
+ * output, for use as the middle segment of a rendered asset's filename
4
+ * (`<hash>.<title>.<ext>`). Falls back to `"score"` when the source
5
+ * location is unknown or sanitizes away to nothing.
6
+ */
7
+ export declare function titleFor(sourceName: string | undefined): string;
8
+ //# sourceMappingURL=titleFor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"titleFor.d.ts","sourceRoot":"","sources":["../../src/utils/titleFor.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAQ/D"}
@@ -0,0 +1,19 @@
1
+ import { basename, extname } from "node:path";
2
+ const UNSAFE_CHARS = /[^a-zA-Z0-9_-]+/g;
3
+ /**
4
+ * Derives a human-readable, filename-safe title from `sourceNameFor()`'s
5
+ * output, for use as the middle segment of a rendered asset's filename
6
+ * (`<hash>.<title>.<ext>`). Falls back to `"score"` when the source
7
+ * location is unknown or sanitizes away to nothing.
8
+ */
9
+ export function titleFor(sourceName) {
10
+ if (!sourceName)
11
+ return "score";
12
+ const stem = basename(sourceName, extname(sourceName));
13
+ const safe = stem
14
+ .replace(UNSAFE_CHARS, "-")
15
+ .replace(/-+/g, "-")
16
+ .replace(/^-|-$/g, "");
17
+ return safe || "score";
18
+ }
19
+ //# sourceMappingURL=titleFor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"titleFor.js","sourceRoot":"","sources":["../../src/utils/titleFor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE9C,MAAM,YAAY,GAAG,kBAAkB,CAAC;AAExC;;;;;GAKG;AACH,MAAM,UAAU,QAAQ,CAAC,UAA8B;IACtD,IAAI,CAAC,UAAU;QAAE,OAAO,OAAO,CAAC;IAChC,MAAM,IAAI,GAAG,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;IACvD,MAAM,IAAI,GAAG,IAAI;SACf,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC;SAC1B,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACxB,OAAO,IAAI,IAAI,OAAO,CAAC;AACxB,CAAC"}
@@ -0,0 +1,31 @@
1
+ import type { Format } from "./render.js";
2
+ export interface WriteAssetOptions {
3
+ /** Content hash — the first segment of the filename. */
4
+ hash: string;
5
+ /**
6
+ * Human-readable title — the middle segment of the filename, e.g. the
7
+ * source file's basename. See `titleFor()`.
8
+ */
9
+ title: string;
10
+ /** Output format — also used as the file extension. */
11
+ format: Format;
12
+ /** Absolute filesystem path to write the file into. */
13
+ outputDir: string;
14
+ /** URL prefix the returned URL is built from, e.g. `"/_lilypond"`. */
15
+ urlBase: string;
16
+ /** Called with the written/reused file's name, hit or miss. */
17
+ trackAsset?: (fileName: string) => void;
18
+ /**
19
+ * Produces the bytes to write. Only invoked on a cache miss, so a caller
20
+ * can defer an expensive render behind this and skip it entirely when the
21
+ * content-addressed file already exists on disk.
22
+ */
23
+ getBuffer: () => Promise<Buffer>;
24
+ }
25
+ /**
26
+ * Persists rendered bytes to a content-addressed file under `outputDir`,
27
+ * skipping the render entirely if that file already exists, and returns the
28
+ * public URL to reference it by.
29
+ */
30
+ export declare function writeAsset(options: WriteAssetOptions): Promise<string>;
31
+ //# sourceMappingURL=writeAsset.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writeAsset.d.ts","sourceRoot":"","sources":["../src/writeAsset.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,WAAW,iBAAiB;IACjC,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAC;IAEf,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAC;IAElB,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAEhB,+DAA+D;IAC/D,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAExC;;;;OAIG;IACH,SAAS,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CACjC;AAED;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CA0B5E"}
@@ -0,0 +1,29 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { access, mkdir, rename, writeFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ /**
5
+ * Persists rendered bytes to a content-addressed file under `outputDir`,
6
+ * skipping the render entirely if that file already exists, and returns the
7
+ * public URL to reference it by.
8
+ */
9
+ export async function writeAsset(options) {
10
+ const { hash, title, format, outputDir, urlBase, trackAsset, getBuffer } = options;
11
+ const fileName = `${hash}.${title}.${format}`;
12
+ const destPath = join(outputDir, fileName);
13
+ const url = `${urlBase}/${fileName}`;
14
+ const alreadyWritten = await access(destPath).then(() => true, () => false);
15
+ if (!alreadyWritten) {
16
+ const buf = await getBuffer();
17
+ await mkdir(outputDir, { recursive: true });
18
+ // Write to a uniquely-suffixed temp file, then atomically rename onto
19
+ // the final path — safe under concurrent writers racing to produce the
20
+ // same hash, since identical hashes imply identical bytes, so whichever
21
+ // rename lands "wins" without ever leaving a corrupt/partial file.
22
+ const tmpPath = `${destPath}.${randomUUID()}.tmp`;
23
+ await writeFile(tmpPath, buf);
24
+ await rename(tmpPath, destPath);
25
+ }
26
+ trackAsset?.(fileName);
27
+ return url;
28
+ }
29
+ //# sourceMappingURL=writeAsset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writeAsset.js","sourceRoot":"","sources":["../src/writeAsset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAiCjC;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAA0B;IAC1D,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,GACvE,OAAO,CAAC;IACT,MAAM,QAAQ,GAAG,GAAG,IAAI,IAAI,KAAK,IAAI,MAAM,EAAE,CAAC;IAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAG,GAAG,OAAO,IAAI,QAAQ,EAAE,CAAC;IAErC,MAAM,cAAc,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CACjD,GAAG,EAAE,CAAC,IAAI,EACV,GAAG,EAAE,CAAC,KAAK,CACX,CAAC;IAEF,IAAI,CAAC,cAAc,EAAE,CAAC;QACrB,MAAM,GAAG,GAAG,MAAM,SAAS,EAAE,CAAC;QAC9B,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5C,sEAAsE;QACtE,uEAAuE;QACvE,wEAAwE;QACxE,mEAAmE;QACnE,MAAM,OAAO,GAAG,GAAG,QAAQ,IAAI,UAAU,EAAE,MAAM,CAAC;QAClD,MAAM,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC9B,MAAM,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACjC,CAAC;IAED,UAAU,EAAE,CAAC,QAAQ,CAAC,CAAC;IACvB,OAAO,GAAG,CAAC;AACZ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "astro-lilypond",
3
- "version": "0.5.2",
3
+ "version": "0.6.0",
4
4
  "description": "An Astro integration for rendering Lilypond markup to music notation.",
5
5
  "homepage": "https://lilypond.ky.fyi",
6
6
  "author": "Ky Decker",
@@ -1,5 +0,0 @@
1
- /**
2
- * Converts a rendered LilyPond buffer to an HTML string.
3
- */
4
- export declare function renderToHtml(buf: Buffer, format: "svg" | "png"): string;
5
- //# sourceMappingURL=renderToHtml.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"renderToHtml.d.ts","sourceRoot":"","sources":["../../src/utils/renderToHtml.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAGvE"}
@@ -1,12 +0,0 @@
1
- const MIME_TYPES = {
2
- svg: "image/svg+xml",
3
- png: "image/png",
4
- };
5
- /**
6
- * Converts a rendered LilyPond buffer to an HTML string.
7
- */
8
- export function renderToHtml(buf, format) {
9
- const b64 = buf.toString("base64");
10
- return `<img class="lilypond" src="data:${MIME_TYPES[format]};base64,${b64}" alt="">`;
11
- }
12
- //# sourceMappingURL=renderToHtml.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"renderToHtml.js","sourceRoot":"","sources":["../../src/utils/renderToHtml.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,GAAG;IAClB,GAAG,EAAE,eAAe;IACpB,GAAG,EAAE,WAAW;CACP,CAAC;AAEX;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,MAAqB;IAC9D,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACnC,OAAO,mCAAmC,UAAU,CAAC,MAAM,CAAC,WAAW,GAAG,WAAW,CAAC;AACvF,CAAC"}