rian 0.0.4 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
  };
@@ -79,6 +79,7 @@ const exporter = (request) => (spans, context) => {
79
79
  droppedEventsCount: 0,
80
80
  droppedLinksCount: 0,
81
81
  attributes: convert_object_to_kv(span_ctx),
82
+ // @ts-expect-error TS2454
82
83
  status: status || { code: SpanStatusCode_UNSET },
83
84
  events: span.events.map((i) => ({
84
85
  name: i.name,
@@ -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
  };
@@ -77,6 +77,7 @@ const exporter = (request) => (spans, context) => {
77
77
  droppedEventsCount: 0,
78
78
  droppedLinksCount: 0,
79
79
  attributes: convert_object_to_kv(span_ctx),
80
+ // @ts-expect-error TS2454
80
81
  status: status || { code: SpanStatusCode_UNSET },
81
82
  events: span.events.map((i) => ({
82
83
  name: i.name,
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 utils = require('rian/utils');
5
6
 
6
7
  function _interopNamespace(e) {
7
8
  if (e && e.__esModule) return e;
@@ -23,32 +24,20 @@ function _interopNamespace(e) {
23
24
 
24
25
  const tctx__namespace = /*#__PURE__*/_interopNamespace(tctx);
25
26
 
26
- const set_error = (scope, error) => {
27
- scope.set_context({
28
- error,
29
- });
30
- };
31
- const measure = (fn, // TODO: fn doesnt see scope correctly
32
- scope, promises, ...args) => {
33
- try {
34
- var r = fn(...args, scope), is_promise = r instanceof Promise;
35
- if (is_promise)
36
- promises.push(r
37
- .catch((e) => void set_error(scope, e))
38
- .finally(() => scope.end()));
39
- return r;
40
- }
41
- catch (e) {
42
- set_error(scope, e);
43
- throw e;
44
- }
45
- finally {
46
- if (is_promise !== true)
47
- scope.end();
48
- }
49
- };
50
-
51
27
  // ==> impl
28
+ /**
29
+ * @internal
30
+ */
31
+ const PROMISES = new WeakMap();
32
+ /**
33
+ * @internal
34
+ */
35
+ const ADD_PROMISE = (scope, promise) => {
36
+ if (PROMISES.has(scope))
37
+ PROMISES.get(scope).push(promise);
38
+ else
39
+ PROMISES.set(scope, [promise]);
40
+ };
52
41
  /**
53
42
  * The default sampler;
54
43
  *
@@ -70,10 +59,12 @@ const sdk_object = {
70
59
  };
71
60
  const create = (name, options) => {
72
61
  const spans = new Set();
73
- const promises = [];
74
62
  const sampler = options.sampler || defaultSampler;
63
+ const sampler_callable = typeof sampler !== 'boolean';
75
64
  const span = (name, parent) => {
76
- const should_sample = sampler(name, parent, options.context);
65
+ const should_sample = sampler_callable
66
+ ? sampler(name, parent, options.context)
67
+ : sampler;
77
68
  const id = parent
78
69
  ? parent.child(should_sample)
79
70
  : tctx__namespace.make(should_sample);
@@ -87,10 +78,10 @@ const create = (name, options) => {
87
78
  };
88
79
  if (should_sample)
89
80
  spans.add(span_obj);
90
- const $ = (cb) => measure(cb, $, promises);
81
+ const $ = (cb) => utils.measureFn($, cb);
91
82
  $.traceparent = id;
92
83
  $.fork = (name) => span(name, id);
93
- $.measure = (name, cb, ...args) => measure(cb, span(name, id), promises, ...args);
84
+ // @ts-expect-error TS7030 its always undefined ts :eye-roll:
94
85
  $.set_context = (ctx) => {
95
86
  if (typeof ctx === 'function')
96
87
  return void (span_obj.context = ctx(span_obj.context));
@@ -104,9 +95,8 @@ const create = (name, options) => {
104
95
  });
105
96
  };
106
97
  $.end = () => {
107
- if (span_obj.end)
108
- return void 0;
109
- span_obj.end = Date.now();
98
+ if (span_obj.end == null)
99
+ span_obj.end = Date.now();
110
100
  };
111
101
  return $;
112
102
  };
@@ -116,7 +106,8 @@ const create = (name, options) => {
116
106
  const endRoot = root.end.bind(root);
117
107
  root.end = async () => {
118
108
  endRoot();
119
- await Promise.all(promises);
109
+ if (PROMISES.has(root))
110
+ await Promise.all(PROMISES.get(root));
120
111
  return options.exporter(spans, {
121
112
  ...(options.context || {}),
122
113
  ...sdk_object,
@@ -125,4 +116,6 @@ const create = (name, options) => {
125
116
  return root;
126
117
  };
127
118
 
119
+ exports.ADD_PROMISE = ADD_PROMISE;
120
+ exports.PROMISES = PROMISES;
128
121
  exports.create = create;
package/index.mjs CHANGED
@@ -1,32 +1,21 @@
1
1
  import { name, version } from 'rian/package.json';
2
2
  import * as tctx from 'tctx';
3
-
4
- const set_error = (scope, error) => {
5
- scope.set_context({
6
- error,
7
- });
8
- };
9
- const measure = (fn, // TODO: fn doesnt see scope correctly
10
- scope, promises, ...args) => {
11
- try {
12
- var r = fn(...args, scope), is_promise = r instanceof Promise;
13
- if (is_promise)
14
- promises.push(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
- };
3
+ import { measureFn } from 'rian/utils';
28
4
 
29
5
  // ==> impl
6
+ /**
7
+ * @internal
8
+ */
9
+ const PROMISES = new WeakMap();
10
+ /**
11
+ * @internal
12
+ */
13
+ const ADD_PROMISE = (scope, promise) => {
14
+ if (PROMISES.has(scope))
15
+ PROMISES.get(scope).push(promise);
16
+ else
17
+ PROMISES.set(scope, [promise]);
18
+ };
30
19
  /**
31
20
  * The default sampler;
32
21
  *
@@ -48,10 +37,12 @@ const sdk_object = {
48
37
  };
49
38
  const create = (name, options) => {
50
39
  const spans = new Set();
51
- const promises = [];
52
40
  const sampler = options.sampler || defaultSampler;
41
+ const sampler_callable = typeof sampler !== 'boolean';
53
42
  const span = (name, parent) => {
54
- const should_sample = sampler(name, parent, options.context);
43
+ const should_sample = sampler_callable
44
+ ? sampler(name, parent, options.context)
45
+ : sampler;
55
46
  const id = parent
56
47
  ? parent.child(should_sample)
57
48
  : tctx.make(should_sample);
@@ -65,10 +56,10 @@ const create = (name, options) => {
65
56
  };
66
57
  if (should_sample)
67
58
  spans.add(span_obj);
68
- const $ = (cb) => measure(cb, $, promises);
59
+ const $ = (cb) => measureFn($, cb);
69
60
  $.traceparent = id;
70
61
  $.fork = (name) => span(name, id);
71
- $.measure = (name, cb, ...args) => measure(cb, span(name, id), promises, ...args);
62
+ // @ts-expect-error TS7030 its always undefined ts :eye-roll:
72
63
  $.set_context = (ctx) => {
73
64
  if (typeof ctx === 'function')
74
65
  return void (span_obj.context = ctx(span_obj.context));
@@ -82,9 +73,8 @@ const create = (name, options) => {
82
73
  });
83
74
  };
84
75
  $.end = () => {
85
- if (span_obj.end)
86
- return void 0;
87
- span_obj.end = Date.now();
76
+ if (span_obj.end == null)
77
+ span_obj.end = Date.now();
88
78
  };
89
79
  return $;
90
80
  };
@@ -94,7 +84,8 @@ const create = (name, options) => {
94
84
  const endRoot = root.end.bind(root);
95
85
  root.end = async () => {
96
86
  endRoot();
97
- await Promise.all(promises);
87
+ if (PROMISES.has(root))
88
+ await Promise.all(PROMISES.get(root));
98
89
  return options.exporter(spans, {
99
90
  ...(options.context || {}),
100
91
  ...sdk_object,
@@ -103,4 +94,4 @@ const create = (name, options) => {
103
94
  return root;
104
95
  };
105
96
 
106
- export { create };
97
+ export { ADD_PROMISE, PROMISES, create };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rian",
3
- "version": "0.0.4",
3
+ "version": "0.1.1",
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,46 @@
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, 'name', get_data, 'user_id_123');
19
+ * ^ ^ ^ ^ ^
20
+ * | | | | |
21
+ * | | | | the first argument to get_data
22
+ * | | | function to be called
23
+ * | | the name of the sub scope
24
+ * | |
25
+ * | the parent scope
26
+ * return value from get_data
27
+ * ```
28
+ */
29
+ declare const measure: <Fn extends MeasureFn>(scope: Scope, name: string, fn: Fn, ...args: RealMeasureFnParams<Parameters<Fn>>) => ReturnType<Fn>;
30
+ /**
31
+ * Wraps any function with a measured scoped function. Useful for when defer function execution
32
+ * till a later time.
33
+ *
34
+ * @example
35
+ *
36
+ * ```js
37
+ * const wrapped = wrap(scope, "run something", my_function);
38
+ *
39
+ * // ... lots of things, where the access to `scope` is lost.
40
+ *
41
+ * wrapped();
42
+ * ```
43
+ */
44
+ declare const wrap: <Fn extends MeasureFn>(scope: Scope, name: string, fn: Fn) => Fn;
45
+
46
+ export { MeasureFn, measure, wrap };
package/utils.js ADDED
@@ -0,0 +1,79 @@
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
+ /**
11
+ * @internal
12
+ */
13
+ const measureFn = (scope, fn, ...args) => {
14
+ try {
15
+ var r = fn(...args, scope), is_promise = r instanceof Promise;
16
+ if (is_promise && rian.PROMISES.has(scope))
17
+ rian.ADD_PROMISE(scope, r
18
+ .catch((e) => void set_error(scope, e))
19
+ .finally(() => scope.end()));
20
+ return r;
21
+ }
22
+ catch (e) {
23
+ if (e instanceof Error)
24
+ set_error(scope, e);
25
+ throw e;
26
+ }
27
+ finally {
28
+ // @ts-expect-error TS2454
29
+ if (is_promise !== true)
30
+ scope.end();
31
+ }
32
+ };
33
+ /**
34
+ * With a passed function — will start a span, and run the function, when the function finishes
35
+ * the span finishes.
36
+ *
37
+ * The measure method will return whatever the function is, so if it's a promise, it returns a
38
+ * promise and so on. Any error is caught and re thrown, and automatically tracked in the
39
+ * context under the `error` property.
40
+ *
41
+ * All promises are tracked, and awaited on a `tracer.end`.
42
+ *
43
+ * @example
44
+ *
45
+ * ```text
46
+ * const data = await measure(scope, 'name', get_data, 'user_id_123');
47
+ * ^ ^ ^ ^ ^
48
+ * | | | | |
49
+ * | | | | the first argument to get_data
50
+ * | | | function to be called
51
+ * | | the name of the sub scope
52
+ * | |
53
+ * | the parent scope
54
+ * return value from get_data
55
+ * ```
56
+ */
57
+ const measure = (scope, name, fn, // TODO: fn doesnt see scope correctly
58
+ ...args) => measureFn(scope.fork(name), fn, ...args);
59
+ /**
60
+ * Wraps any function with a measured scoped function. Useful for when defer function execution
61
+ * till a later time.
62
+ *
63
+ * @example
64
+ *
65
+ * ```js
66
+ * const wrapped = wrap(scope, "run something", my_function);
67
+ *
68
+ * // ... lots of things, where the access to `scope` is lost.
69
+ *
70
+ * wrapped();
71
+ * ```
72
+ */
73
+ const wrap = (scope, name, fn) => function () {
74
+ return measureFn(scope.fork(name), fn, ...arguments);
75
+ };
76
+
77
+ exports.measure = measure;
78
+ exports.measureFn = measureFn;
79
+ exports.wrap = wrap;
package/utils.mjs ADDED
@@ -0,0 +1,75 @@
1
+ import { PROMISES, ADD_PROMISE } from 'rian';
2
+
3
+ const set_error = (scope, error) => {
4
+ scope.set_context({
5
+ error,
6
+ });
7
+ };
8
+ /**
9
+ * @internal
10
+ */
11
+ const measureFn = (scope, fn, ...args) => {
12
+ try {
13
+ var r = fn(...args, scope), is_promise = r instanceof Promise;
14
+ if (is_promise && PROMISES.has(scope))
15
+ ADD_PROMISE(scope, r
16
+ .catch((e) => void set_error(scope, e))
17
+ .finally(() => scope.end()));
18
+ return r;
19
+ }
20
+ catch (e) {
21
+ if (e instanceof Error)
22
+ set_error(scope, e);
23
+ throw e;
24
+ }
25
+ finally {
26
+ // @ts-expect-error TS2454
27
+ if (is_promise !== true)
28
+ scope.end();
29
+ }
30
+ };
31
+ /**
32
+ * With a passed function — will start a span, and run the function, when the function finishes
33
+ * the span finishes.
34
+ *
35
+ * The measure method will return whatever the function is, so if it's a promise, it returns a
36
+ * promise and so on. Any error is caught and re thrown, and automatically tracked in the
37
+ * context under the `error` property.
38
+ *
39
+ * All promises are tracked, and awaited on a `tracer.end`.
40
+ *
41
+ * @example
42
+ *
43
+ * ```text
44
+ * const data = await measure(scope, 'name', get_data, 'user_id_123');
45
+ * ^ ^ ^ ^ ^
46
+ * | | | | |
47
+ * | | | | the first argument to get_data
48
+ * | | | function to be called
49
+ * | | the name of the sub scope
50
+ * | |
51
+ * | the parent scope
52
+ * return value from get_data
53
+ * ```
54
+ */
55
+ const measure = (scope, name, fn, // TODO: fn doesnt see scope correctly
56
+ ...args) => measureFn(scope.fork(name), fn, ...args);
57
+ /**
58
+ * Wraps any function with a measured scoped function. Useful for when defer function execution
59
+ * till a later time.
60
+ *
61
+ * @example
62
+ *
63
+ * ```js
64
+ * const wrapped = wrap(scope, "run something", my_function);
65
+ *
66
+ * // ... lots of things, where the access to `scope` is lost.
67
+ *
68
+ * wrapped();
69
+ * ```
70
+ */
71
+ const wrap = (scope, name, fn) => function () {
72
+ return measureFn(scope.fork(name), fn, ...arguments);
73
+ };
74
+
75
+ export { measure, measureFn, wrap };