119 Commits

Author SHA1 Message Date
Adrià Arrufat
68c1429fdd build: move snapshot_creator and legacy_test to an extras step
Profiling `zig build --release=fast` after a one-file edit showed the
cost was three parallel exe compiles of the same module — each re-runs
LLVM codegen when anything in `lightpanda_module` changes. All C/C++
deps (v8, sqlite, curl, brotli, nghttp2, boringssl) already cache across
builds and are not the bottleneck.

Default install now builds only the main `lightpanda` exe.
`lightpanda-snapshot-creator` and `legacy_test` move to a new named step
and can be built explicitly via `zig build extras`. CI is unaffected:
nightly.yml already invokes `snapshot_creator` as an explicit step, and
no job consumes the legacy_test artifact.

Measured (release=fast, one source file modified, 36/36 steps):
  before: real 3m32s, compile exe lightpanda ~3m, others ~2m each
  after:  real 2m43s, only compile exe lightpanda

Also tried and rejected:
  - self-hosted Zig backend for Debug: fatal linker error, unhandled
    relocation type R_X86_64_PC64 in V8 objects.
  - mold via `mold -run`: ~4s delta, within noise — Zig invokes LLD
    as a library, so no external `ld` process exists to intercept.
2026-04-22 11:16:28 +02:00
Adrià Arrufat
ca1f2c0854 build: port sqlite3 to zig build system 2026-04-22 07:52:10 +02:00
Karl Seguin
6d0003ad2b Sqlite
This adds an app.storage which is a union around configurable storage engine
(currently, only sqlite).

It is _not_ being used anywhere right now. The goal is to get feedback on
the implementation and then move cache to it.

This doesn't expose a generic query API. The goal is that the storage will
expose high level methods, e.g. `cacheGet(req: CacheGetRequest)` and every
storage engine will translate the `storage.CacheGetRequest` as needed.

A thin wrapper around the Sqlite C api is included, e.g. exec(SQL, .{args}) a
`rows` and `row` fetcher. A connection pool is included. By default, an
in-memory DB is currently created. And a `migrations` table with an id of `1`
is created/inserted. I don't imagine needing fancy migratations.
2026-04-20 17:13:06 +08:00
Karl Seguin
b08ae07598 build with sqlite3, just to see how it behaves in the CI 2026-04-20 15:43:49 +08:00
Karl Seguin
23e98a4ce0 Add WPT extensions
Some WPT tests need to interact with the browser in a way that isn't possible
with web apis. Browsers need to expose a way for tests to do this and then use
the testdriver-vendor.js to hook into these special WPT actions.

This commit sets up the infrastructure for supporting this and includes
the delete_all_cookies functionality needed by various cookie tests (e.g.
/cookies/attributes/attributes-ctl.sub.html).

A new compilation flag, `-Dwpt_extensions`, can be specified. When specified
a `window.webdriver` accessor is defined and a `WebDriver` type is exposed.

Note that, while I only implemented delete_all_cookies for now, I've seen other
tests fail because of missing vendor-specific implementation.
2026-04-17 15:59:06 +08:00
Adrià Arrufat
d6cdafc480 build: track html5ever Rust sources as cargo step inputs 2026-04-10 16:42:42 +02:00
Karl Seguin
5733c35a2d WebSocket WebAPI
Uses libcurl's websocket capabilities to add support for WebSocket.

Depends on https://github.com/lightpanda-io/zig-v8-fork/pull/167
Issue: https://github.com/lightpanda-io/browser/issues/1952

This is a WIP because it currently uses the same connection pool used for all
HTTP requests. It would be pretty easy for a page to starve the pool and block
any progress.

We previously stored the *Transfer inside of the easy's private data. We now
store the *Connection, and a Connection now has a `transport` field which is
a union for `http: *Transfer` or `websocket: *Websocket`.
2026-04-04 06:59:28 +08:00
Karl Seguin
38fa9602fa Merge pull request #2067 from lightpanda-io/percent-encode-version
percent encode version query string for crash report
2026-04-02 07:50:31 +08:00
Pierre Tachoire
9661204c8d percent encode version query string for crash report 2026-04-01 22:15:56 +02:00
Karl Seguin
6800e53b0e Merge pull request #2014 from lightpanda-io/build-check
build: add check step to verify compilation
2026-04-01 21:05:04 +08:00
Adrià Arrufat
3aeba97fc9 build: add check step to verify compilation 2026-03-27 14:25:17 +09:00
Adrià Arrufat
7f2139f612 build: simplify nightly versioning 2026-03-27 10:47:43 +09:00
Pierre Tachoire
28cc60adb0 add a -Dpre_version build flag for custom pre version 2026-03-26 11:52:16 +01:00
Adrià Arrufat
7b104789aa build: simplify dev version resolution 2026-03-21 21:13:50 +09:00
Adrià Arrufat
2dbd32d120 build: automate version resolution in build.zig
Removes manual git flags from CI and build scripts.
Versioning is now automatically derived from git and build.zig.zon.

