{"id":18110846,"url":"https://github.com/miserylee/layered-cache-loader","last_synced_at":"2025-04-06T07:46:33.282Z","repository":{"id":47914217,"uuid":"234838810","full_name":"miserylee/layered-cache-loader","owner":"miserylee","description":"Add cache layers based on dataloader.","archived":false,"fork":false,"pushed_at":"2021-08-11T22:02:21.000Z","size":115,"stargazers_count":0,"open_issues_count":4,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-17T04:04:55.326Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","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/miserylee.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":"2020-01-19T04:12:15.000Z","updated_at":"2020-01-19T04:16:28.000Z","dependencies_parsed_at":"2022-08-20T05:00:30.329Z","dependency_job_id":null,"html_url":"https://github.com/miserylee/layered-cache-loader","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miserylee%2Flayered-cache-loader","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miserylee%2Flayered-cache-loader/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miserylee%2Flayered-cache-loader/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/miserylee%2Flayered-cache-loader/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/miserylee","download_url":"https://codeload.github.com/miserylee/layered-cache-loader/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247451624,"owners_count":20940946,"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-11-01T00:12:10.708Z","updated_at":"2025-04-06T07:46:33.253Z","avatar_url":"https://github.com/miserylee.png","language":"TypeScript","readme":"# layered-cache-loader\n\n##  ![NPM version](https://img.shields.io/npm/v/layered-cache-loader.svg?style=flat)\n\n\n# 这是什么？\n\n`layered-cache-loader`是一个基于[dataloader](https://github.com/graphql/dataloader)的多级缓存解决方案。\n\n# 怎么使用？\n\n```js\n// 创建内存缓存层\nconst layer1 = new MemoryLayer\u003cstring, string\u003e();\n// 创建Redis缓存层\nconst layer2 = new RedisLayer\u003cstring, string\u003e({\n  uri: 'redis://localhost:6379',\n  ttl: 10000,\n});\n// 创建数据源\nconst finalMap = new Map\u003cstring, string\u003e([\n  ['foo', 'bar'],\n  ['foo2', 'hahaha'],\n  ['hello', 'world'],\n]);\n// 创建loader，并逐个use缓存层（先use的层距离最近，所以建议越快的缓存层越先use）\nconst layeredCacheLoader = new LayeredCacheLoader\u003cstring, string\u003e()\n  .use(layer1)\n  .use(layer2)\n  .final(async keys =\u003e keys.map(key =\u003e finalMap.get(key) ?? new Error('Value not found.'))); // 未命中任何缓存的情况下，从final loader读取数据\nconst results = await layeredCacheLoader.loadMany(['foo', 'foo2', 'hello']); // 使用dataloader的数据读取方案，详情可以查看dataloader文档\nassert(results[0] === 'bar');\nassert(results[1] === 'hahaha');\nassert(results[2] === 'world');\n```\n\n# API定义\n\n## `LayeredCacheLoader\u003cK, V\u003e`\n\n`K`：`key`值的类型；\n\n`V`: `value`值的类型；\n\n#### `ICacheLayer\u003cK, V\u003e`\n\n```js\nexport interface ICacheLayer\u003cK, V\u003e {\n  batchGet(keys: readonly K[]): Promise\u003cArray\u003cV | Error\u003e\u003e;\n\n  batchSet(map: Map\u003cK, V\u003e): void;\n}\n```\n自定义缓存层按照`ICacheLayer\u003cK, V\u003e`定义\n\n#### `LayeredCacheLoader().use(layer: ICacheLayer\u003cK, V\u003e): this`\n\n使用`use`来配置缓存层，先配置的层距离结果返回最近，建议速度越快的缓存层越先配置。\n\n#### `LayeredCacheLoader().final(batchLoadFn: BatchLoadFn\u003cK, V\u003e): this`\n\n使用`final`来配置最终数据源，当`key`没有命中任何缓存层的情况下，会从`final loader`读取数据。例：在`batchLoadFn`中从`Mongodb`或`Mysql`读取原始数据。\n\n`final`可多次调用，以最后一次调用为准。\n\n#### `LayeredCacheLoader().load(key: K): Promise\u003cV\u003e`\n\n同`dataloader.load`。\n\n#### `LayeredCacheLoader().loadMany(keys: K[]): Promise\u003cArray\u003c(V | Error)\u003e\u003e`\n\n同`dataloader.loadMany`。\n\n## `MemoryLayer\u003cK, V, CK = K\u003e`\n\n`K`：`key`值的类型；\n\n`V`: `value`值的类型；\n\n`CK`: 缓存的`key`的类型；\n\n#### `IMemoryLayerOptions\u003cK, V, CK\u003e`\n\n```js\nexport interface IMemoryLayerOptions\u003cK, V, CK\u003e {\n  ttl?: number; // 缓存存活时间（毫秒），默认为Infinity，即永不过期\n\n  keyFn?(key: K): CK; // key到cacheKey的转换函数\n}\n```\n\n#### `MemoryLayer(options: IMemoryLayerOptions\u003cK, V, CK\u003e = {})`\n\n构造一个基于内存的缓存层对象。\n\n#### `readonly MemoryLayer().map: TTLMap\u003cK, V\u003e`\n\n内存缓存层用于存储数据的`TTLMap`对象，`TTLMap`见后文。\n\n## `RedisLayer\u003cK, V\u003e`\n\n`K`：`key`值的类型；\n\n`V`: `value`值的类型；\n\n#### `IRedisLayerOptions\u003cK, V\u003e`\n\n```js\nexport interface IRedisLayerOptions\u003cK, V\u003e {\n  uri: string; // redis连接uri\n  keyPrefix?: string; // 存储到redis中的key的附加前缀（命名空间），默认为'cacheloader'\n  ttl?: number; // 缓存存货时间（毫秒），默认为Infinity，即永不过期\n\n  keyFn?(key: K): string;  // key到cacheKey的转换函数\n\n  serializer?(value: V): string; // 序列化函数，默认为JSON.stringify\n\n  deserializer?(data: string): V | Error; // 反序列化函数，默认为JSON.parse\n}\n```\n\n#### `RedisLayer(options: IRedisLayerOptions\u003cK, V\u003e)`\n\n构造一个基于Redis的缓存层对象。\n\n#### `readonly RedisLayer().redis: IORedis.Redis`\n\n`redis`缓存层内部使用的`Redis`对象。\n\n## `TTLMap\u003cK, V\u003e extends Map\u003cK, V\u003e`\n\n`K`：`key`值的类型；\n\n`V`: `value`值的类型；\n\n带有`ttl(tive to live)`的`Map`。\n\n#### `TTLMap().setTTL(key: K, value: V, ttl: number): this`\n\n同`Map().set`，第3个参数`ttl`设置该`key`的存活时间。","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmiserylee%2Flayered-cache-loader","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmiserylee%2Flayered-cache-loader","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmiserylee%2Flayered-cache-loader/lists"}