{"id":20165730,"url":"https://github.com/functionalland/functional-redis","last_synced_at":"2025-03-03T03:24:36.741Z","repository":{"id":55455604,"uuid":"318290933","full_name":"functionalland/functional-redis","owner":"functionalland","description":"A simple Redis client in tune with Functional Programming principles in JavaScript for Deno.","archived":false,"fork":false,"pushed_at":"2020-12-29T17:52:31.000Z","size":72,"stargazers_count":2,"open_issues_count":2,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-14T17:03:03.100Z","etag":null,"topics":["deno","denoland","functional","functional-programming","functor","monoid","redis"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/functionalland.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-12-03T18:57:10.000Z","updated_at":"2020-12-29T17:52:33.000Z","dependencies_parsed_at":"2022-08-15T00:40:28.352Z","dependency_job_id":null,"html_url":"https://github.com/functionalland/functional-redis","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/functionalland%2Ffunctional-redis","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/functionalland%2Ffunctional-redis/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/functionalland%2Ffunctional-redis/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/functionalland%2Ffunctional-redis/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/functionalland","download_url":"https://codeload.github.com/functionalland/functional-redis/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241601719,"owners_count":19988967,"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":["deno","denoland","functional","functional-programming","functor","monoid","redis"],"created_at":"2024-11-14T00:38:54.556Z","updated_at":"2025-03-03T03:24:36.721Z","avatar_url":"https://github.com/functionalland.png","language":"JavaScript","readme":"\u003cimg src=\"./.github/fl-logo.svg\" alt=\"Functional Redis\" width=\"450\" /\u003e\n\nA simple Redis client in tune with Functional Programming principles in JavaScript for Deno.\n\n[![deno land](http://img.shields.io/badge/available%20on-deno.land/x-lightgrey.svg?logo=deno\u0026labelColor=black)](https://deno.land/x/functional_redis@v0.3.0)\n[![deno version](https://img.shields.io/badge/deno-^1.6.1-lightgrey?logo=deno)](https://github.com/denoland/deno)\n[![GitHub release](https://img.shields.io/github/v/release/sebastienfilion/functional-redis)](https://github.com/sebastienfilion/functional-redis/releases)\n[![GitHub licence](https://img.shields.io/github/license/sebastienfilion/functional-redis)](https://github.com/sebastienfilion/functional-redis/blob/v0.3.0/LICENSE)\n[![Discord Chat](https://img.shields.io/discord/790708610023555093.svg)](https://discord.gg/)\n\n  * [Redis Request](#redis-request)\n  * [Redis Response](#redis-response)\n  * [Client](#client)\n\n## Usage\n\nFunctional Redis is optimized to write elegant and powerful point-free functions.\nThis example uses the Ramda library - for simplification - but you should be able to use any library that implements the Fantasy-land specifications.\n\n```js\nimport { safeExtract } from \"https://deno.land/x/functional@v1.3.2/library/utilities.js\";\nimport File from \"https://deno.land/x/functional_io@v1.1.0/library/File.js\";\nimport { writeFile } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\nimport RedisRequest from \"https://deno.land/x/functional_redis@v0.3.0/library/RedisRequest.js\";\nimport {\n  createRedisSession,\n  pipeRedisCommand\n} from \"https://deno.land/x/functional_redis@v0.3.0/library/client.js\";\n\nconst copyHogeToFuga = createRedisSession(\n  compose(\n    chain(\n      compose(\n        writeFile({}),\n        concat(File.fromPath(`${Deno.cwd()}/hoge`))\n      )\n    ),\n    pipeRedisCommand(\n      [\n        RedisRequest.set({}, \"hoge\", \"piyo\"),\n        RedisRequest.get(\"hoge\"),\n        RedisRequest.set({}, \"fuga\")\n      ]\n    )\n  )\n);\n\nconst container = await copyHogeToFuga({ port: 6379 }).run();\n\nsafeExtract(\"Failed to execute the request.\", container);\n```\n\n\n\n---\n\n## Redis Request\n\nThe `RedisRequest` represents a Redis request.\nIt has three attributes: the first is the Redis command, the second is a typed array named \"raw\", the last is an\narray of arguments.\nThe `RedisRequest` type is mostly interoperable with `RedisResponse`, [`Resource`](https://github.com/sebastienfilion/functional-io#resource),\n[`File`](https://github.com/sebastienfilion/functional-io#file), [`(HTTP) Request`](https://github.com/sebastienfilion/functional-io#request)  \nand [`(HTTP) Response`](https://github.com/sebastienfilion/functional-io#response).\n\nThe `RedisRequest` type implements the following algebras:\n- [x] Group\n- [x] Comonad\n- [x] Monad\n\n### Example\n\n```js\nimport RedisRequest from \"https://deno.land/x/functional-redis@v0.1.1/library/RedisRequest.js\";\n\nconst redisRequest = RedisRequest(\"GET\", new Uint8Array([]), [ \"hoge\" ]);\n\nassert(RedisRequest.is(redisRequest));\n```  \n\nA Symbol named `rawPlaceholder` may be used as a placeholder for the buffer.\nIn the following example, the request will resolve to: `SET hoge piyo`.\n\n```js\nimport { encodeText } from \"https://deno.land/x/functional@v1.3.2/library/utilities.js\";\nimport RedisRequest from \"https://deno.land/x/functional-redis@v0.1.1/library/RedisRequest.js\";\nimport { $$rawPlaceholder } from \"https://deno.land/x/functional-redis@v0.1.0/library/Symbol.js\";\n\nconst redisRequest = RedisRequest(\"SET\", encodeText(\"piyo\"), [ \"hoge\", $$rawPlaceholder ]);\n\nassert(RedisRequest.is(redisRequest));\n```  \n\nThe placeholder can be used multiple times if the buffer has multiple values separated by CLRF (`\\r\\n`).\n\n```js\nimport { encodeText } from \"https://deno.land/x/functional@v1.3.2/library/utilities.js\";\nimport RedisRequest from \"https://deno.land/x/functional-redis@v0.1.1/library/RedisRequest.js\";\nimport { $$rawPlaceholder } from \"https://deno.land/x/functional-redis@v0.1.0/library/Symbol.js\";\n\nconst redisRequest = RedisRequest(\n  \"MSET\",\n  encodeText(\"piyo\\r\\nfuga\\r\\n\"),\n  [ \"hoge\", $$rawPlaceholder, \"hogefuga\", $$rawPlaceholder ]\n);\n\nassert(RedisRequest.is(redisRequest));\n```  \n\n### Utilities\n\nThe `RedisRequest` namespace comes with methods for convenience to create an instance of `RedisRequest` with various\ncommands. The methods are curried.\n\n#### `factorizeRedisRequest`\n`String → Uint8Array → (String|Symbol)[] → RedisRequest`\n\nThis curried function takes a string for the name of the Redis command, a (optionally empty) `Uint8Array` and, an\narray for the arguments. The return value is an instance of `RedisRequest`.\n\n***\n\n#### String commands\n\n##### RedisRequest`.append` [📕](https://redis.io/commands/append)\n`String → (String|Uint8Array) → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.append(\"hoge\", \"piyo\");\n```\n\n##### RedisRequest`.bitcount` [📕](https://redis.io/commands/bitcount)\n`String → [ Number, Number ] → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.bitcount(\"hoge\", [ 0, 1 ]);\n```\n\n##### RedisRequest`.bitfield` [📕](https://redis.io/commands/bitfield)\n`String → String[] → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.bitfield(\"hoge\", [ \"GET\", \"i8\", 100 ]);\n```\n\n##### RedisRequest`.bitop` [📕](https://redis.io/commands/bitop)\n`String → String → String[] → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.bitop(\"AND\", \"hoge\", [ \"piyo\", \"fuga\" ]);\n```\n\n##### RedisRequest`.bitpos` [📕](https://redis.io/commands/bitpos)\n`String → [ Number, Number ] → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.bitpos(\"hoge\", [ 0, 1 ]);\n```\n\n##### RedisRequest`.decr` [📕](https://redis.io/commands/decr)\n`String → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.decr(\"hoge\");\n```\n\n##### RedisRequest`.decrby` [📕](https://redis.io/commands/decrby)\n`String → Number → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.decrby(\"hoge\", 3);\n```\n\n##### RedisRequest`.get` [📕](https://redis.io/commands/get)\n`String → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.get(\"hoge\");\n```\n\n##### RedisRequest`.getbit` [📕](https://redis.io/commands/getbit)\n`String → Number → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.getbit(\"hoge\", 3);\n```\n\n##### RedisRequest`.getrange` [📕](https://redis.io/commands/getrange)\n`String → [ Number, Number ] → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.getrange(\"hoge\", [ 0, 1 ]);\n```\n\n##### RedisRequest`.getset` [📕](https://redis.io/commands/getset)\n`String → (String|Uint8Array) → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.getset(\"hoge\", \"piyo\");\nconst redisRequestB = RedisRequest.getset(\"hoge\", encodeText(\"piyo\"));\n```\n\n##### RedisRequest`.incr` [📕](https://redis.io/commands/incr)\n`String → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.incr(\"hoge\");\n```\n\n##### RedisRequest`.incrby` [📕](https://redis.io/commands/incrby)\n`String → Number → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.incrby(\"hoge\", 3);\n```\n\n##### RedisRequest`.incrbyfloat` [📕](https://redis.io/commands/incrbyfloat)\n`String → Number → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.incrbyfloat(\"hoge\", 0.1);\n```\n\n##### RedisRequest`.mget` [📕](https://redis.io/commands/mget)\n`(String, ...) → RedisRequest`, or `String[] → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.mget(\"hoge\", \"piyo\");\nconst redisRequestB = RedisRequest.mget([ \"hoge\", \"piyo\" ]);\n```\n\n##### RedisRequest`.mset` [📕](https://redis.io/commands/mset)\n`(String, ...) → RedisRequest`, or `(String|Symbol)[] → Uint8Array → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.mset(\"hoge\", \"piyo\", \"hogefuga\", \"fuga\");\nconst redisRequestB = RedisRequest.mset(\n  [ \"hoge\", $$rawPlaceholder, \"hogefuga\", $$rawPlaceholder ],\n  encodeText(\"piyo\\r\\nfuga\\r\\n\")\n);\n```\n\n##### RedisRequest`.msetnx` [📕](https://redis.io/commands/msetnx)\n`(String, ...) → RedisRequest`, or `(String|Symbol)[] → Uint8Array → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.msetnx(\"hoge\", \"piyo\", \"hogefuga\", \"fuga\");\nconst redisRequestB = RedisRequest.msetnx(\n  [ \"hoge\", $$rawPlaceholder, \"hogefuga\", $$rawPlaceholder ],\n  encodeText(\"piyo\\r\\nfuga\\r\\n\")\n);\n```\n\n##### RedisRequest`.psetex` [📕](https://redis.io/commands/psetex)\n`Number → String → (String|Uint8Array) → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.psetex(1000, \"hoge\", \"piyo\");\nconst redisRequestB = RedisRequest.psetex(1000, \"hoge\", encodeText(\"piyo\"));\n```\n\n##### RedisRequest`.set` [📕](https://redis.io/commands/set)\n`Object → String → (String|Uint8Array) → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.set({}, \"hoge\", \"piyo\");\nconst redisRequestB = RedisRequest.set({}, \"hoge\", encodeText(\"piyo\"));\nconst redisRequestC = RedisRequest.set({ EX: 2000 }, \"hoge\", encodeText(\"piyo\"));\nconst redisRequestD = RedisRequest.set({ KEEPTTL: true }, \"hoge\", encodeText(\"piyo\"));\n```\n\n##### RedisRequest`.setbit` [📕](https://redis.io/commands/setbit)\n`String → Number → Number → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.setbit(\"hoge\", 7, 1);\n```\n\n##### RedisRequest`.setex` [📕](https://redis.io/commands/setex)\n`Number → String → (String|Uint8Array) → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.setex(10, \"hoge\", \"piyo\");\nconst redisRequestB = RedisRequest.setex(10, \"hoge\", encodeText(\"piyo\"));\n```\n\n##### RedisRequest`.setnx` [📕](https://redis.io/commands/setnx)\n`String → (String|Uint8Array) → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.setnx(\"hoge\", \"piyo\");\nconst redisRequestB = RedisRequest.setnx(\"hoge\", encodeText(\"piyo\"));\n```\n\n##### RedisRequest`.setrange` [📕](https://redis.io/commands/setrange)\n`String → Number → (String|Uint8Array) → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.setrange(\"hoge\", 2, \"FU\");\n```\n\n##### RedisRequest`.stralgo` [📕](https://redis.io/commands/stralgo)\n`(String, ...) → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.strlen(\"LCS\", \"KEYS, \"hoge\", \"piyo\");\n```\n\n##### RedisRequest`.strlen` [📕](https://redis.io/commands/strlen)\n`String → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.strlen(\"hoge\");\n```\n\n***\n\n#### Key commands\n\n##### RedisRequest`.copy` [📕](https://redis.io/commands/copy)\n`Object → String → String → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.copy({}, \"hoge\", \"fuga\");\nconst redisRequestB = RedisRequest.copy({ REPLACE: true }, \"hoge\", \"fuga\");\nconst redisRequestC = RedisRequest.copy({ DB: 2 }, \"hoge\", \"fuga\");\n```\n\n##### RedisRequest`.del` [📕](https://redis.io/commands/del)\n`(String, ...) → RedisRequest`, or `String[] → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.del(\"hoge\", \"fuga\");\nconst redisRequestB = RedisRequest.del([ \"hoge\", \"fuga\" ]);\n```\n\n##### RedisRequest`.dump` [📕](https://redis.io/commands/dump)\n`String → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.dump(\"hoge\");\n```\n\n##### RedisRequest`.exists` [📕](https://redis.io/commands/exists)\n`(String, ...) → RedisRequest`, or `String[] → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.exists(\"hoge\", \"fuga\");\nconst redisRequestB = RedisRequest.exists([ \"hoge\", \"fuga\" ]);\n```\n\n##### RedisRequest`.expire` [📕](https://redis.io/commands/expire)\n`Number → String → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.expire(10, \"hoge\");\n```\n\n##### RedisRequest`.expireat` [📕](https://redis.io/commands/expireat)\n`Date|Number → String → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.expireat(new Date(), \"hoge\");\nconst redisRequestB = RedisRequest.expireat(Date.now(), \"hoge\");\n```\n\n##### RedisRequest`.keys` [📕](https://redis.io/commands/keys)\n`String → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.keys(\"*ge\");\n```\n\n##### RedisRequest`.migrate` [📕](https://redis.io/commands/migrate)\n`Object → String|String[] → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.migrate({ host: \"127.0.0.1\", port: 6379, db: 3, timeout: 5000 }, \"hoge\");\nconst redisRequestB = RedisRequest.migrate(\n  { host: \"127.0.0.1\", port: 6379, db: 3, timeout: 5000 },\n  [ \"hoge\", \"fuga\" ]\n);\nconst redisRequestC = RedisRequest.migrate(\n  { host: \"127.0.0.1\", port: 6379, db: 3, timeout: 5000, REPLACE: true },\n  \"hoge\"\n);\nconst redisRequestD = RedisRequest.migrate(\n  { host: \"127.0.0.1\", port: 6379, db: 3, timeout: 5000, password },\n  \"hoge\"\n);\nconst redisRequestE = RedisRequest.migrate(\n  { host: \"127.0.0.1\", port: 6379, db: 3, timeout: 5000, username, password },\n  \"hoge\"\n);\n```\n\n##### RedisRequest`.move` [📕](https://redis.io/commands/move)\n`Number → String → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.move(3, \"hoge\");\n```\n\n##### RedisRequest`.object` [📕](https://redis.io/commands/object)\n`String → String|String[] → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.object(\"ENCODING\", \"hoge\");\nconst redisRequestB = RedisRequest.object(\"ENCODING\", [ \"hoge\" ]);\n```\n\n##### RedisRequest`.persist` [📕](https://redis.io/commands/persist)\n`String → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.persist(\"hoge\");\n```\n\n##### RedisRequest`.pexpireat` [📕](https://redis.io/commands/pexpireat)\n`Date|Number → String → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.pexpireat(new Date(), \"hoge\");\nconst redisRequestB = RedisRequest.pexpireat(Date.now(), \"hoge\");\n```\n\n##### RedisRequest`.pexpire` [📕](https://redis.io/commands/pexpire)\n`Number → String → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.pexpire(5000, \"hoge\");\n```\n\n##### RedisRequest`.ptll` [📕](https://redis.io/commands/ptll)\n`String → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.pttl(\"hoge\");\n```\n\n##### RedisRequest`.randomkey` [📕](https://redis.io/commands/randomkey)\n`String → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.randomkey(\"hoge\");\n```\n\n##### RedisRequest`.rename` [📕](https://redis.io/commands/rename)\n`String → String → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.rename(\"hoge\", \"hogefuga\");\n```\n\n##### RedisRequest`.renamenx` [📕](https://redis.io/commands/renamenx)\n`String → String → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.renamenx(\"hoge\", \"hogefuga\");\n```\n\n##### RedisRequest`.restore` [📕](https://redis.io/commands/restore)\n`Object → String → String|Uint8Array → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.restore(\n  { ttl: 10 },\n  \"hoge\",\n  String.raw`\\u0000\\xC0\\n\\t\\u0000\\xBEm\\u0006\\x89Z(\\u0000\\n`\n);\nconst redisRequestB = RedisRequest.restore(\n  { ttl: 10 },\n  \"hoge\",\n  encodeText(String.raw`\\u0000\\xC0\\n\\t\\u0000\\xBEm\\u0006\\x89Z(\\u0000\\n`)\n);\nconst redisRequestC = RedisRequest.restore(\n  { ttl: 10, REPLACE: true },\n  \"hoge\",\n  String.raw`\\u0000\\xC0\\n\\t\\u0000\\xBEm\\u0006\\x89Z(\\u0000\\n`\n);\nconst redisRequestD = RedisRequest.restore(\n  { ttl: 10, IDLETIME: 1 },\n  \"hoge\",\n  String.raw`\\u0000\\xC0\\n\\t\\u0000\\xBEm\\u0006\\x89Z(\\u0000\\n`\n);\n```\n\n##### RedisRequest`.scan` [📕](https://redis.io/commands/scan)\n`Object → Number → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.scan({}, 0);\nconst redisRequestB = RedisRequest.scan({ MATCH: \"*yo\", COUNT: 1000 }, 0);\n```\n\n##### RedisRequest`.sort` [📕](https://redis.io/commands/migrate)\n`Object → String → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.sort({}, \"hoge\");\nconst redisRequestB = RedisRequest.sort({ BY: \"fuga\" }, \"hoge\");\nconst redisRequestC = RedisRequest.sort({ LIMIT: 10 }, \"hoge\");\nconst redisRequestD = RedisRequest.sort({ ASC: true }, \"hoge\");\nconst redisRequestE = RedisRequest.sort({ DESC: true, ALPHA: true }, \"hoge\");\nconst redisRequestF = RedisRequest.sort({ STORE: \"fuga\" }, \"hoge\");\nconst redisRequestG = RedisRequest.sort({ GET: [ \"*\" ], ALPHA: true }, \"hoge\");\nconst redisRequestH = RedisRequest.sort({ LIMIT: 10, GET: [ \"*\", \"#\" ], ALPHA: true }, \"hoge\");\n```\n\n##### RedisRequest`.touch` [📕](https://redis.io/commands/ptll)\n`String|String[] → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.touch(\"hoge\");\nconst redisRequestB = RedisRequest.touch([ \"hoge\", \"fuga\" ]);\n```\n\n##### RedisRequest`.ttl` [📕](https://redis.io/commands/ttl)\n`String → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.ttl(\"hoge\");\n```\n\n##### RedisRequest`.type` [📕](https://redis.io/commands/type)\n`String → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.type(\"hoge\");\n```\n\n##### RedisRequest`.unlink` [📕](https://redis.io/commands/unlink)\n`String|String[] → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.unlink(\"hoge\");\nconst redisRequestB = RedisRequest.unlink([ \"hoge\", \"fuga\" ]);\n```\n\n##### RedisRequest`.wait` [📕](https://redis.io/commands/wait)\n`Number → Number → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.wait(1,10);\n```\n\n***\n\n#### Hash commands\n\n##### RedisRequest`.hdel` [📕](https://redis.io/commands/hdel)\n`String → String|String[] → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.hdel(\"hoge\", \"piyo\");\nconst redisRequestB = RedisRequest.hdel(\"hoge\", [ \"piyo\", \"fuga\" ]);\n```\n\n##### RedisRequest`.hexists` [📕](https://redis.io/commands/hexists)\n`String → String → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.hexists(\"hoge\", \"piyo\");\n```\n\n##### RedisRequest`.hget` [📕](https://redis.io/commands/hget)\n`String → String → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.hget(\"hoge\", \"piyo\");\n```\n\n##### RedisRequest`.hgetall` [📕](https://redis.io/commands/hgetall)\n`String → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.hgetall(\"hoge\");\n```\n\n##### RedisRequest`.hincrby` [📕](https://redis.io/commands/hincrby)\n`String → Number → String → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.hincrby(\"hoge\", 3, \"piyo\");\n```\n\n##### RedisRequest`.hincrbyfloat` [📕](https://redis.io/commands/hincrbyfloat)\n`String → Number → String → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.hincrbyfloat(\"hoge\", 0.1, \"piyo\");\nconst redisRequestB = RedisRequest.hincrbyfloat(\"hoge\", -5, \"piyo\");\nconst redisRequestC = RedisRequest.hincrbyfloat(\"hoge\", 5.0e3, \"piyo\");\n```\n\n##### RedisRequest`.hkeys` [📕](https://redis.io/commands/hkeys)\n`String → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.hkeys(\"hoge\");\n```\n\n##### RedisRequest`.hlen` [📕](https://redis.io/commands/hlen)\n`String → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.hlen(\"hoge\");\n```\n\n##### RedisRequest`.hmget` [📕](https://redis.io/commands/hmget)\n`String → String|String[] → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.hmget(\"hoge\", \"piyo\");\nconst redisRequestB = RedisRequest.hmget(\"hoge\", [ \"piyo\", \"fuga\" ]);\n```\n\n##### RedisRequest`.hmset` [📕](https://redis.io/commands/hmset)\n`String → String → String|Uint8Array → RedisRequest` or, `String → String[] → Uint8Array → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.hmset(\"hoge\", \"piyo\", \"fuga\");\nconst redisRequestB = RedisRequest.hmset(\"hoge\", \"piyo\", encodeText(\"fuga\"));\nconst redisRequestC = RedisRequest.hmset(\n  \"hoge\",\n  [ \"piyo\", $$rawPlaceholder, \"fuga\", $$rawPlaceholder ],\n  encodeText(\"hogepiyo\\r\\nhogefuga\\r\\n\")\n);\n```\n\n##### RedisRequest`.hscan` [📕](https://redis.io/commands/hscan)\n`Object → String → Number → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.hscan({}, \"hoge\", 0);\nconst redisRequestB = RedisRequest.hscan({ MATCH: \"*yo\", COUNT: 1000 }, \"hoge\", 0);\n```\n\n##### RedisRequest`.hset` [📕](https://redis.io/commands/hset)\n`String → String → (String|Uint8Array) → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.hset(\"hoge\", \"piyo\", \"fuga\");\nconst redisRequestB = RedisRequest.hset(\"hoge\", \"piyo\", encodeText(\"fuga\"));\n```\n\n##### RedisRequest`.hsetnx` [📕](https://redis.io/commands/hsetnx)\n`String → String → (String|Uint8Array) → RedisRequest`\n\n```js\nconst redisRequestA = RedisRequest.hsetnx(\"hoge\", \"piyo\", \"fuga\");\nconst redisRequestB = RedisRequest.hsetnx(\"hoge\", \"piyo\", encodeText(\"fuga\"));\n```\n\n##### RedisRequest`.hstrlen` [📕](https://redis.io/commands/hstrlen)\n`String → String → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.hstrlen(\"hoge\", \"piyo\");\n```\n\n##### RedisRequest`.hvals` [📕](https://redis.io/commands/hvals)\n`String → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.hvals(\"hoge\");\n```\n\n***\n\n#### Server commands\n\n##### RedisRequest`.flushall` [📕](https://redis.io/commands/flushall)\n`() → RedisRequest`\n\n```js\nconst redisRequest = RedisRequest.flushall();\n```\n\n---\n\n## Redis Response\n\nThe `RedisResponse` represents a Redis response.\nIt has only one argument, a typed array named \"raw\".\nThe `RedisResponse` type is mostly interoperable with `RedisRequest`, [`Resource`](https://github.com/sebastienfilion/functional-io#resource),\n[`File`](https://github.com/sebastienfilion/functional-io#file), [`(HTTP) Request`](https://github.com/sebastienfilion/functional-io#request)\nand [`(HTTP) Response`](https://github.com/sebastienfilion/functional-io#response).\n\nThe `RedisResponse` type implements the following algebras:\n- [x] Alternative\n- [x] Group\n- [x] Comonad\n- [x] Monad\n\n### Example\n\n```js\nimport RedisResponse from \"https://deno.land/x/functional-redis@v0.1.1/library/RedisResponse.js\";\n\nconst redisResponse = RedisResponse.Success(new Uint8Array([]));\n\nassert(RedisResponse.is(redisResponse));\n```\n\n### Utilities\n\n#### `factorizeRedisResponseSuccess`\n`Uint8Array → RedisResponse.Success`\n\n#### `factorizeRedisResponseFailure`\n`Uint8Array → RedisResponse.Failure`\n\n---\n\n## Client\n\nThe client module provides various utility functions to interact with a Redis server.\n\n### `decodeRedisResponse`\n`RedisResponse → *`\n\nThis functions takes a `RedisResponse` and, returns the most appropriate JavaScript primitive.\nFor example, [string command's](https://redis.io/commands#string) response would return a string and,\n[hash command's](https://redis.io/commands#hash) response would return an array...\n\n### `parseRedisResponse`\n`RedisResponse → Buffer`\n\nThis functions takes a `RedisResponse` and, returns a `Buffer` which can be interoperated cleanly with `RedisRequest`,\n[`Resource`](https://github.com/sebastienfilion/functional-io#resource),\n[`File`](https://github.com/sebastienfilion/functional-io#file) and,\n[`(HTTP) Request`](https://github.com/sebastienfilion/functional-io#request).\n\n### `connectRedisClient`\n`Object → Task Resource`\n\nThis function takes an object for the connection options and, return a\n[`Task`](https://github.com/sebastienfilion/functional#task-type) of a `Resource`.\n\n```js\nimport { connectRedisClient } from \"https://deno.land/x/functional_redis@v0.3.0/library/client.js\";\n\nconst container = await connectRedisClient({ port: 6379 }).run();\nconst redisResource = safeExtract(\"Failed to connect the client.\", container);\n```\n\n### `disconnectRedisClient`\n`Resource → Task Resource`\n\nThis function takes a Resource and, return a\n[`Task`](https://github.com/sebastienfilion/functional#task-type) of a `Resource`.\n\n```js\nimport { disconnectRedisClient } from \"https://deno.land/x/functional_redis@v0.3.0/library/client.js\";\n\nawait disconnectRedisClient(redisResource).run();\n```\n\n### `executeRedisCommand`\n`RedisRequest → Resource → Task RedisResponse`\n\nThis curried function accepts a `RedisRequest` and a `Resource` that represents a connection to the Redis server\nand, returns a [`Task`](https://github.com/sebastienfilion/functional#task-type) of a `RedisResponse`.\n\n```js\nimport { safeExtract } from \"https://deno.land/x/functional@v1.3.2/library/utilities.js\";\nimport { executeRedisCommand } from \"https://deno.land/x/functional_redis@v0.3.0/library/client.js\";\nimport RedisRequest from \"https://deno.land/x/functional_redis@v0.3.0/library/RedisRequest.js\";\nimport RedisResponse from \"https://deno.land/x/functional_redis@v0.3.0/library/RedisResponse.js\";\n\nconst container = await executeRedisCommand(\n  RedisRequest.set({}, \"hoge\", \"piyo\"),\n  redisResource\n).run();\nconst redisResponse = safeExtract(\"Failed to execute the command..\", container);\n\nassert(RedisResponse.is(redisResponse));\n```\n\n### `executeRedisCommandPipeline`\n`RedisRequest[] → Resource → Task RedisResponse[]`\n\nThis curried function accepts an array of `RedisRequest` and, a `Resource` that represents a connection to the Redis\nserver. The function returns a [`Task`](https://github.com/sebastienfilion/functional#task-type) of an array of\n`RedisResponse`.\n*Do not confuse this function with `pipeRedisCommand`; the term \"pipeline\" refers to the\n[ability of a Redis server](https://redis.io/topics/pipelining) to parse multiple request at a time.*\n\n```js\nimport { safeExtract } from \"https://deno.land/x/functional@v1.3.2/library/utilities.js\";\nimport { executeRedisCommandPipeline } from \"https://deno.land/x/functional_redis@v0.3.0/library/client.js\";\nimport RedisRequest from \"https://deno.land/x/functional_redis@v0.3.0/library/RedisRequest.js\";\nimport RedisResponse from \"https://deno.land/x/functional_redis@v0.3.0/library/RedisResponse.js\";\n\nconst container = await executeRedisCommandPipeline(\n  [\n    RedisRequest.set({}, \"hoge\", \"piyo\"),\n    RedisRequest.get(\"hoge\")\n  ],\n  redisResource\n).run();\nconst redisResponseList = safeExtract(\"Failed to execute the command..\", container);\n\nassert(redisResponseList.every(RedisResponse.is));\n```\n\n### `createRedisSession`\n`(Resource → Task *) → Object → Task Resource`\n\nThis function takes an unary function that accepts a `Resource` that represents a connection to the Redis server and,\nReturn a [`Task`](https://github.com/sebastienfilion/functional#task-type).\n\nThis functions will sequentially connect to the Redis server, execute the unary function and, finally disconnect.\n\n```js\nconst setHoge = createRedisSession(executeRedisCommand(RedisRequest.set({}, \"hoge\", \"piyo\")));\n\nconst container = await setHoge({ port: 6379 }).run();\n\nsafeExtract(\"Failed to read the response.\", container);\n```\n\nThe function resolves to a `Task` of the `Resource`; if you need to access the `RedisResponse`, the unary function\nshould compose with the handler.\n\n```js\nimport { safeExtract } from \"https://deno.land/x/functional@v1.3.2/library/utilities.js\";\nimport File from \"https://deno.land/x/functional_io@v1.1.0/library/File.js\";\nimport { writeFile } from \"https://deno.land/x/functional_io@v1.1.0/library/fs.js\";\nimport {\n  createRedisSession,\n  executeRedisCommand\n} from \"https://deno.land/x/functional_redis@v0.3.0/library/client.js\";\nimport RedisRequest from \"https://deno.land/x/functional_redis@v0.3.0/library/RedisRequest.js\";\n\nconst writeHogeToFile = createRedisSession(\n  compose(\n    chain(\n      compose(\n        writeFile({}),\n        concat(File.fromPath(`${Deno.cwd()}/hoge`)),\n        parseRedisResponse\n      )\n    ),\n    executeRedisCommand(RedisRequest.get(\"hoge\"))\n  )\n);\n\nconst containerB = await writeHogeToFile({ port: 6379 }).run();\n\nsafeExtract(\"Failed to read the response.\", containerB);\n```\n\n### `executeRedisCommandWithSession`\n`Object → RedisRequest → Task RedisResponse`\n\nThis curried function accepts an object for the options of the connection and, a `RedisRequest`. The return value is\na [`Task`](https://github.com/sebastienfilion/functional#task-type) of a `RedisResponse`.\n\nThis is a convenience function that composes `createRedisSession` and `executeRedisCommand`\n\n```js\nimport { safeExtract } from \"https://deno.land/x/functional@v1.3.2/library/utilities.js\";\nimport { executeRedisCommandWithSession } from \"https://deno.land/x/functional_redis@v0.3.0/library/client.js\";\nimport RedisRequest from \"https://deno.land/x/functional_redis@v0.3.0/library/RedisRequest.js\";\n\nconst container = await executeRedisCommandWithSession(\n  { port: 6379 },\n  RedisRequest(\"SET\", new Uint8Array([]), [ \"hoge\", \"piyo\" ])\n).run();\n\nsafeExtract(\"Failed to read the response.\", container);\n````\n\n### `pipeRedisCommand`\n`(RedisRequest|(* → RedisRequest))[] → Resource → Task RedisResponse`\n\nThis curried function accepts an array of `RedisRequest` or a function that would return a `RedisRequest` and, a\n`Resource` that represents a connection to the Redis server. The return value is a\n[`Task`](https://github.com/sebastienfilion/functional#task-type) of the `RedisResponse` of the last `RedisRequest`.\n\nThis function will execute all Redis requests sequentially and optionally pipe the previous response into the next\nrequest.\n\n```js\nimport { safeExtract } from \"https://deno.land/x/functional@v1.3.2/library/utilities.js\";\nimport {\n  createRedisSession,\n  pipeRedisCommand\n} from \"https://deno.land/x/functional_redis@v0.3.0/library/client.js\";\nimport RedisRequest from \"https://deno.land/x/functional_redis@v0.3.0/library/RedisRequest.js\";\n\nconst copyHogeToFuga = createRedisSession(\n  compose(\n    pipeRedisCommand(\n      [\n        RedisRequest.set({}, \"hoge\", \"piyo\"),\n        RedisRequest.get(\"hoge\"),\n        RedisRequest.set({}, \"fuga\")\n      ]\n    )\n  )\n);\n\nconst container = await copyHogeToFuga({ port: 6379 }).run();\n\nsafeExtract(\"Failed to read the response.\", container);\n```\n\n*This example works because `RedisRequest.set` is a curried function that requires 3 arguments and, returns a\n`RedisRequest`.*\n\n---\n\n## Contributing\n\nWe appreciate your help! Please, [read the guidelines](./CONTRIBUTING.md).\n\n## License\n\nMIT License\n\nCopyright © 2020 - Sebastien Filion\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated\ndocumentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the\nrights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit\npersons to whom the Software is furnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the\nSoftware.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\nWARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\nOTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffunctionalland%2Ffunctional-redis","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffunctionalland%2Ffunctional-redis","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffunctionalland%2Ffunctional-redis/lists"}