With this PR, we follow https://semver.org/
Logic:

1. Read the version from build.zig.zon
2. If it doesn't have a `.pre` field (i.e. dev/alpha/beta) it will use that
3. Otherwise it will get the info from git: hash and number of commits since last `.0` version
4. Then build the version: `0.3.0-dev.1493+0896edc3`

Note that, since the latest stable version is `0.2.6`.
The convention is to use `0.3.0-dev`, as:
- `0.2.6` < `0.3.0.dev` < `0.3.0`
2026-03-19 13:03:29 +09:00
Nikolay Govorov
b252aa71d0 Use git_version option for version command 2026-03-17 13:25:15 +00:00
JasonOA888
96e5054ffc feat: add git_version build option for release version detection
- Add git_version option to build.zig (similar to git_commit)
- Update version command to output git_version when available
- Falls back to git_commit when not on a tagged release
- CI can pass -Dgit_version=$(git describe --tags --exact-match) for releases

Fixes #1867
2026-03-17 07:41:11 +08:00
Pierre Tachoire
dd91d28bfa Merge pull request #1761 from lightpanda-io/wp/mrdimidium/c-tsan
Enable tsan for c libs
2026-03-10 15:33:33 +01:00
Nikolay Govorov
7171305972 Enable tsan for c libs 2026-03-10 03:16:50 +00:00
Adrià Arrufat
5568340b9a build: add code formatting check 2026-03-09 18:48:38 +09:00
Pierre Tachoire
24b6934d3b remove WPT specific code
Using both lightpanda-io/wpt and lightpanda-io/demo/wptrunner remove the
need for code specific to run WPT from browser.
2026-02-27 10:09:07 +01:00
Nikolay Govorov
ac5a64d77a Fix typo in build.zig
Co-authored-by: Halil Durak <halildrk@gmail.com>
2026-02-26 08:41:01 +00:00
Nikolay Govorov
32cd3981d8 Update libcurl version, use build based on config file 2026-02-25 05:05:00 +00:00
Nikolay Govorov
ca5af87196 Build C libs in isolated modules 2026-02-25 05:04:58 +00:00
Nikolay Govorov
a8164f612f Use zig package manager instead of submodules 2026-02-25 05:04:57 +00:00
Nikolay Govorov
eb8cac5980 Use asan/tsan for building v8 2026-02-03 16:01:18 +00:00
Karl Seguin
0f9c9e2089 Improve crash handling
This adds a crash handler which reports a crash (if telemetry is enabled). On a
crash, this looks for `curl` (using the PATH env), and forks the process to then
call execve. This relies on a new endpoint to be setup to accept the "report".
Also, we include very little data..I figured just knowing about crashes would
be a good place to start.

A panic handler is provided, which override's Zig default handler and hooks
into the crash handler.

An `assert` function is added and hooks into the crash handler. This is
currently only used in one place (Session.zig) to demonstrate its use. In
addition to reporting a failed assert, the assert aborts execution in
ReleaseFast (as opposed to an undefined behavior with std.debug.assert).

I want to hook this into the v8 global error handler, but only after direct_v8
is merged.

Much of this is inspired by bun's code. They have their own assert (1) and
a [more sophisticated] crashHandler (2).
:

(1) beccd01647/src/bun.zig (L2987)
(2) beccd01647/src/crash_handler.zig (L198)
2026-01-19 07:36:46 +08:00
Karl Seguin
2322cb9b83 remove unused code, remove references to v8::Persistent 2026-01-13 12:58:30 +08:00
Karl Seguin
087086c308 remove some unused imports 2025-12-26 12:40:20 +08:00
Muki Kiboigo
c9f6cb7520 fix single build with rust in ci 2025-12-22 10:41:22 -08:00
Muki Kiboigo
596ee82a52 zig build builds everything 2025-12-22 09:57:34 -08:00
Karl Seguin
b3a0aaaeea Enable v8 snapshots
There are two layers here. The first is that, on startup, a v8 SnapshotCreator
is created, and a snapshot-specific isolate/context is setup with our browser
environment. This contains most of what was in Env.init and a good chunk of
what was in ExecutionWorld.createContext. From this, we create a v8.StartupData
which is used for the creation of all subsequent contexts. The snapshot sits
at the application level, above the Env - it's re-used for all envs/isolates, so
this gives a nice performance boost for both 1 connection opening multiple pages
or multiple connections opening 1 page.

The second layer is that the Snapshot data can be embedded into the binary, so
that it doesn't have to be created on startup, but rather created at build-time.
This improves the startup time (though, I'm not really sure how to measure that
accurately...).

The first layer is the big win (and just works as-is without any build / usage
changes).

with snapshot
total runs 1000
total duration (ms) 7527
avg run duration (ms) 7
min run duration (ms) 5
max run duration (ms) 41

