mnfst 0.5.203 → 0.5.205
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/manifest.appwrite.data.js +90 -40
- package/lib/manifest.data.js +95 -23
- package/lib/manifest.integrity.json +5 -5
- package/lib/manifest.js +51 -17
- package/lib/manifest.schema.json +14 -0
- package/lib/manifest.sw.js +1 -1
- package/lib/manifest.utilities.js +102 -37
- package/lib/manifest.utilities.node.mjs +226 -13
- package/package.json +4 -2
package/lib/manifest.js
CHANGED
|
@@ -187,6 +187,11 @@
|
|
|
187
187
|
// Configuration
|
|
188
188
|
const DEFAULT_VERSION = 'latest';
|
|
189
189
|
|
|
190
|
+
// The version the page booted with (data-version). Every later load —
|
|
191
|
+
// Manifest.loadPlugin(), usage sniffing — resolves against it, so a runtime
|
|
192
|
+
// load can't pull a second copy of the framework at another version.
|
|
193
|
+
let RESOLVED_VERSION = DEFAULT_VERSION;
|
|
194
|
+
|
|
190
195
|
// CDN fallback chain (first-party first). Each origin serves the npm scheme
|
|
191
196
|
// `<origin>/<pkg>@<version>/<path>`. Override order with `data-cdn`
|
|
192
197
|
// (comma-separated origins).
|
|
@@ -298,7 +303,7 @@
|
|
|
298
303
|
// candidate per CDN host, tried in order.
|
|
299
304
|
let _pluginBase = null;
|
|
300
305
|
function setPluginBase(b) { _pluginBase = b || null; }
|
|
301
|
-
function getPluginUrlCandidates(pluginName, version =
|
|
306
|
+
function getPluginUrlCandidates(pluginName, version = RESOLVED_VERSION) {
|
|
302
307
|
// Hyphenated API name → dotted file name (`appwrite-auth` → appwrite.auth).
|
|
303
308
|
const fileName = pluginName.replace(/-/g, '.');
|
|
304
309
|
if (_pluginBase) {
|
|
@@ -307,7 +312,7 @@
|
|
|
307
312
|
}
|
|
308
313
|
return CDN_HOSTS.map(h => `${getBaseUrl(version, h)}/${hostFile(h, `manifest.${fileName}.min.js`)}`);
|
|
309
314
|
}
|
|
310
|
-
function getPluginUrl(pluginName, version =
|
|
315
|
+
function getPluginUrl(pluginName, version = RESOLVED_VERSION) {
|
|
311
316
|
return getPluginUrlCandidates(pluginName, version)[0];
|
|
312
317
|
}
|
|
313
318
|
|
|
@@ -388,14 +393,8 @@
|
|
|
388
393
|
return false;
|
|
389
394
|
}
|
|
390
395
|
|
|
391
|
-
// One fetch per URL: concurrent callers share the first call's promise
|
|
392
|
-
const inflightScripts = new Map();
|
|
393
|
-
|
|
394
396
|
function injectScript(url) {
|
|
395
|
-
|
|
396
|
-
if (shared) return shared;
|
|
397
|
-
|
|
398
|
-
const promise = new Promise((resolve, reject) => {
|
|
397
|
+
return new Promise((resolve, reject) => {
|
|
399
398
|
// Same src already in the DOM (author tag, prerendered HTML, second loader run)
|
|
400
399
|
const existing = document.querySelector(`script[src="${url}"]`);
|
|
401
400
|
if (existing) {
|
|
@@ -418,16 +417,12 @@
|
|
|
418
417
|
script.onerror = () => { script.removeAttribute('data-mnfst-loading'); script.remove(); reject(new Error(`Failed to load ${url}`)); };
|
|
419
418
|
document.head.appendChild(script);
|
|
420
419
|
});
|
|
421
|
-
|
|
422
|
-
inflightScripts.set(url, promise);
|
|
423
|
-
promise.then(() => inflightScripts.delete(url), () => inflightScripts.delete(url)); // dedupe only while in flight
|
|
424
|
-
return promise;
|
|
425
420
|
}
|
|
426
421
|
|
|
427
422
|
// Load a plugin, falling through the CDN chain on error. A fallback insert
|
|
428
423
|
// lands after already-inserted scripts, so strict cross-plugin execution
|
|
429
424
|
// order is traded for availability in the (already degraded) fallback case.
|
|
430
|
-
async function
|
|
425
|
+
async function fetchPluginScript(pluginName, version) {
|
|
431
426
|
const urls = getPluginUrlCandidates(pluginName, version);
|
|
432
427
|
let lastErr = null;
|
|
433
428
|
for (const url of urls) {
|
|
@@ -441,6 +436,26 @@
|
|
|
441
436
|
throw lastErr || new Error(`Failed to load ${pluginName}`);
|
|
442
437
|
}
|
|
443
438
|
|
|
439
|
+
// One execution per plugin per page. injectScript dedupes by URL, which two
|
|
440
|
+
// versions of the same plugin slip past — and a second copy of a plugin that
|
|
441
|
+
// owns page-level state (utilities' style element and its order observer)
|
|
442
|
+
// fights the first. A failed load is forgotten so a retry can still run.
|
|
443
|
+
const pluginLoads = new Map();
|
|
444
|
+
|
|
445
|
+
async function addScript(pluginName, version = RESOLVED_VERSION) {
|
|
446
|
+
const prior = pluginLoads.get(pluginName);
|
|
447
|
+
if (prior) {
|
|
448
|
+
if (prior.version !== version) {
|
|
449
|
+
console.warn(`[Manifest Loader] ${pluginName} already loaded at ${prior.version} — ignoring request for ${version}`);
|
|
450
|
+
}
|
|
451
|
+
return prior.promise;
|
|
452
|
+
}
|
|
453
|
+
const promise = fetchPluginScript(pluginName, version);
|
|
454
|
+
pluginLoads.set(pluginName, { version, promise });
|
|
455
|
+
promise.catch(() => pluginLoads.delete(pluginName));
|
|
456
|
+
return promise;
|
|
457
|
+
}
|
|
458
|
+
|
|
444
459
|
// Resolve plugin dependencies (auto-inject required dependencies)
|
|
445
460
|
function resolveDependencies(pluginList) {
|
|
446
461
|
const resolved = [];
|
|
@@ -635,8 +650,26 @@
|
|
|
635
650
|
};
|
|
636
651
|
}
|
|
637
652
|
|
|
653
|
+
// A publish/render bake stamps `data-mnfst-utilities-complete` on its
|
|
654
|
+
// `<style data-mnfst-utilities>` sheet once it has verified every class
|
|
655
|
+
// scanned from the page's own HTML got a rule (Manifest's + the baked
|
|
656
|
+
// Tailwind pass — see compileUtilities in manifest.utilities.node.mjs).
|
|
657
|
+
// Only the inline `<style>` case is checked: it's synchronous, so this can
|
|
658
|
+
// run before deciding whether to fetch the Tailwind engine at all — a
|
|
659
|
+
// `<link>` sheet would need an async load first, so it's left alone
|
|
660
|
+
// (fail open: Tailwind still loads). No flag, no attribute, any read
|
|
661
|
+
// error → false, so this never skips loading the engine speculatively.
|
|
662
|
+
function staticUtilitiesFullyCovered() {
|
|
663
|
+
try {
|
|
664
|
+
const el = document.querySelector('style[data-mnfst-utilities][data-mnfst-utilities-complete]');
|
|
665
|
+
return !!el;
|
|
666
|
+
} catch (e) {
|
|
667
|
+
return false;
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
|
|
638
671
|
// Load custom Tailwind CDN script, falling through the CDN chain on error
|
|
639
|
-
async function loadTailwind(version =
|
|
672
|
+
async function loadTailwind(version = RESOLVED_VERSION) {
|
|
640
673
|
const urls = CDN_HOSTS.map(h => `${getBaseUrl(version, h)}/${hostFile(h, 'manifest.tailwind.min.js')}`);
|
|
641
674
|
let lastErr = null;
|
|
642
675
|
for (const url of urls) {
|
|
@@ -652,7 +685,7 @@
|
|
|
652
685
|
|
|
653
686
|
// Expose API
|
|
654
687
|
window.Manifest = {
|
|
655
|
-
loadPlugin: function (pluginName, version =
|
|
688
|
+
loadPlugin: function (pluginName, version = RESOLVED_VERSION) {
|
|
656
689
|
const allPlugins = [...AVAILABLE_PLUGINS, ...APPWRITE_PLUGINS, ...AUTHORING_PLUGINS, 'payments', 'chat', 'device'];
|
|
657
690
|
if (!allPlugins.includes(pluginName)) {
|
|
658
691
|
console.warn(`[Manifest Loader] Unknown plugin: ${pluginName}`);
|
|
@@ -780,6 +813,7 @@
|
|
|
780
813
|
|
|
781
814
|
// Parse config and load plugins
|
|
782
815
|
const config = parseDataAttributes();
|
|
816
|
+
if (config && config.version) RESOLVED_VERSION = config.version;
|
|
783
817
|
if (config && config.pluginBase) setPluginBase(config.pluginBase);
|
|
784
818
|
if (config && config.cdn) setCdnHosts(config.cdn);
|
|
785
819
|
armServiceWorker(config);
|
|
@@ -890,7 +924,7 @@
|
|
|
890
924
|
console.warn(`[Manifest Loader] Failed to load plugin ${pluginName}:`, error);
|
|
891
925
|
});
|
|
892
926
|
});
|
|
893
|
-
if (config.tailwind) {
|
|
927
|
+
if (config.tailwind && !staticUtilitiesFullyCovered()) {
|
|
894
928
|
pluginPromises.push(loadTailwind(config.version).catch(() => { }));
|
|
895
929
|
}
|
|
896
930
|
await Promise.all(pluginPromises);
|
package/lib/manifest.schema.json
CHANGED
|
@@ -144,6 +144,20 @@
|
|
|
144
144
|
{ "type": "array", "items": { "type": "string", "enum": ["user", "team"] } }
|
|
145
145
|
]
|
|
146
146
|
},
|
|
147
|
+
"scopeColumn": {
|
|
148
|
+
"description": "Column name(s) `scope` filters/writes on. Default teamId/userId. A string sets both; an object sets them independently.",
|
|
149
|
+
"oneOf": [
|
|
150
|
+
{ "type": "string" },
|
|
151
|
+
{
|
|
152
|
+
"type": "object",
|
|
153
|
+
"properties": {
|
|
154
|
+
"team": { "type": "string" },
|
|
155
|
+
"user": { "type": "string" }
|
|
156
|
+
},
|
|
157
|
+
"additionalProperties": false
|
|
158
|
+
}
|
|
159
|
+
]
|
|
160
|
+
},
|
|
147
161
|
"autoInjectUserId": { "type": "boolean" },
|
|
148
162
|
"autoInjectTeamId": { "type": "boolean" },
|
|
149
163
|
"queries": {
|
package/lib/manifest.sw.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
// Build stamps the published version here; unstamped (dev) falls back to the
|
|
18
18
|
// registration URL's `v`, then 'dev'.
|
|
19
|
-
const BUILD_VERSION = '0.5.
|
|
19
|
+
const BUILD_VERSION = '0.5.205';
|
|
20
20
|
const CACHE_PREFIX = 'mnfst-sw:';
|
|
21
21
|
const META_CACHE = CACHE_PREFIX + 'meta';
|
|
22
22
|
const SWR_CAP = 200;
|
|
@@ -558,8 +558,10 @@ class TailwindCompiler {
|
|
|
558
558
|
|
|
559
559
|
// Read any publish/render-provided static utilities sheet before the
|
|
560
560
|
// first compile — its classes are skipped rather than regenerated.
|
|
561
|
+
// Fails open (never "everything covered") until this resolves —
|
|
562
|
+
// compile()'s first run awaits it, capped at 2s (see static.js).
|
|
561
563
|
this.staticUtilitiesCoveredClasses = null;
|
|
562
|
-
this.detectStaticUtilitiesSheet();
|
|
564
|
+
this.staticUtilitiesReady = this.detectStaticUtilitiesSheet();
|
|
563
565
|
|
|
564
566
|
// Add critical styles IMMEDIATELY - don't wait for anything
|
|
565
567
|
this.addCriticalBlockingStylesSync();
|
|
@@ -1488,9 +1490,12 @@ TailwindCompiler.prototype.scanStaticClasses = async function () {
|
|
|
1488
1490
|
|
|
1489
1491
|
// Extract classes from HTML content
|
|
1490
1492
|
TailwindCompiler.prototype.extractClassesFromHTML = function (html, classSet) {
|
|
1491
|
-
//
|
|
1492
|
-
//
|
|
1493
|
-
|
|
1493
|
+
// Literal class="..."/class='...' only — lookbehind excludes `:class=`
|
|
1494
|
+
// (Alpine binding), whose "class=" substring would otherwise match and
|
|
1495
|
+
// truncate at the literal's first internal quote, leaking a stray '{'.
|
|
1496
|
+
// Whitespace-only split below keeps every token Tailwind would accept
|
|
1497
|
+
// (variants, arbitrary values, leading '-', '!'); only x-/$ tokens drop.
|
|
1498
|
+
const classRegex = /(?<![:\w])class=["']([^"']+)["']/g;
|
|
1494
1499
|
let match;
|
|
1495
1500
|
|
|
1496
1501
|
while ((match = classRegex.exec(html)) !== null) {
|
|
@@ -1701,8 +1706,11 @@ TailwindCompiler.prototype.fetchThemeContent = async function () {
|
|
|
1701
1706
|
TailwindCompiler.prototype.extractThemeVariables = function (cssText) {
|
|
1702
1707
|
const variables = new Map();
|
|
1703
1708
|
|
|
1704
|
-
// Extract ALL CSS custom properties from ANY declaration block
|
|
1705
|
-
|
|
1709
|
+
// Extract ALL CSS custom properties from ANY declaration block. Terminator
|
|
1710
|
+
// is a lookahead (`;` or `}`) rather than a consumed `;` so the last
|
|
1711
|
+
// declaration in a block still matches when the author omits the
|
|
1712
|
+
// trailing semicolon (valid CSS, e.g. `:root{--x:1rem}`).
|
|
1713
|
+
const varRegex = /--([\w-]+):\s*([^;}]+)(?=[;}])/g;
|
|
1706
1714
|
|
|
1707
1715
|
let varMatch;
|
|
1708
1716
|
while ((varMatch = varRegex.exec(cssText)) !== null) {
|
|
@@ -3180,6 +3188,11 @@ TailwindCompiler.prototype.compile = async function () {
|
|
|
3180
3188
|
if (!this.hasScannedStatic) {
|
|
3181
3189
|
await this.scanStaticClasses();
|
|
3182
3190
|
|
|
3191
|
+
// Wait for the static utilities sheet's covered-class read to
|
|
3192
|
+
// settle (capped at 2s in detectStaticUtilitiesSheet) so this
|
|
3193
|
+
// first compile decision isn't a guess — see static.js.
|
|
3194
|
+
if (this.staticUtilitiesReady) await this.staticUtilitiesReady;
|
|
3195
|
+
|
|
3183
3196
|
// Fetch CSS content once for initial compilation
|
|
3184
3197
|
const themeCss = await this.fetchThemeContent();
|
|
3185
3198
|
if (themeCss) {
|
|
@@ -3377,6 +3390,14 @@ TailwindCompiler.prototype.extractSelectorsFromCssText = function (cssText) {
|
|
|
3377
3390
|
const len = cssText.length;
|
|
3378
3391
|
let i = 0;
|
|
3379
3392
|
while (i < len) {
|
|
3393
|
+
// Skip inter-rule whitespace first — without this, whitespace before an
|
|
3394
|
+
// `@layer`/`@media` (e.g. after a preceding `@layer base, ...;` statement
|
|
3395
|
+
// or sibling rule) leaves `i` off the '@', so the block below never fires
|
|
3396
|
+
// and the whole nested block is swallowed whole as one bogus selector,
|
|
3397
|
+
// losing every class inside it (real Tailwind/compileUtilities output is
|
|
3398
|
+
// always `@layer theme {...}` followed by `@layer utilities {...}`).
|
|
3399
|
+
while (i < len && /\s/.test(cssText[i])) i++;
|
|
3400
|
+
if (i >= len) break;
|
|
3380
3401
|
if (cssText[i] === '/' && cssText[i + 1] === '*') {
|
|
3381
3402
|
const end = cssText.indexOf('*/', i + 2);
|
|
3382
3403
|
i = end === -1 ? len : end + 2;
|
|
@@ -3429,40 +3450,70 @@ TailwindCompiler.prototype.classNamesFromCssText = function (cssText) {
|
|
|
3429
3450
|
return classSet;
|
|
3430
3451
|
};
|
|
3431
3452
|
|
|
3432
|
-
//
|
|
3433
|
-
//
|
|
3434
|
-
// (cross-origin,
|
|
3435
|
-
//
|
|
3453
|
+
// Attempt a synchronous CSSOM read of the static link's rules. Returns a Set
|
|
3454
|
+
// of covered classes, or null when nothing could be read — a security error
|
|
3455
|
+
// (cross-origin), an exception, a missing sheet, or zero rules (the link
|
|
3456
|
+
// hasn't finished loading, or its sheet is genuinely empty). null is never
|
|
3457
|
+
// distinguished from "empty": both fail open in filterStaticallyCoveredClasses
|
|
3458
|
+
// / stripCoveredRulesFromCss, and neither is ever treated as "everything
|
|
3459
|
+
// covered".
|
|
3460
|
+
TailwindCompiler.prototype.readStaticUtilitiesRules = function (el) {
|
|
3461
|
+
try {
|
|
3462
|
+
const sheet = Array.from(document.styleSheets).find(s => s.ownerNode === el);
|
|
3463
|
+
const rules = sheet && sheet.cssRules;
|
|
3464
|
+
if (rules && rules.length > 0) {
|
|
3465
|
+
const cssText = Array.from(rules).map(r => r.cssText).join('\n');
|
|
3466
|
+
return this.classNamesFromCssText(cssText);
|
|
3467
|
+
}
|
|
3468
|
+
} catch (e) {
|
|
3469
|
+
// Cross-origin, or not yet parsed.
|
|
3470
|
+
}
|
|
3471
|
+
return null;
|
|
3472
|
+
};
|
|
3473
|
+
|
|
3474
|
+
// Read the static sheet's covered classes once per page load. `<style>` and
|
|
3475
|
+
// an already-loaded `<link>` resolve synchronously. A `<link>` that hasn't
|
|
3476
|
+
// finished loading (or whose sheet can't be read yet) is awaited via its
|
|
3477
|
+
// `load`/`error` event, capped at 2s, then re-read once more; the caller
|
|
3478
|
+
// (compile()'s first run) awaits the returned promise so the very first
|
|
3479
|
+
// compile decision sees an accurate covered set rather than a guess. Fails
|
|
3480
|
+
// open the whole time — staticUtilitiesCoveredClasses stays null (nothing
|
|
3481
|
+
// covered) until a read actually succeeds, never cached as "covered".
|
|
3436
3482
|
TailwindCompiler.prototype.detectStaticUtilitiesSheet = function () {
|
|
3437
3483
|
this.staticUtilitiesCoveredClasses = null;
|
|
3438
3484
|
const el = this.findStaticUtilitiesElement();
|
|
3439
|
-
if (!el) return;
|
|
3485
|
+
if (!el) return Promise.resolve();
|
|
3440
3486
|
|
|
3441
3487
|
if (el.tagName === 'STYLE') {
|
|
3442
3488
|
this.staticUtilitiesCoveredClasses = this.classNamesFromCssText(el.textContent || '');
|
|
3443
|
-
return;
|
|
3489
|
+
return Promise.resolve();
|
|
3444
3490
|
}
|
|
3445
3491
|
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
const cssText = Array.from(rules).map(r => r.cssText).join('\n');
|
|
3451
|
-
this.staticUtilitiesCoveredClasses = this.classNamesFromCssText(cssText);
|
|
3452
|
-
return;
|
|
3453
|
-
}
|
|
3454
|
-
} catch (e) {
|
|
3455
|
-
// Cross-origin (or not yet parsed) — fall through to fetch.
|
|
3492
|
+
const covered = this.readStaticUtilitiesRules(el);
|
|
3493
|
+
if (covered) {
|
|
3494
|
+
this.staticUtilitiesCoveredClasses = covered;
|
|
3495
|
+
return Promise.resolve();
|
|
3456
3496
|
}
|
|
3457
3497
|
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3498
|
+
return new Promise((resolve) => {
|
|
3499
|
+
let settled = false;
|
|
3500
|
+
const finish = () => {
|
|
3501
|
+
if (settled) return;
|
|
3502
|
+
settled = true;
|
|
3503
|
+
clearTimeout(timer);
|
|
3504
|
+
el.removeEventListener('load', onLoad);
|
|
3505
|
+
el.removeEventListener('error', onError);
|
|
3506
|
+
// staticUtilitiesCoveredClasses stays null (fail open) if this
|
|
3507
|
+
// still can't be read — e.g. a cross-origin sheet without CORS.
|
|
3508
|
+
this.staticUtilitiesCoveredClasses = this.readStaticUtilitiesRules(el);
|
|
3509
|
+
resolve();
|
|
3510
|
+
};
|
|
3511
|
+
const onLoad = () => finish();
|
|
3512
|
+
const onError = () => finish();
|
|
3513
|
+
const timer = setTimeout(finish, 2000);
|
|
3514
|
+
el.addEventListener('load', onLoad, { once: true });
|
|
3515
|
+
el.addEventListener('error', onError, { once: true });
|
|
3516
|
+
});
|
|
3466
3517
|
};
|
|
3467
3518
|
|
|
3468
3519
|
// Drop classes already covered by the static sheet before generating rules
|
|
@@ -3486,6 +3537,12 @@ TailwindCompiler.prototype.stripCoveredRulesFromCss = function (cssText) {
|
|
|
3486
3537
|
const len = text.length;
|
|
3487
3538
|
let i = 0;
|
|
3488
3539
|
while (i < len) {
|
|
3540
|
+
// Skip (but preserve) inter-rule whitespace before checking for an
|
|
3541
|
+
// at-rule — see extractSelectorsFromCssText for why this matters.
|
|
3542
|
+
const wsStart = i;
|
|
3543
|
+
while (i < len && /\s/.test(text[i])) i++;
|
|
3544
|
+
if (i > wsStart) out.push(text.slice(wsStart, i));
|
|
3545
|
+
if (i >= len) break;
|
|
3489
3546
|
if (text[i] === '/' && text[i + 1] === '*') {
|
|
3490
3547
|
const end = text.indexOf('*/', i + 2);
|
|
3491
3548
|
const stop = end === -1 ? len : end + 2;
|
|
@@ -3831,8 +3888,13 @@ function injectTailwindVariants() {
|
|
|
3831
3888
|
}
|
|
3832
3889
|
injectTailwindVariants();
|
|
3833
3890
|
|
|
3834
|
-
//
|
|
3835
|
-
|
|
3891
|
+
// One compiler per page: a second copy would own a rival #manifest-styles and
|
|
3892
|
+
// the two order observers would re-append their own style to <head> forever.
|
|
3893
|
+
// A compiler whose style element left the document is stale, so it is rebuilt.
|
|
3894
|
+
const existingCompiler = window.ManifestUtilities;
|
|
3895
|
+
const compiler = (existingCompiler && existingCompiler.styleElement && existingCompiler.styleElement.isConnected)
|
|
3896
|
+
? existingCompiler
|
|
3897
|
+
: new TailwindCompiler();
|
|
3836
3898
|
|
|
3837
3899
|
// Expose utilities compiler for optional integration
|
|
3838
3900
|
window.ManifestUtilities = compiler;
|
|
@@ -3856,11 +3918,14 @@ if ('PerformanceObserver' in window) {
|
|
|
3856
3918
|
}
|
|
3857
3919
|
|
|
3858
3920
|
// Recompile on DOMContentLoaded for late-added elements
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3921
|
+
if (!compiler.__mnfstDomReadyBound) {
|
|
3922
|
+
compiler.__mnfstDomReadyBound = true;
|
|
3923
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
3924
|
+
if (!compiler.usesStaticPrerenderUtilities && !compiler.isCompiling) {
|
|
3925
|
+
compiler.compile();
|
|
3926
|
+
}
|
|
3927
|
+
});
|
|
3928
|
+
}
|
|
3864
3929
|
|
|
3865
3930
|
|
|
3866
3931
|
|