@vutex/vutex 0.0.14 → 0.0.17
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/licenses/NotoSansMono.OFL.md +93 -0
- package/licenses/NotoSerifSC.OFL.md +94 -0
- package/licenses/Tinos.OFL.md +93 -0
- package/locales/en-US/cli.json +5 -4
- package/package.json +8 -7
- package/readme.md +29 -3
- package/src/cli/commands/package.ts +41 -12
- package/src/cli/commands/render.ts +5 -1
- package/src/index.ts +3 -0
- package/src/node/load.ts +18 -22
- package/src/packages/builtin.ts +129 -0
- package/src/packages/lockfile.ts +33 -1
- package/src/packages/manager.ts +1125 -64
- package/src/packages/manifest.ts +45 -0
- package/src/packages/math_font.ts +63 -0
- package/src/packages/registry.ts +405 -0
- package/src/packages/template.ts +352 -0
- package/src/runtime.ts +387 -37
- package/src/types.ts +173 -15
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
|
|
3
|
+
import type { PackageSlot } from "../types.js";
|
|
4
|
+
|
|
5
|
+
export type BuiltinFile = {
|
|
6
|
+
/** Path relative to `projects/vutex.rs/fonts`. */
|
|
7
|
+
path: string;
|
|
8
|
+
digest: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type BuiltinPackage = {
|
|
12
|
+
id: string;
|
|
13
|
+
slot: PackageSlot;
|
|
14
|
+
version: string;
|
|
15
|
+
files: BuiltinFile[];
|
|
16
|
+
artifactHash?: string;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
function treeDigest(files: BuiltinFile[]): string | undefined {
|
|
20
|
+
if (files.length === 0) {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
const lines = [...files]
|
|
24
|
+
.sort((left, right) => left.path.localeCompare(right.path, "en"))
|
|
25
|
+
.map((file) => `${file.path}\u0000${file.digest}`)
|
|
26
|
+
.join("\n");
|
|
27
|
+
return `sha256:${createHash("sha256").update(lines).digest("hex")}`;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Built-in resource registry.
|
|
32
|
+
*
|
|
33
|
+
* Font digests are the SHA-256 of the bundled files under
|
|
34
|
+
* `projects/vutex.rs/fonts`. A test recomputes them so the registry cannot
|
|
35
|
+
* drift from the files shipped by the repository.
|
|
36
|
+
*/
|
|
37
|
+
const BUILTIN_SEEDS: Array<Pick<BuiltinPackage, "id" | "slot" | "version" | "files">> = [
|
|
38
|
+
{
|
|
39
|
+
id: "xits-math",
|
|
40
|
+
slot: "math-font",
|
|
41
|
+
version: "builtin",
|
|
42
|
+
files: [
|
|
43
|
+
{
|
|
44
|
+
path: "XITSMath-Regular.otf",
|
|
45
|
+
digest: "3025792adb0b7072ace08bf5726d341de32f2254612ddec6dd98271a8dd29689",
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
id: "latin-modern-math",
|
|
51
|
+
slot: "math-font",
|
|
52
|
+
version: "builtin",
|
|
53
|
+
files: [
|
|
54
|
+
{
|
|
55
|
+
path: "LatinModernMath-Regular.otf",
|
|
56
|
+
digest: "6075562b771f8b82f0c179e363389684f2dd09de30038269e2628e504bd7be0f",
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
id: "noto-serif-sc",
|
|
62
|
+
slot: "font",
|
|
63
|
+
version: "builtin",
|
|
64
|
+
files: [
|
|
65
|
+
{
|
|
66
|
+
path: "NotoSerifSC-Regular.ttf",
|
|
67
|
+
digest: "043a8c85f8ff69eaff7304f99e18f09e9207b5f409646e03774d95203a61407e",
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
path: "NotoSerifSC-Bold.ttf",
|
|
71
|
+
digest: "d0a964ff4d2c31d6b2f6bc7fd9ff03f8d780fb4ed9cba829fc08521bb2e579c8",
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
id: "noto-sans-mono",
|
|
77
|
+
slot: "font",
|
|
78
|
+
version: "builtin",
|
|
79
|
+
files: [
|
|
80
|
+
{
|
|
81
|
+
path: "NotoSansMono-Regular.ttf",
|
|
82
|
+
digest: "98bbd03bea509b41148f06d545e6522e2cdd63cd27ff68173e3fe6af6f7fcfd1",
|
|
83
|
+
},
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
id: "tinos",
|
|
88
|
+
slot: "font",
|
|
89
|
+
version: "builtin",
|
|
90
|
+
files: [
|
|
91
|
+
{
|
|
92
|
+
path: "Tinos-Regular.ttf",
|
|
93
|
+
digest: "3bb337e701eaee742ae90748f83e49e0c6a9427c361bde7fd89ea81b24895c8c",
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
path: "Tinos-Bold.ttf",
|
|
97
|
+
digest: "3a94ee4124abc908dc14f0f961f3653682ede1b6e1f9098d8dba4b90e1c2e3e9",
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
path: "Tinos-Italic.ttf",
|
|
101
|
+
digest: "23640368a2325ab8e5a272de59a16098050d3912997d7b031e00719651eaf6c4",
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
{ id: "baseline", slot: "theme", version: "builtin", files: [] },
|
|
106
|
+
{ id: "traditional", slot: "theme", version: "builtin", files: [] },
|
|
107
|
+
{ id: "editorial", slot: "theme", version: "builtin", files: [] },
|
|
108
|
+
{ id: "classic", slot: "theme", version: "builtin", files: [] },
|
|
109
|
+
{ id: "latex", slot: "profile", version: "builtin", files: [] },
|
|
110
|
+
{ id: "typst", slot: "profile", version: "builtin", files: [] },
|
|
111
|
+
{ id: "notedown", slot: "profile", version: "builtin", files: [] },
|
|
112
|
+
{ id: "markdown", slot: "profile", version: "builtin", files: [] },
|
|
113
|
+
{ id: "html", slot: "profile", version: "builtin", files: [] },
|
|
114
|
+
{ id: "docx", slot: "profile", version: "builtin", files: [] },
|
|
115
|
+
{ id: "epub", slot: "profile", version: "builtin", files: [] },
|
|
116
|
+
];
|
|
117
|
+
|
|
118
|
+
export const BUILTIN_PACKAGES: BuiltinPackage[] = BUILTIN_SEEDS.map((item) => ({
|
|
119
|
+
...item,
|
|
120
|
+
artifactHash: treeDigest(item.files),
|
|
121
|
+
}));
|
|
122
|
+
|
|
123
|
+
export function lookupBuiltin(id: string, slot: PackageSlot): BuiltinPackage | undefined {
|
|
124
|
+
return BUILTIN_PACKAGES.find((item) => item.id === id && item.slot === slot);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export function isBuiltinProfile(id: string): boolean {
|
|
128
|
+
return lookupBuiltin(id, "profile") !== undefined;
|
|
129
|
+
}
|
package/src/packages/lockfile.ts
CHANGED
|
@@ -4,10 +4,12 @@ import { join } from "node:path";
|
|
|
4
4
|
import TOML from "@iarna/toml";
|
|
5
5
|
|
|
6
6
|
export type LockedPackage = {
|
|
7
|
+
slot: string;
|
|
7
8
|
name: string;
|
|
8
9
|
version: string;
|
|
9
10
|
source: string;
|
|
10
11
|
contentHash: string;
|
|
12
|
+
artifactHash?: string;
|
|
11
13
|
dependencies: string[];
|
|
12
14
|
};
|
|
13
15
|
|
|
@@ -16,6 +18,21 @@ export type VuTeXLockfile = {
|
|
|
16
18
|
packages: LockedPackage[];
|
|
17
19
|
};
|
|
18
20
|
|
|
21
|
+
function canonicalPackage(item: LockedPackage): LockedPackage {
|
|
22
|
+
const canonical: LockedPackage = {
|
|
23
|
+
slot: item.slot,
|
|
24
|
+
name: item.name,
|
|
25
|
+
version: item.version,
|
|
26
|
+
source: item.source,
|
|
27
|
+
contentHash: item.contentHash,
|
|
28
|
+
dependencies: [...item.dependencies].sort(),
|
|
29
|
+
};
|
|
30
|
+
if (item.artifactHash !== undefined) {
|
|
31
|
+
canonical.artifactHash = item.artifactHash;
|
|
32
|
+
}
|
|
33
|
+
return canonical;
|
|
34
|
+
}
|
|
35
|
+
|
|
19
36
|
export async function readLockfile(projectRoot: string): Promise<VuTeXLockfile | null> {
|
|
20
37
|
const path = join(projectRoot, "vutex.lock");
|
|
21
38
|
try {
|
|
@@ -29,7 +46,22 @@ export async function readLockfile(projectRoot: string): Promise<VuTeXLockfile |
|
|
|
29
46
|
}
|
|
30
47
|
}
|
|
31
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Write the lockfile in canonical order.
|
|
51
|
+
*
|
|
52
|
+
* Package entries are sorted by slot then name and every field keeps a fixed
|
|
53
|
+
* position so that installing the same manifest twice produces byte-identical
|
|
54
|
+
* output.
|
|
55
|
+
*/
|
|
32
56
|
export async function writeLockfile(projectRoot: string, lockfile: VuTeXLockfile): Promise<void> {
|
|
33
57
|
const path = join(projectRoot, "vutex.lock");
|
|
34
|
-
|
|
58
|
+
const packages = lockfile.packages
|
|
59
|
+
.map(canonicalPackage)
|
|
60
|
+
.sort((left, right) =>
|
|
61
|
+
left.slot === right.slot
|
|
62
|
+
? left.name.localeCompare(right.name, "en")
|
|
63
|
+
: left.slot.localeCompare(right.slot, "en"),
|
|
64
|
+
);
|
|
65
|
+
const canonical: VuTeXLockfile = { version: lockfile.version, packages };
|
|
66
|
+
await writeFile(path, `${TOML.stringify(canonical)}\n`, "utf8");
|
|
35
67
|
}
|