Add the data spine: typed records, query engine, and Memory/gRPC proxies - #1
Merged
Conversation
The headless data layer of the go-widgets ecosystem. Pure Go, CGO=0; the core imports only the standard library and go-widgets/mvvm. Core (package data): - Value/Kind: a comparable typed scalar (string/int/float/bool). - Record/Schema/Field/Rule: a typed row and its validation (Required, StrMinLen/StrMaxLen, NumMin/NumMax), mirroring toolkit's validation shape lifted to typed values. - Query -> Apply -> View: a pure query engine — filter, sort (multi-key, asc/desc), group-by, paginate (rows or groups), and aggregate (count/sum/avg/min/max, grand + per-group). - Proxy seam (List/Query/Mutate) with MemoryProxy, the in-process reference backend. - Store[R]: a typed, bindable collection wired through mvvm.ObservableList, so a view re-renders when the data changes. - Canonical(View): a deterministic, map-order-independent encoding used to compare views byte for byte. Transport (package grpcproxy): - A small list/query/mutate .proto service (datapb, generated) carried over grpc-transports/websocket, so the client compiles to js/wasm and a browser speaks the same gRPC service. Server is native-only (//go:build !js); Client is a data.Proxy that builds everywhere. Proxy conformance (the key test): a battery of 15 sort->filter->group->page ->aggregate queries is run through the MemoryProxy, the remote GRPCProxy, and the engine directly; every resulting View canonicalises to identical bytes across all three. The same data code therefore yields identical results native and over the wire (browser/wasm) — proven, not asserted. 100% statement coverage on data/ and grpcproxy/ (generated datapb/ excepted); CI builds 6 arches + wasm + darwin + windows and runs the race detector. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
What
The headless data spine of the go-widgets ecosystem — the model layer an application skeleton binds its grids and lists to. Pure Go,
CGO=0; the core imports only the standard library andgo-widgets/mvvm.Core (
package data)Value/Kind— a comparable typed scalar (string / int / float / bool).Record/Schema/Field/Rule— a typed row and its validation (Required,StrMinLen/StrMaxLen,NumMin/NumMax), mirroringtoolkit's validation shape lifted to typed values.Query→Apply→View— a pure query engine: filter (eq/ne/lt/le/gt/ge/contains), multi-key sort (asc/desc), group-by, paginate (rows or groups), aggregate (count/sum/avg/min/max, grand + per-group).Proxyseam (List/Query/Mutate) withMemoryProxy, the in-process reference backend.Store[R]— a typed, bindable collection wired throughmvvm.ObservableList, so a view re-renders on data change.Canonical(View)— a deterministic, map-order-independent encoding used to compare views byte for byte.Transport (
package grpcproxy).protoservice (datapb, generated) carried overgrpc-transports/websocket. The Client is adata.Proxythat compiles tojs/wasm(a browser speaks the same gRPC service); the Server is native-only (//go:build !js).Proxy conformance — the key test
grpcproxyruns a battery of 15sort→filter→group→page→aggregatequeries through the MemoryProxy, the remote GRPCProxy, and the engine directly, canonicalises every resultingView, and requires all three identical byte for byte:So the same data code yields identical results native and over the wire (browser/wasm) — proven with a live gRPC-over-websocket round trip, not asserted.
Quality
data/andgrpcproxy/(the generateddatapb/protobuf excepted — filtered from the gate, DO NOT EDIT).gofmt/vetclean,-raceclean.js/wasm+ darwin + windows (the wasm build proves the GRPCProxy client is browser-ready).Notes for the reviewer
go-widgets/toolkit: the toolkit is stdlib-only (justpainter), and pulling gRPC + the websocket transport into it would pollute that purity and churn a repo that is co-edited live. This mirrors thego-widgets/mvvmprecedent.🤖 Generated with Claude Code