Merge remote-tracking branch 'origin/master' into fix-webplugins-watch-flake
# Conflicts: # packages/host/webserver/src/web-plugins.ts # packages/host/webserver/tests/web-plugins.spec.ts
This commit is contained in:
@@ -76,7 +76,7 @@ Why is the roster a hand-written list and not a scan? Because which plugins comp
|
||||
|
||||
Whether hot reload is active is a composition decision: dev graphs include the `client-hmr` row (a normal plugin package) and turn on bundle watching; prod graphs do neither.
|
||||
|
||||
How does a rebuilt bundle become a reload signal? The webserver observes it itself — no builder tells it. The registry scan already holds every plugin's bundle path (`clientPath`), so in dev mode one registry-owned interval stat-polls every scanned bundle file against the stat baseline its own scan captured (synchronously, immediately before hashing that content — not `fs.watchFile`, whose asynchronous first-stat baseline silently absorbs a write landing during registry construction). Polling is by design: inotify does not fire on the weka network mount, the same reason the build-side watcher needs `--poll`. On a mtime/size change the registry re-hashes that row (`rebuilt(id)`); when the `rev` actually changed, it broadcasts a `rebuilt` frame on `GET /plugins/events` — a system SSE channel that sends the full graph on connect and `rebuilt` frames on change, presentation-only wire that never enters the session log. The poll iterates the live table, so rescans retarget the watch for free (fresh rows carry fresh baselines) and dispose clears the one timer. The poll interval is a validated config field (default 500ms), not a constant. Rebuilding the bundles is any tsdown watch process's business — `scripts/dev-web.ts` remains as the watch-build entry point, its package list dshClient-discovered by scanning `packages/*/*/package.json` at startup — and builder and host share zero protocol. A torn read of a half-written bundle self-heals: the stats keep changing while the write completes, so the next poll tick re-hashes again and broadcasts the final rev.
|
||||
How does a rebuilt bundle become a reload signal? The webserver observes it itself — no builder tells it. The registry scan already holds every plugin's bundle path (`clientPath`), so in dev mode one registry-owned interval stat-polls every scanned bundle file against an explicit baseline the registry captures synchronously before construction returns (not `fs.watchFile`, whose asynchronous first-stat baseline silently absorbs a rebuild landing during registry construction — a CI-reproduced miss). Polling is by design: inotify does not fire on the weka network mount, the same reason the build-side watcher needs `--poll`. On a mtime/size change the registry re-hashes that row (`rebuilt(id)`); when the `rev` actually changed, it broadcasts a `rebuilt` frame on `GET /plugins/events` — a system SSE channel that sends the full graph on connect and `rebuilt` frames on change, presentation-only wire that never enters the session log. Rescans stage table, graph, and watch baselines atomically (a failed rescan keeps all three previous values), and a bundle missing at poll time marks its watch dirty so the reappearing file re-hashes even with identical metadata; dispose clears the one timer. The poll interval is a validated config field (default 500ms), not a constant. Rebuilding the bundles is any tsdown watch process's business — `scripts/dev-web.ts` remains as the watch-build entry point, its package list dshClient-discovered by scanning `packages/*/*/package.json` at startup — and builder and host share zero protocol. A torn read of a half-written bundle self-heals: the stats keep changing while the write completes, so the next poll tick re-hashes again and broadcasts the final rev.
|
||||
|
||||
On the browser side, the driver reloads one plugin per frame, serialized:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user