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

Reviving async nested objects causes missing values #22

Open
lordofthelake opened this issue Mar 26, 2020 · 1 comment
Open

Reviving async nested objects causes missing values #22

lordofthelake opened this issue Mar 26, 2020 · 1 comment
Labels

Comments

@lordofthelake
Copy link

lordofthelake commented Mar 26, 2020

When trying to revive custom objects that have as properties other custom objects, if the reviver functions are asynchronous, the outer object's reviver doesn't receive the nested revived value as an argument immediately, but it does after a timeout.

Simplified example:

class CustomObject { 
	constructor(value) {
		this.value = value;
	}
}

class CustomObjectWithNestedObject {
	constructor(custom) {
		this.custom = custom
	}
}

const tson = new Typeson().register([{
	CustomObject: {
		test: (v) => v instanceof CustomObject,
		replaceAsync: (v) => Typeson.Promise.resolve(v.value),
		reviveAsync: (v) => Typeson.Promise.resolve(new CustomObject(v))
	},
	CustomObjectWithNestedObject: {
		test: (v) => v instanceof CustomObjectWithNestedObject,
		replaceAsync: (v) => Typeson.Promise.resolve({ custom: v.custom }),
		reviveAsync: (v) => Typeson.Promise.resolve(new CustomObjectWithNestedObject(v.custom))
	}
}])

const custom = new CustomObject("Hello")
const customNested = new CustomObjectWithNestedObject(custom);

tson.encapsulateAsync(customNested)
	.then(encapsulated => tson.reviveAsync(encapsulated))
	.then(revived => console.log(revived.customNested)) // => undefined

Interestingly, when rewriting CustomObjectWithNestedObject's reviver using a setTimeout, the property appears, making the problem look like a race condition:

		// ...
		// This works! 
		reviveAsync: (v) => new Typeson.Promise((resolve, reject) => {
			setTimeout(() => {
				// By the time this is executed, v.custom appears on the object!
				resolve(new CustomObjectWithNestedObject(v.custom))
			}, 0);
		})

I have created a CodeSandbox with a reproduction here, with tests extracted from my code: https://codesandbox.io/s/typeson-async-bug-reproduction-prpp9

I hope this can be fixed soon, as this is an otherwise great library :)

@brettz9
Copy link
Collaborator

brettz9 commented Mar 27, 2020

Thanks for your encouragement of the project. I'd like to help, but I'm afraid I have too much on my plate at this time, but I should be able to find time to review a PR if you might be able to take a closer look. Note that the typeson proper codebase is fairly small, so though it can be a little dizzying to track (and the reason why I haven't gotten to #11 as well--which incidentally sounds like it could be similar if not a dupe), it should be doable with some focused time (and probably more importantly, enough forethought on how such nesting needs to work).

@brettz9 brettz9 added the bug label Aug 13, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants