@canmi/web 2026.1005.2 → 2026.1005.3
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.
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Disclosure } from "./index.js";
|
|
2
2
|
//#region disclose/src/build.d.ts
|
|
3
3
|
/**
|
|
4
|
-
* What an app is made of, read from its `package.json` at build time.
|
|
4
|
+
* What an app is made of, read from its `package.json` at build time: only what it lists itself.
|
|
5
5
|
*
|
|
6
6
|
* A version is the installed package's, read from its own `package.json` beside the app rather than
|
|
7
7
|
* through its exports, which rarely offer it. See spec/web/disclose.md.
|
|
@@ -2,23 +2,28 @@ import { readFileSync } from "node:fs";
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
//#region disclose/src/build.ts
|
|
4
4
|
/**
|
|
5
|
-
* The packages whose version a
|
|
6
|
-
*
|
|
7
|
-
* Only an app that lists one in its own `package.json` gets its version; the others are absent.
|
|
5
|
+
* The packages whose version a component's own patch reads, by the name an app installs them as:
|
|
6
|
+
* used on some pages only, so the component that uses one discloses it. See spec/web/disclose.md.
|
|
8
7
|
*/
|
|
9
8
|
const VERSIONED = [
|
|
10
9
|
"@codemirror/view",
|
|
11
10
|
"@videojs/core",
|
|
12
|
-
"algoliasearch",
|
|
13
11
|
"d3-hierarchy"
|
|
14
12
|
];
|
|
13
|
+
/** The globals a package used on every page is disclosed as, given its installed version. */
|
|
14
|
+
const GLOBALS = {
|
|
15
|
+
algoliasearch: (version) => ({ "__algolia.algoliasearch.version": version }),
|
|
16
|
+
motion: () => ({ MotionIsMounted: true })
|
|
17
|
+
};
|
|
18
|
+
/** The address a package is named by in the page's data block, for a fingerprint that reads one. */
|
|
19
|
+
const REFERENCES = { "@tanstack/svelte-query": "https://tanstack.com/query" };
|
|
15
20
|
/** A dependency an app is deployed to Cloudflare Workers with. */
|
|
16
21
|
const WORKERS = ["@sveltejs/adapter-cloudflare", "wrangler"];
|
|
17
22
|
function readJson(path) {
|
|
18
23
|
return JSON.parse(readFileSync(path, "utf8"));
|
|
19
24
|
}
|
|
20
25
|
/**
|
|
21
|
-
* What an app is made of, read from its `package.json` at build time.
|
|
26
|
+
* What an app is made of, read from its `package.json` at build time: only what it lists itself.
|
|
22
27
|
*
|
|
23
28
|
* A version is the installed package's, read from its own `package.json` beside the app rather than
|
|
24
29
|
* through its exports, which rarely offer it. See spec/web/disclose.md.
|
|
@@ -26,13 +31,15 @@ function readJson(path) {
|
|
|
26
31
|
function disclosure(root) {
|
|
27
32
|
const manifest = readJson(join(root, "package.json"));
|
|
28
33
|
const names = /* @__PURE__ */ new Set([...Object.keys(manifest.dependencies ?? {}), ...Object.keys(manifest.devDependencies ?? {})]);
|
|
34
|
+
const installed = (name) => readJson(join(root, "node_modules", name, "package.json")).version;
|
|
29
35
|
const versions = {};
|
|
30
|
-
for (const name of VERSIONED)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
36
|
+
for (const name of VERSIONED) if (names.has(name)) versions[name] = installed(name);
|
|
37
|
+
const globals = {};
|
|
38
|
+
for (const [name, entries] of Object.entries(GLOBALS)) if (names.has(name)) Object.assign(globals, entries(installed(name)));
|
|
34
39
|
return {
|
|
35
40
|
versions,
|
|
41
|
+
globals,
|
|
42
|
+
references: Object.entries(REFERENCES).filter(([name]) => names.has(name)).map(([, address]) => address),
|
|
36
43
|
...WORKERS.some((name) => names.has(name)) ? { runtime: "Cloudflare Workers" } : {}
|
|
37
44
|
};
|
|
38
45
|
}
|
|
@@ -6,9 +6,21 @@
|
|
|
6
6
|
export interface Disclosure {
|
|
7
7
|
/** Installed versions, by package name, of the packages a fingerprint reads a version for. */
|
|
8
8
|
readonly versions: Readonly<Record<string, string>>;
|
|
9
|
+
/** Globals for what every page uses, by dotted path, set by `discloseGlobals`. */
|
|
10
|
+
readonly globals: Readonly<Record<string, unknown>>;
|
|
11
|
+
/** Addresses named in the page's data block, written by `disclosureHead`. */
|
|
12
|
+
readonly references: readonly string[];
|
|
9
13
|
/** Where the app runs, when a fingerprint names it: set for an app deployed to Workers. */
|
|
10
14
|
readonly runtime?: 'Cloudflare Workers';
|
|
11
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* The head an app's root layout writes with `{@html}`: the `runtime` meta, and a data block naming
|
|
18
|
+
* `references`, which the browser never runs and a profiler reads as script text. Empty when there
|
|
19
|
+
* is nothing to say. See spec/web/disclose.md.
|
|
20
|
+
*/
|
|
21
|
+
export declare function disclosureHead(disclosure: Disclosure | undefined): string;
|
|
22
|
+
/** Sets `globals` on `window`, from an app's root layout; nothing on the server. */
|
|
23
|
+
export declare function discloseGlobals(disclosure: Disclosure | undefined): void;
|
|
12
24
|
/**
|
|
13
25
|
* What the page is built with, said where a profiler reads it: each dotted path set on `window`,
|
|
14
26
|
* the objects on the way made as needed, nothing already there replaced, and an undefined value
|
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
//#region disclose/src/index.ts
|
|
2
2
|
/**
|
|
3
|
+
* The head an app's root layout writes with `{@html}`: the `runtime` meta, and a data block naming
|
|
4
|
+
* `references`, which the browser never runs and a profiler reads as script text. Empty when there
|
|
5
|
+
* is nothing to say. See spec/web/disclose.md.
|
|
6
|
+
*/
|
|
7
|
+
function disclosureHead(disclosure) {
|
|
8
|
+
if (!disclosure) return "";
|
|
9
|
+
const parts = [];
|
|
10
|
+
if (disclosure.runtime) parts.push(`<meta name="runtime" content="${disclosure.runtime}">`);
|
|
11
|
+
if (disclosure.references.length > 0) {
|
|
12
|
+
const data = JSON.stringify(disclosure.references).replaceAll("<", "\\u003c");
|
|
13
|
+
parts.push(`<script type="application/json" data-disclosure>${data}<\/script>`);
|
|
14
|
+
}
|
|
15
|
+
return parts.join("");
|
|
16
|
+
}
|
|
17
|
+
/** Sets `globals` on `window`, from an app's root layout; nothing on the server. */
|
|
18
|
+
function discloseGlobals(disclosure) {
|
|
19
|
+
if (disclosure) disclose(disclosure.globals);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
3
22
|
* What the page is built with, said where a profiler reads it: each dotted path set on `window`,
|
|
4
23
|
* the objects on the way made as needed, nothing already there replaced, and an undefined value
|
|
5
24
|
* skipped, so an entry the build did not find is simply absent. A patch for
|
|
@@ -22,4 +41,4 @@ function disclose(entries) {
|
|
|
22
41
|
}
|
|
23
42
|
}
|
|
24
43
|
//#endregion
|
|
25
|
-
export { disclose };
|
|
44
|
+
export { disclose, discloseGlobals, disclosureHead };
|