@rsdk/common 6.0.0-next.1 → 6.0.0-next.11
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/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/validation/index.d.ts +1 -0
- package/dist/{observable → validation}/index.js +1 -1
- package/dist/validation/index.js.map +1 -0
- package/dist/validation/typebox.validator.d.ts +26 -0
- package/dist/validation/typebox.validator.js +38 -0
- package/dist/validation/typebox.validator.js.map +1 -0
- package/package.json +9 -4
- package/src/index.ts +1 -1
- package/src/validation/index.ts +1 -0
- package/src/validation/typebox.validator.ts +38 -0
- package/dist/observable/index.d.ts +0 -1
- package/dist/observable/index.js.map +0 -1
- package/dist/observable/observable-to-async-iterable.d.ts +0 -7
- package/dist/observable/observable-to-async-iterable.js +0 -107
- package/dist/observable/observable-to-async-iterable.js.map +0 -1
- package/src/observable/index.ts +0 -1
- package/src/observable/observable-to-async-iterable.ts +0 -115
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -21,6 +21,6 @@ __exportStar(require("./time"), exports);
|
|
|
21
21
|
__exportStar(require("./functions"), exports);
|
|
22
22
|
__exportStar(require("./size"), exports);
|
|
23
23
|
__exportStar(require("./strings"), exports);
|
|
24
|
-
__exportStar(require("./observable"), exports);
|
|
25
24
|
__exportStar(require("./parsers"), exports);
|
|
25
|
+
__exportStar(require("./validation"), exports);
|
|
26
26
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,0CAAwB;AACxB,4CAA0B;AAC1B,yCAAuB;AACvB,8CAA4B;AAC5B,yCAAuB;AACvB,4CAA0B;AAC1B,+CAA6B
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,0CAAwB;AACxB,4CAA0B;AAC1B,yCAAuB;AACvB,8CAA4B;AAC5B,yCAAuB;AACvB,4CAA0B;AAC1B,4CAA0B;AAC1B,+CAA6B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './typebox.validator';
|
|
@@ -14,5 +14,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./
|
|
17
|
+
__exportStar(require("./typebox.validator"), exports);
|
|
18
18
|
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/validation/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,sDAAoC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { TSchema } from '@sinclair/typebox';
|
|
2
|
+
import type { ValueError } from '@sinclair/typebox/compiler';
|
|
3
|
+
/**
|
|
4
|
+
* Wrapper around Typebox's type validation.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```ts
|
|
8
|
+
* const validator = new Validator(t.Object({ name: t.String() }));
|
|
9
|
+
* const { isValid, errors } = validator.run({ name: 'John' });
|
|
10
|
+
* ...
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export declare class TypeBoxValidator<T extends TSchema> {
|
|
14
|
+
private readonly validator;
|
|
15
|
+
constructor(schema: T);
|
|
16
|
+
/**
|
|
17
|
+
* Run the validator on the given data.
|
|
18
|
+
*
|
|
19
|
+
* @param data - The data to validate.
|
|
20
|
+
* @returns The validation result.
|
|
21
|
+
*/
|
|
22
|
+
check(data: unknown): {
|
|
23
|
+
isValid: boolean;
|
|
24
|
+
errors: ValueError[];
|
|
25
|
+
};
|
|
26
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TypeBoxValidator = void 0;
|
|
4
|
+
const compiler_1 = require("@sinclair/typebox/compiler");
|
|
5
|
+
/**
|
|
6
|
+
* Wrapper around Typebox's type validation.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* const validator = new Validator(t.Object({ name: t.String() }));
|
|
11
|
+
* const { isValid, errors } = validator.run({ name: 'John' });
|
|
12
|
+
* ...
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
class TypeBoxValidator {
|
|
16
|
+
validator;
|
|
17
|
+
constructor(schema) {
|
|
18
|
+
this.validator = compiler_1.TypeCompiler.Compile(schema);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Run the validator on the given data.
|
|
22
|
+
*
|
|
23
|
+
* @param data - The data to validate.
|
|
24
|
+
* @returns The validation result.
|
|
25
|
+
*/
|
|
26
|
+
check(data) {
|
|
27
|
+
/**
|
|
28
|
+
* TODO: При случае, придумать, как нормально распечатывать ошибки для union'ов.
|
|
29
|
+
* Сейчас они ужасно неинформативные.
|
|
30
|
+
*/
|
|
31
|
+
return {
|
|
32
|
+
isValid: this.validator.Check(data),
|
|
33
|
+
errors: [...this.validator.Errors(data)],
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.TypeBoxValidator = TypeBoxValidator;
|
|
38
|
+
//# sourceMappingURL=typebox.validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typebox.validator.js","sourceRoot":"","sources":["../../src/validation/typebox.validator.ts"],"names":[],"mappings":";;;AAEA,yDAA0D;AAE1D;;;;;;;;;GASG;AACH,MAAa,gBAAgB;IACV,SAAS,CAAe;IAEzC,YAAY,MAAS;QACnB,IAAI,CAAC,SAAS,GAAG,uBAAY,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,IAAa;QACjB;;;WAGG;QACH,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC;YACnC,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;SACzC,CAAC;IACJ,CAAC;CACF;AAvBD,4CAuBC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rsdk/common",
|
|
3
|
-
"version": "6.0.0-next.
|
|
3
|
+
"version": "6.0.0-next.11",
|
|
4
4
|
"description": "Useful common classes, functions and types",
|
|
5
5
|
"license": "Apache License 2.0",
|
|
6
6
|
"publishConfig": {
|
|
@@ -13,8 +13,13 @@
|
|
|
13
13
|
"scripts": {
|
|
14
14
|
"prepublishOnly": "npm run build"
|
|
15
15
|
},
|
|
16
|
-
"
|
|
17
|
-
"
|
|
16
|
+
"peerDependencies": {
|
|
17
|
+
"@sinclair/typebox": "^0.34.9"
|
|
18
18
|
},
|
|
19
|
-
"
|
|
19
|
+
"peerDependenciesMeta": {
|
|
20
|
+
"@sinclair/typebox": {
|
|
21
|
+
"optional": true
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"gitHead": "e4a3d962f23e2c4ea39ec08e07628290f54812a6"
|
|
20
25
|
}
|
package/src/index.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './typebox.validator';
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { TSchema } from '@sinclair/typebox';
|
|
2
|
+
import type { TypeCheck, ValueError } from '@sinclair/typebox/compiler';
|
|
3
|
+
import { TypeCompiler } from '@sinclair/typebox/compiler';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Wrapper around Typebox's type validation.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* const validator = new Validator(t.Object({ name: t.String() }));
|
|
11
|
+
* const { isValid, errors } = validator.run({ name: 'John' });
|
|
12
|
+
* ...
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export class TypeBoxValidator<T extends TSchema> {
|
|
16
|
+
private readonly validator: TypeCheck<T>;
|
|
17
|
+
|
|
18
|
+
constructor(schema: T) {
|
|
19
|
+
this.validator = TypeCompiler.Compile(schema);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Run the validator on the given data.
|
|
24
|
+
*
|
|
25
|
+
* @param data - The data to validate.
|
|
26
|
+
* @returns The validation result.
|
|
27
|
+
*/
|
|
28
|
+
check(data: unknown): { isValid: boolean; errors: ValueError[] } {
|
|
29
|
+
/**
|
|
30
|
+
* TODO: При случае, придумать, как нормально распечатывать ошибки для union'ов.
|
|
31
|
+
* Сейчас они ужасно неинформативные.
|
|
32
|
+
*/
|
|
33
|
+
return {
|
|
34
|
+
isValid: this.validator.Check(data),
|
|
35
|
+
errors: [...this.validator.Errors(data)],
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './observable-to-async-iterable';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/observable/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iEAA+C"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { Observable } from 'rxjs';
|
|
2
|
-
export type Callback = (value?: any) => any;
|
|
3
|
-
/**
|
|
4
|
-
* Утилита для создания асинк итератора из обзервабл
|
|
5
|
-
* поиском "observableToAsyncIterable" можно найти тесты в которых есть пример использования
|
|
6
|
-
*/
|
|
7
|
-
export declare function observableToAsyncIterable<T>(observable: Observable<T>): AsyncIterableIterator<T>;
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.observableToAsyncIterable = observableToAsyncIterable;
|
|
4
|
-
/**
|
|
5
|
-
* Утилита для создания асинк итератора из обзервабл
|
|
6
|
-
* поиском "observableToAsyncIterable" можно найти тесты в которых есть пример использования
|
|
7
|
-
*/
|
|
8
|
-
function observableToAsyncIterable(observable) {
|
|
9
|
-
const pullQueue = [];
|
|
10
|
-
const pushQueue = [];
|
|
11
|
-
let listening = true;
|
|
12
|
-
const pushValue = (value) => {
|
|
13
|
-
if (pullQueue.length > 0) {
|
|
14
|
-
// It is safe to use the ! operator here as we check the length.
|
|
15
|
-
pullQueue.shift()({
|
|
16
|
-
value,
|
|
17
|
-
done: false,
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
else {
|
|
21
|
-
pushQueue.push({
|
|
22
|
-
value,
|
|
23
|
-
done: false,
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
const pushError = (error) => {
|
|
28
|
-
if (pullQueue.length > 0) {
|
|
29
|
-
// It is safe to use the ! operator here as we check the length.
|
|
30
|
-
pullQueue.shift()({
|
|
31
|
-
value: { errors: [error] },
|
|
32
|
-
done: false,
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
pushQueue.push({
|
|
37
|
-
value: { errors: [error] },
|
|
38
|
-
done: false,
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
const pushDone = () => {
|
|
43
|
-
if (pullQueue.length > 0) {
|
|
44
|
-
// It is safe to use the ! operator here as we check the length.
|
|
45
|
-
pullQueue.shift()({ done: true });
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
pushQueue.push({ done: true });
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
const pullValue = () => new Promise((resolve) => {
|
|
52
|
-
if (pushQueue.length > 0) {
|
|
53
|
-
const element = pushQueue.shift();
|
|
54
|
-
// either {value: {errors: [...]}} or {value: ...}
|
|
55
|
-
resolve(element);
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
pullQueue.push(resolve);
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
const subscription = observable.subscribe({
|
|
62
|
-
next(value) {
|
|
63
|
-
pushValue(value);
|
|
64
|
-
},
|
|
65
|
-
error(err) {
|
|
66
|
-
pushError(err);
|
|
67
|
-
},
|
|
68
|
-
complete() {
|
|
69
|
-
pushDone();
|
|
70
|
-
},
|
|
71
|
-
});
|
|
72
|
-
const emptyQueue = () => {
|
|
73
|
-
if (listening) {
|
|
74
|
-
listening = false;
|
|
75
|
-
subscription.unsubscribe();
|
|
76
|
-
for (const resolve of pullQueue) {
|
|
77
|
-
resolve({
|
|
78
|
-
value: undefined,
|
|
79
|
-
done: true,
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
pullQueue.length = 0;
|
|
83
|
-
pushQueue.length = 0;
|
|
84
|
-
}
|
|
85
|
-
};
|
|
86
|
-
return {
|
|
87
|
-
next() {
|
|
88
|
-
// return is a defined method, so it is safe to call it.
|
|
89
|
-
return listening ? pullValue() : this.return();
|
|
90
|
-
},
|
|
91
|
-
return() {
|
|
92
|
-
emptyQueue();
|
|
93
|
-
return Promise.resolve({
|
|
94
|
-
value: undefined,
|
|
95
|
-
done: true,
|
|
96
|
-
});
|
|
97
|
-
},
|
|
98
|
-
throw(error) {
|
|
99
|
-
emptyQueue();
|
|
100
|
-
return Promise.reject(error);
|
|
101
|
-
},
|
|
102
|
-
[Symbol.asyncIterator]() {
|
|
103
|
-
return this;
|
|
104
|
-
},
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
//# sourceMappingURL=observable-to-async-iterable.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"observable-to-async-iterable.js","sourceRoot":"","sources":["../../src/observable/observable-to-async-iterable.ts"],"names":[],"mappings":";;AAQA,8DA0GC;AA9GD;;;GAGG;AACH,SAAgB,yBAAyB,CACvC,UAAyB;IAEzB,MAAM,SAAS,GAAoB,EAAE,CAAC;IACtC,MAAM,SAAS,GAAe,EAAE,CAAC;IAEjC,IAAI,SAAS,GAAG,IAAI,CAAC;IAErB,MAAM,SAAS,GAAG,CAAC,KAAU,EAAQ,EAAE;QACrC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,gEAAgE;YAChE,SAAS,CAAC,KAAK,EAAG,CAAC;gBACjB,KAAK;gBACL,IAAI,EAAE,KAAK;aACZ,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,IAAI,CAAC;gBACb,KAAK;gBACL,IAAI,EAAE,KAAK;aACZ,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,CAAC,KAAU,EAAQ,EAAE;QACrC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,gEAAgE;YAChE,SAAS,CAAC,KAAK,EAAG,CAAC;gBACjB,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE;gBAC1B,IAAI,EAAE,KAAK;aACZ,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,IAAI,CAAC;gBACb,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,EAAE;gBAC1B,IAAI,EAAE,KAAK;aACZ,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,GAAS,EAAE;QAC1B,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,gEAAgE;YAChE,SAAS,CAAC,KAAK,EAAG,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACjC,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,GAA+B,EAAE,CACjD,IAAI,OAAO,CAAoB,CAAC,OAAO,EAAE,EAAE;QACzC,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC;YAElC,kDAAkD;YAClD,OAAO,CAAC,OAAO,CAAC,CAAC;QACnB,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,MAAM,YAAY,GAAG,UAAU,CAAC,SAAS,CAAC;QACxC,IAAI,CAAC,KAAU;YACb,SAAS,CAAC,KAAK,CAAC,CAAC;QACnB,CAAC;QACD,KAAK,CAAC,GAAU;YACd,SAAS,CAAC,GAAG,CAAC,CAAC;QACjB,CAAC;QACD,QAAQ;YACN,QAAQ,EAAE,CAAC;QACb,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,GAAS,EAAE;QAC5B,IAAI,SAAS,EAAE,CAAC;YACd,SAAS,GAAG,KAAK,CAAC;YAClB,YAAY,CAAC,WAAW,EAAE,CAAC;YAC3B,KAAK,MAAM,OAAO,IAAI,SAAS,EAAE,CAAC;gBAChC,OAAO,CAAC;oBACN,KAAK,EAAE,SAAS;oBAChB,IAAI,EAAE,IAAI;iBACX,CAAC,CAAC;YACL,CAAC;YACD,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;YACrB,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;QACvB,CAAC;IACH,CAAC,CAAC;IAEF,OAAO;QACL,IAAI;YACF,wDAAwD;YACxD,OAAO,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAO,EAAE,CAAC;QAClD,CAAC;QACD,MAAM;YACJ,UAAU,EAAE,CAAC;YACb,OAAO,OAAO,CAAC,OAAO,CAAC;gBACrB,KAAK,EAAE,SAAS;gBAChB,IAAI,EAAE,IAAI;aACX,CAAC,CAAC;QACL,CAAC;QACD,KAAK,CAAC,KAAK;YACT,UAAU,EAAE,CAAC;YACb,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/B,CAAC;QACD,CAAC,MAAM,CAAC,aAAa,CAAC;YACpB,OAAO,IAAI,CAAC;QACd,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/src/observable/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './observable-to-async-iterable';
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
import type { Observable } from 'rxjs';
|
|
2
|
-
|
|
3
|
-
export type Callback = (value?: any) => any;
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Утилита для создания асинк итератора из обзервабл
|
|
7
|
-
* поиском "observableToAsyncIterable" можно найти тесты в которых есть пример использования
|
|
8
|
-
*/
|
|
9
|
-
export function observableToAsyncIterable<T>(
|
|
10
|
-
observable: Observable<T>,
|
|
11
|
-
): AsyncIterableIterator<T> {
|
|
12
|
-
const pullQueue: Array<Callback> = [];
|
|
13
|
-
const pushQueue: Array<any> = [];
|
|
14
|
-
|
|
15
|
-
let listening = true;
|
|
16
|
-
|
|
17
|
-
const pushValue = (value: any): void => {
|
|
18
|
-
if (pullQueue.length > 0) {
|
|
19
|
-
// It is safe to use the ! operator here as we check the length.
|
|
20
|
-
pullQueue.shift()!({
|
|
21
|
-
value,
|
|
22
|
-
done: false,
|
|
23
|
-
});
|
|
24
|
-
} else {
|
|
25
|
-
pushQueue.push({
|
|
26
|
-
value,
|
|
27
|
-
done: false,
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
const pushError = (error: any): void => {
|
|
33
|
-
if (pullQueue.length > 0) {
|
|
34
|
-
// It is safe to use the ! operator here as we check the length.
|
|
35
|
-
pullQueue.shift()!({
|
|
36
|
-
value: { errors: [error] },
|
|
37
|
-
done: false,
|
|
38
|
-
});
|
|
39
|
-
} else {
|
|
40
|
-
pushQueue.push({
|
|
41
|
-
value: { errors: [error] },
|
|
42
|
-
done: false,
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
const pushDone = (): void => {
|
|
48
|
-
if (pullQueue.length > 0) {
|
|
49
|
-
// It is safe to use the ! operator here as we check the length.
|
|
50
|
-
pullQueue.shift()!({ done: true });
|
|
51
|
-
} else {
|
|
52
|
-
pushQueue.push({ done: true });
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
const pullValue = (): Promise<IteratorResult<T>> =>
|
|
57
|
-
new Promise<IteratorResult<T>>((resolve) => {
|
|
58
|
-
if (pushQueue.length > 0) {
|
|
59
|
-
const element = pushQueue.shift();
|
|
60
|
-
|
|
61
|
-
// either {value: {errors: [...]}} or {value: ...}
|
|
62
|
-
resolve(element);
|
|
63
|
-
} else {
|
|
64
|
-
pullQueue.push(resolve);
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
const subscription = observable.subscribe({
|
|
69
|
-
next(value: any) {
|
|
70
|
-
pushValue(value);
|
|
71
|
-
},
|
|
72
|
-
error(err: Error) {
|
|
73
|
-
pushError(err);
|
|
74
|
-
},
|
|
75
|
-
complete() {
|
|
76
|
-
pushDone();
|
|
77
|
-
},
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
const emptyQueue = (): void => {
|
|
81
|
-
if (listening) {
|
|
82
|
-
listening = false;
|
|
83
|
-
subscription.unsubscribe();
|
|
84
|
-
for (const resolve of pullQueue) {
|
|
85
|
-
resolve({
|
|
86
|
-
value: undefined,
|
|
87
|
-
done: true,
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
|
-
pullQueue.length = 0;
|
|
91
|
-
pushQueue.length = 0;
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
return {
|
|
96
|
-
next(): Promise<IteratorResult<T>> {
|
|
97
|
-
// return is a defined method, so it is safe to call it.
|
|
98
|
-
return listening ? pullValue() : this.return!();
|
|
99
|
-
},
|
|
100
|
-
return(): Promise<IteratorResult<T>> {
|
|
101
|
-
emptyQueue();
|
|
102
|
-
return Promise.resolve({
|
|
103
|
-
value: undefined,
|
|
104
|
-
done: true,
|
|
105
|
-
});
|
|
106
|
-
},
|
|
107
|
-
throw(error): Promise<IteratorResult<T>> {
|
|
108
|
-
emptyQueue();
|
|
109
|
-
return Promise.reject(error);
|
|
110
|
-
},
|
|
111
|
-
[Symbol.asyncIterator](): AsyncIterableIterator<T> {
|
|
112
|
-
return this;
|
|
113
|
-
},
|
|
114
|
-
};
|
|
115
|
-
}
|