liriliri / luna

UI library
https://luna.liriliri.io
MIT License
250 stars 22 forks source link

`console` – display `Set`, `Map`, etc. like browsers do #14

Open CetinSert opened 1 year ago

CetinSert commented 1 year ago

Currently LunaConsole just shows Set {}.

vs the native consoles

Chrome: image

CetinSert commented 1 year ago

Initial approach:

                               eruda.constructorWithSize = (o, e, i = 0) => new Proxy((Object.defineProperties(e, { size: { value: o.size } }), e), { get: (t, p, r) => p === 'length' ? (i++ === 0 ? o.size : undefined) : p === 'constructor' ? { name: `${o?.constructor?.name}(${o?.size ?? 0})` } : t[p] });
             eruda[Set] = o => eruda.constructorWithSize   (o,                    [...o]);
             eruda[Map] = o => eruda.constructorWithSize   (o, Object.fromEntries([...o]));
console.warn(eruda[Set](new Set([   'fulfilled', 3   ])));
console.warn(eruda[Map](new Map([ [ 'fulfilled', 3 ] ])));

image image

CetinSert commented 1 year ago

A more complete approach handling prototype chains:

const prototype = (P, { add = 'push' } = {}) => (t, ...T) => { if (t === null || t === undefined) return t; let o = t; const S = new Set(T);
  let x;
  let y;
  let z;
  while (t = Object.getPrototypeOf(t)) { if (0 && x !== undefined) console.warn(x); if (S.has(x ?? o)) break;
    if (y !== undefined) P?.[add]?.(y);
    x = y;
    y = z;
    z = t;
  }; return x ?? o;
}
prototype.top       =                               prototype(                     );
prototype.chain     = (t, ...T) => { const P = [t]; prototype(P                    )(t, ...T); return P; };
prototype.chain.z_a = (t, ...T) => { const P = [t]; prototype(P                    )(t, ...T); return P; };
prototype.chain.a_z = (t, ...T) => { const P = [t]; prototype(P, { add: 'unshift' })(t, ...T); return P; };

class Se1 extends Set { constructor(...A) { super(...A) } }
class Se2 extends Se1 { constructor(...A) { super(...A) } }

const                     lunaCast = new Map();  lunaCast.constructorWithSize = (o, e, i = 0) => new Proxy((Object.defineProperties(e, { size: { value: o.size } }), e), { get: (t, p, r) => p === 'length' ? (i++ === 0 ? o.size : undefined) : p === 'constructor' ? { name: `${o?.constructor?.name}(${o?.size ?? 0})` } : t[p] });
/**/                      lunaCast.set(Set, o => lunaCast.constructorWithSize   (o,                    [...o]));
/**/                      lunaCast.set(Map, o => lunaCast.constructorWithSize   (o, Object.fromEntries([...o])));
//           _______________________________________________________________   →   Set
console.warn(firstDefined(lunaCast, prototype.chain(Set))?.(new Set([   'fulfilled', 3   ])));
//           _______________________________________________________________   →   Set
console.warn(firstDefined(lunaCast, prototype.chain(Se2))?.(new Se2([   'fulfilled', 3   ])));
console.warn(firstDefined(lunaCast, prototype.chain(Map))?.(new Map([ [ 'fulfilled', 3 ] ])));

if (0) console.warn('_______________________'); //   Se2  Se1  Set
if (0) console.warn(prototype.top(Set));        //             Set
if (0) console.warn(prototype.top(Se1));        //             Set 
if (0) console.warn(prototype.top(Se2));        //             Set 
if (0) console.warn(prototype.top(Se2, Se1));   //        Se1
if (1) console.warn(prototype.chain(Set));      // [           Set ]
if (1) console.warn(prototype.chain(Se2, Se1)); // [ Se2, Se1      ]
if (1) console.warn(prototype.chain(Se2));      // [ Se2, Se1, Set ]
if (1) console.warn(prototype.chain.z_a(Se2));  // [ Se2, Se1, Set ]
if (1) console.warn(prototype.chain.a_z(Se2));  // [ Set, Se1, Se2 ]
if (1) console.warn('_______________________');

image


Known issues:

CetinSert commented 11 months ago

@surunzi – can you please review this issue and implement a fix?