feat!: typed identifiers and uniform conventions across the public API #119
Labels
No labels
breaking-change
bug
documentation
duplicate
enhancement
good first issue
help wanted
performance
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Grandiras/ATProto.NET#119
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Part of the v0.7.0 update cycle (wave 3). Owner decision: typed identifiers everywhere. This is the one large, deliberate break that gives the SDK a type-safe surface. It lands after the identifier fixes (#114), the open-union/extension-data foundation (#115) and the transport/error rework, and before the lexicon additions, so new models are written typed from the start.
Typed identifiers
stringproperties exist today against 8 typed ones. Update the JSON converters accordingly; they throwJsonExceptionon invalid input.AtDatetime(readonly record struct) for Lexicondatetimefields. It preserves the original string so records round-trip byte-for-byte (and therefore CID-stable). It parses leniently on read (exposingTryGetValue/Value), is strict on construction, and hasNow()andToString().AtProtoRecord.CreatedAtbecomesAtDatetime?.RepoClient.CreateRecordAsync(AtIdentifier repo, Nsid collection, …, RecordKey? rkey, …, Cid? swapCommit),GetProfileAsync(AtIdentifier actor), …). Convenience overloads takingAtUriwhere the lexicon names a record.AtProtoClient.Did/HandlebecomeDid?/Handle?.rkey→ propertyRkey, typeRecordKey). TodayRKey,Rkey,rkeyandRecordKeyall appear.Uniform conventions (while every signature is being touched)
limit, thencursor, thenCancellationToken. Today at least three methods order them differently.ICursorPage<T> { IReadOnlyList<T> Items; string? Cursor; }implemented by every cursored response. Today only 2 of about 50 implementICursoredResponse.Enumerate*methods returningIAsyncEnumerable<T>through one internal paginator that stops on a null, empty or repeated cursor. A server repeating its cursor currently drives about 160k requests per second. RenameListAll*toEnumerate*. Add enumerators for timeline, author feed, followers, follows, likes, notifications, list members, records and convo messages.IReadOnlyList<T>for outputs; public method inputs takeIEnumerable<T>/IReadOnlyCollection<T>.*RequestDTOs that are never accepted by a public method becomeinternal.SpaceUrioverloads made redundant by typed parameters.Generator
atproto-lexgen csharp'sTypeMappermaps string formats to the typed identifiers andAtDatetime, and arrays toIReadOnlyList<T>, so generated code matches the SDK.Acceptance
string. Add a reflection test that asserts this, with an explicit allow-list for deliberate exceptions.Breaking changeswith a migration section (Did.Parse("…")at literal call sites,AtDatetime, parameter reordering,Enumerate*renames).Delivery plan: four PRs. This change touches every model and client, so it lands in four steps:
com.atprotoAtDatetime.ICursorPage<T>plus the internal paginator (stops on a null, empty or repeated cursor); theEnumerate*naming.CONTRIBUTING.md.TypeMapper.string. It starts with a temporary namespace allow-list that later PRs shrink to empty.Models/CommonModels,RecordCollection, theAtProtoClientfacade,Lexicon/Com/AtProto/{Repo,Server,Identity,Sync,Admin,Label,Moderation},PdsAdminClient.app.bsky.*(Lexicon/App/Bsky/**), plus the Blazor components that consume it.chat.bsky.*,tools.ozone.*,site.standard.*.Lexicon/Com/AtProto/{Space,SimpleSpace},src/ATProtoNet/Spaces/*,ATProtoNet.Server/Spaces/*, and the Jetstream and firehose models. The last PR empties the allow-list and closes this issue.PRs 2–4 run in parallel once 1 has merged.
DidDocument/ PLC models are left to #120, which replaces them.