diff --git a/packages/vestjs-runtime/src/Isolate/Isolate.ts b/packages/vestjs-runtime/src/Isolate/Isolate.ts index e9ea74e8a..9f92a05d0 100644 --- a/packages/vestjs-runtime/src/Isolate/Isolate.ts +++ b/packages/vestjs-runtime/src/Isolate/Isolate.ts @@ -2,6 +2,7 @@ import { CB, Maybe, Nullable, isNotNullish, isPromise } from 'vest-utils'; import { IsolateKeys } from 'IsolateKeys'; import { IsolateMutator } from 'IsolateMutator'; +import { IsolateStatus } from 'IsolateStatus'; import { Reconciler } from 'Reconciler'; import * as VestRuntime from 'VestRuntime'; @@ -13,6 +14,7 @@ export type TIsolate

= { [IsolateKeys.Type]: string; [IsolateKeys.Keys]: Nullable>; [IsolateKeys.Data]: DataOnly

; + [IsolateKeys.Status]: IsolateStatus; children: Nullable; key: IsolateKey; output: any; @@ -85,11 +87,17 @@ function useRunAsNew( const output = callback(current); if (isPromise(output)) { + IsolateMutator.setPending(current); + output.then(iso => { if (Isolate.isIsolate(iso)) { IsolateMutator.addChild(current, iso); } + + IsolateMutator.setDone(current); }); + } else { + IsolateMutator.setDone(current); } return output; @@ -112,6 +120,7 @@ function baseIsolate( [IsolateKeys.Parent]: null, [IsolateKeys.Type]: type, [IsolateKeys.Data]: data as IsolateData, + [IsolateKeys.Status]: IsolateStatus.INITIAL, children: null, key, output: null, diff --git a/packages/vestjs-runtime/src/Isolate/IsolateKeys.ts b/packages/vestjs-runtime/src/Isolate/IsolateKeys.ts index 8a1c410ac..66cf037ef 100644 --- a/packages/vestjs-runtime/src/Isolate/IsolateKeys.ts +++ b/packages/vestjs-runtime/src/Isolate/IsolateKeys.ts @@ -5,6 +5,7 @@ export enum IsolateKeys { Parent = 'parent', Data = 'data', AllowReorder = 'allowReorder', + Status = 'status', } enum MinifiedKeys { @@ -14,6 +15,7 @@ enum MinifiedKeys { Parent = 'P', Data = 'D', AllowReorder = 'aR', + Status = 'S', } export const KeyToMinified = { @@ -23,6 +25,7 @@ export const KeyToMinified = { [IsolateKeys.Data]: MinifiedKeys.Data, [IsolateKeys.Key]: MinifiedKeys.Key, [IsolateKeys.AllowReorder]: MinifiedKeys.AllowReorder, + [IsolateKeys.Status]: MinifiedKeys.Status, }; // This const is an object that looks like this: diff --git a/packages/vestjs-runtime/src/Isolate/IsolateMutator.ts b/packages/vestjs-runtime/src/Isolate/IsolateMutator.ts index 79467c1f5..1c19c4b06 100644 --- a/packages/vestjs-runtime/src/Isolate/IsolateMutator.ts +++ b/packages/vestjs-runtime/src/Isolate/IsolateMutator.ts @@ -1,6 +1,7 @@ import { Nullable, invariant, isNullish } from 'vest-utils'; import { TIsolate } from 'Isolate'; +import { IsolateStatus } from 'IsolateStatus'; export class IsolateMutator { static setParent(isolate: TIsolate, parent: Nullable): TIsolate { @@ -50,4 +51,12 @@ export class IsolateMutator { static setData(isolate: TIsolate, data: any): void { isolate.data = data; } + + static setPending(isolate: TIsolate): void { + isolate.status = IsolateStatus.PENDING; + } + + static setDone(isolate: TIsolate): void { + isolate.status = IsolateStatus.DONE; + } } diff --git a/packages/vestjs-runtime/src/Isolate/IsolateStatus.ts b/packages/vestjs-runtime/src/Isolate/IsolateStatus.ts new file mode 100644 index 000000000..f8a4b8d5e --- /dev/null +++ b/packages/vestjs-runtime/src/Isolate/IsolateStatus.ts @@ -0,0 +1,5 @@ +export enum IsolateStatus { + PENDING = 'PENDING', + DONE = 'DONE', + INITIAL = 'INITIAL', +} diff --git a/packages/vestjs-runtime/src/Isolate/__tests__/Isolate.test.ts b/packages/vestjs-runtime/src/Isolate/__tests__/Isolate.test.ts index a27b0ea22..da7dfbc3d 100644 --- a/packages/vestjs-runtime/src/Isolate/__tests__/Isolate.test.ts +++ b/packages/vestjs-runtime/src/Isolate/__tests__/Isolate.test.ts @@ -93,6 +93,26 @@ describe('Isolate', () => { expect(child.parent).toBe(parent); }); }); + + test('Isolate status is INITIAL before running', () => { + const control = jest.fn(); + withRunTime(() => { + return Isolate.create(IsolateType.Isolate, () => { + expect(useAvailableRoot().status).toBe('INITIAL'); + control(); + }); + }); + + expect(control).toHaveBeenCalled(); + }); + + test('Isolate status is DONE after running', () => { + const isolate = withRunTime(() => { + return Isolate.create(IsolateType.Isolate, () => {}); + }); + + expect(isolate.status).toBe('DONE'); + }); }); function withRunTime(fn: CB) { diff --git a/packages/vestjs-runtime/src/Isolate/__tests__/__snapshots__/asyncIsolate.test.ts.snap b/packages/vestjs-runtime/src/Isolate/__tests__/__snapshots__/asyncIsolate.test.ts.snap index 0b332465b..969b3cf61 100644 --- a/packages/vestjs-runtime/src/Isolate/__tests__/__snapshots__/asyncIsolate.test.ts.snap +++ b/packages/vestjs-runtime/src/Isolate/__tests__/__snapshots__/asyncIsolate.test.ts.snap @@ -18,6 +18,7 @@ exports[`AsyncIsolate It should resolve async isolate into the parent 2`] = ` "keys": null, "output": undefined, "parent": [Circular], + "status": "DONE", }, { "$type": "UGrandChild_2", @@ -28,6 +29,7 @@ exports[`AsyncIsolate It should resolve async isolate into the parent 2`] = ` "keys": null, "output": undefined, "parent": [Circular], + "status": "DONE", }, { "$type": "UGrandChild_3", @@ -38,6 +40,7 @@ exports[`AsyncIsolate It should resolve async isolate into the parent 2`] = ` "keys": null, "output": undefined, "parent": [Circular], + "status": "DONE", }, ], "data": {}, @@ -45,6 +48,7 @@ exports[`AsyncIsolate It should resolve async isolate into the parent 2`] = ` "keys": null, "output": undefined, "parent": [Circular], + "status": "DONE", }, ], "data": {}, @@ -52,5 +56,20 @@ exports[`AsyncIsolate It should resolve async isolate into the parent 2`] = ` "keys": null, "output": Promise {}, "parent": null, + "status": "DONE", +} +`; + +exports[`AsyncIsolate It should set the isolate state to pending 1`] = ` +{ + "$type": "URoot", + "allowReorder": undefined, + "children": null, + "data": {}, + "key": null, + "keys": null, + "output": Promise {}, + "parent": null, + "status": "PENDING", } `; diff --git a/packages/vestjs-runtime/src/Isolate/__tests__/asyncIsolate.test.ts b/packages/vestjs-runtime/src/Isolate/__tests__/asyncIsolate.test.ts index 05c8ae942..a0e63ae2d 100644 --- a/packages/vestjs-runtime/src/Isolate/__tests__/asyncIsolate.test.ts +++ b/packages/vestjs-runtime/src/Isolate/__tests__/asyncIsolate.test.ts @@ -8,12 +8,10 @@ describe('AsyncIsolate', () => { test('It should resolve async isolate into the parent', () => { return new Promise(async done => { let root = {} as TIsolate; - const control = jest.fn(); withRunTime(() => { // Create root isolate from which all others will be created root = Isolate.create('URoot', genChildren); }); - expect(control).not.toHaveBeenCalled(); expect(root).toMatchInlineSnapshot(` { "$type": "URoot", @@ -24,6 +22,7 @@ describe('AsyncIsolate', () => { "keys": null, "output": Promise {}, "parent": null, + "status": "PENDING", } `); await wait(10); @@ -46,6 +45,32 @@ describe('AsyncIsolate', () => { done(); }); }); + + test('It should set the isolate state to pending', () => { + return new Promise(done => { + let root = {} as TIsolate; + withRunTime(() => { + // Create root isolate from which all others will be created + root = Isolate.create('URoot', genChildren); + }); + expect(root).toMatchSnapshot(); + expect(root?.status).toBe('PENDING'); + done(); + }); + }); + + it('should set the isolate state to done when complete', () => { + return new Promise(async done => { + let root = {} as TIsolate; + withRunTime(() => { + // Create root isolate from which all others will be created + root = Isolate.create('URoot', genChildren); + }); + await wait(10); + expect(root?.status).toBe('DONE'); + done(); + }); + }); }); function withRunTime(fn: CB) { diff --git a/packages/vestjs-runtime/src/exports/__tests__/IsolateSerializer.test.ts b/packages/vestjs-runtime/src/exports/__tests__/IsolateSerializer.test.ts index 87908c54c..07fb055a1 100644 --- a/packages/vestjs-runtime/src/exports/__tests__/IsolateSerializer.test.ts +++ b/packages/vestjs-runtime/src/exports/__tests__/IsolateSerializer.test.ts @@ -29,21 +29,25 @@ describe('IsolateSerializer', () => { "some_data": true, }, "parent": [Circular], + "status": "DONE", }, { "$type": "UChild_2", "data": {}, "parent": [Circular], + "status": "DONE", }, { "$type": "UChild_3", "data": {}, "parent": [Circular], + "status": "DONE", }, ], "data": { "some_data": true, }, + "status": "DONE", } `); }); diff --git a/packages/vestjs-runtime/src/exports/__tests__/__snapshots__/IsolateSerializer.test.ts.snap b/packages/vestjs-runtime/src/exports/__tests__/__snapshots__/IsolateSerializer.test.ts.snap index 197a5a7cb..6adbe02aa 100644 --- a/packages/vestjs-runtime/src/exports/__tests__/__snapshots__/IsolateSerializer.test.ts.snap +++ b/packages/vestjs-runtime/src/exports/__tests__/__snapshots__/IsolateSerializer.test.ts.snap @@ -1,3 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`IsolateSerializer serialize Should produce serialized dump 1`] = `"{"children":[{"$":"UChild_1","D":{"some_data":true}},{"$":"UChild_2","D":{}},{"$":"UChild_3","D":{}}],"$":"URoot","D":{"some_data":true}}"`; +exports[`IsolateSerializer serialize Should produce serialized dump 1`] = `"{"children":[{"$":"UChild_1","D":{"some_data":true},"S":"DONE"},{"$":"UChild_2","D":{},"S":"DONE"},{"$":"UChild_3","D":{},"S":"DONE"}],"$":"URoot","D":{"some_data":true},"S":"DONE"}"`; diff --git a/packages/vestjs-runtime/src/exports/test-utils.ts b/packages/vestjs-runtime/src/exports/test-utils.ts index f5fa3ead4..a623f6f8a 100644 --- a/packages/vestjs-runtime/src/exports/test-utils.ts +++ b/packages/vestjs-runtime/src/exports/test-utils.ts @@ -1,5 +1,6 @@ import { TIsolate } from 'Isolate'; import { IsolateKeys } from 'IsolateKeys'; +import { IsolateStatus } from 'IsolateStatus'; export function genTestIsolate(data: Record = {}): TIsolate { return { @@ -9,6 +10,7 @@ export function genTestIsolate(data: Record = {}): TIsolate { keys: {}, output: null, parent: null, + status: IsolateStatus.INITIAL, [IsolateKeys.Type]: 'UnitTest', }; } diff --git a/packages/vestjs-runtime/src/vestjs-runtime.ts b/packages/vestjs-runtime/src/vestjs-runtime.ts index ce38c7785..b9d162788 100644 --- a/packages/vestjs-runtime/src/vestjs-runtime.ts +++ b/packages/vestjs-runtime/src/vestjs-runtime.ts @@ -1,4 +1,5 @@ export { IsolateKey, TIsolate, Isolate } from 'Isolate'; +export { IsolateStatus } from 'IsolateStatus'; export { Reconciler, IRecociler } from 'Reconciler'; export * as Walker from 'IsolateWalker'; export { RuntimeApi as VestRuntime } from 'VestRuntime'; diff --git a/packages/vestjs-runtime/tsconfig.json b/packages/vestjs-runtime/tsconfig.json index d748a0d0e..156a69a70 100644 --- a/packages/vestjs-runtime/tsconfig.json +++ b/packages/vestjs-runtime/tsconfig.json @@ -15,6 +15,7 @@ "test-utils": ["./src/exports/test-utils.ts"], "IsolateSerializer": ["./src/exports/IsolateSerializer.ts"], "ErrorStrings": ["./src/errors/ErrorStrings.ts"], + "IsolateStatus": ["./src/Isolate/IsolateStatus.ts"], "IsolateSelectors": ["./src/Isolate/IsolateSelectors.ts"], "IsolateMutator": ["./src/Isolate/IsolateMutator.ts"], "IsolateKeys": ["./src/Isolate/IsolateKeys.ts"],