Skip to content

add Events.Typed for registry-backed typed event access#8

Merged
hstern merged 1 commit into
mainfrom
secevent-11-typed-events
Jun 21, 2026
Merged

add Events.Typed for registry-backed typed event access#8
hstern merged 1 commit into
mainfrom
secevent-11-typed-events

Conversation

@hstern

@hstern hstern commented Jun 21, 2026

Copy link
Copy Markdown
Owner

What

Adds Events.Typed(uri string) (Event, bool, error) — registry-backed
typed access to a single events-claim member, completing the consumer
half of the event-type registry seam (the Event interface plus
RegisterEventType/LookupEventType landed previously).

Behaviour — four cases, bool true in exactly one

Member state Returns
URI not present in the events claim (nil, false, nil)
Present, no decoder registered (unknown/future event type) (nil, false, nil) — stays raw, reachable via Raw()[uri]
Present, registered decoder succeeds (event, true, nil)
Present, registered decoder fails (nil, false, err) — wrapped %w with the event-type URI

An unregistered URI is the expected forward-compatibility case
(RFC 8417 §2.2), not an error — its bytes round-trip byte-stably, which
CAEP, RISC, and other event vocabularies depend on.

Notes

  • No enumeration helper added. Ranging the keys of Raw() and
    calling Typed per URI reads cleanly without new surface, so the
    godoc documents that pattern instead of introducing a URIs method.
  • Zero-copy decode. The raw bytes are passed to the decoder as-is,
    per the decoder contract that forbids mutating them, preserving the
    no-deserialization-cost property of unread events.
  • Decode-error wrapping uses %w so errors.Is/errors.As reach
    the cause; the message names the failing event-type URI.

Tests

Distinct event-type URIs per case keep the suite order-independent under
-shuffle against the process-wide registry. Coverage: all four
documented outcomes, a nil receiver, errors.Is on a decoder sentinel,
errors.As unwrapping to a concrete JSON error, and the documented
range-over-Raw iteration.

Local CI

gofmt -l clean · go vet ./... clean · go mod tidy -diff no drift ·
go test -race -shuffle=on ./... pass · golangci-lint run ./... 0 issues.

🤖 Generated with Claude Code

The events container has held its members as raw json.RawMessage since
the wire-shape phase, and the event-type registry (Event, EventDecoder,
RegisterEventType, LookupEventType) landed alongside it. This connects
the two: Events.Typed decodes a single events-claim member through the
registry, turning a recognized event type's raw payload into the typed
Event its vocabulary registered.

The method distinguishes four outcomes, and the returned bool is true in
exactly one of them. An absent member and a present-but-unregistered
member both report (nil, false, nil) — an event type this build does not
recognize is the expected forward-compatibility case (RFC 8417 §2.2),
not an error, and its bytes stay reachable through Raw so the
byte-stable round-trip is preserved. A present member whose registered
decoder succeeds returns (event, true, nil). A present member whose
decoder fails returns (nil, false, err), wrapping the decoder's error
with %w and the event-type URI so errors.Is/As reach the cause and the
message names which event failed.

No enumeration helper is added: ranging the keys of Raw and calling
Typed per URI reads cleanly and needs no new surface, so the godoc
documents that pattern rather than introducing a URIs method. Decoding
is left zero-copy — the raw bytes are handed to the decoder as-is, per
the decoder contract that forbids mutating them — to keep the
no-deserialization-cost property of unread events.

Tests register distinct event-type URIs per case so they stay
order-independent under -shuffle against the process-wide registry, and
cover all four documented outcomes plus a nil receiver, errors.Is
matching on a decoder sentinel, errors.As unwrapping to a concrete JSON
error, and the documented range-over-Raw iteration.

Co-Authored-By: Claude <noreply@anthropic.com>
@hstern hstern enabled auto-merge (squash) June 21, 2026 01:42
@hstern hstern merged commit 9d202cb into main Jun 21, 2026
4 checks passed
@hstern hstern deleted the secevent-11-typed-events branch June 21, 2026 01:44
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