@webjsdev/server 0.8.62 → 0.8.64
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/index.d.ts +32 -3
- package/package.json +2 -2
- package/src/browser-entries.js +64 -0
- package/src/check/helpers.js +365 -0
- package/src/check/rules-actions.js +174 -0
- package/src/check/rules-components.js +275 -0
- package/src/check/rules-imports.js +166 -0
- package/src/check/rules-registry.js +128 -0
- package/src/check/rules-routing.js +224 -0
- package/src/check/rules-typescript.js +177 -0
- package/src/check/rules.js +127 -0
- package/src/check/runner-support.js +405 -0
- package/src/check/runner.js +113 -0
- package/src/check.js +4 -1774
- package/src/component-elision.js +1 -1
- package/src/dev/config.js +338 -0
- package/src/dev/handler.js +1372 -0
- package/src/dev/helpers.js +542 -0
- package/src/dev/serve.js +840 -0
- package/src/dev/server.js +322 -0
- package/src/dev-classify.js +174 -0
- package/src/dev-reload-worker.js +133 -7
- package/src/dev-styles.js +97 -0
- package/src/dev.js +22 -3077
- package/src/form-dispatch.js +12 -3
- package/src/importmap.js +6 -3
- package/src/listener-core.js +16 -2
- package/src/module-graph.js +112 -7
- package/src/rate-limit.js +50 -5
- package/src/router.js +11 -1
- package/src/ssr/client-router-flag.js +42 -0
- package/src/ssr/document.js +361 -0
- package/src/ssr/env-shim.js +51 -0
- package/src/ssr/escape.js +29 -0
- package/src/ssr/head.js +857 -0
- package/src/ssr/preloads.js +195 -0
- package/src/ssr/render.js +1481 -0
- package/src/ssr/responses.js +201 -0
- package/src/ssr.js +28 -2445
- package/src/vendor/audit.js +400 -0
- package/src/vendor/integrity.js +245 -0
- package/src/vendor/jspm.js +348 -0
- package/src/vendor/manifest.js +96 -0
- package/src/vendor/pins.js +892 -0
- package/src/vendor/providers.js +35 -0
- package/src/vendor/resolver.js +225 -0
- package/src/vendor/scanner.js +132 -0
- package/src/vendor.js +29 -2371
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stylesheet re-request for the in-place dev refresh (#1398), the BROWSER half.
|
|
3
|
+
* Kept as a standalone browser-safe module (no node imports) so the served
|
|
4
|
+
* reload client inlines the EXACT source a browser test drives, with no drift,
|
|
5
|
+
* the same pattern as `dev-overlay.js` (#264) and `dev-reload-worker.js` (#887).
|
|
6
|
+
*
|
|
7
|
+
* Why it has to exist at all. A swap never re-requests the page's stylesheets
|
|
8
|
+
* on its own: `mergeHead` preserves every stylesheet unconditionally (#936),
|
|
9
|
+
* `addNewHeadElements` is add-only, and the dev href carries no content hash
|
|
10
|
+
* (`asset()` is prod-only), so the link node is kept by identity and the browser
|
|
11
|
+
* never asks the server for it again. A full page reload used to do that
|
|
12
|
+
* asking, which is how `webjs.dev.regenerate` (#967) ever ran, since it rebuilds
|
|
13
|
+
* a stale build output like `public/tailwind.css` ON REQUEST. Without this, an
|
|
14
|
+
* edit that adds a utility class morphs in and the class has no backing rule
|
|
15
|
+
* until a manual reload. Every in-repo app is configured that way, and the plain
|
|
16
|
+
* `tailwindcss --watch` shape has the same problem.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Re-request every same-origin stylesheet under `root`, cache-busted.
|
|
21
|
+
*
|
|
22
|
+
* The replacement is inserted BESIDE the old link, and which of the two
|
|
23
|
+
* survives depends on how the request went. That asymmetry is the whole point
|
|
24
|
+
* and must not be collapsed into one shared handler:
|
|
25
|
+
*
|
|
26
|
+
* - On `load` the OLD link is dropped, so the page is never briefly unstyled.
|
|
27
|
+
* - On `error` the NEW link is dropped and the old one kept. A re-request can
|
|
28
|
+
* fail (the server is mid-restart, the file was renamed or deleted), and
|
|
29
|
+
* removing the last working sheet there would leave the page permanently
|
|
30
|
+
* unstyled, which is exactly the failure #936 and #1400 exist to prevent.
|
|
31
|
+
*
|
|
32
|
+
* Duplicates are collapsed to one link per IDENTITY, where the identity is
|
|
33
|
+
* every attribute except the href's query. The duplicate being collapsed is the
|
|
34
|
+
* one the head merge re-appends (the incoming bare-href link beside the busted
|
|
35
|
+
* one), so the head would otherwise gain a link on every refresh. Keying on the
|
|
36
|
+
* path alone would be wrong in the other direction: it would delete an author's
|
|
37
|
+
* second, legitimately distinct link to the same file, such as a `media="print"`
|
|
38
|
+
* sheet.
|
|
39
|
+
*
|
|
40
|
+
* @param {ParentNode} [root] where to scan, defaulting to the whole document.
|
|
41
|
+
* Injectable so a browser test can scope itself to its own container.
|
|
42
|
+
* @param {() => number} [now] cache-buster source, injectable for tests.
|
|
43
|
+
* @returns {Element[]} the replacement links, so a caller (a test) can await them.
|
|
44
|
+
*/
|
|
45
|
+
export function refreshStyles(root, now) {
|
|
46
|
+
const scope = root || (typeof document !== 'undefined' ? document : null);
|
|
47
|
+
if (!scope) return [];
|
|
48
|
+
const stamp = now || Date.now;
|
|
49
|
+
/** @type {Record<string, { el: Element, url: URL }>} */
|
|
50
|
+
const kept = Object.create(null);
|
|
51
|
+
const links = [].slice.call(scope.querySelectorAll('link[rel~="stylesheet"][href]'));
|
|
52
|
+
for (const el of links) {
|
|
53
|
+
let url;
|
|
54
|
+
try { url = new URL(el.getAttribute('href'), location.href); } catch (_) { continue; }
|
|
55
|
+
if (url.origin !== location.origin) continue;
|
|
56
|
+
const key = identityKey(el, url);
|
|
57
|
+
if (kept[key]) { if (el.parentNode) el.parentNode.removeChild(el); continue; }
|
|
58
|
+
kept[key] = { el, url };
|
|
59
|
+
}
|
|
60
|
+
const added = [];
|
|
61
|
+
for (const key of Object.keys(kept)) {
|
|
62
|
+
const old = kept[key].el;
|
|
63
|
+
const url = kept[key].url;
|
|
64
|
+
if (!old.parentNode) continue;
|
|
65
|
+
url.searchParams.set('__webjs_dev', String(stamp()));
|
|
66
|
+
const next = /** @type {Element} */ (old.cloneNode(false));
|
|
67
|
+
next.setAttribute('href', url.pathname + url.search);
|
|
68
|
+
next.addEventListener('load', function () {
|
|
69
|
+
if (old.parentNode) old.parentNode.removeChild(old);
|
|
70
|
+
});
|
|
71
|
+
next.addEventListener('error', function () {
|
|
72
|
+
// Keep the sheet that still works rather than the one that just failed.
|
|
73
|
+
if (next.parentNode) next.parentNode.removeChild(next);
|
|
74
|
+
});
|
|
75
|
+
old.parentNode.insertBefore(next, old.nextSibling);
|
|
76
|
+
added.push(next);
|
|
77
|
+
}
|
|
78
|
+
return added;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* A link's identity for de-duping: its path plus every attribute except `href`.
|
|
83
|
+
* JSON-encoded over a sorted list so no separator can collide with an attribute
|
|
84
|
+
* value.
|
|
85
|
+
* @param {Element} el
|
|
86
|
+
* @param {URL} url
|
|
87
|
+
*/
|
|
88
|
+
function identityKey(el, url) {
|
|
89
|
+
const parts = [];
|
|
90
|
+
const attrs = el.attributes;
|
|
91
|
+
for (let a = 0; a < attrs.length; a++) {
|
|
92
|
+
if (attrs[a].name === 'href') continue;
|
|
93
|
+
parts.push([attrs[a].name, attrs[a].value]);
|
|
94
|
+
}
|
|
95
|
+
parts.sort((x, y) => (x[0] < y[0] ? -1 : x[0] > y[0] ? 1 : 0));
|
|
96
|
+
return JSON.stringify([url.pathname, parts]);
|
|
97
|
+
}
|