{"id":25383396,"url":"https://github.com/paddls/rxjs-common","last_synced_at":"2026-04-08T12:32:25.747Z","repository":{"id":39718581,"uuid":"230415440","full_name":"paddls/rxjs-common","owner":"paddls","description":"A collection of useful RxJS operators","archived":false,"fork":false,"pushed_at":"2025-06-10T13:29:48.000Z","size":553,"stargazers_count":31,"open_issues_count":1,"forks_count":2,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-11-02T16:17:09.324Z","etag":null,"topics":["javascript","rxjs","rxjs-observables","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@paddls/rxjs-common","language":"TypeScript","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/paddls.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2019-12-27T09:37:56.000Z","updated_at":"2025-10-15T11:00:54.000Z","dependencies_parsed_at":"2024-06-20T00:11:28.226Z","dependency_job_id":"1db4c59d-97ff-4c90-a5e6-3a0b21f0f405","html_url":"https://github.com/paddls/rxjs-common","commit_stats":{"total_commits":90,"total_committers":10,"mean_commits":9.0,"dds":0.7777777777777778,"last_synced_commit":"1107f5324a056a91b2ee33293b764df14ab6bfc7"},"previous_names":[],"tags_count":29,"template":false,"template_full_name":null,"purl":"pkg:github/paddls/rxjs-common","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paddls%2Frxjs-common","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paddls%2Frxjs-common/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paddls%2Frxjs-common/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paddls%2Frxjs-common/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/paddls","download_url":"https://codeload.github.com/paddls/rxjs-common/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/paddls%2Frxjs-common/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31556232,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-08T10:21:54.569Z","status":"ssl_error","status_checked_at":"2026-04-08T10:21:38.171Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["javascript","rxjs","rxjs-observables","typescript"],"created_at":"2025-02-15T08:01:24.189Z","updated_at":"2026-04-08T12:32:25.723Z","avatar_url":"https://github.com/paddls.png","language":"TypeScript","readme":"# Rxjs Common\n\n![rxjs-common-ci](https://github.com/paddls/rxjs-common/workflows/rxjs-common-build/badge.svg)\n[![Coverage Status](https://coveralls.io/repos/github/paddls/rxjs-common/badge.svg?branch=master)](https://coveralls.io/github/paddls/rxjs-common?branch=master)\n[![npm version](https://badge.fury.io/js/@paddls%2Frxjs-common.svg)](https://badge.fury.io/js/@paddls%2Frxjs-common)\n![GitHub](https://img.shields.io/github/license/paddls/rxjs-common)\n![GitHub repo size](https://img.shields.io/github/repo-size/paddls/rxjs-common)\n![GitHub last commit](https://img.shields.io/github/last-commit/paddls/rxjs-common)\n![GitHub issues](https://img.shields.io/github/issues/paddls/rxjs-common)\n![GitHub top language](https://img.shields.io/github/languages/top/paddls/rxjs-common)\n\n## Informations\n\n\u003e :warning: Since version 1.3.2, ```rxjs-common``` has been published under ```@paddls``` namespace. We continue to maintain ```@witty-services``` namespace.\n\n## Summary\n\n* [How to install](#how-to-install)\n* [Most used operators](#most-used-operators)\n  * [log](#log--)\n  * [softCache](#softcache--)\n  * [hardCache](#hardcache--)\n  * [refreshOn](#refreshon--)\n* [Array operators](#array-operators)\n  * [arrayFilter](#arrayfilter--)\n  * [arrayFind](#arrayfind--)\n  * [arrayMap](#arraymap--)\n  * [Other array operators](#other-array-operators)\n* [Filtering operators](#filtering-operators)\n  * [ifEmpty](#ifempty--)\n  * [ifFalsy](#iffalsy--)\n  * [ifNotNull](#ifnotnull--)\n  * [ifNotNulls](#ifnotnulls--)\n  * [ifNull](#ifnull--)\n  * [ifNulls](#ifnulls--)\n  * [ifTruthy](#iftruthy--)\n* [Other operators](#other-operators)\n  * [countSubscription](#countsubscription--)\n  * [joinArray](#joinarray--)\n  * [onAny](#onany--)\n  * [onError](#onerror--)\n  * [poll](#poll--)\n  * [sneakyThrow](#sneakythrow--)\n  * [toHotArray](#tohotarray--)\n  * [wif](#wif--)\n\n## How to install\n\n```\nnpm install --save @paddls/rxjs-common\n```\n\n**`RxJS` compatibility table :**\n\n| `RxJS`            | `rxjs-common`     |\n|-------------------|-------------------|\n| `7.0.0` and above | `2.0.0` and above |\n| `6.5.4` and above | `1.0.0` and above |\n\n## Most used operators\n\n### log()\n\nLogs observable content with console API.\n\nBasic usage :\n\n```typescript\nimport { from } from 'rxjs';\nimport { log } from '@paddls/rxjs-common';\n\nfrom(['a', 'b']).pipe(\n        log()\n).subscribe();\n\n// output: 'a', 'b'\n```\n\nWith params usage :\n\n```typescript\nimport { from } from 'rxjs';\nimport { log } from '@paddls/rxjs-common';\n\nfrom(['a', 'b']).pipe(\n        log('Hello World !')\n).subscribe();\n\n// output: 'Hello World !', 'a', 'Hello World !', 'b'\n```\n\n### softCache()\n\nCreates a cache destroyed when there is no more active subscription.\n\nUsage :\n\n```typescript\nimport { from } from 'rxjs';\nimport { log, softCache } from '@paddls/rxjs-common';\n\nconst buffer$ = from('a').pipe(\n        log(),\n        softCache()\n)\n\nbuffer$.subscribe().unsubscribe(); // should display 'a' cause no active subscription\nbuffer$.subscribe(); // should display 'a' again cause no active subscription (unsubscribed previously)\nbuffer$.subscribe().unsubscribe(); // should display nothing cause previous subscription still active\n```\n\n### hardCache()\n\nCreates a cache between buffer and subscriptions. Cache is not destroyed when there is no more active subscription.\n\nUsage :\n\n```typescript\nimport { from } from 'rxjs';\nimport { log, hardCache } from '@paddls/rxjs-common';\n\nconst buffer$ = from('a').pipe(\n        log(),\n        hardCache()\n)\n\nbuffer$.subscribe().unsubscribe(); // should display 'a' cause no active subscription\nbuffer$.subscribe(); // should display nothing although the previous unsubscribe call\n```\n\n### refreshOn()\n\nEmits or re-emits source's value at each trigger observable emission.\n\nUsage :\n\n```typescript\nimport { of, interval } from \"rxjs\";\nimport { refreshOn } from '@paddls/rxjs-common';\n\nconst source$ = of(1);\nconst triggerOne$ = of('a');\nconst triggerTwo$ = interval(1000);\n\ndataSource$.pipe(\n        refreshOn(triggerOne$, triggerTwo$)\n).subscribe(console.log);\n\n// output: 1, 1, ... 1 every seconds\n```\n\n## Array operators\n\n### arrayFilter()\n\nReturns the elements of source's array that meet the condition specified in a callback function.\n\nUsage :\n\n```typescript\nimport { of } from 'rxjs';\nimport { arrayFilter } from '@paddls/rxjs-common';\n\nof([1, 2, 3, 4, 5]).pipe(\n        arrayFilter((input: number) =\u003e input % 2 === 0)\n).subscribe(console.log);\n\n// output: [2, 4]\n```\n\n### arrayFind()\n\nReturns the single element of source's array that meet the condition specified in a callback function.\n\nUsage :\n\n```typescript\nimport { of } from 'rxjs';\nimport { arrayFind } from '@paddls/rxjs-common';\n\nof([1, 2, 3, 4, 5]).pipe(\n        arrayFind((input: number) =\u003e input \u003e 1)\n).subscribe(console.log);\n\n// output: 2\n```\n\n### arrayMap()\n\nCalls a defined callback function on each element of source's array, and returns an array that contains the results.\n\nUsage :\n\n```typescript\nimport { of } from 'rxjs';\nimport { arrayMap } from '@paddls/rxjs-common';\n\nof([1, 2, 3]).pipe(\n        arrayMap((input: number) =\u003e `${ input }`)\n).subscribe(console.log);\n\n// output: ['1', '2', '3']\n```\n\n### Other array operators\n\n- `arrayEvery`\n- `arraySome`\n- `arraySort`\n\nEach of these operators follow the same principle and have the same signature as corresponding ES5 methods.\n\n## Filtering operators\n\n### ifEmpty()\n\nReturns default observable when parent return is empty.\n\nUsage :\n\n```typescript\nimport { EMPTY, of } from 'rxjs';\nimport { ifEmpty } from '@paddls/rxjs-common';\n\nEMPTY.pipe(\n        ifEmpty('test')\n).subscribe(console.log)\n\nof('test').pipe(\n        ifEmpty('Is empty')\n).subscribe(console.log)\n\n\n// output: 'test'\n```\n\n### ifFalsy()\n\nFilters source where value is null, undefined, '', 0.\n\nUsage :\n\n```typescript\nimport { from } from 'rxjs';\nimport { ifFalsy } from '@paddls/rxjs-common';\n\nfrom([0, 1]).pipe(\n        ifFalsy()\n).subscribe(console.log)\n\n// output:  0\n```\n\n### ifNotNull()\n\nFilters items emitted by the source Observable by only emitting non-null value.\n\nUsage :\n\n```typescript\nimport { from } from 'rxjs';\nimport { ifNotNull } from '@paddls/rxjs-common';\n\nfrom([1, null, '', undefined, false, 0, '2']).pipe(\n        ifNotNull()\n).subscribe(console.log)\n\n// output: 1, 0, '2'\n```\n\n### ifNotNulls()\n\nFilters items emitted by the source array by only emitting when each item satisfies the != null condition.\n\nUsage :\n\n```typescript\nimport { combineLatest, from } from 'rxjs';\nimport { ifNotNulls } from './if-not-nulls.operator';\n\ncombineLatest([\n  from([null, 1, 2]),\n  from([3, undefined, 4])\n]).pipe(\n        ifNotNulls()\n).subscribe(console.log)\n\n// output: [1, 3], [2, 4]\n```\n\n### ifNull()\n\nFilters items emitted by the source Observable by only emitting null value.\n\nUsage :\n\n```typescript\nimport { from } from 'rxjs';\nimport { ifNull } from '@paddls/rxjs-common';\n\nfrom([1, null, '', undefined, false, 0, '2']).pipe(\n        ifNull()\n).subscribe(console.log)\n\n// output: null, '', undefined, false\n```\n\n### ifNulls()\n\nFilters items emitted by the source array by only emitting when each item satisfies the == null condition.\n\nUsage :\n\n```typescript\nimport { combineLatest, from } from 'rxjs';\nimport { ifNulls } from './if-nulls.operator';\n\ncombineLatest([\n  from([1, null]),\n  from([undefined, 2])\n]).pipe(\n        ifNulls()\n).subscribe(console.log)\n\n// output: [null, undefined], [undefined, undefined]\n```\n\n### ifTruthy()\n\nFilters source where value is not null, undefined, '', 0.\n\nUsage :\n\n```typescript\nimport { from } from 'rxjs';\nimport { ifTruthy } from '@paddls/rxjs-common';\n\nfrom([0, 1]).pipe(\n        ifTruthy()\n).subscribe(console.log)\n\n// output:  1\n```\n\n### countSubscription()\n\nLogs number of active subscriptions.\n\nBasic usage :\n\n```typescript\nimport { from } from 'rxjs';\nimport { countSubscription } from '@paddls/rxjs-common';\n\nfrom(['a', 'b']).pipe(\n  countSubscription()\n).subscribe();\n\n// outputs number of active subscriptions through time\n```\n\n### joinArray()\n\nCombines the latest values of source and each input array into a single array.\n\nUsage :\n\n```typescript\nimport { from } from 'rxjs';\nimport { joinArray } from '@paddls/rxjs-common';\n\nfrom([[1], [3]]).pipe(\n  joinArray(from([[], [2], []])),\n).subscribe(console.log)\n\n// output:  [1], [1, 2], [3]\n```\n\n## Other operators\n\n### onAny()\n\nTriggers callback on any event passing through (EMPTY observable, error or value).\n\nUsage :\n\n```typescript\nimport { EMPTY } from 'rxjs';\nimport { onAny } from '@paddls/rxjs-common';\n\nEMPTY.pipe(\n  onAny(() =\u003e console.log('Hello'))\n).subscribe()\n\n// output: 'Hello'\n```\n\n### onError()\n\nHandles errors of specified type.\n\nUsage :\n\n```typescript\nimport { of, timer } from 'rxjs';\nimport { tap } from 'rxjs/operators';\nimport { onError } from '@paddls/rxjs-common';\n\nclass MyCustomError {\n}\n\ntimer(1000).pipe(\n        tap(() =\u003e throw new MyCustomError()),\n        onError(MyCustomError, (err: MyCustomError) =\u003e {\n          return of('Hello')\n        })\n).subscribe()\n\n// output: 'Hello'\n```\n\n### poll()\n\nEmits source value at every interval.\n\nUsage :\n\n```typescript\nimport { of } from \"rxjs\";\nimport { take } from \"rxjs/operators\";\nimport { poll } from '@paddls/rxjs-common';\n\nconst dataSource$ = of(1);\n\ndataSource$.pipe(\n  poll(500, true),\n  take(4),\n).subscribe(console.log)\n\n// output: 1, 1, 1, 1\n```\n\n### sneakyThrow()\n\nCatches observable error and returns EMPTY.\n\nUsage :\n\n```typescript\nimport { of } from \"rxjs\";\nimport { tap } from \"rxjs/operators\";\nimport { sneakyThrow } from '@paddls/rxjs-common';\n\nthrowError(new Error('An error')).pipe(\n  sneakyThrow()\n).subscribe(console.log);\n\n// output: EMPTY\n```\n\n### toHotArray()\n\nScans source values into an array.\n\nUsage :\n\n```typescript\nimport { from } from \"rxjs\";\nimport { sneakyThrow } from '@paddls/rxjs-common';\n\nfrom([1, 2, 3]).pipe(\n  toHotArray()\n).subscribe(console.log);\n\n// output: [1], [1, 2], [1, 2, 3]\n```\n\n### wif()\n\nReturns either an observable or another depending on the condition.\n\nUsage :\n\n```typescript\nimport { from } from 'rxjs';\nimport { wif } from '@paddls/rxjs-common';\n\nfrom([1, 2, 3]).pipe(\n  wif(\n    (value: number) =\u003e value \u003e 2,\n    () =\u003e 'Greater than',\n    () =\u003e 'Less than or equal'\n  )\n).subscribe(console.log)\n\n// output:  'Less than or equal', 'Less than or equal', 'Greater than'\n```\n","funding_links":[],"categories":["Underlying Technologies"],"sub_categories":["RxJS"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaddls%2Frxjs-common","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpaddls%2Frxjs-common","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpaddls%2Frxjs-common/lists"}