@xnoxs/flux-lang 3.5.2 → 4.0.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/src/self/pkg.flux CHANGED
@@ -24,16 +24,17 @@ val FLUX_PKG_DIR = "flux_modules"
24
24
  val PKG_FILE = "flux.json"
25
25
 
26
26
  // ── ANSI colors ───────────────────────────────────────────────
27
+ val ESC = "\u001b"
27
28
  val C = {
28
- reset: "\u001b[0m",
29
- bold: "\u001b[1m",
30
- dim: "\u001b[2m",
31
- red: "\u001b[31m",
32
- green: "\u001b[32m",
33
- yellow: "\u001b[33m",
34
- blue: "\u001b[34m",
35
- cyan: "\u001b[36m",
36
- gray: "\u001b[90m",
29
+ reset: ESC + "[0m",
30
+ bold: ESC + "[1m",
31
+ dim: ESC + "[2m",
32
+ red: ESC + "[31m",
33
+ green: ESC + "[32m",
34
+ yellow: ESC + "[33m",
35
+ blue: ESC + "[34m",
36
+ cyan: ESC + "[36m",
37
+ gray: ESC + "[90m",
37
38
  }
38
39
 
39
40
  fn clr(c, s): return c + s + C.reset
@@ -41,6 +42,24 @@ fn ok(msg): console.log(clr(C.green, "✓ ") + msg)
41
42
  fn err(msg): console.error(clr(C.red, "✗ ") + msg)
42
43
  fn info(msg): console.log(clr(C.cyan, " ") + msg)
43
44
 
45
+ // ── Spinner ───────────────────────────────────────────────────
46
+ val SPIN_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]
47
+ val stdout = process.stdout
48
+
49
+ fn startSpinner(label):
50
+ if not stdout.isTTY: return null
51
+ var frame = 0
52
+ fn tick():
53
+ stdout.write("\r" + clr(C.cyan, SPIN_FRAMES[frame % SPIN_FRAMES.length]) + " " + label + " ")
54
+ frame = frame + 1
55
+ val timer = setInterval(tick, 80)
56
+ return timer
57
+
58
+ fn stopSpinner(timer):
59
+ if not timer: return
60
+ clearInterval(timer)
61
+ stdout.write("\r" + ESC + "[2K")
62
+
44
63
  // ── HTTP fetch (Node built-in, no dependencies) ───────────────
45
64
  async fn fetchJson(url):
46
65
  val mod = url.startsWith("https") ? Https : Http
@@ -103,13 +122,14 @@ export async fn cmdAdd(specs, opts):
103
122
 
104
123
  for spec in specs:
105
124
  val { name, version } = parsePackageSpec(spec)
106
- console.log(clr(C.cyan, "\n Adding ") + clr(C.bold, name) + clr(C.gray, "@" + version) + " ...")
125
+ val spinner = startSpinner("Fetching " + clr(C.bold, name) + clr(C.gray, "@" + version) + " ...")
107
126
 
108
127
  try:
109
128
  val info_ = await fetchJson(REGISTRY_URL + "/" + name)
110
129
  val resolvedVersion = version == "latest" ? (info_["dist-tags"]?.latest ?? "1.0.0") : version
111
130
 
112
131
  val versionInfo = info_.versions?.[resolvedVersion]
132
+ stopSpinner(spinner)
113
133
  if not versionInfo:
114
134
  err("Version " + resolvedVersion + " not found for " + name)
115
135
  continue
@@ -125,6 +145,7 @@ export async fn cmdAdd(specs, opts):
125
145
  info("Added to " + (isDev ? "devDependencies" : "dependencies"))
126
146
 
127
147
  catch(e):
148
+ stopSpinner(spinner)
128
149
  err("Failed to fetch " + name + ": " + e.message)
129
150
 
130
151
  console.log()
@@ -302,6 +323,82 @@ export async fn cmdInfo(name, opts):
302
323
  catch(e):
303
324
  err("Could not fetch info for " + name + ": " + e.message)
304
325
 
