@hpcc-js/esbuild-plugins 1.8.4 → 1.8.7

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,87 +1,87 @@
1
- import type { Plugin } from "vite";
2
-
3
- export interface PackageVersionPluginOptions {
4
- /**
5
- * Package.json object containing name and version
6
- */
7
- pkg: {
8
- name: string;
9
- version: string;
10
- };
11
- /**
12
- * Build version (typically from root package.json)
13
- * If not provided, defaults to pkg.version
14
- */
15
- buildVersion?: string;
16
- /**
17
- * Placeholder for package name (default: "__PACKAGE_NAME__")
18
- */
19
- namePlaceholder?: string;
20
- /**
21
- * Placeholder for package version (default: "__PACKAGE_VERSION__")
22
- */
23
- versionPlaceholder?: string;
24
- /**
25
- * Placeholder for build version (default: "__BUILD_VERSION__")
26
- */
27
- buildVersionPlaceholder?: string;
28
- }
29
-
30
- /**
31
- * Vite plugin to replace package version placeholders during build
32
- * This allows keeping version information in source files as placeholders
33
- * that get replaced with actual values from package.json during the build
34
- */
35
- export function packageVersionPlugin(options: PackageVersionPluginOptions): Plugin {
36
- const {
37
- pkg,
38
- buildVersion = pkg.version,
39
- namePlaceholder = "__PACKAGE_NAME__",
40
- versionPlaceholder = "__PACKAGE_VERSION__",
41
- buildVersionPlaceholder = "__BUILD_VERSION__"
42
- } = options;
43
-
44
- return {
45
- name: "hpcc-package-version-plugin",
46
- enforce: "pre",
47
- transform(code: string, id: string) {
48
- // Only process TypeScript/JavaScript files
49
- if (!id.endsWith(".ts") && !id.endsWith(".js")) {
50
- return null;
51
- }
52
-
53
- // Check if the file contains any placeholders
54
- if (!code.includes(namePlaceholder) &&
55
- !code.includes(versionPlaceholder) &&
56
- !code.includes(buildVersionPlaceholder)) {
57
- return null;
58
- }
59
-
60
- // Replace placeholders with actual values
61
- let transformedCode = code;
62
- if (code.includes(namePlaceholder)) {
63
- transformedCode = transformedCode.replace(
64
- new RegExp(namePlaceholder, "g"),
65
- pkg.name
66
- );
67
- }
68
- if (code.includes(versionPlaceholder)) {
69
- transformedCode = transformedCode.replace(
70
- new RegExp(versionPlaceholder, "g"),
71
- pkg.version
72
- );
73
- }
74
- if (code.includes(buildVersionPlaceholder)) {
75
- transformedCode = transformedCode.replace(
76
- new RegExp(buildVersionPlaceholder, "g"),
77
- buildVersion
78
- );
79
- }
80
-
81
- return {
82
- code: transformedCode,
83
- map: null // Could generate source map if needed
84
- };
85
- }
86
- };
87
- }
1
+ import type { Plugin } from "vite";
2
+
3
+ export interface PackageVersionPluginOptions {
4
+ /**
5
+ * Package.json object containing name and version
6
+ */
7
+ pkg: {
8
+ name: string;
9
+ version: string;
10
+ };
11
+ /**
12
+ * Build version (typically from root package.json)
13
+ * If not provided, defaults to pkg.version
14
+ */
15
+ buildVersion?: string;
16
+ /**
17
+ * Placeholder for package name (default: "__PACKAGE_NAME__")
18
+ */
19
+ namePlaceholder?: string;
20
+ /**
21
+ * Placeholder for package version (default: "__PACKAGE_VERSION__")
22
+ */
23
+ versionPlaceholder?: string;
24
+ /**
25
+ * Placeholder for build version (default: "__BUILD_VERSION__")
26
+ */
27
+ buildVersionPlaceholder?: string;
28
+ }
29
+
30
+ /**
31
+ * Vite plugin to replace package version placeholders during build
32
+ * This allows keeping version information in source files as placeholders
33
+ * that get replaced with actual values from package.json during the build
34
+ */
35
+ export function packageVersionPlugin(options: PackageVersionPluginOptions): Plugin {
36
+ const {
37
+ pkg,
38
+ buildVersion = pkg.version,
39
+ namePlaceholder = "__PACKAGE_NAME__",
40
+ versionPlaceholder = "__PACKAGE_VERSION__",
41
+ buildVersionPlaceholder = "__BUILD_VERSION__"
42
+ } = options;
43
+
44
+ return {
45
+ name: "hpcc-package-version-plugin",
46
+ enforce: "pre",
47
+ transform(code: string, id: string) {
48
+ // Only process TypeScript/JavaScript files
49
+ if (!id.endsWith(".ts") && !id.endsWith(".js")) {
50
+ return null;
51
+ }
52
+
53
+ // Check if the file contains any placeholders
54
+ if (!code.includes(namePlaceholder) &&
55
+ !code.includes(versionPlaceholder) &&
56
+ !code.includes(buildVersionPlaceholder)) {
57
+ return null;
58
+ }
59
+
60
+ // Replace placeholders with actual values
61
+ let transformedCode = code;
62
+ if (code.includes(namePlaceholder)) {
63
+ transformedCode = transformedCode.replace(
64
+ new RegExp(namePlaceholder, "g"),
65
+ pkg.name
66
+ );
67
+ }
68
+ if (code.includes(versionPlaceholder)) {
69
+ transformedCode = transformedCode.replace(
70
+ new RegExp(versionPlaceholder, "g"),
71
+ pkg.version
72
+ );
73
+ }
74
+ if (code.includes(buildVersionPlaceholder)) {
75
+ transformedCode = transformedCode.replace(
76
+ new RegExp(buildVersionPlaceholder, "g"),
77
+ buildVersion
78
+ );
79
+ }
80
+
81
+ return {
82
+ code: transformedCode,
83
+ map: null // Could generate source map if needed
84
+ };
85
+ }
86
+ };
87
+ }
@@ -1,24 +1,24 @@
1
- import type { PluginBuild, Plugin } from "esbuild";
2
-
3
- export function problemMatcher(): Plugin {
4
- return {
5
- name: "problem-matcher",
6
-
7
- setup(build: PluginBuild) {
8
-
9
- build.onStart(() => {
10
- // eslint-disable-next-line no-console
11
- console.log("[watch] build started");
12
- });
13
-
14
- build.onEnd((result) => {
15
- result.errors.forEach(({ text, location }) => {
16
- console.error(`✘ [ERROR] ${text}`);
17
- console.error(` ${location?.file}:${location?.line}:${location?.column}:`);
18
- });
19
- // eslint-disable-next-line no-console
20
- console.log("[watch] build finished");
21
- });
22
- }
23
- };
24
- }
1
+ import type { PluginBuild, Plugin } from "esbuild";
2
+
3
+ export function problemMatcher(): Plugin {
4
+ return {
5
+ name: "problem-matcher",
6
+
7
+ setup(build: PluginBuild) {
8
+
9
+ build.onStart(() => {
10
+ // eslint-disable-next-line no-console
11
+ console.log("[watch] build started");
12
+ });
13
+
14
+ build.onEnd((result) => {
15
+ result.errors.forEach(({ text, location }) => {
16
+ console.error(`✘ [ERROR] ${text}`);
17
+ console.error(` ${location?.file}:${location?.line}:${location?.column}:`);
18
+ });
19
+ // eslint-disable-next-line no-console
20
+ console.log("[watch] build finished");
21
+ });
22
+ }
23
+ };
24
+ }
@@ -1,24 +1,24 @@
1
- import type { PluginBuild, Plugin } from "esbuild";
2
-
3
- export interface RebuildLoggerOptions {
4
- outfile?: string;
5
- }
6
-
7
- export function rebuildLogger(opts: RebuildLoggerOptions): Plugin {
8
- return {
9
- name: "rebuild-logger",
10
-
11
- setup(build: PluginBuild) {
12
-
13
- build.onStart(() => {
14
- // eslint-disable-next-line no-console
15
- console.log("[watch] build started");
16
- });
17
-
18
- build.onEnd(() => {
19
- // eslint-disable-next-line no-console
20
- console.log(`Rebuilt ${opts.outfile ?? "Unknown"}`);
21
- });
22
- }
23
- };
24
- }
1
+ import type { PluginBuild, Plugin } from "esbuild";
2
+
3
+ export interface RebuildLoggerOptions {
4
+ outfile?: string;
5
+ }
6
+
7
+ export function rebuildLogger(opts: RebuildLoggerOptions): Plugin {
8
+ return {
9
+ name: "rebuild-logger",
10
+
11
+ setup(build: PluginBuild) {
12
+
13
+ build.onStart(() => {
14
+ // eslint-disable-next-line no-console
15
+ console.log("[watch] build started");
16
+ });
17
+
18
+ build.onEnd(() => {
19
+ // eslint-disable-next-line no-console
20
+ console.log(`Rebuilt ${opts.outfile ?? "Unknown"}`);
21
+ });
22
+ }
23
+ };
24
+ }
@@ -1,21 +1,21 @@
1
- import { writeFileSync } from "node:fs";
2
- import type { PluginBuild, Plugin } from "esbuild";
3
-
4
- export function removeStrict(): Plugin {
5
- return {
6
- name: "remove-strict",
7
- setup(build: PluginBuild) {
8
- build.initialOptions.write = false;
9
- build.onEnd((result) => {
10
- result?.outputFiles?.forEach(file => {
11
- if (file.path.endsWith(".js")) {
12
- const contents = file.text.replace(/"use strict";/g, "");
13
- writeFileSync(file.path, contents, { encoding: "utf8" });
14
- } else {
15
- writeFileSync(file.path, file.contents, { encoding: "binary" });
16
- }
17
- });
18
- });
19
- }
20
- };
21
- }
1
+ import { writeFileSync } from "node:fs";
2
+ import type { PluginBuild, Plugin } from "esbuild";
3
+
4
+ export function removeStrict(): Plugin {
5
+ return {
6
+ name: "remove-strict",
7
+ setup(build: PluginBuild) {
8
+ build.initialOptions.write = false;
9
+ build.onEnd((result) => {
10
+ result?.outputFiles?.forEach(file => {
11
+ if (file.path.endsWith(".js")) {
12
+ const contents = file.text.replace(/"use strict";/g, "");
13
+ writeFileSync(file.path, contents, { encoding: "utf8" });
14
+ } else {
15
+ writeFileSync(file.path, file.contents, { encoding: "binary" });
16
+ }
17
+ });
18
+ });
19
+ }
20
+ };
21
+ }
@@ -1,152 +1,152 @@
1
- import { readFile } from "node:fs/promises";
2
- import { existsSync } from "node:fs";
3
- import { Base91 } from "@hpcc-js/wasm-base91";
4
- import { Zstd } from "@hpcc-js/wasm-zstd";
5
- import type { Plugin, PluginBuild } from "esbuild";
6
-
7
- const table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_\`{|}~"';
8
- const DECODE_TABLE = (() => {
9
- const t = new Int8Array(128).fill(-1);
10
- for (let i = 0; i < table.length; ++i) {
11
- t[table.charCodeAt(i)] = i;
12
- }
13
- return t;
14
- })();
15
-
16
- function tpl(wasmJsPath: string, base91Wasm: string, base91CompressedWasm: string, wasmSize: number, compressedSize: number) {
17
-
18
- const compressed = (base91CompressedWasm.length + 8 * 1024) <= base91Wasm.length;
19
- const wasmJsExists = existsSync(wasmJsPath);
20
-
21
- return `\
22
- ${compressed ? 'import { decompress } from "fzstd";' : ""}
23
- ${wasmJsExists ? `import wrapper from "${wasmJsPath}";` : ""}
24
-
25
- const D = new Int8Array([${DECODE_TABLE.join(",")}]);
26
-
27
- function decode(s: string): Uint8Array {
28
- const out = new Uint8Array(${compressed ? compressedSize : wasmSize});
29
- let pos = 0, b = 0, n = 0, v = -1;
30
-
31
- for (let i = 0, len = s.length; i < len; i++) {
32
- const c = s.charCodeAt(i);
33
- if (c > 127) continue;
34
- const p = D[c];
35
- if (p < 0) continue;
36
- if (v < 0) {
37
- v = p;
38
- } else {
39
- v += p * 91;
40
- b |= v << n;
41
- n += (v & 8191) > 88 ? 13 : 14;
42
- do {
43
- out[pos++] = b;
44
- b >>>= 8;
45
- n -= 8;
46
- } while (n > 7);
47
- v = -1;
48
- }
49
- }
50
-
51
- if (v >= 0) out[pos++] = (b | v << n) & 0xff;
52
-
53
- return out;
54
- }
55
-
56
- const blobStr = '${compressed ? base91CompressedWasm : base91Wasm}';
57
-
58
- let g_wasmBinary: Uint8Array | undefined;
59
- export default function() {
60
- g_wasmBinary ??= ${compressed ? "decompress(decode(blobStr))" : "decode(blobStr)"};
61
- ${!wasmJsExists ? `\
62
- return g_wasmBinary;
63
- `: `\
64
- return wrapper({
65
- wasmBinary: g_wasmBinary,
66
- locateFile: () => ""
67
- });
68
- `}
69
- }
70
-
71
- export function reset() {
72
- g_wasmBinary = undefined;
73
- } `.trim();
74
- }
75
-
76
- let base91Promise: Promise<Base91> | undefined;
77
- let zstdPromise: Promise<Zstd> | undefined;
78
- function getBase91() {
79
- base91Promise ??= Base91.load();
80
- return base91Promise;
81
- }
82
- function getZstd() {
83
- zstdPromise ??= Zstd.load();
84
- return zstdPromise;
85
- }
86
-
87
- export async function wrap(path: string) {
88
- console.info(`Wrapping: ${path}`);
89
- const [base91, zstd] = await Promise.all([getBase91(), getZstd()]);
90
-
91
- console.info(" Reading WASM file...");
92
- const wasm = await readFile(path);
93
- const wasmJsPath = path.replace(/\.wasm$/, ".js");
94
- const CHUNK_SIZE = 64 * 1024 * 1024;
95
-
96
- const base91Parts: string[] = [];
97
- base91.reset();
98
- for (let offset = 0; offset < wasm.length; offset += CHUNK_SIZE) {
99
- const chunk = wasm.subarray(offset, Math.min(offset + CHUNK_SIZE, wasm.length));
100
- base91Parts.push(base91.encodeChunk(chunk));
101
- console.info(` Encoded ${Math.min(offset + CHUNK_SIZE, wasm.length)} / ${wasm.length} bytes`);
102
- }
103
- base91Parts.push(base91.encodeChunkEnd());
104
- const base91Wasm = base91Parts.join("");
105
-
106
- console.info(" Compressing...");
107
- const compressedChunks: Uint8Array[] = [];
108
- zstd.reset();
109
- for (let offset = 0; offset < wasm.length; offset += CHUNK_SIZE) {
110
- const chunk = wasm.subarray(offset, Math.min(offset + CHUNK_SIZE, wasm.length));
111
- compressedChunks.push(zstd.compressChunk(chunk));
112
- console.info(` Compressed ${Math.min(offset + CHUNK_SIZE, wasm.length)} / ${wasm.length} bytes`);
113
- }
114
- compressedChunks.push(zstd.compressEnd());
115
- const totalLength = compressedChunks.reduce((sum, chunk) => sum + chunk.length, 0);
116
- const compressedWasm = new Uint8Array(totalLength);
117
- let compressionOffset = 0;
118
- for (const chunk of compressedChunks) {
119
- compressedWasm.set(chunk, compressionOffset);
120
- compressionOffset += chunk.length;
121
- }
122
-
123
- console.info(" Encoding compressed...");
124
- const base91CompressedParts: string[] = [];
125
- base91.reset();
126
- for (let offset = 0; offset < compressedWasm.length; offset += CHUNK_SIZE) {
127
- const chunk = compressedWasm.subarray(offset, Math.min(offset + CHUNK_SIZE, compressedWasm.length));
128
- base91CompressedParts.push(base91.encodeChunk(chunk));
129
- console.info(` Encoded ${Math.min(offset + CHUNK_SIZE, compressedWasm.length)} / ${compressedWasm.length} bytes (compressed)`);
130
- }
131
- base91CompressedParts.push(base91.encodeChunkEnd());
132
- const base91CompressedWasm = base91CompressedParts.join("");
133
-
134
- console.info(" Creating wrapper...");
135
- return tpl(wasmJsPath, base91Wasm, base91CompressedWasm, wasm.length, compressedWasm.length);
136
- }
137
-
138
- export function sfxWasm(): Plugin {
139
- return {
140
- name: "sfx-wasm",
141
-
142
- setup(build: PluginBuild) {
143
-
144
- build.onLoad({ filter: /\.wasm$/ }, async args => {
145
- return {
146
- contents: await wrap(args.path),
147
- loader: "ts",
148
- };
149
- });
150
- }
151
- };
152
- }
1
+ import { readFile } from "node:fs/promises";
2
+ import { existsSync } from "node:fs";
3
+ import { Base91 } from "@hpcc-js/wasm-base91";
4
+ import { Zstd } from "@hpcc-js/wasm-zstd";
5
+ import type { Plugin, PluginBuild } from "esbuild";
6
+
7
+ const table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_\`{|}~"';
8
+ const DECODE_TABLE = (() => {
9
+ const t = new Int8Array(128).fill(-1);
10
+ for (let i = 0; i < table.length; ++i) {
11
+ t[table.charCodeAt(i)] = i;
12
+ }
13
+ return t;
14
+ })();
15
+
16
+ function tpl(wasmJsPath: string, base91Wasm: string, base91CompressedWasm: string, wasmSize: number, compressedSize: number) {
17
+
18
+ const compressed = (base91CompressedWasm.length + 8 * 1024) <= base91Wasm.length;
19
+ const wasmJsExists = existsSync(wasmJsPath);
20
+
21
+ return `\
22
+ ${compressed ? 'import { decompress } from "fzstd";' : ""}
23
+ ${wasmJsExists ? `import wrapper from "${wasmJsPath}";` : ""}
24
+
25
+ const D = new Int8Array([${DECODE_TABLE.join(",")}]);
26
+
27
+ function decode(s: string): Uint8Array {
28
+ const out = new Uint8Array(${compressed ? compressedSize : wasmSize});
29
+ let pos = 0, b = 0, n = 0, v = -1;
30
+
31
+ for (let i = 0, len = s.length; i < len; i++) {
32
+ const c = s.charCodeAt(i);
33
+ if (c > 127) continue;
34
+ const p = D[c];
35
+ if (p < 0) continue;
36
+ if (v < 0) {
37
+ v = p;
38
+ } else {
39
+ v += p * 91;
40
+ b |= v << n;
41
+ n += (v & 8191) > 88 ? 13 : 14;
42
+ do {
43
+ out[pos++] = b;
44
+ b >>>= 8;
45
+ n -= 8;
46
+ } while (n > 7);
47
+ v = -1;
48
+ }
49
+ }
50
+
51
+ if (v >= 0) out[pos++] = (b | v << n) & 0xff;
52
+
53
+ return out;
54
+ }
55
+
56
+ const blobStr = '${compressed ? base91CompressedWasm : base91Wasm}';
57
+
58
+ let g_wasmBinary: Uint8Array | undefined;
59
+ export default function() {
60
+ g_wasmBinary ??= ${compressed ? "decompress(decode(blobStr))" : "decode(blobStr)"};
61
+ ${!wasmJsExists ? `\
62
+ return g_wasmBinary;
63
+ `: `\
64
+ return wrapper({
65
+ wasmBinary: g_wasmBinary,
66
+ locateFile: () => ""
67
+ });
68
+ `}
69
+ }
70
+
71
+ export function reset() {
72
+ g_wasmBinary = undefined;
73
+ } `.trim();
74
+ }
75
+
76
+ let base91Promise: Promise<Base91> | undefined;
77
+ let zstdPromise: Promise<Zstd> | undefined;
78
+ function getBase91() {
79
+ base91Promise ??= Base91.load();
80
+ return base91Promise;
81
+ }
82
+ function getZstd() {
83
+ zstdPromise ??= Zstd.load();
84
+ return zstdPromise;
85
+ }
86
+
87
+ export async function wrap(path: string) {
88
+ console.info(`Wrapping: ${path}`);
89
+ const [base91, zstd] = await Promise.all([getBase91(), getZstd()]);
90
+
91
+ console.info(" Reading WASM file...");
92
+ const wasm = await readFile(path);
93
+ const wasmJsPath = path.replace(/\.wasm$/, ".js");
94
+ const CHUNK_SIZE = 64 * 1024 * 1024;
95
+
96
+ const base91Parts: string[] = [];
97
+ base91.reset();
98
+ for (let offset = 0; offset < wasm.length; offset += CHUNK_SIZE) {
99
+ const chunk = wasm.subarray(offset, Math.min(offset + CHUNK_SIZE, wasm.length));
100
+ base91Parts.push(base91.encodeChunk(chunk));
101
+ console.info(` Encoded ${Math.min(offset + CHUNK_SIZE, wasm.length)} / ${wasm.length} bytes`);
102
+ }
103
+ base91Parts.push(base91.encodeChunkEnd());
104
+ const base91Wasm = base91Parts.join("");
105
+
106
+ console.info(" Compressing...");
107
+ const compressedChunks: Uint8Array[] = [];
108
+ zstd.reset();
109
+ for (let offset = 0; offset < wasm.length; offset += CHUNK_SIZE) {
110
+ const chunk = wasm.subarray(offset, Math.min(offset + CHUNK_SIZE, wasm.length));
111
+ compressedChunks.push(zstd.compressChunk(chunk));
112
+ console.info(` Compressed ${Math.min(offset + CHUNK_SIZE, wasm.length)} / ${wasm.length} bytes`);
113
+ }
114
+ compressedChunks.push(zstd.compressEnd());
115
+ const totalLength = compressedChunks.reduce((sum, chunk) => sum + chunk.length, 0);
116
+ const compressedWasm = new Uint8Array(totalLength);
117
+ let compressionOffset = 0;
118
+ for (const chunk of compressedChunks) {
119
+ compressedWasm.set(chunk, compressionOffset);
120
+ compressionOffset += chunk.length;
121
+ }
122
+
123
+ console.info(" Encoding compressed...");
124
+ const base91CompressedParts: string[] = [];
125
+ base91.reset();
126
+ for (let offset = 0; offset < compressedWasm.length; offset += CHUNK_SIZE) {
127
+ const chunk = compressedWasm.subarray(offset, Math.min(offset + CHUNK_SIZE, compressedWasm.length));
128
+ base91CompressedParts.push(base91.encodeChunk(chunk));
129
+ console.info(` Encoded ${Math.min(offset + CHUNK_SIZE, compressedWasm.length)} / ${compressedWasm.length} bytes (compressed)`);
130
+ }
131
+ base91CompressedParts.push(base91.encodeChunkEnd());
132
+ const base91CompressedWasm = base91CompressedParts.join("");
133
+
134
+ console.info(" Creating wrapper...");
135
+ return tpl(wasmJsPath, base91Wasm, base91CompressedWasm, wasm.length, compressedWasm.length);
136
+ }
137
+
138
+ export function sfxWasm(): Plugin {
139
+ return {
140
+ name: "sfx-wasm",
141
+
142
+ setup(build: PluginBuild) {
143
+
144
+ build.onLoad({ filter: /\.wasm$/ }, async args => {
145
+ return {
146
+ contents: await wrap(args.path),
147
+ loader: "ts",
148
+ };
149
+ });
150
+ }
151
+ };
152
+ }