@qlever-llc/trellis 0.10.11 → 0.10.13

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.
Files changed (124) hide show
  1. package/esm/contract_support/mod.d.ts +1 -0
  2. package/esm/contract_support/mod.d.ts.map +1 -1
  3. package/esm/contract_support/mod.js +1 -0
  4. package/esm/contract_support/schema_pointers.d.ts +6 -0
  5. package/esm/contract_support/schema_pointers.d.ts.map +1 -1
  6. package/esm/contract_support/schema_pointers.js +59 -7
  7. package/esm/errors/TrellisError.d.ts +3 -3
  8. package/esm/errors/TrellisError.js +3 -3
  9. package/esm/server/internal_jobs/job-manager.d.ts.map +1 -1
  10. package/esm/server/internal_jobs/job-manager.js +32 -1
  11. package/esm/server/runtime.d.ts +3 -0
  12. package/esm/server/runtime.d.ts.map +1 -1
  13. package/esm/server/service.d.ts +15 -0
  14. package/esm/server/service.d.ts.map +1 -1
  15. package/esm/server/service.js +8 -0
  16. package/esm/server.d.ts.map +1 -1
  17. package/esm/server.js +54 -6
  18. package/esm/service/deno.d.ts +1 -1
  19. package/esm/service/deno.d.ts.map +1 -1
  20. package/esm/service/mod.d.ts +1 -1
  21. package/esm/service/mod.d.ts.map +1 -1
  22. package/esm/service/node.d.ts +1 -1
  23. package/esm/service/node.d.ts.map +1 -1
  24. package/esm/service/outbox_inbox.d.ts.map +1 -1
  25. package/esm/service/outbox_inbox.js +14 -0
  26. package/esm/telemetry/core.d.ts.map +1 -1
  27. package/esm/telemetry/core.js +1 -1
  28. package/esm/telemetry/env.d.ts.map +1 -1
  29. package/esm/telemetry/env.js +6 -1
  30. package/esm/telemetry/init.d.ts +3 -0
  31. package/esm/telemetry/init.d.ts.map +1 -0
  32. package/esm/telemetry/init.js +7 -0
  33. package/esm/telemetry/metrics.d.ts +34 -0
  34. package/esm/telemetry/metrics.d.ts.map +1 -0
  35. package/esm/telemetry/metrics.js +181 -0
  36. package/esm/telemetry/mod.d.ts +3 -0
  37. package/esm/telemetry/mod.d.ts.map +1 -1
  38. package/esm/telemetry/mod.js +2 -0
  39. package/esm/telemetry/runtime.d.ts +2 -0
  40. package/esm/telemetry/runtime.d.ts.map +1 -0
  41. package/esm/telemetry/runtime.js +134 -0
  42. package/esm/telemetry.d.ts +3 -0
  43. package/esm/telemetry.d.ts.map +1 -0
  44. package/esm/telemetry.js +2 -0
  45. package/esm/transfer.d.ts.map +1 -1
  46. package/esm/transfer.js +27 -16
  47. package/esm/trellis.d.ts.map +1 -1
  48. package/esm/trellis.js +460 -56
  49. package/package.json +7 -5
  50. package/script/contract_support/mod.d.ts +1 -0
  51. package/script/contract_support/mod.d.ts.map +1 -1
  52. package/script/contract_support/mod.js +4 -1
  53. package/script/contract_support/schema_pointers.d.ts +6 -0
  54. package/script/contract_support/schema_pointers.d.ts.map +1 -1
  55. package/script/contract_support/schema_pointers.js +59 -7
  56. package/script/errors/TrellisError.d.ts +3 -3
  57. package/script/errors/TrellisError.js +3 -3
  58. package/script/server/internal_jobs/job-manager.d.ts.map +1 -1
  59. package/script/server/internal_jobs/job-manager.js +32 -1
  60. package/script/server/runtime.d.ts +3 -0
  61. package/script/server/runtime.d.ts.map +1 -1
  62. package/script/server/service.d.ts +15 -0
  63. package/script/server/service.d.ts.map +1 -1
  64. package/script/server/service.js +8 -0
  65. package/script/server.d.ts.map +1 -1
  66. package/script/server.js +54 -6
  67. package/script/service/deno.d.ts +1 -1
  68. package/script/service/deno.d.ts.map +1 -1
  69. package/script/service/mod.d.ts +1 -1
  70. package/script/service/mod.d.ts.map +1 -1
  71. package/script/service/node.d.ts +1 -1
  72. package/script/service/node.d.ts.map +1 -1
  73. package/script/service/outbox_inbox.d.ts.map +1 -1
  74. package/script/service/outbox_inbox.js +14 -0
  75. package/script/telemetry/core.d.ts.map +1 -1
  76. package/script/telemetry/core.js +1 -1
  77. package/script/telemetry/env.d.ts.map +1 -1
  78. package/script/telemetry/env.js +6 -1
  79. package/script/telemetry/init.d.ts +3 -0
  80. package/script/telemetry/init.d.ts.map +1 -0
  81. package/script/telemetry/init.js +10 -0
  82. package/script/telemetry/metrics.d.ts +34 -0
  83. package/script/telemetry/metrics.d.ts.map +1 -0
  84. package/script/telemetry/metrics.js +186 -0
  85. package/script/telemetry/mod.d.ts +3 -0
  86. package/script/telemetry/mod.d.ts.map +1 -1
  87. package/script/telemetry/mod.js +7 -1
  88. package/script/telemetry/runtime.d.ts +2 -0
  89. package/script/telemetry/runtime.d.ts.map +1 -0
  90. package/script/telemetry/runtime.js +137 -0
  91. package/script/telemetry.d.ts +3 -0
  92. package/script/telemetry.d.ts.map +1 -0
  93. package/script/telemetry.js +18 -0
  94. package/script/transfer.d.ts.map +1 -1
  95. package/script/transfer.js +28 -17
  96. package/script/trellis.d.ts.map +1 -1
  97. package/script/trellis.js +490 -86
  98. package/src/contract_support/mod.ts +4 -0
  99. package/src/contract_support/schema_pointers.ts +80 -7
  100. package/src/errors/TrellisError.ts +4 -4
  101. package/src/server/internal_jobs/job-manager.ts +35 -5
  102. package/src/server/runtime.ts +4 -0
  103. package/src/server/service.ts +27 -0
  104. package/src/server.ts +66 -11
  105. package/src/service/deno.ts +1 -0
  106. package/src/service/mod.ts +1 -0
  107. package/src/service/node.ts +1 -0
  108. package/src/service/outbox_inbox.ts +14 -0
  109. package/src/telemetry/core.ts +1 -1
  110. package/src/telemetry/env.ts +5 -1
  111. package/src/telemetry/init.ts +8 -0
  112. package/src/telemetry/metrics.ts +294 -0
  113. package/src/telemetry/mod.ts +7 -0
  114. package/src/telemetry/runtime.ts +218 -0
  115. package/src/telemetry.ts +2 -0
  116. package/src/transfer.ts +69 -30
  117. package/src/trellis.ts +487 -88
  118. package/esm/tracing.d.ts +0 -5
  119. package/esm/tracing.d.ts.map +0 -1
  120. package/esm/tracing.js +0 -8
  121. package/script/tracing.d.ts +0 -5
  122. package/script/tracing.d.ts.map +0 -1
  123. package/script/tracing.js +0 -27
  124. package/src/tracing.ts +0 -28
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getTrellisMeter = getTrellisMeter;
4
+ exports.recordTrellisError = recordTrellisError;
5
+ exports.buildTrellisErrorMetricAttributes = buildTrellisErrorMetricAttributes;
6
+ const api_1 = require("@opentelemetry/api");
7
+ const TRELLIS_METER_NAME = "@qlever-llc/trellis";
8
+ const MAX_ATTRIBUTE_LENGTH = 96;
9
+ const LOW_CARDINALITY_PATTERN = /^[A-Za-z0-9_.:-]+$/;
10
+ const UUID_PATTERN = /(^|[_.:-])[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}($|[_.:-])/i;
11
+ const ULID_PATTERN = /(^|[_.:-])[0-7][0-9A-HJKMNP-TV-Z]{25}($|[_.:-])/i;
12
+ const LONG_HEX_SEGMENT_PATTERN = /(^|[_.:-])[0-9a-f]{12,}($|[_.:-])/i;
13
+ const TRELLIS_SUBJECT_PREFIX_PATTERN = /^(rpc|events|feeds|operations|jobs|state|kv|store|resources|transfer)\.v\d+\./;
14
+ const AUTH_REASONS = new Set([
15
+ "invalid_request",
16
+ "missing_session_key",
17
+ "missing_proof",
18
+ "session_not_found",
19
+ "session_expired",
20
+ "invalid_signature",
21
+ "user_not_found",
22
+ "user_already_exists",
23
+ "username_taken",
24
+ "identity_already_exists",
25
+ "identity_not_found",
26
+ "user_inactive",
27
+ "unknown_device",
28
+ "device_deployment_not_found",
29
+ "device_deployment_disabled",
30
+ "device_activation_revoked",
31
+ "unknown_service",
32
+ "service_disabled",
33
+ "iat_out_of_range",
34
+ "invalid_binding_token",
35
+ "session_corrupted",
36
+ "session_already_bound",
37
+ "authtoken_already_used",
38
+ "oauth_session_key_mismatch",
39
+ "reply_subject_mismatch",
40
+ "insufficient_permissions",
41
+ "forbidden",
42
+ "last_admin_required",
43
+ "missing_flow_id",
44
+ "device_activation_flow_not_found",
45
+ "device_activation_flow_expired",
46
+ "device_activation_rejected",
47
+ "device_identity_key_mismatch",
48
+ "invalid_device_qr_mac",
49
+ ]);
50
+ /** Returns the shared Trellis OpenTelemetry meter. */
51
+ function getTrellisMeter() {
52
+ return api_1.metrics.getMeter(TRELLIS_METER_NAME);
53
+ }
54
+ /** Records one Trellis error with only stable, low-cardinality attributes. */
55
+ function recordTrellisError(error, attributes = {}) {
56
+ getTrellisMeter().createCounter("trellis.errors", {
57
+ description: "Trellis errors observed by runtime instrumentation.",
58
+ unit: "{error}",
59
+ }).add(1, buildTrellisErrorMetricAttributes(error, attributes));
60
+ }
61
+ /**
62
+ * Builds sanitized, low-cardinality attributes for `trellis.errors`.
63
+ *
64
+ * @internal Exported for focused tests; runtime callers should use
65
+ * {@link recordTrellisError}.
66
+ */
67
+ function buildTrellisErrorMetricAttributes(error, attributes = {}) {
68
+ const serializable = serializableErrorData(error);
69
+ const metricAttributes = {
70
+ "exception.type": exceptionType(error),
71
+ "trellis.error.type": trellisErrorType(error, serializable, attributes.errorType),
72
+ };
73
+ const remoteErrorType = lowCardinalityValue(attributes.remoteErrorType) ??
74
+ remoteSerializableErrorType(serializable);
75
+ if (remoteErrorType) {
76
+ metricAttributes["trellis.remote_error.type"] = remoteErrorType;
77
+ }
78
+ setLowCardinalityAttribute(metricAttributes, "trellis.surface", attributes.surface);
79
+ setLowCardinalityAttribute(metricAttributes, "trellis.direction", attributes.direction);
80
+ setLowCardinalityAttribute(metricAttributes, "trellis.operation", attributes.operation);
81
+ setLowCardinalityAttribute(metricAttributes, "trellis.phase", attributes.phase);
82
+ setLowCardinalityAttribute(metricAttributes, "trellis.auth.reason", boundedAuthReason(attributes.authReason) ?? authReason(serializable));
83
+ setLowCardinalityAttribute(metricAttributes, "messaging.system", attributes.messagingSystem);
84
+ setLowCardinalityAttribute(metricAttributes, "messaging.operation", attributes.messagingOperation);
85
+ return metricAttributes;
86
+ }
87
+ function trellisErrorType(error, serializable, override) {
88
+ const overrideType = lowCardinalityValue(override);
89
+ if (overrideType)
90
+ return overrideType;
91
+ const serializableType = lowCardinalityValue(serializable?.type);
92
+ if (serializableType)
93
+ return serializableType;
94
+ const objectType = objectStringProperty(error, "type");
95
+ if (objectType)
96
+ return objectType;
97
+ return exceptionType(error);
98
+ }
99
+ function exceptionType(error) {
100
+ if (error instanceof Error) {
101
+ const name = lowCardinalityValue(error.name);
102
+ if (name)
103
+ return name;
104
+ }
105
+ const objectType = objectStringProperty(error, "type");
106
+ if (objectType)
107
+ return objectType;
108
+ return "unknown";
109
+ }
110
+ function serializableErrorData(error) {
111
+ const toSerializable = safeProperty(error, "toSerializable");
112
+ if (!isSerializableMethod(toSerializable))
113
+ return undefined;
114
+ try {
115
+ const data = toSerializable.call(error);
116
+ return isRecord(data) ? data : undefined;
117
+ }
118
+ catch {
119
+ return undefined;
120
+ }
121
+ }
122
+ function remoteSerializableErrorType(serializable) {
123
+ const remoteError = safeProperty(serializable, "remoteError");
124
+ if (!isRecord(remoteError))
125
+ return undefined;
126
+ return objectStringProperty(remoteError, "type");
127
+ }
128
+ function authReason(serializable) {
129
+ const type = safeProperty(serializable, "type");
130
+ if (type === "AuthError") {
131
+ return boundedAuthReason(safeProperty(serializable, "reason"));
132
+ }
133
+ if (type === "RemoteError") {
134
+ const remoteError = safeProperty(serializable, "remoteError");
135
+ if (isRecord(remoteError) && objectStringProperty(remoteError, "type") ===
136
+ "AuthError") {
137
+ return boundedAuthReason(safeProperty(remoteError, "reason"));
138
+ }
139
+ }
140
+ return undefined;
141
+ }
142
+ function boundedAuthReason(value) {
143
+ const sanitized = lowCardinalityValue(value);
144
+ if (!sanitized || !AUTH_REASONS.has(sanitized))
145
+ return undefined;
146
+ return sanitized;
147
+ }
148
+ function isRecord(value) {
149
+ return value !== null && typeof value === "object" && !Array.isArray(value);
150
+ }
151
+ function isSerializableMethod(value) {
152
+ return typeof value === "function";
153
+ }
154
+ function safeProperty(value, key) {
155
+ if (!isRecord(value))
156
+ return undefined;
157
+ try {
158
+ return value[key];
159
+ }
160
+ catch {
161
+ return undefined;
162
+ }
163
+ }
164
+ function objectStringProperty(value, key) {
165
+ return lowCardinalityValue(safeProperty(value, key));
166
+ }
167
+ function setLowCardinalityAttribute(attributes, key, value) {
168
+ const sanitized = lowCardinalityValue(value);
169
+ if (sanitized)
170
+ attributes[key] = sanitized;
171
+ }
172
+ function lowCardinalityValue(value) {
173
+ if (typeof value !== "string")
174
+ return undefined;
175
+ const trimmed = value.trim();
176
+ if (trimmed.length === 0 ||
177
+ trimmed.length > MAX_ATTRIBUTE_LENGTH ||
178
+ !LOW_CARDINALITY_PATTERN.test(trimmed) ||
179
+ UUID_PATTERN.test(trimmed) ||
180
+ ULID_PATTERN.test(trimmed) ||
181
+ LONG_HEX_SEGMENT_PATTERN.test(trimmed) ||
182
+ TRELLIS_SUBJECT_PREFIX_PATTERN.test(trimmed)) {
183
+ return undefined;
184
+ }
185
+ return trimmed;
186
+ }
@@ -3,6 +3,9 @@ export { createMapCarrier, extractTraceContext, injectTraceContext, } from "./ca
3
3
  export type { Context, Span } from "./core.js";
