Backplane projector fix + multinode chat & Signal showcase + docs#95
Merged
Conversation
The projector treated any offset gap (rec.Offset > cursor+1) as a compacted prefix and halted when no bridging snapshot existed. Backends that sequence a key's offsets from a shared space (e.g. one NATS JetStream stream across subjects) produce gaps that are not data loss, so the first record of any key halted the projector and silently dropped every event (the multi-log clustered case the chatcluster/viashowcase apps exposed). classifyGap now distinguishes a real compaction gap (a Compacted snapshot proves a lost prefix -> reseed or halt) from a benign non-contiguous gap (no snapshot, or an uncompacted/unreadable one -> fold), latching gapsBenign so a busy shared stream does not pay a snapshot read per record. Compaction safety is preserved: only a Compacted-but-unbridgeable snapshot halts. Documents the monotone-not-contiguous Offset contract (backplane.go) and a production note.
New Learn page for the state backplane (clustered StateApp/StateSess + StateAppEvents) and a Showcase page for the Signal app, with cross-links from home, why-via, and reactive-state.
Runs the single-node chat as multiple nodes behind a sticky-cookie HAProxy LB with JetStream NATS, demonstrating cross-node StateAppEvents convergence. Adds a docker-compose stack, a tag-gated compose e2e, and gitignore rules for the nested example/showcase build outputs.
Dependency ReviewThe following issues were found:
Vulnerabilitiesviashowcase/go.mod
Only included vulnerabilities with severity high or higher. License Issuesinternal/examples/chatcluster/go.mod
viashowcase/go.mod
OpenSSF ScorecardScorecard details
Scanned Files
|
A live audience platform (polls / word cloud / Q&A) exercising every Via plugin (picocss, echarts, maplibre), the JetStream backplane (StateAppEvents + OnEvent), Postgres-backed auth/profiles/avatars, cross-page theme persistence, graceful shutdown, /healthz, and a 3-pod docker-compose deployment behind a sticky HAProxy LB. Its own module (replace -> ../, ../vianats).
joaomdsg
force-pushed
the
feat/showcase-and-backplane-fix
branch
from
June 5, 2026 20:39
13b40fe to
e73c7c8
Compare
The broadcast script concatenated json.Marshal(title) between two raw JS string fragments (b.textContent=…;b.style.cssText='…'), the exact shape CodeQL's 'potentially unsafe quoting' rule flags — a crafted room title can break out of the string and inject JS into every connected tab. Reshape the snippet to match the established convention in push.go (Toast) and plugins/maplibre/popups.go (ShowPopup): the title is the sole argument of a function-call IIFE, JSON-parsed at the call site, and consumed via b.textContent=msg (the XSS-safe DOM sink). One isolated data segment, never dropped between two raw JS string pieces, so the rule has nothing to flag. Extract the builder as buildNoticeScript and assert its safety directly in notice_internal_test.go — internal package test, justified in the file header as a last-resort claim on a security-critical pure function whose public-API equivalent needs DB + auth + echarts + maplibre wired up.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Work from this session, in four logical commits.
1.
fix(applog)— projector tolerates non-contiguous per-key offsetsThe event-log projector treated any offset gap (
rec.Offset > cursor+1) as acompacted prefix and halted when no bridging snapshot existed. Backends that
sequence a key's offsets from a shared space — e.g. a single NATS JetStream
stream across subjects — produce gaps that are not data loss, so the first
record of any key halted the projector and silently dropped every event. This is
the multi-log clustered case the new example/showcase apps exposed;
chatcluster(single log) never hit it.
classifyGapnow separates a real compaction gap (aCompactedsnapshot provesa lost prefix → reseed or halt) from a benign non-contiguous gap (no snapshot, or
an uncompacted/unreadable one → fold), latching
gapsBenignso a busy sharedstream doesn't pay a snapshot read per record. Compaction safety preserved:
only a
Compacted-but-unbridgeable snapshot halts. Newapplognoncontiguoustests (incl. a
LoadSnapshot-counting latch test); two existing reseed teststightened to
Compacted: true. TheOffsetcontract (monotone, notcontiguous) is now documented in
backplane.go+docs/production.md.2.
docs— backplane + showcase pagesNew Distributed state Learn page and Showcase: Signal page, with
cross-links from home / why-via / reactive-state.
3.
example(chatcluster)— multinode chat over the backplaneThe single-node chat run as multiple nodes behind a sticky-cookie HAProxy LB with
JetStream NATS, demonstrating cross-node
StateAppEventsconvergence. Includes adocker-compose stack and a tag-gated compose e2e. (Own module.)
4.
feat(viashowcase)— "Signal" flagship appA live audience platform (polls / word cloud / Q&A) exercising every plugin
(picocss, echarts, maplibre), the JetStream backplane (
StateAppEvents+OnEvent), Postgres-backed auth/profiles/avatars, cross-page theme persistence,graceful shutdown,
/healthz, and a 3-pod docker-compose deployment behind asticky LB. Own module (
replace→../,../vianats). Includes a stored-XSSfix in the broadcast path, crypto-random room codes, and a11y/empty-state/toast
polish.
Verification
ci-check.shpasses locally: gofmt,go vet, golangci-lint, govulncheck, build,example builds,
go test -race ./..., allocation gates. The chatcluster andviashowcase compose e2es were run live (3-pod stacks, cross-pod convergence
confirmed). The new modules are separate (
go.mod), so the root module's CI isunaffected by their deps.