nodality 1.0.152 → 1.0.153
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/layout/animator.js +1 -1
- package/layout/audio.js +1 -1
- package/layout/audionew.js +1 -1
- package/layout/base-2.js +1 -1
- package/layout/base.js +1 -1
- package/layout/beta-desktop-bar.js +1 -1
- package/layout/beta-mobile-bar.js +1 -1
- package/layout/box.js +1 -1
- package/layout/button.js +1 -1
- package/layout/cards.js +1 -1
- package/layout/center.js +1 -1
- package/layout/checkbox.js +1 -1
- package/layout/circle.js +1 -1
- package/layout/clean-row.js +1 -1
- package/layout/code.js +1 -1
- package/layout/container.js +1 -1
- package/layout/custom.js +1 -1
- package/layout/div-image.js +1 -1
- package/layout/dropdown-2025.js +1 -1
- package/layout/dropdown.js +1 -1
- package/layout/empty-element.js +1 -1
- package/layout/external-stylesheet.js +1 -1
- package/layout/flex-card.js +1 -1
- package/layout/flex-grid.js +1 -1
- package/layout/flex-row.js +1 -1
- package/layout/footer.js +1 -1
- package/layout/form-components/custom.js +1 -1
- package/layout/form-components/data-list.js +1 -1
- package/layout/form-components/floating-input.js +1 -1
- package/layout/form-components/form-all.js +1 -1
- package/layout/form-components/form.js +1 -1
- package/layout/form-components/image-picker.js +1 -1
- package/layout/form-components/picker.js +1 -1
- package/layout/form-components/radio.js +1 -1
- package/layout/form-components/radiogroup.js +1 -1
- package/layout/form-components/range.js +1 -1
- package/layout/free.js +1 -1
- package/layout/grid-new.js +1 -1
- package/layout/grid-switcher.js +1 -1
- package/layout/grid.js +1 -1
- package/layout/group.js +1 -1
- package/layout/header.js +1 -1
- package/layout/horizontal-scroller.js +1 -1
- package/layout/image-old.js +1 -1
- package/layout/image.js +1 -1
- package/layout/index.js +1 -1
- package/layout/label.js +1 -1
- package/layout/link.js +1 -1
- package/layout/list-OLD.js +1 -1
- package/layout/list.js +1 -1
- package/layout/meta-adder.js +1 -1
- package/layout/modal-2025.js +1 -1
- package/layout/modernwrap.js +1 -1
- package/layout/multiswitcher.js +1 -1
- package/layout/multiswitcherBeta.js +1 -1
- package/layout/nav-bar.js +1 -1
- package/layout/nav-factor/custom-div.js +1 -1
- package/layout/navBar-OLD.js +1 -1
- package/layout/new-flat-adder.js +1 -1
- package/layout/new-nav-bar.js +1 -1
- package/layout/offset-container.js +1 -1
- package/layout/polygon.js +1 -1
- package/layout/prerender-site.js +85 -24
- package/layout/prerender.js +1 -1
- package/layout/progress.js +1 -1
- package/layout/row.js +1 -1
- package/layout/saved-new-nav-bar.js +1 -1
- package/layout/scroll-video.js +1 -1
- package/layout/side-bar.js +1 -1
- package/layout/side-nav-bar.js +1 -1
- package/layout/simple-bar.js +1 -1
- package/layout/slider-2025.js +1 -1
- package/layout/spacer.js +1 -1
- package/layout/stack.js +1 -1
- package/layout/styler.js +1 -1
- package/layout/svg.js +1 -1
- package/layout/switcher.js +1 -1
- package/layout/table.js +1 -1
- package/layout/text-field.js +1 -1
- package/layout/text.js +1 -1
- package/layout/ulist.js +1 -1
- package/layout/video.js +1 -1
- package/layout/without-new.js +1 -1
- package/layout/wrap.js +1 -1
- package/layout/zoom-card.js +1 -1
- package/lib/card-getter.js +1 -1
- package/lib/designer.js +1 -1
- package/lib/element-mapper.js +1 -1
- package/lib/keyframe-animation.js +1 -1
- package/lib/link-getter.js +1 -1
- package/lib/scroll-video.js +1 -1
- package/lib/stacker.js +1 -1
- package/lib/theme.js +1 -1
- package/lib/transform-anim.js +1 -1
- package/package.json +1 -1
package/layout/animator.js
CHANGED
package/layout/audio.js
CHANGED
package/layout/audionew.js
CHANGED
package/layout/base-2.js
CHANGED
package/layout/base.js
CHANGED
package/layout/box.js
CHANGED
package/layout/button.js
CHANGED
package/layout/cards.js
CHANGED
package/layout/center.js
CHANGED
package/layout/checkbox.js
CHANGED
package/layout/circle.js
CHANGED
package/layout/clean-row.js
CHANGED
package/layout/code.js
CHANGED
package/layout/container.js
CHANGED
package/layout/custom.js
CHANGED
package/layout/div-image.js
CHANGED
package/layout/dropdown-2025.js
CHANGED
package/layout/dropdown.js
CHANGED
package/layout/empty-element.js
CHANGED
package/layout/flex-card.js
CHANGED
package/layout/flex-grid.js
CHANGED
package/layout/flex-row.js
CHANGED
package/layout/footer.js
CHANGED
package/layout/free.js
CHANGED
package/layout/grid-new.js
CHANGED
package/layout/grid-switcher.js
CHANGED
package/layout/grid.js
CHANGED
package/layout/group.js
CHANGED
package/layout/header.js
CHANGED
package/layout/image-old.js
CHANGED
package/layout/image.js
CHANGED
package/layout/index.js
CHANGED
package/layout/label.js
CHANGED
package/layout/link.js
CHANGED
package/layout/list-OLD.js
CHANGED
package/layout/list.js
CHANGED
package/layout/meta-adder.js
CHANGED
package/layout/modal-2025.js
CHANGED
package/layout/modernwrap.js
CHANGED
package/layout/multiswitcher.js
CHANGED
package/layout/nav-bar.js
CHANGED
package/layout/navBar-OLD.js
CHANGED
package/layout/new-flat-adder.js
CHANGED
package/layout/new-nav-bar.js
CHANGED
package/layout/polygon.js
CHANGED
package/layout/prerender-site.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* nodality v1.0.
|
|
2
|
+
* nodality v1.0.153
|
|
3
3
|
* (c) 2026 Filip Vabrousek
|
|
4
4
|
* License: MIT
|
|
5
5
|
*/
|
|
@@ -96,11 +96,15 @@ const DEFAULT_ASSET_PREFIXES = [
|
|
|
96
96
|
* the template HTML + entry .js files. Output
|
|
97
97
|
* files are written under it (default locale
|
|
98
98
|
* at the root, others under /<locale>/).
|
|
99
|
-
* @param {string} config.defaultLocale
|
|
99
|
+
* @param {string} [config.defaultLocale] — The locale code whose pages live at the
|
|
100
100
|
* root of uploadDir. All other locales get a
|
|
101
|
-
* same-named subdir.
|
|
102
|
-
*
|
|
103
|
-
*
|
|
101
|
+
* same-named subdir. Optional — omit for a
|
|
102
|
+
* single-locale site with no locale tagging.
|
|
103
|
+
* @param {string[]} [config.locales] — All locale codes to render. Must include
|
|
104
|
+
* `defaultLocale` (if both given). Defaults
|
|
105
|
+
* to `[defaultLocale]` when only the default
|
|
106
|
+
* is set; defaults to a single untagged
|
|
107
|
+
* build when neither is set.
|
|
104
108
|
* @param {Array<{html:string,entry:string}>} config.pages
|
|
105
109
|
* — Each page's public HTML file (used as
|
|
106
110
|
* template) and the JS entry script that
|
|
@@ -121,19 +125,39 @@ export async function prerenderSite(config) {
|
|
|
121
125
|
|
|
122
126
|
// Child mode? Render exactly one locale and exit.
|
|
123
127
|
const childLocale = process.env[ENV_LOCALE];
|
|
124
|
-
if (childLocale) {
|
|
125
|
-
|
|
128
|
+
if (childLocale !== undefined) {
|
|
129
|
+
// The env var carries a string; map the literal "null" sentinel
|
|
130
|
+
// back to a real null so single-locale paths work in the child.
|
|
131
|
+
const locale = childLocale === "__none__" ? null : childLocale;
|
|
132
|
+
return runChild(config, locale);
|
|
126
133
|
}
|
|
127
134
|
|
|
128
|
-
//
|
|
129
|
-
//
|
|
135
|
+
// Single-locale (or unspecified) fast path: skip subprocess fanout.
|
|
136
|
+
// There's no ESM-cache-leak risk to guard against because only one
|
|
137
|
+
// locale will run in this process. Sitemap/hreflang are also no-ops
|
|
138
|
+
// when there's only one locale.
|
|
130
139
|
const startedAt = Date.now();
|
|
140
|
+
const isMulti = config.locales.length > 1;
|
|
141
|
+
|
|
142
|
+
if (!isMulti) {
|
|
143
|
+
const locale = config.locales[0];
|
|
144
|
+
console.log(`🌍 Prerendering ${config.pages.length} page(s)${locale ? ` (${locale})` : ""}…`);
|
|
145
|
+
console.log();
|
|
146
|
+
await runChild(config, locale);
|
|
147
|
+
const elapsed = ((Date.now() - startedAt) / 1000).toFixed(1);
|
|
148
|
+
console.log(`✅ Prerender done in ${elapsed}s — ${config.pages.length} page(s)`);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Multi-locale: fan out one subprocess per locale, sequentially
|
|
153
|
+
// (parallel would scramble console output and risk thrashing CPU).
|
|
131
154
|
console.log(`🌍 Prerendering ${config.locales.length} locales × ${config.pages.length} pages…`);
|
|
132
155
|
console.log();
|
|
133
156
|
|
|
134
157
|
let failures = 0;
|
|
135
158
|
for (const locale of config.locales) {
|
|
136
|
-
|
|
159
|
+
const label = locale ?? "(default)";
|
|
160
|
+
console.log(`── ${label} ${"─".repeat(60 - String(label).length - 3)}`);
|
|
137
161
|
const ok = await runLocaleSubprocess(locale);
|
|
138
162
|
if (!ok) failures++;
|
|
139
163
|
console.log();
|
|
@@ -153,16 +177,11 @@ export async function prerenderSite(config) {
|
|
|
153
177
|
}
|
|
154
178
|
|
|
155
179
|
function validateConfig(config) {
|
|
156
|
-
|
|
180
|
+
// Hard requirements — no sensible defaults possible.
|
|
181
|
+
const required = ["origin", "uploadDir", "pages"];
|
|
157
182
|
for (const k of required) {
|
|
158
183
|
if (!config[k]) throw new Error(`prerenderSite: config.${k} is required`);
|
|
159
184
|
}
|
|
160
|
-
if (!Array.isArray(config.locales) || config.locales.length === 0) {
|
|
161
|
-
throw new Error("prerenderSite: config.locales must be a non-empty array");
|
|
162
|
-
}
|
|
163
|
-
if (!config.locales.includes(config.defaultLocale)) {
|
|
164
|
-
throw new Error(`prerenderSite: config.defaultLocale "${config.defaultLocale}" not in config.locales`);
|
|
165
|
-
}
|
|
166
185
|
if (!Array.isArray(config.pages) || config.pages.length === 0) {
|
|
167
186
|
throw new Error("prerenderSite: config.pages must be a non-empty array");
|
|
168
187
|
}
|
|
@@ -171,6 +190,32 @@ function validateConfig(config) {
|
|
|
171
190
|
throw new Error("prerenderSite: each page needs { html, entry }");
|
|
172
191
|
}
|
|
173
192
|
}
|
|
193
|
+
|
|
194
|
+
// Soft defaults for the locale config — a single-locale site
|
|
195
|
+
// doesn't need to declare anything beyond the implicit "default".
|
|
196
|
+
// We mutate config here so the rest of the file can assume both
|
|
197
|
+
// keys are populated.
|
|
198
|
+
if (!config.defaultLocale && !config.locales) {
|
|
199
|
+
// Fully unspecified — single-locale build, no locale tagging.
|
|
200
|
+
// Use a sentinel `null` so subsequent code can skip <html lang>,
|
|
201
|
+
// hreflang, and localStorage injection.
|
|
202
|
+
config.defaultLocale = null;
|
|
203
|
+
config.locales = [null];
|
|
204
|
+
} else if (!config.locales) {
|
|
205
|
+
// Default declared but no list given — single-locale build at
|
|
206
|
+
// the root with that default locale's <html lang>.
|
|
207
|
+
config.locales = [config.defaultLocale];
|
|
208
|
+
} else if (!Array.isArray(config.locales) || config.locales.length === 0) {
|
|
209
|
+
throw new Error("prerenderSite: config.locales must be a non-empty array");
|
|
210
|
+
} else if (!config.defaultLocale) {
|
|
211
|
+
// Locales given but no default — assume the first entry is the
|
|
212
|
+
// one whose pages live at the root.
|
|
213
|
+
config.defaultLocale = config.locales[0];
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (config.defaultLocale && !config.locales.includes(config.defaultLocale)) {
|
|
217
|
+
throw new Error(`prerenderSite: config.defaultLocale "${config.defaultLocale}" not in config.locales`);
|
|
218
|
+
}
|
|
174
219
|
}
|
|
175
220
|
|
|
176
221
|
/**
|
|
@@ -188,9 +233,12 @@ function runLocaleSubprocess(locale) {
|
|
|
188
233
|
resolve(false);
|
|
189
234
|
return;
|
|
190
235
|
}
|
|
236
|
+
// Encode null locale as a sentinel string so it survives the env
|
|
237
|
+
// round-trip (env vars are always strings).
|
|
238
|
+
const localeStr = locale === null ? "__none__" : locale;
|
|
191
239
|
const child = spawn(process.execPath, [entry], {
|
|
192
240
|
cwd: process.cwd(),
|
|
193
|
-
env: { ...process.env, [ENV_LOCALE]:
|
|
241
|
+
env: { ...process.env, [ENV_LOCALE]: localeStr },
|
|
194
242
|
stdio: "inherit",
|
|
195
243
|
});
|
|
196
244
|
child.on("exit", (code) => resolve(code === 0));
|
|
@@ -218,7 +266,9 @@ async function runChild(config, locale) {
|
|
|
218
266
|
localStorageKey = "h7lang",
|
|
219
267
|
} = config;
|
|
220
268
|
|
|
221
|
-
|
|
269
|
+
// A null locale (single-locale, untagged) always renders to the
|
|
270
|
+
// root. Any other locale goes to root only if it equals the default.
|
|
271
|
+
const isSubdir = locale !== null && locale !== defaultLocale;
|
|
222
272
|
const localeDir = isSubdir ? path.join(uploadDir, locale) : uploadDir;
|
|
223
273
|
await fs.mkdir(localeDir, { recursive: true });
|
|
224
274
|
|
|
@@ -255,17 +305,27 @@ async function runChild(config, locale) {
|
|
|
255
305
|
process.stdout.write(` ${page.html.padEnd(22)} `);
|
|
256
306
|
|
|
257
307
|
try {
|
|
308
|
+
// Build the prerender call. Locale-related options are
|
|
309
|
+
// skipped when this is a single-locale-untagged build
|
|
310
|
+
// (locale === null) so the static output has no <html lang>,
|
|
311
|
+
// no canonical, no hreflang, no localStorage seed. The
|
|
312
|
+
// consumer's site looks like a vanilla single-page build.
|
|
313
|
+
const isLocaleAware = locale !== null;
|
|
258
314
|
const result = await prerender({
|
|
259
315
|
template: tmplPath,
|
|
260
316
|
output: outPath,
|
|
261
317
|
mount,
|
|
262
|
-
locale,
|
|
318
|
+
locale: isLocaleAware ? locale : undefined,
|
|
263
319
|
localStorageKey,
|
|
264
320
|
viewport,
|
|
265
321
|
url: urlFor(config, locale, page.html),
|
|
266
|
-
htmlLang: locale,
|
|
267
|
-
canonical:
|
|
268
|
-
|
|
322
|
+
htmlLang: isLocaleAware ? locale : undefined,
|
|
323
|
+
canonical: isLocaleAware && config.locales.length > 1
|
|
324
|
+
? urlFor(config, locale, page.html)
|
|
325
|
+
: undefined,
|
|
326
|
+
alternates: isLocaleAware && config.locales.length > 1
|
|
327
|
+
? alternatesFor(config, page.html)
|
|
328
|
+
: undefined,
|
|
269
329
|
build: async () => {
|
|
270
330
|
const importUrl = `${pathToFileURL(entryPath).href}?t=${stamp}-${page.entry}`;
|
|
271
331
|
await import(importUrl);
|
|
@@ -331,7 +391,8 @@ async function buildCleanTemplate(htmlPath, isSubdir, mount) {
|
|
|
331
391
|
|
|
332
392
|
/** URL for a (locale, page) pair under this site's origin. */
|
|
333
393
|
function urlFor(config, locale, page) {
|
|
334
|
-
|
|
394
|
+
// Null locale (untagged) and the default locale both live at root.
|
|
395
|
+
const slash = (locale === null || locale === config.defaultLocale) ? "" : `${locale}/`;
|
|
335
396
|
const tail = page === "index.html" ? slash : `${slash}${page}`;
|
|
336
397
|
return `${config.origin}/${tail}`;
|
|
337
398
|
}
|
package/layout/prerender.js
CHANGED
package/layout/progress.js
CHANGED
package/layout/row.js
CHANGED
package/layout/scroll-video.js
CHANGED
package/layout/side-bar.js
CHANGED
package/layout/side-nav-bar.js
CHANGED
package/layout/simple-bar.js
CHANGED
package/layout/slider-2025.js
CHANGED
package/layout/spacer.js
CHANGED
package/layout/stack.js
CHANGED
package/layout/styler.js
CHANGED
package/layout/svg.js
CHANGED
package/layout/switcher.js
CHANGED
package/layout/table.js
CHANGED
package/layout/text-field.js
CHANGED
package/layout/text.js
CHANGED
package/layout/ulist.js
CHANGED
package/layout/video.js
CHANGED
package/layout/without-new.js
CHANGED
package/layout/wrap.js
CHANGED
package/layout/zoom-card.js
CHANGED
package/lib/card-getter.js
CHANGED
package/lib/designer.js
CHANGED
package/lib/element-mapper.js
CHANGED
package/lib/link-getter.js
CHANGED
package/lib/scroll-video.js
CHANGED
package/lib/stacker.js
CHANGED
package/lib/theme.js
CHANGED
package/lib/transform-anim.js
CHANGED