rian 0.0.3 → 0.1.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/exporter.otel.http.js +1 -1
- package/exporter.otel.http.mjs +1 -1
- package/exporter.zipkin.js +7 -2
- package/exporter.zipkin.mjs +7 -2
- package/index.d.ts +1 -29
- package/index.js +49 -9
- package/index.mjs +48 -10
- package/package.json +5 -1
- package/utils.d.ts +43 -0
- package/utils.js +70 -0
- package/utils.mjs +67 -0
package/exporter.otel.http.js
CHANGED
@@ -19,7 +19,7 @@ const convert_value_to_anyvalue = (value) => {
|
|
19
19
|
any_value.arrayValue = {
|
20
20
|
values: value.map((i) => convert_value_to_anyvalue(i)),
|
21
21
|
};
|
22
|
-
else
|
22
|
+
else if (value)
|
23
23
|
any_value.kvlistValue = { values: convert_object_to_kv(value) };
|
24
24
|
return any_value;
|
25
25
|
};
|
package/exporter.otel.http.mjs
CHANGED
@@ -17,7 +17,7 @@ const convert_value_to_anyvalue = (value) => {
|
|
17
17
|
any_value.arrayValue = {
|
18
18
|
values: value.map((i) => convert_value_to_anyvalue(i)),
|
19
19
|
};
|
20
|
-
else
|
20
|
+
else if (value)
|
21
21
|
any_value.kvlistValue = { values: convert_object_to_kv(value) };
|
22
22
|
return any_value;
|
23
23
|
};
|
package/exporter.zipkin.js
CHANGED
@@ -26,8 +26,13 @@ const exporter = (request) => (spans, context) => {
|
|
26
26
|
kind: kind === 'INTERNAL' ? undefined : kind,
|
27
27
|
timestamp: span.start * 1000,
|
28
28
|
duration: span.end ? (span.end - span.start) * 1000 : undefined,
|
29
|
-
localEndpoint: context.localEndpoint
|
30
|
-
|
29
|
+
localEndpoint: context.localEndpoint || {
|
30
|
+
serviceName: span_ctx['service.name'],
|
31
|
+
},
|
32
|
+
tags: flattie.flattie({
|
33
|
+
...context,
|
34
|
+
...span_ctx,
|
35
|
+
}, '.', true),
|
31
36
|
annotations: span.events.map((i) => ({
|
32
37
|
value: `${i.name} :: ${JSON.stringify(i.attributes)}`,
|
33
38
|
timestamp: i.timestamp * 1000,
|
package/exporter.zipkin.mjs
CHANGED
@@ -24,8 +24,13 @@ const exporter = (request) => (spans, context) => {
|
|
24
24
|
kind: kind === 'INTERNAL' ? undefined : kind,
|
25
25
|
timestamp: span.start * 1000,
|
26
26
|
duration: span.end ? (span.end - span.start) * 1000 : undefined,
|
27
|
-
localEndpoint: context.localEndpoint
|
28
|
-
|
27
|
+
localEndpoint: context.localEndpoint || {
|
28
|
+
serviceName: span_ctx['service.name'],
|
29
|
+
},
|
30
|
+
tags: flattie({
|
31
|
+
...context,
|
32
|
+
...span_ctx,
|
33
|
+
}, '.', true),
|
29
34
|
annotations: span.events.map((i) => ({
|
30
35
|
value: `${i.name} :: ${JSON.stringify(i.attributes)}`,
|
31
36
|
timestamp: i.timestamp * 1000,
|
package/index.d.ts
CHANGED
@@ -1,8 +1,4 @@
|
|
1
1
|
import { Traceparent } from 'tctx';
|
2
|
-
import { Scope as Scope$1 } from 'rian';
|
3
|
-
|
4
|
-
declare type MeasureFn = ((...args: [...args: any[]]) => any) | ((...args: [...args: any[], scope: Scope$1]) => any);
|
5
|
-
declare type RealMeasureFnParams<T extends unknown[]> = T extends [] ? [] : T extends [...rest: infer U, scope: Scope$1] ? U : T;
|
6
2
|
|
7
3
|
/**
|
8
4
|
* Spans are units within a distributed trace. Spans encapsulate mainly 3 pieces of information, a
|
@@ -96,30 +92,6 @@ interface Scope {
|
|
96
92
|
* Forks the span into a new child span.
|
97
93
|
*/
|
98
94
|
fork(name: string): CallableScope;
|
99
|
-
/**
|
100
|
-
* With a passed function — will start a span, and run the function, when the function finishes
|
101
|
-
* the span finishes.
|
102
|
-
*
|
103
|
-
* The measure method will return whatever the function is, so if it's a promise, it returns a
|
104
|
-
* promise and so on. Any error is caught and re thrown, and automatically tracked in the
|
105
|
-
* context under the `error` property.
|
106
|
-
*
|
107
|
-
* All promises are tracked, and awaited on a `tracer.end`.
|
108
|
-
*
|
109
|
-
* @example
|
110
|
-
*
|
111
|
-
* ```text
|
112
|
-
* const data = await scope.measure('name', get_data, 'user_id_123');
|
113
|
-
* ^ ^ ^ ^
|
114
|
-
* | | | |
|
115
|
-
* | | | the first argument to get_data
|
116
|
-
* | | function to be called
|
117
|
-
* | the name of the sub scope
|
118
|
-
* return value from get_data
|
119
|
-
* ```
|
120
|
-
*/
|
121
|
-
measure<Fn extends MeasureFn>(name: string, fn: Fn, // TODO: fn doesnt see scope correctly
|
122
|
-
...args: RealMeasureFnParams<Parameters<Fn>>): ReturnType<Fn>;
|
123
95
|
/**
|
124
96
|
* Allows the span's context to be set. Passing an object will be `Object.assign`ed into the
|
125
97
|
* current context.
|
@@ -170,7 +142,7 @@ interface Options {
|
|
170
142
|
/**
|
171
143
|
* @borrows {@link Sampler}
|
172
144
|
*/
|
173
|
-
sampler?: Sampler;
|
145
|
+
sampler?: Sampler | boolean;
|
174
146
|
context?: Context;
|
175
147
|
/**
|
176
148
|
* A root, or extracted w3c traceparent stringed header.
|
package/index.js
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
const package_json = require('rian/package.json');
|
4
4
|
const tctx = require('tctx');
|
5
|
+
const rian = require('rian');
|
5
6
|
|
6
7
|
function _interopNamespace(e) {
|
7
8
|
if (e && e.__esModule) return e;
|
@@ -28,12 +29,11 @@ const set_error = (scope, error) => {
|
|
28
29
|
error,
|
29
30
|
});
|
30
31
|
};
|
31
|
-
const
|
32
|
-
scope, promises, ...args) => {
|
32
|
+
const measureFn = (scope, fn, ...args) => {
|
33
33
|
try {
|
34
34
|
var r = fn(...args, scope), is_promise = r instanceof Promise;
|
35
|
-
if (is_promise)
|
36
|
-
|
35
|
+
if (is_promise && rian.PROMISES.has(scope))
|
36
|
+
rian.ADD_PROMISE(scope, r
|
37
37
|
.catch((e) => void set_error(scope, e))
|
38
38
|
.finally(() => scope.end()));
|
39
39
|
return r;
|
@@ -47,8 +47,44 @@ scope, promises, ...args) => {
|
|
47
47
|
scope.end();
|
48
48
|
}
|
49
49
|
};
|
50
|
+
/**
|
51
|
+
* With a passed function — will start a span, and run the function, when the function finishes
|
52
|
+
* the span finishes.
|
53
|
+
*
|
54
|
+
* The measure method will return whatever the function is, so if it's a promise, it returns a
|
55
|
+
* promise and so on. Any error is caught and re thrown, and automatically tracked in the
|
56
|
+
* context under the `error` property.
|
57
|
+
*
|
58
|
+
* All promises are tracked, and awaited on a `tracer.end`.
|
59
|
+
*
|
60
|
+
* @example
|
61
|
+
*
|
62
|
+
* ```text
|
63
|
+
* const data = await measure(scope, get_data, 'user_id_123');
|
64
|
+
* ^ ^ ^
|
65
|
+
* | | |
|
66
|
+
* | | the first argument to get_data
|
67
|
+
* | function to be called
|
68
|
+
* return value from get_data
|
69
|
+
* ```
|
70
|
+
*/
|
71
|
+
const measure = (scope, fn, // TODO: fn doesnt see scope correctly
|
72
|
+
...args) => measureFn(scope, fn, ...args);
|
50
73
|
|
51
74
|
// ==> impl
|
75
|
+
/**
|
76
|
+
* @internal
|
77
|
+
*/
|
78
|
+
const PROMISES = new WeakMap();
|
79
|
+
/**
|
80
|
+
* @internal
|
81
|
+
*/
|
82
|
+
const ADD_PROMISE = (scope, promise) => {
|
83
|
+
if (PROMISES.has(scope))
|
84
|
+
PROMISES.get(scope).push(promise);
|
85
|
+
else
|
86
|
+
PROMISES.set(scope, [promise]);
|
87
|
+
};
|
52
88
|
/**
|
53
89
|
* The default sampler;
|
54
90
|
*
|
@@ -70,10 +106,12 @@ const sdk_object = {
|
|
70
106
|
};
|
71
107
|
const create = (name, options) => {
|
72
108
|
const spans = new Set();
|
73
|
-
const promises = [];
|
74
109
|
const sampler = options.sampler || defaultSampler;
|
110
|
+
const sampler_callable = typeof sampler !== 'boolean';
|
75
111
|
const span = (name, parent) => {
|
76
|
-
const should_sample =
|
112
|
+
const should_sample = sampler_callable
|
113
|
+
? sampler(name, parent, options.context)
|
114
|
+
: sampler;
|
77
115
|
const id = parent
|
78
116
|
? parent.child(should_sample)
|
79
117
|
: tctx__namespace.make(should_sample);
|
@@ -87,10 +125,9 @@ const create = (name, options) => {
|
|
87
125
|
};
|
88
126
|
if (should_sample)
|
89
127
|
spans.add(span_obj);
|
90
|
-
const $ = (cb) => measure(
|
128
|
+
const $ = (cb) => measure($, cb);
|
91
129
|
$.traceparent = id;
|
92
130
|
$.fork = (name) => span(name, id);
|
93
|
-
$.measure = (name, cb, ...args) => measure(cb, span(name, id), promises, ...args);
|
94
131
|
$.set_context = (ctx) => {
|
95
132
|
if (typeof ctx === 'function')
|
96
133
|
return void (span_obj.context = ctx(span_obj.context));
|
@@ -116,7 +153,8 @@ const create = (name, options) => {
|
|
116
153
|
const endRoot = root.end.bind(root);
|
117
154
|
root.end = async () => {
|
118
155
|
endRoot();
|
119
|
-
|
156
|
+
if (PROMISES.has(root))
|
157
|
+
await Promise.all(PROMISES.get(root));
|
120
158
|
return options.exporter(spans, {
|
121
159
|
...(options.context || {}),
|
122
160
|
...sdk_object,
|
@@ -125,4 +163,6 @@ const create = (name, options) => {
|
|
125
163
|
return root;
|
126
164
|
};
|
127
165
|
|
166
|
+
exports.ADD_PROMISE = ADD_PROMISE;
|
167
|
+
exports.PROMISES = PROMISES;
|
128
168
|
exports.create = create;
|
package/index.mjs
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
import { name, version } from 'rian/package.json';
|
2
2
|
import * as tctx from 'tctx';
|
3
|
+
import { PROMISES as PROMISES$1, ADD_PROMISE as ADD_PROMISE$1 } from 'rian';
|
3
4
|
|
4
5
|
const set_error = (scope, error) => {
|
5
6
|
scope.set_context({
|
6
7
|
error,
|
7
8
|
});
|
8
9
|
};
|
9
|
-
const
|
10
|
-
scope, promises, ...args) => {
|
10
|
+
const measureFn = (scope, fn, ...args) => {
|
11
11
|
try {
|
12
12
|
var r = fn(...args, scope), is_promise = r instanceof Promise;
|
13
|
-
if (is_promise)
|
14
|
-
|
13
|
+
if (is_promise && PROMISES$1.has(scope))
|
14
|
+
ADD_PROMISE$1(scope, r
|
15
15
|
.catch((e) => void set_error(scope, e))
|
16
16
|
.finally(() => scope.end()));
|
17
17
|
return r;
|
@@ -25,8 +25,44 @@ scope, promises, ...args) => {
|
|
25
25
|
scope.end();
|
26
26
|
}
|
27
27
|
};
|
28
|
+
/**
|
29
|
+
* With a passed function — will start a span, and run the function, when the function finishes
|
30
|
+
* the span finishes.
|
31
|
+
*
|
32
|
+
* The measure method will return whatever the function is, so if it's a promise, it returns a
|
33
|
+
* promise and so on. Any error is caught and re thrown, and automatically tracked in the
|
34
|
+
* context under the `error` property.
|
35
|
+
*
|
36
|
+
* All promises are tracked, and awaited on a `tracer.end`.
|
37
|
+
*
|
38
|
+
* @example
|
39
|
+
*
|
40
|
+
* ```text
|
41
|
+
* const data = await measure(scope, get_data, 'user_id_123');
|
42
|
+
* ^ ^ ^
|
43
|
+
* | | |
|
44
|
+
* | | the first argument to get_data
|
45
|
+
* | function to be called
|
46
|
+
* return value from get_data
|
47
|
+
* ```
|
48
|
+
*/
|
49
|
+
const measure = (scope, fn, // TODO: fn doesnt see scope correctly
|
50
|
+
...args) => measureFn(scope, fn, ...args);
|
28
51
|
|
29
52
|
// ==> impl
|
53
|
+
/**
|
54
|
+
* @internal
|
55
|
+
*/
|
56
|
+
const PROMISES = new WeakMap();
|
57
|
+
/**
|
58
|
+
* @internal
|
59
|
+
*/
|
60
|
+
const ADD_PROMISE = (scope, promise) => {
|
61
|
+
if (PROMISES.has(scope))
|
62
|
+
PROMISES.get(scope).push(promise);
|
63
|
+
else
|
64
|
+
PROMISES.set(scope, [promise]);
|
65
|
+
};
|
30
66
|
/**
|
31
67
|
* The default sampler;
|
32
68
|
*
|
@@ -48,10 +84,12 @@ const sdk_object = {
|
|
48
84
|
};
|
49
85
|
const create = (name, options) => {
|
50
86
|
const spans = new Set();
|
51
|
-
const promises = [];
|
52
87
|
const sampler = options.sampler || defaultSampler;
|
88
|
+
const sampler_callable = typeof sampler !== 'boolean';
|
53
89
|
const span = (name, parent) => {
|
54
|
-
const should_sample =
|
90
|
+
const should_sample = sampler_callable
|
91
|
+
? sampler(name, parent, options.context)
|
92
|
+
: sampler;
|
55
93
|
const id = parent
|
56
94
|
? parent.child(should_sample)
|
57
95
|
: tctx.make(should_sample);
|
@@ -65,10 +103,9 @@ const create = (name, options) => {
|
|
65
103
|
};
|
66
104
|
if (should_sample)
|
67
105
|
spans.add(span_obj);
|
68
|
-
const $ = (cb) => measure(
|
106
|
+
const $ = (cb) => measure($, cb);
|
69
107
|
$.traceparent = id;
|
70
108
|
$.fork = (name) => span(name, id);
|
71
|
-
$.measure = (name, cb, ...args) => measure(cb, span(name, id), promises, ...args);
|
72
109
|
$.set_context = (ctx) => {
|
73
110
|
if (typeof ctx === 'function')
|
74
111
|
return void (span_obj.context = ctx(span_obj.context));
|
@@ -94,7 +131,8 @@ const create = (name, options) => {
|
|
94
131
|
const endRoot = root.end.bind(root);
|
95
132
|
root.end = async () => {
|
96
133
|
endRoot();
|
97
|
-
|
134
|
+
if (PROMISES.has(root))
|
135
|
+
await Promise.all(PROMISES.get(root));
|
98
136
|
return options.exporter(spans, {
|
99
137
|
...(options.context || {}),
|
100
138
|
...sdk_object,
|
@@ -103,4 +141,4 @@ const create = (name, options) => {
|
|
103
141
|
return root;
|
104
142
|
};
|
105
143
|
|
106
|
-
export { create };
|
144
|
+
export { ADD_PROMISE, PROMISES, create };
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "rian",
|
3
|
-
"version": "0.0
|
3
|
+
"version": "0.1.0",
|
4
4
|
"description": "Effective tracing for the edge and origins",
|
5
5
|
"keywords": [
|
6
6
|
"opentelemetry",
|
@@ -37,6 +37,10 @@
|
|
37
37
|
"import": "./exporter.zipkin.mjs",
|
38
38
|
"require": "./exporter.zipkin.js"
|
39
39
|
},
|
40
|
+
"./utils": {
|
41
|
+
"import": "./utils.mjs",
|
42
|
+
"require": "./utils.js"
|
43
|
+
},
|
40
44
|
"./package.json": "./package.json"
|
41
45
|
},
|
42
46
|
"main": "./index.js",
|
package/utils.d.ts
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
import { Scope } from 'rian';
|
2
|
+
|
3
|
+
declare type MeasureFn = ((...args: [...args: any[]]) => any) | ((...args: [...args: any[], scope: Scope]) => any);
|
4
|
+
declare type RealMeasureFnParams<T extends unknown[]> = T extends [] ? [] : T extends [...rest: infer U, scope: Scope] ? U : T;
|
5
|
+
/**
|
6
|
+
* With a passed function — will start a span, and run the function, when the function finishes
|
7
|
+
* the span finishes.
|
8
|
+
*
|
9
|
+
* The measure method will return whatever the function is, so if it's a promise, it returns a
|
10
|
+
* promise and so on. Any error is caught and re thrown, and automatically tracked in the
|
11
|
+
* context under the `error` property.
|
12
|
+
*
|
13
|
+
* All promises are tracked, and awaited on a `tracer.end`.
|
14
|
+
*
|
15
|
+
* @example
|
16
|
+
*
|
17
|
+
* ```text
|
18
|
+
* const data = await measure(scope, get_data, 'user_id_123');
|
19
|
+
* ^ ^ ^
|
20
|
+
* | | |
|
21
|
+
* | | the first argument to get_data
|
22
|
+
* | function to be called
|
23
|
+
* return value from get_data
|
24
|
+
* ```
|
25
|
+
*/
|
26
|
+
declare const measure: <Fn extends MeasureFn>(scope: Scope, fn: Fn, ...args: RealMeasureFnParams<Parameters<Fn>>) => ReturnType<Fn>;
|
27
|
+
/**
|
28
|
+
* Wraps any function with a measured scoped function. Useful for when defer function execution
|
29
|
+
* till a later time.
|
30
|
+
*
|
31
|
+
* @example
|
32
|
+
*
|
33
|
+
* ```js
|
34
|
+
* const wrapped = wrap(scope, my_function);
|
35
|
+
*
|
36
|
+
* // ... lots of things, where the access to `scope` is lost.
|
37
|
+
*
|
38
|
+
* wrapped();
|
39
|
+
* ```
|
40
|
+
*/
|
41
|
+
declare const wrap: <Fn extends MeasureFn>(scope: Scope, fn: Fn) => Fn;
|
42
|
+
|
43
|
+
export { MeasureFn, measure, wrap };
|
package/utils.js
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
const rian = require('rian');
|
4
|
+
|
5
|
+
const set_error = (scope, error) => {
|
6
|
+
scope.set_context({
|
7
|
+
error,
|
8
|
+
});
|
9
|
+
};
|
10
|
+
const measureFn = (scope, fn, ...args) => {
|
11
|
+
try {
|
12
|
+
var r = fn(...args, scope), is_promise = r instanceof Promise;
|
13
|
+
if (is_promise && rian.PROMISES.has(scope))
|
14
|
+
rian.ADD_PROMISE(scope, r
|
15
|
+
.catch((e) => void set_error(scope, e))
|
16
|
+
.finally(() => scope.end()));
|
17
|
+
return r;
|
18
|
+
}
|
19
|
+
catch (e) {
|
20
|
+
set_error(scope, e);
|
21
|
+
throw e;
|
22
|
+
}
|
23
|
+
finally {
|
24
|
+
if (is_promise !== true)
|
25
|
+
scope.end();
|
26
|
+
}
|
27
|
+
};
|
28
|
+
/**
|
29
|
+
* With a passed function — will start a span, and run the function, when the function finishes
|
30
|
+
* the span finishes.
|
31
|
+
*
|
32
|
+
* The measure method will return whatever the function is, so if it's a promise, it returns a
|
33
|
+
* promise and so on. Any error is caught and re thrown, and automatically tracked in the
|
34
|
+
* context under the `error` property.
|
35
|
+
*
|
36
|
+
* All promises are tracked, and awaited on a `tracer.end`.
|
37
|
+
*
|
38
|
+
* @example
|
39
|
+
*
|
40
|
+
* ```text
|
41
|
+
* const data = await measure(scope, get_data, 'user_id_123');
|
42
|
+
* ^ ^ ^
|
43
|
+
* | | |
|
44
|
+
* | | the first argument to get_data
|
45
|
+
* | function to be called
|
46
|
+
* return value from get_data
|
47
|
+
* ```
|
48
|
+
*/
|
49
|
+
const measure = (scope, fn, // TODO: fn doesnt see scope correctly
|
50
|
+
...args) => measureFn(scope, fn, ...args);
|
51
|
+
/**
|
52
|
+
* Wraps any function with a measured scoped function. Useful for when defer function execution
|
53
|
+
* till a later time.
|
54
|
+
*
|
55
|
+
* @example
|
56
|
+
*
|
57
|
+
* ```js
|
58
|
+
* const wrapped = wrap(scope, my_function);
|
59
|
+
*
|
60
|
+
* // ... lots of things, where the access to `scope` is lost.
|
61
|
+
*
|
62
|
+
* wrapped();
|
63
|
+
* ```
|
64
|
+
*/
|
65
|
+
const wrap = (scope, fn) => function () {
|
66
|
+
return measureFn(scope, fn, ...arguments);
|
67
|
+
};
|
68
|
+
|
69
|
+
exports.measure = measure;
|
70
|
+
exports.wrap = wrap;
|
package/utils.mjs
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
import { PROMISES, ADD_PROMISE } from 'rian';
|
2
|
+
|
3
|
+
const set_error = (scope, error) => {
|
4
|
+
scope.set_context({
|
5
|
+
error,
|
6
|
+
});
|
7
|
+
};
|
8
|
+
const measureFn = (scope, fn, ...args) => {
|
9
|
+
try {
|
10
|
+
var r = fn(...args, scope), is_promise = r instanceof Promise;
|
11
|
+
if (is_promise && PROMISES.has(scope))
|
12
|
+
ADD_PROMISE(scope, r
|
13
|
+
.catch((e) => void set_error(scope, e))
|
14
|
+
.finally(() => scope.end()));
|
15
|
+
return r;
|
16
|
+
}
|
17
|
+
catch (e) {
|
18
|
+
set_error(scope, e);
|
19
|
+
throw e;
|
20
|
+
}
|
21
|
+
finally {
|
22
|
+
if (is_promise !== true)
|
23
|
+
scope.end();
|
24
|
+
}
|
25
|
+
};
|
26
|
+
/**
|
27
|
+
* With a passed function — will start a span, and run the function, when the function finishes
|
28
|
+
* the span finishes.
|
29
|
+
*
|
30
|
+
* The measure method will return whatever the function is, so if it's a promise, it returns a
|
31
|
+
* promise and so on. Any error is caught and re thrown, and automatically tracked in the
|
32
|
+
* context under the `error` property.
|
33
|
+
*
|
34
|
+
* All promises are tracked, and awaited on a `tracer.end`.
|
35
|
+
*
|
36
|
+
* @example
|
37
|
+
*
|
38
|
+
* ```text
|
39
|
+
* const data = await measure(scope, get_data, 'user_id_123');
|
40
|
+
* ^ ^ ^
|
41
|
+
* | | |
|
42
|
+
* | | the first argument to get_data
|
43
|
+
* | function to be called
|
44
|
+
* return value from get_data
|
45
|
+
* ```
|
46
|
+
*/
|
47
|
+
const measure = (scope, fn, // TODO: fn doesnt see scope correctly
|
48
|
+
...args) => measureFn(scope, fn, ...args);
|
49
|
+
/**
|
50
|
+
* Wraps any function with a measured scoped function. Useful for when defer function execution
|
51
|
+
* till a later time.
|
52
|
+
*
|
53
|
+
* @example
|
54
|
+
*
|
55
|
+
* ```js
|
56
|
+
* const wrapped = wrap(scope, my_function);
|
57
|
+
*
|
58
|
+
* // ... lots of things, where the access to `scope` is lost.
|
59
|
+
*
|
60
|
+
* wrapped();
|
61
|
+
* ```
|
62
|
+
*/
|
63
|
+
const wrap = (scope, fn) => function () {
|
64
|
+
return measureFn(scope, fn, ...arguments);
|
65
|
+
};
|
66
|
+
|
67
|
+
export { measure, wrap };
|