rian 0.1.1 → 0.2.1
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/exporter.otel.http/index.d.ts +3 -0
- package/exporter.otel.http/index.js +110 -0
- package/exporter.otel.http/index.mjs +110 -0
- package/exporter.zipkin/index.d.ts +3 -0
- package/exporter.zipkin/index.js +43 -0
- package/exporter.zipkin/index.mjs +43 -0
- package/index.d.ts +146 -117
- package/index.js +66 -111
- package/index.mjs +70 -91
- package/package.json +20 -8
- package/{utils.d.ts → utils/index.d.ts} +28 -6
- package/utils/index.js +30 -0
- package/utils/index.mjs +30 -0
- package/exporter.otel.http.d.ts +0 -5
- package/exporter.otel.http.js +0 -113
- package/exporter.otel.http.mjs +0 -111
- package/exporter.zipkin.d.ts +0 -5
- package/exporter.zipkin.js +0 -45
- package/exporter.zipkin.mjs +0 -43
- package/utils.js +0 -79
- package/utils.mjs +0 -75
@@ -0,0 +1,110 @@
|
|
1
|
+
// src/exporter.otel.http.ts
|
2
|
+
const { name:rian_name, version:rian_version } = require('rian/package.json');
|
3
|
+
var SpanStatusCode_UNSET = 0;
|
4
|
+
var SpanStatusCode_ERROR = 2;
|
5
|
+
var convert_value_to_anyvalue = (value) => {
|
6
|
+
let type = typeof value, any_value = {};
|
7
|
+
if (type === "string")
|
8
|
+
any_value.stringValue = value;
|
9
|
+
else if (type === "number")
|
10
|
+
if (Number.isInteger(value))
|
11
|
+
any_value.intValue = value;
|
12
|
+
else
|
13
|
+
any_value.doubleValue = value;
|
14
|
+
else if (type === "boolean")
|
15
|
+
any_value.boolValue = value;
|
16
|
+
else if (Array.isArray(value))
|
17
|
+
any_value.arrayValue = {
|
18
|
+
values: value.map((i) => convert_value_to_anyvalue(i))
|
19
|
+
};
|
20
|
+
else if (value)
|
21
|
+
any_value.kvlistValue = { values: convert_object_to_kv(value) };
|
22
|
+
return any_value;
|
23
|
+
};
|
24
|
+
var convert_object_to_kv = (input) => {
|
25
|
+
const value = [];
|
26
|
+
for (let key of Object.keys(input)) {
|
27
|
+
value.push({
|
28
|
+
key,
|
29
|
+
value: convert_value_to_anyvalue(input[key])
|
30
|
+
});
|
31
|
+
}
|
32
|
+
return value;
|
33
|
+
};
|
34
|
+
var map_kind = (kind) => {
|
35
|
+
switch (kind) {
|
36
|
+
default:
|
37
|
+
case "INTERNAL": {
|
38
|
+
return 1;
|
39
|
+
}
|
40
|
+
case "SERVER": {
|
41
|
+
return 2;
|
42
|
+
}
|
43
|
+
case "CLIENT": {
|
44
|
+
return 3;
|
45
|
+
}
|
46
|
+
case "PRODUCER": {
|
47
|
+
return 4;
|
48
|
+
}
|
49
|
+
case "CONSUMER": {
|
50
|
+
return 5;
|
51
|
+
}
|
52
|
+
}
|
53
|
+
};
|
54
|
+
var exporter = (request) => (spans, context) => {
|
55
|
+
const otel_spans = [];
|
56
|
+
for (let span of spans) {
|
57
|
+
const { kind, error, ...span_ctx } = span.context;
|
58
|
+
let status;
|
59
|
+
if (error) {
|
60
|
+
status = {
|
61
|
+
code: SpanStatusCode_ERROR
|
62
|
+
};
|
63
|
+
if ("message" in error) {
|
64
|
+
status.message = error.message;
|
65
|
+
}
|
66
|
+
}
|
67
|
+
otel_spans.push({
|
68
|
+
traceId: span.id.trace_id,
|
69
|
+
spanId: span.id.parent_id,
|
70
|
+
parentSpanId: span.parent?.parent_id,
|
71
|
+
name: span.name,
|
72
|
+
kind: map_kind(kind || "INTERNAL"),
|
73
|
+
startTimeUnixNano: span.start * 1e6,
|
74
|
+
endTimeUnixNano: span.end ? span.end * 1e6 : void 0,
|
75
|
+
droppedAttributesCount: 0,
|
76
|
+
droppedEventsCount: 0,
|
77
|
+
droppedLinksCount: 0,
|
78
|
+
attributes: convert_object_to_kv(span_ctx),
|
79
|
+
status: status || { code: SpanStatusCode_UNSET },
|
80
|
+
events: span.events.map((i) => ({
|
81
|
+
name: i.name,
|
82
|
+
attributes: convert_object_to_kv(i.attributes),
|
83
|
+
droppedAttributesCount: 0,
|
84
|
+
timeUnixNano: i.timestamp * 1e6
|
85
|
+
}))
|
86
|
+
});
|
87
|
+
}
|
88
|
+
return request({
|
89
|
+
resourceSpans: [
|
90
|
+
{
|
91
|
+
resource: {
|
92
|
+
attributes: convert_object_to_kv(context),
|
93
|
+
droppedAttributesCount: 0
|
94
|
+
},
|
95
|
+
instrumentationLibrarySpans: [
|
96
|
+
{
|
97
|
+
instrumentationLibrary: {
|
98
|
+
name: rian_name,
|
99
|
+
version: rian_version
|
100
|
+
},
|
101
|
+
spans: otel_spans
|
102
|
+
}
|
103
|
+
]
|
104
|
+
}
|
105
|
+
]
|
106
|
+
});
|
107
|
+
};
|
108
|
+
|
109
|
+
|
110
|
+
exports.exporter = exporter;
|
@@ -0,0 +1,110 @@
|
|
1
|
+
// src/exporter.otel.http.ts
|
2
|
+
import { name as rian_name, version as rian_version } from "rian/package.json";
|
3
|
+
var SpanStatusCode_UNSET = 0;
|
4
|
+
var SpanStatusCode_ERROR = 2;
|
5
|
+
var convert_value_to_anyvalue = (value) => {
|
6
|
+
let type = typeof value, any_value = {};
|
7
|
+
if (type === "string")
|
8
|
+
any_value.stringValue = value;
|
9
|
+
else if (type === "number")
|
10
|
+
if (Number.isInteger(value))
|
11
|
+
any_value.intValue = value;
|
12
|
+
else
|
13
|
+
any_value.doubleValue = value;
|
14
|
+
else if (type === "boolean")
|
15
|
+
any_value.boolValue = value;
|
16
|
+
else if (Array.isArray(value))
|
17
|
+
any_value.arrayValue = {
|
18
|
+
values: value.map((i) => convert_value_to_anyvalue(i))
|
19
|
+
};
|
20
|
+
else if (value)
|
21
|
+
any_value.kvlistValue = { values: convert_object_to_kv(value) };
|
22
|
+
return any_value;
|
23
|
+
};
|
24
|
+
var convert_object_to_kv = (input) => {
|
25
|
+
const value = [];
|
26
|
+
for (let key of Object.keys(input)) {
|
27
|
+
value.push({
|
28
|
+
key,
|
29
|
+
value: convert_value_to_anyvalue(input[key])
|
30
|
+
});
|
31
|
+
}
|
32
|
+
return value;
|
33
|
+
};
|
34
|
+
var map_kind = (kind) => {
|
35
|
+
switch (kind) {
|
36
|
+
default:
|
37
|
+
case "INTERNAL": {
|
38
|
+
return 1;
|
39
|
+
}
|
40
|
+
case "SERVER": {
|
41
|
+
return 2;
|
42
|
+
}
|
43
|
+
case "CLIENT": {
|
44
|
+
return 3;
|
45
|
+
}
|
46
|
+
case "PRODUCER": {
|
47
|
+
return 4;
|
48
|
+
}
|
49
|
+
case "CONSUMER": {
|
50
|
+
return 5;
|
51
|
+
}
|
52
|
+
}
|
53
|
+
};
|
54
|
+
var exporter = (request) => (spans, context) => {
|
55
|
+
const otel_spans = [];
|
56
|
+
for (let span of spans) {
|
57
|
+
const { kind, error, ...span_ctx } = span.context;
|
58
|
+
let status;
|
59
|
+
if (error) {
|
60
|
+
status = {
|
61
|
+
code: SpanStatusCode_ERROR
|
62
|
+
};
|
63
|
+
if ("message" in error) {
|
64
|
+
status.message = error.message;
|
65
|
+
}
|
66
|
+
}
|
67
|
+
otel_spans.push({
|
68
|
+
traceId: span.id.trace_id,
|
69
|
+
spanId: span.id.parent_id,
|
70
|
+
parentSpanId: span.parent?.parent_id,
|
71
|
+
name: span.name,
|
72
|
+
kind: map_kind(kind || "INTERNAL"),
|
73
|
+
startTimeUnixNano: span.start * 1e6,
|
74
|
+
endTimeUnixNano: span.end ? span.end * 1e6 : void 0,
|
75
|
+
droppedAttributesCount: 0,
|
76
|
+
droppedEventsCount: 0,
|
77
|
+
droppedLinksCount: 0,
|
78
|
+
attributes: convert_object_to_kv(span_ctx),
|
79
|
+
status: status || { code: SpanStatusCode_UNSET },
|
80
|
+
events: span.events.map((i) => ({
|
81
|
+
name: i.name,
|
82
|
+
attributes: convert_object_to_kv(i.attributes),
|
83
|
+
droppedAttributesCount: 0,
|
84
|
+
timeUnixNano: i.timestamp * 1e6
|
85
|
+
}))
|
86
|
+
});
|
87
|
+
}
|
88
|
+
return request({
|
89
|
+
resourceSpans: [
|
90
|
+
{
|
91
|
+
resource: {
|
92
|
+
attributes: convert_object_to_kv(context),
|
93
|
+
droppedAttributesCount: 0
|
94
|
+
},
|
95
|
+
instrumentationLibrarySpans: [
|
96
|
+
{
|
97
|
+
instrumentationLibrary: {
|
98
|
+
name: rian_name,
|
99
|
+
version: rian_version
|
100
|
+
},
|
101
|
+
spans: otel_spans
|
102
|
+
}
|
103
|
+
]
|
104
|
+
}
|
105
|
+
]
|
106
|
+
});
|
107
|
+
};
|
108
|
+
export {
|
109
|
+
exporter
|
110
|
+
};
|
@@ -0,0 +1,43 @@
|
|
1
|
+
// src/exporter.zipkin.ts
|
2
|
+
const { flattie } = require('flattie');
|
3
|
+
var exporter = (request) => (spans, context) => {
|
4
|
+
const zipkin = [];
|
5
|
+
for (let span of spans) {
|
6
|
+
const { kind, error, ...span_ctx } = span.context;
|
7
|
+
if (error) {
|
8
|
+
if ("message" in error) {
|
9
|
+
span_ctx.error = {
|
10
|
+
name: error.name,
|
11
|
+
message: error.message,
|
12
|
+
stack: error.stack
|
13
|
+
};
|
14
|
+
} else {
|
15
|
+
span_ctx.error = true;
|
16
|
+
}
|
17
|
+
}
|
18
|
+
zipkin.push({
|
19
|
+
id: span.id.parent_id,
|
20
|
+
traceId: span.id.trace_id,
|
21
|
+
parentId: span.parent ? span.parent.parent_id : void 0,
|
22
|
+
name: span.name,
|
23
|
+
kind: kind === "INTERNAL" ? void 0 : kind,
|
24
|
+
timestamp: span.start * 1e3,
|
25
|
+
duration: span.end ? (span.end - span.start) * 1e3 : void 0,
|
26
|
+
localEndpoint: context.localEndpoint || {
|
27
|
+
serviceName: span_ctx["service.name"]
|
28
|
+
},
|
29
|
+
tags: flattie({
|
30
|
+
...context,
|
31
|
+
...span_ctx
|
32
|
+
}, ".", true),
|
33
|
+
annotations: span.events.map((i) => ({
|
34
|
+
value: `${i.name} :: ${JSON.stringify(i.attributes)}`,
|
35
|
+
timestamp: i.timestamp * 1e3
|
36
|
+
}))
|
37
|
+
});
|
38
|
+
}
|
39
|
+
return request(zipkin);
|
40
|
+
};
|
41
|
+
|
42
|
+
|
43
|
+
exports.exporter = exporter;
|
@@ -0,0 +1,43 @@
|
|
1
|
+
// src/exporter.zipkin.ts
|
2
|
+
import { flattie } from "flattie";
|
3
|
+
var exporter = (request) => (spans, context) => {
|
4
|
+
const zipkin = [];
|
5
|
+
for (let span of spans) {
|
6
|
+
const { kind, error, ...span_ctx } = span.context;
|
7
|
+
if (error) {
|
8
|
+
if ("message" in error) {
|
9
|
+
span_ctx.error = {
|
10
|
+
name: error.name,
|
11
|
+
message: error.message,
|
12
|
+
stack: error.stack
|
13
|
+
};
|
14
|
+
} else {
|
15
|
+
span_ctx.error = true;
|
16
|
+
}
|
17
|
+
}
|
18
|
+
zipkin.push({
|
19
|
+
id: span.id.parent_id,
|
20
|
+
traceId: span.id.trace_id,
|
21
|
+
parentId: span.parent ? span.parent.parent_id : void 0,
|
22
|
+
name: span.name,
|
23
|
+
kind: kind === "INTERNAL" ? void 0 : kind,
|
24
|
+
timestamp: span.start * 1e3,
|
25
|
+
duration: span.end ? (span.end - span.start) * 1e3 : void 0,
|
26
|
+
localEndpoint: context.localEndpoint || {
|
27
|
+
serviceName: span_ctx["service.name"]
|
28
|
+
},
|
29
|
+
tags: flattie({
|
30
|
+
...context,
|
31
|
+
...span_ctx
|
32
|
+
}, ".", true),
|
33
|
+
annotations: span.events.map((i) => ({
|
34
|
+
value: `${i.name} :: ${JSON.stringify(i.attributes)}`,
|
35
|
+
timestamp: i.timestamp * 1e3
|
36
|
+
}))
|
37
|
+
});
|
38
|
+
}
|
39
|
+
return request(zipkin);
|
40
|
+
};
|
41
|
+
export {
|
42
|
+
exporter
|
43
|
+
};
|
package/index.d.ts
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
import { Traceparent } from 'tctx';
|
2
|
-
|
3
1
|
/**
|
4
2
|
* Spans are units within a distributed trace. Spans encapsulate mainly 3 pieces of information, a
|
5
3
|
* {@link Span.name|name}, and a {@link Span.start|start} and {@link Span.end|end} time.
|
@@ -20,110 +18,124 @@ import { Traceparent } from 'tctx';
|
|
20
18
|
* Spans are aimed to interoperate with
|
21
19
|
* {@link https://github.com/opentracing/specification/blob/master/specification.md|OpenTracing's Spans}, albeit not entirely api compatible — they do share principles.
|
22
20
|
*/
|
23
|
-
interface Span {
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
21
|
+
export interface Span {
|
22
|
+
/**
|
23
|
+
* A human-readable name for this span. For example the function name, the name of a subtask,
|
24
|
+
* or stage of the larger stack.
|
25
|
+
*
|
26
|
+
* @example
|
27
|
+
* "resolve_user_ids"
|
28
|
+
* "[POST] /api"
|
29
|
+
*/
|
30
|
+
name: string;
|
31
|
+
|
32
|
+
/**
|
33
|
+
* A w3c trace context compatible id for this span. Will .toString() into an injectable header.
|
34
|
+
*
|
35
|
+
* @see https://www.w3.org/TR/trace-context/#traceparent-header
|
36
|
+
* @see https://github.com/maraisr/tctx
|
37
|
+
*/
|
38
|
+
id: Traceparent;
|
39
|
+
|
40
|
+
/**
|
41
|
+
* Is the id of rhe parent if this is not the parent {@link Span}.
|
42
|
+
*
|
43
|
+
* @see {@link Span.id}
|
44
|
+
*/
|
45
|
+
parent: Traceparent | undefined;
|
46
|
+
|
47
|
+
/**
|
48
|
+
* The time represented as a UNIX epoch timestamp in milliseconds when this span was created.
|
49
|
+
* Typically, via
|
50
|
+
* {@link Scope.fork|tracer.fork()}.
|
51
|
+
*/
|
52
|
+
start: number;
|
53
|
+
|
54
|
+
/**
|
55
|
+
* The UNIX epoch timestamp in milliseconds when the span ended, or undefined if ending was not
|
56
|
+
* captured during the current trace. Time should then be assumed as current time.
|
57
|
+
*/
|
58
|
+
end?: number;
|
59
|
+
|
60
|
+
/**
|
61
|
+
* An arbitrary context object useful for storing information during a trace.
|
62
|
+
*
|
63
|
+
* Usually following a convention such as `tag.*`, `http.*` or any of the
|
64
|
+
* {@link https://github.com/opentracing/specification/blob/master/semantic_conventions.md|Semantic Conventions outlined by OpenTracing}.
|
65
|
+
*
|
66
|
+
* ### Note!
|
67
|
+
*
|
68
|
+
* There are a few keys with "powers"
|
69
|
+
*
|
70
|
+
* - `kind` when set will coerce into the exports scheme, aka INTERNAL in zipkin will be
|
71
|
+
* `"INTERNAL"`, or `1` in otel
|
72
|
+
* - `error` when set, will be assumed to be an `Error` instance, and thus its `.message` wil
|
73
|
+
* exist as `error.message` in zipkin, and `status: 2` in otel.
|
74
|
+
*/
|
75
|
+
context: Context;
|
76
|
+
|
77
|
+
/**
|
78
|
+
* Events are user-defined timestamped annotations of "events" that happened during the
|
79
|
+
* lifetime of a span. Consisting of a textual message, and optional attributes.
|
80
|
+
*
|
81
|
+
* As a rule-of-thumb use events to attach verbose information about a span, than an entirely
|
82
|
+
* new span.
|
83
|
+
*/
|
84
|
+
events: { name: string; timestamp: number; attributes: Context }[];
|
85
85
|
}
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
86
|
+
|
87
|
+
export interface Scope {
|
88
|
+
/**
|
89
|
+
* A W3C traceparent. One can .toString() this if you want to cross a network.
|
90
|
+
*/
|
91
|
+
traceparent: Traceparent;
|
92
|
+
|
93
|
+
/**
|
94
|
+
* Forks the span into a new child span.
|
95
|
+
*/
|
96
|
+
fork(name: string): CallableScope;
|
97
|
+
|
98
|
+
/**
|
99
|
+
* Allows the span's context to be set. Passing an object will be `Object.assign`ed into the
|
100
|
+
* current context.
|
101
|
+
*
|
102
|
+
* Passing a function will be available to return a new context.
|
103
|
+
*/
|
104
|
+
set_context(contextFn: Context | ((context: Context) => Context)): void;
|
105
|
+
|
106
|
+
/**
|
107
|
+
* Adds a new event to the span. As a rule-of-thumb use events to attach verbose information
|
108
|
+
* about a span, than an entirely new span.
|
109
|
+
*/
|
110
|
+
add_event(name: string, attributes?: Record<string, any>): void;
|
111
|
+
|
112
|
+
/**
|
113
|
+
* Ends the current span — setting its `end` timestamp. Not calling this, will have its `end`
|
114
|
+
* timestamp nulled out — when the tracer ends.
|
115
|
+
*/
|
116
|
+
end(): void;
|
112
117
|
}
|
113
|
-
|
114
|
-
|
118
|
+
|
119
|
+
export interface Tracer extends Omit<Scope, 'end'> {
|
120
|
+
end(): ReturnType<Exporter>;
|
115
121
|
}
|
122
|
+
|
116
123
|
/**
|
117
124
|
* An exporter is a method called when the parent scope ends, gets given a Set of all spans traced
|
118
125
|
* during this execution.
|
119
126
|
*/
|
120
|
-
|
127
|
+
export type Exporter = (
|
128
|
+
spans: ReadonlySet<Readonly<Span>>,
|
129
|
+
context: Context,
|
130
|
+
) => any;
|
131
|
+
|
121
132
|
/**
|
122
133
|
* @borrows {@link Span.context}
|
123
134
|
*/
|
124
|
-
interface Context {
|
125
|
-
|
135
|
+
export interface Context {
|
136
|
+
[property: string]: any;
|
126
137
|
}
|
138
|
+
|
127
139
|
/**
|
128
140
|
* Should return true when you want to sample the span, this is ran before the span is traced — so
|
129
141
|
* decisions is made preemptively.
|
@@ -133,28 +145,45 @@ interface Context {
|
|
133
145
|
*
|
134
146
|
* Sampling does impact the traceparent, for injection — and is encoded there.
|
135
147
|
*/
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
148
|
+
export type Sampler = (
|
149
|
+
name: string,
|
150
|
+
parentId?: Traceparent,
|
151
|
+
context?: Context,
|
152
|
+
) => boolean;
|
153
|
+
|
154
|
+
export interface Options {
|
155
|
+
/**
|
156
|
+
* @borrows {@link Exporter}
|
157
|
+
*/
|
158
|
+
exporter: Exporter;
|
159
|
+
|
160
|
+
/**
|
161
|
+
* @borrows {@link Sampler}
|
162
|
+
*/
|
163
|
+
sampler?: Sampler | boolean;
|
164
|
+
|
165
|
+
context?: Context;
|
166
|
+
|
167
|
+
/**
|
168
|
+
* A root, or extracted w3c traceparent stringed header.
|
169
|
+
*
|
170
|
+
* If the id is malformed, the {@link create} method will throw an exception. If no root is
|
171
|
+
* provided then one will be created obeying the {@link Options.sampler|sampling} rules.
|
172
|
+
*/
|
173
|
+
traceparent?: string;
|
154
174
|
}
|
155
|
-
|
156
|
-
|
175
|
+
|
176
|
+
export const create: (name: string, options: Options) => Tracer;
|
177
|
+
|
178
|
+
// ==> internals
|
179
|
+
|
180
|
+
/** @internal */
|
181
|
+
export interface CallableScope extends Scope {
|
182
|
+
(cb: (scope: Omit<Scope, 'end'>) => void): ReturnType<typeof cb>;
|
157
183
|
}
|
158
|
-
declare const create: (name: string, options: Options) => Tracer;
|
159
184
|
|
160
|
-
|
185
|
+
/** @internal */
|
186
|
+
export const PROMISES: WeakMap<Scope, Promise<any>[]>;
|
187
|
+
|
188
|
+
/** @internal */
|
189
|
+
export const ADD_PROMISE: (scope: Scope, promise: Promise<any>) => void;
|