rollup-plugin-websqz 1.0.5 → 1.1.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.
- package/README.md +2 -0
- package/dist/index.js +28 -28
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
- package/scripts/install.js +0 -180
package/README.md
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
# rollup-plugin-websqz
|
|
2
|
+

|
|
3
|
+
|
|
2
4
|
Rollup / Vite plugin for using [websqz](https://github.com/r00tkids/websqz) to compress and bundle code and assets into one HTML file. This is intented for intros in the [demoscene](https://en.wikipedia.org/wiki/Demoscene) or size restricted JS challenges.
|
|
3
5
|
|
|
4
6
|
## Install
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const node_child_process_1 = tslib_1.__importDefault(require("node:child_process"));
|
|
9
|
-
const pluginutils_1 = require("@rollup/pluginutils");
|
|
1
|
+
import querystring from 'node:querystring';
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import fsSync from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import child_process from 'node:child_process';
|
|
6
|
+
import { createFilter } from '@rollup/pluginutils';
|
|
7
|
+
|
|
10
8
|
class WebSqzExe {
|
|
11
9
|
websqzPath;
|
|
12
10
|
constructor(websqzPath) {
|
|
@@ -22,7 +20,7 @@ class WebSqzExe {
|
|
|
22
20
|
args.push("--pre-compressed-files", preCompressedFile);
|
|
23
21
|
}
|
|
24
22
|
args.push("--output-directory", cliOptions.output);
|
|
25
|
-
const spawn = await
|
|
23
|
+
const spawn = await child_process.spawn(this.websqzPath, args, {
|
|
26
24
|
stdio: "inherit",
|
|
27
25
|
});
|
|
28
26
|
return new Promise((resolve, reject) => {
|
|
@@ -44,14 +42,14 @@ function websqzExecutablePath(executablePath) {
|
|
|
44
42
|
if (!executablePath) {
|
|
45
43
|
const path = __dirname + "/bin/websqz";
|
|
46
44
|
const extension = process.platform == "win32" ? ".exe" : "";
|
|
47
|
-
if (
|
|
45
|
+
if (fsSync.existsSync(path + extension)) {
|
|
48
46
|
return path + extension;
|
|
49
47
|
}
|
|
50
48
|
return "websqz" + extension;
|
|
51
49
|
}
|
|
52
50
|
return executablePath;
|
|
53
51
|
}
|
|
54
|
-
function
|
|
52
|
+
function index (options = {}) {
|
|
55
53
|
const isBuild = process.env.NODE_ENV === "production";
|
|
56
54
|
const websqzExePath = websqzExecutablePath(options.websqzPath);
|
|
57
55
|
const websqzExe = new WebSqzExe(websqzExePath);
|
|
@@ -60,7 +58,7 @@ function default_1(options = {}) {
|
|
|
60
58
|
: undefined;
|
|
61
59
|
const exclude = transform.exclude ? (Array.isArray(transform.exclude) ? transform.exclude : [transform.exclude])
|
|
62
60
|
: undefined;
|
|
63
|
-
const filter =
|
|
61
|
+
const filter = createFilter(include, exclude);
|
|
64
62
|
return {
|
|
65
63
|
transform: transform.transform,
|
|
66
64
|
filter,
|
|
@@ -88,7 +86,7 @@ function default_1(options = {}) {
|
|
|
88
86
|
fileName,
|
|
89
87
|
content: hookRes.content,
|
|
90
88
|
isCompressed: hookRes.isCompressed,
|
|
91
|
-
fileExt: hookRes.fileExt ??
|
|
89
|
+
fileExt: hookRes.fileExt ?? path.extname(id),
|
|
92
90
|
isText: hookRes.isText,
|
|
93
91
|
});
|
|
94
92
|
return {
|
|
@@ -117,14 +115,14 @@ function default_1(options = {}) {
|
|
|
117
115
|
const qIdx = id.indexOf("?");
|
|
118
116
|
const beforeParams = id.slice(0, qIdx === -1 ? id.length : qIdx);
|
|
119
117
|
const afterParams = id.slice(id.indexOf("?") + 1);
|
|
120
|
-
const parsed =
|
|
118
|
+
const parsed = querystring.parse(afterParams);
|
|
121
119
|
const cleanedUpId = beforeParams;
|
|
122
120
|
let cachedFile = null;
|
|
123
121
|
const loadFromDisk = async () => {
|
|
124
122
|
if (cachedFile != null) {
|
|
125
123
|
return cachedFile;
|
|
126
124
|
}
|
|
127
|
-
cachedFile = await
|
|
125
|
+
cachedFile = await fs.readFile(cleanedUpId);
|
|
128
126
|
return cachedFile;
|
|
129
127
|
};
|
|
130
128
|
if (fileTransforms) {
|
|
@@ -150,7 +148,7 @@ function default_1(options = {}) {
|
|
|
150
148
|
content,
|
|
151
149
|
isCompressed,
|
|
152
150
|
isText: isWebSqzTxt,
|
|
153
|
-
fileExt:
|
|
151
|
+
fileExt: path.extname(cleanedUpId),
|
|
154
152
|
};
|
|
155
153
|
return await loadAndTransform(id, hookRes);
|
|
156
154
|
}
|
|
@@ -167,37 +165,39 @@ function default_1(options = {}) {
|
|
|
167
165
|
}
|
|
168
166
|
const [jsFileName, jsChunk] = jsFiles[0];
|
|
169
167
|
if (isBuild) {
|
|
170
|
-
const outDir =
|
|
171
|
-
if (await
|
|
172
|
-
await
|
|
168
|
+
const outDir = path.resolve(outputOptions.dir || "", "websqz-tmp");
|
|
169
|
+
if (await fs.stat(outDir).catch(() => false)) {
|
|
170
|
+
await fs.rm(outDir, { recursive: true, force: true });
|
|
173
171
|
}
|
|
174
172
|
const filesToCompress = [];
|
|
175
173
|
const preCompressedFiles = [];
|
|
176
174
|
for (const [id, file] of files) {
|
|
177
175
|
this.debug(`Copying '${id}' for websqz...`);
|
|
178
|
-
const outPath =
|
|
179
|
-
await
|
|
180
|
-
await
|
|
176
|
+
const outPath = path.resolve(outputOptions.dir || "", "websqz-tmp", file.fileName);
|
|
177
|
+
await fs.mkdir(path.dirname(outPath), { recursive: true });
|
|
178
|
+
await fs.writeFile(outPath, file.content);
|
|
181
179
|
if (file.isCompressed) {
|
|
182
|
-
preCompressedFiles.push(
|
|
180
|
+
preCompressedFiles.push(path.relative(".", outPath));
|
|
183
181
|
}
|
|
184
182
|
else {
|
|
185
|
-
filesToCompress.push({ isText: file.isText, fileExt: file.fileExt, path:
|
|
183
|
+
filesToCompress.push({ isText: file.isText, fileExt: file.fileExt, path: path.relative(".", outPath) });
|
|
186
184
|
}
|
|
187
185
|
}
|
|
188
186
|
// Sort by file extension for better compression ratios in websqz
|
|
189
187
|
filesToCompress.sort((a, b) => Math.sign(a.fileExt.localeCompare(b.fileExt)) + 2 * (a.isText === b.isText ? 0 : a.isText ? -1 : 1));
|
|
190
188
|
this.info(`Using websqz executable at '${websqzExe.websqzPath}'`);
|
|
191
189
|
await websqzExe.run({
|
|
192
|
-
jsMain:
|
|
190
|
+
jsMain: path.resolve(outputOptions.dir || "", jsFileName),
|
|
193
191
|
files: filesToCompress.map(f => f.path),
|
|
194
192
|
preCompressedFiles: preCompressedFiles,
|
|
195
|
-
output:
|
|
193
|
+
output: path.resolve(outputOptions.dir || "", "websqz-output"),
|
|
196
194
|
});
|
|
197
|
-
const relOutPath =
|
|
195
|
+
const relOutPath = path.relative(".", path.resolve(outputOptions.dir || "", "websqz-output"));
|
|
198
196
|
this.info(`Websqz completed, output at '${relOutPath}'.\nRun 'python -m http.server -d ${relOutPath}' to serve the output.`);
|
|
199
197
|
}
|
|
200
198
|
},
|
|
201
199
|
};
|
|
202
200
|
}
|
|
201
|
+
|
|
202
|
+
export { index as default };
|
|
203
203
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { PluginContext, rollup, type OutputAsset, type OutputChunk, type OutputOptions, type Plugin } from \"rollup\";\nimport querystring from \"node:querystring\";\nimport fs from \"node:fs/promises\";\nimport fsSync from \"node:fs\";\nimport path from \"node:path\";\nimport child_process from \"node:child_process\";\nimport { createFilter, FilterPattern } from \"@rollup/pluginutils\";\n\ntype WebSqzFile = {\n fileName: string;\n content: Buffer;\n isCompressed: boolean;\n fileExt: string;\n isText: boolean;\n};\n\nexport type WebsqzFileTransformRes = {\n /**\n * The result of processing\n */\n content: Buffer;\n\n /**\n * Is already compressed and should not be compressed again by websqz\n */\n isCompressed: boolean;\n\n /**\n * Is it text? The plugin orders files by type for better compression ratios\n */\n isText: boolean;\n\n /**\n * File extension including the dot, e.g. .txt.\n * This is used to order files for better compression ratios.\n * Same type of content should share same file extension.\n * \n * By default it is extracted from the original file path.\n */\n fileExt?: string;\n};\n\ntype WebSqzOptions = {\n websqzPath?: string;\n\n /**\n * File transform hooks to process files before they are imported in code or compressed by websqz\n */\n fileTransforms?: [\n {\n include?: FilterPattern,\n exclude?: FilterPattern,\n transform: (ctx: PluginContext, id: string, content: Buffer) => Promise<WebsqzFileTransformRes>;\n }\n ]\n};\n\ntype WebSqzCliOptions = {\n jsMain: string;\n files: string[];\n preCompressedFiles: string[];\n output: string;\n}\n\nclass WebSqzExe {\n websqzPath: string;\n constructor(websqzPath: string) {\n this.websqzPath = websqzPath;\n }\n\n async run(cliOptions: WebSqzCliOptions): Promise<void> {\n const args: string[] = [];\n\n args.push(\"--js-main\", cliOptions.jsMain);\n\n for (const file of cliOptions.files) {\n args.push(\"--files\", file);\n }\n for (const preCompressedFile of cliOptions.preCompressedFiles) {\n args.push(\"--pre-compressed-files\", preCompressedFile);\n }\n\n args.push(\"--output-directory\", cliOptions.output);\n\n const spawn = await child_process.spawn(this.websqzPath, args, {\n stdio: \"inherit\",\n });\n\n return new Promise<void>((resolve, reject) => {\n spawn.once(\"error\", (err) => {\n reject(err);\n });\n\n spawn.once(\"close\", (code) => {\n if (code !== 0) {\n reject(new Error(`websqz process exited with code ${code}`));\n } else {\n resolve();\n }\n });\n });\n }\n}\n\nfunction websqzExecutablePath(executablePath: string | undefined): string {\n if (!executablePath) {\n const path = __dirname + \"/bin/websqz\";\n const extension = process.platform == \"win32\" ? \".exe\" : \"\";\n\n if (fsSync.existsSync(path + extension)) {\n return path + extension;\n }\n\n return \"websqz\" + extension;\n }\n\n return executablePath;\n}\n\nexport default function (options: WebSqzOptions = {}): Plugin {\n const isBuild = process.env.NODE_ENV === \"production\";\n const websqzExePath = websqzExecutablePath(options.websqzPath);\n const websqzExe = new WebSqzExe(websqzExePath);\n\n const fileTransforms = options.fileTransforms?.map(transform => {\n const include = transform.include ? (Array.isArray(transform.include) ? transform.include : [transform.include]) \n : undefined;\n const exclude = transform.exclude ? (Array.isArray(transform.exclude) ? transform.exclude : [transform.exclude]) \n : undefined;\n\n const filter = createFilter(include, exclude);\n return {\n transform: transform.transform,\n filter,\n }\n });\n\n const files = new Map<string, WebSqzFile>();\n let fileNameIdx = 0;\n\n const findNextAvailableFileName = () => {\n const startChar = 97; // a\n const endChar = 122; // z\n const alphabetSize= endChar - startChar;\n\n let numChars = fileNameIdx === 0 ? 1 : Math.floor(Math.log(fileNameIdx) / Math.log(alphabetSize)) + 1;\n let candidateName = \"\";\n \n for (let i = 0; i < numChars; i++) {\n const charCode = startChar + ((Math.floor(fileNameIdx / Math.pow(alphabetSize, i))) % alphabetSize);\n candidateName = String.fromCharCode(charCode) + candidateName;\n }\n\n fileNameIdx++;\n\n return candidateName;\n }\n\n const loadAndTransform = async function (id: string, hookRes: WebsqzFileTransformRes) {\n if (isBuild) {\n const fileName = findNextAvailableFileName();\n files.set(id, {\n fileName,\n content: hookRes.content,\n isCompressed: hookRes.isCompressed,\n fileExt: hookRes.fileExt ?? path.extname(id),\n isText: hookRes.isText,\n });\n\n return {\n code: hookRes.isText \n ? `export default new TextDecoder().decode(wsqz.files[\"${fileName}\"]);` \n : `export default wsqz.files[\"${fileName}\"];`,\n moduleSideEffects: false,\n moduleType: 'js',\n };\n } else {\n return {\n code: hookRes.isText \n ? `export default ${JSON.stringify(hookRes.content.toString(\"utf-8\"))};` \n : `export default Uint8Array.fromBase64(\"${hookRes.content.toString(\"base64\")}\");`,\n moduleSideEffects: false,\n moduleType: 'js',\n };\n }\n };\n\n return {\n name: \"rollup-plugin-websqz\",\n\n load: {\n order: \"pre\",\n async handler(id: string) {\n const qIdx = id.indexOf(\"?\");\n const beforeParams = id.slice(0, qIdx === -1 ? id.length : qIdx);\n const afterParams = id.slice(id.indexOf(\"?\") + 1);\n const parsed = querystring.parse(afterParams);\n const cleanedUpId = beforeParams;\n\n let cachedFile: Buffer | null = null;\n const loadFromDisk = async () => {\n if (cachedFile != null) {\n return cachedFile;\n }\n cachedFile = await fs.readFile(cleanedUpId);\n return cachedFile;\n };\n\n if (fileTransforms) {\n for (const transform of fileTransforms) {\n if (transform.filter(id)) {\n let hookRes = await transform.transform(this, id, await loadFromDisk());\n if (hookRes == null) {\n continue;\n }\n return await loadAndTransform(id, hookRes);\n }\n }\n }\n\n const isWebSqzTxt = parsed[\"websqz-txt\"] != null;\n const isWebSqzBin = parsed[\"websqz-bin\"] != null;\n\n if (isWebSqzTxt && isWebSqzBin) {\n throw new Error(\n `Cannot use both websqz-txt and websqz-bin on the same import: ${id}`,\n );\n }\n\n const isCompressed = parsed[\"compressed\"] != null;\n\n if (isWebSqzTxt || isWebSqzBin) {\n const content = await loadFromDisk();\n \n let hookRes: WebsqzFileTransformRes = {\n content,\n isCompressed,\n isText: isWebSqzTxt,\n fileExt: path.extname(cleanedUpId),\n };\n return await loadAndTransform(id, hookRes);\n }\n }\n },\n\n writeBundle: async function (outputOptions: OutputOptions, bundle: { [fileName: string]: OutputAsset | OutputChunk }) {\n const jsFiles = Object.entries(bundle)\n .filter(([fileName, asset]) => fileName.endsWith('.js') && asset.type === 'chunk');\n\n if (jsFiles.length === 0) {\n throw new Error('No JavaScript file found in the bundle.');\n }\n if (jsFiles.length > 1) {\n throw new Error('Multiple JavaScript files found in the bundle. Make sure to bundle into a single file.\\nTry setting \"build.rollupOptions.output.inlineDynamicImports\" to true in Vite config.');\n }\n\n const [jsFileName, jsChunk] = jsFiles[0];\n\n if (isBuild) {\n const outDir = path.resolve(\n outputOptions.dir || \"\",\n \"websqz-tmp\");\n if (await fs.stat(outDir).catch(() => false)) {\n await fs.rmdir(outDir, { recursive: true });\n }\n\n const filesToCompress = [];\n const preCompressedFiles = [];\n\n for (const [id, file] of files) {\n this.debug(`Copying '${id}' for websqz...`);\n const outPath = path.resolve(\n outputOptions.dir || \"\",\n \"websqz-tmp\",\n file.fileName,\n );\n\n await fs.mkdir(path.dirname(outPath), { recursive: true });\n await fs.writeFile(outPath, file.content);\n\n if (file.isCompressed) {\n preCompressedFiles.push(path.relative(\".\", outPath));\n } else {\n filesToCompress.push({ isText: file.isText, fileExt: file.fileExt, path: path.relative(\".\", outPath) });\n }\n }\n\n // Sort by file extension for better compression ratios in websqz\n filesToCompress.sort((a, b) => Math.sign(a.fileExt.localeCompare(b.fileExt)) + 2 * (a.isText === b.isText ? 0 : a.isText ? -1 : 1));\n\n this.info(`Using websqz executable at '${websqzExe.websqzPath}'`);\n await websqzExe.run({\n jsMain: path.resolve(\n outputOptions.dir || \"\",\n jsFileName,\n ),\n files: filesToCompress.map(f => f.path),\n preCompressedFiles: preCompressedFiles,\n output: path.resolve(\n outputOptions.dir || \"\",\n \"websqz-output\",\n ),\n });\n\n const relOutPath = path.relative(\".\", path.resolve(outputOptions.dir || \"\", \"websqz-output\"));\n this.info(`Websqz completed, output at '${relOutPath}'.\\nRun 'python -m http.server -d ${relOutPath}' to serve the output.`);\n }\n },\n };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { PluginContext, rollup, type OutputAsset, type OutputChunk, type OutputOptions, type Plugin } from \"rollup\";\nimport querystring from \"node:querystring\";\nimport fs from \"node:fs/promises\";\nimport fsSync from \"node:fs\";\nimport path from \"node:path\";\nimport child_process from \"node:child_process\";\nimport { createFilter, FilterPattern } from \"@rollup/pluginutils\";\n\ntype WebSqzFile = {\n fileName: string;\n content: Buffer;\n isCompressed: boolean;\n fileExt: string;\n isText: boolean;\n};\n\nexport type WebsqzFileTransformRes = {\n /**\n * The result of processing\n */\n content: Buffer;\n\n /**\n * Is already compressed and should not be compressed again by websqz\n */\n isCompressed: boolean;\n\n /**\n * Is it text? The plugin orders files by type for better compression ratios\n */\n isText: boolean;\n\n /**\n * File extension including the dot, e.g. .txt.\n * This is used to order files for better compression ratios.\n * Same type of content should share same file extension.\n * \n * By default it is extracted from the original file path.\n */\n fileExt?: string;\n};\n\ntype WebSqzOptions = {\n websqzPath?: string;\n\n /**\n * File transform hooks to process files before they are imported in code or compressed by websqz\n */\n fileTransforms?: [\n {\n include?: FilterPattern,\n exclude?: FilterPattern,\n transform: (ctx: PluginContext, id: string, content: Buffer) => Promise<WebsqzFileTransformRes>;\n }\n ]\n};\n\ntype WebSqzCliOptions = {\n jsMain: string;\n files: string[];\n preCompressedFiles: string[];\n output: string;\n}\n\nclass WebSqzExe {\n websqzPath: string;\n constructor(websqzPath: string) {\n this.websqzPath = websqzPath;\n }\n\n async run(cliOptions: WebSqzCliOptions): Promise<void> {\n const args: string[] = [];\n\n args.push(\"--js-main\", cliOptions.jsMain);\n\n for (const file of cliOptions.files) {\n args.push(\"--files\", file);\n }\n for (const preCompressedFile of cliOptions.preCompressedFiles) {\n args.push(\"--pre-compressed-files\", preCompressedFile);\n }\n\n args.push(\"--output-directory\", cliOptions.output);\n\n const spawn = await child_process.spawn(this.websqzPath, args, {\n stdio: \"inherit\",\n });\n\n return new Promise<void>((resolve, reject) => {\n spawn.once(\"error\", (err) => {\n reject(err);\n });\n\n spawn.once(\"close\", (code) => {\n if (code !== 0) {\n reject(new Error(`websqz process exited with code ${code}`));\n } else {\n resolve();\n }\n });\n });\n }\n}\n\nfunction websqzExecutablePath(executablePath: string | undefined): string {\n if (!executablePath) {\n const path = __dirname + \"/bin/websqz\";\n const extension = process.platform == \"win32\" ? \".exe\" : \"\";\n\n if (fsSync.existsSync(path + extension)) {\n return path + extension;\n }\n\n return \"websqz\" + extension;\n }\n\n return executablePath;\n}\n\nexport default function (options: WebSqzOptions = {}): Plugin {\n const isBuild = process.env.NODE_ENV === \"production\";\n const websqzExePath = websqzExecutablePath(options.websqzPath);\n const websqzExe = new WebSqzExe(websqzExePath);\n\n const fileTransforms = options.fileTransforms?.map(transform => {\n const include = transform.include ? (Array.isArray(transform.include) ? transform.include : [transform.include]) \n : undefined;\n const exclude = transform.exclude ? (Array.isArray(transform.exclude) ? transform.exclude : [transform.exclude]) \n : undefined;\n\n const filter = createFilter(include, exclude);\n return {\n transform: transform.transform,\n filter,\n }\n });\n\n const files = new Map<string, WebSqzFile>();\n let fileNameIdx = 0;\n\n const findNextAvailableFileName = () => {\n const startChar = 97; // a\n const endChar = 122; // z\n const alphabetSize= endChar - startChar;\n\n let numChars = fileNameIdx === 0 ? 1 : Math.floor(Math.log(fileNameIdx) / Math.log(alphabetSize)) + 1;\n let candidateName = \"\";\n \n for (let i = 0; i < numChars; i++) {\n const charCode = startChar + ((Math.floor(fileNameIdx / Math.pow(alphabetSize, i))) % alphabetSize);\n candidateName = String.fromCharCode(charCode) + candidateName;\n }\n\n fileNameIdx++;\n\n return candidateName;\n }\n\n const loadAndTransform = async function (id: string, hookRes: WebsqzFileTransformRes) {\n if (isBuild) {\n const fileName = findNextAvailableFileName();\n files.set(id, {\n fileName,\n content: hookRes.content,\n isCompressed: hookRes.isCompressed,\n fileExt: hookRes.fileExt ?? path.extname(id),\n isText: hookRes.isText,\n });\n\n return {\n code: hookRes.isText \n ? `export default new TextDecoder().decode(wsqz.files[\"${fileName}\"]);` \n : `export default wsqz.files[\"${fileName}\"];`,\n moduleSideEffects: false,\n moduleType: 'js',\n };\n } else {\n return {\n code: hookRes.isText \n ? `export default ${JSON.stringify(hookRes.content.toString(\"utf-8\"))};` \n : `export default Uint8Array.fromBase64(\"${hookRes.content.toString(\"base64\")}\");`,\n moduleSideEffects: false,\n moduleType: 'js',\n };\n }\n };\n\n return {\n name: \"rollup-plugin-websqz\",\n\n load: {\n order: \"pre\",\n async handler(id: string) {\n const qIdx = id.indexOf(\"?\");\n const beforeParams = id.slice(0, qIdx === -1 ? id.length : qIdx);\n const afterParams = id.slice(id.indexOf(\"?\") + 1);\n const parsed = querystring.parse(afterParams);\n const cleanedUpId = beforeParams;\n\n let cachedFile: Buffer | null = null;\n const loadFromDisk = async () => {\n if (cachedFile != null) {\n return cachedFile;\n }\n cachedFile = await fs.readFile(cleanedUpId);\n return cachedFile;\n };\n\n if (fileTransforms) {\n for (const transform of fileTransforms) {\n if (transform.filter(id)) {\n let hookRes = await transform.transform(this, id, await loadFromDisk());\n if (hookRes == null) {\n continue;\n }\n return await loadAndTransform(id, hookRes);\n }\n }\n }\n\n const isWebSqzTxt = parsed[\"websqz-txt\"] != null;\n const isWebSqzBin = parsed[\"websqz-bin\"] != null;\n\n if (isWebSqzTxt && isWebSqzBin) {\n throw new Error(\n `Cannot use both websqz-txt and websqz-bin on the same import: ${id}`,\n );\n }\n\n const isCompressed = parsed[\"compressed\"] != null;\n\n if (isWebSqzTxt || isWebSqzBin) {\n const content = await loadFromDisk();\n \n let hookRes: WebsqzFileTransformRes = {\n content,\n isCompressed,\n isText: isWebSqzTxt,\n fileExt: path.extname(cleanedUpId),\n };\n return await loadAndTransform(id, hookRes);\n }\n }\n },\n\n writeBundle: async function (outputOptions: OutputOptions, bundle: { [fileName: string]: OutputAsset | OutputChunk }) {\n const jsFiles = Object.entries(bundle)\n .filter(([fileName, asset]) => fileName.endsWith('.js') && asset.type === 'chunk');\n\n if (jsFiles.length === 0) {\n throw new Error('No JavaScript file found in the bundle.');\n }\n if (jsFiles.length > 1) {\n throw new Error('Multiple JavaScript files found in the bundle. Make sure to bundle into a single file.\\nTry setting \"build.rollupOptions.output.inlineDynamicImports\" to true in Vite config.');\n }\n\n const [jsFileName, jsChunk] = jsFiles[0];\n\n if (isBuild) {\n const outDir = path.resolve(\n outputOptions.dir || \"\",\n \"websqz-tmp\");\n if (await fs.stat(outDir).catch(() => false)) {\n await fs.rm(outDir, { recursive: true, force: true });\n }\n\n const filesToCompress = [];\n const preCompressedFiles = [];\n\n for (const [id, file] of files) {\n this.debug(`Copying '${id}' for websqz...`);\n const outPath = path.resolve(\n outputOptions.dir || \"\",\n \"websqz-tmp\",\n file.fileName,\n );\n\n await fs.mkdir(path.dirname(outPath), { recursive: true });\n await fs.writeFile(outPath, file.content);\n\n if (file.isCompressed) {\n preCompressedFiles.push(path.relative(\".\", outPath));\n } else {\n filesToCompress.push({ isText: file.isText, fileExt: file.fileExt, path: path.relative(\".\", outPath) });\n }\n }\n\n // Sort by file extension for better compression ratios in websqz\n filesToCompress.sort((a, b) => Math.sign(a.fileExt.localeCompare(b.fileExt)) + 2 * (a.isText === b.isText ? 0 : a.isText ? -1 : 1));\n\n this.info(`Using websqz executable at '${websqzExe.websqzPath}'`);\n await websqzExe.run({\n jsMain: path.resolve(\n outputOptions.dir || \"\",\n jsFileName,\n ),\n files: filesToCompress.map(f => f.path),\n preCompressedFiles: preCompressedFiles,\n output: path.resolve(\n outputOptions.dir || \"\",\n \"websqz-output\",\n ),\n });\n\n const relOutPath = path.relative(\".\", path.resolve(outputOptions.dir || \"\", \"websqz-output\"));\n this.info(`Websqz completed, output at '${relOutPath}'.\\nRun 'python -m http.server -d ${relOutPath}' to serve the output.`);\n }\n },\n };\n}\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rollup-plugin-websqz",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"type": "module",
|
|
4
5
|
"description": "",
|
|
5
6
|
"main": "./dist/index.js",
|
|
6
7
|
"types": "./dist/index.d.ts",
|
|
7
8
|
"exports": "./dist/index.js",
|
|
8
9
|
"files": [
|
|
9
|
-
"scripts/install.
|
|
10
|
+
"scripts/install.cj",
|
|
10
11
|
"dist/index.js",
|
|
11
12
|
"dist/index.js.map",
|
|
12
13
|
"dist/index.d.ts"
|
|
@@ -30,6 +31,7 @@
|
|
|
30
31
|
"devDependencies": {
|
|
31
32
|
"@rollup/plugin-typescript": "^12.3.0",
|
|
32
33
|
"@tsconfig/node22": "^22.0.5",
|
|
34
|
+
"@types/node": "^26.0.0",
|
|
33
35
|
"rollup": "^4.55.3",
|
|
34
36
|
"typescript": "^5.9.3"
|
|
35
37
|
},
|
package/scripts/install.js
DELETED
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
const fs = require("fs");
|
|
2
|
-
const https = require("https");
|
|
3
|
-
const http = require("http");
|
|
4
|
-
const path = require("path");
|
|
5
|
-
const os = require("os");
|
|
6
|
-
|
|
7
|
-
const RELEASE_BASE_URL = "https://github.com/r00tkids/websqz/releases/download";
|
|
8
|
-
const VERSION = "0.3";
|
|
9
|
-
const TOOL_NAME = "websqz";
|
|
10
|
-
const BIN_DIR = path.resolve(__dirname, "../dist/bin");
|
|
11
|
-
|
|
12
|
-
function getRustTarget() {
|
|
13
|
-
const platform = process.platform;
|
|
14
|
-
const arch = process.arch;
|
|
15
|
-
|
|
16
|
-
let triple;
|
|
17
|
-
let ext = "";
|
|
18
|
-
|
|
19
|
-
if (platform === "win32") {
|
|
20
|
-
ext = ".exe";
|
|
21
|
-
if (arch === "x64") triple = "x86_64-pc-windows-msvc";
|
|
22
|
-
else if (arch === "arm64") triple = "aarch64-pc-windows-msvc";
|
|
23
|
-
else triple = `${arch}-pc-windows-msvc`;
|
|
24
|
-
} else if (platform === "darwin") {
|
|
25
|
-
if (arch === "x64") triple = "x86_64-apple-darwin";
|
|
26
|
-
else if (arch === "arm64") triple = "aarch64-apple-darwin";
|
|
27
|
-
else triple = `${arch}-apple-darwin`;
|
|
28
|
-
} else if (platform === "linux") {
|
|
29
|
-
if (arch === "x64") triple = "x86_64-unknown-linux-gnu";
|
|
30
|
-
else if (arch === "arm64") triple = "aarch64-unknown-linux-gnu";
|
|
31
|
-
else triple = `${arch}-unknown-linux-gnu`;
|
|
32
|
-
} else {
|
|
33
|
-
throw new Error(`Unsupported platform: ${platform}`);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return { triple, ext };
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function buildAssetName(triple, ext) {
|
|
40
|
-
return `${TOOL_NAME}-${triple}${ext}`;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function getDownloadUrl(assetName) {
|
|
44
|
-
return `${RELEASE_BASE_URL}/v${VERSION}/${assetName}`;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function httpRequest(url, opts, callback) {
|
|
48
|
-
const client = url.startsWith("https://") ? https : http;
|
|
49
|
-
return client.get(url, opts, callback);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
function downloadToFile(url, destPath) {
|
|
53
|
-
return new Promise((resolve, reject) => {
|
|
54
|
-
const maxRedirects = 5;
|
|
55
|
-
let redirects = 0;
|
|
56
|
-
|
|
57
|
-
function get(urlToGet) {
|
|
58
|
-
const req = httpRequest(urlToGet, {}, (res) => {
|
|
59
|
-
// Follow redirects
|
|
60
|
-
if (
|
|
61
|
-
res.statusCode >= 300 &&
|
|
62
|
-
res.statusCode < 400 &&
|
|
63
|
-
res.headers.location
|
|
64
|
-
) {
|
|
65
|
-
if (redirects++ >= maxRedirects) {
|
|
66
|
-
reject(new Error("Too many redirects"));
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
const next = new URL(res.headers.location, urlToGet).toString();
|
|
70
|
-
res.resume();
|
|
71
|
-
get(next);
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (res.statusCode !== 200) {
|
|
76
|
-
reject(
|
|
77
|
-
new Error(
|
|
78
|
-
`Download failed: ${res.statusCode} ${res.statusMessage}`,
|
|
79
|
-
),
|
|
80
|
-
);
|
|
81
|
-
res.resume();
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const total = parseInt(res.headers["content-length"] || "0", 10);
|
|
86
|
-
let downloaded = 0;
|
|
87
|
-
|
|
88
|
-
const fileStream = fs.createWriteStream(destPath, { mode: 0o755 });
|
|
89
|
-
res.on("data", (chunk) => {
|
|
90
|
-
downloaded += chunk.length;
|
|
91
|
-
if (total) {
|
|
92
|
-
const pct = ((downloaded / total) * 100).toFixed(1);
|
|
93
|
-
process.stdout.write(
|
|
94
|
-
`\rDownloading ${path.basename(destPath)} ${pct}% (${(downloaded / 1024).toFixed(1)} KB)`,
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
res.pipe(fileStream);
|
|
100
|
-
|
|
101
|
-
fileStream.on("finish", () => {
|
|
102
|
-
fileStream.close(() => {
|
|
103
|
-
process.stdout.write("\n");
|
|
104
|
-
resolve();
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
fileStream.on("error", (err) => {
|
|
109
|
-
fs.unlink(destPath, () => reject(err));
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
req.on("error", (err) => reject(err));
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
get(url);
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
async function ensureBinDir() {
|
|
121
|
-
await fs.promises.mkdir(BIN_DIR, { recursive: true });
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
async function makeExecutable(filePath) {
|
|
125
|
-
if (process.platform === "win32") {
|
|
126
|
-
// Windows uses .exe; no chmod needed generally
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
try {
|
|
130
|
-
await fs.promises.chmod(filePath, 0o755);
|
|
131
|
-
} catch (err) {
|
|
132
|
-
// Best-effort, not fatal
|
|
133
|
-
console.warn(
|
|
134
|
-
`Warning: could not set executable permissions on ${filePath}: ${err.message}`,
|
|
135
|
-
);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
async function main() {
|
|
140
|
-
try {
|
|
141
|
-
const { triple, ext } = getRustTarget();
|
|
142
|
-
const assetName = buildAssetName(triple, ext);
|
|
143
|
-
const url = getDownloadUrl(assetName);
|
|
144
|
-
|
|
145
|
-
console.log(`Detected platform: ${process.platform} ${process.arch}`);
|
|
146
|
-
console.log(`Downloading asset: ${assetName}`);
|
|
147
|
-
console.log(`From: ${url}`);
|
|
148
|
-
|
|
149
|
-
if (fs.existsSync(BIN_DIR + "/" + TOOL_NAME + ext)) {
|
|
150
|
-
console.log(`WebSQZ binary already exists at ${BIN_DIR}/${TOOL_NAME}${ext}, skipping download.`);
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
await ensureBinDir();
|
|
155
|
-
|
|
156
|
-
const destFileName = `${TOOL_NAME}${ext}`; // place binary in bin with consistent name
|
|
157
|
-
const destPath = path.join(BIN_DIR, destFileName);
|
|
158
|
-
|
|
159
|
-
// Remove existing file if present (optional)
|
|
160
|
-
try {
|
|
161
|
-
await fs.promises.unlink(destPath);
|
|
162
|
-
} catch (err) {
|
|
163
|
-
// ignore if not exists
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
await downloadToFile(url, destPath);
|
|
167
|
-
|
|
168
|
-
await makeExecutable(destPath);
|
|
169
|
-
|
|
170
|
-
console.log(`Downloaded and saved to: ${destPath}`);
|
|
171
|
-
console.log("Done.");
|
|
172
|
-
} catch (err) {
|
|
173
|
-
console.error(`Error: ${err.message}`);
|
|
174
|
-
process.exitCode = 1;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
if (require.main === module) {
|
|
179
|
-
main();
|
|
180
|
-
}
|