-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Simplify types, inheritance structure, and API #156
Conversation
🦋 Changeset detectedLatest commit: 099c88f The changes in this PR will be included in the next version bump. This PR includes changesets to release 3 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 |
e6a58ba
to
c77d9b4
Compare
TBDocs Report 🛑 Errors: 0 @tbdex/protocol
@tbdex/http-client
@tbdex/http-server
TBDocs Report Updated at 2024-02-06T23:33:14Z |
diving into this now |
regarding changes made to
|
Glad you think so! I made a deliberate choice to allow small amounts of repetition in order to make the API surface and the implementation simpler.
Absolutely. I'll add details to the PR description tomorrow. |
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## main #156 +/- ##
==========================================
+ Coverage 78.69% 85.52% +6.82%
==========================================
Files 19 35 +16
Lines 1169 2798 +1629
Branches 99 234 +135
==========================================
+ Hits 920 2393 +1473
- Misses 249 405 +156
|
* main: adding `replyTo` field in http request body to submit RFQ (#142)
packages/http-client/src/client.ts
Outdated
data.push(resource) | ||
const responseBody = await response.json() | ||
const jsonOfferings = responseBody.data as any[] | ||
for (let jsonResource of jsonOfferings) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for (let jsonResource of jsonOfferings) { | |
for (let jsonOffering of jsonOfferings) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
soo awesome!! i love the changes you've made to protocol
(which in turn also affects http-client
positively in simplifying types and tightening type constraints wherever possible). i also very much appreciate the small cleanups throughout this PR.
i don't immediately love the api changes to http-server
- i wish we could preserve some of our generic magic in submit<T>
and get<T>
so we don't have to write / update concrete impls if tbdex messages change in the future. but i think changes i have to make as a consumer won't be too bad.
/** the message you want to send */ | ||
message: Message<T> | MessageModel<T> | ||
message: T |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is pretty great!!
@@ -82,7 +83,7 @@ | |||
"build:esm": "rimraf dist/esm dist/types && tsc", | |||
"build:cjs": "rimraf dist/cjs && tsc -p tsconfig.cjs.json && echo '{\"type\": \"commonjs\"}' > ./dist/cjs/package.json", | |||
"build:browser": "rimraf dist/browser.mjs dist/browser.js && node build/bundles.js", | |||
"test:node": "rimraf tests/compiled && pnpm compile-validators && tsc -p tests/tsconfig.json && mocha", | |||
"test:node": "rimraf tests/compiled && pnpm compile-validators && tsc -p tests/tsconfig.json && c8 mocha", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is c8
for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
c8 produces a code coverage report when you run the tests
id : id, | ||
exchangeId : id, | ||
createdAt : new Date().toISOString() | ||
} | ||
|
||
// TODO: hash `data.payinMethod.paymentDetails` and set `private` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we keep these // TODO
if they aren't completed in this pr and are still to be done?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like in other areas of this PR that we're doing away with the concept of private
fields? not 100% sure tho
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My bad, I should have provided more context there. In this proposal for how to handle private data, we're doing away with the notion of private
as a top-level field in RFQs. This PR does not implement the proposal, but it does clean up private
in preparation for implementing the proposal. I'll put the TODO back in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
packages/protocol/src/parse.ts
Outdated
let message: Message | ||
switch(jsonMessage.metadata.kind) { | ||
case 'rfq': | ||
message = new Rfq( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
message = new Rfq( | |
message = await Rfq.parse(rawMessage) |
just wondering if we can use parse()
method you already wrote for each of the concrete message impls?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer not to reuse Rfq.parse
etc. Rfq.parse()
does some of the same things that are already done in parseMessage
, so we would be repeating operations (.verify()
, and rawToMessageModel
). While we could remove those operations from parseMessage
, I think it would be less clear what parseMessage
is doing. Also, i prefer to think of Rfq.parse()
and parseMessage
as part of the public API for this library, and that we use the constructors and instance methods when appropriate internally.
}) | ||
}) | ||
|
||
// describe('validate', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove these commented out bits if not relevant anymore?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
upd8d
packages/protocol/src/parse.ts
Outdated
* @param message - the message to parse. can either be an object or a string | ||
* @returns {@link Message} | ||
*/ | ||
export async function parseMessage(rawMessage: MessageModel | string): Promise<Message> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thoughts on being able to call this like MessageUtils.parseMessage()
as a static method? a good amount of our other API surfaces tend to follow this pattern i.e. Rfq.parse()
or Crypto.verify()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Works for me. Instead of MessageUtils
, I'm calling it Parser
which matches the grammatical pattern of our Validator
and DidResolver
. MessageUtils
seems a little too broad, plus this file contains utils for parsing resources in addition to messages.
oh, could you add a changeset? steps here |
32a8777
to
483dc1d
Compare
483dc1d
to
654c31f
Compare
Fair enough. Here's my defense. First, a petite polemic: Generics are a fatal temptation. The DRYness that generics promise only breeds a thirst for even more generics. One drop may be invigorating, but we must not become addicted, lest we resent their absence. In this PR I adopt the principle that anything that can be accomplished clearly and readably without generics, should be done without generics. The existing For example,
I'd argue this is an anti-pattern in the context of |
fair @diehuxx i'll take maintainability and clarity over hipster api surface vibes. fwiw looks like all that's left is addressing the tbdocs warnings i think? |
All Changes
Message
and its subclasses andResource
and its subclasses.protocol
andhttp-server
packages. Remove generics wherever possible. Replace generics with intersection types which are easier to read. Remove all types which could be considered "typescript neckbeardery"Message.factory
andResource.factory
. Introduce standalone functionsparseMessage
andparseResource
, reducing coupling and circular dependency.Message
andRfq
. In follow up PRs, I will further improve test coverage in the all three packages. I'm not testing in this PR because it's already a big diff.TbdexHttpServer
for adding callback functions. http-server has no tests currently, so tests for this new API will come in a follow up PR.Changes to public API surface
tbdex/protocol
I updated the README to reflect the new uses.
All uses of
MessageKindClass
andResourceKindClass
have been replaced withMessage
andResource
.Message.parse
andResource.parse
have been replaced withparseMessage()
andparseResource()
.Each message-kind subclass and resource-kind subclass (e.g.
Rfq
,Offering
, etc.) now have their own dedicated.parse()
method which checks that the input is the expected message kind. For example,Rfq.parse(inputJson)
will return an instance of theRfq
class if and only ifinputJson
is a valid, signed RFQ.Message.verify()
,Resource.verify()
,Message.validate()
, andResource.validate()
are no longer static methods. They have been replaced with instance methodstbdex/http-server
Updated to reflect type changes from
tbdex/protocol
, most notablyMessageKindClass
->Message
.Alter API for adding callbacks methods to Tbdex server. Removes methods
get
andsubmit
, replacing them withonSubmitRfq(callback: SubmitRfqCallback): void
onSubmitOrder(callback: SubmitOrderCallback): void
onSubmitClose(callback: SubmitCloseCallback): void
onGetExchanges(callback: GetExchangesCallback): void
onGetOfferings(callback: GetOfferingsCallback): void