UNPKG

3.59 kBJavaScriptView Raw
1import { parenth } from '@texting/bracket';
2import { SP } from '@spare/enum-chars';
3import { lange } from '@texting/lange';
4import { Blue, LightBlue, Lime, Grey, Brown, BlueGrey, Purple, DeepPurple } from '@palett/cards';
5import { DyeFab } from '@palett/dye';
6import { makeReplaceable } from '@spare/translator';
7
8const DECOFUN_CONFIG = {
9 pr: true,
10 fw: 160,
11 aw: 192
12};
13const DECOFUNC_CONFIG = {
14 pretty: true,
15 flatMark: 160,
16 abbrMark: 192
17};
18
19var _ref;
20const hexDye = DyeFab.hex();
21const nameDye = hexDye.make(Blue.lighten_2);
22const argsDye = hexDye.make(LightBlue.accent_2);
23const bodyDye = hexDye.make(LightBlue.lighten_3);
24const arrowDye = hexDye.make(Lime.lighten_1);
25const PresetDye = (_ref = [[/function/gi, hexDye.render(Grey.base, 'function')], [/return/gi, hexDye.render(Brown.lighten_3, 'return')], [/\bthis\b/gi, hexDye.make(BlueGrey.accent_2)], [/\b(if|else|while|do|switch|for)\b/gi, hexDye.make(Purple.lighten_3)], [/\b(var|let|const)\b/gi, hexDye.make(DeepPurple.lighten_3)]], makeReplaceable(_ref));
26
27const funcName = func => `[fn:(${(func === null || func === void 0 ? void 0 : func.name) ?? '<anonym>'})]`;
28
29const FUNCTION_BODY = /function\s*(\w*)\s*\(([\w\s,]+)\)\s*\{\s*return(.+);?\s*\}/gs;
30const THIS_REG = /\bthis\b/;
31const FUNCTION_INITIAL = /^function/;
32const LINEFEEDS = /\n\s*(\n\s*)/g;
33
34const funcToLined = func => {
35 return func.toString().replace(LINEFEEDS, (_, p1) => p1);
36};
37
38const flatten = (text, flatMark) => {
39 const temp = text.replace(/\s+/g, ' ');
40 if (temp.length <= flatMark) text = temp.replace(/;\s*}/g, ' }');
41 return text;
42};
43
44const lambdafy = (text, pretty, defaultName = 'anonym') => {
45 if (!THIS_REG.test(text)) text = pretty ? text.replace(FUNCTION_BODY, (_, name, args, body) => nameDye(name === 'anonymous' ? defaultName : name) + SP + parenth(argsDye(args.trim())) + SP + arrowDye('=>') + bodyDye(body)) : text.replace(FUNCTION_BODY, (_, name, args, body) => name + SP + parenth(args) + SP + '=>' + body);
46 return text.replace(FUNCTION_INITIAL, '').trim();
47};
48
49const abbrev = (text, abbrMark, func) => {
50 if (lange(text) > abbrMark) return funcName(func);
51 return text;
52};
53
54const prettify = (text, pretty) => {
55 if (pretty) return text.replace(PresetDye);
56 return text;
57};
58
59const _decoFunc = function (func) {
60 let text;
61 const {
62 pr,
63 fw,
64 aw
65 } = this;
66 text = funcToLined(func);
67 text = flatten(text, fw);
68 text = lambdafy(text, pr, func === null || func === void 0 ? void 0 : func.name);
69 text = abbrev(text, aw, func);
70 return prettify(text, pr);
71};
72
73const FUNC_REG = /\((.*?)\)\s+{/s;
74const LAMB_REG = /\(?(.*?)\)?\s+=>/s;
75const argnames = fn => {
76 const text = fn.toString();
77 let ms, ph;
78 if ((ms = FUNC_REG.exec(text)) && ([, ph] = ms)) return ph.match(/\w+/g);
79 if ((ms = LAMB_REG.exec(text)) && ([, ph] = ms)) return ph.match(/\w+/g);
80 return [];
81};
82
83const parseConfig = p => {
84 p.pr = p.pretty ?? p.pr ?? true;
85 p.fw = p.flatMark ?? p.fw ?? 160;
86 p.aw = p.abbrMark ?? p.aw ?? 192;
87 return p;
88};
89/**
90 * @param {Function} func
91 * @param {Object} p
92 * @param {boolean} [p.pretty=true]
93 * @param {number} [p.flatMark=160]
94 * @param {number} [p.abbrMark=192]
95 * @returns {string}
96 */
97
98
99const decoFunc = (func, p = DECOFUNC_CONFIG) => _decoFunc.call(parseConfig(p), func);
100/**
101 * @param {Object} p
102 * @param {boolean} [p.pretty=true]
103 * @param {number} [p.flatMark=160]
104 * @param {number} [p.abbrMark=192]
105 * @returns {Function}
106 */
107
108const DecoFunc = (p = DECOFUNC_CONFIG) => _decoFunc.bind(parseConfig(p));
109
110export { DECOFUN_CONFIG, DecoFunc, _decoFunc, argnames, decoFunc, funcName };