novac 2.0.1 → 2.2.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 (161) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +1574 -597
  3. package/bin/novac +468 -171
  4. package/bin/nvc +522 -0
  5. package/bin/nvml +78 -17
  6. package/demo.nv +0 -0
  7. package/demo_builtins.nv +0 -0
  8. package/demo_http.nv +0 -0
  9. package/examples/bf.nv +69 -0
  10. package/examples/math.nv +21 -0
  11. package/kits/birdAPI/kitdef.js +954 -0
  12. package/kits/kitRNG/kitdef.js +740 -0
  13. package/kits/kitSSH/kitdef.js +1272 -0
  14. package/kits/kitadb/kitdef.js +606 -0
  15. package/kits/kitai/kitdef.js +2185 -0
  16. package/kits/kitansi/kitdef.js +1402 -0
  17. package/kits/kitcanvas/kitdef.js +914 -0
  18. package/kits/kitclippy/kitdef.js +925 -0
  19. package/kits/kitformat/kitdef.js +1485 -0
  20. package/kits/kitgps/kitdef.js +1862 -0
  21. package/kits/kitlibproc/kitdef.js +3 -2
  22. package/kits/kitmatrix/ex.js +19 -0
  23. package/kits/kitmatrix/kitdef.js +960 -0
  24. package/kits/kitmorse/kitdef.js +229 -0
  25. package/kits/kitmpatch/kitdef.js +906 -0
  26. package/kits/kitnet/kitdef.js +1401 -0
  27. package/kits/kitnovacweb/README.md +1416 -143
  28. package/kits/kitnovacweb/kitdef.js +92 -2
  29. package/kits/kitnovacweb/nvml/executor.js +578 -176
  30. package/kits/kitnovacweb/nvml/index.js +2 -2
  31. package/kits/kitnovacweb/nvml/lexer.js +72 -69
  32. package/kits/kitnovacweb/nvml/parser.js +328 -159
  33. package/kits/kitnovacweb/nvml/renderer.js +770 -270
  34. package/kits/kitparse/kitdef.js +1688 -0
  35. package/kits/kitproto/kitdef.js +613 -0
  36. package/kits/kitqr/kitdef.js +637 -0
  37. package/kits/kitregex++/kitdef.js +1353 -0
  38. package/kits/kitrequire/kitdef.js +1599 -0
  39. package/kits/kitx11/kitdef.js +1 -0
  40. package/kits/kitx11/kitx11.js +2472 -0
  41. package/kits/kitx11/kitx11_conn.js +948 -0
  42. package/kits/kitx11/kitx11_worker.js +121 -0
  43. package/kits/libtea/kitdef.js +2691 -0
  44. package/kits/libterm/ex.js +285 -0
  45. package/kits/libterm/kitdef.js +1927 -0
  46. package/novac/LICENSE +21 -0
  47. package/novac/README.md +1823 -0
  48. package/novac/bin/novac +950 -0
  49. package/novac/bin/nvc +522 -0
  50. package/novac/bin/nvml +542 -0
  51. package/novac/demo.nv +245 -0
  52. package/novac/demo_builtins.nv +209 -0
  53. package/novac/demo_http.nv +62 -0
  54. package/novac/examples/bf.nv +69 -0
  55. package/novac/examples/math.nv +21 -0
  56. package/novac/kits/kitai/kitdef.js +2185 -0
  57. package/novac/kits/kitansi/kitdef.js +1402 -0
  58. package/novac/kits/kitformat/kitdef.js +1485 -0
  59. package/novac/kits/kitgps/kitdef.js +1862 -0
  60. package/novac/kits/kitlibfs/kitdef.js +231 -0
  61. package/{examples/example-project/nova_modules → novac/kits}/kitlibproc/kitdef.js +3 -2
  62. package/novac/kits/kitmatrix/ex.js +19 -0
  63. package/novac/kits/kitmatrix/kitdef.js +960 -0
  64. package/novac/kits/kitmpatch/kitdef.js +906 -0
  65. package/novac/kits/kitnovacweb/README.md +1572 -0
  66. package/novac/kits/kitnovacweb/demo.nv +12 -0
  67. package/novac/kits/kitnovacweb/demo.nvml +71 -0
  68. package/novac/kits/kitnovacweb/index.nova +12 -0
  69. package/novac/kits/kitnovacweb/kitdef.js +692 -0
  70. package/novac/kits/kitnovacweb/nova.kit.json +8 -0
  71. package/novac/kits/kitnovacweb/nvml/executor.js +739 -0
  72. package/novac/kits/kitnovacweb/nvml/index.js +67 -0
  73. package/novac/kits/kitnovacweb/nvml/lexer.js +263 -0
  74. package/novac/kits/kitnovacweb/nvml/parser.js +508 -0
  75. package/novac/kits/kitnovacweb/nvml/renderer.js +924 -0
  76. package/novac/kits/kitparse/kitdef.js +1688 -0
  77. package/novac/kits/kitregex++/kitdef.js +1353 -0
  78. package/novac/kits/kitrequire/kitdef.js +1599 -0
  79. package/novac/kits/kitx11/kitdef.js +1 -0
  80. package/novac/kits/kitx11/kitx11.js +2472 -0
  81. package/novac/kits/kitx11/kitx11_conn.js +948 -0
  82. package/novac/kits/kitx11/kitx11_worker.js +121 -0
  83. package/novac/kits/libtea/tf.js +2691 -0
  84. package/novac/kits/libterm/ex.js +285 -0
  85. package/novac/kits/libterm/kitdef.js +1927 -0
  86. package/novac/node_modules/chalk/license +9 -0
  87. package/novac/node_modules/chalk/package.json +83 -0
  88. package/novac/node_modules/chalk/readme.md +297 -0
  89. package/novac/node_modules/chalk/source/index.d.ts +325 -0
  90. package/novac/node_modules/chalk/source/index.js +225 -0
  91. package/novac/node_modules/chalk/source/utilities.js +33 -0
  92. package/novac/node_modules/chalk/source/vendor/ansi-styles/index.d.ts +236 -0
  93. package/novac/node_modules/chalk/source/vendor/ansi-styles/index.js +223 -0
  94. package/novac/node_modules/chalk/source/vendor/supports-color/browser.d.ts +1 -0
  95. package/novac/node_modules/chalk/source/vendor/supports-color/browser.js +34 -0
  96. package/novac/node_modules/chalk/source/vendor/supports-color/index.d.ts +55 -0
  97. package/novac/node_modules/chalk/source/vendor/supports-color/index.js +190 -0
  98. package/novac/node_modules/commander/LICENSE +22 -0
  99. package/novac/node_modules/commander/Readme.md +1176 -0
  100. package/novac/node_modules/commander/esm.mjs +16 -0
  101. package/novac/node_modules/commander/index.js +24 -0
  102. package/novac/node_modules/commander/lib/argument.js +150 -0
  103. package/novac/node_modules/commander/lib/command.js +2777 -0
  104. package/novac/node_modules/commander/lib/error.js +39 -0
  105. package/novac/node_modules/commander/lib/help.js +747 -0
  106. package/novac/node_modules/commander/lib/option.js +380 -0
  107. package/novac/node_modules/commander/lib/suggestSimilar.js +101 -0
  108. package/novac/node_modules/commander/package-support.json +19 -0
  109. package/novac/node_modules/commander/package.json +82 -0
  110. package/novac/node_modules/commander/typings/esm.d.mts +3 -0
  111. package/novac/node_modules/commander/typings/index.d.ts +1113 -0
  112. package/novac/node_modules/node-addon-api/LICENSE.md +9 -0
  113. package/novac/node_modules/node-addon-api/README.md +95 -0
  114. package/novac/node_modules/node-addon-api/common.gypi +21 -0
  115. package/novac/node_modules/node-addon-api/except.gypi +25 -0
  116. package/novac/node_modules/node-addon-api/index.js +14 -0
  117. package/novac/node_modules/node-addon-api/napi-inl.deprecated.h +186 -0
  118. package/novac/node_modules/node-addon-api/napi-inl.h +7165 -0
  119. package/novac/node_modules/node-addon-api/napi.h +3364 -0
  120. package/novac/node_modules/node-addon-api/node_addon_api.gyp +42 -0
  121. package/novac/node_modules/node-addon-api/node_api.gyp +9 -0
  122. package/novac/node_modules/node-addon-api/noexcept.gypi +26 -0
  123. package/novac/node_modules/node-addon-api/package-support.json +21 -0
  124. package/novac/node_modules/node-addon-api/package.json +480 -0
  125. package/novac/node_modules/node-addon-api/tools/README.md +73 -0
  126. package/novac/node_modules/node-addon-api/tools/check-napi.js +99 -0
  127. package/novac/node_modules/node-addon-api/tools/clang-format.js +71 -0
  128. package/novac/node_modules/node-addon-api/tools/conversion.js +301 -0
  129. package/novac/node_modules/serialize-javascript/LICENSE +27 -0
  130. package/novac/node_modules/serialize-javascript/README.md +149 -0
  131. package/novac/node_modules/serialize-javascript/index.js +297 -0
  132. package/novac/node_modules/serialize-javascript/package.json +33 -0
  133. package/novac/package.json +27 -0
  134. package/novac/scripts/update-bin.js +24 -0
  135. package/novac/src/core/bstd.js +1035 -0
  136. package/novac/src/core/config.js +155 -0
  137. package/novac/src/core/describe.js +187 -0
  138. package/novac/src/core/emitter.js +499 -0
  139. package/novac/src/core/error.js +86 -0
  140. package/novac/src/core/executor.js +5606 -0
  141. package/novac/src/core/formatter.js +686 -0
  142. package/novac/src/core/lexer.js +1026 -0
  143. package/novac/src/core/nova_builtins.js +717 -0
  144. package/novac/src/core/nova_thread_worker.js +166 -0
  145. package/novac/src/core/parser.js +2181 -0
  146. package/novac/src/core/types.js +112 -0
  147. package/novac/src/index.js +28 -0
  148. package/novac/src/runtime/stdlib.js +244 -0
  149. package/package.json +6 -3
  150. package/scripts/update-bin.js +0 -0
  151. package/src/core/bstd.js +838 -362
  152. package/src/core/executor.js +2578 -170
  153. package/src/core/lexer.js +502 -54
  154. package/src/core/nova_builtins.js +21 -3
  155. package/src/core/parser.js +413 -72
  156. package/src/core/types.js +30 -2
  157. package/src/index.js +0 -0
  158. package/examples/example-project/README.md +0 -3
  159. package/examples/example-project/src/main.nova +0 -3
  160. package/src/core/environment.js +0 -0
  161. /package/{examples/example-project/bin/example-project.nv → novac/node_modules/node-addon-api/nothing.c} +0 -0
