-
Notifications
You must be signed in to change notification settings - Fork 70
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
Feat deser class by schema collection #370
Feat deser class by schema collection #370
Conversation
0451a4e
to
203e139
Compare
4d7bd09
to
5ab1e68
Compare
5ab1e68
to
1eb4e97
Compare
a04ce8c
to
aed493d
Compare
63f3ece
to
4c2e622
Compare
4c2e622
to
c43ab16
Compare
packages/near-sdk-js/src/utils.ts
Outdated
} | ||
} | ||
// eslint-disable-next-line no-prototype-builtins | ||
} else if (ty !== undefined && ty.hasOwnProperty(UNORDERED_MAP_SCHE)) { |
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.
Can we check if ty
has reconstructor
method, and call that instead of check UNORDERED_MAP_SCHE
, etc.? If this is possible I feel it is more general and extensible, because assume user implement a new collection class, if he has reconstruct
method implemented, check reconstructor
approach will automatically work, but this way will need modify decodeObj2class.
On highlevel this is like: if schema
exist, use schema
. Otherwise try reconstructor
. Else, simply class_instance[key] = obj[key]
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.
ok, I will try it
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.
resolve! I use this format in schema, a general collection
type with reconstructor
method:
@NearBindgen({})
export class StatusDeserializeClass {
static schema = {
is_inited: "boolean",
records: {map: { key: 'string', value: 'string' }},
truck: Truck,
messages: {array: {value: 'string'}},
efficient_recordes: {collection: {reconstructor: UnorderedMap.reconstruct, value: 'string'}},
nested_efficient_recordes: {collection: {reconstructor: UnorderedMap.reconstruct, value: { collection: {reconstructor: UnorderedMap.reconstruct, value: 'string'}}}},
nested_lookup_recordes: {collection: {reconstructor: UnorderedMap.reconstruct, value: { collection: {reconstructor: LookupMap.reconstruct, value: 'string'}}}},
vector_nested_group: {collection: {reconstructor: Vector.reconstruct, value: { collection: {reconstructor: LookupMap.reconstruct, value: 'string'}}}},
lookup_nest_vec: {collection: {reconstructor: LookupMap.reconstruct, value: { collection: { reconstructor: Vector.reconstruct, value: 'string' }}}},
unordered_set: {collection: {reconstructor: UnorderedSet.reconstruct, value: 'string'}},
user_car_map: {collection: {reconstructor: UnorderedMap.reconstruct, value: Car }},
big_num: 'bigint',
date: 'date'
};
constructor() {
this.is_inited = false;
this.records = {};
this.truck = new Truck();
this.messages = [];
// account_id -> message
this.efficient_recordes = new UnorderedMap("a");
// id -> account_id -> message
this.nested_efficient_recordes = new UnorderedMap("b");
// id -> account_id -> message
this.nested_lookup_recordes = new UnorderedMap("c");
// index -> account_id -> message
this.vector_nested_group = new Vector("d");
// account_id -> index -> message
this.lookup_nest_vec = new LookupMap("e");
this.unordered_set = new UnorderedSet("f");
this.user_car_map = new UnorderedMap("g");
this.big_num = 1n;
this.date = new Date();
this.message_without_schema_defined = "";
this.number_without_schema_defined = 0;
this.records_without_schema_defined = {};
}
// ..
}
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 challenging and your implementation is great! just one little catch,
nested_efficient_recordes: {collection: {reconstructor: UnorderedMap.reconstruct, value: { collection: {reconstructor: UnorderedMap.reconstruct, value: 'string'}}}},
API looks a little bit unfriendly, can we slightly generalize and improve the API, to be:
nested_efficient_recordes: {class: UnorderedMap, value: UnorderedMap} // value: UnorderedMap is a shortcut for value: {class: UnorderedMap, value:'string'}
sdk should first try if UnorderedMap has a static schema
and use it to recursively decode. In this case, UnorderedMap doesn't. So sdk should next try call UnorderedMap.reconstruct.
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.
ok, I will try it
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.
Overall this is an excellent work that solves our long existing problem! There can be small improvements and additional features on top of this, for example if it's in typescript, make nearbindgen auto generate schema when build. But this PR is already a great enhancement, a well tested and a lot of work, let's only work on the PR reviews that can be quickly addressed, and create issue for bigger ones such as typescript auto generate.
Again this is a great job and I think this plus the borsh support worth a 2.0 release. Let's release after merge this PR!
d2c5b40
to
24f4e5e
Compare
a219875
to
1b4ec32
Compare
e43fe94
to
4ec38f8
Compare
4ec38f8
to
c8baf76
Compare
Pre-flight checklist
Motivation
Improve user experience in writing smart contract:
options.reconstructor
inget()
methodProposal and more details can be found in the file of
AUTO_RECONSCTRUCT_BY_JSON_SCHEME.md
Test Plan
current example class to be decoded by json schema:
Related issues/PRs
#239