rian 0.0.4 → 0.1.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.
@@ -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 };