@fbltd/async 1.0.6 → 1.0.8

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,10 +1,37 @@
1
- ### R&D async tools ###
1
+ # Async tools
2
2
 
3
- First of all, attention paid to creation of reactive model
4
- leveraging native JavaScript async features like Promises, (async) iterators
5
- and generators.
3
+ ## delay
4
+ delay is a function that can be executed synchronous or asynchronous.
5
+ The behaviour depends on passed arguments:
6
+ ```typescript
7
+ // Returns a promise - asynchrounous running in a non-blocking manner;
8
+ await delay(number);
9
+
10
+ // Returns nothing - synchrounous running in a blocking manner;
11
+ delay(number, true);
12
+ ```
13
+
14
+ ## getPromise
15
+ getPromise is a function that creates and returns promise, its fulfillment functions
16
+ and status flags.
17
+ Returned type is:
18
+ ```typescript
19
+ type IPromiseConfiguration<T> = {
20
+ resolve(arg: T): void, // function that resolves promise
21
+ reject(err: Error): void, // function that rejects promise
22
+ promise: Promise<T>, // promise itself
23
+ readonly isPending: boolean, // promise status flag
24
+ readonly isFulfilled: boolean, // reverted promise status flag
25
+ }
26
+ ```
27
+ There is no any management of passed data for resolving.
28
+ Returned promise is usual ES promise so it is impossible to fulfill promise twice.
6
29
 
7
- The version is 0.0.0 so keep it in mind
30
+ ## DependencyStream
31
+ ### core
32
+ Implementation of reactive model leveraging native JavaScript async features like
33
+ Promises, (async) iterators and generators.
34
+ The version is 0.0.x so keep it in mind
8
35
 
9
36
  ```typescript
10
37
  const counter = new DependencyStream<number>(0);
@@ -32,6 +59,8 @@ setInterval(() => {
32
59
  }, 1000)
33
60
  ```
34
61
 
62
+ ### Framework integrations
63
+ #### React
35
64
  Of course, there is a React integration via useStream hook:
36
65
 
37
66
  ```typescript jsx
@@ -70,4 +99,5 @@ export const Counter: React.FC<ITest> = React.memo(({
70
99
  })
71
100
  ```
72
101
 
73
- Now this package is CommonJS module but should be ESM.
102
+ ## Disclaimer
103
+ Now this package is CommonJS module but should be an ESM.
@@ -7,26 +7,26 @@ function baseComparer(prev, cur) {
7
7
  }
