https://github.com/menduz/fp-future
A Future is a placeholder object for a value that may not yet exist
https://github.com/menduz/fp-future
fp future typescript
Last synced: about 2 months ago
JSON representation
A Future is a placeholder object for a value that may not yet exist
- Host: GitHub
- URL: https://github.com/menduz/fp-future
- Owner: menduz
- Created: 2018-12-17T20:27:36.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2023-04-30T02:15:25.000Z (about 2 years ago)
- Last Synced: 2025-03-28T12:11:06.957Z (2 months ago)
- Topics: fp, future, typescript
- Language: TypeScript
- Homepage:
- Size: 22.5 KB
- Stars: 6
- Watchers: 1
- Forks: 1
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
> **A Future is a placeholder object for a value that may not yet exist**
Futures are well [known data structures](https://en.wikipedia.org/wiki/Futures_and_promises), at it's core, futures, are simply promises. This simple package exposes a simple interface on top of promises to leverage a them as boxed value placeholders.
# Installation
```bash
npm install fp-future
```# Interface
```ts
function future(): IFuture;type IFuture = Promise & {
resolve: (x: T) => void;
reject: (x: Error) => void;
finally: (fn: () => void) => void;
isPending: boolean;
}
```# Usage
## Futures are awaitable
```ts
const loading = future()loading.resolve(123)
assert(await loading == 123)
```## Futures are awaitable and can be rejected
```ts
const loading = future()loading.reject(new Error('It did fail'))
try {
await loading
} catch(e) {
assert(e.message == 'It did fail')
}
```## Promisify is easy too
```ts
const loadingFuture = future()
// load(successCallback, errorCallback)
load(loadingFuture.resolve, loadingFuture.reject)await loadingFuture
```
## Blackbox testing has never been easier (to read)
It is useful for blackbox testing without _weird injections_ and other magical things.
```ts
it("executes the callback", async () => {
const didClickFuture = future();// happy path
entity.onClick(clickId => {
didClickFuture.resolve(clickId);
// ^^^^^^^^^^^^^^
// Here we resolve the future with a click
});// unhappy path
setTimeout(() => {
didClickFuture.reject(new Error("Timeout"))
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Timeout, just in case we don't receive the event
}, 1000);// Generate synthetic event and trigger the event
const clickId = Math.random()
entity.triggerClick(clickId);// Await the value or fail!
const receivedNonce = await somethingToBeResolved;// Assertion
expect(receivedNonce).toEq(clickId);
});
```## Async-awaitable injection of scripts in an HTML
```ts
async function injectScript(url: string) {
const theFuture = future();
const theScript = document.createElement("script");
theScript.src = url;
theScript.async = true;
theScript.type = "application/javascript";
theScript.addEventListener("load", theFuture.resolve);
theScript.addEventListener("error", e => theFuture.reject(e.error));
document.body.appendChild(theScript);
return theFuture;
}async function main() {
await injectScript("https://www.gstatic.com/firebasejs/7.12.0/firebase-app.js");
await injectScript("https://www.gstatic.com/firebasejs/7.12.0/firebase-analytics.js");
await injectScript("https://www.gstatic.com/firebasejs/7.12.0/firebase-auth.js");// use the injected scripts
firebase.initializeApp(firebaseConfig);
firebase.analytics();
}```
## Load image data
```ts
async function loadImageData(src: string): Promise {
const futureColors = future();var img = new Image();
img.crossOrigin = "Anonymous"
img.onload = function() {
var imageData = loadingContext.getImageData(0, 0, img.width, img.height);futureColors.resolve(imageData);
};img.src = src;
return futureColors;
}
```