Add RpcSendable / RpcSubscribable duck-types and loosen reactive-store config#1708
Add RpcSendable / RpcSubscribable duck-types and loosen reactive-store config#1708mcintyre94 wants to merge 1 commit into
RpcSendable / RpcSubscribable duck-types and loosen reactive-store config#1708Conversation
🦋 Changeset detectedLatest commit: 0153a07 The changes in this PR will be included in the next version bump. This PR includes changesets to release 47 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
BundleMonFiles updated (25)
Unchanged files (122)
Total files change +3.94KB +0.75% Final result: ✅ View report in BundleMon website ➡️ |
|
Documentation Preview: https://kit-docs-mfs2aeazv-anza-tech.vercel.app |
c71602b to
4399c85
Compare
trevor-cortex
left a comment
There was a problem hiding this comment.
LGTM (commenting because I can't formally approve without explicit repo access).
Summary
Adds two structural duck-types — RpcSendable<TResponse> (just send(options?)) in @solana/rpc-spec and RpcSubscribable<TNotification> (just subscribe(options)) in @solana/rpc-subscriptions-spec — and uses them to loosen the rpcRequest / rpcSubscriptionRequest fields on the configs for createReactiveStoreWithInitialValueAndSlotTracking and createAsyncGeneratorWithInitialValueAndSlotTracking. Both primitives only ever call .send() / .subscribe() on those inputs, so the narrower types are sufficient and existing callers continue to work because PendingRpcRequest / PendingRpcSubscriptionsRequest structurally satisfy the new types.
Mirrors the prior-art pattern from ReactiveActionSource / ReactiveStreamSource, and makes life easier for plugin authors / test mocks that don't want to fabricate a full { reactiveStore, send } object.
What I verified
- The new
RpcSendable.sendsignature is identical toPendingRpcRequest.send(send(options?: RpcSendOptions): Promise<TResponse>), andRpcSubscribable.subscribeis identical toPendingRpcSubscriptionsRequest.subscribe(subscribe(options: RpcSubscribeOptions): Promise<AsyncIterable<TNotification>>) — so structural compatibility actually holds and existing call sites compile unchanged. - The new types flow through to
@solana/kitvia the existingexport *chains (rpc-spec→rpc→kit,rpc-subscriptions-spec→rpc-subscriptions→kit), matching the changeset's documentedimport type { RpcSendable, RpcSubscribable } from '@solana/kit'example. - Both implementation files only consume
.send()/.subscribe()on these inputs, so loosening the type is purely additive at runtime. - Docblock copy on the two config fields was updated from "A pending RPC request" → "A one-shot RPC request" / "An RPC subscription request", which more accurately describes the looser contract.
Changeset
minor across @solana/rpc-spec, @solana/rpc-subscriptions-spec, and @solana/kit looks right — purely additive new exports plus a contravariant input loosening, no breaking change. Fixed-version lockstep handles the umbrella @solana/rpc / @solana/rpc-subscriptions packages automatically.
Notes for subsequent reviewers
- Worth a quick sanity check that no downstream consumer is relying on the specific
PendingRpcRequest/PendingRpcSubscriptionsRequestshape on the config (e.g. calling.reactiveStore()on the passed-in object). A grep overrpcRequest.reactiveStore/rpcSubscriptionRequest.reactiveStorein this repo andkit-pluginsshould be enough. - No tests changed. Given this is type-only and the structural relationship is mechanically obvious, that's fine — but if there's a
__typetests__directory for these primitives, a one-liner asserting that aPending*Requestis assignable to the new config (and that a bare{ send }/{ subscribe }object also is) would lock in the contract cheaply.
4399c85 to
d303d3d
Compare
d303d3d to
eb7e142
Compare
b81de7d to
f0abc4e
Compare
eb7e142 to
0153a07
Compare
…store config
Add `RpcSendable<T>` to `@solana/rpc-spec` and `RpcSubscribable<T>` to `@solana/rpc-subscriptions-spec` — structural duck-types covering just `send({ abortSignal })` and `subscribe({ abortSignal })` respectively. Both are intentionally narrower than the concrete `PendingRpcRequest<T>` / `PendingRpcSubscriptionsRequest<T>`, which also expose `reactiveStore()`. Use them at consumer boundaries to accept request-like objects without forcing producers to implement the full store-bearing shape.
Loosens the `rpcRequest` and `rpcSubscriptionRequest` fields on `CreateReactiveStoreWithInitialValueAndSlotTrackingConfig` (exported) and the internal config for `createAsyncGeneratorWithInitialValueAndSlotTracking` to use the new types. Both primitives only ever call `.send()` and `.subscribe()` on their inputs, so the previous `Pending*Request` constraint was over-tight — existing callers passing concrete `rpc.getAccountInfo(addr)` / `rpcSubscriptions.accountNotifications(addr)` results still satisfy the loosened types structurally.
Motivation: plugin-authored wrappers (caching layers, request batchers, request dedup) and test mocks no longer need to stub out an unused `reactiveStore()` method just to satisfy the type. Parallels the existing `ReactiveStreamSource<T>` / `ReactiveActionSource<T>` duck-types in `@solana/subscribable` — same pattern, applied to the producer side of one-shot and subscription requests.
0153a07 to
e40f088
Compare
f0abc4e to
5dc6620
Compare

Problem
createReactiveStoreWithInitialValueAndSlotTrackingcurrently takes as input aPendingRpcRequestand aPendingRpcSubscriptionsRequest. These types are a bit more restrictive than they need to be, and particularly now include areactiveStore()function thatcreateReactiveStoreWithInitialValueAndSlotTrackingdoes not need.Summary of Changes
Add new types:
RpcSendable: just requires the.send()function fromPendingRpcRequestRpcSubscribable: just requires the.subscribe()function fromPendingRpcSubscriptionsRequestThis is similar to the
ReactiveActionSourceandReactiveStreamSourcetypes which only include the.reactiveStore()functions. They are introduced for the same reason, to make it easier for plugins etc to create instances of these types.createReactiveStoreWithInitialValueAndSlotTrackingandcreateAsyncGeneratorWithInitialValueAndSlotTrackingnow takeRpcSendableandRpcSubscribableinputs, making them more flexible.PendingRpcRequestandPendingRpcSubscriptionsRequestare still valid inputs as they satisfy these new types.