4
4
  export { context, getActiveSpan, getTracer, SpanKind, SpanStatusCode, trace, withSpan, withSpanAsync, } from "./core.js";
5
5
  export { getEnv } from "./env.js";
6
+ export { initTelemetry } from "./init.js";
7
+ export { buildTrellisErrorMetricAttributes, getTrellisMeter, recordTrellisError, } from "./metrics.js";
8
+ export type { TrellisErrorMetricAttributes } from "./metrics.js";
6
9
  export type { NatsHeadersLike } from "./nats.js";
7
10
  export { createNatsHeaderCarrier } from "./nats.js";
8
11
  export { configureErrorTraceId } from "./result.js";
@@ -1 +1 @@
1
- {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/telemetry/mod.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EACL,OAAO,EACP,aAAa,EACb,SAAS,EACT,QAAQ,EACR,cAAc,EACd,KAAK,EACL,QAAQ,EACR,aAAa,GACd,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,eAAe,GAChB,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/telemetry/mod.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EACL,OAAO,EACP,aAAa,EACb,SAAS,EACT,QAAQ,EACR,cAAc,EACd,KAAK,EACL,QAAQ,EACR,aAAa,GACd,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EACL,iCAAiC,EACjC,eAAe,EACf,kBAAkB,GACnB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,4BAA4B,EAAE,MAAM,cAAc,CAAC;AACjE,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,eAAe,GAChB,MAAM,cAAc,CAAC"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.startServerSpan = exports.startClientSpan = exports.getTrellisTracer = exports.configureErrorTraceId = exports.createNatsHeaderCarrier = exports.getEnv = exports.withSpanAsync = exports.withSpan = exports.trace = exports.SpanStatusCode = exports.SpanKind = exports.getTracer = exports.getActiveSpan = exports.context = exports.injectTraceContext = exports.extractTraceContext = exports.createMapCarrier = void 0;
3
+ exports.startServerSpan = exports.startClientSpan = exports.getTrellisTracer = exports.configureErrorTraceId = exports.createNatsHeaderCarrier = exports.recordTrellisError = exports.getTrellisMeter = exports.buildTrellisErrorMetricAttributes = exports.initTelemetry = exports.getEnv = exports.withSpanAsync = exports.withSpan = exports.trace = exports.SpanStatusCode = exports.SpanKind = exports.getTracer = exports.getActiveSpan = exports.context = exports.injectTraceContext = exports.extractTraceContext = exports.createMapCarrier = void 0;
4
4
  var carrier_js_1 = require("./carrier.js");
5
5
  Object.defineProperty(exports, "createMapCarrier", { enumerable: true, get: function () { return carrier_js_1.createMapCarrier; } });
6
6
  Object.defineProperty(exports, "extractTraceContext", { enumerable: true, get: function () { return carrier_js_1.extractTraceContext; } });
@@ -16,6 +16,12 @@ Object.defineProperty(exports, "withSpan", { enumerable: true, get: function ()
16
16
  Object.defineProperty(exports, "withSpanAsync", { enumerable: true, get: function () { return core_js_1.withSpanAsync; } });
17
17
  var env_js_1 = require("./env.js");
18
18
  Object.defineProperty(exports, "getEnv", { enumerable: true, get: function () { return env_js_1.getEnv; } });
19
+ var init_js_1 = require("./init.js");
20
+ Object.defineProperty(exports, "initTelemetry", { enumerable: true, get: function () { return init_js_1.initTelemetry; } });
21
+ var metrics_js_1 = require("./metrics.js");
22
+ Object.defineProperty(exports, "buildTrellisErrorMetricAttributes", { enumerable: true, get: function () { return metrics_js_1.buildTrellisErrorMetricAttributes; } });
23
+ Object.defineProperty(exports, "getTrellisMeter", { enumerable: true, get: function () { return metrics_js_1.getTrellisMeter; } });
24
+ Object.defineProperty(exports, "recordTrellisError", { enumerable: true, get: function () { return metrics_js_1.recordTrellisError; } });
19
25
  var nats_js_1 = require("./nats.js");
20
26
  Object.defineProperty(exports, "createNatsHeaderCarrier", { enumerable: true, get: function () { return nats_js_1.createNatsHeaderCarrier; } });
21
27
  var result_js_1 = require("./result.js");
@@ -0,0 +1,2 @@
1
+ export declare function initTelemetryRuntime(serviceName: string): void;
2
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/telemetry/runtime.ts"],"names":[],"mappings":"AAmNA,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAM9D"}
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.initTelemetryRuntime = initTelemetryRuntime;
4
+ const api_1 = require("@opentelemetry/api");
5
+ const env_js_1 = require("./env.js");
6
+ let initialized = false;
7
+ let provider;
8
+ let metricProvider;
9
+ function runtimeImport(specifier) {
10
+ const load = new Function("specifier", "return import(specifier);");
11
+ return load(specifier);
12
+ }
13
+ async function loadTracingRuntime() {
14
+ const [traceNode, otlp, traceBase, resources, semantic] = await Promise.all([
15
+ runtimeImport(["@opentelemetry", "sdk-trace-node"].join("/")),
16
+ runtimeImport(["@opentelemetry", "exporter-trace-otlp-proto"].join("/")),
17
+ runtimeImport(["@opentelemetry", "sdk-trace-base"].join("/")),
18
+ runtimeImport(["@opentelemetry", "resources"].join("/")),
19
+ runtimeImport(["@opentelemetry", "semantic-conventions"].join("/")),
20
+ ]);
21
+ return {
22
+ NodeTracerProvider: traceNode.NodeTracerProvider,
23
+ OTLPTraceExporter: otlp.OTLPTraceExporter,
24
+ BatchSpanProcessor: traceBase.BatchSpanProcessor,
25
+ ConsoleSpanExporter: traceBase.ConsoleSpanExporter,
26
+ resourceFromAttributes: resources.resourceFromAttributes,
27
+ ATTR_SERVICE_NAME: semantic.ATTR_SERVICE_NAME,
28
+ };
29
+ }
30
+ async function loadMetricsRuntime() {
31
+ const [sdkMetrics, otlp, resources, semantic] = await Promise.all([
32
+ runtimeImport(["@opentelemetry", "sdk-metrics"].join("/")),
33
+ runtimeImport(["@opentelemetry", "exporter-metrics-otlp-proto"].join("/")),
34
+ runtimeImport(["@opentelemetry", "resources"].join("/")),
35
+ runtimeImport(["@opentelemetry", "semantic-conventions"].join("/")),
36
+ ]);
37
+ return {
38
+ MeterProvider: sdkMetrics.MeterProvider,
39
+ PeriodicExportingMetricReader: sdkMetrics.PeriodicExportingMetricReader,
40
+ ConsoleMetricExporter: sdkMetrics.ConsoleMetricExporter,
41
+ OTLPMetricExporter: otlp.OTLPMetricExporter,
42
+ resourceFromAttributes: resources.resourceFromAttributes,
43
+ ATTR_SERVICE_NAME: semantic.ATTR_SERVICE_NAME,
44
+ };
45
+ }
46
+ async function initTracingRuntime(serviceName) {
47
+ const endpoint = (0, env_js_1.getEnv)("OTEL_EXPORTER_OTLP_ENDPOINT");
48
+ const consoleTracing = (0, env_js_1.getEnv)("OTEL_TRACES_CONSOLE") === "true";
49
+ if (!endpoint && !consoleTracing) {
50
+ return;
51
+ }
52
+ try {
53
+ const runtime = await loadTracingRuntime();
54
+ const spanProcessors = [];
55
+ if (endpoint) {
56
+ spanProcessors.push(new runtime.BatchSpanProcessor(new runtime.OTLPTraceExporter({ url: `${endpoint}/v1/traces` })));
57
+ }
58
+ if (consoleTracing) {
59
+ spanProcessors.push(new runtime.BatchSpanProcessor(new runtime.ConsoleSpanExporter()));
60
+ }
61
+ const nextProvider = new runtime.NodeTracerProvider({
62
+ resource: runtime.resourceFromAttributes({
63
+ [runtime.ATTR_SERVICE_NAME]: serviceName,
64
+ }),
65
+ ...(spanProcessors.length > 0 ? { spanProcessors } : {}),
66
+ });
67
+ provider = nextProvider;
68
+ nextProvider.register();
69
+ }
70
+ catch (error) {
71
+ console.warn("Failed to initialize tracing runtime", error);
72
+ }
73
+ }
74
+ function metricEndpoint() {
75
+ const metricsEndpoint = (0, env_js_1.getEnv)("OTEL_EXPORTER_OTLP_METRICS_ENDPOINT");
76
+ if (metricsEndpoint)
77
+ return metricsEndpoint;
78
+ const endpoint = (0, env_js_1.getEnv)("OTEL_EXPORTER_OTLP_ENDPOINT");
79
+ if (!endpoint)
80
+ return undefined;
81
+ return `${endpoint.replace(/\/$/, "")}/v1/metrics`;
82
+ }
83
+ function metricExportIntervalMillis() {
84
+ const configured = (0, env_js_1.getEnv)("OTEL_METRIC_EXPORT_INTERVAL");
85
+ if (!configured)
86
+ return undefined;
87
+ const parsed = Number(configured);
88
+ if (!Number.isFinite(parsed) || parsed <= 0)
89
+ return undefined;
90
+ return Math.trunc(parsed);
91
+ }
92
+ async function initMetricsRuntime(serviceName) {
93
+ const endpoint = metricEndpoint();
94
+ const consoleMetrics = (0, env_js_1.getEnv)("TRELLIS_METRICS_CONSOLE") === "true";
95
+ if (!endpoint && !consoleMetrics) {
96
+ return;
97
+ }
98
+ try {
99
+ const runtime = await loadMetricsRuntime();
100
+ const readers = [];
101
+ const exportIntervalMillis = metricExportIntervalMillis();
102
+ if (endpoint) {
103
+ readers.push(new runtime.PeriodicExportingMetricReader({
104
+ exporter: new runtime.OTLPMetricExporter({ url: endpoint }),
105
+ ...(exportIntervalMillis !== undefined
106
+ ? { exportIntervalMillis }
107
+ : {}),
108
+ }));
109
+ }
110
+ if (consoleMetrics) {
111
+ readers.push(new runtime.PeriodicExportingMetricReader({
112
+ exporter: new runtime.ConsoleMetricExporter(),
113
+ ...(exportIntervalMillis !== undefined
114
+ ? { exportIntervalMillis }
115
+ : {}),
116
+ }));
117
+ }
118
+ const nextMetricProvider = new runtime.MeterProvider({
119
+ resource: runtime.resourceFromAttributes({
120
+ [runtime.ATTR_SERVICE_NAME]: serviceName,
121
+ }),
122
+ ...(readers.length > 0 ? { readers } : {}),
123
+ });
124
+ metricProvider = nextMetricProvider;
125
+ api_1.metrics.setGlobalMeterProvider(nextMetricProvider);
126
+ }
127
+ catch (error) {
128
+ console.warn("Failed to initialize metrics runtime", error);
129
+ }
130
+ }
131
+ function initTelemetryRuntime(serviceName) {
132
+ if (initialized)
133
+ return;
134
+ initialized = true;
135
+ void initTracingRuntime(serviceName);
136
+ void initMetricsRuntime(serviceName);
137
+ }
@@ -0,0 +1,3 @@
1
+ import "./_dnt.polyfills.js";
2
+ export * from "./telemetry/mod.js";
3
+ //# sourceMappingURL=telemetry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAC7B,cAAc,oBAAoB,CAAC"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ require("./_dnt.polyfills.js");
18
+ __exportStar(require("./telemetry/mod.js"), exports);
@@ -1 +1 @@
1
- {"version":3,"file":"transfer.d.ts","sourceRoot":"","sources":["../src/transfer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EAGX,KAAK,MAAM,IAAI,UAAU,EAC1B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAIL,KAAK,OAAO,EACZ,KAAK,cAAc,EAEpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,IAAI,EAAE,EAAE,KAAK,MAAM,EAAE,MAAM,SAAS,CAAC;AAI5C,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAM1D,eAAO,MAAM,cAAc;;;;;;;EAOzB,CAAC;AAEH,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC;AAYrD,eAAO,MAAM,uBAAuB;;;;;;;;;;;;EAQlC,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;EAIrC,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAG9B,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,OAAO,uBAAuB,CAAC,CAAC;AACvE,MAAM,MAAM,oBAAoB,GAAG,MAAM,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAC7E,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAE/D,MAAM,MAAM,YAAY,GACpB,UAAU,GACV,WAAW,GACX,cAAc,CAAC,UAAU,CAAC,GAC1B,aAAa,CAAC,UAAU,CAAC,CAAC;AAE9B,KAAK,mBAAmB,GAAG;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,UAAU,CAAC;IACzD,UAAU,CAAC,EAAE,MAAM,MAAM,CAAC;CAC3B,CAAC;AA4NF,cAAM,kBAAkB;;IAKtB,SAAS,aACP,EAAE,EAAE,cAAc,EAClB,IAAI,EAAE,mBAAmB,EACzB,SAAS,EAAE,MAAM;IAOnB,SAAS,KAAK,EAAE,IAAI,cAAc,CAEjC;IAED,SAAS,KAAK,IAAI,IAAI,mBAAmB,CAExC;IAED,SAAS,KAAK,SAAS,IAAI,MAAM,CAEhC;IAED,SAAS,CAAC,aAAa,CACrB,KAAK,EAAE,aAAa,EACpB,SAAS,EAAE,MAAM,GAChB,UAAU,CAAC,IAAI,EAAE,aAAa,CAAC;cAwBlB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,UAAU,EACnB,GAAG,CAAC,EAAE,MAAM,EACZ,GAAG,CAAC,EAAE,OAAO,GACZ,OAAO,CAAC,OAAO,CAAC;CAgBpB;AAED,qBAAa,kBAAmB,SAAQ,kBAAkB;;gBAItD,EAAE,EAAE,cAAc,EAClB,IAAI,EAAE,mBAAmB,EACzB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,iBAAiB;IAM1B,IAAI,CAAC,IAAI,EAAE,YAAY,GAAG,WAAW,CAAC,QAAQ,EAAE,aAAa,CAAC;CA+F/D;AAED,qBAAa,qBAAsB,SAAQ,kBAAkB;;gBAIzD,EAAE,EAAE,cAAc,EAClB,IAAI,EAAE,mBAAmB,EACzB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,oBAAoB;IAM7B,MAAM,IAAI,WAAW,CAAC,cAAc,CAAC,UAAU,CAAC,EAAE,aAAa,CAAC;IAiChE,KAAK,IAAI,WAAW,CAAC,UAAU,EAAE,aAAa,CAAC;CAWhD;AAED,MAAM,MAAM,cAAc,GAAG,kBAAkB,GAAG,qBAAqB,CAAC;AAExE,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,cAAc,EAClB,IAAI,EAAE,mBAAmB,EACzB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,iBAAiB,GACvB,kBAAkB,CAAC;AACtB,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,cAAc,EAClB,IAAI,EAAE,mBAAmB,EACzB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,oBAAoB,GAC1B,qBAAqB,CAAC;AACzB,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,cAAc,EAClB,IAAI,EAAE,mBAAmB,EACzB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,aAAa,GACnB,cAAc,CAAC;AAYlB,wBAAsB,qBAAqB,CAAC,IAAI,EAAE;IAChD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,UAAU,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,GAAG,OAAO,CAAC,OAAO,CAAC,CAiBnB"}
1
+ {"version":3,"file":"transfer.d.ts","sourceRoot":"","sources":["../src/transfer.ts"],"names":[],"mappings":"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"}
@@ -25,7 +25,7 @@ const ulid_1 = require("ulid");
25
25
  const proof_js_1 = require("./auth/proof.js");
26
26
  const utils_js_1 = require("./auth/utils.js");
27
27
  const TransferError_js_1 = require("./errors/TransferError.js");
28
- const tracing_js_1 = require("./tracing.js");
28
+ const mod_js_1 = require("./telemetry/mod.js");
29
29
  const TRANSFER_SEQUENCE_HEADER = "trellis-transfer-seq";
30
30
  const TRANSFER_EOF_HEADER = "trellis-transfer-eof";
31
31
  exports.FileInfoSchema = typebox_1.default.Object({
@@ -138,7 +138,7 @@ function deserializeTransferError(msg, operation) {
138
138
  try {
139
139
  const value = JSON.parse(msg.string());
140
140
  return new TransferError_js_1.TransferError({
141
- operation: value.operation ?? operation,
141
+ operation,
142
142
  context: value.context,
143
143
  cause: value.message ? new Error(value.message) : undefined,
144
144
  });
@@ -147,6 +147,16 @@ function deserializeTransferError(msg, operation) {
147
147
  return new TransferError_js_1.TransferError({ operation, cause });
148
148
  }
149
149
  }
150
+ function recordTransferError(error, direction, phase) {
151
+ (0, mod_js_1.recordTrellisError)(error, {
152
+ surface: "transfer",
153
+ direction,
154
+ operation: error.operation ?? direction,
155
+ phase,
156
+ messagingSystem: "nats",
157
+ });
158
+ return error;
159
+ }
150
160
  function receiveStream(sub, timeoutMs) {
151
161
  const iterator = sub[Symbol.asyncIterator]();
152
162
  return new ReadableStream({
@@ -187,9 +197,10 @@ function receiveStream(sub, timeoutMs) {
187
197
  }
188
198
  catch (cause) {
189
199
  sub.unsubscribe();
190
- controller.error(cause instanceof TransferError_js_1.TransferError
200
+ const error = cause instanceof TransferError_js_1.TransferError
191
201
  ? cause
192
- : new TransferError_js_1.TransferError({ operation: "stream", cause }));
202
+ : new TransferError_js_1.TransferError({ operation: "stream", cause });
203
+ controller.error(recordTransferError(error, "receive", "stream"));
193
204
  }
194
205
  },
195
206
  cancel() {
@@ -276,7 +287,7 @@ class BaseTransferHandle {
276
287
  if (eof) {
277
288
  headers.set(TRANSFER_EOF_HEADER, "true");
278
289
  }
279
- (0, tracing_js_1.injectTraceContext)((0, tracing_js_1.createNatsHeaderCarrier)(headers));
290
+ (0, mod_js_1.injectTraceContext)((0, mod_js_1.createNatsHeaderCarrier)(headers));
280
291
  return headers;
281
292
  }
282
293
  }
@@ -291,7 +302,7 @@ class SendTransferHandle extends BaseTransferHandle {
291
302
  return result_1.AsyncResult.from((async () => {
292
303
  const valid = this.validateGrant(__classPrivateFieldGet(this, _SendTransferHandle_grant, "f"), "send").take();
293
304
  if ((0, result_1.isErr)(valid)) {
294
- return result_1.Result.err(valid.error);
305
+ return result_1.Result.err(recordTransferError(valid.error, "send", "grant"));
295
306
  }
296
307
  let sentBytes = 0;
297
308
  let seq = 0;
@@ -300,14 +311,14 @@ class SendTransferHandle extends BaseTransferHandle {
300
311
  sentBytes += chunk.length;
301
312
  if (__classPrivateFieldGet(this, _SendTransferHandle_grant, "f").maxBytes !== undefined &&
302
313
  sentBytes > __classPrivateFieldGet(this, _SendTransferHandle_grant, "f").maxBytes) {
303
- return result_1.Result.err(new TransferError_js_1.TransferError({
314
+ return result_1.Result.err(recordTransferError(new TransferError_js_1.TransferError({
304
315
  operation: "send",
305
316
  context: {
306
317
  reason: "max_bytes_exceeded",
307
318
  maxBytes: __classPrivateFieldGet(this, _SendTransferHandle_grant, "f").maxBytes,
308
319
  attemptedBytes: sentBytes,
309
320
  },
310
- }));
321
+ }), "send", "validation"));
311
322
  }
312
323
  const headers = await this.buildHeaders(__classPrivateFieldGet(this, _SendTransferHandle_grant, "f").subject, chunk, seq, false);
313
324
  const response = await result_1.AsyncResult.try(() => this.nc.request(__classPrivateFieldGet(this, _SendTransferHandle_grant, "f").subject, chunk, {
@@ -315,11 +326,11 @@ class SendTransferHandle extends BaseTransferHandle {
315
326
  headers,
316
327
  })).take();
317
328
  if ((0, result_1.isErr)(response)) {
318
- return result_1.Result.err(new TransferError_js_1.TransferError({ operation: "send", cause: response.error }));
329
+ return result_1.Result.err(recordTransferError(new TransferError_js_1.TransferError({ operation: "send", cause: response.error }), "send", "send"));
319
330
  }
320
331
  const ack = parseTransferAck(response, "send").take();
321
332
  if ((0, result_1.isErr)(ack)) {
322
- return result_1.Result.err(ack.error);
333
+ return result_1.Result.err(recordTransferError(ack.error, "send", "ack"));
323
334
  }
324
335
  if (ack.status === "complete") {
325
336
  completed = ack.info;
@@ -332,20 +343,20 @@ class SendTransferHandle extends BaseTransferHandle {
332
343
  headers: finalHeaders,
333
344
  })).take();
334
345
  if ((0, result_1.isErr)(finalResponse)) {
335
- return result_1.Result.err(new TransferError_js_1.TransferError({
346
+ return result_1.Result.err(recordTransferError(new TransferError_js_1.TransferError({
336
347
  operation: "send",
337
348
  cause: finalResponse.error,
338
- }));
349
+ }), "send", "send"));
339
350
  }
340
351
  const finalAck = parseTransferAck(finalResponse, "send").take();
341
352
  if ((0, result_1.isErr)(finalAck)) {
342
- return result_1.Result.err(finalAck.error);
353
+ return result_1.Result.err(recordTransferError(finalAck.error, "send", "ack"));
343
354
  }
344
355
  if (finalAck.status !== "complete") {
345
- return result_1.Result.err(new TransferError_js_1.TransferError({
356
+ return result_1.Result.err(recordTransferError(new TransferError_js_1.TransferError({
346
357
  operation: "send",
347
358
  context: { reason: "missing_completion" },
348
- }));
359
+ }), "send", "ack"));
349
360
  }
350
361
  return result_1.Result.ok(finalAck.info ?? completed);
351
362
  })());
@@ -363,7 +374,7 @@ class ReceiveTransferHandle extends BaseTransferHandle {
363
374
  return result_1.AsyncResult.from((async () => {
364
375
  const valid = this.validateGrant(__classPrivateFieldGet(this, _ReceiveTransferHandle_grant, "f"), "stream").take();
365
376
  if ((0, result_1.isErr)(valid)) {
366
- return result_1.Result.err(valid.error);
377
+ return result_1.Result.err(recordTransferError(valid.error, "receive", "grant"));
367
378
  }
368
379
  const inbox = (0, nats_core_1.createInbox)(`_INBOX.${this.auth.sessionKey.slice(0, 16)}`);
369
380
  const sub = this.nc.subscribe(inbox);
@@ -378,7 +389,7 @@ class ReceiveTransferHandle extends BaseTransferHandle {
378
389
  }
379
390
  catch (cause) {
380
391
  sub.unsubscribe();
381
- return result_1.Result.err(new TransferError_js_1.TransferError({ operation: "stream", cause }));
392
+ return result_1.Result.err(recordTransferError(new TransferError_js_1.TransferError({ operation: "stream", cause }), "receive", "send"));
382
393
  }
383
394
  return result_1.Result.ok(receiveStream(sub, this.timeoutMs));
384
395
  })());