@@ -0,0 +1,112 @@
1
+ class NovaValue {
2
+ constructor(inner) { this.inner = inner; }
3
+ get type() { return this.constructor.name; }
4
+ valueOf() { return this.inner?.valueOf?.() ?? this.inner; }
5
+ toString() { return String(this.valueOf()); }
6
+ }
7
+ class NovaNumber extends NovaValue { constructor(n) { super(Number(n)); } }
8
+ class NovaString extends NovaValue { constructor(s) { super(String(s)); } }
9
+ class NovaBool extends NovaValue { constructor(b) { super(!!b); } }
10
+ class NovaNull extends NovaValue { constructor() { super(null); } toString() { return 'null'; } valueOf() { return null; } }
11
+ class NovaFunction extends NovaValue {
12
+ constructor(fn, scope=null, args=[]) { super(fn); this.scope=scope; this.args=args; }
13
+ call(thisArg, ...args) {
14
+ if (typeof this.inner === 'function') return this.inner.apply(thisArg, args);
15
+ }
16
+ }
17
+ class NovaTemplateString extends NovaValue {
18
+ constructor(parts=[]) { super(parts.join('')); this.parts=parts; }
19
+ }
20
+ class NovaPointer extends NovaValue {
21
+ constructor(value, readFn=null, writeFn=null, address=null) {
22
+ super(value); this.readFn=readFn; this.writeFn=writeFn; this.address=address??Symbol('ptr');
23
+ }
24
+ read() { return this.readFn ? this.readFn(this.valueOf()) : this.valueOf(); }
25
+ write(v) { if (this.writeFn) this.writeFn(v, this.address); this.inner=v; }
26
+ toString(){ return '<Pointer@' + this.address.toString().slice(7,13) + '=' + this.inner + '>'; }
27
+ }
28
+ // Symbol used to attach a meta protocol to a NovaObject
29
+ const NOVA_META = Symbol('NOVA_META');
30
+
31
+ class NovaObject extends NovaValue {
32
+ constructor(obj={}) { super(obj); }
33
+
34
+ // Attach a meta descriptor: { get(k), set(k,v), missing(k) }
35
+ attachMeta(meta) { this[NOVA_META] = meta; }
36
+
37
+ get(k) {
38
+ const m = this[NOVA_META];
39
+ if (m) {
40
+ // If key exists, use meta.get if defined
41
+ if (k in this.inner) {
42
+ if (m.get) return m.get(k, this.inner[k]);
43
+ return this.inner[k];
44
+ }
45
+ // Key missing — use meta.missing
46
+ if (m.missing) return m.missing(k);
47
+ return undefined;
48
+ }
49
+ return this.inner[k];
50
+ }
51
+
52
+ set(k, v) {
53
+ const m = this[NOVA_META];
54
+ if (m && m.set) { m.set(k, v, this.inner); return; }
55
+ this.inner[k] = v;
56
+ }
57
+
58
+ delete(k) { delete this.inner[k]; }
59
+ keys() { return Object.keys(this.inner); }
60
+ values() { return Object.values(this.inner); }
61
+ entries() { return Object.entries(this.inner); }
62
+ has(k) { return Object.hasOwnProperty(this.inner, k); }
63
+ toCallable(){ return (vals) => new NovaObject(Object.fromEntries(vals.map((v,i)=>[i,v]))); }
64
+ }
65
+ class NovaArray extends NovaValue {
66
+ constructor(arr=[]) { super(arr); }
67
+ get(i) { return this.inner[i]; }
68
+ set(i,v) { this.inner[i]=v; }
69
+ delete(i) { this.inner.splice(Number(i),1); }
70
+ push(v) { this.inner.push(v); }
71
+ get length(){ return this.inner.length; }
72
+ toCallable(){ return (vals) => new NovaArray(vals); }
73
+ }
74
+ class NovaRange extends NovaValue {
75
+ constructor(start, end, step=1) { super({start,end,step}); this.start=start; this.end=end; this.step=step; }
76
+ toArray() {
77
+ const arr=[];
78
+ if (this.step>0) { for (let i=this.start;i<=this.end;i+=this.step) arr.push(i); }
79
+ else { for (let i=this.start;i>=this.end;i+=this.step) arr.push(i); }
80
+ return arr;
81
+ }
82
+ includes(v) { return v>=Math.min(this.start,this.end)&&v<=Math.max(this.start,this.end); }
83
+ get length(){ return Math.max(0,Math.floor(Math.abs(this.end-this.start)/Math.abs(this.step))+1); }
84
+ toString() { return 'Range(' + this.start + '..' + this.end + ')'; }
85
+ }
86
+ /** Struct instance — typed object created by a struct declaration */
87
+ class NovaStruct extends NovaValue {
88
+ constructor(typeName, inner={}) { super(inner); this.typeName=typeName; }
89
+ get(k) { return this.inner[k]; }
90
+ set(k,v) { this.inner[k]=v; }
91
+ delete(k) { delete this.inner[k]; }
92
+ toString() {
93
+ const fields = Object.entries(this.inner).map(([k,v])=>k+': '+String(v)).join(', ');
94
+ return this.typeName + ' { ' + fields + ' }';
95
+ }
96
+ }
97
+ /** Enum value — access via .variant, .enumType, .value, .typeName */
98
+ class NovaEnum extends NovaValue {
99
+ constructor(typeName, variant, value=null) {
100
+ super(value);
101
+ this.typeName = typeName;
102
+ this.variant = variant;
103
+ this.enumType = typeName; // .enumType instead of .type (avoids NovaValue getter clash)
104
+ }
105
+ toString() { return this.typeName + '::' + this.variant; }
106
+ }
107
+ module.exports = {
108
+ NovaValue, NovaNumber, NovaString, NovaBool, NovaNull,
109
+ NovaFunction, NovaTemplateString, NovaPointer,
110
+ NovaObject, NovaArray, NovaRange, NovaStruct, NovaEnum,
111
+ NOVA_META,
112
+ };
@@ -0,0 +1,28 @@
1
+ const { Lexer } = require('./core/lexer');
2
+ const { Parser } = require('./core/parser');
3
+ const { Formatter } = require('./core/formatter');
4
+ const { Executor, Scope, TypeRegistry } = require('./core/executor');
5
+ const stdlib = require('./runtime/stdlib');
6
+
7
+ function run(source, builtins) {
8
+ const fullstd = { ...stdlib, ...builtins };
9
+ const parser = new Parser(source);
10
+ const ast = parser.parse();
11
+ const executor = new Executor(source, fullstd);
12
+ // Inject caller-provided builtins (e.g. document, request) directly into
13
+ // globalScope so Nova scripts can reference them as top-level variables.
14
+ // Without this they only land at globalScope.variables.std (as std.document)
15
+ // which is not how Nova scripts address them.
16
+ if (builtins) {
17
+ for (const [k, v] of Object.entries(builtins)) {
18
+ executor.globalScope.set(k, v);
19
+ }
20
+ }
21
+ return executor.run(ast);
22
+ }
23
+
24
+ function tokenize(source) { return new Lexer(source).tokenize(); }
25
+ function parse(source) { return new Parser(source).parse(); }
26
+ function format(source) { return new Formatter(source).format(); }
27
+
28
+ module.exports = { run, tokenize, parse, format, Lexer, Parser, Formatter, Executor, Scope, TypeRegistry };
@@ -0,0 +1,244 @@
1
+ const { NovaArray, NovaObject, NovaRange, NovaBool, NovaNull } = require("../core/types");
2
+
3
+ module.exports = {
4
+ print: (...args) => console.log(...args),
5
+
6
+ // ── Math ──
7
+ Math: {
8
+ abs: Math.abs, ceil: Math.ceil, floor: Math.floor,
9
+ round: Math.round, sqrt: Math.sqrt, pow: Math.pow,
10
+ max: Math.max, min: Math.min, log: Math.log,
11
+ log2: Math.log2, log10: Math.log10,
12
+ sin: Math.sin, cos: Math.cos, tan: Math.tan,
13
+ PI: Math.PI, E: Math.E,
14
+ trunc: Math.trunc, sign: Math.sign,
15
+ random: Math.random,
16
+ clamp: (v, lo, hi) => Math.min(Math.max(v, lo), hi),
17
+ floorTo(a, b) { return Math.floor(a / b) * b; },
18
+ ceilTo(a, b) { return Math.ceil(a / b) * b; },
19
+ factorial(n) {
20
+ //memo to optimize for larger n
21
+ const memo = [1];
22
+ function fact(x) {
23
+ if (x < 0) return NaN;
24
+ if (x === 0) return 1;
25
+ if (memo[x] !== undefined) return memo[x];
26
+ return memo[x] = x * fact(x - 1);
27
+ }
28
+ return fact(n);
29
+ },
30
+ fibonacci(n) {
31
+ //memo to optimize for larger n
32
+ const memo = [0, 1];
33
+ function fib(x) {
34
+ if (x < 0) return NaN;
35
+ if (memo[x] !== undefined) return memo[x];
36
+ return memo[x] = fib(x - 1) + fib(x - 2);
37
+ }
38
+ return fib(n);
39
+ },
40
+ divmod(a, b) {
41
+ if (b === 0) throw new Error("Division by zero");
42
+ const q = Math.floor(a / b);
43
+ const r = a - q * b;
44
+ return [q, r];
45
+ },
46
+ },
47
+
48
+ // ── Array utils ──
49
+ Array: {
50
+ from: (it) => new NovaArray(Array.from(it instanceof NovaArray ? it.inner : (it ?? []))),
51
+ of: (...args) => new NovaArray(args),
52
+ range: (start, end, step = 1) => new NovaRange(start, end, step),
53
+ isArray: (v) => v instanceof NovaArray || Array.isArray(v),
54
+ fill: (n, val) => new NovaArray(Array(n).fill(val)),
55
+ zip: (...arrs) => {
56
+ const inners = arrs.map(a => a instanceof NovaArray ? a.inner : a);
57
+ const len = Math.min(...inners.map(a => a.length));
58
+ return new NovaArray(Array.from({ length: len }, (_, i) => new NovaArray(inners.map(a => a[i]))));
59
+ },
60
+ },
61
+
62
+ // ── Object utils ──
63
+ Object: {
64
+ keys: (o) => new NovaArray(o instanceof NovaObject ? Object.keys(o.inner) : Object.keys(o)),
65
+ values: (o) => new NovaArray(o instanceof NovaObject ? Object.values(o.inner) : Object.values(o)),
66
+ entries: (o) => new NovaArray((o instanceof NovaObject ? Object.entries(o.inner) : Object.entries(o)).map(([k,v]) => new NovaArray([k,v]))),
67
+ assign: (target, ...sources) => {
68
+ const t = target instanceof NovaObject ? target.inner : target;
69
+ for (const s of sources) Object.assign(t, s instanceof NovaObject ? s.inner : s);
70
+ return target;
71
+ },
72
+ freeze: (o) => { Object.freeze(o instanceof NovaObject ? o.inner : o); return o; },
73
+ has: (o, k) => o instanceof NovaObject ? k in o.inner : (k in (o ?? {})),
74
+ create: (proto) => new NovaObject(Object.create(proto instanceof NovaObject ? proto.inner : proto)),
75
+ },
76
+
77
+ // ── String utils ──
78
+ String: {
79
+ from: (v) => String(v),
80
+ padStart: (s, n, ch = " ") => String(s).padStart(n, ch),
81
+ padEnd: (s, n, ch = " ") => String(s).padEnd(n, ch),
82
+ repeat: (s, n) => String(s).repeat(n),
83
+ includes: (s, sub) => String(s).includes(sub),
84
+ startsWith: (s, sub) => String(s).startsWith(sub),
85
+ endsWith: (s, sub) => String(s).endsWith(sub),
86
+ trim: (s) => String(s).trim(),
87
+ split: (s, sep) => new NovaArray(String(s).split(sep)),
88
+ replace: (s, from, to) => String(s).replace(from, to),
89
+ replaceAll: (s, from, to) => String(s).replaceAll(from, to),
90
+ toUpper: (s) => String(s).toUpperCase(),
91
+ toLower: (s) => String(s).toLowerCase(),
92
+ charAt: (s, i) => String(s).charAt(i),
93
+ charCodeAt: (s, i) => String(s).charCodeAt(i),
94
+ fromCharCode: (...codes) => String.fromCharCode(...codes),
95
+ slice: (s, a, b) => String(s).slice(a, b),
96
+ indexOf: (s, sub) => String(s).indexOf(sub),
97
+ },
98
+
99
+ // ── Type checks ──
100
+ is: {
101
+ number: (v) => typeof v === "number",
102
+ string: (v) => typeof v === "string",
103
+ bool: (v) => typeof v === "boolean" || v instanceof NovaBool,
104
+ array: (v) => v instanceof NovaArray || Array.isArray(v),
105
+ object: (v) => v instanceof NovaObject,
106
+ null: (v) => v == null || v instanceof NovaNull,
107
+ func: (v) => typeof v === "function" || (v?.args !== undefined && v?.body !== undefined),
108
+ range: (v) => v instanceof NovaRange,
109
+ integer: (v) => Number.isInteger(v),
110
+ finite: (v) => Number.isFinite(v),
111
+ NaN: (v) => Number.isNaN(v),
112
+ },
113
+
114
+ // ── Conversion ──
115
+ num: (v) => Number(v),
116
+ str: (v) => String(v),
117
+ bool: (v) => Boolean(v),
118
+ int: (v) => Math.trunc(Number(v)),
119
+
120
+ // ── I/O ──
121
+ console: {
122
+ log: console.log,
123
+ warn: console.warn,
124
+ error: console.error,
125
+ info: console.info,
126
+ time: console.time,
127
+ timeEnd: console.timeEnd,
128
+ },
129
+
130
+ // ── Time ──
131
+ Date: {
132
+ now: () => Date.now(),
133
+ create: (...args) => new Date(...args),
134
+ },
135
+
136
+ // ── JSON ──
137
+ json: {
138
+ parse: (s) => JSON.parse(s),
139
+ stringify: (v, sp) => JSON.stringify(v instanceof NovaObject ? v.inner : (v instanceof NovaArray ? v.inner : v), null, sp),
140
+ },
141
+
142
+ // ── Promise / async ──
143
+ Promise: {
144
+ resolve: (v) => Promise.resolve(v),
145
+ reject: (v) => Promise.reject(v),
146
+ all: (arr) => Promise.all(arr instanceof NovaArray ? arr.inner : arr),
147
+ race: (arr) => Promise.race(arr instanceof NovaArray ? arr.inner : arr),
148
+ allSettled: (arr) => Promise.allSettled(arr instanceof NovaArray ? arr.inner : arr),
149
+ any: (arr) => Promise.any(arr instanceof NovaArray ? arr.inner : arr),
150
+ },
151
+
152
+ // ── Functional helpers ──
153
+ fn: {
154
+ identity: (x) => x,
155
+ compose: (...fns) => (x) => fns.reduceRight((v, f) => f(v), x),
156
+ pipe: (...fns) => (x) => fns.reduce((v, f) => f(v), x),
157
+ memoize: (f) => { const c = new Map(); return (x) => { if (!c.has(x)) c.set(x, f(x)); return c.get(x); }; },
158
+ once: (f) => { let called = false, result; return (...a) => { if (!called) { called = true; result = f(...a); } return result; }; },
159
+ partial: (f, ...a) => (...b) => f(...a, ...b),
160
+ curry: (f) => { const a = (args) => args.length >= f.length ? f(...args) : (...more) => a([...args, ...more]); return a([]); },
161
+ noop: () => undefined,
162
+ always: (x) => () => x,
163
+ flip: (f) => (a, b) => f(b, a),
164
+ not: (f) => (...a) => !f(...a),
165
+ },
166
+
167
+ // ── Errors ──
168
+ error: (msg) => { throw new Error(msg); },
169
+
170
+ // ── Range ──
171
+ range: (start, end, step = 1) => new NovaRange(start, end, step),
172
+
173
+ range: (start, end, step) => new NovaRange(start, end, step !== undefined ? step : 1),
174
+
175
+ fnum: (min, max, initial) => {
176
+ let v = Math.min(Math.max(initial !== undefined ? initial : min, min), max);
177
+ return { get value(){ return v; }, set value(nv){ v = Math.min(Math.max(Number(nv),min),max); }, valueOf(){ return v; }, toString(){ return String(v); } };
178
+ },
179
+ fint: (min, max, initial) => {
180
+ let v = Math.min(Math.max(Math.trunc(initial !== undefined ? initial : min), min), max);
181
+ return { get value(){ return v; }, set value(nv){ v = Math.min(Math.max(Math.trunc(Number(nv)),min),max); }, valueOf(){ return v; }, toString(){ return String(v); } };
182
+ },
183
+ convertCase: (str, target) => {
184
+ const words = String(str).replace(/([a-z])([A-Z])/g,'$1 $2').replace(/[-_]/g,' ').split(' ');
185
+ const m = { snake: w=>w.join('_'), camel: w=>w.map((s,i)=>i?s[0].toUpperCase()+s.slice(1).toLowerCase():s.toLowerCase()).join(''), pascal: w=>w.map(s=>s[0].toUpperCase()+s.slice(1).toLowerCase()).join(''), kebab: w=>w.join('-'), upper: w=>str.toUpperCase(), lower: w=>str.toLowerCase() };
186
+ return (m[target] || (()=>str))(words.map(s=>s.toLowerCase()));
187
+ },
188
+ randomWord: () => {
189
+ const v = 'aeiou';
190
+ const c = 'bcdfghjklmnpqrstvwxyz';
191
+ const pick = a => a[Math.floor(Math.random() * a.length)];
192
+ const patterns = ['CV','CVC','VC','CVV','CCV','VCC'];
193
+ const makeSyllable = () => patterns[Math.floor(Math.random() * patterns.length)].split('').map(p => p === 'C' ? pick(c) : pick(v)).join('');
194
+ const count = Math.floor(Math.random() * 3) + 1;
195
+ return Array.from({ length: count }, () => makeSyllable()).join('');
196
+ },
197
+ randomName: (format, minLen = 4, maxLen = 9) => {
198
+ const pick = a => a[Math.floor(Math.random() * a.length)];
199
+ const consonants = ['b','c','d','f','g','h','j','k','l','m','n','p','r','s','t','v','w','z'];
200
+ const consonantClusters = ['br','cr','dr','fr','gr','pr','tr','bl','cl','fl','gl','pl','sl','sc','sk','sm','sn','sp','st','str','ch','sh','th','wh','qu'];
201
+ const vowels = ['a','e','i','o','u','ae','ai','au','ea','ee','ei','ie','io','oa','oe','oi','oo','ou','ui','y','ay','ey','oy'];
202
+
203
+ const randomF = () => {
204
+ if (Math.random() < 0.35) return pick(consonantClusters);
205
+ return pick(consonants);
206
+ };
207
+ const randomL = () => {
208
+ if (Math.random() < 0.6) return pick(vowels);
209
+ return pick(['a','e','i','o','u']);
210
+ };
211
+ const parseFormat = str => {
212
+ if (typeof str !== 'string' || !str) return null;
213
+ const normalized = str.toLowerCase().trim();
214
+ if (!/^[fl]+$/.test(normalized)) return null;
215
+ return normalized.split('');
216
+ };
217
+ const makePieces = () => {
218
+ const blocks = Math.floor(Math.random() * 3) + 2;
219
+ const generated = [];
220
+ for (let i = 0; i < blocks; i++) {
221
+ const prev = generated[i - 1];
222
+ generated.push(i === 0 ? 'f' : (prev === 'f' ? 'l' : 'f'));
223
+ }
224
+ return generated;
225
+ };
226
+ const buildName = pieces => pieces.map(chunk => chunk === 'f' ? randomF() : randomL()).join('');
227
+ const normalizedMin = Math.max(1, Math.floor(minLen));
228
+ const normalizedMax = Math.max(normalizedMin, Math.floor(maxLen));
229
+ const pieces = parseFormat(format) || makePieces();
230
+
231
+ let name = buildName(pieces);
232
+ let attempts = 0;
233
+ while ((name.length < normalizedMin || name.length > normalizedMax) && attempts < 10) {
234
+ if (!parseFormat(format)) {
235
+ name = buildName(makePieces());
236
+ } else {
237
+ name = buildName(pieces);
238
+ }
239
+ attempts += 1;
240
+ }
241
+
242
+ return name[0].toUpperCase() + name.slice(1);
243
+ },
244
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "novac",
3
- "version": "2.0.1",
3
+ "version": "2.2.0",
4
4
  "description": "a rewrite version of my package nvlang",
5
5
  "license": "MIT",
6
6
  "author": "purcwix",
@@ -8,7 +8,8 @@
8
8
  "main": "./bin/novac",
9
9
  "bin": {
10
10
  "novac": "./bin/novac",
11
- "nvml": "./bin/nvml"
11
+ "nvml": "./bin/nvml",
12
+ "nvc": "./bin/nvc"
12
13
  },
13
14
  "directories": {
14
15
  "example": "examples",
@@ -20,6 +21,8 @@
20
21
  "dependencies": {
21
22
  "chalk": "^5.6.2",
22
23
  "commander": "^14.0.2",
23
- "serialize-javascript": "^7.0.5"
24
+ "node-addon-api": "latest",
25
+ "serialize-javascript": "^7.0.5",
26
+ "ssh2": "^1.17.0"
24
27
  }
25
28
  }
File without changes