326
+ // ── flux upgrade [--check] ────────────────────────────────────
327
+ export async fn cmdUpgrade(opts):
328
+ val isCheck = opts?.check ?? false
329
+ val cwd = process.cwd()
330
+ val pkg = readPackage(cwd)
331
+
332
+ if not pkg:
333
+ err("No flux.json found. Run: flux init")
334
+ return
335
+
336
+ val deps = pkg.dependencies ?? {}
337
+ val devDeps = pkg.devDependencies ?? {}
338
+ val all = { ...deps, ...devDeps }
339
+ val names = Object.keys(all)
340
+
341
+ if names.length == 0:
342
+ info("No dependencies to upgrade")
343
+ console.log()
344
+ return
345
+
346
+ if isCheck:
347
+ console.log(clr(C.cyan, "\n Checking " + names.length + " package(s) for updates...\n"))
348
+ else:
349
+ console.log(clr(C.cyan, "\n Upgrading " + names.length + " package(s) to latest...\n"))
350
+
351
+ var outdated = 0
352
+ var updated = 0
353
+
354
+ for name in names:
355
+ val current = all[name]
356
+ val spinner = startSpinner("Checking " + clr(C.bold, name) + " ...")
357
+ try:
358
+ val info_ = await fetchJson(REGISTRY_URL + "/" + name)
359
+ val latest = info_["dist-tags"]?.latest ?? null
360
+ stopSpinner(spinner)
361
+
362
+ if not latest:
363
+ console.log(" " + clr(C.gray, "? ") + clr(C.bold, name) + clr(C.gray, " — could not resolve latest"))
364
+ continue
365
+
366
+ val currentClean = current.replace("^", "").replace("~", "")
367
+ if currentClean == latest:
368
+ console.log(" " + clr(C.green, "✓ ") + clr(C.bold, name) + clr(C.gray, " " + current + " (up to date)"))
369
+ else:
370
+ outdated = outdated + 1
371
+ if isCheck:
372
+ console.log(" " + clr(C.yellow, "↑ ") + clr(C.bold, name) + clr(C.gray, " " + current + " → ") + clr(C.green, "^" + latest))
373
+ else:
374
+ val isDev = devDeps[name] != null
375
+ val depKey = isDev ? "devDependencies" : "dependencies"
376
+ pkg[depKey][name] = "^" + latest
377
+ updated = updated + 1
378
+ console.log(" " + clr(C.green, "✓ ") + clr(C.bold, name) + clr(C.gray, " " + current + " → ") + clr(C.green, "^" + latest))
379
+
380
+ catch(e):
381
+ stopSpinner(spinner)
382
+ console.log(" " + clr(C.red, "✗ ") + clr(C.bold, name) + clr(C.gray, " — " + e.message))
383
+
384
+ console.log()
385
+
386
+ if isCheck:
387
+ if outdated == 0:
388
+ ok("All packages are up to date")
389
+ else:
390
+ console.log(clr(C.yellow, " " + outdated + " package(s) can be upgraded"))
391
+ console.log(clr(C.gray, " Run ") + clr(C.yellow, "flux upgrade") + clr(C.gray, " to apply updates"))
392
+ else:
393
+ if updated == 0:
394
+ ok("All packages are already up to date")
395
+ else:
396
+ saveFluxJson(pkg, cwd)
397
+ ok(updated + " package(s) updated in flux.json")
398
+ console.log(clr(C.gray, " Run ") + clr(C.yellow, "flux install") + clr(C.gray, " to install updated versions"))
399
+
400
+ console.log()
401
+
305
402
  // ── flux publish ──────────────────────────────────────────────
306
403
  export fn cmdPublish(opts):
307
404
  val cwd = process.cwd()
package/src/self/pkg.js CHANGED
@@ -21,7 +21,8 @@ const { readPackage, writeConfig, loadConfig } = require("./config");
21
21
  const REGISTRY_URL = "https://registry.npmjs.org";
22
22
  const FLUX_PKG_DIR = "flux_modules";
23
23
  const PKG_FILE = "flux.json";
24
- const C = { reset: "\\u001b[0m", bold: "\\u001b[1m", dim: "\\u001b[2m", red: "\\u001b[31m", green: "\\u001b[32m", yellow: "\\u001b[33m", blue: "\\u001b[34m", cyan: "\\u001b[36m", gray: "\\u001b[90m" };
24
+ const ESC = "\u001b";
25
+ const C = { reset: (ESC + "[0m"), bold: (ESC + "[1m"), dim: (ESC + "[2m"), red: (ESC + "[31m"), green: (ESC + "[32m"), yellow: (ESC + "[33m"), blue: (ESC + "[34m"), cyan: (ESC + "[36m"), gray: (ESC + "[90m") };
25
26
  function clr(c, s) {
26
27
  return ((c + s) + C.reset);
27
28
  }
