@weapp-tailwindcss/lynx 0.4.3 → 0.5.0

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.
Files changed (36) hide show
  1. package/README.md +41 -3
  2. package/README.zh-CN.md +44 -6
  3. package/dist/decoder-data/AGENTS.md +31 -0
  4. package/dist/decoder-data/fixtures/selector-identifiers.json +159 -0
  5. package/dist/decoder-data/manifest.json +130 -0
  6. package/dist/decoder-data/patches/0001-decode-page-config-before-css.patch +33 -0
  7. package/dist/decoder-data/patches/0002-serialize-css-identifiers.patch +55 -0
  8. package/dist/decoder-data/rebuild/bootstrap-inputs.json +25 -0
  9. package/dist/decoder-data/rebuild/inputs.json +198 -0
  10. package/dist/decoder-data/vendor/.gitattributes +2 -0
  11. package/dist/decoder-data/vendor/README.md +11 -0
  12. package/dist/decoder-data/vendor/lepus.cjs.gz +0 -0
  13. package/dist/decoder-data/vendor/licenses/emsdk-upstream-emscripten-LICENSE.txt +102 -0
  14. package/dist/decoder-data/vendor/licenses/emsdk-upstream-emscripten-system-lib-compiler-rt-LICENSE.TXT.txt +311 -0
  15. package/dist/decoder-data/vendor/licenses/emsdk-upstream-emscripten-system-lib-libc-musl-COPYRIGHT.txt +193 -0
  16. package/dist/decoder-data/vendor/licenses/emsdk-upstream-emscripten-system-lib-libcxx-LICENSE.TXT.txt +311 -0
  17. package/dist/decoder-data/vendor/licenses/emsdk-upstream-emscripten-system-lib-libcxxabi-LICENSE.TXT.txt +311 -0
  18. package/dist/decoder-data/vendor/licenses/emsdk-upstream-emscripten-system-lib-libunwind-LICENSE.TXT.txt +311 -0
  19. package/dist/decoder-data/vendor/licenses/source-LICENSE.txt +203 -0
  20. package/dist/decoder-data/vendor/licenses/source-NOTICE.txt +4 -0
  21. package/dist/decoder-data/vendor/licenses/source-third_party-aes-LICENSE.txt +21 -0
  22. package/dist/decoder-data/vendor/licenses/source-third_party-double-conversion-LICENSE.txt +26 -0
  23. package/dist/decoder-data/vendor/licenses/source-third_party-jsoncpp-LICENSE.txt +55 -0
  24. package/dist/decoder-data/vendor/licenses/source-third_party-modp_b64-LICENSE.txt +33 -0
  25. package/dist/decoder-data/vendor/licenses/source-third_party-quickjs-LICENSE.txt +22 -0
  26. package/dist/decoder-data/vendor/licenses/source-third_party-quickjs-src-LICENSE.txt +202 -0
  27. package/dist/decoder-data/vendor/licenses/source-third_party-rapidjson-license.txt.txt +57 -0
  28. package/dist/decoder-data/vendor/reproducibility.json +63 -0
  29. package/dist/decoder.cjs +108 -0
  30. package/dist/decoder.d.ts +25 -0
  31. package/dist/decoder.js +101 -0
  32. package/dist/index.cjs +574 -8
  33. package/dist/index.d.ts +74 -4
  34. package/dist/index.js +572 -8
  35. package/dist/rolldown-runtime-CmQyd0Gu.cjs +27 -0
  36. package/package.json +17 -7
