Skip to content

Debug Console [intermediate] #6

@PaperPrototype

Description

@PaperPrototype

Using LunaConsole from liriliri you can recreate chrome devtools console (here is the official demo from liriliri)

Image

Since the playground runs all your scripts in a web worker you can't easily override the default console.log method. Instead you will have to create a custom postMessage({}) and make sure to properly serialize all the messages (eg. you can't serialize a function or class through postMessage):

// re-creating console.log methods inside your code
const console = {
    log(...args) {
        postMessage({ type: "console:log", payload: serializeConsoleArgs(args) })
    }
}

// custom serializer
function serializeConsoleArgs(args: any[]): Array<{ type: string; content: any }> {
  return args.map((arg) => {
    switch (kind(arg)) {
      case 'window':
      case 'function':
      case 'date':
      case 'symbol':
        return { type: kind(arg), content: arg.toString() };
      case 'document':
        return { type: kind(arg), content: arg.documentElement.outerHTML };
      case 'element':
        return { type: kind(arg), content: arg.outerHTML };
      case 'node':
        return { type: kind(arg), content: arg.textContent };
      case 'nodelist':
      case 'htmlcollection':
        return {
          type: kind(arg),
          content: [...arg].map((x: unknown) => consoleArgs([x])[0].content),
        };
      case 'array':
        return { type: kind(arg), content: arg.map((x: unknown) => consoleArgs([x])[0].content) };
      case 'object':
      case 'event':
        const obj: Record<string, any> = {};
        // eslint-disable-next-line guard-for-in
        for (const k in arg) {
          obj[k] = arg[k];
        }
        return {
          type: kind(arg),
          content: Object.keys(obj).reduce(
            (acc, key) => ({ ...acc, [key]: consoleArgs([obj[key]])[0].content }),
            {},
          ),
        };
    //   case 'error':
    //     return {
    //       type: typeOf(arg),
    //       content: arg.constructor.name + ': ' + arg.message,
    //     };
    }
    return { type: 'other', content: arg };
    // try {
    //   return { type: 'other', content: structuredClone(arg) };
    // } catch {
    //   return { type: 'other', content: String(arg) };
    // }
  });
}

You can find the full implementation in src/lib/components/LunaConsole/test-worker.ts and a demo of it working in the Playground as well as in src/routes/luna

Metadata

Metadata

Projects

Status

No status

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions