Skip to content

Add the data spine: typed records, query engine, and Memory/gRPC proxies - #1

Merged
tannevaled merged 1 commit into
mainfrom
feat/data-spine
Aug 11, 2026
Merged

Add the data spine: typed records, query engine, and Memory/gRPC proxies#1
tannevaled merged 1 commit into
mainfrom
feat/data-spine

Conversation

@tannevaled

Copy link
Copy Markdown
Contributor

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 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.
  • QueryApplyView — 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).
  • 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 on data change.
  • 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. The Client is a data.Proxy that compiles to js/wasm (a browser speaks the same gRPC service); the Server is native-only (//go:build !js).

Proxy conformance — the key test

grpcproxy runs a battery of 15 sort→filter→group→page→aggregate queries through the MemoryProxy, the remote GRPCProxy, and the engine directly, canonicalises every resulting View, and requires all three identical byte for byte:

proxy conformance: 15 queries, MemoryProxy == GRPCProxy == engine (byte-identical)

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

  • 100% statement coverage on data/ and grpcproxy/ (the generated datapb/ protobuf excepted — filtered from the gate, DO NOT EDIT).
  • gofmt / vet clean, -race clean.
  • Cross-compiles all six 64-bit Go targets + js/wasm + darwin + windows (the wasm build proves the GRPCProxy client is browser-ready).

Notes for the reviewer

  • New repo under the go-widgets org; not auto-merged — opened green for review.
  • The data spine is a separate module rather than living inside go-widgets/toolkit: the toolkit is stdlib-only (just painter), and pulling gRPC + the websocket transport into it would pollute that purity and churn a repo that is co-edited live. This mirrors the go-widgets/mvvm precedent.
  • Org-conformance landing / logo / favicon / docs are a follow-up.

🤖 Generated with Claude Code

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>
@tannevaled
tannevaled merged commit 4645c6a into main Aug 11, 2026
1 check passed
@tannevaled
tannevaled deleted the feat/data-spine branch August 11, 2026 14:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant