DEV Community

Rémy F.
Rémy F.

Posted on

QuickJS: Handle Typescript Sourcemap

I'm currently using Bellard's QuickJS engine on a new TypeScript project.

Since QuickJS only support JS, we need to transpile our TS first (qjs --std typescript.js path/to/your/project)

We can debug quickjs execution but stacktraces are relativ to JS so we need to parse our sourcemap files to get the TS line back. Those sourcemap use VLQ encoding, so let's make a VLQ parser:

const VLQ_BASE = 5;
const VLQ_CONT = 1 << VLQ_BASE;  // 100000
const VLQ_MASK = VLQ_CONT - 1;   // 011111
const b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
function vlq(segment) {
    const fields = [];
    for (let segIdx = 0; segIdx < segment.length;) {
        let result = 0;
        for (let shift = 0; ; shift += VLQ_BASE) {
            const digit = b64.indexOf(segment.charAt(segIdx++));
            result += ((digit & VLQ_MASK) << shift);
            if (!(digit & VLQ_CONT)) break;
        };
        fields.push(result & 1 ? -(result >> 1) : result >> 1)
    }
    return fields; // col,srcIdx,lineSrc,colSrc,nameIdx
};

Enter fullscreen mode Exit fullscreen mode

this allows us to lookup the original TS line of a given JsLine using a myMap file

// JsLine = 42
// myMap = await fetch("my.map").then(r=>r.json())
const fields = myMap.mappings.split(';').map(g=>g.split(',').map(vlq));
let sum = 0;
const tsLine = fields.map(f => sum += f[0][2])[JsLine];
Enter fullscreen mode Exit fullscreen mode

enjoy !

Top comments (0)

typescript

11 Tips That Make You a Better Typescript Programmer

1 Think in {Set}

Type is an everyday concept to programmers, but it’s surprisingly difficult to define it succinctly. I find it helpful to use Set as a conceptual model instead.

#2 Understand declared type and narrowed type

One extremely powerful typescript feature is automatic type narrowing based on control flow. This means a variable has two types associated with it at any specific point of code location: a declaration type and a narrowed type.

#3 Use discriminated union instead of optional fields

...

Read the whole post now!