Skip to content

Commit

Permalink
fix(vow): allow resolving vow to external promise
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelfig authored and mhofman committed Jun 22, 2024
1 parent f3c6393 commit 945a60c
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 7 deletions.
5 changes: 1 addition & 4 deletions packages/boot/test/upgrading/upgrade-vats.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -557,10 +557,7 @@ test('upgrade vat-vow', async t => {
vowFulfilled: { status: 'fulfilled', value: 'hello' },
vowRejected: { status: 'rejected', reason: 'goodbye' },
vowPostUpgrade: { status: 'fulfilled', value: 'bonjour' },
// The 'fulfilled' result below is wishful thinking. Long-lived
// promises are not supported by `watch` at this time.
// vowExternalPromise: { status: 'fulfilled', value: 'ciao' },
vowExternalPromise: upgradeRejection,
vowExternalPromise: { status: 'fulfilled', value: 'ciao' },
vowExternalVow: upgradeRejection,
vowPromiseForever: upgradeRejection,
});
Expand Down
24 changes: 21 additions & 3 deletions packages/vow/src/vow.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ export const prepareVowKit = zone => {
() => ({
value: undefined,
// The stepStatus is null if the promise step hasn't settled yet.
stepStatus: /** @type {null | 'fulfilled' | 'rejected'} */ (null),
stepStatus: /** @type {null | 'pending' | 'fulfilled' | 'rejected'} */ (
null
),
}),
{
vowV0: {
Expand All @@ -84,6 +86,7 @@ export const prepareVowKit = zone => {
case 'rejected':
throw value;
case null:
case 'pending':
return provideCurrentKit(this.facets.resolver).promise;
default:
throw new TypeError(`unexpected stepStatus ${stepStatus}`);
Expand All @@ -96,26 +99,41 @@ export const prepareVowKit = zone => {
*/
resolve(value) {
const { resolver } = this.facets;
const { promise, resolve } = getPromiseKitForResolution(resolver);
const { stepStatus } = this.state;
const { resolve } = getPromiseKitForResolution(resolver);
if (resolve) {
resolve(value);
zone.watchPromise(promise, this.facets.watchNextStep);
}
if (stepStatus === null) {
this.state.stepStatus = 'pending';
zone.watchPromise(
HandledPromise.resolve(value),
this.facets.watchNextStep,
);
}
},
/**
* @param {any} [reason]
*/
reject(reason) {
const { resolver, watchNextStep } = this.facets;
const { stepStatus } = this.state;
const { reject } = getPromiseKitForResolution(resolver);
if (reject) {
reject(reason);
}
if (stepStatus === null) {
watchNextStep.onRejected(reason);
}
},
},
watchNextStep: {
onFulfilled(value) {
const { resolver } = this.facets;
const { resolve } = getPromiseKitForResolution(resolver);
if (resolve) {
resolve(value);
}
this.state.stepStatus = 'fulfilled';
this.state.value = value;
},
Expand Down

0 comments on commit 945a60c

Please sign in to comment.