rian 0.0.5 → 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/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.
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 measure = (fn, // TODO: fn doesnt see scope correctly
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
- promises.push(r
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,7 +106,6 @@ 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;
75
110
  const sampler_callable = typeof sampler !== 'boolean';
76
111
  const span = (name, parent) => {
@@ -90,10 +125,9 @@ const create = (name, options) => {
90
125
  };
91
126
  if (should_sample)
92
127
  spans.add(span_obj);
93
- const $ = (cb) => measure(cb, $, promises);
128
+ const $ = (cb) => measure($, cb);
94
129
  $.traceparent = id;
95
130
  $.fork = (name) => span(name, id);
96
- $.measure = (name, cb, ...args) => measure(cb, span(name, id), promises, ...args);
97
131
  $.set_context = (ctx) => {
98
132
  if (typeof ctx === 'function')
99
133
  return void (span_obj.context = ctx(span_obj.context));
@@ -119,8 +153,8 @@ const create = (name, options) => {
119
153
  const endRoot = root.end.bind(root);
120
154
  root.end = async () => {
121
155
  endRoot();
122
- if (promises.length)
123
- await Promise.all(promises);
156
+ if (PROMISES.has(root))
157
+ await Promise.all(PROMISES.get(root));
124
158
  return options.exporter(spans, {
125
159
  ...(options.context || {}),
126
160
  ...sdk_object,
@@ -129,4 +163,6 @@ const create = (name, options) => {
129
163
  return root;
130
164
  };
131
165
 
166
+ exports.ADD_PROMISE = ADD_PROMISE;
167
+ exports.PROMISES = PROMISES;
132
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 measure = (fn, // TODO: fn doesnt see scope correctly
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
- promises.push(r
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,7 +84,6 @@ 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;
53
88
  const sampler_callable = typeof sampler !== 'boolean';
54
89
  const span = (name, parent) => {
@@ -68,10 +103,9 @@ const create = (name, options) => {
68
103
  };
69
104
  if (should_sample)
70
105
  spans.add(span_obj);
71
- const $ = (cb) => measure(cb, $, promises);
106
+ const $ = (cb) => measure($, cb);
72
107
  $.traceparent = id;
73
108
  $.fork = (name) => span(name, id);
74
- $.measure = (name, cb, ...args) => measure(cb, span(name, id), promises, ...args);
75
109
  $.set_context = (ctx) => {
76
110
  if (typeof ctx === 'function')
77
111
  return void (span_obj.context = ctx(span_obj.context));
@@ -97,8 +131,8 @@ const create = (name, options) => {
97
131
  const endRoot = root.end.bind(root);
98
132
  root.end = async () => {
99
133
  endRoot();
100
- if (promises.length)
101
- await Promise.all(promises);
134
+ if (PROMISES.has(root))
135
+ await Promise.all(PROMISES.get(root));
102
136
  return options.exporter(spans, {
103
137
  ...(options.context || {}),
104
138
  ...sdk_object,
@@ -107,4 +141,4 @@ const create = (name, options) => {
107
141
  return root;
108
142
  };
109
143
 
110
- 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.5",
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 };