@canopy-iiif/app 0.7.0 → 0.7.2

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.
@@ -9,11 +9,13 @@ const {
9
9
  const mdx = require("./mdx");
10
10
  const iiif = require("./iiif");
11
11
  const pages = require("./pages");
12
- const search = require("../search/search");
13
12
  const searchBuild = require("./search");
14
13
  const { buildSearchIndex } = require("./search-index");
15
- const { generateFacets } = require("./facets");
16
14
  const runtimes = require("./runtimes");
15
+ const {
16
+ ensureSearchInitialized,
17
+ finalizeSearch,
18
+ } = require("./search-workflow");
17
19
  const { ensureStyles } = require("./styles");
18
20
  const { copyAssets } = require("./assets");
19
21
  const { logLine } = require("./log");
@@ -23,7 +25,7 @@ let iiifRecordsCache = [];
23
25
  let pageRecords = [];
24
26
 
25
27
  async function build(options = {}) {
26
- const skipIiif = !!options?.skipIiif;
28
+ const skipIiif = !!(options?.skipIiif || process.env.CANOPY_SKIP_IIIF === '1' || process.env.CANOPY_SKIP_IIIF === 'true');
27
29
  if (!fs.existsSync(CONTENT_DIR)) {
28
30
  console.error("No content directory found at", CONTENT_DIR);
29
31
  process.exit(1);
@@ -32,15 +34,17 @@ async function build(options = {}) {
32
34
  /**
33
35
  * Clean and prepare output directory
34
36
  */
35
- logLine("\n[1/6] Clean and prepare directories", "magenta", {
37
+ logLine("\nClean and prepare directories", "magenta", {
36
38
  bright: true,
39
+ underscore: true,
37
40
  });
41
+ logLine("• Reset MDX cache", "blue", { dim: true });
38
42
  mdx?.resetMdxCaches();
39
43
  if (!skipIiif) {
40
44
  await cleanDir(OUT_DIR);
41
- logLine("✓ Cleaned output directory\n", "cyan");
45
+ logLine(`• Cleaned output directory`, "blue", { dim: true });
42
46
  } else {
43
- logLine("• Incremental rebuild\n", "blue");
47
+ logLine("• Retaining cache (skipping IIIF rebuild)", "blue", { dim: true });
44
48
  }
45
49
 
46
50
  /**
@@ -48,19 +52,15 @@ async function build(options = {}) {
48
52
  * This includes building IIIF manifests for works and collections,
49
53
  * as well as collecting search records for works.
50
54
  */
51
- logLine("\n[2/6] Build IIIF Collection content", "magenta", {
55
+ logLine("\nBuild IIIF Collection content", "magenta", {
52
56
  bright: true,
57
+ underscore: true,
53
58
  });
54
- let searchRecords = [];
59
+ let iiifRecords = [];
55
60
  if (!skipIiif) {
56
61
  const CONFIG = await iiif.loadConfig();
57
- const res = await iiif.buildIiifCollectionPages(CONFIG);
58
- searchRecords = Array.isArray(res && res.searchRecords)
59
- ? res.searchRecords
60
- : [];
61
- iiifRecordsCache = searchRecords;
62
- } else {
63
- searchRecords = Array.isArray(iiifRecordsCache) ? iiifRecordsCache : [];
62
+ const results = await iiif.buildIiifCollectionPages(CONFIG);
63
+ iiifRecords = results?.iiifRecords;
64
64
  }
65
65
 
66
66
  /**
@@ -68,109 +68,53 @@ async function build(options = {}) {
68
68
  * This includes collecting page metadata for sitemap and search index,
69
69
  * as well as building all MDX pages to HTML.
70
70
  */
71
- logLine("\n[3/6] Build contextual content from Markdown pages", "magenta", {
71
+ logLine("\nBuild contextual content from Markdown pages", "magenta", {
72
72
  bright: true,
73
+ underscore: true,
73
74
  });
74
- // Collect pages metadata for sitemap injection
75
75
  pageRecords = await searchBuild.collectMdxPageRecords();
76
- // Build all MDX and assets
77
- logLine("\n• Building MDX pages...", "blue", { bright: true });
78
76
  await pages.buildContentTree(CONTENT_DIR, pageRecords);
79
- logLine("✓ MDX pages built\n", "green");
77
+ logLine("✓ MDX pages built", "green");
80
78
 
81
79
  /**
82
80
  * Build search index from IIIF and MDX records, then build or update
83
81
  * the search.html page and search runtime bundle.
84
82
  * This is done after all content is built so that the index is comprehensive.
85
83
  */
86
- logLine("\n[4/6] Create search indices", "magenta", { bright: true });
84
+ logLine("\nCreate search indices", "magenta", {
85
+ bright: true,
86
+ underscore: true,
87
+ });
87
88
  try {
88
- const searchPath = path.join(OUT_DIR, "search.html");
89
- const needCreatePage = !fs.existsSync(searchPath);
90
- if (needCreatePage) {
91
- try {
92
- logLine(" Preparing search (initial)...", "blue", { bright: true });
93
- } catch (_) {}
94
- // Build result item template (if present) up-front so it can be inlined
95
- try {
96
- await search.ensureResultTemplate();
97
- } catch (_) {}
98
- try {
99
- logLine(" - Writing empty index...", "blue");
100
- } catch (_) {}
101
- await search.writeSearchIndex([]);
102
- try {
103
- logLine(" - Writing runtime...", "blue");
104
- } catch (_) {}
105
- const timeoutMs = Number(process.env.CANOPY_BUNDLE_TIMEOUT || 10000);
106
- let timedOut = false;
107
- await runtimes.prepareSearchRuntime(
108
- process.env.CANOPY_BUNDLE_TIMEOUT || 10000,
109
- "initial"
110
- );
111
- try {
112
- logLine(" - Building search.html...", "blue");
113
- } catch (_) {}
114
- await search.buildSearchPage();
115
- logLine("✓ Created search page", "cyan");
116
- }
117
- // Always (re)write the search index combining IIIF and MDX pages
118
- const combined = await buildSearchIndex(searchRecords, pageRecords);
119
- // Build facets for IIIF works based on configured metadata labels
120
- await generateFacets(combined);
121
- try {
122
- logLine("• Writing search runtime (final)...", "blue", { bright: true });
123
- } catch (_) {}
124
- await runtimes.prepareSearchRuntime(
125
- process.env.CANOPY_BUNDLE_TIMEOUT || 10000,
126
- "final"
127
- );
128
- // Rebuild result item template after content processing to capture latest
129
- try {
130
- await search.ensureResultTemplate();
131
- } catch (_) {}
132
- // Rebuild search.html to inline the latest result template
133
- try {
134
- logLine("• Updating search.html...", "blue");
135
- } catch (_) {}
136
- await search.buildSearchPage();
137
- try {
138
- logLine("✓ Search page updated", "cyan");
139
- } catch (_) {}
140
- // Itemize counts by type for a clearer summary
141
- const counts = new Map();
142
- for (const r of combined) {
143
- const t = String((r && r.type) || "page").toLowerCase();
144
- counts.set(t, (counts.get(t) || 0) + 1);
145
- }
146
- const parts = Array.from(counts.entries())
147
- .sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))
148
- .map(([t, n]) => `${t}: ${n}`);
149
- const breakdown = parts.length ? `: ${parts.join(", ")}` : "";
150
- logLine(
151
- `✓ Search index: ${combined.length} total records${breakdown}`,
152
- "cyan"
153
- );
154
- } catch (_) {}
89
+ await ensureSearchInitialized();
90
+ const combined = await buildSearchIndex(iiifRecords, pageRecords);
91
+ await finalizeSearch(combined);
92
+ } catch (e) {
93
+ logLine(" Search index creation failed", "red", { bright: true });
94
+ logLine(" " + String(e), "red");
95
+ }
155
96
 
156
97
  /**
157
98
  * Prepare client runtimes (e.g. search) by bundling with esbuild.
158
99
  * This is done early so that MDX content can reference runtime assets if needed.
159
100
  */
160
- logLine("\n[5/6] Prepare client runtimes and stylesheets", "magenta", {
101
+ logLine("\nPrepare client runtimes and stylesheets", "magenta", {
161
102
  bright: true,
103
+ underscore: true,
162
104
  });
163
- await runtimes.prepareAllRuntimes();
164
- ensureDirSync(path.join(OUT_DIR, "styles"));
165
105
  if (!process.env.CANOPY_SKIP_STYLES) {
166
106
  await ensureStyles();
167
- logLine("✓ Wrote styles.css\n", "cyan");
107
+ logLine("✓ Wrote styles.css", "cyan");
168
108
  }
109
+ await runtimes.prepareAllRuntimes();
169
110
 
170
111
  /**
171
112
  * Copy static assets from the assets directory to the output directory.
172
113
  */
173
- logLine("\n[6/6] Copy static assets", "magenta", { bright: true });
114
+ logLine("\nCopy static assets", "magenta", {
115
+ bright: true,
116
+ underscore: true,
117
+ });
174
118
  await copyAssets();
175
119
  }
176
120