8
8
  class DependencyStream {
9
9
  _value;
10
- promiseConf;
10
+ reactionPromise;
11
11
  abortPromise = (0, utils_1.getPromise)();
12
12
  config;
13
13
  constructor(_value, config = {}) {
14
14
  this._value = _value;
15
15
  this.config = {
16
- isEqual: baseComparer,
16
+ withCustomEquality: baseComparer,
17
+ withReactionOnSubscribe: false,
17
18
  ...config,
18
19
  };
19
20
  }
20
- _set(v, force) {
21
- if (!force) {
22
- if (this.config.isEqual(this._value, v)) {
23
- return;
24
- }
25
- }
26
- if (v === this._value)
21
+ _set(v) {
22
+ if (this.config.withCustomEquality(this._value, v)) {
27
23
  return;
24
+ }
28
25
  this._value = v;
29
- this.promiseConf && this.promiseConf.resolve(v);
26
+ if (this.reactionPromise) {
27
+ this.reactionPromise.resolve(v);
28
+ this.reactionPromise = undefined;
29
+ }
30
30
  }
31
31
  set value(v) {
32
32
  this._set(v);
@@ -37,28 +37,37 @@ class DependencyStream {
37
37
  [Symbol.asyncIterator]() {
38
38
  const totalDispose = this.abortPromise;
39
39
  const selfDispose = (0, utils_1.getPromise)();
40
+ const externalPromises = [totalDispose.promise, selfDispose.promise];
41
+ let firstPromise;
42
+ if (this.config.withReactionOnSubscribe) {
43
+ firstPromise = (0, utils_1.getPromise)();
44
+ firstPromise.resolve(this.value);
45
+ externalPromises.push(firstPromise.promise);
46
+ }
47
+ const owner = this;
40
48
  return {
41
- owner: this,
49
+ owner,
42
50
  dispose: () => selfDispose.resolve(),
43
51
  next: async () => {
44
- if (!this.promiseConf) {
45
- this.promiseConf = (0, utils_1.getPromise)();
52
+ if (!this.reactionPromise) {
53
+ this.reactionPromise = (0, utils_1.getPromise)();
46
54
  this._set(this._value);
47
55
  }
48
56
  await Promise.race([
49
- totalDispose.promise,
50
- selfDispose.promise,
51
- this.promiseConf.promise,
57
+ ...externalPromises,
58
+ this.reactionPromise.promise,
52
59
  ]);
53
- this.promiseConf = undefined;
54
60
  if (totalDispose.isFulfilled || selfDispose.isFulfilled) {
55
61
  return { done: true };
56
62
  }
57
- const value = this.value;
63
+ if (firstPromise) {
64
+ firstPromise = undefined;
65
+ externalPromises.pop();
66
+ }
58
67
  return {
59
68
  done: false,
60
69
  get value() {
61
- return value;
70
+ return owner.value;
62
71
  }
63
72
  };
64
73
  }
@@ -67,6 +76,7 @@ class DependencyStream {
67
76
  dispose() {
68
77
  this.abortPromise.resolve();
69
78
  this.abortPromise = (0, utils_1.getPromise)();
79
+ this.reactionPromise = undefined;
70
80
  }
71
81
  }
72
82
  exports.DependencyStream = DependencyStream;
@@ -2,11 +2,26 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.delay = delay;
4
4
  const get_promise_1 = require("./get-promise");
5
- function delay(ms = 0) {
5
+ function delay(ms = 0, sync) {
6
6
  ms = Math.max(ms, 0);
7
- const { promise, resolve } = (0, get_promise_1.getPromise)();
8
- setTimeout(() => {
9
- resolve();
10
- }, ms);
11
- return promise;
7
+ return delay.methods[typeof sync](ms);
12
8
  }
9
+ Object.defineProperty(delay, 'methods', {
10
+ value: {
11
+ boolean: (ms) => {
12
+ const start = performance.now();
13
+ while (true) {
14
+ if (performance.now() - start >= ms) {
15
+ return;
16
+ }
17
+ }
18
+ },
19
+ undefined: (ms) => {
20
+ const { promise, resolve } = (0, get_promise_1.getPromise)();
21
+ setTimeout(() => {
22
+ resolve();
23
+ }, ms);
24
+ return promise;
25
+ }
26
+ }
27
+ });
@@ -1,12 +1,13 @@
1
- interface ICompareFn<T> {
1
+ interface IIsEquals<T> {
2
2
  (prev: T, cur: T): boolean;
3
3
  }
4
4
  type IDependencyStreamConfig<T> = {
5
- isEqual: ICompareFn<T>;
5
+ withCustomEquality: IIsEquals<T>;
6
+ withReactionOnSubscribe: boolean;
6
7
  };
7
8
  export declare class DependencyStream<T = any> {
8
9
  private _value;
9
- private promiseConf;
10
+ private reactionPromise;
10
11
  private abortPromise;
11
12
  private config;
12
13
  constructor(_value: T, config?: Partial<IDependencyStreamConfig<T>>);
@@ -1 +1,2 @@
1
+ export declare function delay(ms: number, sync: true): void;
1
2
  export declare function delay(ms?: number): Promise<void>;
@@ -5,3 +5,4 @@ export declare function getPromise<TReturn = void>(): {
5
5
  readonly isFulfilled: boolean;
6
6
  promise: Promise<TReturn>;
7
7
  };
8
+ export type IPromiseConfiguration<T = void> = ReturnType<typeof getPromise<T>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fbltd/async",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "R&D async tools",
5
5
  "exports": {
6
6
  "require": "./dist/bin/index.js",