react-obsidian 2.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,15 +1,14 @@
1
1
  [![SWUbanner](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner2-direct.svg)](https://vshymanskyy.github.io/StandWithUkraine)
2
2
 
3
3
  <p align="center">
4
- </br><img width="300px" src=".github/logo.svg"></br>
4
+ </br><img width="300px" src=".github/logo.svg"></br></br>
5
5
  <a href="https://npmjs.com/package/react-obsidian"><img src="https://img.shields.io/npm/v/react-obsidian.svg" alt="npm package"></a>
6
6
  <a href="https://www.npmjs.com/package/react-obsidian"><img src="https://img.shields.io/npm/dm/react-obsidian.svg" alt="NPM downloads"></a>
7
7
  <a href="https://github.com/wix-incubator/react-obsidian/actions/workflows/ci.yml"><img src="https://github.com/wix-incubator/react-obsidian/actions/workflows/ci.yml/badge.svg?branch=master" alt="build status"></a>
8
8
  <a href="https://discord.gg/MDH2axwaPy"><img src="https://img.shields.io/badge/chat-discord-blue?style=flat&logo=discord" alt="discord chat"></a>
9
+ <h1 align="center">Obsidian</h1>
9
10
  </p>
10
11
 
11
- # React Obsidian
12
-
13
12
  React Obsidian is a dependency injection framework for React and React Native applications. It allows you to inject dependencies into hooks, components, and classes. Separating the construction and consumption of dependencies is crucial to maintaining a readable and testable codebase.
14
13
 
15
14
  > 📖 Read more about Dependency Injection and Obsidian in [Breaking complexity with Dependency Injection: Introducing Obsidian](https://guyca.medium.com/breaking-complexity-with-dependency-injection-introducing-obsidian-cd452802f076) on Medium.
@@ -1,7 +1,9 @@
1
1
  import { Observable } from '../Observable';
2
- import { Mapper, OnNext } from '../types';
2
+ import { Mapper, MultiMapper, Observables, OnNext, Observable as IObservable, OnMultiNext } from '../types';
3
3
  export declare class MediatorObservable<T> extends Observable<T> {
4
4
  mapSource<Source, Result extends T>(source: Observable<Source>, mapNext: Mapper<Source, Result>): this;
5
- addSource<S>(source: Observable<S>, onNext: OnNext<S>): this;
5
+ addSource<S>(source: IObservable<S>, onNext: OnNext<S>): this;
6
+ addSources<S1, S2, S3, S4, S5>(sources: Observables<S1, S2, S3, S4, S5>, onNext: OnMultiNext<S1, S2, S3, S4, S5>): this;
7
+ mapSources<S1, S2, S3, S4, S5>(sources: Observables<S1, S2, S3, S4, S5>, mapNext: MultiMapper<T, S1, S2, S3, S4, S5>): this;
6
8
  }
7
9
  //# sourceMappingURL=MediatorObservable.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MediatorObservable.d.ts","sourceRoot":"","sources":["../../../../src/observable/mediator/MediatorObservable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAE1C,qBAAa,kBAAkB,CAAC,CAAC,CAAE,SAAQ,UAAU,CAAC,CAAC,CAAC;IACtD,SAAS,CAAC,MAAM,EAAE,MAAM,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAQ/F,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAOtD"}
1
+ {"version":3,"file":"MediatorObservable.d.ts","sourceRoot":"","sources":["../../../../src/observable/mediator/MediatorObservable.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EACL,MAAM,EACN,WAAW,EACX,WAAW,EACX,MAAM,EACN,UAAU,IAAI,WAAW,EAEzB,WAAW,EACZ,MAAM,UAAU,CAAC;AAElB,qBAAa,kBAAkB,CAAC,CAAC,CAAE,SAAQ,UAAU,CAAC,CAAC,CAAC;IACtD,SAAS,CAAC,MAAM,EAAE,MAAM,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAO/F,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAQtD,UAAU,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAC3B,OAAO,EAAE,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EACxC,MAAM,EAAE,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;IAuBzC,UAAU,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAC3B,OAAO,EAAE,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EACxC,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;CAsB9C"}
@@ -1,12 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MediatorObservable = void 0;
4
+ const notNull_1 = require("../../utils/notNull");
4
5
  const Observable_1 = require("../Observable");
5
6
  class MediatorObservable extends Observable_1.Observable {
6
7
  mapSource(source, mapNext) {
7
8
  this.addSource(source, (next) => {
8
- const mapped = mapNext(next, this.value);
9
- this.value = mapped;
9
+ this.value = mapNext(next, this.value);
10
10
  });
11
11
  return this;
12
12
  }
@@ -17,6 +17,46 @@ class MediatorObservable extends Observable_1.Observable {
17
17
  }
18
18
  return this;
19
19
  }
20
+ addSources(sources, onNext) {
21
+ const values = new Array(sources.length);
22
+ sources
23
+ .filter(notNull_1.notNull)
24
+ .forEach((source, index) => {
25
+ this.addSource(source, (next) => {
26
+ if (values[index] === next)
27
+ return;
28
+ if (values[index] === undefined) {
29
+ values[index] = next;
30
+ }
31
+ else {
32
+ values[index] = next;
33
+ onNext(values);
34
+ }
35
+ });
36
+ });
37
+ onNext(values);
38
+ return this;
39
+ }
40
+ mapSources(sources, mapNext) {
41
+ const values = new Array(sources.length);
42
+ sources
43
+ .filter(notNull_1.notNull)
44
+ .forEach((source, index) => {
45
+ this.addSource(source, (next) => {
46
+ if (values[index] === next)
47
+ return;
48
+ if (values[index] === undefined) {
49
+ values[index] = next;
50
+ }
51
+ else {
52
+ values[index] = next;
53
+ this.value = mapNext(values, this.value);
54
+ }
55
+ });
56
+ });
57
+ this.value = mapNext(values, this.value);
58
+ return this;
59
+ }
20
60
  }
21
61
  exports.MediatorObservable = MediatorObservable;
22
62
  //# sourceMappingURL=MediatorObservable.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MediatorObservable.js","sourceRoot":"","sources":["../../../../src/observable/mediator/MediatorObservable.ts"],"names":[],"mappings":";;;AAAA,8CAA2C;AAG3C,MAAa,kBAAsB,SAAQ,uBAAa;IACtD,SAAS,CAA2B,MAA0B,EAAE,OAA+B;QAC7F,IAAI,CAAC,SAAS,CAAS,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACtC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,KAAe,CAAW,CAAC;YAC7D,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC;QACtB,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAED,SAAS,CAAI,MAAqB,EAAE,MAAiB;QACnD,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACzB,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE;YAC9B,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;SACtB;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAhBD,gDAgBC"}
1
+ {"version":3,"file":"MediatorObservable.js","sourceRoot":"","sources":["../../../../src/observable/mediator/MediatorObservable.ts"],"names":[],"mappings":";;;AAAA,iDAA8C;AAC9C,8CAA2C;AAW3C,MAAa,kBAAsB,SAAQ,uBAAa;IACtD,SAAS,CAA2B,MAA0B,EAAE,OAA+B;QAC7F,IAAI,CAAC,SAAS,CAAS,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACtC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,KAAe,CAAW,CAAC;QAC7D,CAAC,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;IAED,SAAS,CAAI,MAAsB,EAAE,MAAiB;QACpD,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACzB,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE;YAC9B,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;SACtB;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,UAAU,CACR,OAAwC,EACxC,MAAuC;QAEvC,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAA6B,CAAC;QAErE,OAAO;aACJ,MAAM,CAAC,iBAAO,CAAC;aACf,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;YACzB,IAAI,CAAC,SAAS,CAAC,MAA0B,EAAE,CAAC,IAAI,EAAE,EAAE;gBAClD,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI;oBAAE,OAAO;gBAEnC,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,SAAS,EAAE;oBAC/B,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;iBACtB;qBAAM;oBACL,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;oBACrB,MAAM,CAAC,MAAM,CAAC,CAAC;iBAChB;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEL,MAAM,CAAC,MAAM,CAAC,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC;IAED,UAAU,CACR,OAAwC,EACxC,OAA2C;QAE3C,MAAM,MAAM,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAA6B,CAAC;QAErE,OAAO;aACJ,MAAM,CAAC,iBAAO,CAAC;aACf,OAAO,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;YACzB,IAAI,CAAC,SAAS,CAAC,MAA0B,EAAE,CAAC,IAAI,EAAE,EAAE;gBAClD,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI;oBAAE,OAAO;gBAEnC,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,SAAS,EAAE;oBAC/B,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;iBACtB;qBAAM;oBACL,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;oBACrB,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAM,CAAC;iBAC/C;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEL,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAjED,gDAiEC"}
@@ -1,4 +1,5 @@
1
1
  export type OnNext<T> = (value: T) => void | undefined;
2
+ export type OnMultiNext<S1, S2, S3, S4, S5> = ([S1, S2, S3, S4, S5]: Args<S1, S2, S3, S4, S5>) => void | undefined;
2
3
  export type Mapper<Other, Mine> = (next: Other, currentValue: Mine) => Mine extends void ? 'A map function must return a value. Check your map function and ensure it has a valid return statement.' : Mine;
3
4
  export type Unsubscribe = () => void;
4
5
  export interface Observable<T> {
@@ -8,4 +9,43 @@ export interface Observable<T> {
8
9
  export type ObservedValues<T> = {
9
10
  [K in keyof T]: T[K] extends Observable<infer R> ? R : never;
10
11
  };
12
+ export type MultiMapper<Mine, S1, S2, S3, S4, S5> = ([S1, S2, S3, S4, S5]: Args<S1, S2, S3, S4, S5>, currentValue: Mine) => Mine;
13
+ export type Observables<S1, S2, S3, S4, S5> = [
14
+ Observable<S1>,
15
+ Observable<S2>
16
+ ] | [
17
+ Observable<S1>,
18
+ Observable<S2>,
19
+ Observable<S3>
20
+ ] | [
21
+ Observable<S1>,
22
+ Observable<S2>,
23
+ Observable<S3>,
24
+ Observable<S4>
25
+ ] | [
26
+ Observable<S1>,
27
+ Observable<S2>,
28
+ Observable<S3>,
29
+ Observable<S4>,
30
+ Observable<S5>
31
+ ];
32
+ export type Args<A1, A2, A3, A4, A5> = [
33
+ A1,
34
+ A2
35
+ ] | [
36
+ A1,
37
+ A2,
38
+ A3
39
+ ] | [
40
+ A1,
41
+ A2,
42
+ A3,
43
+ A4
44
+ ] | [
45
+ A1,
46
+ A2,
47
+ A3,
48
+ A4,
49
+ A5
50
+ ];
11
51
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/observable/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAAG,SAAS,CAAC;AACvD,MAAM,MAAM,MAAM,CAAC,KAAK,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,KAAK,IAAI,SAAS,IAAI,GACtF,yGAAyG,GACzG,IAAI,CAAC;AACP,MAAM,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC;AAErC,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,KAAK,EAAE,CAAC,CAAC;IACT,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;CAC3C;AAED,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;CAAE,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/observable/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAAG,SAAS,CAAC;AAEvD,MAAM,MAAM,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,KAAK,IAAI,GAAG,SAAS,CAAC;AAEnH,MAAM,MAAM,MAAM,CAAC,KAAK,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,KAAK,IAAI,SAAS,IAAI,GACtF,yGAAyG,GACzG,IAAI,CAAC;AACP,MAAM,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC;AAErC,MAAM,WAAW,UAAU,CAAC,CAAC;IAC3B,KAAK,EAAE,CAAC,CAAC;IACT,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC;CAC3C;AAED,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;CAAE,CAAC;AAEjG,MAAM,MAAM,WAAW,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,CAClD,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAC9C,YAAY,EAAE,IAAI,KACf,IAAI,CAAC;AAEV,MAAM,MAAM,WAAW,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,IACxC;IAAC,UAAU,CAAC,EAAE,CAAC;IAAE,UAAU,CAAC,EAAE,CAAC;CAAC,GAChC;IAAC,UAAU,CAAC,EAAE,CAAC;IAAE,UAAU,CAAC,EAAE,CAAC;IAAE,UAAU,CAAC,EAAE,CAAC;CAAC,GAChD;IAAC,UAAU,CAAC,EAAE,CAAC;IAAE,UAAU,CAAC,EAAE,CAAC;IAAE,UAAU,CAAC,EAAE,CAAC;IAAE,UAAU,CAAC,EAAE,CAAC;CAAC,GAChE;IAAC,UAAU,CAAC,EAAE,CAAC;IAAE,UAAU,CAAC,EAAE,CAAC;IAAE,UAAU,CAAC,EAAE,CAAC;IAAE,UAAU,CAAC,EAAE,CAAC;IAAE,UAAU,CAAC,EAAE,CAAC;CAAC,CAAC;AAEnF,MAAM,MAAM,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,IACjC;IAAC,EAAE;IAAE,EAAE;CAAC,GACR;IAAC,EAAE;IAAE,EAAE;IAAE,EAAE;CAAC,GACZ;IAAC,EAAE;IAAE,EAAE;IAAE,EAAE;IAAE,EAAE;CAAC,GAChB;IAAC,EAAE;IAAE,EAAE;IAAE,EAAE;IAAE,EAAE;IAAE,EAAE;CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const notNull: (value: any) => boolean;
2
+ //# sourceMappingURL=notNull.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notNull.d.ts","sourceRoot":"","sources":["../../../src/utils/notNull.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,UAAW,GAAG,YAA0C,CAAC"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.notNull = void 0;
4
+ const notNull = (value) => value !== null && value !== undefined;
5
+ exports.notNull = notNull;
6
+ //# sourceMappingURL=notNull.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notNull.js","sourceRoot":"","sources":["../../../src/utils/notNull.ts"],"names":[],"mappings":";;;AAAO,MAAM,OAAO,GAAG,CAAC,KAAU,EAAE,EAAE,CAAC,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,CAAC;AAAhE,QAAA,OAAO,WAAyD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-obsidian",
3
- "version": "2.0.0",
3
+ "version": "2.2.0",
4
4
  "description": "Dependency injection framework for React and React Native applications",
5
5
  "scripts": {
6
6
  "prepack": "npm run lint && tsc --project tsconfig.prod.json",
@@ -1,20 +1,78 @@
1
+ import { notNull } from '../../utils/notNull';
1
2
  import { Observable } from '../Observable';
2
- import { Mapper, OnNext } from '../types';
3
+ import {
4
+ Mapper,
5
+ MultiMapper,
6
+ Observables,
7
+ OnNext,
8
+ Observable as IObservable,
9
+ Args,
10
+ OnMultiNext,
11
+ } from '../types';
3
12
 
4
13
  export class MediatorObservable<T> extends Observable<T> {
5
14
  mapSource<Source, Result extends T>(source: Observable<Source>, mapNext: Mapper<Source, Result>) {
6
15
  this.addSource<Source>(source, (next) => {
7
- const mapped = mapNext(next, this.value as Result) as Result;
8
- this.value = mapped;
16
+ this.value = mapNext(next, this.value as Result) as Result;
9
17
  });
10
18
  return this;
11
19
  }
12
20
 
13
- addSource<S>(source: Observable<S>, onNext: OnNext<S>) {
21
+ addSource<S>(source: IObservable<S>, onNext: OnNext<S>) {
14
22
  source.subscribe(onNext);
15
23
  if (source.value !== undefined) {
16
24
  onNext(source.value);
17
25
  }
18
26
  return this;
19
27
  }
28
+
29
+ addSources<S1, S2, S3, S4, S5>(
30
+ sources: Observables<S1, S2, S3, S4, S5>,
31
+ onNext: OnMultiNext<S1, S2, S3, S4, S5>,
32
+ ) {
33
+ const values = new Array(sources.length) as Args<S1, S2, S3, S4, S5>;
34
+
35
+ sources
36
+ .filter(notNull)
37
+ .forEach((source, index) => {
38
+ this.addSource(source as IObservable<any>, (next) => {
39
+ if (values[index] === next) return;
40
+
41
+ if (values[index] === undefined) {
42
+ values[index] = next;
43
+ } else {
44
+ values[index] = next;
45
+ onNext(values);
46
+ }
47
+ });
48
+ });
49
+
50
+ onNext(values);
51
+ return this;
52
+ }
53
+
54
+ mapSources<S1, S2, S3, S4, S5>(
55
+ sources: Observables<S1, S2, S3, S4, S5>,
56
+ mapNext: MultiMapper<T, S1, S2, S3, S4, S5>,
57
+ ) {
58
+ const values = new Array(sources.length) as Args<S1, S2, S3, S4, S5>;
59
+
60
+ sources
61
+ .filter(notNull)
62
+ .forEach((source, index) => {
63
+ this.addSource(source as IObservable<any>, (next) => {
64
+ if (values[index] === next) return;
65
+
66
+ if (values[index] === undefined) {
67
+ values[index] = next;
68
+ } else {
69
+ values[index] = next;
70
+ this.value = mapNext(values, this.value) as T;
71
+ }
72
+ });
73
+ });
74
+
75
+ this.value = mapNext(values, this.value);
76
+ return this;
77
+ }
20
78
  }
@@ -1,4 +1,7 @@
1
1
  export type OnNext<T> = (value: T) => void | undefined; // OnNext callbacks should never return a value
2
+
3
+ export type OnMultiNext<S1, S2, S3, S4, S5> = ([S1, S2, S3, S4, S5]: Args<S1, S2, S3, S4, S5>) => void | undefined;
4
+
2
5
  export type Mapper<Other, Mine> = (next: Other, currentValue: Mine) => Mine extends void ?
3
6
  'A map function must return a value. Check your map function and ensure it has a valid return statement.' :
4
7
  Mine;
@@ -10,3 +13,20 @@ export interface Observable<T> {
10
13
  }
11
14
 
12
15
  export type ObservedValues<T> = { [K in keyof T]: T[K] extends Observable<infer R> ? R : never };
16
+
17
+ export type MultiMapper<Mine, S1, S2, S3, S4, S5> = (
18
+ [S1, S2, S3, S4, S5]: Args<S1, S2, S3, S4, S5>,
19
+ currentValue: Mine,
20
+ ) => Mine;
21
+
22
+ export type Observables<S1, S2, S3, S4, S5> =
23
+ [Observable<S1>, Observable<S2>] |
24
+ [Observable<S1>, Observable<S2>, Observable<S3>] |
25
+ [Observable<S1>, Observable<S2>, Observable<S3>, Observable<S4>] |
26
+ [Observable<S1>, Observable<S2>, Observable<S3>, Observable<S4>, Observable<S5>];
27
+
28
+ export type Args<A1, A2, A3, A4, A5> =
29
+ [A1, A2] |
30
+ [A1, A2, A3] |
31
+ [A1, A2, A3, A4] |
32
+ [A1, A2, A3, A4, A5];
@@ -0,0 +1 @@
1
+ export const notNull = (value: any) => value !== null && value !== undefined;