1 | import { parenth } from '@texting/bracket';
|
2 | import { SP } from '@spare/enum-chars';
|
3 | import { lange } from '@texting/lange';
|
4 | import { Blue, LightBlue, Lime, Grey, Brown, BlueGrey, Purple, DeepPurple } from '@palett/cards';
|
5 | import { DyeFab } from '@palett/dye';
|
6 | import { makeReplaceable } from '@spare/translator';
|
7 |
|
8 | const DECOFUN_CONFIG = {
|
9 | pr: true,
|
10 | fw: 160,
|
11 | aw: 192
|
12 | };
|
13 | const DECOFUNC_CONFIG = {
|
14 | pretty: true,
|
15 | flatMark: 160,
|
16 | abbrMark: 192
|
17 | };
|
18 |
|
19 | var _ref;
|
20 | const hexDye = DyeFab.hex();
|
21 | const nameDye = hexDye.make(Blue.lighten_2);
|
22 | const argsDye = hexDye.make(LightBlue.accent_2);
|
23 | const bodyDye = hexDye.make(LightBlue.lighten_3);
|
24 | const arrowDye = hexDye.make(Lime.lighten_1);
|
25 | const 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 |
|
27 | const funcName = func => `[fn:(${(func === null || func === void 0 ? void 0 : func.name) ?? '<anonym>'})]`;
|
28 |
|
29 | const FUNCTION_BODY = /function\s*(\w*)\s*\(([\w\s,]+)\)\s*\{\s*return(.+);?\s*\}/gs;
|
30 | const THIS_REG = /\bthis\b/;
|
31 | const FUNCTION_INITIAL = /^function/;
|
32 | const LINEFEEDS = /\n\s*(\n\s*)/g;
|
33 |
|
34 | const funcToLined = func => {
|
35 | return func.toString().replace(LINEFEEDS, (_, p1) => p1);
|
36 | };
|
37 |
|
38 | const 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 |
|
44 | const 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 |
|
49 | const abbrev = (text, abbrMark, func) => {
|
50 | if (lange(text) > abbrMark) return funcName(func);
|
51 | return text;
|
52 | };
|
53 |
|
54 | const prettify = (text, pretty) => {
|
55 | if (pretty) return text.replace(PresetDye);
|
56 | return text;
|
57 | };
|
58 |
|
59 | const _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 |
|
73 | const FUNC_REG = /\((.*?)\)\s+{/s;
|
74 | const LAMB_REG = /\(?(.*?)\)?\s+=>/s;
|
75 | const 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 |
|
83 | const 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 |
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 |
|
98 |
|
99 | const decoFunc = (func, p = DECOFUNC_CONFIG) => _decoFunc.call(parseConfig(p), func);
|
100 |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 |
|
108 | const DecoFunc = (p = DECOFUNC_CONFIG) => _decoFunc.bind(parseConfig(p));
|
109 |
|
110 | export { DECOFUN_CONFIG, DecoFunc, _decoFunc, argnames, decoFunc, funcName };
|