tova 0.8.2 → 0.9.4

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.
@@ -60,7 +60,39 @@ export const PROPAGATE = `function __propagate(val) {
60
60
 
61
61
  // Individual builtin functions for tree-shaking
62
62
  export const BUILTIN_FUNCTIONS = {
63
- print: `function print(...args) { console.log(...args); }`,
63
+ print: `function print(...args) {
64
+ var _noColor = typeof process !== 'undefined' && (process.env.NO_COLOR || (process.stdout && !process.stdout.isTTY));
65
+ var _codes = { red: '31', green: '32', yellow: '33', blue: '34', magenta: '35', cyan: '36', gray: '90', bold: '1', dim: '2', underline: '4' };
66
+ var _styled = function(s) {
67
+ if (typeof s !== 'string') return s;
68
+ return s.replace(/\\{(\\/|red|green|yellow|blue|magenta|cyan|gray|bold|dim|underline)\\}/g, function(_, tag) {
69
+ if (_noColor) return '';
70
+ if (tag === '/') return '\\x1b[0m';
71
+ return '\\x1b[' + _codes[tag] + 'm';
72
+ });
73
+ };
74
+ var _pretty = function(v) {
75
+ if (v === null || v === undefined) return v;
76
+ if (typeof v !== 'object') return v;
77
+ if (Array.isArray(v) && v.length > 0 && typeof v[0] === 'object' && v[0] !== null && !Array.isArray(v[0])) {
78
+ var headers = Object.keys(v[0]);
79
+ var rows = v.map(function(r) { return headers.map(function(h) { return String(r[h] != null ? r[h] : ''); }); });
80
+ var widths = headers.map(function(h, i) { return Math.max(h.length, Math.max.apply(null, rows.map(function(r) { return r[i].length; }))); });
81
+ var line = widths.map(function(w) { return '-'.repeat(w + 2); }).join('+');
82
+ var head = headers.map(function(h, i) { return ' ' + h.padEnd(widths[i]) + ' '; }).join('|');
83
+ var body = rows.map(function(r) { return r.map(function(c, i) { return ' ' + c.padEnd(widths[i]) + ' '; }).join('|'); }).join('\\n');
84
+ return head + '\\n' + line + '\\n' + body;
85
+ }
86
+ return JSON.stringify(v, null, 2);
87
+ };
88
+ if (args.length === 1) {
89
+ var processed = _styled(_pretty(args[0]));
90
+ console.log(processed);
91
+ } else {
92
+ var processed = args.map(function(a) { return _styled(a); });
93
+ console.log.apply(console, processed);
94
+ }
95
+ }`,
64
96
  len: `function len(v) { if (v == null) return 0; if (typeof v === 'string' || Array.isArray(v) || ArrayBuffer.isView(v)) return v.length; if (typeof v === 'object') return Object.keys(v).length; return 0; }`,
65
97
  range: `function range(s, e, st) { if (e === undefined) { e = s; s = 0; } if (st === undefined) st = s < e ? 1 : -1; if (st === 0) return []; const r = []; if (st > 0) { for (let i = s; i < e; i += st) r.push(i); } else { for (let i = s; i > e; i += st) r.push(i); } return r; }`,
66
98
  enumerate: `function enumerate(a) { return a.map((v, i) => [i, v]); }`,
@@ -196,7 +228,7 @@ export const BUILTIN_FUNCTIONS = {
196
228
  atan2: `function atan2(y, x) { return Math.atan2(y, x); }`,
197
229
 
198
230
  // ── Logarithmic / Exponential ─────────────────────────
199
- log: `function log(n) { return Math.log(n); }`,
231
+ ln: `function ln(n) { return Math.log(n); }`,
200
232
  log2: `function log2(n) { return Math.log2(n); }`,
201
233
  log10: `function log10(n) { return Math.log10(n); }`,
202
234
  exp: `function exp(n) { return Math.exp(n); }`,
@@ -240,7 +272,7 @@ Table.prototype = { get rows() { return this._rows.length; }, get columns() { re
240
272
  table_agg: `function table_agg(grouped, aggregations) { if (!grouped || !grouped.__grouped) throw new Error('agg() must be called after group_by()'); const rows = []; for (const [, { key, rows: gr }] of grouped.groups) { const row = typeof key === 'object' && key !== null ? { ...key } : { _group: key }; for (const [n, fn] of Object.entries(aggregations)) { row[n] = fn(gr); } rows.push(row); } return Table(rows, rows.length > 0 ? Object.keys(rows[0]) : []); }`,
241
273
  table_sort_by: `function table_sort_by(table, keyFn, opts) { const desc = opts && opts.desc; const rows = [...table._rows].sort((a, b) => { const ka = typeof keyFn === 'function' ? keyFn(a) : a[keyFn]; const kb = typeof keyFn === 'function' ? keyFn(b) : b[keyFn]; let c = ka < kb ? -1 : ka > kb ? 1 : 0; return desc ? -c : c; }); return Table(rows, table._columns); }`,
242
274
  table_limit: `function table_limit(table, n) { return Table(table._rows.slice(0, n), table._columns); }`,
243
- table_join: `function table_join(table, other, opts) { const { left, right, how } = opts || {}; if (!left || !right) throw new Error('join() requires left and right key functions'); const rows = []; const ri = new Map(); for (const r of other._rows) { const k = typeof right === 'function' ? right(r) : r[right]; const ks = String(k); if (!ri.has(ks)) ri.set(ks, []); ri.get(ks).push(r); } const cc = [...new Set([...table._columns, ...other._columns])]; for (const lr of table._rows) { const k = typeof left === 'function' ? left(lr) : lr[left]; const ms = ri.get(String(k)) || []; if (ms.length > 0) { for (const rr of ms) rows.push({ ...lr, ...rr }); } else if (how === 'left' || how === 'outer') { const row = { ...lr }; for (const c of other._columns) { if (!(c in row)) row[c] = null; } rows.push(row); } } return Table(rows, cc); }`,
275
+ table_join: `function table_join(table, other, opts) { const { left, right, how } = opts || {}; if (how === 'cross') { const rows = []; const cc = [...new Set([...table._columns, ...other._columns])]; for (const lr of table._rows) { for (const rr of other._rows) { rows.push({ ...lr, ...rr }); } } return Table(rows, cc); } if (!left || !right) throw new Error('join() requires left and right key functions'); if (how === 'anti') { const ri = new Set(); for (const r of other._rows) { ri.add(String(typeof right === 'function' ? right(r) : r[right])); } const rows = []; for (const lr of table._rows) { const k = typeof left === 'function' ? left(lr) : lr[left]; if (!ri.has(String(k))) rows.push({ ...lr }); } return Table(rows, [...table._columns]); } if (how === 'semi') { const ri = new Set(); for (const r of other._rows) { ri.add(String(typeof right === 'function' ? right(r) : r[right])); } const rows = []; for (const lr of table._rows) { const k = typeof left === 'function' ? left(lr) : lr[left]; if (ri.has(String(k))) rows.push({ ...lr }); } return Table(rows, [...table._columns]); } if (how === 'right') { const sw = table_join(other, table, { left: right, right: left, how: 'left' }); const cc = [...new Set([...table._columns, ...other._columns])]; return Table(sw._rows, cc); } const ri = new Map(); for (const r of other._rows) { const k = typeof right === 'function' ? right(r) : r[right]; const ks = String(k); if (!ri.has(ks)) ri.set(ks, []); ri.get(ks).push(r); } const cc = [...new Set([...table._columns, ...other._columns])]; const rows = []; const mrk = how === 'outer' ? new Set() : null; for (const lr of table._rows) { const k = typeof left === 'function' ? left(lr) : lr[left]; const ms = ri.get(String(k)) || []; if (ms.length > 0) { for (const rr of ms) rows.push({ ...lr, ...rr }); if (mrk) mrk.add(String(k)); } else if (how === 'left' || how === 'outer') { const row = { ...lr }; for (const c of other._columns) { if (!(c in row)) row[c] = null; } rows.push(row); } } if (how === 'outer') { for (const r of other._rows) { const k = typeof right === 'function' ? right(r) : r[right]; if (!mrk.has(String(k))) { const row = { ...r }; for (const c of table._columns) { if (!(c in row)) row[c] = null; } rows.push(row); } } } return Table(rows, cc); }`,
244
276
  table_pivot: `function table_pivot(table, opts) { const { index, columns: colFn, values: valFn } = opts || {}; const pm = new Map(); const ac = new Set(); for (const row of table._rows) { const ik = typeof index === 'function' ? index(row) : row[index]; const col = typeof colFn === 'function' ? colFn(row) : row[colFn]; const val = typeof valFn === 'function' ? valFn(row) : row[valFn]; const ks = String(ik); if (!pm.has(ks)) pm.set(ks, { _index: ik }); pm.get(ks)[String(col)] = val; ac.add(String(col)); } return Table([...pm.values()], ['_index', ...ac]); }`,
245
277
  table_unpivot: `function table_unpivot(table, opts) { const { id, columns: uc } = opts || {}; const cn = uc.filter(c => typeof c === 'string'); const rows = []; for (const row of table._rows) { const iv = typeof id === 'function' ? id(row) : row[id]; for (const col of cn) rows.push({ id: iv, variable: col, value: row[col] }); } return Table(rows, ['id', 'variable', 'value']); }`,
246
278
  table_explode: `function table_explode(table, colFn) { const rows = []; for (const row of table._rows) { const arr = typeof colFn === 'function' ? colFn(row) : row[colFn]; if (Array.isArray(arr)) { const cn = typeof colFn === 'string' ? colFn : null; for (const val of arr) { const r = { ...row }; if (cn) r[cn] = val; rows.push(r); } } else { rows.push({ ...row }); } } return Table(rows, table._columns); }`,
@@ -352,6 +384,24 @@ Table.prototype = { get rows() { return this._rows.length; }, get columns() { re
352
384
  agg_min: `function agg_min(fn) { return (rows) => { if (rows.length === 0) return null; let m = typeof fn === 'function' ? fn(rows[0]) : rows[0][fn]; for (let i = 1; i < rows.length; i++) { const v = typeof fn === 'function' ? fn(rows[i]) : rows[i][fn]; if (v < m) m = v; } return m; }; }`,
353
385
  agg_max: `function agg_max(fn) { return (rows) => { if (rows.length === 0) return null; let m = typeof fn === 'function' ? fn(rows[0]) : rows[0][fn]; for (let i = 1; i < rows.length; i++) { const v = typeof fn === 'function' ? fn(rows[i]) : rows[i][fn]; if (v > m) m = v; } return m; }; }`,
354
386
 
387
+ // ── Window functions ─────────────────────────────────
388
+ win_row_number: `function win_row_number() { return (_rows, index) => index + 1; }`,
389
+ win_rank: `function win_rank() { return (_rows, index, ctx) => { if (index === 0) return 1; const cur = ctx.orderValues[index]; for (let i = index - 1; i >= 0; i--) { if (ctx.orderValues[i] !== cur) return i + 2; } return 1; }; }`,
390
+ win_dense_rank: `function win_dense_rank() { return (_rows, index, ctx) => { if (index === 0) return 1; let rank = 1; for (let i = 1; i <= index; i++) { if (ctx.orderValues[i] !== ctx.orderValues[i - 1]) rank++; } return rank; }; }`,
391
+ win_percent_rank: `function win_percent_rank() { return (rows, index, ctx) => { const n = ctx.partitionSize; if (n <= 1) return 0; const cur = ctx.orderValues[index]; let r = 1; if (index > 0) { for (let i = index - 1; i >= 0; i--) { if (ctx.orderValues[i] !== cur) { r = i + 2; break; } } } return (r - 1) / (n - 1); }; }`,
392
+ win_ntile: `function win_ntile(buckets) { return (_rows, index, ctx) => Math.floor(index * buckets / ctx.partitionSize) + 1; }`,
393
+ win_lag: `function win_lag(colFn, offset, defaultVal) { if (offset === undefined) offset = 1; if (defaultVal === undefined) defaultVal = null; return (rows, index) => { const t = index - offset; if (t < 0 || t >= rows.length) return defaultVal; return typeof colFn === 'function' ? colFn(rows[t]) : rows[t][colFn]; }; }`,
394
+ win_lead: `function win_lead(colFn, offset, defaultVal) { if (offset === undefined) offset = 1; if (defaultVal === undefined) defaultVal = null; return (rows, index) => { const t = index + offset; if (t < 0 || t >= rows.length) return defaultVal; return typeof colFn === 'function' ? colFn(rows[t]) : rows[t][colFn]; }; }`,
395
+ win_first_value: `function win_first_value(colFn) { return (rows) => { if (rows.length === 0) return null; return typeof colFn === 'function' ? colFn(rows[0]) : rows[0][colFn]; }; }`,
396
+ win_last_value: `function win_last_value(colFn) { return (rows) => { if (rows.length === 0) return null; const last = rows[rows.length - 1]; return typeof colFn === 'function' ? colFn(last) : last[colFn]; }; }`,
397
+ win_running_sum: `function win_running_sum(colFn) { return (rows, index) => { let s = 0; for (let i = 0; i <= index; i++) s += typeof colFn === 'function' ? colFn(rows[i]) : rows[i][colFn]; return s; }; }`,
398
+ win_running_count: `function win_running_count() { return (_rows, index) => index + 1; }`,
399
+ win_running_avg: `function win_running_avg(colFn) { return (rows, index) => { let s = 0; for (let i = 0; i <= index; i++) s += typeof colFn === 'function' ? colFn(rows[i]) : rows[i][colFn]; return s / (index + 1); }; }`,
400
+ win_running_min: `function win_running_min(colFn) { return (rows, index) => { let m = typeof colFn === 'function' ? colFn(rows[0]) : rows[0][colFn]; for (let i = 1; i <= index; i++) { const v = typeof colFn === 'function' ? colFn(rows[i]) : rows[i][colFn]; if (v < m) m = v; } return m; }; }`,
401
+ win_running_max: `function win_running_max(colFn) { return (rows, index) => { let m = typeof colFn === 'function' ? colFn(rows[0]) : rows[0][colFn]; for (let i = 1; i <= index; i++) { const v = typeof colFn === 'function' ? colFn(rows[i]) : rows[i][colFn]; if (v > m) m = v; } return m; }; }`,
402
+ win_moving_avg: `function win_moving_avg(colFn, windowSize) { return (rows, index) => { const start = Math.max(0, index - windowSize + 1); let s = 0; for (let i = start; i <= index; i++) s += typeof colFn === 'function' ? colFn(rows[i]) : rows[i][colFn]; return s / (index - start + 1); }; }`,
403
+ table_window: `function table_window(table, opts, windowFns) { const partFn = opts.partition || null; const ordFn = opts.order || null; const desc = opts.desc || false; const parts = new Map(); for (let i = 0; i < table._rows.length; i++) { const r = table._rows[i]; const k = partFn ? String(typeof partFn === 'function' ? partFn(r) : r[partFn]) : '__all__'; if (!parts.has(k)) parts.set(k, []); parts.get(k).push({ row: r, oi: i }); } if (ordFn) { for (const [, items] of parts) { items.sort((a, b) => { const ka = typeof ordFn === 'function' ? ordFn(a.row) : a.row[ordFn]; const kb = typeof ordFn === 'function' ? ordFn(b.row) : b.row[ordFn]; let c = 0; if (ka < kb) c = -1; else if (ka > kb) c = 1; return desc ? -c : c; }); } } const res = new Array(table._rows.length); for (let i = 0; i < res.length; i++) res[i] = {}; for (const [, items] of parts) { const pr = items.map(it => it.row); const ov = ordFn ? pr.map(r => typeof ordFn === 'function' ? ordFn(r) : r[ordFn]) : pr.map((_, i) => i); const ctx = { orderValues: ov, partitionSize: pr.length }; for (const [cn, wf] of Object.entries(windowFns)) { for (let idx = 0; idx < pr.length; idx++) { res[items[idx].oi][cn] = wf(pr, idx, ctx); } } } const nc = [...table._columns]; for (const cn of Object.keys(windowFns)) { if (!nc.includes(cn)) nc.push(cn); } return new Table(table._rows.map((r, i) => Object.assign({}, r, res[i])), nc); }`,
404
+
355
405
  // ── Data exploration ────────────────────────────────
356
406
  peek: `function peek(table, opts) { const o = typeof opts === 'object' ? opts : {}; console.log(table._format ? table._format(o.n || 10, o.title) : String(table)); return table; }`,
357
407
  describe: `function describe(table) { const stats = []; for (const col of table._columns) { const vals = table._rows.map(r => r[col]).filter(v => v != null); const st = { Column: col, Type: 'Unknown', 'Non-Null': vals.length }; if (vals.length > 0) { const s = vals[0]; if (typeof s === 'number') { st.Type = Number.isInteger(s) ? 'Int' : 'Float'; st.Mean = vals.reduce((a, b) => a + b, 0) / vals.length; let mn = vals[0], mx = vals[0]; for (let i = 1; i < vals.length; i++) { if (vals[i] < mn) mn = vals[i]; if (vals[i] > mx) mx = vals[i]; } st.Min = mn; st.Max = mx; } else if (typeof s === 'string') { st.Type = 'String'; st.Unique = new Set(vals).size; } else if (typeof s === 'boolean') { st.Type = 'Bool'; } } stats.push(st); } const dt = Table(stats); console.log(dt._format(100, 'describe()')); return dt; }`,
@@ -381,7 +431,10 @@ Table.prototype = { get rows() { return this._rows.length; }, get columns() { re
381
431
  try { const data = JSON.parse(text); if (Array.isArray(data)) return Table(data); return data; } catch { return __parseCSV(text, options); }
382
432
  }
383
433
  const fs = await import('fs'); const path = await import('path');
384
- const ext = path.extname(source).toLowerCase(); const text = fs.readFileSync(source, 'utf-8');
434
+ const ext = path.extname(source).toLowerCase();
435
+ if (ext === '.parquet') return readParquet(source);
436
+ if (ext === '.xlsx') return readExcel(source, options);
437
+ const text = fs.readFileSync(source, 'utf-8');
385
438
  if (ext === '.csv') return __parseCSV(text, options);
386
439
  if (ext === '.tsv') return __parseCSV(text, { ...options, delimiter: '\\t' });
387
440
  if (ext === '.json') { const data = JSON.parse(text); if (Array.isArray(data)) return Table(data); return data; }
@@ -391,6 +444,8 @@ Table.prototype = { get rows() { return this._rows.length; }, get columns() { re
391
444
  write: `async function write(data, destination, opts) {
392
445
  const fs = await import('fs'); const path = await import('path');
393
446
  const ext = path.extname(destination).toLowerCase();
447
+ if (ext === '.parquet') { return writeParquet(data, destination, opts); }
448
+ if (ext === '.xlsx') { return writeExcel(data, destination, opts); }
394
449
  const isTable = data && data._rows && data._columns;
395
450
  const td = isTable ? data : (Array.isArray(data) ? Table(data) : null);
396
451
  let content;
@@ -516,7 +571,7 @@ Table.prototype = { get rows() { return this._rows.length; }, get columns() { re
516
571
  // ── Validation ─────────────────────────────────────────
517
572
  is_email: `function is_email(s) { return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(s); }`,
518
573
  is_url: `function is_url(s) { try { new URL(s); return true; } catch { return false; } }`,
519
- is_numeric: `function is_numeric(s) { return typeof s === 'string' && s.length > 0 && !isNaN(Number(s)); }`,
574
+ is_numeric: `function is_numeric(s) { return typeof s === 'string' && s.length > 0 && s.trim().length > 0 && !isNaN(Number(s)); }`,
520
575
  is_alpha: `function is_alpha(s) { return /^[a-zA-Z]+$/.test(s); }`,
521
576
  is_alphanumeric: `function is_alphanumeric(s) { return /^[a-zA-Z0-9]+$/.test(s); }`,
522
577
  is_uuid: `function is_uuid(s) { return /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(s); }`,
@@ -581,11 +636,11 @@ Table.prototype = { get rows() { return this._rows.length; }, get columns() { re
581
636
  flip: `function flip(fn) { return function(a, b, ...rest) { return fn(b, a, ...rest); }; }`,
582
637
 
583
638
  // ── Encoding (extended) ────────────────────────────────
584
- hex_encode: `function hex_encode(s) { let r = ''; for (let i = 0; i < s.length; i++) r += s.charCodeAt(i).toString(16).padStart(2, '0'); return r; }`,
639
+ hex_encode: `function hex_encode(s) { let r = ''; if (ArrayBuffer.isView(s) || s instanceof ArrayBuffer) { const u = ArrayBuffer.isView(s) ? s : new Uint8Array(s); for (let i = 0; i < u.length; i++) r += u[i].toString(16).padStart(2, '0'); return r; } for (let i = 0; i < s.length; i++) r += s.charCodeAt(i).toString(16).padStart(2, '0'); return r; }`,
585
640
  hex_decode: `function hex_decode(s) { let r = ''; for (let i = 0; i < s.length; i += 2) r += String.fromCharCode(parseInt(s.substr(i, 2), 16)); return r; }`,
586
641
 
587
642
  // ── String (extended) ──────────────────────────────────
588
- fmt: `function fmt(template, ...args) { let i = 0; return template.replace(/\\{\\}/g, () => i < args.length ? String(args[i++]) : '{}'); }`,
643
+ fmt: `function fmt(template, ...args) { var named = args.length === 1 && args[0] !== null && typeof args[0] === 'object' && !Array.isArray(args[0]) && !(args[0] instanceof Date); var obj = named ? args[0] : null; var ai = 0, result = '', pos = 0, len = template.length; while (pos < len) { if (pos + 1 < len && template[pos] === '{' && template[pos + 1] === '{') { result += '{'; pos += 2; continue; } if (pos + 1 < len && template[pos] === '}' && template[pos + 1] === '}') { result += '}'; pos += 2; continue; } if (template[pos] === '{') { var close = template.indexOf('}', pos + 1); if (close === -1) { result += template[pos]; pos++; continue; } var inner = template.substring(pos + 1, close); pos = close + 1; var colonIdx = inner.indexOf(':'); var key = colonIdx >= 0 ? inner.substring(0, colonIdx) : inner; var spec = colonIdx >= 0 ? inner.substring(colonIdx + 1) : ''; var val; if (named && key.length > 0) { val = obj[key]; if (val === undefined) { result += '{' + inner + '}'; continue; } } else if (key.length === 0) { if (ai < args.length) { val = args[ai++]; } else { result += '{}'; continue; } } else { if (ai < args.length) { val = args[ai++]; } else { result += '{' + inner + '}'; continue; } } if (!spec) { result += String(val); continue; } var si = 0, fill = ' ', align = '', sign = '', comma = false, width = 0, hasWidth = false, precision = -1, type = ''; if (si + 1 < spec.length && (spec[si + 1] === '<' || spec[si + 1] === '>' || spec[si + 1] === '^')) { fill = spec[si]; align = spec[si + 1]; si += 2; } else if (si < spec.length && (spec[si] === '<' || spec[si] === '>' || spec[si] === '^')) { align = spec[si]; si += 1; } if (si < spec.length && (spec[si] === '+' || spec[si] === '-' || spec[si] === ' ')) { sign = spec[si]; si += 1; } while (si < spec.length && spec[si] >= '0' && spec[si] <= '9') { width = width * 10 + (spec.charCodeAt(si) - 48); hasWidth = true; si += 1; } if (si < spec.length && spec[si] === ',') { comma = true; si += 1; } if (si < spec.length && spec[si] === '.') { si += 1; precision = 0; while (si < spec.length && spec[si] >= '0' && spec[si] <= '9') { precision = precision * 10 + (spec.charCodeAt(si) - 48); si += 1; } } if (si < spec.length) { type = spec[si]; } var formatted, numVal = typeof val === 'number' ? val : Number(val); switch (type) { case 'b': formatted = (numVal >>> 0).toString(2); if (numVal === 0) formatted = '0'; break; case 'o': formatted = (numVal >>> 0).toString(8); if (numVal === 0) formatted = '0'; break; case 'x': formatted = (numVal >>> 0).toString(16); if (numVal === 0) formatted = '0'; break; case 'X': formatted = (numVal >>> 0).toString(16).toUpperCase(); if (numVal === 0) formatted = '0'; break; case 'f': formatted = numVal.toFixed(precision >= 0 ? precision : 6); break; case '%': { var pct = numVal * 100; formatted = precision >= 0 ? pct.toFixed(precision) + '%' : (Math.round(pct * 1e10) / 1e10).toString() + '%'; break; } case '$': { var abs = Math.abs(numVal), dollars = abs.toFixed(2), dotIdx2 = dollars.indexOf('.'), intPart2 = dollars.substring(0, dotIdx2), decPart2 = dollars.substring(dotIdx2); var withCommas2 = ''; for (var j2 = 0; j2 < intPart2.length; j2++) { if (j2 > 0 && (intPart2.length - j2) % 3 === 0) withCommas2 += ','; withCommas2 += intPart2[j2]; } formatted = (numVal < 0 ? '-' : '') + '$' + withCommas2 + decPart2; break; } case 's': formatted = String(val); if (precision >= 0) formatted = formatted.substring(0, precision); break; default: if (typeof val === 'number' && precision >= 0 && !type) formatted = numVal.toFixed(precision); else formatted = String(val); break; } if (comma && type !== '$') { var dIdx = formatted.indexOf('.'), iPart = dIdx >= 0 ? formatted.substring(0, dIdx) : formatted, dPart = dIdx >= 0 ? formatted.substring(dIdx) : ''; var signChar = '', digits = iPart; if (digits[0] === '-' || digits[0] === '+') { signChar = digits[0]; digits = digits.substring(1); } var withC = ''; for (var j = 0; j < digits.length; j++) { if (j > 0 && (digits.length - j) % 3 === 0) withC += ','; withC += digits[j]; } formatted = signChar + withC + dPart; } if (sign && type !== '$' && type !== '%') { if (typeof val === 'number') { var s = formatted; if (s[0] === '-' || s[0] === '+') { s = s.substring(1); } if (numVal >= 0) { if (sign === '+') formatted = '+' + s; else if (sign === ' ') formatted = ' ' + s; else formatted = s; } else { formatted = '-' + s; } } } if (hasWidth && formatted.length < width) { var pad = width - formatted.length, a = align || '>'; if (a === '<') formatted = formatted + fill.repeat(pad); else if (a === '^') { var left = Math.floor(pad / 2); formatted = fill.repeat(left) + formatted + fill.repeat(pad - left); } else formatted = fill.repeat(pad) + formatted; } result += formatted; continue; } result += template[pos]; pos++; } return result; }`,
589
644
 
590
645
  // ── Scripting: Environment & CLI ──────────────────────
591
646
  env: `function env(key, fallback) { if (key === undefined) return { ...process.env }; const v = process.env[key]; return v !== undefined ? v : (fallback !== undefined ? fallback : null); }`,
@@ -992,6 +1047,19 @@ Table.prototype = { get rows() { return this._rows.length; }, get columns() { re
992
1047
  pretty(v) { return JSON.stringify(v, null, 2); }
993
1048
  });`,
994
1049
 
1050
+ crypto: `const crypto = Object.freeze({
1051
+ sha256(data) { const c = require('crypto'); return c.createHash('sha256').update(typeof data === 'string' ? data : Buffer.from(data)).digest('hex'); },
1052
+ sha512(data) { const c = require('crypto'); return c.createHash('sha512').update(typeof data === 'string' ? data : Buffer.from(data)).digest('hex'); },
1053
+ hmac(algo, key, data) { const c = require('crypto'); return c.createHmac(algo, key).update(data).digest('hex'); },
1054
+ random_bytes(n) { return new Uint8Array(require('crypto').randomBytes(n)); },
1055
+ random_int(min, max) { return min + Math.floor(Math.random() * (max - min + 1)); },
1056
+ hash_password(password) { try { const c = require('crypto'); const salt = c.randomBytes(16); const hash = c.scryptSync(password, salt, 64); return Ok(salt.toString('hex') + ':' + hash.toString('hex')); } catch (e) { return Err(e.message); } },
1057
+ verify_password(password, stored) { try { const c = require('crypto'); const [saltHex, hashHex] = stored.split(':'); const salt = Buffer.from(saltHex, 'hex'); const hash = Buffer.from(hashHex, 'hex'); const derived = c.scryptSync(password, salt, 64); return c.timingSafeEqual(hash, derived); } catch { return false; } },
1058
+ encrypt(plaintext, key) { try { const c = require('crypto'); const iv = c.randomBytes(12); const kb = typeof key === 'string' ? Buffer.from(key, 'utf-8').slice(0, 32) : key; const cipher = c.createCipheriv('aes-256-gcm', kb, iv); let enc = cipher.update(plaintext, 'utf8', 'hex'); enc += cipher.final('hex'); const tag = cipher.getAuthTag().toString('hex'); return Ok(iv.toString('hex') + ':' + tag + ':' + enc); } catch (e) { return Err(e.message); } },
1059
+ decrypt(ciphertext, key) { try { const c = require('crypto'); const [ivHex, tagHex, enc] = ciphertext.split(':'); const iv = Buffer.from(ivHex, 'hex'); const tag = Buffer.from(tagHex, 'hex'); const kb = typeof key === 'string' ? Buffer.from(key, 'utf-8').slice(0, 32) : key; const decipher = c.createDecipheriv('aes-256-gcm', kb, iv); decipher.setAuthTag(tag); let dec = decipher.update(enc, 'hex', 'utf8'); dec += decipher.final('utf8'); return Ok(dec); } catch (e) { return Err(e.message); } },
1060
+ constant_time_equal(a, b) { try { const ba = Buffer.from(a); const bb = Buffer.from(b); if (ba.length !== bb.length) return false; return require('crypto').timingSafeEqual(ba, bb); } catch { return false; } }
1061
+ });`,
1062
+
995
1063
  fs: `const fs = Object.freeze({
996
1064
  read_text(path, enc) { try { return Ok(require('fs').readFileSync(path, enc || 'utf-8')); } catch (e) { return Err(e.message); } },
997
1065
  write_text(path, content, opts) { try { const f = require('fs'); if (opts && opts.append) f.appendFileSync(path, content); else f.writeFileSync(path, content); return Ok(path); } catch (e) { return Err(e.message); } },
@@ -1013,6 +1081,48 @@ Table.prototype = { get rows() { return this._rows.length; }, get columns() { re
1013
1081
  build_query(obj) { return Object.entries(obj).map(([k, v]) => encodeURIComponent(k) + '=' + encodeURIComponent(v)).join('&'); }
1014
1082
  });`,
1015
1083
 
1084
+ http: `const http = Object.freeze({
1085
+ async _request(method, url, body, opts) {
1086
+ var o = opts || {};
1087
+ var headers = o.headers ? { ...o.headers } : {};
1088
+ if (o.bearer) headers['Authorization'] = 'Bearer ' + o.bearer;
1089
+ if (o.params) { var _qs = new URLSearchParams(o.params).toString(); if (_qs) url += (url.includes('?') ? '&' : '?') + _qs; }
1090
+ if (typeof FormData !== 'undefined' && body instanceof FormData) { delete headers['Content-Type']; }
1091
+ else if (body && typeof body === 'object' && body.__form) { var _fd = new FormData(); Object.keys(body).forEach(function(k) { if (k !== '__form') _fd.append(k, body[k]); }); body = _fd; delete headers['Content-Type']; }
1092
+ else if (body && typeof body === 'object' && !(body instanceof ArrayBuffer) && !(body instanceof Uint8Array) && !headers['Content-Type']) { headers['Content-Type'] = 'application/json'; body = JSON.stringify(body); }
1093
+ var timeout = o.timeout || 30000;
1094
+ var retries = o.retries || 0;
1095
+ var retryDelay = o.retry_delay || 1000;
1096
+ var attempt = 0;
1097
+ while (true) {
1098
+ try {
1099
+ var controller = new AbortController();
1100
+ var timer = setTimeout(function() { controller.abort(); }, timeout);
1101
+ var resp = await fetch(url, { method: method, headers: headers, body: method !== 'GET' && method !== 'HEAD' ? body : undefined, signal: controller.signal, redirect: o.follow_redirects === false ? 'manual' : 'follow' });
1102
+ clearTimeout(timer);
1103
+ var respHeaders = {};
1104
+ resp.headers.forEach(function(v, k) { respHeaders[k] = v; });
1105
+ if (o.stream) { return Ok({ status: resp.status, headers: respHeaders, body: resp.body, ok: resp.ok }); }
1106
+ var respBody;
1107
+ var ct = resp.headers.get('content-type') || '';
1108
+ if (ct.includes('application/json')) { try { respBody = await resp.json(); } catch(e) { respBody = await resp.text(); } }
1109
+ else { respBody = await resp.text(); }
1110
+ return Ok({ status: resp.status, headers: respHeaders, body: respBody, ok: resp.ok, json: function() { try { return Ok(typeof respBody === 'string' ? JSON.parse(respBody) : respBody); } catch (e) { return Err(e.message); } } });
1111
+ } catch (e) {
1112
+ if (attempt < retries) { attempt++; await new Promise(function(r) { setTimeout(r, retryDelay * attempt); }); continue; }
1113
+ return Err(e.name === 'AbortError' ? 'Timeout after ' + timeout + 'ms' : e.message);
1114
+ }
1115
+ }
1116
+ },
1117
+ get(url, opts) { return http._request('GET', url, null, opts); },
1118
+ post(url, body, opts) { return http._request('POST', url, body, opts); },
1119
+ put(url, body, opts) { return http._request('PUT', url, body, opts); },
1120
+ patch(url, body, opts) { return http._request('PATCH', url, body, opts); },
1121
+ delete(url, opts) { return http._request('DELETE', url, null, opts); },
1122
+ head(url, opts) { return http._request('HEAD', url, null, opts); },
1123
+ get_stream(url, opts) { return http._request('GET', url, null, Object.assign({}, opts, { stream: true })); }
1124
+ })`,
1125
+
1016
1126
  // ── Channel-based async ───────────────────────────────
1017
1127
  Channel: `class Channel {
1018
1128
  constructor(capacity) {
@@ -1227,6 +1337,24 @@ Table.prototype = { get rows() { return this._rows.length; }, get columns() { re
1227
1337
  OrderedDict, DefaultDict, Counter, Deque
1228
1338
  });`,
1229
1339
 
1340
+ // ── LRU Cache ─────────────────────────────────────────
1341
+ LRUCache: `class LRUCache {
1342
+ constructor(maxSize, ttl) { this._max = maxSize; this._ttl = ttl || 0; this._map = new Map(); this._hits = 0; this._misses = 0; }
1343
+ get(key) { var entry = this._map.get(key); if (\!entry) { this._misses++; return None; } if (this._ttl > 0 && Date.now() - entry.t > this._ttl) { this._map.delete(key); this._misses++; return None; } this._map.delete(key); this._map.set(key, entry); this._hits++; return Some(entry.v); }
1344
+ set(key, value) { if (this._map.has(key)) this._map.delete(key); else if (this._map.size >= this._max) { var first = this._map.keys().next().value; this._map.delete(first); } this._map.set(key, { v: value, t: Date.now() }); }
1345
+ has(key) { if (\!this._map.has(key)) return false; if (this._ttl > 0) { var entry = this._map.get(key); if (Date.now() - entry.t > this._ttl) { this._map.delete(key); return false; } } return true; }
1346
+ delete(key) { return this._map.delete(key); }
1347
+ clear() { this._map.clear(); this._hits = 0; this._misses = 0; }
1348
+ size() { return this._map.size; }
1349
+ keys() { return [...this._map.keys()]; }
1350
+ stats() { var total = this._hits + this._misses; return { hits: this._hits, misses: this._misses, hit_rate: total > 0 ? this._hits / total : 0 }; }
1351
+ }`,
1352
+
1353
+ cache: `const cache = Object.freeze({
1354
+ lru(maxSize) { return new LRUCache(maxSize, 0); },
1355
+ ttl(maxSize, ttlMs) { return new LRUCache(maxSize, ttlMs); }
1356
+ })`,
1357
+
1230
1358
  // ─── Typed numeric array functions for @fast mode ───────────────
1231
1359
 
1232
1360
  typed_zeros: `function typed_zeros(n, Type) {
@@ -1322,6 +1450,172 @@ Table.prototype = { get rows() { return this._rows.length; }, get columns() { re
1322
1450
  out.sort((a, b) => a - b);
1323
1451
  return out;
1324
1452
  }`,
1453
+
1454
+ // ── Logging Namespace ──────────────────────────────────
1455
+ log: `var log = (function() {
1456
+ var _level = 1;
1457
+ var _levels = { debug: 0, info: 1, warn: 2, error: 3, silent: 4 };
1458
+ var _format = 'pretty';
1459
+ var _noColor = typeof process !== 'undefined' && (process.env.NO_COLOR || (process.stdout && !process.stdout.isTTY));
1460
+ var _colors = { debug: '36', info: '32', warn: '33', error: '31' };
1461
+ var _labels = { debug: 'DBG', info: 'INF', warn: 'WRN', error: 'ERR' };
1462
+ function _emit(lvl, context, msg, data) {
1463
+ if (_levels[lvl] < _level) return;
1464
+ var consoleFn = lvl === 'error' ? console.error : lvl === 'warn' ? console.warn : lvl === 'debug' ? (console.debug || console.log) : console.log;
1465
+ if (_format === 'json') {
1466
+ var obj = { level: lvl, msg: msg, timestamp: new Date().toISOString() };
1467
+ if (context) Object.assign(obj, context);
1468
+ if (data && typeof data === 'object') Object.assign(obj, data);
1469
+ consoleFn(JSON.stringify(obj));
1470
+ return;
1471
+ }
1472
+ var ts = new Date().toISOString().slice(11, 19);
1473
+ var label = _labels[lvl];
1474
+ if (!_noColor) label = '\\x1b[' + _colors[lvl] + 'm' + label + '\\x1b[0m';
1475
+ var parts = [ts, label, msg];
1476
+ if (data !== undefined) parts.push(typeof data === 'object' ? JSON.stringify(data) : String(data));
1477
+ if (context) parts.push(JSON.stringify(context));
1478
+ consoleFn(parts.join(' '));
1479
+ }
1480
+ function _makeLogger(ctx) {
1481
+ return {
1482
+ debug: function(msg, data) { _emit('debug', ctx, msg, data); },
1483
+ info: function(msg, data) { _emit('info', ctx, msg, data); },
1484
+ warn: function(msg, data) { _emit('warn', ctx, msg, data); },
1485
+ error: function(msg, data) { _emit('error', ctx, msg, data); },
1486
+ level: function(l) { _level = _levels[l] !== undefined ? _levels[l] : 1; },
1487
+ format: function(f) { _format = f; },
1488
+ with: function(extra) { var merged = ctx ? Object.assign({}, ctx, extra) : extra; return _makeLogger(merged); }
1489
+ };
1490
+ }
1491
+ return _makeLogger(null);
1492
+ })()`,
1493
+ // ── Sampling ──────────────────────────────────────────
1494
+ __xorshift128: `function __xorshift128(seed) { let s = [seed, seed ^ 0xDEADBEEF, seed ^ 0x12345678, seed ^ 0x87654321]; return function() { let t = s[3]; t ^= t << 11; t ^= t >>> 8; s[3] = s[2]; s[2] = s[1]; s[1] = s[0]; t ^= s[0]; t ^= s[0] >>> 19; s[0] = t; return (t >>> 0) / 4294967296; }; }`,
1495
+ table_sample: `function table_sample(table, n, opts) { var total = table._rows.length; var k = n < 1 ? Math.floor(n * total) : Math.min(n, total); if (k <= 0) return Table([], table._columns); if (k >= total) return Table([].concat(table._rows), table._columns); var rng = opts && opts.seed != null ? __xorshift128(opts.seed) : function() { return Math.random(); }; var indices = Array.from({ length: total }, function(_, i) { return i; }); for (var i = 0; i < k; i++) { var j = i + Math.floor(rng() * (total - i)); var tmp = indices[i]; indices[i] = indices[j]; indices[j] = tmp; } var rows = []; for (var i = 0; i < k; i++) rows.push(table._rows[indices[i]]); return Table(rows, table._columns); }`,
1496
+ table_stratified_sample: `function table_stratified_sample(table, keyFn, n, opts) { var groups = new Map(); for (var ri = 0; ri < table._rows.length; ri++) { var row = table._rows[ri]; var key = String(typeof keyFn === 'function' ? keyFn(row) : row[keyFn]); if (!groups.has(key)) groups.set(key, []); groups.get(key).push(row); } var allRows = []; var gi = 0; groups.forEach(function(gr) { var gt = Table(gr, table._columns); var go = opts && opts.seed != null ? { seed: opts.seed + gi * 7919 } : {}; var s = table_sample(gt, n, go); for (var si = 0; si < s._rows.length; si++) allRows.push(s._rows[si]); gi++; }); return Table(allRows, table._columns); }`,
1497
+
1498
+ // ── SQLite Connector ──────────────────────────────────
1499
+ sqlite: `function sqlite(path) { var Database; try { Database = typeof Bun !== 'undefined' ? require('bun:sqlite').Database : require('better-sqlite3'); } catch(e) { throw new Error('SQLite requires Bun (built-in) or "better-sqlite3" package under Node'); } var db = new Database(path); function _inferType(v) { if (v === null || v === undefined) return 'TEXT'; if (typeof v === 'boolean') return 'INTEGER'; if (typeof v === 'number') return Number.isInteger(v) ? 'INTEGER' : 'REAL'; return 'TEXT'; } return { _isTovaSqlite: true, query: function(sql, params) { var stmt = db.prepare(sql); var rows = params ? stmt.all.apply(stmt, params) : stmt.all(); return Table(rows); }, exec: function(sql, params) { var stmt = db.prepare(sql); var result = params ? stmt.run.apply(stmt, params) : stmt.run(); return { changes: result.changes }; }, writeTable: function(tableData, tableName, opts) { var t = tableData._rows ? tableData : Table(tableData); if (t._rows.length === 0) return; if (!opts || !opts.append) { db.run('DROP TABLE IF EXISTS "' + tableName + '"'); var colDefs = t._columns.map(function(c) { return '"' + c + '" ' + _inferType(t._rows[0][c]); }).join(', '); db.run('CREATE TABLE "' + tableName + '" (' + colDefs + ')'); } var ph = t._columns.map(function() { return '?'; }).join(', '); var cols = t._columns.map(function(c) { return '"' + c + '"'; }).join(', '); var ins = db.prepare('INSERT INTO "' + tableName + '" (' + cols + ') VALUES (' + ph + ')'); var tx = db.transaction(function(rows) { for (var i = 0; i < rows.length; i++) { var vals = t._columns.map(function(c) { var v = rows[i][c]; if (v === undefined || v === null) return null; if (typeof v === 'boolean') return v ? 1 : 0; return v; }); ins.run.apply(ins, vals); } }); tx(t._rows); }, close: function() { db.close(); } }; }`,
1500
+
1501
+ // ── SVG Charting ──────────────────────────────────────────
1502
+ __chart_helpers: `var __chart_PALETTE = ['#4f46e5', '#059669', '#d97706', '#dc2626', '#7c3aed', '#0891b2', '#be185d', '#65a30d'];
1503
+ var __chart_DEFAULT_MARGIN = { top: 40, right: 20, bottom: 60, left: 70 };
1504
+ function __chart_esc(s) { return String(s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;'); }
1505
+ function __chart_getRows(data) { if (data && data._rows) return data._rows; if (Array.isArray(data)) return data; return []; }
1506
+ function __chart_niceTicks(mn, mx, count) { if (count === undefined) count = 5; if (mn === mx) { mn = mn - 1; mx = mx + 1; } var range = mx - mn; var roughStep = range / count; var mag = Math.pow(10, Math.floor(Math.log10(roughStep))); var cands = [1, 2, 5, 10]; var step = mag; for (var i = 0; i < cands.length; i++) { if (cands[i] * mag >= roughStep) { step = cands[i] * mag; break; } } var start = Math.floor(mn / step) * step; var ticks = []; for (var v = start; v <= mx + step * 0.5; v += step) { ticks.push(Math.round(v * 1e10) / 1e10); } return ticks; }
1507
+ function __chart_formatNum(n) { if (Number.isInteger(n)) return String(n); if (Math.abs(n) >= 1000) return String(Math.round(n)); return n.toFixed(1); }
1508
+ function __chart_empty(w, h, msg) { return '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ' + w + ' ' + h + '" width="' + w + '" height="' + h + '" style="font-family:system-ui,sans-serif"><text x="' + (w / 2) + '" y="' + (h / 2) + '" text-anchor="middle" fill="#888" font-size="14">' + __chart_esc(msg || 'No data') + '</text></svg>'; }`,
1509
+
1510
+ bar_chart: `function bar_chart(data, opts) { if (!opts) opts = {}; var rows = __chart_getRows(data); var width = opts.width || 600; var height = opts.height || 400; if (rows.length === 0) return __chart_empty(width, height, 'No data'); var xFn = opts.x; var yFn = opts.y; var title = opts.title || ''; var clr = opts.color || __chart_PALETTE[0]; var margin = { top: title ? 50 : 40, right: 20, bottom: 60, left: 70 }; var labels = rows.map(function(r) { return String(xFn(r)); }); var values = rows.map(function(r) { return Number(yFn(r)); }); var plotW = width - margin.left - margin.right; var plotH = height - margin.top - margin.bottom; var yMax = Math.max.apply(null, values); var ticks = __chart_niceTicks(0, yMax); var scaleMax = ticks[ticks.length - 1]; var barW = plotW / labels.length; var innerW = barW * 0.85; var p = []; p.push('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ' + width + ' ' + height + '" width="' + width + '" height="' + height + '" style="font-family:system-ui,sans-serif">'); if (title) p.push('<text x="' + (width / 2) + '" y="24" text-anchor="middle" font-size="16" font-weight="bold" fill="#111">' + __chart_esc(title) + '</text>'); for (var ti = 0; ti < ticks.length; ti++) { var t = ticks[ti]; var ty = margin.top + plotH - (t / scaleMax) * plotH; p.push('<line x1="' + margin.left + '" y1="' + ty + '" x2="' + (margin.left + plotW) + '" y2="' + ty + '" stroke="#e5e7eb" stroke-width="1"/>'); p.push('<text x="' + (margin.left - 8) + '" y="' + (ty + 4) + '" text-anchor="end" font-size="11" fill="#666">' + __chart_formatNum(t) + '</text>'); } for (var i = 0; i < labels.length; i++) { var barH = scaleMax > 0 ? (values[i] / scaleMax) * plotH : 0; var bx = margin.left + i * barW + (barW - innerW) / 2; var by = margin.top + plotH - barH; var bc = Array.isArray(clr) ? clr[i % clr.length] : (opts.colors ? opts.colors[i % opts.colors.length] : clr); p.push('<rect x="' + bx + '" y="' + by + '" width="' + innerW + '" height="' + barH + '" fill="' + bc + '" rx="2"/>'); } p.push('<line x1="' + margin.left + '" y1="' + (margin.top + plotH) + '" x2="' + (margin.left + plotW) + '" y2="' + (margin.top + plotH) + '" stroke="#9ca3af" stroke-width="1"/>'); var rot = labels.length > 6; for (var i = 0; i < labels.length; i++) { var lx = margin.left + i * barW + barW / 2; var ly = margin.top + plotH + 16; if (rot) { p.push('<text x="' + lx + '" y="' + ly + '" text-anchor="end" font-size="11" fill="#666" transform="rotate(-45 ' + lx + ' ' + ly + ')">' + __chart_esc(labels[i]) + '</text>'); } else { p.push('<text x="' + lx + '" y="' + ly + '" text-anchor="middle" font-size="11" fill="#666">' + __chart_esc(labels[i]) + '</text>'); } } p.push('<line x1="' + margin.left + '" y1="' + margin.top + '" x2="' + margin.left + '" y2="' + (margin.top + plotH) + '" stroke="#9ca3af" stroke-width="1"/>'); p.push('</svg>'); return p.join('\\n'); }`,
1511
+
1512
+ line_chart: `function line_chart(data, opts) { if (!opts) opts = {}; var rows = __chart_getRows(data); var width = opts.width || 600; var height = opts.height || 400; if (rows.length === 0) return __chart_empty(width, height, 'No data'); var xFn = opts.x; var yFn = opts.y; var title = opts.title || ''; var clr = opts.color || __chart_PALETTE[0]; var showPts = opts.points || false; var margin = { top: title ? 50 : 40, right: 20, bottom: 60, left: 70 }; var xVals = rows.map(function(r) { return xFn(r); }); var yVals = rows.map(function(r) { return Number(yFn(r)); }); var plotW = width - margin.left - margin.right; var plotH = height - margin.top - margin.bottom; var xNum = xVals.every(function(v) { return typeof v === 'number' && !isNaN(v); }); var xPos; if (xNum) { var xMn = Math.min.apply(null, xVals); var xMx = Math.max.apply(null, xVals); var xR = xMx - xMn || 1; xPos = xVals.map(function(v) { return margin.left + ((v - xMn) / xR) * plotW; }); } else { var n = xVals.length; xPos = xVals.map(function(_, i) { return margin.left + (n > 1 ? (i / (n - 1)) * plotW : plotW / 2); }); } var yMn = Math.min.apply(null, yVals); var yMx = Math.max.apply(null, yVals); var ticks = __chart_niceTicks(yMn > 0 ? 0 : yMn, yMx); var sMn = ticks[0]; var sMx = ticks[ticks.length - 1]; var sR = sMx - sMn || 1; var yPos = yVals.map(function(v) { return margin.top + plotH - ((v - sMn) / sR) * plotH; }); var p = []; p.push('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ' + width + ' ' + height + '" width="' + width + '" height="' + height + '" style="font-family:system-ui,sans-serif">'); if (title) p.push('<text x="' + (width / 2) + '" y="24" text-anchor="middle" font-size="16" font-weight="bold" fill="#111">' + __chart_esc(title) + '</text>'); for (var ti = 0; ti < ticks.length; ti++) { var t = ticks[ti]; var ty = margin.top + plotH - ((t - sMn) / sR) * plotH; p.push('<line x1="' + margin.left + '" y1="' + ty + '" x2="' + (margin.left + plotW) + '" y2="' + ty + '" stroke="#e5e7eb" stroke-width="1"/>'); p.push('<text x="' + (margin.left - 8) + '" y="' + (ty + 4) + '" text-anchor="end" font-size="11" fill="#666">' + __chart_formatNum(t) + '</text>'); } var pts = xPos.map(function(x, i) { return x + ',' + yPos[i]; }).join(' '); p.push('<polyline points="' + pts + '" fill="none" stroke="' + clr + '" stroke-width="2" stroke-linejoin="round"/>'); if (showPts) { for (var i = 0; i < xPos.length; i++) { p.push('<circle cx="' + xPos[i] + '" cy="' + yPos[i] + '" r="4" fill="' + clr + '"/>'); } } p.push('<line x1="' + margin.left + '" y1="' + (margin.top + plotH) + '" x2="' + (margin.left + plotW) + '" y2="' + (margin.top + plotH) + '" stroke="#9ca3af" stroke-width="1"/>'); var lStep = Math.max(1, Math.floor(xVals.length / 8)); for (var i = 0; i < xVals.length; i += lStep) { var lx = xPos[i]; var ly = margin.top + plotH + 16; p.push('<text x="' + lx + '" y="' + ly + '" text-anchor="middle" font-size="11" fill="#666">' + __chart_esc(String(xVals[i])) + '</text>'); } p.push('<line x1="' + margin.left + '" y1="' + margin.top + '" x2="' + margin.left + '" y2="' + (margin.top + plotH) + '" stroke="#9ca3af" stroke-width="1"/>'); p.push('</svg>'); return p.join('\\n'); }`,
1513
+
1514
+ scatter_chart: `function scatter_chart(data, opts) { if (!opts) opts = {}; var rows = __chart_getRows(data); var width = opts.width || 600; var height = opts.height || 400; if (rows.length === 0) return __chart_empty(width, height, 'No data'); var xFn = opts.x; var yFn = opts.y; var title = opts.title || ''; var clr = opts.color || __chart_PALETTE[0]; var rad = opts.r || 5; var margin = { top: title ? 50 : 40, right: 20, bottom: 60, left: 70 }; var xVals = rows.map(function(r) { return Number(xFn(r)); }); var yVals = rows.map(function(r) { return Number(yFn(r)); }); var plotW = width - margin.left - margin.right; var plotH = height - margin.top - margin.bottom; var xTk = __chart_niceTicks(Math.min.apply(null, xVals), Math.max.apply(null, xVals)); var yTk = __chart_niceTicks(Math.min.apply(null, yVals), Math.max.apply(null, yVals)); var xMn = xTk[0]; var xMx = xTk[xTk.length - 1]; var yMn = yTk[0]; var yMx = yTk[yTk.length - 1]; var xR = xMx - xMn || 1; var yR = yMx - yMn || 1; var p = []; p.push('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ' + width + ' ' + height + '" width="' + width + '" height="' + height + '" style="font-family:system-ui,sans-serif">'); if (title) p.push('<text x="' + (width / 2) + '" y="24" text-anchor="middle" font-size="16" font-weight="bold" fill="#111">' + __chart_esc(title) + '</text>'); for (var i = 0; i < yTk.length; i++) { var t = yTk[i]; var ty = margin.top + plotH - ((t - yMn) / yR) * plotH; p.push('<line x1="' + margin.left + '" y1="' + ty + '" x2="' + (margin.left + plotW) + '" y2="' + ty + '" stroke="#e5e7eb" stroke-width="1"/>'); p.push('<text x="' + (margin.left - 8) + '" y="' + (ty + 4) + '" text-anchor="end" font-size="11" fill="#666">' + __chart_formatNum(t) + '</text>'); } for (var i = 0; i < xTk.length; i++) { var t = xTk[i]; var tx = margin.left + ((t - xMn) / xR) * plotW; p.push('<line x1="' + tx + '" y1="' + margin.top + '" x2="' + tx + '" y2="' + (margin.top + plotH) + '" stroke="#e5e7eb" stroke-width="1"/>'); p.push('<text x="' + tx + '" y="' + (margin.top + plotH + 16) + '" text-anchor="middle" font-size="11" fill="#666">' + __chart_formatNum(t) + '</text>'); } for (var i = 0; i < rows.length; i++) { var cx = margin.left + ((xVals[i] - xMn) / xR) * plotW; var cy = margin.top + plotH - ((yVals[i] - yMn) / yR) * plotH; var cc = Array.isArray(clr) ? clr[i % clr.length] : clr; p.push('<circle cx="' + cx + '" cy="' + cy + '" r="' + rad + '" fill="' + cc + '" opacity="0.7"/>'); } p.push('<line x1="' + margin.left + '" y1="' + (margin.top + plotH) + '" x2="' + (margin.left + plotW) + '" y2="' + (margin.top + plotH) + '" stroke="#9ca3af" stroke-width="1"/>'); p.push('<line x1="' + margin.left + '" y1="' + margin.top + '" x2="' + margin.left + '" y2="' + (margin.top + plotH) + '" stroke="#9ca3af" stroke-width="1"/>'); p.push('</svg>'); return p.join('\\n'); }`,
1515
+
1516
+ histogram: `function histogram(data, opts) { if (!opts) opts = {}; var rows = __chart_getRows(data); var width = opts.width || 600; var height = opts.height || 400; if (rows.length === 0) return __chart_empty(width, height, 'No data'); var colFn = opts.col; var title = opts.title || ''; var clr = opts.color || __chart_PALETTE[0]; var numBins = opts.bins || 20; var margin = { top: title ? 50 : 40, right: 20, bottom: 60, left: 70 }; var values = rows.map(function(r) { return Number(colFn(r)); }).filter(function(v) { return !isNaN(v); }); if (values.length === 0) return __chart_empty(width, height, 'No data'); var dMn = Math.min.apply(null, values); var dMx = Math.max.apply(null, values); var bw = (dMx - dMn) / numBins || 1; var bins = []; for (var i = 0; i < numBins; i++) bins.push({ lo: dMn + i * bw, hi: dMn + (i + 1) * bw, count: 0 }); for (var i = 0; i < values.length; i++) { var idx = Math.floor((values[i] - dMn) / bw); if (idx >= numBins) idx = numBins - 1; if (idx < 0) idx = 0; bins[idx].count++; } var maxC = Math.max.apply(null, bins.map(function(b) { return b.count; })); var ticks = __chart_niceTicks(0, maxC); var scaleMax = ticks[ticks.length - 1]; var plotW = width - margin.left - margin.right; var plotH = height - margin.top - margin.bottom; var barW = plotW / numBins; var p = []; p.push('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ' + width + ' ' + height + '" width="' + width + '" height="' + height + '" style="font-family:system-ui,sans-serif">'); if (title) p.push('<text x="' + (width / 2) + '" y="24" text-anchor="middle" font-size="16" font-weight="bold" fill="#111">' + __chart_esc(title) + '</text>'); for (var ti = 0; ti < ticks.length; ti++) { var t = ticks[ti]; var ty = margin.top + plotH - (scaleMax > 0 ? (t / scaleMax) * plotH : 0); p.push('<line x1="' + margin.left + '" y1="' + ty + '" x2="' + (margin.left + plotW) + '" y2="' + ty + '" stroke="#e5e7eb" stroke-width="1"/>'); p.push('<text x="' + (margin.left - 8) + '" y="' + (ty + 4) + '" text-anchor="end" font-size="11" fill="#666">' + __chart_formatNum(t) + '</text>'); } for (var i = 0; i < bins.length; i++) { var barH = scaleMax > 0 ? (bins[i].count / scaleMax) * plotH : 0; var bx = margin.left + i * barW; var by = margin.top + plotH - barH; p.push('<rect x="' + bx + '" y="' + by + '" width="' + barW + '" height="' + barH + '" fill="' + clr + '" stroke="#fff" stroke-width="0.5"/>'); } p.push('<line x1="' + margin.left + '" y1="' + (margin.top + plotH) + '" x2="' + (margin.left + plotW) + '" y2="' + (margin.top + plotH) + '" stroke="#9ca3af" stroke-width="1"/>'); var lc = Math.min(numBins + 1, 8); var ls = Math.max(1, Math.floor(numBins / (lc - 1))); for (var i = 0; i <= numBins; i += ls) { var val = dMn + i * bw; var lx = margin.left + i * barW; var ly = margin.top + plotH + 16; p.push('<text x="' + lx + '" y="' + ly + '" text-anchor="middle" font-size="10" fill="#666">' + __chart_formatNum(val) + '</text>'); } p.push('<line x1="' + margin.left + '" y1="' + margin.top + '" x2="' + margin.left + '" y2="' + (margin.top + plotH) + '" stroke="#9ca3af" stroke-width="1"/>'); p.push('</svg>'); return p.join('\\n'); }`,
1517
+
1518
+ pie_chart: `function pie_chart(data, opts) { if (!opts) opts = {}; var rows = __chart_getRows(data); var width = opts.width || 400; var height = opts.height || 400; if (rows.length === 0) return __chart_empty(width, height, 'No data'); var labelFn = opts.label; var valueFn = opts.value; var title = opts.title || ''; var colors = opts.colors || __chart_PALETTE; var labels = rows.map(function(r) { return String(labelFn(r)); }); var values = rows.map(function(r) { return Number(valueFn(r)); }); var total = values.reduce(function(a, b) { return a + b; }, 0); if (total === 0) return __chart_empty(width, height, 'No data'); var cx = width / 2; var cy = title ? (height + 30) / 2 : height / 2; var r = Math.min(cx, cy) - 50; var p = []; p.push('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ' + width + ' ' + height + '" width="' + width + '" height="' + height + '" style="font-family:system-ui,sans-serif">'); if (title) p.push('<text x="' + (width / 2) + '" y="24" text-anchor="middle" font-size="16" font-weight="bold" fill="#111">' + __chart_esc(title) + '</text>'); var sa = -Math.PI / 2; for (var i = 0; i < values.length; i++) { var sl = (values[i] / total) * 2 * Math.PI; var ea = sa + sl; var x1 = cx + r * Math.cos(sa); var y1 = cy + r * Math.sin(sa); var x2 = cx + r * Math.cos(ea); var y2 = cy + r * Math.sin(ea); var la = sl > Math.PI ? 1 : 0; var c = colors[i % colors.length]; if (values.length === 1) { p.push('<circle cx="' + cx + '" cy="' + cy + '" r="' + r + '" fill="' + c + '"/>'); } else { p.push('<path d="M ' + cx + ' ' + cy + ' L ' + x1 + ' ' + y1 + ' A ' + r + ' ' + r + ' 0 ' + la + ' 1 ' + x2 + ' ' + y2 + ' Z" fill="' + c + '" stroke="#fff" stroke-width="1.5"/>'); } var ma = sa + sl / 2; var lr = r * 0.7; var lx = cx + lr * Math.cos(ma); var ly = cy + lr * Math.sin(ma); var pct = ((values[i] / total) * 100).toFixed(1); p.push('<text x="' + lx + '" y="' + ly + '" text-anchor="middle" font-size="11" fill="#fff" font-weight="bold">' + __chart_esc(labels[i]) + '</text>'); p.push('<text x="' + lx + '" y="' + (ly + 13) + '" text-anchor="middle" font-size="10" fill="#fff">' + pct + '%</text>'); sa = ea; } p.push('</svg>'); return p.join('\\n'); }`,
1519
+
1520
+ // ── Parquet Read/Write ────────────────────────────────────────
1521
+ readParquet: `async function readParquet(path) {
1522
+ var fs = await import('fs'); var arrow = await import('apache-arrow'); var pw = await import('parquet-wasm/node');
1523
+ var fileBytes = new Uint8Array(fs.readFileSync(path));
1524
+ var wasmTable = pw.readParquet(fileBytes);
1525
+ var ipcBytes = wasmTable.intoIPCStream();
1526
+ var arrowTable = arrow.tableFromIPC(ipcBytes);
1527
+ var columns = arrowTable.schema.fields.map(function(f) { return f.name; });
1528
+ var rows = [];
1529
+ for (var i = 0; i < arrowTable.numRows; i++) {
1530
+ var row = {};
1531
+ for (var ci = 0; ci < columns.length; ci++) { var col = columns[ci]; var val = arrowTable.getChild(col).get(i); row[col] = val === undefined ? null : val; }
1532
+ rows.push(row);
1533
+ }
1534
+ return Table(rows, columns);
1535
+ }`,
1536
+
1537
+ writeParquet: `async function writeParquet(tableData, path, opts) {
1538
+ var fs = await import('fs'); var arrow = await import('apache-arrow'); var pw = await import('parquet-wasm/node');
1539
+ var t = tableData && tableData._rows ? tableData : Table(Array.isArray(tableData) ? tableData : []);
1540
+ var columns = t._columns;
1541
+ var COMP_MAP = { snappy: 1, gzip: 2, brotli: 3, zstd: 5, lz4: 6, uncompressed: 0, none: 0 };
1542
+ function _inferType(values) { for (var i = 0; i < values.length; i++) { var v = values[i]; if (v === null || v === undefined) continue; if (typeof v === 'boolean') return 'bool'; if (typeof v === 'number') return Number.isInteger(v) ? 'int' : 'float'; if (typeof v === 'string') return 'string'; } return 'string'; }
1543
+ var colVecs = {};
1544
+ for (var ci = 0; ci < columns.length; ci++) {
1545
+ var col = columns[ci]; var values = t._rows.map(function(r) { var v = r[col]; return v === undefined ? null : v; });
1546
+ var tp = _inferType(values);
1547
+ if (tp === 'int') colVecs[col] = arrow.vectorFromArray(values, new arrow.Int32());
1548
+ else if (tp === 'float') colVecs[col] = arrow.vectorFromArray(values, new arrow.Float64());
1549
+ else if (tp === 'bool') colVecs[col] = arrow.vectorFromArray(values, new arrow.Bool());
1550
+ else colVecs[col] = arrow.vectorFromArray(values, new arrow.Utf8());
1551
+ }
1552
+ var arrowTable = new arrow.Table(colVecs);
1553
+ var ipcBytes = arrow.tableToIPC(arrowTable, 'stream');
1554
+ var wasmTable = pw.Table.fromIPCStream(ipcBytes);
1555
+ var writerProps = null;
1556
+ var comp = (opts && opts.compression) || 'snappy';
1557
+ var compCode = COMP_MAP[comp.toLowerCase()];
1558
+ if (compCode !== undefined) { writerProps = new pw.WriterPropertiesBuilder().setCompression(compCode).build(); }
1559
+ var parquetBytes = pw.writeParquet(wasmTable, writerProps);
1560
+ fs.writeFileSync(path, parquetBytes);
1561
+ }`,
1562
+
1563
+ readExcel: `async function readExcel(path, opts) {
1564
+ var ExcelJS = require('exceljs');
1565
+ var workbook = new ExcelJS.Workbook();
1566
+ await workbook.xlsx.readFile(path);
1567
+ var worksheet;
1568
+ if (opts && typeof opts.sheet === 'string') { worksheet = workbook.getWorksheet(opts.sheet); if (!worksheet) throw new Error('Sheet "' + opts.sheet + '" not found'); }
1569
+ else if (opts && typeof opts.sheet === 'number') { var sheets = workbook.worksheets; if (opts.sheet < 1 || opts.sheet > sheets.length) throw new Error('Sheet index out of range'); worksheet = sheets[opts.sheet - 1]; }
1570
+ else { worksheet = workbook.worksheets[0]; }
1571
+ if (!worksheet) throw new Error('No worksheets found');
1572
+ var headerRow = worksheet.getRow(1);
1573
+ var colArr = [];
1574
+ headerRow.eachCell({ includeEmpty: false }, function(cell, colNumber) { colArr[colNumber] = __excelCellValue(cell); });
1575
+ var colMap = [];
1576
+ for (var i = 1; i < colArr.length; i++) { if (colArr[i] !== undefined && colArr[i] !== null) colMap.push({ colNumber: i, name: String(colArr[i]) }); }
1577
+ if (colMap.length === 0) return Table([], []);
1578
+ var columnNames = colMap.map(function(c) { return c.name; });
1579
+ var rows = [];
1580
+ var rowCount = worksheet.rowCount;
1581
+ for (var r = 2; r <= rowCount; r++) {
1582
+ var excelRow = worksheet.getRow(r);
1583
+ var row = {};
1584
+ for (var ci = 0; ci < colMap.length; ci++) { var cm = colMap[ci]; var cell = excelRow.getCell(cm.colNumber); row[cm.name] = __excelCellValue(cell); }
1585
+ rows.push(row);
1586
+ }
1587
+ return Table(rows, columnNames);
1588
+ }`,
1589
+
1590
+ writeExcel: `async function writeExcel(tableData, path, opts) {
1591
+ var ExcelJS = require('exceljs');
1592
+ var t = tableData && tableData._rows ? tableData : Table(Array.isArray(tableData) ? tableData : []);
1593
+ var workbook = new ExcelJS.Workbook();
1594
+ var sheetName = (opts && opts.sheet) || 'Sheet1';
1595
+ var worksheet = workbook.addWorksheet(sheetName);
1596
+ var cols = t._columns;
1597
+ if (cols.length > 0) worksheet.addRow(cols);
1598
+ for (var i = 0; i < t._rows.length; i++) {
1599
+ var row = t._rows[i];
1600
+ var values = [];
1601
+ for (var ci = 0; ci < cols.length; ci++) { var v = row[cols[ci]]; values.push(v === undefined ? null : v); }
1602
+ worksheet.addRow(values);
1603
+ }
1604
+ await workbook.xlsx.writeFile(path);
1605
+ }`,
1606
+
1607
+ __excelCellValue: `function __excelCellValue(cell) {
1608
+ if (!cell || cell.type === 0) return null;
1609
+ var val = cell.value;
1610
+ if (val === null || val === undefined) return null;
1611
+ if (typeof val === 'object' && val.formula !== undefined) { var result = val.result; return (result === null || result === undefined) ? null : result; }
1612
+ if (typeof val === 'object' && val.richText) { return val.richText.map(function(p) { return p.text; }).join(''); }
1613
+ if (typeof val === 'object' && val.hyperlink) { return val.text || val.hyperlink; }
1614
+ if (typeof val === 'object' && val.error) { return null; }
1615
+ return val;
1616
+ }`,
1617
+
1618
+ heatmap: `function heatmap(data, opts) { if (!opts) opts = {}; var rows = __chart_getRows(data); var width = opts.width || 600; var height = opts.height || 400; if (rows.length === 0) return __chart_empty(width, height, 'No data'); var xFn = opts.x; var yFn = opts.y; var valueFn = opts.value; var title = opts.title || ''; var margin = { top: title ? 50 : 40, right: 40, bottom: 60, left: 80 }; var xCats = []; var yCats = []; var xSet = new Set(); var ySet = new Set(); for (var i = 0; i < rows.length; i++) { var xv = String(xFn(rows[i])); var yv = String(yFn(rows[i])); if (!xSet.has(xv)) { xSet.add(xv); xCats.push(xv); } if (!ySet.has(yv)) { ySet.add(yv); yCats.push(yv); } } var grid = {}; var vMn = Infinity; var vMx = -Infinity; for (var i = 0; i < rows.length; i++) { var xv = String(xFn(rows[i])); var yv = String(yFn(rows[i])); var val = Number(valueFn(rows[i])); grid[xv + '|' + yv] = val; if (val < vMn) vMn = val; if (val > vMx) vMx = val; } var vR = vMx - vMn || 1; var plotW = width - margin.left - margin.right; var plotH = height - margin.top - margin.bottom; var cellW = plotW / xCats.length; var cellH = plotH / yCats.length; function hc(val) { var t = (val - vMn) / vR; var r = Math.round(255 - t * (255 - 79)); var g = Math.round(255 - t * (255 - 70)); var b = Math.round(255 - t * (255 - 229)); return 'rgb(' + r + ',' + g + ',' + b + ')'; } var p = []; p.push('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ' + width + ' ' + height + '" width="' + width + '" height="' + height + '" style="font-family:system-ui,sans-serif">'); if (title) p.push('<text x="' + (width / 2) + '" y="24" text-anchor="middle" font-size="16" font-weight="bold" fill="#111">' + __chart_esc(title) + '</text>'); for (var xi = 0; xi < xCats.length; xi++) { for (var yi = 0; yi < yCats.length; yi++) { var key = xCats[xi] + '|' + yCats[yi]; var val = grid[key]; var rx = margin.left + xi * cellW; var ry = margin.top + yi * cellH; var fill = val !== undefined ? hc(val) : '#f3f4f6'; p.push('<rect x="' + rx + '" y="' + ry + '" width="' + cellW + '" height="' + cellH + '" fill="' + fill + '" stroke="#fff" stroke-width="1"/>'); if (val !== undefined) { var tc = ((val - vMn) / vR) > 0.5 ? '#fff' : '#111'; p.push('<text x="' + (rx + cellW / 2) + '" y="' + (ry + cellH / 2 + 4) + '" text-anchor="middle" font-size="11" fill="' + tc + '">' + __chart_formatNum(val) + '</text>'); } } } for (var xi = 0; xi < xCats.length; xi++) { var lx = margin.left + xi * cellW + cellW / 2; var ly = margin.top + plotH + 16; p.push('<text x="' + lx + '" y="' + ly + '" text-anchor="middle" font-size="11" fill="#666">' + __chart_esc(xCats[xi]) + '</text>'); } for (var yi = 0; yi < yCats.length; yi++) { var lx = margin.left - 8; var ly = margin.top + yi * cellH + cellH / 2 + 4; p.push('<text x="' + lx + '" y="' + ly + '" text-anchor="end" font-size="11" fill="#666">' + __chart_esc(yCats[yi]) + '</text>'); } p.push('</svg>'); return p.join('\\n'); }`,
1325
1619
  };
1326
1620
 
1327
1621
  // All known builtin names for matching
@@ -1341,10 +1635,12 @@ export const STDLIB_DEPS = {
1341
1635
  // These are provided by RESULT_OPTION, not the builtin map, so no dep here
1342
1636
  // Namespace modules that use builtins internally
1343
1637
  json: ['Ok', 'Err'],
1638
+ crypto: ['Ok', 'Err'],
1344
1639
  re: ['Ok', 'Err'],
1345
1640
  dt: ['Ok', 'Err'],
1346
1641
  fs: ['Ok', 'Err'],
1347
1642
  url: ['Ok', 'Err'],
1643
+ http: ['Ok', 'Err'],
1348
1644
  parse_url: ['Ok', 'Err'],
1349
1645
  regex_test: ['__regex_cache'],
1350
1646
  regex_match: ['Ok', 'Err', '__regex_cache'],
@@ -1363,6 +1659,8 @@ export const STDLIB_DEPS = {
1363
1659
  LazyTable: ['Table', 'table_where', 'table_group_by'],
1364
1660
  // Seq uses Some/None
1365
1661
  Seq: ['Some', 'None'],
1662
+ // Channel uses Some/None
1663
+ Channel: ['Some', 'None'],
1366
1664
  // compare family
1367
1665
  compare: ['Less', 'Equal', 'Greater'],
1368
1666
  compare_by: ['Less', 'Equal', 'Greater'],
@@ -1376,6 +1674,31 @@ export const STDLIB_DEPS = {
1376
1674
  cyan: ['color'],
1377
1675
  magenta: ['color'],
1378
1676
  gray: ['color'],
1677
+ // LRU cache namespace
1678
+ LRUCache: ['Some', 'None'],
1679
+ cache: ['LRUCache', 'Some', 'None'],
1680
+ // Window functions require Table
1681
+ table_window: ['Table'],
1682
+ // Sampling functions
1683
+ table_sample: ['Table', '__xorshift128'],
1684
+ table_stratified_sample: ['Table', 'table_sample', '__xorshift128'],
1685
+ // SQLite connector
1686
+ sqlite: ['Table'],
1687
+ // Parquet read/write
1688
+ readParquet: ['Table'],
1689
+ writeParquet: ['Table'],
1690
+ readExcel: ['Table', '__excelCellValue'],
1691
+ writeExcel: ['Table'],
1692
+ read: ['Table', '__parseCSV', '__parseJSONL', 'readParquet', 'readExcel', '__excelCellValue'],
1693
+ write: ['Table', 'writeParquet', 'writeExcel'],
1694
+ // SVG Charting
1695
+ __chart_helpers: ['Table'],
1696
+ bar_chart: ['Table', '__chart_helpers'],
1697
+ line_chart: ['Table', '__chart_helpers'],
1698
+ scatter_chart: ['Table', '__chart_helpers'],
1699
+ histogram: ['Table', '__chart_helpers'],
1700
+ pie_chart: ['Table', '__chart_helpers'],
1701
+ heatmap: ['Table', '__chart_helpers'],
1379
1702
  };
1380
1703
 
1381
1704
  // Resolve all transitive dependencies for a set of used names