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
[HACKDAY] added populate
method to Promise to chain off any load / find call
#133
base: main
Are you sure you want to change the base?
Conversation
32f5971
to
451bf60
Compare
451bf60
to
3ea526a
Compare
export {}; | ||
|
||
declare global { | ||
interface Promise<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.
I appreciate the creativity here :-) but yeah, I'm not comfortable with this level of prototype hacking, both a) outside of graphql-service
, and b) these populate
methods only allow to promises of entities and not all promises.
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.
was thinking maybe we just provide the method definitions in their own interface and a helper function that would add the implementation to Promise.prototype
. Then consumers could apply it globally on an opt in basis.
eg we'd define something like this:
export interface PromisePopulate<T> {
populate<T extends Entity, H extends LoadHint<T>>(this: Promise<T>, hint: H): Promise<Loaded<T, H>>;
...
}
export function addPopulateToPromise() { Promise.prototype.populate = ... }
and then codebases that use joist could add this somewhere to get the behavior if they wanted:
declare global { interface Promise<T> extends PromisePopulate<T> {} }
addPopulateToPromise();
// When we load the author then try to load and populate through publisher | ||
const em = newEntityManager(); | ||
const author = await em.load(Author, "a:1"); | ||
const publisher = await author.publisher.load().populate("images"); |
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.
And this is what we originally wanted to be author.publisher.load("images")
but doesn't jive with TS?
Can you just the return type of Reference.load
to Promise<...> & { populate: ... }
, and then monkey-patch populate
directly onto that single promise
instead of the global Promise
prototype?
I guess I wouldn't be surprised if, to do something like:
const promise = em.load(....);
promise.populate = ....
return promise;
We can't use async
functions b/c the compiler/runtime rewriting of the function might create it's own promise, and not use the promise that we monkey-patched with a populate
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.
iirc adding a Loaded
or LoadHint
anywhere in the definition of Reference
or Collection
resulted in circular reference compiler errors
c936e48
to
7037a81
Compare
not 100% on this being the right way to go, but it compiles and actually works 🙃