{"id":17668652,"url":"https://github.com/evanshortiss/expeditious","last_synced_at":"2025-10-06T04:53:41.700Z","repository":{"id":66153832,"uuid":"62477434","full_name":"evanshortiss/expeditious","owner":"evanshortiss","description":"caching interface for node.js with support for multiple storage engines","archived":false,"fork":false,"pushed_at":"2023-01-09T21:16:32.000Z","size":22,"stargazers_count":7,"open_issues_count":6,"forks_count":5,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-08T22:44:38.875Z","etag":null,"topics":["cache","caching","callback","expeditious","node-module","nodejs","storage-engine"],"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/evanshortiss.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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-07-03T02:06:03.000Z","updated_at":"2023-03-05T07:22:18.000Z","dependencies_parsed_at":"2023-05-04T06:04:25.096Z","dependency_job_id":null,"html_url":"https://github.com/evanshortiss/expeditious","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/evanshortiss/expeditious","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evanshortiss%2Fexpeditious","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evanshortiss%2Fexpeditious/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evanshortiss%2Fexpeditious/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evanshortiss%2Fexpeditious/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/evanshortiss","download_url":"https://codeload.github.com/evanshortiss/expeditious/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/evanshortiss%2Fexpeditious/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271090504,"owners_count":24697616,"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","status":"online","status_checked_at":"2025-08-19T02:00:09.176Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["cache","caching","callback","expeditious","node-module","nodejs","storage-engine"],"created_at":"2024-10-23T23:23:20.351Z","updated_at":"2025-10-06T04:53:36.679Z","avatar_url":"https://github.com/evanshortiss.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"expeditious\n===========\n![TravisCI](https://travis-ci.org/evanshortiss/expeditious.svg) [![npm version](https://badge.fury.io/js/expeditious.svg)](https://badge.fury.io/js/expeditious) [![Coverage Status](https://coveralls.io/repos/github/evanshortiss/expeditious/badge.svg?branch=master)](https://coveralls.io/github/evanshortiss/expeditious?branch=master)\n\nexpeditious is a generic caching API that can read/write key value pairs\nfrom/to compatible caching \"engines\". Engines enable you to easily switch cache\nstorage providers e.g from in node.js memory cache to redis, if desired.\n\n\n## Install\nYou know the drill...\n\n```\nnpm install expeditious --save\n```\n\n## Example\n\n```js\nvar expeditious = require('expeditious');\n\nvar words = expeditious({\n  namespace: 'words',\n  engine: require('expeditious-engine-memory')(),\n  defaultTtl: (60 * 1000)\n});\n\nwords.set({\n  key: 'fáilte',\n  val: 'An Irish Gaelic word meaning \"hello\"'\n}, function (err) {\n  if (err) {\n    console.error('failed to set item in the words cache');\n  } else {\n    console.log('added an item to the words cache')\n  }\n});\n```\n\n## Debugging\nIf you need some debug logging from this module then it can be enabled using\na `DEBUG` environment variable. This is because we use the `debug` module for\nlogging.\n\nHere's the general format:\n\n```\nexport DEBUG=expeditious@$EXPEDITIOUS_VERSION-$NAMESPACE\n```\n\nFor example, if you were using expeditious 0.2.0 had a logger with the namespace\n_users_ then the following would allow it to write debug logs:\n\n```\nexport DEBUG=expeditious@0.2.0-users\n```\n\nAlternatively you can enable logging for all 0.2.0 loggers like so:\n\n```\nexport DEBUG=expeditious@0.2.0-*\n```\n\n## API\n\n### expeditious.ExpeditiousEngine\nThe base class/constructor that can be used to create your own engines. More\ninfo is provided below in the _Custom Storage Engines_ section.\n\n### expeditious(opts)\n_require-ing_ expeditious returns a factory function that can be called to\ncreate an expeditious instance. _opts_ must be an Object and can contain the\nfollowing keys:\n\n* namespace  ([String] Required) - namespace for keys. Used to avoid clashes\nwith other expeditious instances that might be using the same _opts.engine_.\n* engine     ([String] Required) - _ExpeditiousEngine_ that communicates with\nthe underlying cache datastore\n* defaultTtl ([Number] Required) - number of milliseconds to wait before\nconsidering an entry expired\n* objectMode ([Boolean] Optional) - Determines if this expeditious instance\nshould automatically attempt to _JSON.parse_ and _JSON.stringify_ entries on\n_set_ and _get_ calls. This will be performed safely, so if an exception occurs\nit will be returned as the _err_ param.\n\n### instance\nEvery instance function accepts a params Object. set/get/del/ttl functions require _params.key_. Each function\naccepts a callback that is called with the typical _fn(err, res)_ pattern in\nnode.js.\n\n#### instance.set(params[, callback])\nSet an item in the underlying cache store, having an optional callback\ntriggered on success or failure. _params.key_ should be a String and\n_params.val_ should be an Object or String depending on the _objectMode_ flag.\n\n#### instance.get(params, callback)\nGet an item from the cache. _params_ requires a _key_ option that should be a\nString.\n\n#### instance.keys(params, callback)\nFetch all keys in the cache. No params are supported yet, but we include it for\nfuture support.\n\n#### instance.ttl(params, callback)\nGet the remaining milliseconds before the cache entry identified by\n_params.key_ expires. Returns null as the result if _params.key_ does not exist.\n\n#### instance.flush(params[, callback])\nFlush all keys from the cache. Similar to _instance.keys_, no params are\nsupported yet, but we include it for future support.\n\n#### instance.del(params[, callback])\nDelete a cache entry identified by _params.key_. Callback will be passed an\nError if one occurred.\n\n\n## Examples\n\n### String Mode\nBy default expeditious expects to receive String values to _set_ calls, and it\nwill return _String_ values too. An example is below:\n\n```js\nvar expeditious = require('expeditious');\n\nvar words = expeditious({\n  // Namespace cache entries to minimise (hopefully completely avoid) conflicts\n  namespace: 'words',\n\n  // The engine used to cache items. Here we use an engine that stores\n  // items in process memory - in production you might use redis etc.\n  engine: require('expeditious-engine-memory')(),\n\n  // The default timeout for items written to cache. 1 minute here (60 seconds)\n  defaultTtl: (60 * 1000)\n});\n\nwords.set({\n  key: 'fáilte',\n  val: 'An Irish Gaelic word meaning \"hello\"'\n}, onItemSet);\n\nfunction onItemSet (err) {\n  if (err) {\n    console.log('failed to set definition for \"fáilte\"');\n  } else {\n    loadItem();\n  }\n}\n\nfunction loadItem () {\n  words.get({\n    key: 'fáilte'\n  }, function (err, definitionStr) {\n    if (err) {\n      console.error('hmm, we failed to load definition for \"fáilte\"');\n    } else {\n      console.log('here is definition for the word \"fáilte\"', definitionStr);\n    }\n  });\n}\n```\n\n### Object Mode\nOptionally you can enable _objectMode_ when using expeditious to have it\nseamlessly convert items to and from JSON format as demonstrated below.\n\n```js\nvar expeditious = require('expeditious');\n\nvar words = expeditious({\n  namespace: 'words',\n  engine: require('expeditious-engine-memory')(),\n  defaultTtl: (60 * 1000),\n\n  // Tells expeditious that items being \"set\" should be JSON.strigify-d and\n  // \"get\" should be JSON.parse-d for this particular instance\n  objectMode: true\n});\n\n// Add some data with the key \"fáilte\"\nwords.set({\n  key: 'fáilte',\n  val: {\n    definition: 'An Irish Gaelic word meaning \"hello\"'\n  }\n}, onItemSet);\n\nfunction onItemSet (err) {\n  if (err) {\n    console.log('failed to set data for \"fáilte\"');\n  } else {\n    // Load the item back from the cache\n    loadItem();\n  }\n}\n\nfunction loadItem () {\n  words.get({\n    key: 'fáilte'\n  }, function (err, definitionJson) {\n    if (err) {\n      console.error('hmm, we failed to load json for \"fáilte\"');\n    } else {\n      console.log('here is json for the word \"fáilte\"', definitionJson);\n    }\n  });\n}\n```\n\n\n## Storage Engines\nAn engine is an implementation of the _ExpeditiousEngine_ constructor.\nTypically an engine will use a database, Redis, or process memory to store\ndata, but you can create an engine to store any data format.\n\n### Existing Engines\nHere's a list of existing engines that you can use right now:\n\n* expeditious-engine-memory\n\n### Custom Engines\nYou can create a custom engine by inheriting from _ExpeditiousEngine_ and\nimplementing the required functions. If a function is not implemented in your\nsubclass it will use the default behaviour of returning an error stating that\nthe called function is not implemented.\n\nBelow is an example of an incomplete custom engine. For the full prototype\ndefinition see the [Engine constructor](https://github.com/evanshortiss/expeditious/blob/master/lib/expeditious-engine.js)\n\n```js\nvar ExpeditiousEngine = require('expeditious').ExpeditiousEngine;\nvar util = require('util');\n\nfunction CustomEngine (opts) {\n  ExpeditiousEngine.call(this);\n\n  this.entries = {};\n}\nutil.inherits(CustomEngine, ExpeditiousEngine);\n\nmodule.exports = CustomEngine;\n\nCustomEngine.prototype.get = function (namespacedKey, callback) {\n  /* get the value for the given key from the data store */\n  callback(null, this.entries[namespacedKey].value);\n};\n\nCustomEngine.prototype.set = function (namespacedKey, val, exp, callback) {\n  var self = this;\n\n  self.entries[namespacedKey] = {\n    value: val\n  };\n\n  setTimeout(function () {\n    delete self.entries[namespacedKey];\n  }, exp);\n\n  // Cached successfully!\n  callback(null);\n};\n```\n\n## Contributing\nContributions are always welcome, just open a PR and add/fix tests for new/changed functionality. If you are unsure about a PR you have in mind, then open an issue for discussion.\n\n## Changelog\n\n* 1.0.0 - Initial stable release. No API changes from 0.2.0.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevanshortiss%2Fexpeditious","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fevanshortiss%2Fexpeditious","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fevanshortiss%2Fexpeditious/lists"}