@@ -0,0 +1,63 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "verified": true,
4
+ "scope": "macOS arm64,同一固定 SDK;两次独立源码归档解压、生成、完整编译和链接;不声称跨操作系统或跨工具链字节可重复",
5
+ "coreInputsSha256": "5b51e443783b9fdbf76ff2909e956a5a37f33c8e628c4bd91b229341e002d91d",
6
+ "bootstrapInputsSha256": "f376a22909f457f83790ad1e4d897b9ef39f2811c0b0fd070475aa8082fadb59",
7
+ "runs": [
8
+ {
9
+ "id": "clean-source-1",
10
+ "schemaVersion": 1,
11
+ "sourceCommit": "3526f07a8cb25cfb2841736c76b54deadc7e6e46",
12
+ "compilerCommit": "bebaf7e50e31865b0724f17eaa52e161e2dfef5a",
13
+ "platform": "darwin",
14
+ "arch": "arm64",
15
+ "nodeVersion": "v24.18.0",
16
+ "sourceDateEpoch": "0",
17
+ "raw": {
18
+ "byteLength": 13254390,
19
+ "sha256": "013cedf5d7fe0db0103b74d2936fba072e0f5a89c0a715af77f30b1d0627878b"
20
+ },
21
+ "gzip": {
22
+ "byteLength": 2235071,
23
+ "sha256": "69e7b4cedc110e5ccdce3be24341cfb32ff67c171449b9fcc4c74515383d4b1a"
24
+ },
25
+ "matchesCommittedRaw": true,
26
+ "matchesCommittedGzip": true
27
+ },
28
+ {
29
+ "id": "clean-source-2",
30
+ "schemaVersion": 1,
31
+ "sourceCommit": "3526f07a8cb25cfb2841736c76b54deadc7e6e46",
32
+ "compilerCommit": "bebaf7e50e31865b0724f17eaa52e161e2dfef5a",
33
+ "platform": "darwin",
34
+ "arch": "arm64",
35
+ "nodeVersion": "v24.18.0",
36
+ "sourceDateEpoch": "0",
37
+ "semanticProbe": {
38
+ "bundleSha256": "0b751511fd435c1e54ef84ba932f3abe947d069dd91ea30b7bb165f4d80a6035",
39
+ "cssSha256": "9adde11b9a2d6744d5ff270ce6442f713d60a4316decec694565e55e7a386ebf",
40
+ "selectorRules": 17
41
+ },
42
+ "toolchain": {
43
+ "receipt": "releases-bebaf7e50e31865b0724f17eaa52e161e2dfef5a-64bit",
44
+ "emccVersion": "emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 4.0.22 (0f3d2e62bccf8e14497ff19e05a1202c51eb0c65)",
45
+ "emccSha256": "8aceac1889631c2902b2265c7991a18d187e3deec157e8194e489e0988a564d1",
46
+ "clangVersion": "clang version 22.0.0git (https:/github.com/llvm/llvm-project c7706d9472fe880ba1d3418919ad4185710c9559)",
47
+ "clangSha256": "0e966e8d4d52dd12e809f062667c50839173eab6a13ed4c10354604fd0bc0967",
48
+ "clangByteLength": 114441120,
49
+ "registeredClangDigest": true
50
+ },
51
+ "raw": {
52
+ "byteLength": 13254390,
53
+ "sha256": "013cedf5d7fe0db0103b74d2936fba072e0f5a89c0a715af77f30b1d0627878b"
54
+ },
55
+ "gzip": {
56
+ "byteLength": 2235071,
57
+ "sha256": "69e7b4cedc110e5ccdce3be24341cfb32ff67c171449b9fcc4c74515383d4b1a"
58
+ },
59
+ "matchesCommittedRaw": true,
60
+ "matchesCommittedGzip": true
61
+ }
62
+ ]
63
+ }
@@ -0,0 +1,108 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_rolldown_runtime = require("./rolldown-runtime-CmQyd0Gu.cjs");
3
+ let node_crypto = require("node:crypto");
4
+ let node_fs_promises = require("node:fs/promises");
5
+ node_fs_promises = require_rolldown_runtime.__toESM(node_fs_promises, 1);
6
+ let node_module = require("node:module");
7
+ let node_path = require("node:path");
8
+ node_path = require_rolldown_runtime.__toESM(node_path, 1);
9
+ let node_fs = require("node:fs");
10
+ let node_os = require("node:os");
11
+ node_os = require_rolldown_runtime.__toESM(node_os, 1);
12
+ let node_zlib = require("node:zlib");
13
+ // src/decoder.ts
14
+ const decoderDirectory = node_path.default.join(__dirname, "decoder-data");
15
+ let factoryCache;
16
+ function sha256(value) {
17
+ return (0, node_crypto.createHash)("sha256").update(value).digest("hex");
18
+ }
19
+ function readManifest(directory) {
20
+ const source = (0, node_fs.readFileSync)(node_path.default.join(directory, "manifest.json"), "utf8");
21
+ const manifest = JSON.parse(source);
22
+ if (manifest.schemaVersion !== 1 || manifest.version !== "0.0.53" || !/^[a-f0-9]{40}$/.test(manifest.sourceCommit) || manifest.inputs?.file !== "rebuild/inputs.json" || !/^[a-f0-9]{64}$/.test(manifest.inputs.sha256) || manifest.compressed.file !== "vendor/lepus.cjs.gz" || !manifest.patches.length || manifest.patches.some((patch) => !/^patches\/[a-z0-9-]+\.patch$/.test(patch.file))) throw new Error("Lynx decoder manifest 的固定来源或资源身份无效");
23
+ return {
24
+ source,
25
+ manifest
26
+ };
27
+ }
28
+ /** 身份覆盖构建来源、补丁、工具链和产物;修改其中任一项都会使历史报告过期。 */
29
+ function lynxDecoderIdentity(directory = decoderDirectory) {
30
+ const { source, manifest } = readManifest(directory);
31
+ return `${manifest.version}+${sha256(source)}`;
32
+ }
33
+ function assertDigest(source, expected, name) {
34
+ if (!Number.isSafeInteger(expected.byteLength) || expected.byteLength <= 0 || expected.byteLength > 33554432 || source.byteLength !== expected.byteLength || sha256(source) !== expected.sha256) throw new Error(`Lynx decoder ${name} 的字节或 SHA-256 不匹配`);
35
+ }
36
+ async function verifyDecoderFiles(directory) {
37
+ const { source, manifest } = readManifest(directory);
38
+ if (sha256(await node_fs_promises.default.readFile(node_path.default.resolve(directory, manifest.inputs.file))) !== manifest.inputs.sha256) throw new Error("Lynx decoder 构建输入的 SHA-256 不匹配");
39
+ for (const patch of manifest.patches) if (sha256(await node_fs_promises.default.readFile(node_path.default.resolve(directory, patch.file))) !== patch.sha256) throw new Error(`Lynx decoder 补丁 ${patch.file} 的 SHA-256 不匹配`);
40
+ const compressed = await node_fs_promises.default.readFile(node_path.default.resolve(directory, manifest.compressed.file));
41
+ assertDigest(compressed, manifest.compressed, "gzip");
42
+ if (!Number.isSafeInteger(manifest.decompressed.byteLength) || manifest.decompressed.byteLength <= 0 || manifest.decompressed.byteLength > 33554432) throw new Error("Lynx decoder WASM 的固定大小无效");
43
+ return {
44
+ manifest,
45
+ compressed,
46
+ identity: sha256(source)
47
+ };
48
+ }
49
+ async function createDecoderFactory({ manifest, compressed }) {
50
+ const decompressed = (0, node_zlib.gunzipSync)(compressed, { maxOutputLength: manifest.decompressed.byteLength });
51
+ assertDigest(decompressed, manifest.decompressed, "WASM");
52
+ const temporaryDirectory = await node_fs_promises.default.mkdtemp(node_path.default.join(node_os.default.tmpdir(), "lynx-decoder-"));
53
+ const modulePath = node_path.default.join(temporaryDirectory, "lepus.cjs");
54
+ const require$1 = (0, node_module.createRequire)(require("url").pathToFileURL(__filename).href);
55
+ try {
56
+ await node_fs_promises.default.writeFile(modulePath, decompressed);
57
+ const factory = require$1(modulePath);
58
+ if (typeof factory !== "function") throw new TypeError("Lynx decoder 未提供 WASM factory");
59
+ return factory;
60
+ } finally {
61
+ delete require$1.cache[modulePath];
62
+ await node_fs_promises.default.rm(temporaryDirectory, {
63
+ recursive: true,
64
+ force: true
65
+ });
66
+ }
67
+ }
68
+ /** 仅加载固定来源的便携 WASM;缺失、篡改或解码失败均不得回退 serializer 或系统原生库。 */
69
+ async function loadVerifiedDecoderFactory(directory = decoderDirectory) {
70
+ return createDecoderFactory(await verifyDecoderFiles(directory));
71
+ }
72
+ async function verifiedDecoderFactory(directory) {
73
+ const verified = await verifyDecoderFiles(directory);
74
+ let entry = factoryCache;
75
+ if (!entry || entry.identity !== verified.identity) {
76
+ entry = {
77
+ identity: verified.identity,
78
+ promise: createDecoderFactory(verified)
79
+ };
80
+ factoryCache = entry;
81
+ }
82
+ try {
83
+ return await entry.promise;
84
+ } catch (error) {
85
+ if (factoryCache === entry) factoryCache = void 0;
86
+ throw error;
87
+ }
88
+ }
89
+ /** 每次解码使用独立实例,输入只接受实际 bundle 字节,保留 decoder 的原始 CSS 展示文本。 */
90
+ async function decodeLynxBundle(source, directory = decoderDirectory) {
91
+ if (source.byteLength === 0 || source.byteLength > 67108864) throw new Error("Lynx bundle 字节长度无效");
92
+ const module = await (await verifiedDecoderFactory(directory))();
93
+ const pointer = module._malloc(source.byteLength);
94
+ if (!pointer) throw new Error("Lynx decoder 无法分配 bundle 内存");
95
+ try {
96
+ module.HEAPU8.set(source, pointer);
97
+ const result = module._decode(pointer, source.byteLength);
98
+ if (result.status !== 0) throw new Error(`Lynx bundle 解码失败:${result.result}`);
99
+ const decoded = JSON.parse(result.result);
100
+ if (typeof decoded.css?.text !== "string" || typeof decoded["engine-version"] !== "string" || typeof decoded["page-config"] !== "string") throw new TypeError("Lynx bundle 解码结果缺少 CSS 或版本配置");
101
+ return decoded;
102
+ } finally {
103
+ module._free(pointer);
104
+ }
105
+ }
106
+ exports.decodeLynxBundle = decodeLynxBundle;
107
+ exports.loadVerifiedDecoderFactory = loadVerifiedDecoderFactory;
108
+ exports.lynxDecoderIdentity = lynxDecoderIdentity;
@@ -0,0 +1,25 @@
1
+ interface DecodeResult {
2
+ status: number;
3
+ result: string;
4
+ }
5
+ interface DecoderModule {
6
+ HEAPU8: Uint8Array;
7
+ _malloc: (size: number) => number;
8
+ _free: (pointer: number) => void;
9
+ _decode: (pointer: number, size: number) => DecodeResult;
10
+ }
11
+ type DecoderFactory = () => Promise<DecoderModule>;
12
+ export interface DecodedLynxBundle {
13
+ 'engine-version': string;
14
+ 'page-config': string;
15
+ 'css': {
16
+ text: string;
17
+ };
18
+ }
19
+ /** 身份覆盖构建来源、补丁、工具链和产物;修改其中任一项都会使历史报告过期。 */
20
+ export declare function lynxDecoderIdentity(directory?: string): string;
21
+ /** 仅加载固定来源的便携 WASM;缺失、篡改或解码失败均不得回退 serializer 或系统原生库。 */
22
+ export declare function loadVerifiedDecoderFactory(directory?: string): Promise<DecoderFactory>;
23
+ /** 每次解码使用独立实例,输入只接受实际 bundle 字节,保留 decoder 的原始 CSS 展示文本。 */
24
+ export declare function decodeLynxBundle(source: Uint8Array, directory?: string): Promise<DecodedLynxBundle>;
25
+ export {};
@@ -0,0 +1,101 @@
1
+ import { createRequire } from "node:module";
2
+ import { createHash } from "node:crypto";
3
+ import fs from "node:fs/promises";
4
+ import path from "node:path";
5
+ import { readFileSync } from "node:fs";
6
+ import os from "node:os";
7
+ import { gunzipSync } from "node:zlib";
8
+ // src/decoder.ts
9
+ const decoderDirectory = path.join(import.meta.dirname, "decoder-data");
10
+ let factoryCache;
11
+ function sha256(value) {
12
+ return createHash("sha256").update(value).digest("hex");
13
+ }
14
+ function readManifest(directory) {
15
+ const source = readFileSync(path.join(directory, "manifest.json"), "utf8");
16
+ const manifest = JSON.parse(source);
17
+ if (manifest.schemaVersion !== 1 || manifest.version !== "0.0.53" || !/^[a-f0-9]{40}$/.test(manifest.sourceCommit) || manifest.inputs?.file !== "rebuild/inputs.json" || !/^[a-f0-9]{64}$/.test(manifest.inputs.sha256) || manifest.compressed.file !== "vendor/lepus.cjs.gz" || !manifest.patches.length || manifest.patches.some((patch) => !/^patches\/[a-z0-9-]+\.patch$/.test(patch.file))) throw new Error("Lynx decoder manifest 的固定来源或资源身份无效");
18
+ return {
19
+ source,
20
+ manifest
21
+ };
22
+ }
23
+ /** 身份覆盖构建来源、补丁、工具链和产物;修改其中任一项都会使历史报告过期。 */
24
+ function lynxDecoderIdentity(directory = decoderDirectory) {
25
+ const { source, manifest } = readManifest(directory);
26
+ return `${manifest.version}+${sha256(source)}`;
27
+ }
28
+ function assertDigest(source, expected, name) {
29
+ if (!Number.isSafeInteger(expected.byteLength) || expected.byteLength <= 0 || expected.byteLength > 33554432 || source.byteLength !== expected.byteLength || sha256(source) !== expected.sha256) throw new Error(`Lynx decoder ${name} 的字节或 SHA-256 不匹配`);
30
+ }
31
+ async function verifyDecoderFiles(directory) {
32
+ const { source, manifest } = readManifest(directory);
33
+ if (sha256(await fs.readFile(path.resolve(directory, manifest.inputs.file))) !== manifest.inputs.sha256) throw new Error("Lynx decoder 构建输入的 SHA-256 不匹配");
34
+ for (const patch of manifest.patches) if (sha256(await fs.readFile(path.resolve(directory, patch.file))) !== patch.sha256) throw new Error(`Lynx decoder 补丁 ${patch.file} 的 SHA-256 不匹配`);
35
+ const compressed = await fs.readFile(path.resolve(directory, manifest.compressed.file));
36
+ assertDigest(compressed, manifest.compressed, "gzip");
37
+ if (!Number.isSafeInteger(manifest.decompressed.byteLength) || manifest.decompressed.byteLength <= 0 || manifest.decompressed.byteLength > 33554432) throw new Error("Lynx decoder WASM 的固定大小无效");
38
+ return {
39
+ manifest,
40
+ compressed,
41
+ identity: sha256(source)
42
+ };
43
+ }
44
+ async function createDecoderFactory({ manifest, compressed }) {
45
+ const decompressed = gunzipSync(compressed, { maxOutputLength: manifest.decompressed.byteLength });
46
+ assertDigest(decompressed, manifest.decompressed, "WASM");
47
+ const temporaryDirectory = await fs.mkdtemp(path.join(os.tmpdir(), "lynx-decoder-"));
48
+ const modulePath = path.join(temporaryDirectory, "lepus.cjs");
49
+ const require = createRequire(import.meta.url);
50
+ try {
51
+ await fs.writeFile(modulePath, decompressed);
52
+ const factory = require(modulePath);
53
+ if (typeof factory !== "function") throw new TypeError("Lynx decoder 未提供 WASM factory");
54
+ return factory;
55
+ } finally {
56
+ delete require.cache[modulePath];
57
+ await fs.rm(temporaryDirectory, {
58
+ recursive: true,
59
+ force: true
60
+ });
61
+ }
62
+ }
63
+ /** 仅加载固定来源的便携 WASM;缺失、篡改或解码失败均不得回退 serializer 或系统原生库。 */
64
+ async function loadVerifiedDecoderFactory(directory = decoderDirectory) {
65
+ return createDecoderFactory(await verifyDecoderFiles(directory));
66
+ }
67
+ async function verifiedDecoderFactory(directory) {
68
+ const verified = await verifyDecoderFiles(directory);
69
+ let entry = factoryCache;
70
+ if (!entry || entry.identity !== verified.identity) {
71
+ entry = {
72
+ identity: verified.identity,
73
+ promise: createDecoderFactory(verified)
74
+ };
75
+ factoryCache = entry;
76
+ }
77
+ try {
78
+ return await entry.promise;
79
+ } catch (error) {
80
+ if (factoryCache === entry) factoryCache = void 0;
81
+ throw error;
82
+ }
83
+ }
84
+ /** 每次解码使用独立实例,输入只接受实际 bundle 字节,保留 decoder 的原始 CSS 展示文本。 */
85
+ async function decodeLynxBundle(source, directory = decoderDirectory) {
86
+ if (source.byteLength === 0 || source.byteLength > 67108864) throw new Error("Lynx bundle 字节长度无效");
87
+ const module = await (await verifiedDecoderFactory(directory))();
88
+ const pointer = module._malloc(source.byteLength);
89
+ if (!pointer) throw new Error("Lynx decoder 无法分配 bundle 内存");
90
+ try {
91
+ module.HEAPU8.set(source, pointer);
92
+ const result = module._decode(pointer, source.byteLength);
93
+ if (result.status !== 0) throw new Error(`Lynx bundle 解码失败:${result.result}`);
94
+ const decoded = JSON.parse(result.result);
95
+ if (typeof decoded.css?.text !== "string" || typeof decoded["engine-version"] !== "string" || typeof decoded["page-config"] !== "string") throw new TypeError("Lynx bundle 解码结果缺少 CSS 或版本配置");
96
+ return decoded;
97
+ } finally {
98
+ module._free(pointer);
99
+ }
100
+ }
101
+ export { decodeLynxBundle, loadVerifiedDecoderFactory, lynxDecoderIdentity };