@@ -34,6 +35,27 @@ function err(msg) {
34
35
  function info(msg) {
35
36
  console.log((clr(C.cyan, " ") + msg));
36
37
  }
38
+ const SPIN_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
39
+ const stdout = process.stdout;
40
+ function startSpinner(label) {
41
+ if (!stdout.isTTY) {
42
+ return null;
43
+ }
44
+ let frame = 0;
45
+ function tick() {
46
+ stdout.write((((("\r" + clr(C.cyan, SPIN_FRAMES[(frame % SPIN_FRAMES.length)])) + " ") + label) + " "));
47
+ frame = (frame + 1);
48
+ }
49
+ const timer = setInterval(tick, 80);
50
+ return timer;
51
+ }
52
+ function stopSpinner(timer) {
53
+ if (!timer) {
54
+ return;
55
+ }
56
+ clearInterval(timer);
57
+ stdout.write((("\r" + ESC) + "[2K"));
58
+ }
37
59
  async function fetchJson(url) {
38
60
  const mod = (url.startsWith("https") ? Https : Http);
39
61
  function doRequest(resolve, reject) {
@@ -85,11 +107,12 @@ async function cmdAdd(specs, opts) {
85
107
  const pkg = ensureFluxJson(cwd);
86
108
  for (const spec of specs) {
87
109
  const { name, version } = parsePackageSpec(spec);
88
- console.log((((clr(C.cyan, "\n Adding ") + clr(C.bold, name)) + clr(C.gray, ("@" + version))) + " ..."));
110
+ const spinner = startSpinner(((("Fetching " + clr(C.bold, name)) + clr(C.gray, ("@" + version))) + " ..."));
89
111
  try {
90
112
  const info_ = await fetchJson(((REGISTRY_URL + "/") + name));
91
113
  const resolvedVersion = ((version == "latest") ? (info_["dist-tags"]?.latest ?? "1.0.0") : version);
92
114
  const versionInfo = info_.versions?.[resolvedVersion];
115
+ stopSpinner(spinner);
93
116
  if (!versionInfo) {
94
117
  err(((("Version " + resolvedVersion) + " not found for ") + name));
95
118
  continue;
@@ -105,6 +128,7 @@ async function cmdAdd(specs, opts) {
105
128
  info(("Added to " + (isDev ? "devDependencies" : "dependencies")));
106
129
  }
107
130
  catch (e) {
131
+ stopSpinner(spinner);
108
132
  err(((("Failed to fetch " + name) + ": ") + e.message));
109
133
  }
110
134
  }
@@ -286,6 +310,88 @@ async function cmdInfo(name, opts) {
286
310
  }
287
311
  }
288
312
  module.exports.cmdInfo = cmdInfo;
313
+ async function cmdUpgrade(opts) {
314
+ const isCheck = (opts?.check ?? false);
315
+ const cwd = process.cwd();
316
+ const pkg = readPackage(cwd);
317
+ if (!pkg) {
318
+ err("No flux.json found. Run: flux init");
319
+ return;
320
+ }
321
+ const deps = (pkg.dependencies ?? { });
322
+ const devDeps = (pkg.devDependencies ?? { });
323
+ const all = { ...deps, ...devDeps };
324
+ const names = Object.keys(all);
325
+ if ((names.length == 0)) {
326
+ info("No dependencies to upgrade");
327
+ console.log();
328
+ return;
329
+ }
330
+ if (isCheck) {
331
+ console.log(clr(C.cyan, (("\n Checking " + names.length) + " package(s) for updates...\n")));
332
+ }
333
+ else {
334
+ console.log(clr(C.cyan, (("\n Upgrading " + names.length) + " package(s) to latest...\n")));
335
+ }
336
+ let outdated = 0;
337
+ let updated = 0;
338
+ for (const name of names) {
339
+ const current = all[name];
340
+ const spinner = startSpinner((("Checking " + clr(C.bold, name)) + " ..."));
341
+ try {
342
+ const info_ = await fetchJson(((REGISTRY_URL + "/") + name));
343
+ const latest = (info_["dist-tags"]?.latest ?? null);
344
+ stopSpinner(spinner);
345
+ if (!latest) {
346
+ console.log((((" " + clr(C.gray, "? ")) + clr(C.bold, name)) + clr(C.gray, " — could not resolve latest")));
347
+ continue;
348
+ }
349
+ const currentClean = current.replace("^", "").replace("~", "");
350
+ if ((currentClean == latest)) {
351
+ console.log((((" " + clr(C.green, "✓ ")) + clr(C.bold, name)) + clr(C.gray, ((" " + current) + " (up to date)"))));
352
+ }
353
+ else {
354
+ outdated = (outdated + 1);
355
+ if (isCheck) {
356
+ console.log(((((" " + clr(C.yellow, "↑ ")) + clr(C.bold, name)) + clr(C.gray, ((" " + current) + " → "))) + clr(C.green, ("^" + latest))));
357
+ }
358
+ else {
359
+ const isDev = (devDeps[name] != null);
360
+ const depKey = (isDev ? "devDependencies" : "dependencies");
361
+ pkg[depKey][name] = ("^" + latest);
362
+ updated = (updated + 1);
363
+ console.log(((((" " + clr(C.green, "✓ ")) + clr(C.bold, name)) + clr(C.gray, ((" " + current) + " → "))) + clr(C.green, ("^" + latest))));
364
+ }
365
+ }
366
+ }
367
+ catch (e) {
368
+ stopSpinner(spinner);
369
+ console.log((((" " + clr(C.red, "✗ ")) + clr(C.bold, name)) + clr(C.gray, (" — " + e.message))));
370
+ }
371
+ }
372
+ console.log();
373
+ if (isCheck) {
374
+ if ((outdated == 0)) {
375
+ ok("All packages are up to date");
376
+ }
377
+ else {
378
+ console.log(clr(C.yellow, ((" " + outdated) + " package(s) can be upgraded")));
379
+ console.log(((clr(C.gray, " Run ") + clr(C.yellow, "flux upgrade")) + clr(C.gray, " to apply updates")));
380
+ }
381
+ }
382
+ else {
383
+ if ((updated == 0)) {
384
+ ok("All packages are already up to date");
385
+ }
386
+ else {
387
+ saveFluxJson(pkg, cwd);
388
+ ok((updated + " package(s) updated in flux.json"));
389
+ console.log(((clr(C.gray, " Run ") + clr(C.yellow, "flux install")) + clr(C.gray, " to install updated versions")));
390
+ }
391
+ }
392
+ console.log();
393
+ }
394
+ module.exports.cmdUpgrade = cmdUpgrade;
289
395
  function cmdPublish(opts) {
290
396
  const cwd = process.cwd();
291
397
  const pkg = readPackage(cwd);
@@ -21,7 +21,7 @@ function repeat(s, n) { return String(s).repeat(n); }
21
21
  const Fs = require("fs");
22
22
  const Path = require("path");
23
23
  const Os = require("os");
24
- const C = { reset: "\\u001b[0m", bold: "\\u001b[1m", red: "\\u001b[31m", green: "\\u001b[32m", yellow: "\\u001b[33m", cyan: "\\u001b[36m", gray: "\\u001b[90m", dim: "\\u001b[2m" };
24
+ const C = { reset: "\u001b[0m", bold: "\u001b[1m", red: "\u001b[31m", green: "\u001b[32m", yellow: "\u001b[33m", cyan: "\u001b[36m", gray: "\u001b[90m", dim: "\u001b[2m" };
25
25
  function clr(c, s) {
26
26
  return (process.env.NO_COLOR ? s : ((c + s) + C.reset));
27
27
  }
@@ -1,5 +1,5 @@
1
1
  // ============================================================
2
- // Flux Self-Hosted Transpiler — v3.0 (100% Self-Hosting)
2
+ // Flux Self-Hosted Transpiler — v3.5 (100% Self-Hosting)
3
3
  // src/self/transpiler.flux — written in Flux, compiled by stage-0
4
4
  //
5
5
  // Full pipeline:
@@ -15,8 +15,18 @@ import { transformJsx, FLUX_H_BROWSER, FLUX_H_SERVER, FLUX_CSS_BROWSER, FLUX_CSS
15
15
  import { Checker } from './checker'
16
16
  import { FluxTypeChecker } from './type-checker'
17
17
 
18
- // ── Version info ─────────────────────────────────────────────
19
- export val FLUX_VERSION = "3.0.0"
18
+ // ── Version info — always in sync with package.json ──────────
19
+ import Fs from "fs"
20
+ import Path from "path"
21
+
22
+ fn _readFluxVersion():
23
+ try:
24
+ val pkgPath = Path.resolve(__dirname, "../../package.json")
25
+ return JSON.parse(Fs.readFileSync(pkgPath, "utf8")).version
26
+ catch(e):
27
+ return "4.0.0"
28
+
29
+ export val FLUX_VERSION = _readFluxVersion()
20
30
  export val FLUX_STAGE = "self-hosted"
21
31
 
22
32
  // ── Public API ────────────────────────────────────────────────
@@ -89,7 +99,7 @@ export fn transpile(source, options):
89
99
  // ── Stage 5: Code generation ────────────────────────────────
90
100
  result.stage = "codegen"
91
101
  val indent = opts.mangle ? "" : " "
92
- val cg = makeCodeGen({ indent })
102
+ val cg = makeCodeGen({ indent, version: FLUX_VERSION })
93
103
  val genResult = cg.generate(ast)
94
104
  var code = genResult.code
95
105
 
@@ -1,83 +1 @@
1
- // Generated by Flux Transpiler v3.2.0
2
- "use strict";
3
-
4
- const { Lexer, lexerize, T } = require("./lexer");
5
- const { Parser, makeParser } = require("./parser");
6
- const { CodeGenerator, makeCodeGen } = require("./codegen");
7
- const { transformCss } = require("./css-preprocessor");
8
- const { transformJsx, FLUX_H_BROWSER, FLUX_H_SERVER, FLUX_CSS_BROWSER, FLUX_CSS_SERVER } = require("./jsx");
9
- const { Checker } = require("./checker");
10
- const { FluxTypeChecker } = require("./type-checker");
11
- const FLUX_VERSION = "3.0.0";
12
- module.exports.FLUX_VERSION = FLUX_VERSION;
13
- const FLUX_STAGE = "self-hosted";
14
- module.exports.FLUX_STAGE = FLUX_STAGE;
15
- function transpile(source, options) {
16
- const opts = (options ?? { });
17
- const result = { success: false, output: "", ast: null, tokens: null, errors: [], typeErrors: [], typeWarnings: [], stage: "" };
18
- try {
19
- let src = source;
20
- result.stage = "css";
21
- if ((opts.css != false)) {
22
- src = transformCss(src);
23
- }
24
- result.stage = "jsx";
25
- if (opts.jsx) {
26
- const jsxTarget = (opts.jsxTarget ?? "browser");
27
- const jsxResult = transformJsx(src, { target: jsxTarget });
28
- src = jsxResult.source;
29
- if (jsxResult.hasJsx) {
30
- opts._jsxHelpers = jsxResult.runtimeHelpers;
31
- }
32
- }
33
- result.stage = "lexer";
34
- const lexer = lexerize(src);
35
- const tokens = lexer.tokenize();
36
- result.tokens = tokens;
37
- result.stage = "parser";
38
- const ast = makeParser(tokens).parse();
39
- result.ast = ast;
40
- if ((opts.check != false)) {
41
- result.stage = "checker";
42
- const checker = new Checker([], []);
43
- const checkResult = checker.check(ast);
44
- if ((checkResult.errors.length > 0)) {
45
- result.errors = checkResult.errors;
46
- result.stage = null;
47
- return result;
48
- }
49
- }
50
- if (opts.typecheck) {
51
- result.stage = "type-checker";
52
- const tc = new FluxTypeChecker([], [], new Map(), new Map(), new Map(), new Map());
53
- const tcResult = tc.check(ast);
54
- result.typeErrors = tcResult.errors;
55
- result.typeWarnings = tcResult.warnings;
56
- if ((opts.strict && (tcResult.errors.length > 0))) {
57
- result.errors = tcResult.errors;
58
- result.stage = null;
59
- return result;
60
- }
61
- }
62
- result.stage = "codegen";
63
- const indent = (opts.mangle ? "" : " ");
64
- const cg = makeCodeGen({ indent });
65
- const genResult = cg.generate(ast);
66
- let code = genResult.code;
67
- if (opts._jsxHelpers) {
68
- code = ((opts._jsxHelpers + "\n") + code);
69
- }
70
- result.output = code;
71
- result.success = true;
72
- result.stage = null;
73
- }
74
- catch (e) {
75
- result.errors.push({ message: e.message, name: e.name, stage: result.stage });
76
- }
77
- return result;
78
- }
79
- module.exports.transpile = transpile;
80
- function transpileFile(source, opts) {
81
- return transpile(source, { check: true, typecheck: (opts?.typecheck ?? false), jsx: (opts?.jsx ?? false), jsxTarget: (opts?.jsxTarget ?? "browser"), mangle: (opts?.mangle ?? false), strict: (opts?.strict ?? false), ...(opts ?? { }) });
82
- }
83
- module.exports.transpileFile = transpileFile;
1
+ "use strict"; const { Lexer, lexerize, T } = require("./lexer"); const { Parser, makeParser } = require("./parser"); const { CodeGenerator, makeCodeGen } = require("./codegen"); const { transformCss } = require("./css-preprocessor"); const { transformJsx, FLUX_H_BROWSER, FLUX_H_SERVER, FLUX_CSS_BROWSER, FLUX_CSS_SERVER } = require("./jsx"); const { Checker } = require("./checker"); const { FluxTypeChecker } = require("./type-checker"); const Fs = require("fs"); const Path = require("path"); function _a() { try { const pkgPath = Path.resolve(__dirname, "../../package.json"); return JSON.parse(Fs.readFileSync(pkgPath, "utf8")).version; } catch (_b) { return "4.0.0"; } } const FLUX_VERSION = _a(); module.exports.FLUX_VERSION = FLUX_VERSION; const FLUX_STAGE = "self-hosted"; module.exports.FLUX_STAGE = FLUX_STAGE; function transpile(_c, _d) { const opts = (_d ?? { }); const result = { success: false, output: "", ast: null, tokens: null, errors: [], typeErrors: [], typeWarnings: [], stage: "" }; try { let src = _c; result.stage = "css"; if ((opts.css != false)) { src = transformCss(src); } result.stage = "jsx"; if (opts.jsx) { const jsxTarget = (opts.jsxTarget ?? "browser"); const jsxResult = transformJsx(src, { target: jsxTarget }); src = jsxResult.source; if (jsxResult.hasJsx) { opts._jsxHelpers = jsxResult.runtimeHelpers; } } result.stage = "lexer"; const lexer = lexerize(src); const tokens = lexer.tokenize(); result.tokens = tokens; result.stage = "parser"; const ast = makeParser(tokens).parse(); result.ast = ast; if ((opts.check != false)) { result.stage = "checker"; const checker = new Checker([], []); const checkResult = checker.check(ast); if ((checkResult.errors.length > 0)) { result.errors = checkResult.errors; result.stage = null; return result; } } if (opts.typecheck) { result.stage = "type-checker"; const tc = new FluxTypeChecker([], [], new Map(), new Map(), new Map(), new Map()); const tcResult = tc.check(ast); result.typeErrors = tcResult.errors; result.typeWarnings = tcResult.warnings; if ((opts.strict && (tcResult.errors.length > 0))) { result.errors = tcResult.errors; result.stage = null; return result; } } result.stage = "codegen"; const indent = (opts.mangle ? "" : " "); const cg = makeCodeGen({ indent, version: FLUX_VERSION }); const genResult = cg.generate(ast); let code = genResult.code; if (opts._jsxHelpers) { code = ((opts._jsxHelpers + "\n") + code); } result.output = code; result.success = true; result.stage = null; } catch (_b) { result.errors.push({ message: _b.message, name: _b.name, stage: result.stage }); } return result; } module.exports.transpile = transpile; function transpileFile(_c, _e) { return transpile(_c, { check: true, typecheck: (_e?.typecheck ?? false), jsx: (_e?.jsx ?? false), jsxTarget: (_e?.jsxTarget ?? "browser"), mangle: (_e?.mangle ?? false), strict: (_e?.strict ?? false), ...(_e ?? { }) }); } module.exports.transpileFile = transpileFile;
@@ -734,6 +734,18 @@ export class FluxTypeChecker:
734
734
  clsEnv.set("self", T_OBJECT(shape))
735
735
  for m in node.methods: self._checkStmt(m, clsEnv)
736
736
 
737
+ else if node.type == "DeclareDecl":
738
+ val d = node.decl
739
+ if d.type == "FnDecl":
740
+ val retType = d.retType ? parseAnnotation(d.retType) : null
741
+ val paramTypes = d.params.map(p -> p.typeAnn ? parseAnnotation(p.typeAnn) : T_UNKNOWN)
742
+ if d.name: env.set(d.name, T_FN(paramTypes, retType ?? T_UNKNOWN))
743
+ else if d.type == "VarDecl":
744
+ val t = d.typeAnn ? parseAnnotation(d.typeAnn) : T_UNKNOWN
745
+ env.set(d.name, t)
746
+ else if d.type == "ClassDecl":
747
+ env.set(d.name, T_NAMED(d.name))
748
+
737
749
  else if node.type == "TypeDecl":
738
750
  for v in node.variants:
739
751
  if v.fields.length == 0: