Port GLQL to TypeScript
Associated MR: gitlab-org/gitlab-query-language/glql-rust!257
Why port to TypeScript: Advantages
- Simpler dev workflow - No WASM compilation step means faster iteration. Pipelines should be much faster once the Rust version is removed. Reduced bundle size from about 2.5MB to just a few hundred KB (not minified) after the Rust version is removed.
- Better performance - Rust is typically faster than JS, but due to it being wrapped in WASM, the raw JS version would be much faster (upto 10x faster) than the Rust version.
- Better browser debugging - Standard JS tools work without extra layers. Debugging compiled production WASM is impossible as all debug information is removed. With Typescript, it is still possible using source maps (though sourcemap support hasn't been added yet).
- Wider contributor pool - More devs know TypeScript than Rust. Platform analytics team is interesting in contributing, and they can easily contribute now that this is in TypeScript. Previously this was hard when this was in Rust. Also the contribution pool opens up to entire frontend team at GitLab.
- Seamless JS integration - No JS/WASM bridge needed for web APIs. Now we can move all the Vue components and execution layer to this project as well, so this project would not just be a GLQL parser, but everything GLQL related all in one.
- Better tooling/easier debugging - Previously, since we deployed the release (production) version of the compiler, if the compiler had an error (say null pointer exception or bad memory access), there was no way to debug that because stack traces are stripped off in the release version. It is also very hard to debug and add breakpoints to Rust code in your IDE. Additionally, the coverage reporting tool for Rust does not support coverage for any branches (if else/match statements), which makes it pretty useless.
- Consistent tech stack - Aligns with GitLab's primarily JS/TS frontend. This also is important for the new query builder project we've taken on. The query builder's data structure and GLQL's data structure are very similar, and follow a [field operator value] pattern. The rules on what operators are allowed for what fields are also the same, so it will be nicer if other frontend code can reuse this core foundation.
- Easier maintenance - One language ecosystem instead of two
- Good enough performance - Parsing/analysis doesn't need Rust's speed advantages. In fact in some profiling I did, the typescript version turned out to be faster, because there's no WASM boot time to consider and no JS/WASM bridge to cross.
Disadvantages (sort of)
- No backend integration - Previously we had a plan to move GLQL to the backend, but given recent discussions, it is better if the parser itself stays on the frontend, and if necessary, we can create new backend APIs (GraphQL/REST) that consume the output of GLQL compiler (as JSON). Even if we wanted to move the TypeScript version to the backend, it is technically possible using
bun.
Release plan
- Add the typescript port under feature flag
glql_typescript, and for about 1 milestone, enable it for testing for GitLab team members. People who have the feature flag disabled will get the Rust version. If no bugs are reported, we can remove the feature flag and the Rust version.
Edited by Himanshu Kapoor