@xtrable-ltd/nanoesis 0.1.34 → 0.1.36

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 (27) hide show
  1. package/dist/adapter-azure-blob.js +1 -1
  2. package/dist/{chunk-C3QPGXG5.js → chunk-2OWUWOGB.js} +6 -1
  3. package/dist/{chunk-P6NDWIKK.js → chunk-AH2MVN2O.js} +87 -24
  4. package/dist/editor-api.js +2 -2
  5. package/dist/index.d.ts +59 -5
  6. package/dist/index.js +3 -1
  7. package/dist/mcp.js +3 -3
  8. package/editor/assets/{MigrationsPane-BuaKhsie.js → MigrationsPane-DNIZD5v9.js} +1 -1
  9. package/editor/assets/{TemplatesPane-Bg_b0htA.js → TemplatesPane-tI-X3c-0.js} +8 -8
  10. package/editor/assets/{cssMode-Bcwjp8T3.js → cssMode-BHqRWMex.js} +1 -1
  11. package/editor/assets/{freemarker2-Cgqj3dEx.js → freemarker2-CfiPR_ij.js} +1 -1
  12. package/editor/assets/{handlebars-CLf2-RZf.js → handlebars-0ARiDNDT.js} +1 -1
  13. package/editor/assets/{html-BrWGWRh6.js → html-Dp9xFEzA.js} +1 -1
  14. package/editor/assets/{htmlMode-D9skx8gp.js → htmlMode-Di7FTYZK.js} +1 -1
  15. package/editor/assets/{index-CY5Kehuu.js → index-CMn2xISn.js} +73 -73
  16. package/editor/assets/{javascript-KaABDboM.js → javascript-CzNePMtj.js} +1 -1
  17. package/editor/assets/{jsonMode-0usLs2ME.js → jsonMode-CrPeML79.js} +1 -1
  18. package/editor/assets/{liquid-DYna-Clp.js → liquid-Cfq-Fp7b.js} +1 -1
  19. package/editor/assets/{mdx-f7LAIls6.js → mdx-sMGe_OUc.js} +1 -1
  20. package/editor/assets/{python-Bh21_mvq.js → python-lEgAHzP3.js} +1 -1
  21. package/editor/assets/{razor-D_530Ymg.js → razor-BbvZMZxa.js} +1 -1
  22. package/editor/assets/{tsMode-CTRVjt9n.js → tsMode-DMVtz8YS.js} +1 -1
  23. package/editor/assets/{typescript-D084tkOf.js → typescript-D-p3vFTx.js} +1 -1
  24. package/editor/assets/{xml-BFulX1C6.js → xml-CmbnTHPn.js} +1 -1
  25. package/editor/assets/{yaml-CgZsYmUt.js → yaml-HnvHlCHy.js} +1 -1
  26. package/editor/index.html +1 -1
  27. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  contentHash,
3
3
  contentTypeFor
4
- } from "./chunk-P6NDWIKK.js";
4
+ } from "./chunk-AH2MVN2O.js";
5
5
 
6
6
  // ../../adapters/azure-blob/src/container.ts
7
7
  var InMemoryBlobContainer = class {
@@ -18,7 +18,7 @@ import {
18
18
  renderReferenceMarkdown,
19
19
  validateSite,
20
20
  workingStoreRoundTripDiagnostic
21
- } from "./chunk-P6NDWIKK.js";
21
+ } from "./chunk-AH2MVN2O.js";
22
22
 
23
23
  // ../editor-api/src/scaffold.ts
