Skip to content

Commit

Permalink
Abandoning this too
Browse files Browse the repository at this point in the history
  • Loading branch information
hubol committed Sep 4, 2024
1 parent b50db5e commit 5152a04
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 48 deletions.
65 changes: 35 additions & 30 deletions src/lib/zone/prommy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,19 @@ import { ForceAliasType } from "../types/force-alias-type";

const PrommyGlobal = {
$root: Force<PrommyRoot>(),
$push,
$push: $push as any as (p: PromiseLike<unknown>) => PromiseLike<unknown>,
$pop,
}

let installed = false;

export function installPrommy() {
if (installed)
return;
if (!installed) {
installed = true;

installed = true;

globalThis.$p = PrommyGlobal;
redefinePromise();
globalThis.$p = PrommyGlobal;
redefinePromise();
}

return { $p: PrommyGlobal };
}
Expand All @@ -27,10 +26,6 @@ export const Prommy = {
create,
}

export const _Internal_Prommy = {
create: create as <T> (...args: Parameters<typeof create<T>>) => Prommy<T> & PrivatePromise,
}

function createRoot<T>(executor: () => Promise<T>, context: any) {
return new PrommyRoot(executor, context);
}
Expand All @@ -46,7 +41,6 @@ function create<T>(executor: (resolve: (value: T | PromiseLike<T>) => void, reje
interface PrivatePromise {
$isPromise?: true;
$root: PrommyRoot;
$pushed?: boolean;
}

// TODO it may be possible to modify the prototype constructor
Expand All @@ -71,31 +65,36 @@ const Promise_resolve = Promise.resolve;
const Promise_reject = Promise.reject;

function redefinePromise() {
// globalThis.Promise = function (this: Promise<unknown> & PrivatePromise, executor) {
// const p = new Promise_ctor(executor) as Promise<unknown> & PrivatePromise;
// p.$root = PrommyGlobal.$root;
// return p;
// } as any;
globalThis.Promise = function (this: Promise<unknown> & PrivatePromise, executor) {
const p = new Promise_ctor(executor) as Promise<unknown> & PrivatePromise;
p.$root = PrommyGlobal.$root;
return p;
} as any;

new Promise(() => {}).finally()

Object.defineProperties(Promise.prototype, {
then: {
value: function (this: Promise<unknown> & PrivatePromise, onfulfilled?, onrejected?) {
return Promise_then.call(this,
const p = Promise_then.call(this,
onfulfilled && ((value) => {
PrommyGlobal.$root = this.$root;
debugSetGlobal(this.$root, 'Promise.then.onfulfilled');
// PrommyGlobal.$root = this.$root;
const result = onfulfilled(value);
if (isPromise(result)) {
result.$root = this.$root;
}
else if (isPromiseLike(result)) {
// TODO I think a Prommy can be constructed from it
console.error("Don't know how to handle this case!");
console.error("then: Don't know how to handle this case!");
}

return result;
}),
// TODO not sure if this is correct
onrejected);
onrejected) as Promise<unknown> & PrivatePromise;
p.$root = this.$root;
return p;
},
configurable: true,
},
Expand Down Expand Up @@ -153,7 +152,7 @@ function isAwaitedPrommyResult(value: any): value is AwaitedPrommyResult {

function $pop(awaitedResult: unknown) {
if (isAwaitedPrommyResult(awaitedResult)) {
PrommyGlobal.$root = awaitedResult.$root;
debugSetGlobal(awaitedResult.$root, '$pop.isAwaitedPrommyResult');
return awaitedResult.$value;
}

Expand All @@ -163,14 +162,15 @@ function $pop(awaitedResult: unknown) {
}

function $push(promise: PromiseLike<unknown> & PrivatePromise) {
if (promise.$pushed)
return promise;
if (!isPromise(promise)) {
// TODO I think a Prommy can be constructed from it
console.error("Don't know how to handle this case!");
console.error("$push: Don't know how to handle this case!");
}
const p = Promise_then.call(promise, $value => ({ $value, $root: promise.$root })) as Promise<unknown> & PrivatePromise;
p.$pushed = true;
const $root = promise.$root || PrommyGlobal.$root || null;
promise.$root = $root;
debugSetGlobal($root, '$push');
const p = promise.then($value => ({ $value, $root })) as Promise<unknown> & PrivatePromise;
p.$root = $root;
return p;
}

Expand All @@ -186,9 +186,9 @@ export class PrommyRoot {
this.context = context;

const previous = PrommyGlobal.$root;
PrommyGlobal.$root = this;
this._promise = executor().catch(e => {});
PrommyGlobal.$root = previous;
debugSetGlobal(this, 'new PrommyRoot push');
this._promise = executor().catch(console.error);
debugSetGlobal(previous, 'new PrommyRoot pop');
}
}

Expand All @@ -198,4 +198,9 @@ export const PrommyContext = {
current() {
return PrommyGlobal.$root.context;
}
}

function debugSetGlobal(root: PrommyRoot, info: string) {
console.log('-->', root?.context || null, ':', info);
PrommyGlobal.$root = root;
}
76 changes: 61 additions & 15 deletions test/tests/test-prommy-more.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,68 @@
import { Prommy, PrommyContext } from "../../src/lib/zone/prommy";
import { Prommy, PrommyContext, installPrommy } from "../../src/lib/zone/prommy";
import { Assert } from "../lib/assert";
import { TestPromise } from "../lib/test-promise";

export async function morePrommyAndChainingWorks() {
const { $p } = installPrommy();

export async function morePrommyThenChainingWorks() {
const events: string[] = [];

Prommy.createRoot(async () => {
Assert(PrommyContext.current()).toStrictlyBe('rootA');
$p.$pop(await $p.$push(asyncFunction().then(() => {
Assert(PrommyContext.current()).toStrictlyBe('rootA');
events.push('a');
})));
Assert(PrommyContext.current()).toStrictlyBe('rootA');
$p.$pop(await $p.$push(asyncFunction().then(() => {
Assert(PrommyContext.current()).toStrictlyBe('rootA');
events.push('c');
}).then(() => {
Assert(PrommyContext.current()).toStrictlyBe('rootA');
return ticks(10);
})));
Assert(PrommyContext.current()).toStrictlyBe('rootA');
events.push('e');
}, 'rootA');

Prommy.createRoot(async () => {
Assert(PrommyContext.current()).toStrictlyBe('rootB');
$p.$pop(await $p.$push(asyncFunction().then(() => {
Assert(PrommyContext.current()).toStrictlyBe('rootB');
return ticks(2);
}).then(() => events.push('b'))));
Assert(PrommyContext.current()).toStrictlyBe('rootB');
$p.$pop(await $p.$push(asyncFunction()));
Assert(PrommyContext.current()).toStrictlyBe('rootB');
events.push('d');
}, 'rootB');

for (let i = 0; i < 30; i++) {
tick();
await TestPromise.flush();
}

Assert(events.length).toStrictlyBe(5);
Assert(events[0]).toStrictlyBe('a');
Assert(events[1]).toStrictlyBe('b');
Assert(events[2]).toStrictlyBe('c');
Assert(events[3]).toStrictlyBe('d');
Assert(events[4]).toStrictlyBe('e');
}

export async function morePrommyAllWorks() {

}

async function returnsPromisePrommy() {
console.log('a');
(globalThis.$prommyResult = await ticks(2), globalThis.$prommyPop(), globalThis.$prommyResult)
console.log('b');
(globalThis.$prommyResult = await ticks(2), globalThis.$prommyPop(), globalThis.$prommyResult)
async function asyncFunction() {
const initialContext = PrommyContext.current();
console.log(initialContext);
Assert(PrommyContext.current()).toBeTruthy();
$p.$pop(await $p.$push(ticks(2)));
Assert(PrommyContext.current()).toStrictlyBe(initialContext);
$p.$pop(await $p.$push(ticks(2)));
Assert(PrommyContext.current()).toStrictlyBe(initialContext);
return 3;
}

export async function morePrommyUtilityFunctionWorks() {
Expand All @@ -23,20 +71,19 @@ export async function morePrommyUtilityFunctionWorks() {

Prommy.createRoot(async () => {
Assert(PrommyContext.current()).toStrictlyBe('root1');
(globalThis.$prommyResult = await new Prommy(returnsPromisePrommy()), globalThis.$prommyPop(), globalThis.$prommyResult)
// await returnsPromisePrommy();
$p.$pop(await $p.$push(asyncFunction()));
Assert(PrommyContext.current()).toStrictlyBe('root1');
(globalThis.$prommyResult = await new Prommy(returnsPromisePrommy()), globalThis.$prommyPop(), globalThis.$prommyResult)
$p.$pop(await $p.$push(asyncFunction()));
Assert(PrommyContext.current()).toStrictlyBe('root1');
finished1 = true;
}, 'root1');

Prommy.createRoot(async () => {
Assert(PrommyContext.current()).toStrictlyBe('root2');
// TODO this transformation needs to happen in TSvvvvvvvv
(globalThis.$prommyResult = await new Prommy(returnsPromisePrommy()), globalThis.$prommyPop(), globalThis.$prommyResult)
$p.$pop(await $p.$push(asyncFunction()));
Assert(PrommyContext.current()).toStrictlyBe('root2');
(globalThis.$prommyResult = await new Prommy(returnsPromisePrommy()), globalThis.$prommyPop(), globalThis.$prommyResult)
$p.$pop(await $p.$push(asyncFunction()));
Assert(PrommyContext.current()).toStrictlyBe('root2');
finished2 = true;
}, 'root2');
Expand All @@ -48,7 +95,6 @@ export async function morePrommyUtilityFunctionWorks() {

Assert(finished1).toBeTruthy();
Assert(finished2).toBeTruthy();
Assert(PrommyContext._internalStackLength).toStrictlyBe(0);
}

function tick() {
Expand All @@ -67,7 +113,7 @@ function tick() {
const tickMap: Map<Function, number> = new Map();

function ticks(count: number) {
return new Prommy(resolve => {
tickMap.set(resolve, count);
return Prommy.create(resolve => {
tickMap.set(() => resolve(count), count);
});
}
6 changes: 3 additions & 3 deletions test/tests/test-prommy.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Prommy, PrommyContext, _Internal_Prommy, installPrommy } from "../../src/lib/zone/prommy";
import { Prommy, PrommyContext, installPrommy } from "../../src/lib/zone/prommy";
import { Assert } from "../lib/assert";
import { TestPromise } from "../lib/test-promise";

Expand Down Expand Up @@ -157,13 +157,13 @@ function tick() {
const tickMap: Map<Function, number> = new Map();

function ticks(count: number) {
return _Internal_Prommy.create(resolve => {
return Prommy.create(resolve => {
tickMap.set(resolve, count);
});
}

function rejectAfterTicks(count: number, message: string) {
return _Internal_Prommy.create((resolve, reject) => {
return Prommy.create((resolve, reject) => {
tickMap.set(() => reject(message), count);
});
}

0 comments on commit 5152a04

Please sign in to comment.