{"id":18062813,"url":"https://github.com/ded/valentine","last_synced_at":"2025-04-05T21:08:31.571Z","repository":{"id":57390106,"uuid":"1597490","full_name":"ded/valentine","owner":"ded","description":"JavaScripts Functional Sister","archived":false,"fork":false,"pushed_at":"2015-07-20T18:29:31.000Z","size":400,"stargazers_count":286,"open_issues_count":3,"forks_count":21,"subscribers_count":12,"default_branch":"master","last_synced_at":"2024-04-13T21:55:02.600Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/ded.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}},"created_at":"2011-04-11T04:59:38.000Z","updated_at":"2024-03-06T14:55:54.000Z","dependencies_parsed_at":"2022-09-15T05:21:30.417Z","dependency_job_id":null,"html_url":"https://github.com/ded/valentine","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ded%2Fvalentine","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ded%2Fvalentine/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ded%2Fvalentine/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ded%2Fvalentine/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ded","download_url":"https://codeload.github.com/ded/valentine/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247399877,"owners_count":20932876,"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":[],"created_at":"2024-10-31T05:08:31.047Z","updated_at":"2025-04-05T21:08:31.542Z","avatar_url":"https://github.com/ded.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"    \\  / _. |  _  ._ _|_ o ._   _\n     \\/ (_| | (/_ | | |_ | | | (/_\n\n[![Build Status](https://secure.travis-ci.org/ded/valentine.png)](http://travis-ci.org/ded/valentine)\nJavaScript's Sister, and protector — inspired by Underscore; Valentine provides you with type checking, functional iterators, and common utility helpers such as waterfalls, queues, and parallels; all utilizing native JavaScript methods for optimal speed.\n\n## Deprecation notice\n\nAs of version `2.0.0` — Valentine no longer supports `\u003c= IE8` and `\u003c= Safari 4`. It's been real, but time to move on. To access this level of support, use the [1.8 tag](https://github.com/ded/valentine/tree/v1.8.0).\n\n### Browser usage:\n\n``` html\n\u003cscript src=\"valentine.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n  v.forEach(['a', 'b', 'c'], function (letter) {\n\n  })\n\u003c/script\u003e\n```\n\n### Node users\n\n``` sh\nnpm install valentine\n```\n\n``` js\nvar v = require('valentine')\n\n// showcase object style\nv(['a', 'b', 'c']).map(function (letter) {\n  return letter.toUpperCase()\n}).join(' '); // =\u003e 'A B C'\n```\n\n## API\n\n\n\u003ch3\u003eiterators\u003c/h3\u003e\n\n  * v.each(array || object, callback[, scope]) =\u003e void\n  * v.map(array || object, callback[, scope]) =\u003e array\n  * v.every(array || object, *callback[, scope]) =\u003e boolean\n  * v.some(array || object, *callback[, scope]) =\u003e boolean\n  * v.filter(array || object, *callback[, scope]) =\u003e array || object\n\n  * v.reject(ar, *callback[, scope])\n  * v.indexOf(ar, item[, start])\n  * v.lastIndexOf(ar, item[, start])\n  * v.reduce(ar, **callback, memo[, scope])\n  * v.reduceRight(ar, **callback, memo[, scope])\n\n*`callback` is defined as:\n\n``` js\n// when array\nfunction callback(item, index, array) {\n\n}\n// when object\nfunction callback(key, value, object) {\n\n}\n```\n\n**`calback` is defined as:\n\n``` js\nfunction callback(memo, item, index, array) {\n\n}\n```\n\n### utility\n\n  * v.extend(obj[, obj2[, obj3[...]]]) =\u003e object\n  * v.merge(ar1, ar2) =\u003e array (ar1 modified)\n  * v.pluck(array||object, key) =\u003e array\n  * v.toArray(sparse) =\u003e array (duh)\n  * v.size(array) =\u003e number\n  * v.find(array, key) =\u003e *value\n  * v.compact(array) =\u003e array\n  * v.flatten(array) =\u003e array\n  * v.uniq(array) =\u003e array\n  * v.first(array) =\u003e *value\n  * v.last(array) =\u003e *value\n  * v.keys(object) =\u003e array\n  * v.values(object) =\u003e array\n  * v.trim(string) =\u003e string\n  * v.bind(scope, fn, [curried args]) =\u003e function\n  * v.curry(fn, [curried args]) =\u003e function\n  * v.inArray(array, needle) =\u003e boolean\n  * v.memo(fn, hasher) =\u003e function\n\n``` js\n// use memo to cache expensive methods\nvar getAllTheDom = v.memo(function () {\n  return v(document.getElementsByTagName('*')).toArray()\n})\ngetAllTheDom().each(modifier)\n```\n\n#### parallel api\n\n  * v.parallel([fn args]) =\u003e void\n\n``` js\nv.parallel(\n  function (fn) {\n    getTimeline(function (e, timeline) {\n      fn(e, timeline)\n    })\n  }\n, function (fn) {\n    getUser(function (e, user) {\n      fn(e, user)\n    })\n  }\n, function (e, timeline, user) {\n    if (e) return console.log(e)\n    ok(timeline == 'one', 'first result is \"one\"')\n    ok(user == 'two', 'second result is \"two\"')\n  }\n)\n```\n\n#### waterfall api\n\n  * v.waterfall([fn args])\n  * v.waterfall([fn1, fn2\u003c, fn3\u003e], callback)\n\n``` js\nv.waterfall(\n  function (callback) {\n    callback(null, 'one', 'two')\n  }\n, function (a, b, callback) {\n    console.log(a == 'one')\n    console.log(b == 'two')\n    callback(null, 'three')\n  }\n, function (c, callback) {\n    console.log(c == 'three')\n    callback(null, 'final result')\n  }\n, function (err, result) {\n    console.log(!!err == false)\n    console.log(result == 'final result')\n  }\n)\n```\n\n#### series api\n  * similar to `waterfall` except passing along args to next function is not a concern\n  * v.series([fn1, fn2\u003c, fn3\u003e], callback)\n\n``` js\nv.series([\n  function (callback) {\n    setTimeout(callback, 2000)\n  }\n, function (callback) {\n    process.nextTick(callback)\n  }\n, function (callback) {\n    callback(null)\n  }]\n, function (err) {\n    console.log('done')\n  }\n)\n```\n\n#### Queue api\n\n  * v.queue([fn args])\n\n``` js\nvar it = v.queue(\n  function () {\n    console.log('one')\n    it.next()\n  }\n, function () {\n    console.log('two')\n    it.next()\n  }\n, function () {\n    console.log('three')\n  }\n)\nit.next()\n```\n\n#### throttle, debounce, throttleDebounce\n\n  * v.throttle(ms, fn, opt_scope) =\u003e function\n  * v.debounce(ms, fn, opt_scope) =\u003e function\n  * v.throttleDebounce(throttleMs, debounceMs, fn, opt_scope) =\u003e function\n\n``` js\nwindow.onscroll = v.throttle(50, function (e) {\n  // expensive scroll function\n})\n\nwindow.mousemove = v.debounce(500, function (e) {\n  // user has paused momentarily\n})\n\ntextarea.onkeypress = v.throttleDebounce(20000, 1000, function () {\n  // autosave(this.value)\n  // called after 1s if not called again within 1s\n  // but guaranteed to be called within 20s\n})\n```\n\n#### type checking\nEach method returns a boolean\n\n  * v.is.func(o)\n  * v.is.string(o)\n  * v.is.element(o)\n  * v.is.array(o)\n  * v.is.arrLike(o)\n  * v.is.num(o)\n  * v.is.bool(o)\n  * v.is.args(o)\n  * v.is.empty(o)\n  * v.is.date(o)\n  * v.is.nan(o)\n  * v.is.nil(o)\n  * v.is.undef(o)\n  * is.regexp(o)\n  * v.is.obj(o)\n\n### Object Style\n\n``` js\nv(['a', 'b', 'c']).map(function (letter) {\n  return letter.toUpperCase()\n}); // =\u003e ['A', 'B', 'C']\n```\n\n### Chains\n\n``` js\nv(['a', 'b', [['c']], 0, false,,,null,['a', 'b', 'c']])\n  .chain().flatten().compact().uniq().map(function (letter) {\n    return letter.toUpperCase()\n  }).value(); // =\u003e ['A', 'B', 'C']\n```\n\n## Ender Support\n\n``` sh\nender add valentine\n```\n\n``` js\n\n// available as a top level method on `$`\n$.v(['a', ['virus'], 'b', 'c']).reject(function (el, i) {\n  return $.is.arr(el[i])\n})\n\n// top level methods in bridge\n$.each\n  map\n  merge\n  extend\n  toArray\n  keys\n  values\n  trim\n  bind\n  curry\n  parallel\n  waterfall\n  inArray\n  queue\n```\n\nOr just require the valentine module\n\n``` js\n!function (v) {\n  v(['a', ['virus'], 'b', 'c']).reject(function (el, i) {\n    return v.is.arr(el[i])\n  })\n}(require('valentine'))\n```\n\n## Developers\nCare to contribute? Make your edits to `src/valentine.js` and get your environment up and running\n\n``` sh\nnpm install\nmake\nmake test\nopen tests/index.html\n```\n\n*Happy iterating*!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fded%2Fvalentine","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fded%2Fvalentine","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fded%2Fvalentine/lists"}