{"id":15690046,"url":"https://github.com/minecrawler/roption-js","last_synced_at":"2025-10-19T11:18:05.266Z","repository":{"id":143906906,"uuid":"92293216","full_name":"minecrawler/roption-js","owner":"minecrawler","description":"Rusty Monad Options for JS","archived":false,"fork":false,"pushed_at":"2020-04-24T23:07:06.000Z","size":78,"stargazers_count":8,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"develop","last_synced_at":"2025-03-31T15:08:39.745Z","etag":null,"topics":["dependency-less","javascript","monad","monadic-optionals","node-js","node-module","nodejs","rust","rust-lang"],"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":"2017-05-24T13:06:50.000Z","updated_at":"2023-04-18T00:51:19.000Z","dependencies_parsed_at":null,"dependency_job_id":"59642460-5304-4c17-aa64-46907208ce81","html_url":"https://github.com/minecrawler/roption-js","commit_stats":{"total_commits":6,"total_committers":2,"mean_commits":3.0,"dds":"0.33333333333333337","last_synced_commit":"de6c3acab34d9fa6a95104e5c4ccb5a1a76ec49e"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minecrawler%2Froption-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minecrawler%2Froption-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minecrawler%2Froption-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/minecrawler%2Froption-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/minecrawler","download_url":"https://codeload.github.com/minecrawler/roption-js/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252968860,"owners_count":21833369,"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","javascript","monad","monadic-optionals","node-js","node-module","nodejs","rust","rust-lang"],"created_at":"2024-10-03T18:06:44.634Z","updated_at":"2025-10-06T10:26:39.579Z","avatar_url":"https://github.com/minecrawler.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# option-js\n\n[![Greenkeeper badge](https://badges.greenkeeper.io/minecrawler/roption-js.svg)](https://greenkeeper.io/)\nRusty Monad Options for JS\n---\n\n[![Build Status](https://travis-ci.org/minecrawler/option-js.svg?branch=master)](https://travis-ci.org/minecrawler/result-js)\n[![Coverage Status](https://coveralls.io/repos/github/minecrawler/option-js/badge.svg)](https://coveralls.io/github/minecrawler/result-js)\n\nEveryone knows that when dealing with data, sometimes there is nothing to pass or nothing to return.\nUsually, in JS, we have to decide for either `undefined` or `null`, but also sometimes `NaN` and similar.\n\nIn order to simplify this problem, monadic options were created, which can either contain a value, or not.\nOne of the most prominent usages of such an option system is `core::option::Option` 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 option-js uses lowerCamelCase instead of snake_case.\nAdditionally, the methods involving `std::result::Result` were not implemented, since they require a Result-dependency.\n\n`option-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 option-js --save\n\n\n## Simple Example\n\nIn the following example, you can see that the traditional way needs a lot more LoC and might lead to errors.\nThe Option 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\nreadFromDB(rows =\u003e {\n  // would you remember to check this in every situation?\n  if (\n    typeof rows !== 'undefined' \u0026\u0026\n    rows !== null \u0026\u0026\n    rows.length \u003e 0\n  ) {\n    return;\n  }\n\n  processDBRow(rows[0]);\n});\n\n\n// -------------------------------------\n// With Option\n\n\nconst Option = require('option-js');\n\nreadFromDB(result =\u003e {\n  const rows = Option.fromGuess(result);\n  if (rows.isSome()) {\n    processDBRow(rows.unwrap()[0]);\n  }\n});\n```\n\n\n## Usage\n\n### Create new Result\n\n```js\n'use strict';\n\nconst Option = require('option-js');\n\nconst hasSome = Option.fromSome('YaY');\nconst hasNone = Option.fromNone();\n\n// ...\n```\n\n\n### Register Some() and None()\n\n```js\n// ...\n\n// After the following line, Some() and None() will be available on a global level.\n// That means that you can do stuff, like\n//     return Some(val);\n//     return None();\nOption.registerGlobals();\n\n// ...\n```\n\n\n### Check if contains value\n\n```js\n// ...\n\nif (hasSome.isSome() || !hasSome.isNone()) { console.log('Option is Some; this will be visible!'); }\nif (hasNone.isNone() || !hasNone.isSome()) { console.log('Option is None; this will _not_ be visible!'); }\n\n// ...\n```\n\n\n### Get Value\n\n```js\n// ...\n\n// `unwrap` will throw if the Option is None\nvar myResult = hasSome.unwrap();\n\n// `expect` will also throw if the Option is None, but add a message\nmyResult = hasSome.expect('uh oh!');\n\n// `and` will return the passed value instead of the Some-value if the Option is not None\nmyResult = hasSome.and('SURPRISE!');\nmyResult = hasSome.andThen(res =\u003e res + ' for Result!');\n\n\n// `or` will return the passed value in case the Option is None\nmyResult = hasNone.or('some value');\nmyResult = hasNone.orElse(() =\u003e 'a value~');\n\n// Or just a very simple match\nhasNone.match(val =\u003e {\n  console.log('Since we use the `hasNone` Option, this message will never be visiable!');\n}, () =\u003e {\n  console.log('This message will be visible!');\n});\n```\n\n\n## API\n\nAll methods work just as described in the [Rust documentation](https://doc.rust-lang.org/core/option/enum.Option.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 Monad Options for JS\n *\n * @type {Option}\n */\nmodule.exports = class Option {\n    /**\n     * Construct a new Option Object from a value as Some(value)\n     * If no value is passed, the option will contain None\n     *\n     * @param {boolean} isSome\n     * @param {*} val\n     */\n    constructor(isSome, val) { this._init(isSome, val); };\n\n    /**\n     * Create Some(val)\n     *\n     * @param {*} val\n     * @returns {Option}\n     */\n    static fromSome(val) { return new Option(true, val); };\n\n    /**\n     * Create None\n     *\n     * @returns {Option}\n     */\n    static fromNone() { return new Option(false, null); };\n\n    /**\n     * Create an Option from a value.\n     * An algorithm takes a guess if it should be a Some or a None.\n     * Empty arrays will be transformed to None\n     *\n     * @param {*} val\n     * @returns {Option}\n     */\n    static fromGuess(val) { throw new Error ('Not Implemented: Option.fromGuess'); };\n\n    /**\n     * Register Some and None on a global scope\n     */\n    static registerGlobals() { throw new Error ('Not Implemented: Option.registerGlobals'); };\n\n    /**\n     * Returns true if the option is a Some value.\n     *\n     * @returns {boolean}\n     */\n    isSome() { throw new Error ('Not Implemented: Option.isSome'); };\n\n    /**\n     * Returns true if the option is a None value.\n     *\n     * @returns {boolean}\n     */\n    isNone() { throw new Error ('Not Implemented: Option.isNone'); };\n\n    /**\n     * Unwraps an option, yielding the content of a Some.\n     *\n     * @throws if the value is a None with a custom panic message provided by msg.\n     * @param {string} msg\n     * @returns {*}\n     */\n    expect(msg) { throw new Error ('Not Implemented: Option.expect'); };\n\n    /**\n     * Moves the value v out of the Option\u003cT\u003e if it is Some(v).\n     * In general, because this function may panic, its use is discouraged.\n     * Instead, prefer to use pattern matching and handle the None case explicitly.\n     *\n     * @throws if the self value equals None.\n     * @returns {*}\n     */\n    unwrap() { throw new Error ('Not Implemented: Option.unwrap'); };\n\n    /**\n     * Maps an Option\u003cT\u003e to Option\u003cU\u003e by applying a function to a contained value.\n     *\n     * @param {OptionMap} f\n     * @returns {Option}\n     */\n    map(f) { throw new Error ('Not Implemented: Option.map'); };\n\n    /**\n     * Returns an iterator over the possibly contained value.\n     *\n     * @returns {Iterable.\u003c*\u003e}\n     */\n    iter() { throw new Error ('Not Implemented: Option.iter'); };\n\n    /**\n     * Returns None if the option is None, otherwise returns optb.\n     *\n     * @param {*} optb\n     * @returns {*}\n     */\n    and(optb) { throw new Error ('Not Implemented: Option.and'); };\n\n    /**\n     * Returns None if the option is None, otherwise calls f with the wrapped value and returns the result.\n     *\n     * @param {OptionAndThenHandler} f\n     * @returns {*}\n     */\n    andThen(f) { throw new Error ('Not Implemented: Option.andThen'); };\n\n    /**\n     * Returns the option if it contains a value, otherwise returns optb.\n     *\n     * @param {*} optb\n     * @returns {*}\n     */\n    or(optb) { throw new Error ('Not Implemented: Option.or'); };\n\n    /**\n     * Returns the option if it contains a value, otherwise calls f and returns the result.\n     *\n     * @param {OptionOrElseHandler} f\n     * @returns {*}\n     */\n    orElse(f) { throw new Error ('Not Implemented: Option.orElse'); };\n\n    /**\n     * Takes the value out of the option, leaving a None in its place.\n     *\n     * @returns {Option}\n     */\n    take() { throw new Error ('Not Implemented: Option.isSome'); };\n\n    /**\n     * JS convenience method then-like handler for pattern-matching\n     *\n     * @param {OptionSomeHandler} someHandler\n     * @param {OptionNoneHandler} noneHandler\n     */\n    match(someHandler, noneHandler) { throw new Error ('Not Implemented: Option.match'); };\n\n    /**\n     * JS convenience method to handle a result NodeJS-style\n     * Example:\n     * Option.fromNone().node((err, val) =\u003e {\n     *   // do sth.\n     * });\n     *\n     * @param {OptionNodeJSStyleHandler} f\n     */\n    node(f) { throw new Error ('Not Implemented: Option.node'); };\n};\n\n/**\n * This Callback is used to map over an Option\n *\n * @callback OptionMap\n * @param {*} val\n *   `val` will contain the Some-part of {Option}.\n * @returns {*} New Some-part\n */\n\n/**\n * This Callback is used to handle andThen calls\n *\n * @callback OptionAndThenHandler\n * @param {*} val\n *   `val` will contain the Some-part of {Option}.\n * @returns {*}\n */\n\n/**\n * This Callback is used to handle orElse calls\n * It has to generate a new value\n *\n * @callback OptionOrElseHandler\n * @returns {*}\n */\n\n/**\n * This Callback is used to handle pattern-matching calls\n *\n * @callback OptionSomeHandler\n * @param {*} val\n *   `val` will contain the Some-part of {Option}.\n * @returns {*}\n */\n\n/**\n * This Callback is used to handle pattern-matching calls\n *\n * @callback OptionNoneHandler\n * @returns {*}\n */\n\n/**\n * This callback is used as NodeJS-style handler\n *\n * @callback OptionNodeJSStyleHandler\n * @oaram {*} err true if Option contains None, else it's null\n * @param {*} val contains Some-part, else it's null\n */\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fminecrawler%2Froption-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fminecrawler%2Froption-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fminecrawler%2Froption-js/lists"}