@bookshop/hugo-engine 3.18.5 → 3.18.6-rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/engine.js CHANGED
@@ -26,6 +26,8 @@ const UNIFIED_LAYOUT = [
26
26
  `{{ else }}`,
27
27
  `{{ partial "bookshop" (slice .Params.bookshop_name .Params.component) }}`,
28
28
  `{{ end }}`,
29
+ `{{ else if .Params.bookshop_eval }}`,
30
+ `{{ partial "bookshop_eval_expr" . }}`,
29
31
  `{{ end }}`
30
32
  ].join('');
31
33
 
@@ -42,9 +44,12 @@ const ensureUnifiedLayoutInstalled = () => {
42
44
  * Build Hugo with retry logic using componentQuack for error recovery.
43
45
  * @param {Engine} engine - The engine instance for componentQuack access
44
46
  * @param {string} context - Description for logging (e.g., "rendering" or "batch rendering")
47
+ * @param {Object|null} contentFiles - The content files this build renders. Rewritten before
48
+ * each retry: componentQuack may stub out a template that didn't exist before, and pages
49
+ * don't depend on templates they failed to find, so the page must be invalidated directly.
45
50
  * @returns {Promise<string|null>} - The build error if unrecoverable, or null on success
46
51
  */
47
- const buildHugoWithRetry = async (engine, context = "rendering") => {
52
+ const buildHugoWithRetry = async (engine, context = "rendering", contentFiles = null) => {
48
53
  window.hugo_wasm_logging = [];
49
54
  let render_attempts = 1;
50
55
  let buildError = window.buildHugo();
@@ -55,6 +60,9 @@ const buildHugoWithRetry = async (engine, context = "rendering") => {
55
60
  break;
56
61
  }
57
62
  // Try render again with the problem template stubbed out
63
+ if (contentFiles) {
64
+ window.writeHugoFiles(JSON.stringify(contentFiles));
65
+ }
58
66
  window.hugo_wasm_logging = [];
59
67
  buildError = window.buildHugo();
60
68
  render_attempts += 1;
@@ -125,7 +133,11 @@ export class Engine {
125
133
  "layouts/partials/_bookshop/errors/err.html": (await import("../bookshop-hugo-templates/errors/err.html")).default,
126
134
  };
127
135
 
128
- templates["config.toml"] = "params.env_bookshop_live = true\nmarkup.goldmark.renderer.unsafe = true";
136
+ templates["config.toml"] = [
137
+ "params.env_bookshop_live = true",
138
+ "markup.goldmark.renderer.unsafe = true",
139
+ `disableKinds = ["taxonomy", "term", "RSS", "sitemap", "robotsTXT", "404"]`
140
+ ].join('\n');
129
141
 
130
142
  // When this script is run locally, the hugo wasm is loaded as binary rather than output as a file.
131
143
  if (compressedHugoWasm?.constructor === Uint8Array) {
@@ -266,7 +278,8 @@ export class Engine {
266
278
  meta.copyright ? `copyright = ${meta.copyright}` : "",
267
279
  meta.title ? `title = ${meta.title}` : "",
268
280
  "params.env_bookshop_live = true",
269
- "markup.goldmark.renderer.unsafe = true"
281
+ "markup.goldmark.renderer.unsafe = true",
282
+ `disableKinds = ["taxonomy", "term", "RSS", "sitemap", "robotsTXT", "404"]`
270
283
  ].join('\n')
271
284
  }));
272
285
  const err = window.initHugoConfig();
@@ -375,14 +388,17 @@ export class Engine {
375
388
 
376
389
  // If we have assigned a root scope we need to pass that in as the context
377
390
  if (props["."]) props = props["."];
378
- writeFiles[`content/${uuid}.md`] = JSON.stringify({
379
- bookshop_name: name,
380
- bookshop_type: componentType,
381
- component: props
382
- }, null, 2) + "\n";
391
+ const contentFiles = {
392
+ [`content/${uuid}.md`]: JSON.stringify({
393
+ bookshop_name: name,
394
+ bookshop_type: componentType,
395
+ component: props
396
+ }, null, 2) + "\n"
397
+ };
398
+ Object.assign(writeFiles, contentFiles);
383
399
  window.writeHugoFiles(JSON.stringify(writeFiles));
384
400
 
385
- const buildError = await buildHugoWithRetry(this, "rendering");
401
+ const buildError = await buildHugoWithRetry(this, "rendering", contentFiles);
386
402
  if (buildError) {
387
403
  console.error(buildError);
388
404
  return;
@@ -392,7 +408,7 @@ export class Engine {
392
408
  const output = window.readHugoFiles(JSON.stringify([outputFileName]));
393
409
 
394
410
  target.innerHTML = output[outputFileName];
395
- window.removeHugoFiles([outputFileName, `content/${uuid}.md`])
411
+ window.removeHugoFiles(JSON.stringify([outputFileName, `content/${uuid}.md`]))
396
412
  }
397
413
 
398
414
  async renderBatch(components, logger) {
@@ -435,17 +451,20 @@ export class Engine {
435
451
 
436
452
  if (componentData.length === 0) return;
437
453
 
438
- let writeFiles = {
454
+ const contentFiles = {
439
455
  "content/_index.md": JSON.stringify({
440
456
  batch_id: batchId,
441
457
  components: componentData.map(c => ({ name: c.name, type: c.type, props: c.props }))
442
- }, null, 2) + "\n",
458
+ }, null, 2) + "\n"
459
+ };
460
+ let writeFiles = {
461
+ ...contentFiles,
443
462
  ...ensureUnifiedLayoutInstalled()
444
463
  };
445
-
464
+
446
465
  window.writeHugoFiles(JSON.stringify(writeFiles));
447
-
448
- const buildError = await buildHugoWithRetry(this, "batch rendering");
466
+
467
+ const buildError = await buildHugoWithRetry(this, "batch rendering", contentFiles);
449
468
  if (buildError) {
450
469
  console.error(`Batch render error: ${buildError}`);
451
470
  verboseLog('[hugo-engine] Falling back to individual renders');
@@ -567,13 +586,20 @@ export class Engine {
567
586
  // This is the SLOW PATH - we're hitting Hugo WASM because no short-circuit worked
568
587
  verboseLog(`[hugo-engine] eval requires Hugo WASM: "${str.substring(0, 80)}${str.length > 80 ? '...' : ''}"`);
569
588
 
570
- // Reset the unified layout flag since we're about to overwrite the layout
571
- window.__bookshop_unified_layout_installed = false;
572
-
573
- window.writeHugoFiles(JSON.stringify({
574
- "layouts/index.html": eval_str,
575
- "content/_index.md": JSON.stringify({ props: props_obj, full_props: full_props }, null, 2)
576
- }));
589
+ // Evals run through a partial behind the unified layout, rather than
590
+ // a layout file of their own. Writing layouts/index.html here would
591
+ // shadow layouts/all.html for the home page and permanently break
592
+ // batch rendering. Repeated evals of the same expression skip the
593
+ // template write so Hugo doesn't take the template-changed path.
594
+ const writeFiles = {
595
+ "content/_index.md": JSON.stringify({ bookshop_eval: true, props: props_obj, full_props: full_props }, null, 2),
596
+ ...ensureUnifiedLayoutInstalled()
597
+ };
598
+ if (this.lastEvalTemplate !== eval_str) {
599
+ writeFiles["layouts/partials/bookshop_eval_expr.html"] = eval_str;
600
+ this.lastEvalTemplate = eval_str;
601
+ }
602
+ window.writeHugoFiles(JSON.stringify(writeFiles));
577
603
 
578
604
  const buildError = window.buildHugo();
579
605
  if (buildError) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bookshop/hugo-engine",
3
- "version": "3.18.5",
3
+ "version": "3.18.6-rc1",
4
4
  "description": "Bookshop frontend Hugo renderer",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -31,7 +31,7 @@
31
31
  "esbuild": "^0.19.3",
32
32
  "fflate": "^0.7.3",
33
33
  "liquidjs": "10.17.0",
34
- "@bookshop/helpers": "3.18.5"
34
+ "@bookshop/helpers": "3.18.6-rc1"
35
35
  },
36
36
  "engines": {
37
37
  "node": ">=14.16"