{"id":15509640,"url":"https://github.com/willin/v0","last_synced_at":"2025-06-22T19:36:24.506Z","repository":{"id":52800151,"uuid":"282093498","full_name":"willin/v0","owner":"willin","description":"Useful Rxjs Operators","archived":false,"fork":false,"pushed_at":"2021-04-29T01:16:10.000Z","size":213,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-10T05:34:32.856Z","etag":null,"topics":["async","operators","pipe","rxjs","v0"],"latest_commit_sha":null,"homepage":"http://rx.js.cool/v0","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/willin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":"willin"}},"created_at":"2020-07-24T01:29:22.000Z","updated_at":"2021-04-19T04:42:50.000Z","dependencies_parsed_at":"2022-08-22T16:10:35.489Z","dependency_job_id":null,"html_url":"https://github.com/willin/v0","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/willin/v0","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willin%2Fv0","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willin%2Fv0/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willin%2Fv0/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willin%2Fv0/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/willin","download_url":"https://codeload.github.com/willin/v0/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/willin%2Fv0/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260916545,"owners_count":23082135,"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":["async","operators","pipe","rxjs","v0"],"created_at":"2024-10-02T09:43:24.449Z","updated_at":"2025-06-22T19:36:19.495Z","avatar_url":"https://github.com/willin.png","language":"TypeScript","funding_links":["https://github.com/sponsors/willin"],"categories":[],"sub_categories":[],"readme":"# v0\n\nUseful Rxjs Operators \u0026 Utils.\n\n[![github](https://img.shields.io/github/followers/willin.svg?style=social\u0026label=Followers)](https://github.com/willin) [![npm](https://img.shields.io/npm/v/v0.svg)](https://npmjs.org/package/v0) [![npm](https://img.shields.io/npm/dm/v0.svg)](https://npmjs.org/package/v0) [![npm](https://img.shields.io/npm/dt/v0.svg)](https://npmjs.org/package/v0) [![Maintainability](https://api.codeclimate.com/v1/badges/e7da4dfd45eeaa59402a/maintainability)](https://codeclimate.com/github/willin/v0/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/e7da4dfd45eeaa59402a/test_coverage)](https://codeclimate.com/github/willin/v0/test_coverage) [![Build Status](https://travis-ci.com/willin/v0.svg?branch=main)](https://travis-ci.com/willin/v0)\n\n\u003e 你的`关注`是我最大的动力。 Your `Star` is the best gift.\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n- [Install](#install)\n- [Usage](#usage)\n  - [Operators](#operators)\n    - [delayRetry](#delayretry)\n    - [tapAsync](#tapasync)\n  - [Decorators](#decorators)\n    - [@Cacheable(timeout = 0, mode = ReturnType.Detect)](#cacheabletimeout--0-mode--returntypedetect)\n  - [Utils](#utils)\n    - [cacheable(FN, timeout = 0, isPromise = false)](#cacheablefn-timeout--0-ispromise--false)\n    - [RxPromise](#rxpromise)\n- [Contribute](#contribute)\n- [License](#license)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n## Install\n\n```bash\nnpm i --save rxjs v0\n# or\nyarn add rxjs v0\n```\n\n# Usage\n\n中文文档参考： [rx.js.cool](https://rx.js.cool/) 中的【[进阶（Advanced）](http://rx.js.cool/v0)】章节系列文章\n\n## Operators\n\n### delayRetry\n\n```ts\n{\n  maxAttempts?: number;\n  duration?: number;\n}\n```\n\nDefaults:\n\n```\n{\n  maxAttempts = 3,\n  duration = 1000\n}\n```\n\nUsage:\n\n```ts\nimport { delayRetry } from 'v0';\n// import { delayRetry } from 'v0/operators';\n\nsource$.pipe(\n  // ...\n  // Retry all options in current pipe\n  delayRetry({\n    maxAttempts: 2,\n    duration: 200\n  }),\n  // catchError is needed\n  catchError((error) =\u003e of(error))\n);\n```\n\n### tapAsync\n\nJust like tap, support async/await (promise) function.\n\nUsage:\n\n```ts\nimport { tapAsync } from 'v0';\n// import { tapAsync } from 'v0/operators';\n\nsource$.pipe(\n  tapAsync(async (val) =\u003e {\n    await SomeFn(val);\n  })\n);\n```\n\n## Decorators\n\n### @Cacheable(timeout = 0, mode = ReturnType.Detect)\n\nReturn Type:\n\n```ts\nenum ResultType {\n  Promise = 'Promise',\n  Observable = 'Observable',\n  Detect = 'Detect'\n}\n```\n\nUsage:\n\n```ts\nimport { interval } from 'rxjs';\nimport { Cacheable, ReturnType } from 'v0';\n// import { Cacheable } from 'v0/decorators';\n\nclass Demo {\n  @Cacheable(300, ReturnType.Promise)\n  async save(n: number) {\n    // await something...\n    console.log(`${n} saved`);\n    return `${n} succeed`;\n  }\n}\n\nconst demo = new Demo();\n\ndemo.save(1).then(console.log);\ndemo.save(1).then(console.log);\ndemo.save(3).then(console.log);\n\n/** logs:\n *  1 saved         \u003c---- save only called once, the second call resued before if last call is pending\n *  1 succeed\n *  1 succeed\n *  3 saved\n *  3 succeed\n */\n```\n\n## Utils\n\n### cacheable(FN, timeout = 0, isPromise = false)\n\n```ts\nimport { cacheable } from 'v0';\n// import { cacheable } from 'v0/utils';\n\nconst get = () =\u003e {\n  return from(\n    new Promise((resolve) =\u003e {\n      setTimeout(() =\u003e resolve(new Date()), 2000);\n    })\n  );\n};\n\nconst cachedGet = cacheable(get, false /*if this function returns a PromiseLike result*/);\n```\n\n### RxPromise\n\n```ts\nimport { RxPromise } from 'v0';\n// import { RxPromise } from 'v0/utils';\n\n// RxPromise\u003cT, R = Error\u003e extends Observable\u003cT\u003e\nconst mockedPromise = new RxPromise(resolver);\n```\n\nType of `resolver`:\n\n```ts\n(resolve: (r: T) =\u003e void, reject: (r: R) =\u003e void) =\u003e void\n```\n\nExample，transform mongoose `exec` to observable:\n\n```ts\nimport mongoose from 'mongoose';\nimport { RxPromise } from 'v0';\n\nmongoose.Promise = RxPromise;\n\nmongoose.connect('mongodb://localhost/test', { useNewUrlParser: true, useUnifiedTopology: true });\nconst kittySchema = new mongoose.Schema({\n  name: String\n});\nconst Kitten = mongoose.model('Kitten', kittySchema);\n\nconst s$ = \u003cObservable\u003cRecord\u003cstring, unknown\u003e[]\u003e\u003e(\u003cany\u003eKitten.find().exec());\n// or\n// const s$ = (Kitten.find().exec()) as any) as Observable\u003cRecord\u003cstring, unknown\u003e[]\u003e;\n\ns$.subscribe({\n  next(v) {\n    console.log(v);\n  },\n  complete() {\n    console.log('ended');\n  }\n});\n```\n\n# Contribute\n\n1. Add your own operator\n2. Update Readme Doc (List / Usage)\n3. Make a PR\n\n# License\n\nApache 2.0\n\n通过支付宝捐赠：\n\n![qr](https://cloud.githubusercontent.com/assets/1890238/15489630/fccbb9cc-2193-11e6-9fed-b93c59d6ef37.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillin%2Fv0","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwillin%2Fv0","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwillin%2Fv0/lists"}