{"id":17356616,"url":"https://github.com/menduz/fp-future","last_synced_at":"2025-04-15T00:09:01.128Z","repository":{"id":57241169,"uuid":"162186012","full_name":"menduz/fp-future","owner":"menduz","description":"A Future is a placeholder object for a value that may not yet exist","archived":false,"fork":false,"pushed_at":"2023-04-30T02:15:25.000Z","size":23,"stargazers_count":6,"open_issues_count":2,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-28T12:11:06.957Z","etag":null,"topics":["fp","future","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/menduz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-12-17T20:27:36.000Z","updated_at":"2022-10-19T12:18:20.000Z","dependencies_parsed_at":"2024-06-18T18:43:12.965Z","dependency_job_id":"9cee267a-f276-4a4f-bd64-061cfa22cc93","html_url":"https://github.com/menduz/fp-future","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/menduz%2Ffp-future","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/menduz%2Ffp-future/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/menduz%2Ffp-future/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/menduz%2Ffp-future/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/menduz","download_url":"https://codeload.github.com/menduz/fp-future/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248664235,"owners_count":21141917,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fp","future","typescript"],"created_at":"2024-10-15T18:57:35.899Z","updated_at":"2025-04-15T00:09:01.043Z","avatar_url":"https://github.com/menduz.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n\n\u003e **A Future is a placeholder object for a value that may not yet exist**\n\nFutures 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.  \n\n# Installation\n\n```bash\nnpm install fp-future\n```\n\n# Interface\n\n```ts\nfunction future\u003cT\u003e(): IFuture\u003cT\u003e;\n\ntype IFuture\u003cT\u003e = Promise\u003cT\u003e \u0026 {\n  resolve: (x: T) =\u003e void;\n  reject: (x: Error) =\u003e void;\n  finally: (fn: () =\u003e void) =\u003e void;\n  isPending: boolean;\n}\n```\n\n# Usage\n\n## Futures are awaitable\n\n```ts\nconst loading = future()\n\nloading.resolve(123)\n\nassert(await loading == 123)\n```\n\n## Futures are awaitable and can be rejected\n\n```ts\nconst loading = future()\n\nloading.reject(new Error('It did fail'))\n\ntry {\n  await loading\n} catch(e) {\n  assert(e.message == 'It did fail')\n}\n```\n\n## Promisify is easy too\n\n```ts\n\nconst loadingFuture = future()\n\n// load(successCallback, errorCallback)\n   load(loadingFuture.resolve, loadingFuture.reject)\n\nawait loadingFuture\n\n```\n\n## Blackbox testing has never been easier (to read)\n\nIt is useful for blackbox testing without _weird injections_ and other magical things.\n\n```ts\nit(\"executes the callback\", async () =\u003e {\n  const didClickFuture = future();\n\n  // happy path\n  entity.onClick(clickId =\u003e {\n    didClickFuture.resolve(clickId);\n    //             ^^^^^^^^^^^^^^ \n    //             Here we resolve the future with a click\n  });\n\n  // unhappy path\n  setTimeout(() =\u003e {\n    didClickFuture.reject(new Error(\"Timeout\"))\n    //             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n    //             Timeout, just in case we don't receive the event\n  }, 1000);\n\n  // Generate synthetic event and trigger the event\n  const clickId = Math.random()\n  entity.triggerClick(clickId);\n\n  // Await the value or fail!\n  const receivedNonce = await somethingToBeResolved;\n\n  // Assertion\n  expect(receivedNonce).toEq(clickId);\n});\n```\n\n## Async-awaitable injection of scripts in an HTML\n\n```ts\nasync function injectScript(url: string) {\n  const theFuture = future\u003cEvent\u003e();\n  const theScript = document.createElement(\"script\");\n  theScript.src = url;\n  theScript.async = true;\n  theScript.type = \"application/javascript\";\n  theScript.addEventListener(\"load\", theFuture.resolve);\n  theScript.addEventListener(\"error\", e =\u003e theFuture.reject(e.error));\n  document.body.appendChild(theScript);\n  return theFuture;\n}\n\nasync function main() {\n  await injectScript(\"https://www.gstatic.com/firebasejs/7.12.0/firebase-app.js\");\n  await injectScript(\"https://www.gstatic.com/firebasejs/7.12.0/firebase-analytics.js\");\n  await injectScript(\"https://www.gstatic.com/firebasejs/7.12.0/firebase-auth.js\");\n\n  // use the injected scripts\n  firebase.initializeApp(firebaseConfig);\n  firebase.analytics();\n}\n\n```\n\n## Load image data\n\n```ts\nasync function loadImageData(src: string): Promise\u003cImageData\u003e {\n  const futureColors = future\u003cImageData\u003e();\n\n  var img = new Image();\n  img.crossOrigin = \"Anonymous\"\n  img.onload = function() {\n    var imageData = loadingContext.getImageData(0, 0, img.width, img.height);\n\n    futureColors.resolve(imageData);\n  };\n\n  img.src = src;\n\n  return futureColors;\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmenduz%2Ffp-future","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmenduz%2Ffp-future","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmenduz%2Ffp-future/lists"}