@hpcc-js/esbuild-plugins 1.0.10 → 1.1.1
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/LICENSE +43 -0
- package/README.md +45 -45
- package/dist/index.js +5 -5
- package/dist/index.js.map +4 -4
- package/dist/sfx-wrapper.js.map +1 -1
- package/package.json +63 -63
- package/src/build.ts +122 -143
- package/src/exclude-sourcemap.ts +20 -20
- package/src/index.ts +6 -5
- package/src/problem-matcher.ts +24 -24
- package/src/rebuild-logger.ts +24 -24
- package/src/remove-strict.ts +24 -0
- package/src/sfx-wrapper.ts +108 -108
- package/types/build.d.ts +7 -983
- package/types/index.d.ts +1 -0
- package/types/remove-strict.d.ts +2 -0
package/src/build.ts
CHANGED
|
@@ -1,143 +1,122 @@
|
|
|
1
|
-
import * as process from "process";
|
|
2
|
-
import { readFileSync } from "fs";
|
|
3
|
-
import * as path from "path";
|
|
4
|
-
import * as esbuild from "esbuild";
|
|
5
|
-
import type { BuildOptions, Format } from "esbuild";
|
|
6
|
-
import { umdWrapper } from "esbuild-plugin-umd-wrapper";
|
|
7
|
-
import yargs from "yargs";
|
|
8
|
-
import { hideBin } from "yargs/helpers";
|
|
9
|
-
import { rebuildLogger } from "./rebuild-logger.ts";
|
|
10
|
-
import { sfxWasm } from "./sfx-wrapper.ts";
|
|
11
|
-
|
|
12
|
-
const myYargs = yargs(hideBin(process.argv));
|
|
13
|
-
myYargs
|
|
14
|
-
.usage("Usage: node esbuild.mjs [options]")
|
|
15
|
-
.demandCommand(0, 0)
|
|
16
|
-
.example("node esbuild.mjs --watch", "Bundle and watch for changes")
|
|
17
|
-
.option("mode", {
|
|
18
|
-
alias: "m",
|
|
19
|
-
describe: "Build mode",
|
|
20
|
-
choices: ["development", "production"],
|
|
21
|
-
default: "production"
|
|
22
|
-
})
|
|
23
|
-
.option("w", {
|
|
24
|
-
alias: "watch",
|
|
25
|
-
describe: "Watch for changes",
|
|
26
|
-
type: "boolean"
|
|
27
|
-
})
|
|
28
|
-
.help("h")
|
|
29
|
-
.alias("h", "help")
|
|
30
|
-
.epilog("https://github.com/hpcc-systems/hpcc-js-wasm")
|
|
31
|
-
;
|
|
32
|
-
|
|
33
|
-
export const pkg = JSON.parse(readFileSync(path.join(process.cwd(), "./package.json"), "utf8"));
|
|
34
|
-
export const NODE_MJS = pkg.type === "module" ? "js" : "mjs";
|
|
35
|
-
export const NODE_CJS = pkg.type === "module" ? "cjs" : "js";
|
|
36
|
-
|
|
37
|
-
export const argv = await myYargs.argv;
|
|
38
|
-
export const isDevelopment = argv.mode === "development";
|
|
39
|
-
export const isProduction = !isDevelopment;
|
|
40
|
-
export const isWatch = argv.watch;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export function
|
|
104
|
-
return
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
external
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
globalName,
|
|
124
|
-
bundle: true,
|
|
125
|
-
minify: isProduction,
|
|
126
|
-
external,
|
|
127
|
-
plugins: format === "umd" ? [umdWrapper({ libraryName })] : []
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
export function nodeBoth(input: string, output: string, external: string[] = []) {
|
|
132
|
-
return Promise.all([
|
|
133
|
-
nodeTpl(input, output, "esm", external),
|
|
134
|
-
nodeTpl(input, output, "cjs", external)
|
|
135
|
-
]);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
export function bothTpl(input: string, output: string, globalName?: string, libraryName?: string, external: string[] = []) {
|
|
139
|
-
return Promise.all([
|
|
140
|
-
browserBoth(input, output, globalName, libraryName, external),
|
|
141
|
-
nodeTpl(input, output, "cjs", external)
|
|
142
|
-
]);
|
|
143
|
-
}
|
|
1
|
+
import * as process from "process";
|
|
2
|
+
import { readFileSync } from "fs";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
import * as esbuild from "esbuild";
|
|
5
|
+
import type { BuildOptions, Format } from "esbuild";
|
|
6
|
+
import { umdWrapper } from "esbuild-plugin-umd-wrapper";
|
|
7
|
+
import yargs from "yargs";
|
|
8
|
+
import { hideBin } from "yargs/helpers";
|
|
9
|
+
import { rebuildLogger } from "./rebuild-logger.ts";
|
|
10
|
+
import { sfxWasm } from "./sfx-wrapper.ts";
|
|
11
|
+
|
|
12
|
+
const myYargs = yargs(hideBin(process.argv));
|
|
13
|
+
myYargs
|
|
14
|
+
.usage("Usage: node esbuild.mjs [options]")
|
|
15
|
+
.demandCommand(0, 0)
|
|
16
|
+
.example("node esbuild.mjs --watch", "Bundle and watch for changes")
|
|
17
|
+
.option("mode", {
|
|
18
|
+
alias: "m",
|
|
19
|
+
describe: "Build mode",
|
|
20
|
+
choices: ["development", "production"],
|
|
21
|
+
default: "production"
|
|
22
|
+
})
|
|
23
|
+
.option("w", {
|
|
24
|
+
alias: "watch",
|
|
25
|
+
describe: "Watch for changes",
|
|
26
|
+
type: "boolean"
|
|
27
|
+
})
|
|
28
|
+
.help("h")
|
|
29
|
+
.alias("h", "help")
|
|
30
|
+
.epilog("https://github.com/hpcc-systems/hpcc-js-wasm")
|
|
31
|
+
;
|
|
32
|
+
|
|
33
|
+
export const pkg = JSON.parse(readFileSync(path.join(process.cwd(), "./package.json"), "utf8"));
|
|
34
|
+
export const NODE_MJS = pkg.type === "module" ? "js" : "mjs";
|
|
35
|
+
export const NODE_CJS = pkg.type === "module" ? "cjs" : "js";
|
|
36
|
+
|
|
37
|
+
export const argv = await myYargs.argv;
|
|
38
|
+
export const isDevelopment = argv.mode === "development";
|
|
39
|
+
export const isProduction = !isDevelopment;
|
|
40
|
+
export const isWatch = argv.watch;
|
|
41
|
+
|
|
42
|
+
async function buildWatch(input: string, format: Format | "umd" = "esm", external: string[] = [], config: BuildOptions): Promise<void> {
|
|
43
|
+
|
|
44
|
+
const ctx = await esbuild.context({
|
|
45
|
+
entryPoints: [input],
|
|
46
|
+
format: format as Format,
|
|
47
|
+
bundle: true,
|
|
48
|
+
minify: isProduction,
|
|
49
|
+
sourcemap: isDevelopment,
|
|
50
|
+
external,
|
|
51
|
+
...config,
|
|
52
|
+
plugins: [
|
|
53
|
+
...(isWatch ? [rebuildLogger(config)] : []),
|
|
54
|
+
...(config.plugins ?? []),
|
|
55
|
+
sfxWasm()
|
|
56
|
+
]
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
if (isWatch) {
|
|
60
|
+
await ctx.watch();
|
|
61
|
+
} else {
|
|
62
|
+
if (isDevelopment && Array.isArray(config.entryPoints)) {
|
|
63
|
+
// eslint-disable-next-line no-console
|
|
64
|
+
console.log("Start: ", config.entryPoints[0], config.outfile);
|
|
65
|
+
}
|
|
66
|
+
await ctx.rebuild();
|
|
67
|
+
await ctx.dispose();
|
|
68
|
+
if (isDevelopment && Array.isArray(config.entryPoints)) {
|
|
69
|
+
// eslint-disable-next-line no-console
|
|
70
|
+
console.log("Stop: ", config.entryPoints[0], config.outfile);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function browserTpl(input: string, output: string, format: Format | "umd" = "esm", globalName?: string, libraryName?: string, external: string[] = []) {
|
|
76
|
+
return buildWatch(input, format, external, {
|
|
77
|
+
outfile: `${output}.${format === "esm" ? "js" : `${format}.js`}`,
|
|
78
|
+
platform: "browser",
|
|
79
|
+
target: "es2022",
|
|
80
|
+
globalName,
|
|
81
|
+
plugins: format === "umd" ? [umdWrapper({ libraryName })] : []
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function nodeTpl(input: string, output: string, format: Format | "umd" = "esm", external: string[] = []) {
|
|
86
|
+
return buildWatch(input, format, external, {
|
|
87
|
+
outfile: `${output}.${format === "esm" ? NODE_MJS : NODE_CJS}`,
|
|
88
|
+
platform: "node",
|
|
89
|
+
target: "node20"
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function neutralTpl(input: string, output: string, format: Format | "umd" = "esm", globalName?: string, libraryName?: string, external: string[] = []) {
|
|
94
|
+
return buildWatch(input, format, external, {
|
|
95
|
+
outfile: `${output}.${format === "esm" ? "js" : "umd.js"}`,
|
|
96
|
+
platform: "neutral",
|
|
97
|
+
target: "es2022",
|
|
98
|
+
globalName,
|
|
99
|
+
plugins: format === "umd" ? [umdWrapper({ libraryName })] : []
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function browserBoth(input: string, output: string, globalName?: string, libraryName?: string, external: string[] = []) {
|
|
104
|
+
return Promise.all([
|
|
105
|
+
browserTpl(input, output, "esm", globalName, libraryName, external),
|
|
106
|
+
browserTpl(input, output, "umd", globalName, libraryName, external)
|
|
107
|
+
]);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function nodeBoth(input: string, output: string, external: string[] = []) {
|
|
111
|
+
return Promise.all([
|
|
112
|
+
nodeTpl(input, output, "esm", external),
|
|
113
|
+
nodeTpl(input, output, "cjs", external)
|
|
114
|
+
]);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function bothTpl(input: string, output: string, globalName?: string, libraryName?: string, external: string[] = []) {
|
|
118
|
+
return Promise.all([
|
|
119
|
+
browserBoth(input, output, globalName, libraryName, external),
|
|
120
|
+
nodeTpl(input, output, "cjs", external)
|
|
121
|
+
]);
|
|
122
|
+
}
|
package/src/exclude-sourcemap.ts
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { readFile } from "fs/promises";
|
|
2
|
-
import type { PluginBuild, Plugin } from "esbuild";
|
|
3
|
-
|
|
4
|
-
export interface ExcludeSourcemapOptions {
|
|
5
|
-
filter: RegExp;
|
|
6
|
-
}
|
|
7
|
-
export function excludeSourcemap(opts: ExcludeSourcemapOptions): Plugin {
|
|
8
|
-
return {
|
|
9
|
-
name: "exclude-sourcemap",
|
|
10
|
-
|
|
11
|
-
setup(build: PluginBuild) {
|
|
12
|
-
build.onLoad({ filter: opts.filter }, async args => {
|
|
13
|
-
return {
|
|
14
|
-
contents: await readFile(args.path, "utf8") + "\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIiJdLCJtYXBwaW5ncyI6IkEifQ==",
|
|
15
|
-
loader: "default",
|
|
16
|
-
};
|
|
17
|
-
});
|
|
18
|
-
},
|
|
19
|
-
};
|
|
20
|
-
}
|
|
1
|
+
import { readFile } from "fs/promises";
|
|
2
|
+
import type { PluginBuild, Plugin } from "esbuild";
|
|
3
|
+
|
|
4
|
+
export interface ExcludeSourcemapOptions {
|
|
5
|
+
filter: RegExp;
|
|
6
|
+
}
|
|
7
|
+
export function excludeSourcemap(opts: ExcludeSourcemapOptions): Plugin {
|
|
8
|
+
return {
|
|
9
|
+
name: "exclude-sourcemap",
|
|
10
|
+
|
|
11
|
+
setup(build: PluginBuild) {
|
|
12
|
+
build.onLoad({ filter: opts.filter }, async args => {
|
|
13
|
+
return {
|
|
14
|
+
contents: await readFile(args.path, "utf8") + "\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIiJdLCJtYXBwaW5ncyI6IkEifQ==",
|
|
15
|
+
loader: "default",
|
|
16
|
+
};
|
|
17
|
+
});
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export * from "./build.ts";
|
|
2
|
-
export * from "./exclude-sourcemap.ts";
|
|
3
|
-
export * from "./problem-matcher.ts";
|
|
4
|
-
export * from "./rebuild-logger.ts";
|
|
5
|
-
export * from "./
|
|
1
|
+
export * from "./build.ts";
|
|
2
|
+
export * from "./exclude-sourcemap.ts";
|
|
3
|
+
export * from "./problem-matcher.ts";
|
|
4
|
+
export * from "./rebuild-logger.ts";
|
|
5
|
+
export * from "./remove-strict.ts";
|
|
6
|
+
export * from "./sfx-wrapper.ts";
|
package/src/problem-matcher.ts
CHANGED
|
@@ -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
|
+
}
|
package/src/rebuild-logger.ts
CHANGED
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
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
|
+
if (contents.indexOf("use strict") >= 0) {
|
|
14
|
+
console.error("remove-strict: ", file.path);
|
|
15
|
+
}
|
|
16
|
+
writeFileSync(file.path, contents, { encoding: "utf8" });
|
|
17
|
+
} else {
|
|
18
|
+
writeFileSync(file.path, file.contents, { encoding: "binary" });
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
}
|
package/src/sfx-wrapper.ts
CHANGED
|
@@ -1,108 +1,108 @@
|
|
|
1
|
-
import { readFile } from "fs/promises";
|
|
2
|
-
import { existsSync } from "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
|
-
function tpl(wasmJsPath: string, base91Wasm: string, base91CompressedWasm: string) {
|
|
8
|
-
|
|
9
|
-
const compressed = (base91CompressedWasm.length + 8 * 1024) <= base91Wasm.length;
|
|
10
|
-
const wasmJsExists = existsSync(wasmJsPath);
|
|
11
|
-
|
|
12
|
-
return `\
|
|
13
|
-
${compressed ? 'import { decompress } from "fzstd";' : ""}
|
|
14
|
-
${wasmJsExists ? `import wrapper from "${wasmJsPath}";` : ""}
|
|
15
|
-
|
|
16
|
-
const table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_\`{|}~"';
|
|
17
|
-
|
|
18
|
-
function decode(raw: string): Uint8Array {
|
|
19
|
-
const len = raw.length;
|
|
20
|
-
const ret: number[] = [];
|
|
21
|
-
|
|
22
|
-
let b = 0;
|
|
23
|
-
let n = 0;
|
|
24
|
-
let v = -1;
|
|
25
|
-
|
|
26
|
-
for (let i = 0; i < len; i++) {
|
|
27
|
-
const p = table.indexOf(raw[i]);
|
|
28
|
-
/* istanbul ignore next */
|
|
29
|
-
if (p === -1) continue;
|
|
30
|
-
if (v < 0) {
|
|
31
|
-
v = p;
|
|
32
|
-
} else {
|
|
33
|
-
v += p * 91;
|
|
34
|
-
b |= v << n;
|
|
35
|
-
n += (v & 8191) > 88 ? 13 : 14;
|
|
36
|
-
do {
|
|
37
|
-
ret.push(b & 0xff);
|
|
38
|
-
b >>= 8;
|
|
39
|
-
n -= 8;
|
|
40
|
-
} while (n > 7);
|
|
41
|
-
v = -1;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (v > -1) {
|
|
46
|
-
ret.push((b | v << n) & 0xff);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return new Uint8Array(ret);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const blobStr = '${compressed ? base91CompressedWasm : base91Wasm}';
|
|
53
|
-
|
|
54
|
-
let g_module: Uint8Array | undefined;
|
|
55
|
-
let g_wasmBinary: Uint8Array | undefined;
|
|
56
|
-
export default function() {
|
|
57
|
-
if (!g_wasmBinary) {
|
|
58
|
-
g_wasmBinary = ${compressed ? "decompress(decode(blobStr))" : "decode(blobStr)"};
|
|
59
|
-
}
|
|
60
|
-
${!wasmJsExists ? `\
|
|
61
|
-
return g_wasmBinary;
|
|
62
|
-
`: `\
|
|
63
|
-
if (!g_module) {
|
|
64
|
-
g_module = wrapper({
|
|
65
|
-
wasmBinary: g_wasmBinary,
|
|
66
|
-
locateFile: undefined
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
return g_module;
|
|
70
|
-
`}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export function reset() {
|
|
74
|
-
if (g_module) {
|
|
75
|
-
g_module = undefined;
|
|
76
|
-
}
|
|
77
|
-
} `.trim();
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
export async function wrap(path: string) {
|
|
81
|
-
const base91 = await Base91.load();
|
|
82
|
-
const zstd = await Zstd.load();
|
|
83
|
-
|
|
84
|
-
const wasm = await readFile(path);
|
|
85
|
-
path = path.replace(/\.js$/, ".xxx");
|
|
86
|
-
const wasmJsPath = path.replace(/\.wasm$/, ".js");
|
|
87
|
-
const base91Wasm = base91.encode(wasm);
|
|
88
|
-
const compressedWasm = zstd.compress(wasm);
|
|
89
|
-
const base91CompressedWasm = base91.encode(compressedWasm);
|
|
90
|
-
|
|
91
|
-
return tpl(wasmJsPath, base91Wasm, base91CompressedWasm);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export function sfxWasm(): Plugin {
|
|
95
|
-
return {
|
|
96
|
-
name: "sfx-wasm",
|
|
97
|
-
|
|
98
|
-
setup(build: PluginBuild) {
|
|
99
|
-
|
|
100
|
-
build.onLoad({ filter: /\.wasm$/ }, async args => {
|
|
101
|
-
return {
|
|
102
|
-
contents: await wrap(args.path),
|
|
103
|
-
loader: "ts",
|
|
104
|
-
};
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
}
|
|
1
|
+
import { readFile } from "fs/promises";
|
|
2
|
+
import { existsSync } from "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
|
+
function tpl(wasmJsPath: string, base91Wasm: string, base91CompressedWasm: string) {
|
|
8
|
+
|
|
9
|
+
const compressed = (base91CompressedWasm.length + 8 * 1024) <= base91Wasm.length;
|
|
10
|
+
const wasmJsExists = existsSync(wasmJsPath);
|
|
11
|
+
|
|
12
|
+
return `\
|
|
13
|
+
${compressed ? 'import { decompress } from "fzstd";' : ""}
|
|
14
|
+
${wasmJsExists ? `import wrapper from "${wasmJsPath}";` : ""}
|
|
15
|
+
|
|
16
|
+
const table = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_\`{|}~"';
|
|
17
|
+
|
|
18
|
+
function decode(raw: string): Uint8Array {
|
|
19
|
+
const len = raw.length;
|
|
20
|
+
const ret: number[] = [];
|
|
21
|
+
|
|
22
|
+
let b = 0;
|
|
23
|
+
let n = 0;
|
|
24
|
+
let v = -1;
|
|
25
|
+
|
|
26
|
+
for (let i = 0; i < len; i++) {
|
|
27
|
+
const p = table.indexOf(raw[i]);
|
|
28
|
+
/* istanbul ignore next */
|
|
29
|
+
if (p === -1) continue;
|
|
30
|
+
if (v < 0) {
|
|
31
|
+
v = p;
|
|
32
|
+
} else {
|
|
33
|
+
v += p * 91;
|
|
34
|
+
b |= v << n;
|
|
35
|
+
n += (v & 8191) > 88 ? 13 : 14;
|
|
36
|
+
do {
|
|
37
|
+
ret.push(b & 0xff);
|
|
38
|
+
b >>= 8;
|
|
39
|
+
n -= 8;
|
|
40
|
+
} while (n > 7);
|
|
41
|
+
v = -1;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (v > -1) {
|
|
46
|
+
ret.push((b | v << n) & 0xff);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return new Uint8Array(ret);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const blobStr = '${compressed ? base91CompressedWasm : base91Wasm}';
|
|
53
|
+
|
|
54
|
+
let g_module: Uint8Array | undefined;
|
|
55
|
+
let g_wasmBinary: Uint8Array | undefined;
|
|
56
|
+
export default function() {
|
|
57
|
+
if (!g_wasmBinary) {
|
|
58
|
+
g_wasmBinary = ${compressed ? "decompress(decode(blobStr))" : "decode(blobStr)"};
|
|
59
|
+
}
|
|
60
|
+
${!wasmJsExists ? `\
|
|
61
|
+
return g_wasmBinary;
|
|
62
|
+
`: `\
|
|
63
|
+
if (!g_module) {
|
|
64
|
+
g_module = wrapper({
|
|
65
|
+
wasmBinary: g_wasmBinary,
|
|
66
|
+
locateFile: undefined
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
return g_module;
|
|
70
|
+
`}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export function reset() {
|
|
74
|
+
if (g_module) {
|
|
75
|
+
g_module = undefined;
|
|
76
|
+
}
|
|
77
|
+
} `.trim();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export async function wrap(path: string) {
|
|
81
|
+
const base91 = await Base91.load();
|
|
82
|
+
const zstd = await Zstd.load();
|
|
83
|
+
|
|
84
|
+
const wasm = await readFile(path);
|
|
85
|
+
path = path.replace(/\.js$/, ".xxx");
|
|
86
|
+
const wasmJsPath = path.replace(/\.wasm$/, ".js");
|
|
87
|
+
const base91Wasm = base91.encode(wasm);
|
|
88
|
+
const compressedWasm = zstd.compress(wasm);
|
|
89
|
+
const base91CompressedWasm = base91.encode(compressedWasm);
|
|
90
|
+
|
|
91
|
+
return tpl(wasmJsPath, base91Wasm, base91CompressedWasm);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function sfxWasm(): Plugin {
|
|
95
|
+
return {
|
|
96
|
+
name: "sfx-wasm",
|
|
97
|
+
|
|
98
|
+
setup(build: PluginBuild) {
|
|
99
|
+
|
|
100
|
+
build.onLoad({ filter: /\.wasm$/ }, async args => {
|
|
101
|
+
return {
|
|
102
|
+
contents: await wrap(args.path),
|
|
103
|
+
loader: "ts",
|
|
104
|
+
};
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
}
|