Skip to content
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

Fix: maps, sets and vector types #203

Merged
merged 16 commits into from
Sep 16, 2022

Conversation

osalkanovic
Copy link
Contributor

Issue: #199

@osalkanovic osalkanovic marked this pull request as draft September 2, 2022 14:38
@osalkanovic osalkanovic marked this pull request as ready for review September 2, 2022 14:58
@osalkanovic osalkanovic changed the title Fix: maps, sets vector types Fix: maps, sets and vector types Sep 2, 2022
@@ -13,7 +13,7 @@ export class LookupMap {
return near.storageHasKey(storageKey)
}

get(key: Bytes): unknown | null {
get(key: Bytes): T | null {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue is what this get is an object instead of T. For example, the CarSpec get will be {id, color, price, engine}, not CarSpec{id, color, price, engine}

let indexRaw = getIndexRaw(this.keyIndexPrefix, key);
if (indexRaw) {
let index = deserializeIndex(indexRaw);
let value = this.values.get(index);
if (value) {
return value;
return value as T;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ailisp This could be solved by the new brand feature of ES2022 (here). Using TS syntax here is better for DX since the developer won't look at the compiled code anyway.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this feature is not related to deserialization. Can you please elaborate on how it can help?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When constructing a collection we could set the private field (brand) to the type of the underlying data we store, this would be serialized and stored which means we could theoretically infer the type with this field when deserializing the collection. We could also just let the user decide what the type is which is easier, and I don't know how valuable inferring the type is anyway. That's why I am saying it doesn't really matter that it says as T since types in JS/TS are just for developer experience anyway

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@petarvujovic98 what are you think about this example?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@osalkanovic I wouldn't use this approach as the instance is going to also get serialized so you will lose the constructor, plus if it is a primitive type it won't need to have a constructor and you are complicating the DX.

Keeping track of type data after seralization is difficult in JS, but since users are using TS to write the construction and access of variables after deserialization, it's better to keep the logic for those in the TS layer rather than in the JS/runtime layers.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @petarvujovic98 , and the way @osalkanovic shown is quite clever that I didn't think of. May @osalkanovic 's way be incorporated in as a pattern to write deserializer?: (value: unknown) => T

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ailisp I will update PR with deserializer today.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ailisp @volovyks @petarvujovic98 PR is ready for review

Copy link
Member

@ailisp ailisp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! There's still some problems on recovering the type of the object, so still cannot consider it as T 🤔

@petarvujovic98 petarvujovic98 mentioned this pull request Sep 7, 2022
@osalkanovic osalkanovic requested review from ailisp, volovyks and petarvujovic98 and removed request for volovyks, ailisp and petarvujovic98 September 8, 2022 12:57
@osalkanovic osalkanovic requested review from volovyks and ailisp and removed request for volovyks September 8, 2022 12:57
@@ -59,21 +59,21 @@ export class UnorderedMap {
return keysIsEmpty;
}

get(key: Bytes): unknown | null {
get(key: Bytes, deserializer?: (value: unknown) => DataType): DataType | null {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@petarvujovic98 since I see that you are working on the default value, maybe it would be good to convert this to options

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@osalkanovic Seems reasonable to me. This also allows for more extensibility in the future

Copy link
Member

@ailisp ailisp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall your work looks great! Thanks!

I'd like to add a small naming comment: in near-bindgen.ts, we call the process from object to DataType as "reconstruct", and deserializer in libraries usually mean from string/bytes to object. So I wonder if we should name it as reconstructor instead of deserializer?

The other way is make deserializer calls on raw instead of on value, this allow user to even override the JSON.parse with a customizable format, but this seems to be more scoped than this PR intended and a serializer? argument is better to come together.

Therefore I suggest naming it as reconstructor, and make a room for future adding deserializer the get by changing the signatures from:

    get(key: Bytes, reconstructor?: (value: unknown) => DataType): DataType | null {

to

    get(key: Bytes, options?: {reconstructor?: (value: unknown) => DataType}): DataType | null {

And, could you please change a test in tests/src/unordered-map.ts to ensure get with option works. We have an existing test that does manually reconstruct:

With your PR a house will be get directly!

@osalkanovic osalkanovic requested a review from ailisp September 9, 2022 18:57
@osalkanovic
Copy link
Contributor Author

@ailisp Updated with latest develop, ready for merge! :)

@ailisp
Copy link
Member

ailisp commented Sep 13, 2022

@osalkanovic Fantastic! You have even implemented generics for the new lookup map. I think this PR is in production-ready quality. @volovyks If this also looks good to you, let's wait NEARCON end (at Sep 14 and merge this!)

@ailisp
Copy link
Member

ailisp commented Sep 15, 2022

@osalkanovic We turned on ci, if you could resolve and merge latest develop into PR. If everything is good on CI we can merge it!

@osalkanovic
Copy link
Contributor Author

@osalkanovic We turned on ci, if you could resolve and merge latest develop into PR. If everything is good on CI we can merge it!

I will update today

@osalkanovic
Copy link
Contributor Author

@ailisp Ready for merge

@ailisp ailisp merged commit e8d1288 into near:develop Sep 16, 2022
@ailisp
Copy link
Member

ailisp commented Sep 16, 2022

@osalkanovic Thank you!

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.

4 participants