jq79 0.7.4 → 0.7.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jq79",
3
- "version": "0.7.4",
3
+ "version": "0.7.5",
4
4
  "description": "Mini reactive component library: single-file .html components, Svelte-style setup scripts, fine-grained proxy reactivity. No compiler, no bundler, no dependencies — works from any static host.",
5
5
  "keywords": [
6
6
  "reactive",
package/src/jq79.ts CHANGED
@@ -3351,8 +3351,10 @@ const importResource = (url: string): Promise<any> =>
3351
3351
  // For the same reason a *root-absolute* specifier is resolved too, not passed
3352
3352
  // through: `/x.js` means the page's root to whoever wrote it, and the page is
3353
3353
  // the only base under which the two branches agree. Bare specifiers ("lodash")
3354
- // are the exception that stays untouched - they belong to the import map or
3355
- // the bundler, and resolving one would quietly turn it into a path.
3354
+ // are the exception that stays untouched here - they belong to the import map
3355
+ // or the bundler, and resolving one against a base would quietly turn it into
3356
+ // a path. A bare *.html* one still reaches the map: fetchComponent asks it,
3357
+ // since fetch() cannot (see resolveBare)
3356
3358
  //
3357
3359
  // The base is absolutized first, the way hotKey does and for the same reason:
3358
3360
  // the filename may itself be relative ("./card.html", from an import() in a
@@ -3902,7 +3904,32 @@ const warnIfStuck = (component: Component79, gates: Promise<void>[]) => {
3902
3904
  Promise.all(gates).then(() => clearTimeout(timer))
3903
3905
  }
3904
3906
 
3905
- const fetchComponent = async (url: string): Promise<Component79> => {
3907
+ // a bare specifier belongs to the import map, and native import() reads one -
3908
+ // fetch() never does, so `fetch("@app/card.html")` asks the page's directory
3909
+ // for a folder named "@app". A bare URL is resolved here through the same map,
3910
+ // with the function import() itself would use, so the component gets the URL
3911
+ // its own relative imports, its precompiled script and its HMR key resolve
3912
+ // against. That includes a relative path written without "./" ("views/x.html"):
3913
+ // it reaches the map too, and changes only if the map names it. One the map
3914
+ // does not name throws, and goes on unchanged, as it did before.
3915
+ //
3916
+ // The map is read as this module sees it: a `scopes` entry applies when it
3917
+ // covers jq79.js, not the component. Guarded because the CJS and classic-script
3918
+ // builds (jq79.cjs, jq79.global.js) have no import.meta, and there bare URLs go
3919
+ // to fetch() as they are
3920
+ const resolveBare = (url: string): string => {
3921
+ if (RESOLVABLE_SPECIFIER_RE.test(url)) return url
3922
+ const resolve = (import.meta as { resolve?: (spec: string) => string }).resolve
3923
+ if (typeof resolve !== "function") return url
3924
+ try {
3925
+ return resolve(url)
3926
+ } catch {
3927
+ return url
3928
+ }
3929
+ }
3930
+
3931
+ const fetchComponent = async (rawUrl: string): Promise<Component79> => {
3932
+ const url = resolveBare(rawUrl)
3906
3933
  // under safeEval()'s worker, the component's functions arrive beside it,
3907
3934
  // and both have to be in before anyone can render it
3908
3935
  const [text] = await Promise.all([