tova 0.5.0 → 0.7.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.
Files changed (43) hide show
  1. package/bin/tova.js +109 -57
  2. package/package.json +7 -2
  3. package/src/analyzer/analyzer.js +315 -79
  4. package/src/analyzer/{client-analyzer.js → browser-analyzer.js} +20 -17
  5. package/src/analyzer/form-analyzer.js +113 -0
  6. package/src/analyzer/scope.js +2 -2
  7. package/src/codegen/base-codegen.js +1 -0
  8. package/src/codegen/{client-codegen.js → browser-codegen.js} +444 -5
  9. package/src/codegen/cli-codegen.js +386 -0
  10. package/src/codegen/codegen.js +163 -45
  11. package/src/codegen/edge-codegen.js +1351 -0
  12. package/src/codegen/form-codegen.js +553 -0
  13. package/src/codegen/security-codegen.js +5 -5
  14. package/src/codegen/server-codegen.js +88 -7
  15. package/src/diagnostics/error-codes.js +1 -1
  16. package/src/docs/generator.js +1 -1
  17. package/src/formatter/formatter.js +4 -4
  18. package/src/lexer/tokens.js +12 -2
  19. package/src/lsp/server.js +1 -1
  20. package/src/parser/ast.js +45 -5
  21. package/src/parser/{client-ast.js → browser-ast.js} +3 -3
  22. package/src/parser/{client-parser.js → browser-parser.js} +42 -15
  23. package/src/parser/cli-ast.js +35 -0
  24. package/src/parser/cli-parser.js +140 -0
  25. package/src/parser/edge-ast.js +83 -0
  26. package/src/parser/edge-parser.js +262 -0
  27. package/src/parser/form-ast.js +80 -0
  28. package/src/parser/form-parser.js +206 -0
  29. package/src/parser/parser.js +86 -53
  30. package/src/registry/block-registry.js +56 -0
  31. package/src/registry/plugins/bench-plugin.js +23 -0
  32. package/src/registry/plugins/browser-plugin.js +30 -0
  33. package/src/registry/plugins/cli-plugin.js +24 -0
  34. package/src/registry/plugins/data-plugin.js +21 -0
  35. package/src/registry/plugins/edge-plugin.js +32 -0
  36. package/src/registry/plugins/security-plugin.js +27 -0
  37. package/src/registry/plugins/server-plugin.js +46 -0
  38. package/src/registry/plugins/shared-plugin.js +17 -0
  39. package/src/registry/plugins/test-plugin.js +23 -0
  40. package/src/registry/register-all.js +25 -0
  41. package/src/runtime/ssr.js +2 -2
  42. package/src/stdlib/inline.js +178 -3
  43. package/src/version.js +1 -1
@@ -1,6 +1,6 @@
1
1
  // Tova standard library — inline string versions for codegen
2
2
  // Single source of truth for all inline stdlib code used in code generation.
3
- // Used by: base-codegen.js, client-codegen.js, bin/tova.js
3
+ // Used by: base-codegen.js, browser-codegen.js, bin/tova.js
4
4
 
