gofront 1.7.0 → 1.9.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 +14 -14
- package/package.json +10 -38
- package/src/backend/js/expressions.js +2060 -389
- package/src/backend/js/index.js +586 -174
- package/src/backend/js/natives.js +383 -0
- package/src/backend/js/runtime.js +936 -1644
- package/src/backend/js/statements.js +1349 -132
- package/src/backend/js/stdlib/index.js +51 -94
- package/src/backend/js/templ.js +67 -118
- package/src/backend/js/type-info.js +436 -0
- package/src/backend/shared/fixed-float.js +20 -0
- package/src/backend/shared/fmt-types.js +80 -0
- package/src/backend/shared/host-unicode.js +36 -0
- package/src/backend/wasm/boundary.js +753 -872
- package/src/backend/wasm/emit-builtins.js +914 -237
- package/src/backend/wasm/emit-exprs.js +1456 -195
- package/src/backend/wasm/emit-maps.js +78 -380
- package/src/backend/wasm/emit-stmts.js +1659 -214
- package/src/backend/wasm/emit.js +614 -88
- package/src/backend/wasm/encode.js +43 -13
- package/src/backend/wasm/globals.js +491 -0
- package/src/backend/wasm/glue.js +2 -4
- package/src/backend/wasm/index.js +406 -3195
- package/src/backend/wasm/method-expr.js +392 -0
- package/src/backend/wasm/module-emitter.js +1615 -0
- package/src/backend/wasm/monomorph.js +164 -9
- package/src/backend/wasm/natives.js +596 -0
- package/src/backend/wasm/prescan.js +249 -0
- package/src/backend/wasm/prune-funcs.js +89 -0
- package/src/backend/wasm/stdlib/index.js +2 -37
- package/src/backend/wasm/stdlib/simd.js +293 -28
- package/src/backend/wasm/types.js +260 -27
- package/src/backend/wasm/variadic.js +93 -0
- package/src/backend/wasm/wat.js +47 -20
- package/src/{cli-core.js → cli/cli-core.js} +241 -11
- package/src/{test-runner.js → cli/test-runner.js} +188 -122
- package/src/{vendor.js → cli/vendor.js} +3 -4
- package/src/compiler.js +202 -386
- package/src/index.js +15 -169
- package/src/{lexer.js → lexer/lexer.js} +203 -62
- package/src/{templ-lexer.js → lexer/templ-lexer.js} +61 -18
- package/src/{tokens.js → lexer/tokens.js} +2 -0
- package/src/link/sourcemap.js +97 -0
- package/src/link/stdlib.js +737 -0
- package/src/link/type-names.js +148 -0
- package/src/link/wasm.js +318 -0
- package/src/lower/bounds.js +547 -0
- package/src/lower/boxing.js +1 -1
- package/src/lower/captures.js +267 -64
- package/src/lower/embedding.js +32 -3
- package/src/lower/errors-as.js +196 -0
- package/src/lower/fmt-formatters.js +905 -0
- package/src/lower/functions.js +2 -0
- package/src/lower/gen-types.js +274 -0
- package/src/lower/index.js +33 -19
- package/src/lower/json-codecs.js +1379 -0
- package/src/lower/ownership.js +47 -8
- package/src/lower/range.js +86 -1
- package/src/lower/reachability.js +150 -0
- package/src/lower/walk.js +12 -0
- package/src/parser/declarations.js +83 -15
- package/src/parser/expressions.js +110 -18
- package/src/parser/index.js +2 -1
- package/src/parser/statements.js +38 -22
- package/src/{templ-parser.js → parser/templ.js} +179 -17
- package/src/parser/types.js +70 -9
- package/src/resolver.js +21 -1
- package/src/typechecker/assignability.js +291 -19
- package/src/typechecker/const-fold.js +399 -0
- package/src/typechecker/constants.js +282 -0
- package/src/typechecker/expressions.js +1220 -183
- package/src/typechecker/index.js +659 -92
- package/src/typechecker/init-order.js +426 -0
- package/src/typechecker/operand-text.js +40 -0
- package/src/typechecker/resolve.js +613 -62
- package/src/typechecker/statements.js +212 -20
- package/src/typechecker/stdlib/excluded.js +902 -0
- package/src/typechecker/stdlib/index.js +38 -0
- package/src/typechecker/stdlib/simd.js +65 -15
- package/src/typechecker/termination.js +11 -2
- package/src/typechecker/types.js +268 -514
- package/stdlib/bytes/buffer.go +479 -0
- package/stdlib/bytes/bytes.go +1010 -0
- package/stdlib/bytes/reader.go +161 -0
- package/stdlib/cmp/cmp.go +65 -0
- package/stdlib/context/context.go +115 -0
- package/stdlib/crypto/rand/rand.go +34 -0
- package/stdlib/crypto/sha256/sha256.go +249 -0
- package/stdlib/encoding/base64/base64.go +331 -0
- package/stdlib/encoding/binary/binary.go +332 -0
- package/stdlib/encoding/hex/hex.go +140 -0
- package/stdlib/encoding/json/errors.go +31 -0
- package/stdlib/encoding/json/indent.go +71 -0
- package/stdlib/encoding/json/json.go +62 -0
- package/stdlib/encoding/json/number.go +12 -0
- package/stdlib/encoding/json/stream.go +173 -0
- package/stdlib/errors/errors.go +174 -0
- package/stdlib/fmt/errors.go +110 -0
- package/stdlib/fmt/format.go +732 -0
- package/stdlib/fmt/print.go +1232 -0
- package/stdlib/gom/gom.go +293 -0
- package/stdlib/hash/hash.go +53 -0
- package/stdlib/html/html.go +251 -0
- package/stdlib/internal/fmtrt/fmtrt.go +163 -0
- package/stdlib/internal/jsonrt/dec.go +871 -0
- package/stdlib/internal/jsonrt/enc.go +516 -0
- package/stdlib/internal/jsonrt/indent.go +135 -0
- package/stdlib/internal/jsonrt/number.go +27 -0
- package/stdlib/internal/jsonrt/reader.go +73 -0
- package/stdlib/internal/jsonrt/scanner.go +658 -0
- package/stdlib/io/io.go +502 -0
- package/stdlib/iter/iter.go +18 -0
- package/stdlib/maps/maps.go +131 -0
- package/stdlib/math/bits/bits.go +507 -0
- package/stdlib/math/extra.go +272 -0
- package/stdlib/math/math.go +439 -0
- package/stdlib/math/rand/rand.go +297 -0
- package/stdlib/os/os.go +93 -0
- package/stdlib/path/filepath/filepath.go +47 -0
- package/stdlib/path/path.go +394 -0
- package/stdlib/regexp/regexp.go +231 -0
- package/stdlib/slices/slices.go +526 -0
- package/stdlib/slices/sort.go +209 -0
- package/stdlib/slices/zsort_cmp.go +480 -0
- package/stdlib/slices/zsort_ordered.go +482 -0
- package/stdlib/sort/sort.go +500 -0
- package/stdlib/sort/zsort_func.go +480 -0
- package/stdlib/sort/zsort_iface.go +480 -0
- package/stdlib/strconv/float.go +1699 -0
- package/stdlib/strconv/isprint.go +752 -0
- package/stdlib/strconv/quote.go +526 -0
- package/stdlib/strconv/strconv.go +616 -0
- package/stdlib/strings/builder.go +95 -0
- package/stdlib/strings/reader.go +163 -0
- package/stdlib/strings/replacer.go +102 -0
- package/stdlib/strings/strings.go +807 -0
- package/stdlib/sync/sync.go +268 -0
- package/stdlib/testing/async_js.go +61 -0
- package/stdlib/testing/benchmark.go +297 -0
- package/stdlib/testing/testing.go +523 -0
- package/stdlib/time/duration.go +233 -0
- package/stdlib/time/format.go +745 -0
- package/stdlib/time/parse.go +790 -0
- package/stdlib/time/sleep_js.go +63 -0
- package/stdlib/time/time.go +834 -0
- package/stdlib/unicode/unicode.go +250 -0
- package/stdlib/unicode/utf8/utf8.go +464 -0
- package/src/backend/js/stdlib/base64.js +0 -12
- package/src/backend/js/stdlib/binary.js +0 -102
- package/src/backend/js/stdlib/bits.js +0 -46
- package/src/backend/js/stdlib/builder.js +0 -63
- package/src/backend/js/stdlib/bytes.js +0 -122
- package/src/backend/js/stdlib/errors.js +0 -44
- package/src/backend/js/stdlib/fmt.js +0 -178
- package/src/backend/js/stdlib/gom.js +0 -155
- package/src/backend/js/stdlib/hex.js +0 -17
- package/src/backend/js/stdlib/html.js +0 -20
- package/src/backend/js/stdlib/io.js +0 -137
- package/src/backend/js/stdlib/json.js +0 -972
- package/src/backend/js/stdlib/maps.js +0 -45
- package/src/backend/js/stdlib/math.js +0 -69
- package/src/backend/js/stdlib/os.js +0 -13
- package/src/backend/js/stdlib/path.js +0 -48
- package/src/backend/js/stdlib/rand.js +0 -32
- package/src/backend/js/stdlib/regexp.js +0 -54
- package/src/backend/js/stdlib/sha256.js +0 -12
- package/src/backend/js/stdlib/shared.js +0 -17
- package/src/backend/js/stdlib/simd.js +0 -24
- package/src/backend/js/stdlib/slices.js +0 -77
- package/src/backend/js/stdlib/sort.js +0 -30
- package/src/backend/js/stdlib/strconv.js +0 -74
- package/src/backend/js/stdlib/strings.js +0 -222
- package/src/backend/js/stdlib/sync.js +0 -13
- package/src/backend/js/stdlib/testing.js +0 -34
- package/src/backend/js/stdlib/time.js +0 -128
- package/src/backend/js/stdlib/unicode.js +0 -25
- package/src/backend/js/stdlib/utf8.js +0 -26
- package/src/backend/wasm/const-fold.js +0 -205
- package/src/backend/wasm/emit-stdlib.js +0 -13
- package/src/backend/wasm/stdlib/bytes.js +0 -5039
- package/src/backend/wasm/stdlib/core.js +0 -8903
- package/src/backend/wasm/stdlib/io.js +0 -2161
- package/src/backend/wasm/stdlib/packages.js +0 -2400
- package/src/backend/wasm/stdlib/pure.js +0 -720
- package/src/backend/wasm/stdlib/time.js +0 -1200
- package/src/typechecker/stdlib/core.js +0 -801
- package/src/typechecker/stdlib/extended.js +0 -914
- package/src/typechecker/stdlib.js +0 -22
- /package/src/{asset-manager.js → cli/asset-manager.js} +0 -0
- /package/src/{colors.js → cli/colors.js} +0 -0
- /package/src/{dev-server.js → cli/dev-server.js} +0 -0
- /package/src/{minifier.js → cli/minifier.js} +0 -0
- /package/src/{project-config.js → cli/project-config.js} +0 -0
- /package/src/{pwa.js → cli/pwa.js} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// CLI compilation core — extracted for direct import in tests.
|
|
2
|
-
// index.js retains only arg parsing,
|
|
2
|
+
// index.js retains only arg parsing, dispatch, and process.exit.
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
copyFileSync,
|
|
@@ -22,10 +22,10 @@ import {
|
|
|
22
22
|
resolve,
|
|
23
23
|
sep,
|
|
24
24
|
} from "node:path";
|
|
25
|
+
import { isGoFrontWasm } from "../backend/wasm/index.js";
|
|
26
|
+
import { compileDir, compileSingleFile } from "../compiler.js";
|
|
25
27
|
import { copyAssets } from "./asset-manager.js";
|
|
26
|
-
import {
|
|
27
|
-
import { colors, log } from "./colors.js";
|
|
28
|
-
import { compileDir, compileSingleFile } from "./compiler.js";
|
|
28
|
+
import { colors, formatDiagnostic, log, ms, stamp } from "./colors.js";
|
|
29
29
|
import { createDevServer } from "./dev-server.js";
|
|
30
30
|
import { minify } from "./minifier.js";
|
|
31
31
|
import { loadProjectConfig } from "./project-config.js";
|
|
@@ -34,7 +34,7 @@ import { runTests } from "./test-runner.js";
|
|
|
34
34
|
import { bundleVendor } from "./vendor.js";
|
|
35
35
|
|
|
36
36
|
export const GOFRONT_VERSION = JSON.parse(
|
|
37
|
-
readFileSync(new URL("
|
|
37
|
+
readFileSync(new URL("../../package.json", import.meta.url), "utf8"),
|
|
38
38
|
).version;
|
|
39
39
|
|
|
40
40
|
export function runCompile(inputPath, isDir, options) {
|
|
@@ -45,11 +45,12 @@ export function runCompile(inputPath, isDir, options) {
|
|
|
45
45
|
dumpAst = false,
|
|
46
46
|
emitWat = false,
|
|
47
47
|
wasmOpt = false,
|
|
48
|
+
natives = true,
|
|
48
49
|
forceTarget = null,
|
|
49
50
|
targetOverrides = null,
|
|
50
51
|
rootDir = null,
|
|
51
52
|
} = options ?? {};
|
|
52
|
-
const targetOpts = {};
|
|
53
|
+
const targetOpts = { natives };
|
|
53
54
|
if (forceTarget) targetOpts.forceTarget = forceTarget;
|
|
54
55
|
if (targetOverrides) targetOpts.targetOverrides = targetOverrides;
|
|
55
56
|
if (rootDir) targetOpts.rootDir = rootDir;
|
|
@@ -133,13 +134,29 @@ function stripTargetFlag(argv) {
|
|
|
133
134
|
return out;
|
|
134
135
|
}
|
|
135
136
|
|
|
137
|
+
// Creates `dir` and any missing parents. `mkdirSync(dir, { recursive: true })`
|
|
138
|
+
// retries forever when mkdir fails with ENOENT under an existing parent (as it
|
|
139
|
+
// does below /proc), so each missing segment is created on its own and the
|
|
140
|
+
// first failure is thrown.
|
|
141
|
+
export function ensureDir(dir) {
|
|
142
|
+
const missing = [];
|
|
143
|
+
let cur = resolve(dir);
|
|
144
|
+
while (!existsSync(cur)) {
|
|
145
|
+
missing.push(cur);
|
|
146
|
+
const parent = dirname(cur);
|
|
147
|
+
if (parent === cur) break;
|
|
148
|
+
cur = parent;
|
|
149
|
+
}
|
|
150
|
+
for (const d of missing.reverse()) mkdirSync(d);
|
|
151
|
+
}
|
|
152
|
+
|
|
136
153
|
// Writes the JS bundle plus, when the project links wasm packages, the
|
|
137
154
|
// sibling `app.wasm` (and `app.wat` when requested). Stale wasm artifacts
|
|
138
155
|
// are removed so a project that drops its wasm packages serves clean output —
|
|
139
156
|
// but only when the existing file is one GoFront produced (recognised by its
|
|
140
157
|
// `gofront` custom section), so a hand-placed `app.wasm` is left alone.
|
|
141
158
|
export function writeCompileOutput(outputFile, result, js = result.js) {
|
|
142
|
-
|
|
159
|
+
ensureDir(dirname(outputFile));
|
|
143
160
|
writeFileSync(outputFile, `${js}\n`);
|
|
144
161
|
const wasmFile = join(dirname(outputFile), "app.wasm");
|
|
145
162
|
const watFile = join(dirname(outputFile), "app.wat");
|
|
@@ -273,7 +290,7 @@ node_modules/
|
|
|
273
290
|
|
|
274
291
|
export function handleInit(targetDir) {
|
|
275
292
|
try {
|
|
276
|
-
|
|
293
|
+
ensureDir(targetDir);
|
|
277
294
|
} catch (e) {
|
|
278
295
|
throw new Error(`cannot create '${targetDir}': ${e.message}`);
|
|
279
296
|
}
|
|
@@ -286,7 +303,7 @@ export function handleInit(targetDir) {
|
|
|
286
303
|
|
|
287
304
|
for (const { path: filePath, content } of templates) {
|
|
288
305
|
try {
|
|
289
|
-
|
|
306
|
+
ensureDir(dirname(filePath));
|
|
290
307
|
writeFileSync(filePath, content);
|
|
291
308
|
} catch (e) {
|
|
292
309
|
throw new Error(`cannot write '${filePath}': ${e.message}`);
|
|
@@ -334,6 +351,7 @@ export function formatPrepSummary({ assets, vendor }) {
|
|
|
334
351
|
|
|
335
352
|
export function parseTestArgs(argv) {
|
|
336
353
|
let run = null;
|
|
354
|
+
let bench = null;
|
|
337
355
|
const positional = [];
|
|
338
356
|
const rest = stripTargetFlag(argv);
|
|
339
357
|
for (let i = 0; i < rest.length; i++) {
|
|
@@ -342,6 +360,15 @@ export function parseTestArgs(argv) {
|
|
|
342
360
|
run = rest[++i] ?? null;
|
|
343
361
|
} else if (arg.startsWith("-run=") || arg.startsWith("--run=")) {
|
|
344
362
|
run = arg.slice(arg.indexOf("=") + 1);
|
|
363
|
+
} else if (arg === "-bench" || arg === "--bench") {
|
|
364
|
+
const next = rest[i + 1];
|
|
365
|
+
if (next !== undefined && !next.startsWith("-")) {
|
|
366
|
+
bench = rest[++i];
|
|
367
|
+
} else {
|
|
368
|
+
bench = true;
|
|
369
|
+
}
|
|
370
|
+
} else if (arg.startsWith("-bench=") || arg.startsWith("--bench=")) {
|
|
371
|
+
bench = arg.slice(arg.indexOf("=") + 1);
|
|
345
372
|
} else if (!arg.startsWith("-")) {
|
|
346
373
|
positional.push(arg);
|
|
347
374
|
}
|
|
@@ -351,6 +378,7 @@ export function parseTestArgs(argv) {
|
|
|
351
378
|
verbose: argv.includes("-v"),
|
|
352
379
|
dom: argv.includes("--dom"),
|
|
353
380
|
run,
|
|
381
|
+
bench,
|
|
354
382
|
forceTarget: parseTargetFlag(argv),
|
|
355
383
|
};
|
|
356
384
|
}
|
|
@@ -605,6 +633,7 @@ export function parseBuildArgs(argv) {
|
|
|
605
633
|
const noWasmOpt = argv.includes("--no-wasm-opt");
|
|
606
634
|
const wasmOpt = !noWasmOpt && (argv.includes("--wasm-opt") || release);
|
|
607
635
|
const forceTarget = parseTargetFlag(argv);
|
|
636
|
+
const natives = !argv.includes("--no-natives");
|
|
608
637
|
|
|
609
638
|
for (let i = 0; i < argv.length; i++) {
|
|
610
639
|
const arg = argv[i];
|
|
@@ -629,6 +658,7 @@ export function parseBuildArgs(argv) {
|
|
|
629
658
|
mangle: !noMangle && !noMinify,
|
|
630
659
|
release,
|
|
631
660
|
wasmOpt,
|
|
661
|
+
natives,
|
|
632
662
|
forceTarget,
|
|
633
663
|
};
|
|
634
664
|
}
|
|
@@ -662,7 +692,11 @@ function cleanOutputDir(outDir, project, srcDir) {
|
|
|
662
692
|
if (isSafe && existsSync(resolvedOut)) {
|
|
663
693
|
rmSync(resolvedOut, { recursive: true, force: true });
|
|
664
694
|
}
|
|
665
|
-
|
|
695
|
+
try {
|
|
696
|
+
ensureDir(resolvedOut);
|
|
697
|
+
} catch (e) {
|
|
698
|
+
throw new Error(`cannot write '${outDir}': ${e.message}`);
|
|
699
|
+
}
|
|
666
700
|
}
|
|
667
701
|
|
|
668
702
|
const STATIC_ASSET_EXTS = new Set([
|
|
@@ -734,7 +768,7 @@ function copyServeDirAssets(project, outDir, srcDir) {
|
|
|
734
768
|
const copyFile = (full) => {
|
|
735
769
|
const dest = join(out, relative(serveDir, full));
|
|
736
770
|
if (existsSync(dest)) return;
|
|
737
|
-
|
|
771
|
+
ensureDir(dirname(dest));
|
|
738
772
|
copyFileSync(full, dest);
|
|
739
773
|
copied++;
|
|
740
774
|
};
|
|
@@ -827,6 +861,7 @@ export async function handleBuild(targetDir = ".", options = {}) {
|
|
|
827
861
|
sourceMap: options.sourceMap ?? false,
|
|
828
862
|
emitWat: options.emitWat ?? false,
|
|
829
863
|
wasmOpt: options.wasmOpt ?? false,
|
|
864
|
+
natives: options.natives ?? true,
|
|
830
865
|
forceTarget: options.forceTarget ?? null,
|
|
831
866
|
...projectTargetOptions(project, options),
|
|
832
867
|
});
|
|
@@ -908,6 +943,201 @@ export function parseLegacyArgs(argv) {
|
|
|
908
943
|
};
|
|
909
944
|
}
|
|
910
945
|
|
|
946
|
+
// `gofront --help` text.
|
|
947
|
+
export const HELP_TEXT = `
|
|
948
|
+
GoFront — a Go-inspired language that compiles to JavaScript and WebAssembly
|
|
949
|
+
|
|
950
|
+
Usage:
|
|
951
|
+
gofront dev [dir] [options] Start dev server with live reload (default port 3000)
|
|
952
|
+
gofront build [dir] [options] Build production bundle (-o <dir>, --pwa, --minify, --emit-wat, --release, --wasm-opt, --js-only)
|
|
953
|
+
gofront check [dir|dir/...] Type-check only (dir/... recurses into every package)
|
|
954
|
+
gofront test [dir|dir/...] [--dom] Run unit tests (-v verbose, -run <regex>, -bench <regex>)
|
|
955
|
+
gofront prep [dir] [--minify] Copy static assets and bundle vendor dependencies
|
|
956
|
+
gofront init [dir] Scaffold a new GoFront project
|
|
957
|
+
gofront <file.go> Compile single file and print to stdout
|
|
958
|
+
gofront <dir> (or gofront .) Compile all *.go in directory as one bundle
|
|
959
|
+
gofront <input> -o out.js Compile and write to file (wasm packages also emit app.wasm)
|
|
960
|
+
gofront <input> --release Production build with minification and Binaryen wasm optimization
|
|
961
|
+
gofront <input> --wasm-opt Optimize wasm output with Binaryen (-O3 + GUFA)
|
|
962
|
+
gofront <input> --check Type-check only
|
|
963
|
+
gofront <input> --watch Watch for changes and recompile
|
|
964
|
+
gofront <input> -o out.js --serve Watch + serve with live reload (default port 3000)
|
|
965
|
+
gofront <input> -o out.js --serve --port 8080 Use a custom port
|
|
966
|
+
gofront <input> -o out.js --copy-assets Compile and synchronize static assets
|
|
967
|
+
gofront <input> --source-map Append inline source map to output
|
|
968
|
+
gofront <input> --minify Minify output
|
|
969
|
+
gofront <input> --minify --mangle Minify and mangle identifiers
|
|
970
|
+
gofront <file.go> --ast Dump AST (debug)
|
|
971
|
+
gofront <file.go> --tokens Dump tokens (debug)
|
|
972
|
+
gofront --version Print version
|
|
973
|
+
`.trim();
|
|
974
|
+
|
|
975
|
+
// Print the `gofront check` result: one OK line per package, then a total.
|
|
976
|
+
export function reportCheck({ elapsedMs, packages }, targetDir) {
|
|
977
|
+
const okLine = (label, t) =>
|
|
978
|
+
log.info(`${colors.cyan(label)} — ${colors.green("OK")} ${ms(t)}`);
|
|
979
|
+
if (packages) {
|
|
980
|
+
for (const pkg of packages) {
|
|
981
|
+
okLine(relative(process.cwd(), pkg.dir) || ".", pkg.elapsedMs);
|
|
982
|
+
}
|
|
983
|
+
log.info(
|
|
984
|
+
`${colors.bold(`${packages.length} packages`)} — ${colors.bold(colors.green("OK"))} ${ms(elapsedMs)}`,
|
|
985
|
+
);
|
|
986
|
+
} else {
|
|
987
|
+
okLine(targetDir, elapsedMs);
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
// Print the `gofront build` summary lines.
|
|
992
|
+
export function reportBuild(result) {
|
|
993
|
+
for (const line of formatBuildSummary(result)) {
|
|
994
|
+
log.info(
|
|
995
|
+
line
|
|
996
|
+
.replace(/^build complete/, colors.green("build complete"))
|
|
997
|
+
.replace(/\(([\d.]+ kB)\)$/, (_, s) => colors.dim(`(${s})`)),
|
|
998
|
+
);
|
|
999
|
+
}
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
// Copy the project's static assets into place; failures only warn.
|
|
1003
|
+
export function copyProjectAssets(verbose, projectDir = ".") {
|
|
1004
|
+
try {
|
|
1005
|
+
const { copied, skipped } = copyAssets(resolve(projectDir));
|
|
1006
|
+
if (verbose && (copied > 0 || skipped > 0)) {
|
|
1007
|
+
log.info(`copied ${copied} assets (${skipped} skipped)`);
|
|
1008
|
+
}
|
|
1009
|
+
} catch (e) {
|
|
1010
|
+
log.warn(`asset copy failed: ${e.message}`);
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
// Legacy `gofront <input> [flags]` single-shot flow. `flags` is the result of
|
|
1015
|
+
// parseLegacyArgs. Returns the process exit code.
|
|
1016
|
+
export function runSingleShot(inputPath, isDir, flags) {
|
|
1017
|
+
const {
|
|
1018
|
+
inputArg,
|
|
1019
|
+
outputFile,
|
|
1020
|
+
checkOnly,
|
|
1021
|
+
dumpAst,
|
|
1022
|
+
dumpTokens,
|
|
1023
|
+
sourceMap,
|
|
1024
|
+
copyAssets: copyAssetsFlag,
|
|
1025
|
+
wasmOpt,
|
|
1026
|
+
minify: minifyOutput,
|
|
1027
|
+
mangle: mangleOutput,
|
|
1028
|
+
forceTarget,
|
|
1029
|
+
} = flags;
|
|
1030
|
+
|
|
1031
|
+
let result;
|
|
1032
|
+
const startMs = performance.now();
|
|
1033
|
+
try {
|
|
1034
|
+
result = runCompile(inputPath, isDir, {
|
|
1035
|
+
sourceMap,
|
|
1036
|
+
outputFile,
|
|
1037
|
+
dumpTokens,
|
|
1038
|
+
dumpAst,
|
|
1039
|
+
wasmOpt,
|
|
1040
|
+
forceTarget,
|
|
1041
|
+
});
|
|
1042
|
+
} catch (e) {
|
|
1043
|
+
log.fail(e.message);
|
|
1044
|
+
return 1;
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
if (result.tokens) {
|
|
1048
|
+
for (const tok of result.tokens) console.log(tok.toString());
|
|
1049
|
+
return 0;
|
|
1050
|
+
}
|
|
1051
|
+
if (result.ast) {
|
|
1052
|
+
console.log(JSON.stringify(result.ast, null, 2));
|
|
1053
|
+
return 0;
|
|
1054
|
+
}
|
|
1055
|
+
|
|
1056
|
+
if (checkOnly) {
|
|
1057
|
+
const elapsedMs = (performance.now() - startMs).toFixed(0);
|
|
1058
|
+
log.info(
|
|
1059
|
+
`${colors.cyan(inputArg)} — ${colors.green("OK")} ${ms(elapsedMs)}`,
|
|
1060
|
+
);
|
|
1061
|
+
return 0;
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
let js;
|
|
1065
|
+
try {
|
|
1066
|
+
js = maybeMinify(result.js, {
|
|
1067
|
+
minify: minifyOutput,
|
|
1068
|
+
mangle: mangleOutput,
|
|
1069
|
+
sourceMap,
|
|
1070
|
+
});
|
|
1071
|
+
} catch (e) {
|
|
1072
|
+
log.fail(`minify failed: ${e.message}`);
|
|
1073
|
+
return 1;
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
const elapsedMs = (performance.now() - startMs).toFixed(0);
|
|
1077
|
+
|
|
1078
|
+
if (outputFile) {
|
|
1079
|
+
try {
|
|
1080
|
+
const written = writeCompileOutput(resolve(outputFile), result, js);
|
|
1081
|
+
log.info(
|
|
1082
|
+
`wrote ${formatWrittenDesc(written, outputFile)} ${ms(elapsedMs)}`,
|
|
1083
|
+
);
|
|
1084
|
+
if (result.wasmOptInfo && result.wasmOptInfo.originalSize > 0) {
|
|
1085
|
+
const origKb = (result.wasmOptInfo.originalSize / 1024).toFixed(1);
|
|
1086
|
+
const optKb = (result.wasmOptInfo.optimizedSize / 1024).toFixed(1);
|
|
1087
|
+
log.info(
|
|
1088
|
+
`wasm-opt: app.wasm ${origKb} kB → ${optKb} kB (-${result.wasmOptInfo.percentSaved}%) [${result.wasmOptInfo.engine}]`,
|
|
1089
|
+
);
|
|
1090
|
+
}
|
|
1091
|
+
} catch (e) {
|
|
1092
|
+
log.fail(`cannot write '${outputFile}': ${e.message}`);
|
|
1093
|
+
return 1;
|
|
1094
|
+
}
|
|
1095
|
+
} else {
|
|
1096
|
+
console.log(js);
|
|
1097
|
+
if (result.wasm) {
|
|
1098
|
+
log.warn(
|
|
1099
|
+
"wasm packages were linked but app.wasm needs -o <file> to be written",
|
|
1100
|
+
);
|
|
1101
|
+
}
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
if (copyAssetsFlag) copyProjectAssets(true);
|
|
1105
|
+
|
|
1106
|
+
return 0;
|
|
1107
|
+
}
|
|
1108
|
+
|
|
1109
|
+
// Reporters for the legacy `--watch` mode: build and error lines on stderr
|
|
1110
|
+
// (the compiled JS goes to stdout when there is no output file).
|
|
1111
|
+
export function devReporters({
|
|
1112
|
+
outputFile = null,
|
|
1113
|
+
copyAssets = false,
|
|
1114
|
+
projectDir = ".",
|
|
1115
|
+
} = {}) {
|
|
1116
|
+
const prefix = () => `${stamp()} ${colors.bold("gofront:")}`;
|
|
1117
|
+
return {
|
|
1118
|
+
onBuild: ({ js, written, elapsedMs, changedFile }) => {
|
|
1119
|
+
const changeNote = changedFile ? ` — ${changedFile} changed` : "";
|
|
1120
|
+
const timing = colors.dim(`(${elapsedMs}ms${changeNote})`);
|
|
1121
|
+
if (outputFile) {
|
|
1122
|
+
console.error(
|
|
1123
|
+
`${prefix()} ${colors.green("OK")} — wrote ${formatWrittenDesc(written, outputFile)} ${timing}`,
|
|
1124
|
+
);
|
|
1125
|
+
} else {
|
|
1126
|
+
// Clear screen then print
|
|
1127
|
+
process.stdout.write("\x1Bc");
|
|
1128
|
+
console.log(js);
|
|
1129
|
+
console.error(`${prefix()} ${colors.green("OK")} ${timing}`);
|
|
1130
|
+
}
|
|
1131
|
+
if (copyAssets) copyProjectAssets(false, projectDir);
|
|
1132
|
+
},
|
|
1133
|
+
onError: (e) => {
|
|
1134
|
+
console.error(`${prefix()} ${colors.bold(colors.red("ERROR"))}`);
|
|
1135
|
+
for (const line of formatDiagnostic(e.message).split("\n"))
|
|
1136
|
+
console.error(` ${line}`);
|
|
1137
|
+
},
|
|
1138
|
+
};
|
|
1139
|
+
}
|
|
1140
|
+
|
|
911
1141
|
// ── dev command ───────────────────────────────────────────────
|
|
912
1142
|
|
|
913
1143
|
export function parseDevArgs(argv) {
|