From 066fb9a23d3baa9ba7606413d45ed87054479c16 Mon Sep 17 00:00:00 2001 From: Jonas Cosandey Date: Tue, 12 Jul 2022 11:08:33 +0200 Subject: [PATCH] feat(trackedFunction): second attempt at implementing a re-callable trackedFunction but this time with weird magic --- ember-resources/src/util/function.ts | 113 ++++++++++-------- .../app/components/util/function.gts | 3 +- 2 files changed, 65 insertions(+), 51 deletions(-) diff --git a/ember-resources/src/util/function.ts b/ember-resources/src/util/function.ts index 27e4c46c2..a4eeca51f 100644 --- a/ember-resources/src/util/function.ts +++ b/ember-resources/src/util/function.ts @@ -95,45 +95,76 @@ export function trackedFunction(...passedArgs: UseFunctionArgs) return buildResource(context, fn, initialValue); } +function createPropertyValue(getValue) { + const propertyValue = function () { + propertyValue.state = getValue(); + return propertyValue.state; + }; + + Object.defineProperty(propertyValue, "value", { + get: function () { + return ( + propertyValue.state.resolvedValue || + propertyValue.state.initialValue || + null + ); + }, + }); + Object.defineProperty(propertyValue, "isPending", { + get: function () { + return !propertyValue.state.isResolved; + }, + }); + Object.defineProperty(propertyValue, "isLoading", { + get: function () { + return propertyValue.state.isPending; + }, + }); + Object.defineProperty(propertyValue, "isError", { + get: function () { + return Boolean(propertyValue.state.error); + }, + }); + + return propertyValue; +} + function buildResource( context: any, fn: ResourceFn, initialValue: Return | undefined ) { + const getValue = async (state) => { + try { + console.log("Reexecuted"); + + let notQuiteValue = fn(hooks); + let promise = Promise.resolve(notQuiteValue); + + waitForPromise(promise); + + let result = await promise; + + state.error = undefined; + state.resolvedValue = result; + } catch (e) { + state.error = e; + } finally { + state.isResolved = true; + } + }; + return resource>(context, (hooks) => { - let state = new State(initialValue); - state.fn = fn; - state.context = context; - (async () => { - try { - console.log("Reexecuted"); - - let notQuiteValue = fn(hooks); - let promise = Promise.resolve(notQuiteValue); - - waitForPromise(promise); - - let result = await promise; - - state.error = undefined; - state.resolvedValue = result; - } catch (e) { - state.error = e; - } finally { - state.isResolved = true; - } - })(); - - return state; - }); -} + const state = new State(initialValue); + getValue(state); -export function executeTrackedFunction(oldState: State) { - assert(`Expected State to have property "fn"`, oldState.fn !== undefined); - const context = oldState.context; - const fn: ResourceFn = oldState.fn; - const initialValue = oldState.initialValue; - return buildResource(context, fn, initialValue); + const propertyValue = createPropertyValue(() => + getValue(new State(initialValue)) + ); + propertyValue.state = tracked(state); + + return propertyValue; + }); } /** @@ -141,28 +172,10 @@ export function executeTrackedFunction(oldState: State) { */ export class State { @tracked isResolved = false; - @tracked fn?: ResourceFn; - @tracked context?: any; @tracked resolvedValue?: Value; @tracked error?: unknown; constructor(public initialValue?: Value) {} - - get value() { - return this.resolvedValue || this.initialValue || null; - } - - get isPending() { - return !this.isResolved; - } - - get isLoading() { - return this.isPending; - } - - get isError() { - return Boolean(this.error); - } } /** diff --git a/testing/ember-app/app/components/util/function.gts b/testing/ember-app/app/components/util/function.gts index 164e90d6c..4f73ba660 100644 --- a/testing/ember-app/app/components/util/function.gts +++ b/testing/ember-app/app/components/util/function.gts @@ -23,7 +23,8 @@ export default class GlintTest extends Component { } executeTracked(){ - this.aMap = executeTrackedFunction(this.aMap) + const value = this.aMap() + console.log this.aMap.value }