24
24
  var HOME_HTML = `<!doctype html>
@@ -940,6 +940,7 @@ function createEditor(config) {
940
940
  const reconcile = config.enumerate === void 0 ? void 0 : async () => working.reconcile([...await config.enumerate()]);
941
941
  let progressEvents = [];
942
942
  let progressRunning = false;
943
+ let mediaCache = /* @__PURE__ */ new Map();
943
944
  const publish = async (options) => {
944
945
  progressEvents = [];
945
946
  progressRunning = true;
@@ -954,17 +955,21 @@ function createEditor(config) {
954
955
  }
955
956
  const dir = config.users === void 0 ? void 0 : authorDirectory(await config.users());
956
957
  const prebuild = typeof config.prebuild === "function" ? await config.prebuild() : config.prebuild;
958
+ const nextCache = /* @__PURE__ */ new Map();
957
959
  const result = await publishSite(working, sink, {
958
960
  ...config.images !== void 0 && { imageEncoder: config.images },
959
961
  ...config.purge !== void 0 && { purge: config.purge },
960
962
  ...config.baseUrl !== void 0 && { baseUrl: config.baseUrl },
961
963
  ...dir !== void 0 && { authorDirectory: dir },
962
964
  ...prebuild !== void 0 && { prebuild },
965
+ mediaCache,
966
+ onMediaEntry: (hash, cached) => nextCache.set(hash, cached),
963
967
  onProgress: record
964
968
  });
965
969
  if (result.ok && wipeBeforePublish && config.website.prune !== void 0) {
966
970
  await config.website.prune(new Set(result.written));
967
971
  }
972
+ if (result.ok) mediaCache = nextCache;
968
973
  return result;
969
974
  } finally {
970
975
  progressRunning = false;
@@ -1688,26 +1688,22 @@ function contentHash(bytes) {
1688
1688
  }
1689
1689
  return (hash >>> 0).toString(36);
1690
1690
  }
1691
- async function processImage(input, assetPath, encoder) {
1691
+ function buildImageOutput(assetPath, hash, source, variants, bytesFor) {
1692
1692
  const fallbackFormat = fallbackFormatFor(assetPath);
1693
- const formats = [.../* @__PURE__ */ new Set(["avif", "webp", fallbackFormat])];
1694
- const encoded = await encoder.encode(input, { widths: DEFAULT_WIDTHS, formats });
1695
- const hash = contentHash(input);
1696
1693
  const base = assetPath.slice(
1697
1694
  0,
1698
1695
  assetPath.lastIndexOf(".") >= 0 ? assetPath.lastIndexOf(".") : assetPath.length
1699
1696
  );
1700
1697
  const artifacts = [];
1701
- const urlOf = (variant) => {
1702
- const path = `${base}.${hash}-${variant.width}.${extOf(variant.format)}`;
1703
- artifacts.push({ path, contents: variant.bytes, cacheControl: CACHE_IMMUTABLE });
1704
- return `/${path}`;
1705
- };
1706
1698
  const byFormat = /* @__PURE__ */ new Map();
1707
- for (const variant of [...encoded.variants].sort((a, b) => a.width - b.width)) {
1708
- const url = urlOf(variant);
1699
+ for (const variant of [...variants].sort((a, b) => a.width - b.width)) {
1700
+ const path = `${base}.${hash}-${variant.width}.${extOf(variant.format)}`;
1701
+ const bytes = bytesFor(variant);
1702
+ artifacts.push(
1703
+ bytes === void 0 ? { path, contents: EMPTY_BYTES, cacheControl: CACHE_IMMUTABLE, present: true } : { path, contents: bytes, cacheControl: CACHE_IMMUTABLE }
1704
+ );
1709
1705
  const list = byFormat.get(variant.format) ?? [];
1710
- list.push({ url, width: variant.width });
1706
+ list.push({ url: `/${path}`, width: variant.width });
1711
1707
  byFormat.set(variant.format, list);
1712
1708
  }
1713
1709
  const srcsetOf = (format) => (byFormat.get(format) ?? []).map((entry) => `${entry.url} ${entry.width}w`).join(", ");
@@ -1715,14 +1711,57 @@ async function processImage(input, assetPath, encoder) {
1715
1711
  const fallbackList = byFormat.get(fallbackFormat) ?? [];
1716
1712
  const fallbackSrc = fallbackList[fallbackList.length - 1]?.url ?? `/${assetPath}`;
1717
1713
  const info = {
1718
- width: encoded.sourceWidth,
1719
- height: encoded.sourceHeight,
1714
+ width: source.width,
1715
+ height: source.height,
1720
1716
  sources,
1721
1717
  fallbackSrc,
1722
- ...encoded.blurDataUri !== void 0 && { blurDataUri: encoded.blurDataUri }
1718
+ ...source.blurDataUri !== void 0 && { blurDataUri: source.blurDataUri }
1723
1719
  };
1724
1720
  return { artifacts, info };
1725
1721
  }
1722
+ var EMPTY_BYTES = new Uint8Array(0);
1723
+ async function processImage(input, assetPath, encoder) {
1724
+ const fallbackFormat = fallbackFormatFor(assetPath);
1725
+ const formats = [.../* @__PURE__ */ new Set(["avif", "webp", fallbackFormat])];
1726
+ const encoded = await encoder.encode(input, { widths: DEFAULT_WIDTHS, formats });
1727
+ const hash = contentHash(input);
1728
+ const bytesByVariant = /* @__PURE__ */ new Map();
1729
+ const variants = [];
1730
+ for (const variant of encoded.variants) {
1731
+ bytesByVariant.set(variantKey(variant), variant.bytes);
1732
+ variants.push({ format: variant.format, width: variant.width });
1733
+ }
1734
+ const { artifacts, info } = buildImageOutput(
1735
+ assetPath,
1736
+ hash,
1737
+ { width: encoded.sourceWidth, height: encoded.sourceHeight, ...blur(encoded.blurDataUri) },
1738
+ variants,
1739
+ (variant) => bytesByVariant.get(variantKey(variant))
1740
+ );
1741
+ const cached = {
1742
+ sourceWidth: encoded.sourceWidth,
1743
+ sourceHeight: encoded.sourceHeight,
1744
+ // Stored width-ascending so a cache hit rebuilds the identical artifact/srcset order.
1745
+ variants: [...variants].sort((a, b) => a.width - b.width),
1746
+ ...blur(encoded.blurDataUri)
1747
+ };
1748
+ return { artifacts, info, cached };
1749
+ }
1750
+ function processImageFromCache(assetPath, hash, cached) {
1751
+ return buildImageOutput(
1752
+ assetPath,
1753
+ hash,
1754
+ { width: cached.sourceWidth, height: cached.sourceHeight, ...blur(cached.blurDataUri) },
1755
+ cached.variants,
1756
+ () => void 0
1757
+ );
1758
+ }
1759
+ function variantKey(variant) {
1760
+ return `${variant.format}-${variant.width}`;
1761
+ }
1762
+ function blur(blurDataUri) {
1763
+ return blurDataUri !== void 0 ? { blurDataUri } : {};
1764
+ }
1726
1765
  function buildPictureMarkup(info, extraAttrs) {
1727
1766
  const sources = info.sources.map(
1728
1767
  (source) => `<source type="${source.mime}" srcset="${escapeHtmlAttribute(source.srcset)}">`
@@ -2151,6 +2190,9 @@ function urlForItem(contentPath) {
2151
2190
  const dirSegments = segments[segments.length - 1] === "index" ? segments.slice(0, -1) : segments;
2152
2191
  return dirSegments.length === 0 ? "/" : `/${dirSegments.join("/")}/`;
2153
2192
  }
2193
+ function siteUrl(baseUrl) {
2194
+ return baseUrl === void 0 ? "" : baseUrl.replace(/\/+$/, "");
2195
+ }
2154
2196
 
2155
2197
  // ../engine/src/compile/site.ts
2156
2198
  var DEFAULT_IMAGE_CONCURRENCY = 4;
@@ -2284,7 +2326,9 @@ async function compileSite(source, options = {}) {
2284
2326
  plans.map((p) => p.refs),
2285
2327
  options.imageEncoder,
2286
2328
  options.imageConcurrency ?? DEFAULT_IMAGE_CONCURRENCY,
2287
- onProgress === void 0 ? void 0 : (published) => report(published)
2329
+ onProgress === void 0 ? void 0 : (published) => report(published),
2330
+ options.mediaCache,
2331
+ options.onMediaEntry
2288
2332
  );
2289
2333
  artifacts.push(...mediaArtifacts);
2290
2334
  for (const { node, templateName, template, refs } of plans) {
@@ -2292,7 +2336,7 @@ async function compileSite(source, options = {}) {
2292
2336
  const templateScript = await getScript(templateName);
2293
2337
  const contents = compileTemplate({
2294
2338
  template,
2295
- scope: buildScope(node.item),
2339
+ scope: buildScope(node.item, { path: node.path, baseUrl }),
2296
2340
  components,
2297
2341
  context,
2298
2342
  media: resolverFor(refs, imageInfoByPublished, fileUrlByPublished),
@@ -2365,7 +2409,9 @@ async function compilePage(source, itemPath, options = {}) {
2365
2409
  }
2366
2410
  const html = compileTemplate({
2367
2411
  template,
2368
- scope: buildScope(item),
2412
+ // The preview has no site config loaded, so `{site_url}` degrades to empty
2413
+ // while `{url}` still resolves from the item's path (the brief's preview path).
2414
+ scope: buildScope(item, { path: node.path, baseUrl: void 0 }),
2369
2415
  components,
2370
2416
  context: buildResolveContext(tree),
2371
2417
  media,
@@ -2435,7 +2481,7 @@ function itemMediaRefs(node, analysis) {
2435
2481
  }
2436
2482
  return { images, files };
2437
2483
  }
2438
- async function collectSiteMedia(source, itemRefs, encoder, imageConcurrency, onAsset) {
2484
+ async function collectSiteMedia(source, itemRefs, encoder, imageConcurrency, onAsset, mediaCache, onMediaEntry) {
2439
2485
  const uniqueOrdered = (pick) => {
2440
2486
  const seen = /* @__PURE__ */ new Set();
2441
2487
  const order = [];
@@ -2468,7 +2514,14 @@ async function collectSiteMedia(source, itemRefs, encoder, imageConcurrency, onA
2468
2514
  const imagePaths = uniqueOrdered((r) => r.images);
2469
2515
  const encoded = await mapWithConcurrency(imagePaths, imageConcurrency, async (published) => {
2470
2516
  const bytes = await tryReadBytes(source, `content/${published}`);
2471
- const result = bytes === void 0 ? void 0 : await processImage(bytes, published, encoder);
2517
+ if (bytes === void 0) {
2518
+ onAsset?.(published);
2519
+ return void 0;
2520
+ }
2521
+ const hash = contentHash(bytes);
2522
+ const hit = mediaCache?.get(hash);
2523
+ const result = hit !== void 0 ? { ...processImageFromCache(published, hash, hit), cached: hit } : await processImage(bytes, published, encoder);
2524
+ onMediaEntry?.(hash, result.cached);
2472
2525
  onAsset?.(published);
2473
2526
  return result;
2474
2527
  });
@@ -2533,13 +2586,14 @@ function assetRefs(value) {
2533
2586
  return value.filter((entry) => typeof entry === "string");
2534
2587
  return [];
2535
2588
  }
2536
- function buildScope(item) {
2589
+ function buildScope(item, page) {
2537
2590
  return {
2538
2591
  ...item.fields,
2539
2592
  title: item.title,
2540
2593
  ...item.created !== void 0 && { created: item.created },
2541
2594
  ...item.published !== void 0 && { published: item.published },
2542
- ...item.updated !== void 0 && { updated: item.updated }
2595
+ ...item.updated !== void 0 && { updated: item.updated },
2596
+ ...page !== void 0 && { url: urlForItem(page.path), site_url: siteUrl(page.baseUrl) }
2543
2597
  };
2544
2598
  }
2545
2599
  function indexTree(tree) {
@@ -2698,6 +2752,11 @@ function tokensSection() {
2698
2752
  name: "{item} and {item.field}",
2699
2753
  summary: "Inside a loop, the current item: {item} is its URL, and {item.title} (or any field) is its content.",
2700
2754
  example: '<a href="{item}">{item.title}</a>'
2755
+ },
2756
+ {
2757
+ name: "{url} and {site_url}",
2758
+ summary: "The current page\u2019s own location. {url} is its root-relative URL with a trailing slash (the form {item} yields); {site_url} is the configured site origin with no trailing slash (empty when none is set). Compose {site_url}{url} for an absolute canonical URL.",
2759
+ example: '<link rel="canonical" href="{site_url}{url}" />'
2701
2760
  }
2702
2761
  ]
2703
2762
  };
@@ -3312,7 +3371,8 @@ async function publishSite(source, sink, options = {}) {
3312
3371
  const passthrough = await collectPublic(source, publicDir);
3313
3372
  const hashByPath = /* @__PURE__ */ new Map();
3314
3373
  for (const artifact of [...artifacts, ...passthrough])
3315
- hashByPath.set(artifact.path, contentHash(asBytes(artifact.contents)));
3374
+ if (cacheControlFor(artifact) !== CACHE_IMMUTABLE)
3375
+ hashByPath.set(artifact.path, contentHash(asBytes(artifact.contents)));
3316
3376
  const hashFor = (path) => hashByPath.get(path);
3317
3377
  const stamped = artifacts.map(
3318
3378
  (artifact) => typeof artifact.contents === "string" && artifact.path.endsWith(".html") ? { ...artifact, contents: cacheBustAssets(artifact.contents, hashFor) } : artifact
@@ -3326,7 +3386,9 @@ async function publishSite(source, sink, options = {}) {
3326
3386
  let uploaded = 0;
3327
3387
  const writeGroup = async (group) => {
3328
3388
  await mapWithConcurrency(group, writeConcurrency, async (artifact) => {
3329
- await sink.write(artifact.path, artifact.contents, cacheControlFor(artifact));
3389
+ if (artifact.present !== true) {
3390
+ await sink.write(artifact.path, artifact.contents, cacheControlFor(artifact));
3391
+ }
3330
3392
  uploaded += 1;
3331
3393
  onProgress?.({ phase: "upload", written: uploaded, total: uploadTotal });
3332
3394
  });
@@ -3642,6 +3704,7 @@ export {
3642
3704
  cacheControlFor,
3643
3705
  contentHash,
3644
3706
  processImage,
3707
+ processImageFromCache,
3645
3708
  buildPictureMarkup,
3646
3709
  compileTemplate,
3647
3710
  textContent,
@@ -21,8 +21,8 @@ import {
21
21
  serveEditorAsset,
22
22
  templateSnapshotIntegrityDiagnostic,
23
23
  templateSuffixConflictDiagnostic
24
- } from "./chunk-C3QPGXG5.js";
25
- import "./chunk-P6NDWIKK.js";
24
+ } from "./chunk-2OWUWOGB.js";
25
+ import "./chunk-AH2MVN2O.js";
26
26
  export {
27
27
  FileBrandingStore,
28
28
  InMemoryBrandingStore,
package/dist/index.d.ts CHANGED
@@ -448,6 +448,18 @@ interface CompileSiteOptions {
448
448
  readonly imageEncoder?: ImageEncoder;
449
449
  /** Max images encoded in parallel *site-wide* (default {@link DEFAULT_IMAGE_CONCURRENCY}). */
450
450
  readonly imageConcurrency?: number;
451
+ /**
452
+ * The variant cache (DESIGN §8/§11): facts about already-published images keyed by the
453
+ * original's content hash. An image whose hash is here skips the (CPU-heavy) re-encode, its
454
+ * variants are kept (as *present* artifacts) instead of re-uploaded. Omit for a full encode.
455
+ */
456
+ readonly mediaCache?: ReadonlyMap<string, CachedImage>;
457
+ /**
458
+ * Reports each processed image's {@link CachedImage} facts, whether freshly encoded or read
459
+ * from {@link mediaCache}, keyed by content hash, so a host can persist the manifest for the
460
+ * next publish. Side-effect-only; never changes the output (like {@link onProgress}).
461
+ */
462
+ readonly onMediaEntry?: (hash: string, cached: CachedImage) => void;
451
463
  /**
452
464
  * Resolve an author's stored `user` handle to its current display name (DESIGN
453
465
  * §6.11). Host-injected (the engine can't read the user store); without it,
@@ -473,6 +485,13 @@ interface Artifact {
473
485
  * (content-hashed) asset sets it to immutable. Only the publish sink reads it.
474
486
  */
475
487
  readonly cacheControl?: string;
488
+ /**
489
+ * When true, this artifact is **already published** at its (content-hashed) path and its
490
+ * bytes are unchanged, a variant-cache hit (DESIGN §8/§11). The publish keeps the path in
491
+ * its written set (so the orphan sweep does not delete it) but does **not** re-upload it,
492
+ * and `contents` is empty. Absent/false means a normal artifact to write.
493
+ */
494
+ readonly present?: boolean;
476
495
  }
477
496
  /**
478
497
  * Compute what a publish *will* produce (DESIGN §11) without encoding or writing anything:
@@ -575,6 +594,27 @@ interface ImageInfo {
575
594
  readonly fallbackSrc: string;
576
595
  readonly blurDataUri?: string;
577
596
  }
597
+ /** One produced variant's identity, the format + pixel width whose URL is derived
598
+ * from the original's content hash. The bytes are not part of it (they live at the
599
+ * derived path); this is what the variant cache stores. */
600
+ interface VariantSpec {
601
+ readonly format: ImageFormat;
602
+ readonly width: number;
603
+ }
604
+ /**
605
+ * The cacheable facts about one processed image (the publish variant cache, DESIGN §8/§11):
606
+ * everything needed to rebuild its {@link ImageInfo} and variant artifact paths *without*
607
+ * re-running the (CPU-heavy) encode. Keyed by the original's content hash, so an unchanged
608
+ * image reuses its already-published variants instead of encoding again. Holds no bytes,
609
+ * the variant bytes are already at their content-hashed paths in the published site.
610
+ */
611
+ interface CachedImage {
612
+ readonly sourceWidth: number;
613
+ readonly sourceHeight: number;
614
+ /** The variants that were produced, in publish order (width ascending). */
615
+ readonly variants: readonly VariantSpec[];
616
+ readonly blurDataUri?: string;
617
+ }
578
618
  /**
579
619
  * Per-item media lookup the compiler consults: a processed image by its asset
580
620
  * reference, or the published URL of a copied file. Built by the orchestrator.
@@ -586,15 +626,29 @@ interface MediaResolver {
586
626
  /** A small, fast, non-cryptographic content hash (FNV-1a) for cache-busting names. */
587
627
  declare function contentHash(bytes: Uint8Array): string;
588
628
  /**
589
- * Encode one image into variants and compute its {@link ImageInfo} plus the
590
- * binary artifacts to publish. Variant filenames are content-hashed so they
591
- * cache-bust for free (DESIGN §8). `assetPath` is the published-relative path of
592
- * the original, e.g. "blog/assets/hero.jpg".
629
+ * Encode one image into variants and compute its {@link ImageInfo}, the binary artifacts to
630
+ * publish, and the {@link CachedImage} facts a host can cache so the next publish of the same
631
+ * bytes skips this (CPU-heavy) encode. Variant filenames are content-hashed so they cache-bust
632
+ * for free (DESIGN §8). `assetPath` is the published-relative path of the original, e.g.
633
+ * "blog/assets/hero.jpg".
593
634
  */
594
635
  declare function processImage(input: Uint8Array, assetPath: string, encoder: ImageEncoder): Promise<{
595
636
  readonly artifacts: readonly Artifact[];
596
637
  readonly info: ImageInfo;
638
+ readonly cached: CachedImage;
597
639
  }>;
640
+ /**
641
+ * Rebuild an image's {@link ImageInfo} and **present** variant artifacts from a
642
+ * {@link CachedImage} (a variant-cache hit, DESIGN §8/§11), without encoding. `hash` is the
643
+ * original's content hash (the cache key); the output is byte-identical to what
644
+ * {@link processImage} produced for the same bytes, because both go through
645
+ * {@link buildImageOutput}. The artifacts are *present* (already published), so the publish
646
+ * keeps their paths but does not re-upload them.
647
+ */
648
+ declare function processImageFromCache(assetPath: string, hash: string, cached: CachedImage): {
649
+ readonly artifacts: readonly Artifact[];
650
+ readonly info: ImageInfo;
651
+ };
598
652
  /**
599
653
  * Build the `<picture>` markup for an image (DESIGN §8). `extraAttrs` carries the
600
654
  * resolved attributes from the original `<img>` (alt, class, …) onto the fallback.
@@ -1970,4 +2024,4 @@ declare function createDiagnosticRegistry(): DiagnosticRegistry;
1970
2024
 
1971
2025
  declare const workingStoreRoundTripDiagnostic: Diagnostic;
1972
2026
 
1973
- export { type Artifact, type ArtifactSink, type AuthEndpoints, type AuthResult, type AuthorDirectory, type AuthorEntry, type AuthorOption, type AuthorRef, type AuthoringReference, type BlobStore, type BoundItem, CACHE_IMMUTABLE, CACHE_REVALIDATE, type ChangePasswordRequest, type ChangePasswordSuccess, type CollectionConfig, type CollectionQuery, type CompileInput, type CompilePageOptions, type CompileSiteOptions, type CompiledPage, type ComponentMap, type ConditionalBlobStore, type ContentIndex, type ContentItem, ContentParseError, type ContentSource, type CreateTokenSuccess, type CreateUserRequest, DEFAULT_DIRS, DOCUMENT_SHELL, type DerivedField, type DiagnoseDeps, type Severity as DiagnoseSeverity, type Source as DiagnoseSource, type Diagnostic$1 as Diagnostic, type Diagnostic as DiagnosticCheck, type DiagnosticRegistry, type DirEntry, type DirNode, type EncodeRequest, type EncodedImage, type EncodedVariant, type EntryKind, FIELD_TYPES, type FieldPrimitive, type FieldRecord, type FieldType, type FieldTypeDef, type FieldValue, type Finding, type IdentityProvider, type ImageEncoder, type ImageFormat, type ImageInfo, InMemoryArtifactSink, InMemoryBlobStore, InMemoryContentSource, IndexedStore, type ItemNode, type LengthConstraints, type LoginRequest, type LoginSuccess, type MediaResolver, type MigrationResolution, NotFoundError, type PageEntry, type PendingMigrationItem, type PendingMigrations, type PreBuildHook, type Principal, type ProgressReporter, type ProgressSummary, type PublishOptions, type PublishPlan, type PublishProgress, type PublishResource, type PublishResult, type PublishSummary, type PurgeService, RESERVED_PREFIX, type ReconcileResult, type RedirectRule, type ReferenceContext, type ReferenceEntry, type ReferenceSection, type RefreshSuccess, type RenameResult, type Repair, type RepairArgs, type ResetPasswordRequest, type ResolveContext, type Role, type RssOptions, type SchemaDelta, type SchemaFieldRef, type Scope, type Severity$1 as Severity, type SiteConfig, type SortFile, type StampDecision, type StampRecord, type Storage, type TemplateAnalysis, type TemplateKind, type TokenContext, type TokenRef, type TreeNode, type TypeChange, type UpdateUserRequest, type UserAdminEndpoints, type UserSummary, type ValidationResult, type ValueKind, type VersionedIndex, type WorkingStore, analyzeTemplate, applyMigration, baseTemplateName, bestFitSnapshot, buildAuthoringReference, buildContentIndex, buildPictureMarkup, buildRedirects, buildResolveContext, buildRss, buildSitemap, cacheControlFor, canEdit, compilePage, compileSite, compileTemplate, computeSchemaDelta, contentHash, contentTypeFor, createDiagnosticRegistry, deriveFields, detectStamp, emptyIndex, escapeHtmlAttribute, escapeHtmlText, escapeJsonStringContent, findTokens, hasRole, humanize, inferControl, isConditionalBlobStore, isDestructiveTypeChange, isFieldType, isReservedVersionedPath, isVersionedTemplateName, joinAuthors, loadComponentScripts, loadComponentStyles, loadComponents, loadContentTree, loadDocumentShell, loadIndex, loadIndexVersioned, loadRedirects, loadSiteConfig, loadTemplate, nextVersionNumber, noopPurgeService, outputPathForItem, parseContentItem, parseRedirects, parseSortFile, pendingMigrations, planPublish, processImage, publishSite, reconcileIndex, renderAuthors, renderReferenceMarkdown, sanitizeUrl, saveIndex, saveIndexConditional, slugify, snapshotName, textContent, toAuthorRefs, urlForItem, validateSite, valueKindOf, versionNumber, wholeValueToken, workingStoreRoundTripDiagnostic };
2027
+ export { type Artifact, type ArtifactSink, type AuthEndpoints, type AuthResult, type AuthorDirectory, type AuthorEntry, type AuthorOption, type AuthorRef, type AuthoringReference, type BlobStore, type BoundItem, CACHE_IMMUTABLE, CACHE_REVALIDATE, type CachedImage, type ChangePasswordRequest, type ChangePasswordSuccess, type CollectionConfig, type CollectionQuery, type CompileInput, type CompilePageOptions, type CompileSiteOptions, type CompiledPage, type ComponentMap, type ConditionalBlobStore, type ContentIndex, type ContentItem, ContentParseError, type ContentSource, type CreateTokenSuccess, type CreateUserRequest, DEFAULT_DIRS, DOCUMENT_SHELL, type DerivedField, type DiagnoseDeps, type Severity as DiagnoseSeverity, type Source as DiagnoseSource, type Diagnostic$1 as Diagnostic, type Diagnostic as DiagnosticCheck, type DiagnosticRegistry, type DirEntry, type DirNode, type EncodeRequest, type EncodedImage, type EncodedVariant, type EntryKind, FIELD_TYPES, type FieldPrimitive, type FieldRecord, type FieldType, type FieldTypeDef, type FieldValue, type Finding, type IdentityProvider, type ImageEncoder, type ImageFormat, type ImageInfo, InMemoryArtifactSink, InMemoryBlobStore, InMemoryContentSource, IndexedStore, type ItemNode, type LengthConstraints, type LoginRequest, type LoginSuccess, type MediaResolver, type MigrationResolution, NotFoundError, type PageEntry, type PendingMigrationItem, type PendingMigrations, type PreBuildHook, type Principal, type ProgressReporter, type ProgressSummary, type PublishOptions, type PublishPlan, type PublishProgress, type PublishResource, type PublishResult, type PublishSummary, type PurgeService, RESERVED_PREFIX, type ReconcileResult, type RedirectRule, type ReferenceContext, type ReferenceEntry, type ReferenceSection, type RefreshSuccess, type RenameResult, type Repair, type RepairArgs, type ResetPasswordRequest, type ResolveContext, type Role, type RssOptions, type SchemaDelta, type SchemaFieldRef, type Scope, type Severity$1 as Severity, type SiteConfig, type SortFile, type StampDecision, type StampRecord, type Storage, type TemplateAnalysis, type TemplateKind, type TokenContext, type TokenRef, type TreeNode, type TypeChange, type UpdateUserRequest, type UserAdminEndpoints, type UserSummary, type ValidationResult, type ValueKind, type VariantSpec, type VersionedIndex, type WorkingStore, analyzeTemplate, applyMigration, baseTemplateName, bestFitSnapshot, buildAuthoringReference, buildContentIndex, buildPictureMarkup, buildRedirects, buildResolveContext, buildRss, buildSitemap, cacheControlFor, canEdit, compilePage, compileSite, compileTemplate, computeSchemaDelta, contentHash, contentTypeFor, createDiagnosticRegistry, deriveFields, detectStamp, emptyIndex, escapeHtmlAttribute, escapeHtmlText, escapeJsonStringContent, findTokens, hasRole, humanize, inferControl, isConditionalBlobStore, isDestructiveTypeChange, isFieldType, isReservedVersionedPath, isVersionedTemplateName, joinAuthors, loadComponentScripts, loadComponentStyles, loadComponents, loadContentTree, loadDocumentShell, loadIndex, loadIndexVersioned, loadRedirects, loadSiteConfig, loadTemplate, nextVersionNumber, noopPurgeService, outputPathForItem, parseContentItem, parseRedirects, parseSortFile, pendingMigrations, planPublish, processImage, processImageFromCache, publishSite, reconcileIndex, renderAuthors, renderReferenceMarkdown, sanitizeUrl, saveIndex, saveIndexConditional, slugify, snapshotName, textContent, toAuthorRefs, urlForItem, validateSite, valueKindOf, versionNumber, wholeValueToken, workingStoreRoundTripDiagnostic };
package/dist/index.js CHANGED
@@ -66,6 +66,7 @@ import {
66
66
  pendingMigrations,
67
67
  planPublish,
68
68
  processImage,
69
+ processImageFromCache,
69
70
  publishSite,
70
71
  reconcileIndex,
71
72
  renderAuthors,
@@ -83,7 +84,7 @@ import {
83
84
  versionNumber,
84
85
  wholeValueToken,
85
86
  workingStoreRoundTripDiagnostic
86
- } from "./chunk-P6NDWIKK.js";
87
+ } from "./chunk-AH2MVN2O.js";
87
88
  export {
88
89
  CACHE_IMMUTABLE,
89
90
  CACHE_REVALIDATE,
@@ -152,6 +153,7 @@ export {
152
153
  pendingMigrations,
153
154
  planPublish,
154
155
  processImage,
156
+ processImageFromCache,
155
157
  publishSite,
156
158
  reconcileIndex,
157
159
  renderAuthors,
package/dist/mcp.js CHANGED
@@ -3,8 +3,8 @@ import {
3
3
  MCP_TOOLS,
4
4
  callMcpTool,
5
5
  readMcpResource
6
- } from "./chunk-C3QPGXG5.js";
7
- import "./chunk-P6NDWIKK.js";
6
+ } from "./chunk-2OWUWOGB.js";
7
+ import "./chunk-AH2MVN2O.js";
8
8
 
9
9
  // ../../hosts/host-mcp/src/http.ts
10
10
  import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
@@ -56,7 +56,7 @@ function createMcpServer(deps, identity) {
56
56
  }
57
57
 
58
58
  // ../../hosts/host-mcp/src/http.ts
59
- var DEFAULT_VERSION = true ? "0.1.34" : "0.0.0-workspace";
59
+ var DEFAULT_VERSION = true ? "0.1.36" : "0.0.0-workspace";
60
60
  async function handleMcpRequest(deps, request, opts) {
61
61
  const server = createMcpServer(deps, {
62
62
  name: opts?.name ?? "nanoesis",
@@ -1,4 +1,4 @@
1
- import{ai as Ke,aG as F,ag as Te,aa as g,W as w,T as e,h as n,ab as Qe,q as a,Q as z,aH as h,y as j,aC as o,R as _,au as v,r as Ve,J as U,x as Ye,i as ze,aN as Ue,aA as c,aI as J,aw as X,ax as _e,Y as Xe,at as Ze,ac as ea}from"./index-CY5Kehuu.js";var aa=_('<p class="placeholder svelte-1lpfi31">Loading preview…</p>'),ta=_('<p class="error svelte-1lpfi31" role="alert"> </p>'),la=_("<option> </option>"),sa=_('<select class="svelte-1lpfi31"></select>'),ra=_('<li class="orphan svelte-1lpfi31"><div class="orphan-head svelte-1lpfi31"><code class="orphan-name svelte-1lpfi31"> </code> <span class="orphan-value svelte-1lpfi31"> </span></div> <div class="orphan-actions svelte-1lpfi31" role="radiogroup"><label class="svelte-1lpfi31"><input type="radio" value="drop"/> Drop</label> <label class="svelte-1lpfi31"><input type="radio" value="keep"/> Keep (unrendered)</label> <label class="svelte-1lpfi31"><input type="radio" value="rename"/> Rename to</label> <!></div></li>'),ia=_(`<section class="resolutions svelte-1lpfi31" aria-label="Orphan field resolutions"><h3 class="svelte-1lpfi31">Orphan fields</h3> <p class="hint svelte-1lpfi31">These fields exist in this item's JSON but the current template doesn't render them.
1
+ import{ai as Ke,aG as F,ag as Te,aa as g,W as w,T as e,h as n,ab as Qe,q as a,Q as z,aH as h,y as j,aC as o,R as _,au as v,r as Ve,J as U,x as Ye,i as ze,aN as Ue,aA as c,aI as J,aw as X,ax as _e,Y as Xe,at as Ze,ac as ea}from"./index-CMn2xISn.js";var aa=_('<p class="placeholder svelte-1lpfi31">Loading preview…</p>'),ta=_('<p class="error svelte-1lpfi31" role="alert"> </p>'),la=_("<option> </option>"),sa=_('<select class="svelte-1lpfi31"></select>'),ra=_('<li class="orphan svelte-1lpfi31"><div class="orphan-head svelte-1lpfi31"><code class="orphan-name svelte-1lpfi31"> </code> <span class="orphan-value svelte-1lpfi31"> </span></div> <div class="orphan-actions svelte-1lpfi31" role="radiogroup"><label class="svelte-1lpfi31"><input type="radio" value="drop"/> Drop</label> <label class="svelte-1lpfi31"><input type="radio" value="keep"/> Keep (unrendered)</label> <label class="svelte-1lpfi31"><input type="radio" value="rename"/> Rename to</label> <!></div></li>'),ia=_(`<section class="resolutions svelte-1lpfi31" aria-label="Orphan field resolutions"><h3 class="svelte-1lpfi31">Orphan fields</h3> <p class="hint svelte-1lpfi31">These fields exist in this item's JSON but the current template doesn't render them.
2
2
  Pick what to do with each.</p> <ul class="orphans svelte-1lpfi31"></ul></section>`),na=_('<p class="error svelte-1lpfi31" role="alert"> </p>'),oa=_('<div class="diff svelte-1lpfi31"><section class="pane svelte-1lpfi31" aria-label="Previous version (left)"><header class="pane-head svelte-1lpfi31"><!></header> <pre class="source svelte-1lpfi31"> </pre></section> <section class="pane svelte-1lpfi31" aria-label="Current template (right)"><header class="pane-head svelte-1lpfi31"> </header> <pre class="source svelte-1lpfi31"> </pre></section></div> <!> <!> <div class="commit-bar svelte-1lpfi31"><button type="button" class="primary svelte-1lpfi31"> </button></div>',1),va=_('<header class="detail-head svelte-1lpfi31"><button type="button" class="back svelte-1lpfi31">← Back</button> <h2 class="svelte-1lpfi31"> </h2></header> <!>',1),pa=_('<p class="error svelte-1lpfi31" role="alert"> </p>'),ca=_('<p class="placeholder svelte-1lpfi31">Loading…</p>'),fa=_(`<div class="empty svelte-1lpfi31"><h3 class="svelte-1lpfi31">All caught up</h3> <p>Every content item's fields match its bound template. Migrations show up here when a
3
3
  destructive template edit (or a manual hand-edit) leaves an item with orphan fields.</p></div>`),ua=_('<li class="item"><button class="item-row svelte-1lpfi31" type="button"><span class="item-path svelte-1lpfi31"><code> </code></span> <span class="item-summary svelte-1lpfi31"><!> <!> <!></span> <span class="open-icon svelte-1lpfi31">→</span></button></li>'),da=_('<section class="group svelte-1lpfi31"><h3 class="group-title svelte-1lpfi31"><code class="svelte-1lpfi31"> </code> <span class="count svelte-1lpfi31"> </span></h3> <ul class="items svelte-1lpfi31"></ul></section>'),ma=_('<header class="list-head svelte-1lpfi31"><h2>Migrations</h2> <button type="button" class="svelte-1lpfi31"> </button></header> <!>',1),_a=_('<div class="migrations svelte-1lpfi31"><!> <!></div>');function ga(Re,Le){Ke(Le,!0);let M=F(null),u=F(null),Z=F(!1),C=F(null),r=F(Te({})),he=F(Te({})),N=F(!1),W=F(null);g.ensureLoaded();async function Ce(s){v(M,s,!0),v(r,{},!0),v(he,{},!0),v(u,null),v(C,null),v(Z,!0);try{v(u,await ea(s),!0);const f={};for(const l of e(u).orphans){const d=Ee(l.name,e(u).currentTemplateFields);f[l.name]=d?{rename:d}:"keep"}v(r,f,!0)}catch(f){v(C,f instanceof Error?f.message:String(f),!0)}finally{v(Z,!1)}}function ge(){v(M,null),v(u,null),v(C,null)}function Ee(s,f){const l=s.toLowerCase();for(const d of f)if(d.toLowerCase().startsWith(l)||d.toLowerCase().endsWith(l))return d;return null}async function Se(){if(!(e(M)===null||e(u)===null)){v(N,!0),v(W,null);try{const s={drop:Object.entries(e(r)).filter(([,l])=>l==="drop").map(([l])=>l),keep:Object.entries(e(r)).filter(([,l])=>l==="keep").map(([l])=>l),rename:Object.fromEntries(Object.entries(e(r)).filter(([,l])=>typeof l=="object"&&l!==null&&"rename"in l).map(([l,d])=>[l,d.rename])),fill:{...e(he)}},f=await ze(e(M),s);g.refresh().catch(()=>{}),ge()}catch(s){v(W,s instanceof Error?s.message:String(s),!0)}finally{v(N,!1)}}}function Pe(s){return typeof s=="string"?s:JSON.stringify(s)}const qe=Ue(()=>g.list===null?[]:Object.entries(g.list.byTemplate).map(([s,f])=>({template:s,items:[...f].sort((l,d)=>l.path.localeCompare(d.path))})));var be=_a(),xe=a(be);{var Ae=s=>{var f=va(),l=z(f),d=a(l),ee=o(d,2),ae=a(ee),te=o(l,2);{var le=i=>{var m=aa();n(i,m)},se=i=>{var m=ta(),k=a(m);h(()=>c(k,e(C))),n(i,m)},re=i=>{var m=oa(),k=z(m),R=a(k),O=a(R),I=a(O);{var $=p=>{var x=J();h(()=>c(x,`Before — ${e(u).left.template??""}`)),n(p,x)},D=p=>{var x=J("Before — no snapshot available");n(p,x)};w(I,p=>{e(u).left?p($):p(D,-1)})}var ie=o(O,2),ne=a(ie),oe=o(R,2),G=a(oe),E=a(G),b=o(G,2),H=a(b),S=o(k,2);{var K=p=>{var x=ia(),P=o(a(x),4);U(P,21,()=>e(u).orphans,q=>q.name,(q,t)=>{var y=ra(),V=a(y),ye=a(V),We=a(ye),Ie=o(ye,2),$e=a(Ie),we=o(V,2),ke=a(we),fe=a(ke),Fe=o(ke,2),ue=a(Fe),je=o(Fe,2),de=a(je),De=o(je,2);{var Ge=A=>{var T=sa();U(T,20,()=>e(u).currentTemplateFields,B=>B,(B,me)=>{var Y=la(),He=a(Y),Oe={};h(()=>{c(He,me),Oe!==(Oe=me)&&(Y.value=(Y.__value=me)??"")}),n(B,Y)});var Me;Xe(T),h(()=>{Me!==(Me=e(r)[e(t).name].rename)&&(T.value=(T.__value=e(r)[e(t).name].rename)??"",Ze(T,e(r)[e(t).name].rename))}),j("change",T,B=>v(r,{...e(r),[e(t).name]:{rename:B.currentTarget.value}},!0)),n(A,T)};w(De,A=>{typeof e(r)[e(t).name]=="object"&&e(r)[e(t).name]!==null&&"rename"in e(r)[e(t).name]&&A(Ge)})}h(A=>{c(We,e(t).name),c($e,A),X(we,"aria-label",`Resolution for ${e(t).name}`),X(fe,"name",`d-${e(t).name}`),_e(fe,e(r)[e(t).name]==="drop"),X(ue,"name",`d-${e(t).name}`),_e(ue,e(r)[e(t).name]==="keep"),X(de,"name",`d-${e(t).name}`),_e(de,typeof e(r)[e(t).name]=="object"&&e(r)[e(t).name]!==null&&"rename"in e(r)[e(t).name])},[()=>Pe(e(t).value)]),j("change",fe,()=>v(r,{...e(r),[e(t).name]:"drop"},!0)),j("change",ue,()=>v(r,{...e(r),[e(t).name]:"keep"},!0)),j("change",de,()=>v(r,{...e(r),[e(t).name]:{rename:e(u).currentTemplateFields[0]??""}},!0)),n(q,y)}),n(p,x)};w(S,p=>{e(u).orphans.length>0&&p(K)})}var Q=o(S,2);{var ve=p=>{var x=na(),P=a(x);h(()=>c(P,e(W))),n(p,x)};w(Q,p=>{e(W)&&p(ve)})}var pe=o(Q,2),L=a(pe),ce=a(L);h(()=>{var p;c(ne,((p=e(u).left)==null?void 0:p.html)??"(no snapshot covers this item)"),c(E,`After — ${e(u).right.template??""}`),c(H,e(u).right.html),L.disabled=e(N)||e(u).orphans.length===0,c(ce,e(N)?"Migrating…":"Migrate item")}),j("click",L,Se),n(i,m)};w(te,i=>{e(Z)?i(le):e(C)?i(se,1):e(u)&&i(re,2)})}h(()=>c(ae,e(M))),j("click",d,ge),n(s,f)},Be=s=>{var f=ma(),l=z(f),d=o(a(l),2),ee=a(d),ae=o(l,2);{var te=i=>{var m=pa(),k=a(m);h(()=>c(k,g.error)),n(i,m)},le=i=>{var m=ca();n(i,m)},se=i=>{var m=fa();n(i,m)},re=i=>{var m=Ve(),k=z(m);U(k,17,()=>e(qe),R=>R.template,(R,O)=>{var I=da(),$=a(I),D=a($),ie=a(D),ne=o(D,2),oe=a(ne),G=o($,2);U(G,21,()=>e(O).items,E=>E.path,(E,b)=>{var H=ua(),S=a(H),K=a(S),Q=a(K),ve=a(Q),pe=o(K,2),L=a(pe);{var ce=t=>{var y=J();h(V=>c(y,`${e(b).orphanFields.length??""} orphan field${e(b).orphanFields.length===1?"":"s"}:
4
4
  ${V??""}`),[()=>e(b).orphanFields.join(", ")]),n(t,y)};w(L,t=>{e(b).orphanFields.length>0&&t(ce)})}var p=o(L,2);{var x=t=>{var y=J();h(()=>c(y,`· ${e(b).missingRequiredFields.length??""} missing required`)),n(t,y)};w(p,t=>{e(b).missingRequiredFields.length>0&&t(x)})}var P=o(p,2);{var q=t=>{var y=J();h(()=>c(y,`· best-fit: ${e(b).bestFitSnapshot??""}`)),n(t,y)};w(P,t=>{e(b).bestFitSnapshot&&t(q)})}h(()=>c(ve,e(b).path)),j("click",S,()=>Ce(e(b).path)),n(E,H)}),h(()=>{c(ie,e(O).template),c(oe,`${e(O).items.length??""} item${e(O).items.length===1?"":"s"}`)}),n(R,I)}),n(i,m)};w(ae,i=>{g.error?i(te):g.loading&&g.list===null?i(le,1):g.count===0?i(se,2):i(re,-1)})}h(()=>{d.disabled=g.loading,c(ee,g.loading?"Refreshing…":"Refresh")}),j("click",d,()=>g.refresh()),n(s,f)};w(xe,s=>{e(M)!==null?s(Ae):s(Be,-1)})}var Je=o(xe,2);{var Ne=s=>{};w(Je,s=>{!e(M)&&g.list===null&&s(Ne)})}n(Re,be),Qe()}Ye(["click","change"]);export{ga as default};