5
5
  export const RESULT_OPTION = `class _Ok { constructor(value) { this.value = value; } }
6
6
  _Ok.prototype.__tag = "Ok";
@@ -651,6 +651,173 @@ Table.prototype = { get rows() { return this._rows.length; }, get columns() { re
651
651
  bold: `function bold(text) { if (typeof process !== 'undefined' && (process.env.NO_COLOR || (process.stdout && !process.stdout.isTTY))) return String(text); return '\\x1b[1m' + text + '\\x1b[0m'; }`,
652
652
  dim: `function dim(text) { if (typeof process !== 'undefined' && (process.env.NO_COLOR || (process.stdout && !process.stdout.isTTY))) return String(text); return '\\x1b[2m' + text + '\\x1b[0m'; }`,
653
653
 
654
+ // ── Scripting: Color shortcuts ────────────────────────
655
+ green: `function green(text) { return color(text, 'green'); }`,
656
+ red: `function red(text) { return color(text, 'red'); }`,
657
+ yellow: `function yellow(text) { return color(text, 'yellow'); }`,
658
+ blue: `function blue(text) { return color(text, 'blue'); }`,
659
+ cyan: `function cyan(text) { return color(text, 'cyan'); }`,
660
+ magenta: `function magenta(text) { return color(text, 'magenta'); }`,
661
+ gray: `function gray(text) { return color(text, 'gray'); }`,
662
+ underline: `function underline(text) { if (typeof process !== 'undefined' && (process.env.NO_COLOR || (process.stdout && !process.stdout.isTTY))) return String(text); return '\\x1b[4m' + text + '\\x1b[0m'; }`,
663
+ strikethrough: `function strikethrough(text) { if (typeof process !== 'undefined' && (process.env.NO_COLOR || (process.stdout && !process.stdout.isTTY))) return String(text); return '\\x1b[9m' + text + '\\x1b[0m'; }`,
664
+
665
+ // ── Scripting: Rich output ────────────────────────────
666
+ table: `function table(data, opts) {
667
+ if (!data || data.length === 0) { console.log("(empty)"); return; }
668
+ const o = opts || {};
669
+ const headers = o.headers || Object.keys(data[0]);
670
+ const rows = data.map(function(row) { return headers.map(function(h) { return String(row[h] != null ? row[h] : ''); }); });
671
+ const widths = headers.map(function(h, i) {
672
+ return Math.max(h.length, ...rows.map(function(r) { return r[i].length; }));
673
+ });
674
+ const noColor = typeof process !== 'undefined' && (process.env.NO_COLOR || (process.stdout && !process.stdout.isTTY));
675
+ const b = function(t) { return noColor ? t : '\\x1b[1m' + t + '\\x1b[0m'; };
676
+ const line = widths.map(function(w) { return '-'.repeat(w + 2); }).join('+');
677
+ console.log(b(headers.map(function(h, i) { return ' ' + h.padEnd(widths[i]) + ' '; }).join('|')));
678
+ console.log(line);
679
+ rows.forEach(function(r) { console.log(r.map(function(c, i) { return ' ' + c.padEnd(widths[i]) + ' '; }).join('|')); });
680
+ }`,
681
+
682
+ panel: `function panel(title, content) {
683
+ var lines = String(content).split('\\n');
684
+ var maxLen = Math.max(title ? title.length + 2 : 0, ...lines.map(function(l) { return l.length; }));
685
+ var noColor = typeof process !== 'undefined' && (process.env.NO_COLOR || (process.stdout && !process.stdout.isTTY));
686
+ var b = function(t) { return noColor ? t : '\\x1b[1m' + t + '\\x1b[0m'; };
687
+ var top = '\\u250c' + (title ? '\\u2500 ' + b(title) + ' ' + '\\u2500'.repeat(Math.max(0, maxLen - title.length - 2)) : '\\u2500'.repeat(maxLen + 2)) + '\\u2510';
688
+ var bot = '\\u2514' + '\\u2500'.repeat(maxLen + 2) + '\\u2518';
689
+ var body = lines.map(function(l) { return '\\u2502 ' + l.padEnd(maxLen) + ' \\u2502'; }).join('\\n');
690
+ console.log(top + '\\n' + body + '\\n' + bot);
691
+ }`,
692
+
693
+ progress: `function progress(items, opts) {
694
+ var o = opts || {};
695
+ var total = items.length || o.total || 0;
696
+ var label = o.label || '';
697
+ var width = o.width || 30;
698
+ var isTTY = typeof process !== 'undefined' && process.stderr && process.stderr.isTTY;
699
+ var idx = 0;
700
+ return { [Symbol.iterator]() {
701
+ var it = items[Symbol.iterator]();
702
+ return { next() {
703
+ var r = it.next();
704
+ if (!r.done) {
705
+ idx++;
706
+ if (isTTY) {
707
+ var pct = Math.round(idx / total * 100);
708
+ var filled = Math.round(idx / total * width);
709
+ var bar = '\\u2588'.repeat(filled) + '\\u2591'.repeat(width - filled);
710
+ process.stderr.write('\\r' + label + ' [' + bar + '] ' + pct + '% ' + idx + '/' + total);
711
+ }
712
+ } else if (isTTY) {
713
+ process.stderr.write('\\r' + ' '.repeat(width + label.length + 20) + '\\r');
714
+ }
715
+ return r;
716
+ }};
717
+ }};
718
+ }`,
719
+
720
+ spin: `async function spin(label, fn) {
721
+ var frames = ['\\u2838','\\u2834','\\u2826','\\u2823','\\u2831','\\u2839'];
722
+ var isTTY = typeof process !== 'undefined' && process.stderr && process.stderr.isTTY;
723
+ var i = 0;
724
+ var iv = isTTY ? setInterval(function() { process.stderr.write('\\r' + frames[i++ % frames.length] + ' ' + label); }, 80) : null;
725
+ try {
726
+ var result = await fn();
727
+ if (iv) clearInterval(iv);
728
+ if (isTTY) process.stderr.write('\\r\\u2714 ' + label + '\\n');
729
+ return result;
730
+ } catch (e) {
731
+ if (iv) clearInterval(iv);
732
+ if (isTTY) process.stderr.write('\\r\\u2718 ' + label + '\\n');
733
+ throw e;
734
+ }
735
+ }`,
736
+
737
+ // ── Scripting: Interactive prompts ─────────────────────
738
+ ask: `async function ask(prompt, opts) {
739
+ var o = opts || {};
740
+ var rl = require('readline').createInterface({ input: process.stdin, output: process.stdout });
741
+ var suffix = o.default ? ' (' + o.default + ')' : '';
742
+ return new Promise(function(resolve) {
743
+ rl.question(prompt + suffix + ' ', function(answer) {
744
+ rl.close();
745
+ resolve(answer || o.default || '');
746
+ });
747
+ });
748
+ }`,
749
+
750
+ confirm: `async function confirm(prompt, opts) {
751
+ var o = opts || {};
752
+ var def = o.default !== undefined ? o.default : true;
753
+ var hint = def ? '[Y/n]' : '[y/N]';
754
+ var rl = require('readline').createInterface({ input: process.stdin, output: process.stdout });
755
+ return new Promise(function(resolve) {
756
+ rl.question(prompt + ' ' + hint + ' ', function(answer) {
757
+ rl.close();
758
+ if (!answer) { resolve(def); return; }
759
+ resolve(answer.toLowerCase().startsWith('y'));
760
+ });
761
+ });
762
+ }`,
763
+
764
+ choose: `async function choose(prompt, options) {
765
+ console.log(prompt);
766
+ for (var i = 0; i < options.length; i++) console.log(' ' + (i + 1) + '. ' + options[i]);
767
+ var rl = require('readline').createInterface({ input: process.stdin, output: process.stdout });
768
+ return new Promise(function(resolve) {
769
+ rl.question('Select [1-' + options.length + ']: ', function(answer) {
770
+ rl.close();
771
+ var idx = parseInt(answer, 10) - 1;
772
+ resolve(idx >= 0 && idx < options.length ? options[idx] : options[0]);
773
+ });
774
+ });
775
+ }`,
776
+
777
+ choose_many: `async function choose_many(prompt, options) {
778
+ console.log(prompt);
779
+ for (var i = 0; i < options.length; i++) console.log(' ' + (i + 1) + '. ' + options[i]);
780
+ var rl = require('readline').createInterface({ input: process.stdin, output: process.stdout });
781
+ return new Promise(function(resolve) {
782
+ rl.question('Select (comma-separated): ', function(answer) {
783
+ rl.close();
784
+ var indices = answer.split(',').map(function(s) { return parseInt(s.trim(), 10) - 1; });
785
+ resolve(indices.filter(function(i) { return i >= 0 && i < options.length; }).map(function(i) { return options[i]; }));
786
+ });
787
+ });
788
+ }`,
789
+
790
+ secret: `async function secret(prompt) {
791
+ var rl = require('readline').createInterface({ input: process.stdin, output: process.stdout });
792
+ return new Promise(function(resolve) {
793
+ if (process.stdin.isTTY) {
794
+ process.stdout.write(prompt + ' ');
795
+ process.stdin.setRawMode(true);
796
+ process.stdin.resume();
797
+ var buf = '';
798
+ var onData = function(ch) {
799
+ ch = ch.toString();
800
+ if (ch === '\\n' || ch === '\\r' || ch === '\\u0004') {
801
+ process.stdin.setRawMode(false);
802
+ process.stdin.pause();
803
+ process.stdin.removeListener('data', onData);
804
+ process.stdout.write('\\n');
805
+ rl.close();
806
+ resolve(buf);
807
+ } else if (ch === '\\u007f' || ch === '\\b') {
808
+ if (buf.length > 0) { buf = buf.slice(0, -1); process.stdout.write('\\b \\b'); }
809
+ } else {
810
+ buf += ch;
811
+ process.stdout.write('*');
812
+ }
813
+ };
814
+ process.stdin.on('data', onData);
815
+ } else {
816
+ rl.question(prompt + ' ', function(answer) { rl.close(); resolve(answer); });
817
+ }
818
+ });
819
+ }`,
820
+
654
821
  // ── Scripting: Signal handling ────────────────────────
655
822
  on_signal: `function on_signal(name, callback) { process.on(name, callback); }`,
656
823
 
@@ -1169,6 +1336,14 @@ export const STDLIB_DEPS = {
1169
1336
  compare_by: ['Less', 'Equal', 'Greater'],
1170
1337
  // mock/spy
1171
1338
  create_mock: ['create_spy'],
1339
+ // color shortcuts depend on color()
1340
+ green: ['color'],
1341
+ red: ['color'],
1342
+ yellow: ['color'],
1343
+ blue: ['color'],
1344
+ cyan: ['color'],
1345
+ magenta: ['color'],
1346
+ gray: ['color'],
1172
1347
  };
1173
1348
 
1174
1349
  // Resolve all transitive dependencies for a set of used names
@@ -1286,7 +1461,7 @@ export function getFullStdlib() {
1286
1461
  return `${NATIVE_INIT_SYNC}\n${buildSelectiveStdlib(BUILTIN_NAMES)}\n${RESULT_OPTION}\n${PROPAGATE}`;
1287
1462
  }
1288
1463
 
1289
- // Stdlib for client codegen (includes builtins + result/option + propagate)
1290
- export function getClientStdlib() {
1464
+ // Stdlib for browser codegen (includes builtins + result/option + propagate)
1465
+ export function getBrowserStdlib() {
1291
1466
  return `${buildSelectiveStdlib(BUILTIN_NAMES)}\n${RESULT_OPTION}\n${PROPAGATE}`;
1292
1467
  }
package/src/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // Auto-generated by scripts/embed-runtime.js — do not edit
2
- export const VERSION = "0.5.0";
2
+ export const VERSION = "0.7.0";