{"id":15678175,"url":"https://github.com/minecrawler/result-js","last_synced_at":"2025-05-07T02:26:51.556Z","repository":{"id":143906396,"uuid":"76038891","full_name":"minecrawler/result-js","owner":"minecrawler","description":"Rusty Monad Results for JS","archived":false,"fork":false,"pushed_at":"2020-04-24T23:04:26.000Z","size":139,"stargazers_count":12,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"develop","last_synced_at":"2025-04-28T23:44:22.479Z","etag":null,"topics":["dependency-less","either","either-monad","maybe","monadic-result","node-js","nodejs","result","rusty-monad"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/minecrawler.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2016-12-09T13:44:22.000Z","updated_at":"2021-12-11T18:52:26.000Z","dependencies_parsed_at":null,"dependency_job_id":"fc4b7dc6-76f5-4259-ad78-3d3de17fe70b","html_url":"https://github.com/minecrawler/result-js","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minecrawler%2Fresult-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minecrawler%2Fresult-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minecrawler%2Fresult-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minecrawler%2Fresult-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/minecrawler","download_url":"https://codeload.github.com/minecrawler/result-js/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252800564,"owners_count":21806180,"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":["dependency-less","either","either-monad","maybe","monadic-result","node-js","nodejs","result","rusty-monad"],"created_at":"2024-10-03T16:18:21.375Z","updated_at":"2025-05-07T02:26:51.513Z","avatar_url":"https://github.com/minecrawler.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# result-js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/minecrawler/result-js.svg)](https://greenkeeper.io/)\nRusty Monad Results for JS\n---\n\n[![Build Status](https://travis-ci.org/minecrawler/result-js.svg?branch=master)](https://travis-ci.org/minecrawler/result-js)\n[![Coverage Status](https://coveralls.io/repos/github/minecrawler/result-js/badge.svg)](https://coveralls.io/github/minecrawler/result-js)\n\nStandard JS error management is done via `throw` and `try..catch` statements.\nThey, however, pose the risk that error opportunities are not handled by the user of an API,\nhence pose the risk of fatal runtime errors.\n\nIn order to make a user aware of the risk of failure, monad error management was created.\nOne of the most prominent usages of such a result system is `core::result::Result` of the programming language Rust.\n\nThis module is based on the Rust implementation, but brings some changes in order to better use it in JS.\nOne of the major differences is that result-js uses lowerCamelCase instead of snake_case.\nAdditionally, the methods `ok()`, `err()` and `unwrapOrDefault()` were not implemented, since the former require a Option-dependency and the latter can easily be worked around by providing a default value yourself (using `Result.or()`).\n\n`result-js` does not have any dependencies and conducts unit tests and coverage with `TAP` and `coveralls`.\n\n**You can find the complete API, as defined in code, below the examples!**\n\n\n## Installation\n\n    npm i result-js --save\n\n\n## Simple Example\n\nIn the following example, you can see that the traditional way needs a lot more LoC, the type of myResult is not pinned and you might forget to use `try..catch`.\nThe Result Monad helps to clean this mess up!\n\nFor more simple examples, please take a look at `./test.js`, on which Travis CI and Coveralls tests are based!\n\n```js\n'use strict';\n\n// Traditional way\n\nconst syncButMightFail = () =\u003e {\n\n  throw 'NaY!';\n};\n\nlet myResult = 'YaY';\ntry {\n  myResult = syncButMightFail();\n}\ncatch($e) {\n  console.log($e.toString()); // don't even care...\n}\n\n\n// -------------------------------------\n// With Result\n\n\nconst Result = require('result-js');\n\nconst syncButMightFail = () =\u003e {\n\n  return Result.fromError('NaY!');\n};\n\nconst myResult = syncButMightFail().or('YaY');\n```\n\n\n## Usage\n\n### Create new Result\n\n```js\n'use strict';\n\nconst Result = require('result-js');\n\nconst resultOk = Result.fromSuccess('YaY');\nconst resultErr = Result.fromError('NaY');\n\n// ...\n```\n\n\n### Register Ok() and Err()\n\n```js\n// ...\n\n// After the following line, Ok() and Err() will be available on a global level.\n// That means that you can do stuff, like\n//     return Ok(val);\n//     return Err('failed!');\nResult.registerGlobals();\n\n// ...\n```\n\n\n### Check if Error\n\n```js\n// ...\n\nif (resultOk.isOk() || !resultOk.isErr()) { console.log('Result is OK; this will be visible!'); }\nif (resultErr.isOk() || !resultErr.isErr()) { console.log('Result is OK; this will _not_ be visible!'); }\n```\n\n\n### Get Value\n\n```js\n// ...\n\n// `unwrap` will throw if the Result is an Error\nvar myResult = resultOk.unwrap();\n\n// `expect` will also throw if the Result is an Error, but add a message\nmyResult = resultOk.expect('uh oh!');\n\n// `and` will return the passed value instead of the Ok-value if the Result is not an error\nmyResult = resultOk.and('SURPRISE!');\nmyResult = resultOk.andThen(res =\u003e res + ' for Result!');\n\n\n// `or` will return the passed value instead of the Result's error value in case the Result was an error\nmyResult = resultErr.or('no error any more!');\nmyResult = resultErr.orElse(err =\u003e new Error(err));\n\n// Or just a very simple match, just what you already know from then-ables, like Promises\nresultErr.match(okVal =\u003e {\n  console.log('Since we use the `resultErr` Result, this message will never be visiable!');\n}, errVal =\u003e {\n  console.log('This message will be visible! The error is: ' + errVal);\n});\n```\n\n\n### Control Flow\n\n```js\n// ...\n\nconsole.log(\n  resultOk.andThen(() =\u003e Ok(2)).andThen(val =\u003e val * val)\n);\n// -\u003e 4\n\n\nconsole.log(\n  resultErr.orElse(() =\u003e Ok(3)).andThen(val =\u003e val * val)\n);\n// -\u003e 9\n```\n\n\n## API\n\nAll methods work just as described in the [Rust documentation](https://doc.rust-lang.org/core/result/enum.Result.html).\nThe interface below includes Exceptions, however all methods are fully implemented and will not throw.\nThe Exceptions are in place in order to provide you a clear, non-cluttered API overview.\n\n```js\n/**\n * Rusty Result wrapper\n *\n * @type {Result}\n */\nmodule.exports = class Result {\n    /**\n     * Create success Result with a return value.\n     *\n     * @param {*} val\n     * @returns {Result}\n     */\n    static fromSuccess(val) { throw new Error ('Not Implemented: Result.fromSuccess'); };\n\n    /**\n     * Create error Result with a return value.\n     *\n     * @param {*} err\n     * @returns {Result}\n     */\n    static fromError(err) { throw new Error ('Not Implemented: Result.fromError'); };\n\n    /**\n     * Similar to Rust's `try!`, but only returns a {Result} to the caller\n     *\n     * @param {function} fun Function to execute\n     * @returns {Result}\n     */\n    static fromTry(fun) { throw new Error ('Not Implemented: Result.fromTry'); };\n\n    /**\n     * Register global convenience-functions Ok() and Err()\n     */\n    static registerGlobals() { throw new Error ('Not Implemented: Result.registerGlobals'); };\n\n    /**\n     * Returns true if the result is Ok.\n     *\n     * @returns {boolean}\n     */\n    isOk() { throw new Error ('Not Implemented: Result.isOk'); };\n\n    /**\n     * Returns true if the result is Err.\n     *\n     * @returns {boolean}\n     */\n    isErr() { throw new Error ('Not Implemented: Result.isErr'); };\n\n    /**\n     * Maps a Result\u003cT, E\u003e to Result\u003cU, E\u003e by applying a function to a contained Ok value, leaving an Err value untouched.\n     * This function can be used to compose the results of two functions.\n     *\n     * @param {function} op\n     * @returns {Result}\n     */\n    map(op) { throw new Error ('Not Implemented: Result.map'); };\n\n    /**\n     * Maps a Result\u003cT, E\u003e to Result\u003cT, F\u003e by applying a function to a contained Err value, leaving an Ok value untouched.\n     * This function can be used to pass through a successful result while handling an error.\n     *\n     * @param {function} op\n     * @returns {Result}\n     */\n    mapErr(op) { throw new Error ('Not Implemented: Result.mapErr'); };\n\n    /**\n     * Returns an iterator over the possibly contained value.\n     * The iterator yields one value if the result is Ok, otherwise none.\n     *\n     * @returns {Iterable.\u003c*\u003e}\n     */\n    iter() { throw new Error ('Not Implemented: Result.iter'); };\n\n    /**\n     * Returns `Ok(val)` if the result is Ok, otherwise returns `Err(err)` of itself.\n     *\n     * @param {*} val\n     * @returns {Result}\n     */\n    and(val) { throw new Error ('Not Implemented: Result.and'); };\n\n    /**\n     * Calls `resultEmitter` if the result is Ok, otherwise returns `Err(err)` value of itself.\n     * This function can be used for control flow based on Result values.\n     *\n     * @param {ResultEmitter} resultEmitter\n     * @returns {Result}\n     */\n    andThen(resultEmitter) { throw new Error ('Not Implemented: Result.andThen'); };\n\n    /**\n     * Returns `Ok(val)` if the result is Err, otherwise returns `Ok(ok)` of itself.\n     *\n     * @param {*} val\n     * @returns {Result}\n     */\n    or(val) { throw new Error ('Not Implemented: Result.or'); };\n\n    /**\n     * Calls `resultEmitter` if the result is Err, otherwise returns the `Ok(ok)` value of itself.\n     * This function can be used for control flow based on result values.\n     *\n     * @param {ResultEmitter} resultEmitter\n     * @returns {Result}\n     */\n    orElse(resultEmitter) { throw new Error ('Not Implemented: Result.orElse'); };\n\n    /**\n     * Unwraps a result, yielding the content of an Ok.\n     *\n     * @throws if the value is an Err, with a message provided by the Err's value.\n     * @returns {*}\n     */\n    unwrap() { throw new Error ('Not Implemented: Result.unwrap'); };\n\n    /**\n     * Unwraps a result, yielding the content of optb. Else it throws.\n     *\n     * @param {*} optb\n     * @return {*}\n     */\n    unwrapAnd(optb) { throw new Error ('Not Implemented: Result.unwrapAnd'); };\n\n    /**\n     * Unwraps a result, calling valEmitter with its value. If the value is an Err then it throws.\n     *\n     * @param {ValueEmitter} valEmitter\n     * @return {*}\n     */\n    unwrapAndThen(valEmitter) { throw new Error ('Not Implemented: Result.unwrapAndThen'); };\n\n    /**\n     * Unwraps a result, yielding the content of an Err.\n     *\n     * @throws if the value is an Ok, with a custom panic message provided by the Ok's value.\n     * @returns {*}\n     */\n    unwrapErr() { throw new Error ('Not Implemented: Result.unwrapErr'); };\n\n    /**\n     * Unwraps a result, yielding the content of an Ok. Else it returns optb.\n     *\n     * @param {*} optb\n     * @return {*}\n     */\n    unwrapOr(optb) { throw new Error ('Not Implemented: Result.unwrapOr'); };\n\n    /**\n     * Unwraps a result, yielding the content of an Ok. If the value is an Err then it calls valEmitter with its value.\n     *\n     * @param {ValueEmitter} valEmitter\n     * @return {*}\n     */\n    unwrapOrElse(valEmitter) { throw new Error ('Not Implemented: Result.unwrapOrElse'); };\n\n    /**\n     * Unwraps a result, yielding the content of an Ok.\n     *\n     * @throws if the value is an Err, with a message including the passed message, and the content of the Err.\n     * @param {String} msg\n     * @returns {*}\n     */\n    expect(msg) { throw new Error ('Not Implemented: Result.expect'); };\n\n    /**\n     * Unwraps a result, yielding the content of an Err.\n     *\n     * @throws if the value is an Ok, with a panic message including the passed message, and the content of the Ok.\n     * @param {String} msg\n     * @returns {*}\n     */\n    expectErr(msg) { throw new Error ('Not Implemented: Result.expectErr'); };\n\n    /**\n     * JS convenience then-like handler (sync)\n     *\n     * @param {ResultHandler} okHandler\n     * @param {ResultHandler} errHandler\n     */\n    match(okHandler, errHandler) { throw new Error ('Not Implemented: Result.match'); };\n\n    /**\n     * JS convenience method to handle a result NodeJS-style\n     * Example:\n     * Result.fromError('uh oh!').node((err, val) =\u003e {\n     *   // do sth.\n     * });\n     *\n     * @param {NodeJSStyleHandler} handler\n     */\n    node(handler) { throw 'Not Implemented: Result.node'; };\n};\n\n\n/**\n * This Callback is used to produce a final Result\n *\n * @callback ResultEmitter\n * @param {*} val\n *   `val` will contain the result of {Result}.\n * @returns {*}\n */\n\n/**\n * This Callback is used to produce a final Value\n *\n * @callback ValueEmitter\n * @param {*} val\n *   `val` will contain the result of {Result}.\n * @returns {*}\n */\n\n/**\n * This Callback is used as a return-handler\n *\n * @callback ResultHandler\n * @param {*} ret\n *   `ret` will either contain the result or the error, depending on the parameter position of the callback\n */\n\n/**\n * This callback is used as NodeJS-style handler\n *\n * @callback NodeJSStyleHandler\n * @oaram {*} err null if no error occurred\n * @param {*} val null if an error occurred\n */\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fminecrawler%2Fresult-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fminecrawler%2Fresult-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fminecrawler%2Fresult-js/lists"}