asygen 0.0.7 → 0.0.9

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/package.json CHANGED
@@ -1,13 +1,15 @@
1
1
  {
2
2
  "name": "asygen",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "description": "0-Deps, simple and fast async generator library for browser and NodeJS",
5
5
  "type": "module",
6
6
  "main": "build/index.cjs",
7
7
  "types": "build/index.d.ts",
8
8
  "files": [
9
9
  "build",
10
- "src/index.ts"
10
+ "src/index.ts",
11
+ "src/defer.ts",
12
+ "src/generatorify.ts"
11
13
  ],
12
14
  "module": "build/index.js",
13
15
  "sideEffects": false,
package/src/defer.ts ADDED
@@ -0,0 +1,65 @@
1
+ export enum Status {
2
+ PENDING = 'pending',
3
+ RESOLVED = 'resolved',
4
+ REJECTED = 'rejected',
5
+ }
6
+
7
+ const counter: [number, number] = [0,0];
8
+ export const getId = () => {
9
+ const result = Date.now() * 100;
10
+ if (counter[0] !== result) {
11
+ counter[0] = result;
12
+ counter[1] = 0;
13
+ };
14
+ return (counter[0] + (counter[1]++)).toString(16);
15
+ };
16
+
17
+ export class Deferred<T = void, E = unknown> {
18
+ private txts = getId();
19
+ private _promise: Promise<T>;
20
+ private _resolve?: (value: T) => void;
21
+ private _reject?: (error: E) => void;
22
+ private _status: Status = Status.PENDING;
23
+
24
+ constructor() {
25
+ this._promise = new Promise<T>((resolve, reject) => {
26
+ this._resolve = resolve;
27
+ this._reject = reject;
28
+ });
29
+ this.resolve = this.resolve.bind(this);
30
+ this.reject = this.reject.bind(this);
31
+ }
32
+
33
+ get [Symbol.toStringTag]() {
34
+ return `Deferred ${this.txts} ${this._status}`;
35
+ }
36
+
37
+ get promise() {
38
+ return this._promise;
39
+ }
40
+
41
+ get status() {
42
+ return this._status;
43
+ }
44
+
45
+ resolve(value: T) {
46
+ if (this._status === Status.PENDING) {
47
+ this._status = Status.RESOLVED;
48
+ this._resolve(value);
49
+ }
50
+
51
+ return this;
52
+ }
53
+
54
+ reject(error: E) {
55
+ if (this._status === Status.PENDING) {
56
+ this._status = Status.REJECTED;
57
+ this._reject(error);
58
+ }
59
+ return this;
60
+ }
61
+ }
62
+
63
+ export const defer = <T = void, E = unknown>() => {
64
+ return new Deferred<T, E>();
65
+ }
@@ -0,0 +1,37 @@
1
+ import { defer, Deferred } from './defer';
2
+
3
+ export interface TaskCallback<T> {
4
+ (value: T): Promise<T>;
5
+ }
6
+
7
+ export interface Task<T, R = unknown> {
8
+ (callback: TaskCallback<T>): R;
9
+ }
10
+
11
+ export const generatorify = <T, R = unknown>(task: Task<T, R>): AsyncIterable<T> => {
12
+ const dPoll: Deferred<IteratorResult<T, R>>[] = [defer<IteratorYieldResult<T>>()];
13
+
14
+ Promise.resolve(task(value => {
15
+ const next = defer<IteratorYieldResult<T>>();
16
+ const prev = dPoll.push(next) - 2;
17
+ const prevDeferred = dPoll[prev] as Deferred<IteratorYieldResult<T>>;
18
+ prevDeferred.resolve({ value, done: false });
19
+ return prevDeferred.promise.then(v => v.value);
20
+ })).then(async (value) => {
21
+ dPoll[dPoll.length - 1].resolve({ value, done: true });
22
+ await Promise.all(dPoll.map(d => d.promise));
23
+ return { value, done: true };
24
+ });
25
+
26
+ return {
27
+ [Symbol.asyncIterator]() {
28
+ return {
29
+ next() {
30
+ const current = dPoll[0];
31
+ current.promise.then(() => dPoll.shift());
32
+ return current.promise;
33
+ },
34
+ };
35
+ }
36
+ };
37
+ }