@lowerdeck/programmable-promise 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +11 -0
- package/.turbo/turbo-test.log +24 -0
- package/README.md +57 -0
- package/package.json +31 -0
- package/src/index.test.ts +32 -0
- package/src/index.ts +30 -0
- package/tsconfig.json +13 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
|
|
2
|
+
[0m[2m[35m$[0m [2m[1mmicrobundle[0m
|
|
3
|
+
[34mBuild "@lowerdeck/programmable-promise" to dist:[39m
|
|
4
|
+
[32m482 B[39m: [37mindex.cjs[39m.gz
|
|
5
|
+
[32m417 B[39m: [37mindex.cjs[39m.br
|
|
6
|
+
[32m173 B[39m: [37mindex.modern.js[39m.gz
|
|
7
|
+
[32m148 B[39m: [37mindex.modern.js[39m.br
|
|
8
|
+
[32m487 B[39m: [37mindex.module.js[39m.gz
|
|
9
|
+
[32m418 B[39m: [37mindex.module.js[39m.br
|
|
10
|
+
[32m555 B[39m: [37mindex.umd.js[39m.gz
|
|
11
|
+
[32m480 B[39m: [37mindex.umd.js[39m.br
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
[0m[2m[35m$[0m [2m[1mvitest run --passWithNoTests[0m
|
|
3
|
+
[?25l
|
|
4
|
+
[1m[46m RUN [49m[22m [36mv3.2.4 [39m[90m/Users/tobias/code/metorial/metorial-enterprise/oss/src/packages/shared/programmable-promise[39m
|
|
5
|
+
|
|
6
|
+
[?2026h
|
|
7
|
+
[1m[33m ❯ [39m[22msrc/index.test.ts[2m [queued][22m
|
|
8
|
+
|
|
9
|
+
[2m Test Files [22m[1m[32m0 passed[39m[22m[90m (1)[39m
|
|
10
|
+
[2m Tests [22m[1m[32m0 passed[39m[22m[90m (0)[39m
|
|
11
|
+
[2m Start at [22m10:23:27
|
|
12
|
+
[2m Duration [22m101ms
|
|
13
|
+
[?2026l[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K [32m✓[39m src/index.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 3[2mms[22m[39m
|
|
14
|
+
[32m✓[39m ProgrammablePromise[2m > [22mshould resolve with the provided value[32m 1[2mms[22m[39m
|
|
15
|
+
[32m✓[39m ProgrammablePromise[2m > [22mshould reject with the provided reason[32m 1[2mms[22m[39m
|
|
16
|
+
[32m✓[39m ProgrammablePromise[2m > [22mshould allow accessing the resolved value after resolution[32m 0[2mms[22m[39m
|
|
17
|
+
[32m✓[39m ProgrammablePromise[2m > [22mshould not have a value before resolution[32m 0[2mms[22m[39m
|
|
18
|
+
|
|
19
|
+
[2m Test Files [22m [1m[32m1 passed[39m[22m[90m (1)[39m
|
|
20
|
+
[2m Tests [22m [1m[32m4 passed[39m[22m[90m (4)[39m
|
|
21
|
+
[2m Start at [22m 10:23:27
|
|
22
|
+
[2m Duration [22m 217ms[2m (transform 29ms, setup 0ms, collect 28ms, tests 3ms, environment 0ms, prepare 41ms)[22m
|
|
23
|
+
|
|
24
|
+
[?25h
|
package/README.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# `@lowerdeck/programmable-promise`
|
|
2
|
+
|
|
3
|
+
Promise with externally controllable resolve and reject. Allows you to create a promise and settle it from outside, useful for complex control flow patterns.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @lowerdeck/programmable-promise
|
|
9
|
+
yarn add @lowerdeck/programmable-promise
|
|
10
|
+
bun add @lowerdeck/programmable-promise
|
|
11
|
+
pnpm add @lowerdeck/programmable-promise
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
import { ProgrammablePromise } from '@lowerdeck/programmable-promise';
|
|
18
|
+
|
|
19
|
+
// Create a promise you can control externally
|
|
20
|
+
const pp = new ProgrammablePromise<string>();
|
|
21
|
+
|
|
22
|
+
// Pass the promise around
|
|
23
|
+
setTimeout(() => {
|
|
24
|
+
pp.resolve('Hello!');
|
|
25
|
+
}, 1000);
|
|
26
|
+
|
|
27
|
+
const result = await pp.promise;
|
|
28
|
+
console.log(result); // 'Hello!'
|
|
29
|
+
|
|
30
|
+
// Useful for event-driven flows
|
|
31
|
+
class EventHandler {
|
|
32
|
+
private completion = new ProgrammablePromise<void>();
|
|
33
|
+
|
|
34
|
+
onComplete() {
|
|
35
|
+
return this.completion.promise;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
handleEvent(event: Event) {
|
|
39
|
+
if (event.type === 'done') {
|
|
40
|
+
this.completion.resolve();
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Access resolved value without awaiting
|
|
46
|
+
const pp2 = new ProgrammablePromise<number>();
|
|
47
|
+
pp2.resolve(42);
|
|
48
|
+
console.log(pp2.value); // 42
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## License
|
|
52
|
+
|
|
53
|
+
This project is licensed under the Apache License 2.0.
|
|
54
|
+
|
|
55
|
+
<div align="center">
|
|
56
|
+
<sub>Built with ❤️ by <a href="https://metorial.com">Metorial</a></sub>
|
|
57
|
+
</div>
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lowerdeck/programmable-promise",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
7
|
+
"author": "Tobias Herber",
|
|
8
|
+
"license": "Apache 2",
|
|
9
|
+
"type": "module",
|
|
10
|
+
"source": "src/index.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
"require": "./dist/index.cjs",
|
|
13
|
+
"default": "./dist/index.modern.js"
|
|
14
|
+
},
|
|
15
|
+
"main": "./dist/index.cjs",
|
|
16
|
+
"module": "./dist/index.module.js",
|
|
17
|
+
"types": "dist/index.d.ts",
|
|
18
|
+
"unpkg": "./dist/index.umd.js",
|
|
19
|
+
"scripts": {
|
|
20
|
+
"test": "vitest run --passWithNoTests",
|
|
21
|
+
"lint": "prettier src/**/*.ts --check",
|
|
22
|
+
"build": "microbundle"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"microbundle": "^0.15.1",
|
|
27
|
+
"@lowerdeck/tsconfig": "^1.0.0",
|
|
28
|
+
"typescript": "^5.8.3",
|
|
29
|
+
"vitest": "^3.1.2"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { ProgrammablePromise } from './index';
|
|
3
|
+
|
|
4
|
+
describe('ProgrammablePromise', () => {
|
|
5
|
+
it('should resolve with the provided value', async () => {
|
|
6
|
+
const promise = new ProgrammablePromise<number>();
|
|
7
|
+
promise.resolve(42);
|
|
8
|
+
const result = await promise.promise;
|
|
9
|
+
expect(result).toBe(42);
|
|
10
|
+
expect(promise.value).toBe(42);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
it('should reject with the provided reason', async () => {
|
|
14
|
+
const promise = new ProgrammablePromise<number>();
|
|
15
|
+
const error = new Error('Test error');
|
|
16
|
+
promise.reject(error);
|
|
17
|
+
|
|
18
|
+
await expect(promise.promise).rejects.toThrow('Test error');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('should allow accessing the resolved value after resolution', async () => {
|
|
22
|
+
const promise = new ProgrammablePromise<string>();
|
|
23
|
+
promise.resolve('Hello, world!');
|
|
24
|
+
await promise.promise;
|
|
25
|
+
expect(promise.value).toBe('Hello, world!');
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('should not have a value before resolution', () => {
|
|
29
|
+
const promise = new ProgrammablePromise<number>();
|
|
30
|
+
expect(promise.value).toBeUndefined();
|
|
31
|
+
});
|
|
32
|
+
});
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export class ProgrammablePromise<T> {
|
|
2
|
+
private _resolve!: (value: T | PromiseLike<T>) => void;
|
|
3
|
+
private _reject!: (reason?: any) => void;
|
|
4
|
+
private _promise: Promise<T>;
|
|
5
|
+
private _value!: T;
|
|
6
|
+
|
|
7
|
+
constructor() {
|
|
8
|
+
this._promise = new Promise<T>((resolve, reject) => {
|
|
9
|
+
this._resolve = resolve;
|
|
10
|
+
this._reject = reject;
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
get promise() {
|
|
15
|
+
return this._promise;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
resolve(value: T | PromiseLike<T>) {
|
|
19
|
+
this._resolve(value);
|
|
20
|
+
this._value = value as T;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
get reject() {
|
|
24
|
+
return this._reject;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
get value() {
|
|
28
|
+
return this._value;
|
|
29
|
+
}
|
|
30
|
+
}
|