without snapshot
total runs 1000
total duration (ms) 9350
avg run duration (ms) 9
min run duration (ms) 8
max run duration (ms) 42

To embed a snapshot into the binary, we first need to create the snapshot file:

zig build -Doptimize=ReleaseFast snapshot_creator -- src/snapshot.bin

And then build using the new snapshot_path argument:

zig build -Dsnapshot_path=../../snapshot.bin -Doptimize=ReleaseFast

The paths are weird, I know...since it's embedded, it needs to be inside the
project path, hence we put it in src/snapshot.bin. And since it's embedded
relative to the embedder (src/browser/js/Snapshot.zig) the path has to be
relative to that, hence ../../snapshot.bin. I'm open to suggestions on
improving this.
2025-12-18 20:10:38 +08:00
Pierre Tachoire
22303d2ae8 Merge pull request #1236 from lightpanda-io/v8-build-with-zig-gclient-ci
V8 build with zig gclient ci
2025-12-18 11:55:55 +08:00
Muki Kiboigo
bd0f1d2884 remove mbedtls stuff for build.zig 2025-12-11 12:25:34 -08:00
Halil Durak
bead805680 backport: Prefer BoringSSL as TLS backend 2025-12-11 10:19:07 +03:00
Halil Durak
129b59a43f html5ever: prefer dev build only on Debug optimization 2025-12-01 11:17:59 +03:00
Halil Durak
444ae00129 mv vendor/html5ever src/html5ever 2025-11-26 14:27:28 +03:00
Halil Durak
6280232e91 add a build step for html5ever in build.zig 2025-11-26 14:20:39 +03:00
Muki Kiboigo
38ca58d71e use llvm on tests 2025-11-17 07:25:44 -08:00
Muki Kiboigo
c1c0edab9f fix curl dependency issue with zlib 2025-11-17 07:22:40 -08:00
Karl Seguin
7ab88e9a71 add legacy tests, optimize empty types 2025-11-14 15:55:02 +08:00
Karl Seguin
b047cb6dc1 remove libdom 2025-10-27 22:14:59 +08:00
Karl Seguin
cf378dfd6d add brotli include path 2025-10-06 12:39:30 +08:00
Karl Seguin
a3939d9a66 Supports brotli compression
Adds bortli as a submodules, and compiles the decoder, making it available to
libcurl.

Some websites appear to sent brotli encoded responses even though we don't
advertise support for it (e.g. https://movie.douban.com).
2025-10-06 12:30:06 +08:00
Karl Seguin
c7c5af4708 zig fmt 2025-08-29 10:51:19 +08:00
Karl Seguin
0b6a9d3a0b use llvm. The new x86 backend crashes with v8. 2025-08-29 10:42:07 +08:00
Karl Seguin
23d6362058 fix telemetry, link libc and libcpp 2025-08-29 10:42:06 +08:00
Karl Seguin
1443f38e5f Zig 0.15.1
Depends on https://github.com/lightpanda-io/zig-v8-fork/pull/89
2025-08-29 10:42:06 +08:00
Karl Seguin
0959eea677 Remove the loop
Previously, the IO loop was doing three things:
1 - Managing timeouts (either from scripts or for our own needs)
2 - Handling browser IO events (page/script/xhr)
3 - Handling CDP events (accept, read, write, timeout)

With the libcurl merge, 1 was moved to an in-process scheduler and 2 was moved
to libcurl's own event loop. That means the entire loop code, including
the dependency on tigerbeetle-io existed for handling a single TCP client.
Not only is that a lot of code, there was also friction between the two loops
(the libcurl one and our IO loop), which would result in latency - while one
loop is waiting for the events, any events on the other loop go un-processed.

This PR removes our IO loop. To accomplish this:

1 - The main accept loop is blocking. This is simpler and works perfectly well,
given we only allow 1 active connection.
2 - The client socket is passed to libcurl - yes, libcurl's loop can take
arbitrary FDs and poll them along with its own.

In addition to having one less dependency, the CDP code is quite a bit simpler,
especially around shutdowns and writes. This also removes _some_ of the latency
caused by the friction between page process and CDP processing. Specifically,
when CDP now blocks for input, http page events (script loading, xhr, ...) will
still be processed.

There's still friction. For one, the reverse isn't true: when the page is
waiting for events, CDP events aren't going to be processed. But the page.wait
already have some sensitivity to this (e.g. the page.request_intercepted flag).
Also, when CDP waits, while we will process network events, page timeouts are
still not processed. Because of both these remaining issues, we still need to
jump between the two loops - but being able to block on CDP (even for a short
time) WITHOUT stopping the page's network I/O, should reduce some latency.
2025-08-25 17:27:28 +08:00
Karl Seguin
65088b8644 swap unnecessary addModule with createModule 2025-08-21 09:59:42 +08:00