@kultify/kmicro-js 0.0.10 → 0.0.14
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/dist/index.cjs +11 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +14 -11
- package/dist/index.js.map +1 -1
- package/package.json +17 -17
package/dist/index.cjs
CHANGED
|
@@ -45,6 +45,7 @@ var import_api = require("@opentelemetry/api");
|
|
|
45
45
|
var import_exporter_trace_otlp_proto = require("@opentelemetry/exporter-trace-otlp-proto");
|
|
46
46
|
var import_resources = require("@opentelemetry/resources");
|
|
47
47
|
var import_sdk_node = require("@opentelemetry/sdk-node");
|
|
48
|
+
var import_semantic_conventions = require("@opentelemetry/semantic-conventions");
|
|
48
49
|
var import_incubating = require("@opentelemetry/semantic-conventions/incubating");
|
|
49
50
|
var import_pino = __toESM(require("pino"), 1);
|
|
50
51
|
async function init(nats, serviceName, version, description) {
|
|
@@ -77,7 +78,7 @@ var Kmicro = class {
|
|
|
77
78
|
pass: natsUrl.password,
|
|
78
79
|
servers: [natsUrl.host]
|
|
79
80
|
});
|
|
80
|
-
const svc = new import_services.
|
|
81
|
+
const svc = new import_services.Svcm(this.nc);
|
|
81
82
|
this.service = await svc.add({
|
|
82
83
|
name: this.meta.name,
|
|
83
84
|
version: this.meta.version,
|
|
@@ -88,7 +89,7 @@ var Kmicro = class {
|
|
|
88
89
|
serviceName: this.meta.name,
|
|
89
90
|
traceExporter: new import_exporter_trace_otlp_proto.OTLPTraceExporter(),
|
|
90
91
|
resource: new import_resources.Resource({
|
|
91
|
-
[
|
|
92
|
+
[import_semantic_conventions.ATTR_SERVICE_NAME]: this.meta.name,
|
|
92
93
|
[import_incubating.ATTR_MESSAGING_SYSTEM]: "nats"
|
|
93
94
|
})
|
|
94
95
|
});
|
|
@@ -118,7 +119,7 @@ var Kmicro = class {
|
|
|
118
119
|
10
|
|
119
120
|
);
|
|
120
121
|
if (currentCallDepth >= 20) {
|
|
121
|
-
throw new Error(
|
|
122
|
+
throw new Error(`max call depth reached: ${currentCallDepth}`);
|
|
122
123
|
}
|
|
123
124
|
const contextWithOtel = import_api.propagation.extract(
|
|
124
125
|
import_api.context.active(),
|
|
@@ -156,6 +157,7 @@ var Kmicro = class {
|
|
|
156
157
|
const requestContext = new RequestContext(
|
|
157
158
|
contextWithOtel,
|
|
158
159
|
span,
|
|
160
|
+
// biome-ignore lint/style/noNonNullAssertion: Checked with assert
|
|
159
161
|
this.nc,
|
|
160
162
|
spanLogger,
|
|
161
163
|
{
|
|
@@ -249,7 +251,7 @@ var CallError = class extends Error {
|
|
|
249
251
|
};
|
|
250
252
|
async function doCall(nc, target, payload, meta, options) {
|
|
251
253
|
if (meta.callDepth >= 20) {
|
|
252
|
-
throw new Error(
|
|
254
|
+
throw new Error(`max call depth reached: ${meta.callDepth}`);
|
|
253
255
|
}
|
|
254
256
|
const carrierData = meta.context ?? {};
|
|
255
257
|
if (options?.trace && !meta.context) {
|
|
@@ -287,23 +289,25 @@ async function doCall(nc, target, payload, meta, options) {
|
|
|
287
289
|
if (!Object.hasOwn(mergedHeaders, key)) {
|
|
288
290
|
continue;
|
|
289
291
|
}
|
|
290
|
-
|
|
292
|
+
if (mergedHeaders[key]) {
|
|
293
|
+
natsHeadersMap.set(key, mergedHeaders[key]);
|
|
294
|
+
}
|
|
291
295
|
}
|
|
292
296
|
try {
|
|
293
297
|
const result = await nc.request(target, payload, {
|
|
294
298
|
headers: natsHeadersMap,
|
|
295
299
|
timeout: options?.timeout ?? 5e3
|
|
296
300
|
});
|
|
297
|
-
span.setStatus({ code: import_api.SpanStatusCode.OK });
|
|
298
301
|
if (result.headers?.get("Nats-Service-Error-Code")) {
|
|
299
302
|
span.setStatus({ code: import_api.SpanStatusCode.ERROR });
|
|
300
303
|
span.recordException(result.headers.get("Nats-Service-Error"));
|
|
301
304
|
throw new CallError(
|
|
302
|
-
|
|
305
|
+
`received error: ${result.headers.get("Nats-Service-Error")}`,
|
|
303
306
|
target,
|
|
304
307
|
payload
|
|
305
308
|
);
|
|
306
309
|
}
|
|
310
|
+
span.setStatus({ code: import_api.SpanStatusCode.OK });
|
|
307
311
|
return result.data;
|
|
308
312
|
} finally {
|
|
309
313
|
span.end();
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/KMicro.ts"],"sourcesContent":["export * from './KMicro.js';\n","import assert from 'node:assert';\nimport {Svc, type Service, type ServiceGroup} from '@nats-io/services';\nimport {connect, headers, type NatsConnection} from '@nats-io/transport-node';\nimport {\n\tcontext,\n\tpropagation,\n\tSpanKind,\n\tSpanStatusCode,\n\ttrace,\n\ttype Context,\n\ttype Span,\n} from '@opentelemetry/api';\nimport {OTLPTraceExporter} from '@opentelemetry/exporter-trace-otlp-proto';\nimport {Resource} from '@opentelemetry/resources';\nimport {NodeSDK} from '@opentelemetry/sdk-node';\nimport {\n\tATTR_MESSAGING_SYSTEM,\n\tATTR_RPC_METHOD,\n\tATTR_RPC_SERVICE,\n\tATTR_SERVICE_NAME,\n} from '@opentelemetry/semantic-conventions/incubating';\nimport pino, {type Logger} from 'pino';\n\n/**\n * Use init to create a kmicro instance and directly start (init) it\n */\nexport async function init(\n\tnats: string,\n\tserviceName: string,\n\tversion: string,\n\tdescription?: string,\n) {\n\tconst kmicro = new Kmicro({\n\t\tname: serviceName,\n\t\tversion,\n\t\tdescription,\n\t});\n\tawait kmicro.init(nats);\n\treturn kmicro;\n}\n\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\ninterface Callable {\n\tcall(\n\t\ttarget: string,\n\t\tpayload: Uint8Array,\n\t\toptions?: {\n\t\t\t/**\n\t\t\t * @default 5000 ms\n\t\t\t */\n\t\t\ttimeout?: number;\n\t\t},\n\t): Promise<Uint8Array>;\n}\n\nexport class Kmicro implements Callable {\n\tprivate service: Service | undefined;\n\tprivate group: ServiceGroup | undefined;\n\tprivate nc: NatsConnection | undefined;\n\tprivate otel: NodeSDK | undefined;\n\tprivate readonly pinoLogger: pino.Logger;\n\n\tconstructor(\n\t\tprivate readonly meta: {\n\t\t\tname: string;\n\t\t\tversion: string;\n\t\t\tdescription: string | undefined;\n\t\t},\n\t) {\n\t\tthis.pinoLogger = pino.pino();\n\t}\n\n\tpublic getLogger(module?: string) {\n\t\treturn this.pinoLogger.child({module});\n\t}\n\n\tpublic async init(natsURI: string) {\n\t\tconst natsUrl = new URL(natsURI);\n\t\tthis.nc = await connect({\n\t\t\tname: this.meta.name,\n\t\t\tuser: natsUrl.username,\n\t\t\tpass: natsUrl.password,\n\t\t\tservers: [natsUrl.host],\n\t\t});\n\t\tconst svc = new Svc(this.nc);\n\t\tthis.service = await svc.add({\n\t\t\tname: this.meta.name,\n\t\t\tversion: this.meta.version,\n\t\t\tdescription: this.meta.description,\n\t\t});\n\t\tthis.group = this.service.addGroup(this.meta.name);\n\t\tthis.otel = new NodeSDK({\n\t\t\tserviceName: this.meta.name,\n\t\t\ttraceExporter: new OTLPTraceExporter(),\n\t\t\tresource: new Resource({\n\t\t\t\t[ATTR_SERVICE_NAME]: this.meta.name,\n\t\t\t\t[ATTR_MESSAGING_SYSTEM]: 'nats',\n\t\t\t}),\n\t\t});\n\n\t\tthis.otel.start();\n\t}\n\n\tpublic async stop() {\n\t\tawait this.service?.stop().catch((error: unknown) => {\n\t\t\tconsole.error(error);\n\t\t});\n\t\tawait this.nc?.close().catch((error: unknown) => {\n\t\t\tconsole.error(error);\n\t\t});\n\t\tawait this.otel?.shutdown().catch((error: unknown) => {\n\t\t\tconsole.error(error);\n\t\t});\n\t}\n\n\tpublic addEndpoint(\n\t\tname: string,\n\t\thandler: (\n\t\t\tcontext_: RequestContext,\n\t\t\tdata: Uint8Array,\n\t\t) => Promise<Uint8Array>,\n\t) {\n\t\tassert(this.group);\n\n\t\tthis.group.addEndpoint(name, async (error, message) => {\n\t\t\tassert(this.nc);\n\t\t\tif (error) {\n\t\t\t\tconsole.error(error);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Prevent infinite loops\n\t\t\tconst currentCallDepth = Number.parseInt(\n\t\t\t\tmessage.headers?.get('kmc-depth') ?? '0',\n\t\t\t\t10,\n\t\t\t);\n\t\t\tif (currentCallDepth >= 20) {\n\t\t\t\tthrow new Error('max call depth reached: ' + currentCallDepth);\n\t\t\t}\n\n\t\t\tconst contextWithOtel: Context = propagation.extract(\n\t\t\t\tcontext.active(),\n\t\t\t\tmessage.headers,\n\t\t\t\t{\n\t\t\t\t\tget(carrier, key) {\n\t\t\t\t\t\treturn carrier?.get(key);\n\t\t\t\t\t},\n\t\t\t\t\tkeys(carrier) {\n\t\t\t\t\t\treturn carrier?.keys() ?? [];\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tconst tracer = trace.getTracer(this.meta.name, this.meta.version);\n\t\t\tconst spanName = `handle: ${this.meta.name}.${name}`;\n\t\t\tawait tracer.startActiveSpan(\n\t\t\t\tspanName,\n\t\t\t\t{\n\t\t\t\t\tkind: SpanKind.SERVER,\n\t\t\t\t},\n\t\t\t\tcontextWithOtel,\n\t\t\t\tasync (span) => {\n\t\t\t\t\tconst spanLogger = this.pinoLogger.child({\n\t\t\t\t\t\taction: name,\n\t\t\t\t\t\tspanId: span.spanContext().spanId,\n\t\t\t\t\t\ttraceId: span.spanContext().traceId,\n\t\t\t\t\t});\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst header: Record<string, string> = {};\n\t\t\t\t\t\tfor (const key of message.headers?.keys() ?? []) {\n\t\t\t\t\t\t\tif (message.headers?.has(key)) {\n\t\t\t\t\t\t\t\theader[key] = message.headers?.get(key);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst requestContext = new RequestContext(\n\t\t\t\t\t\t\tcontextWithOtel,\n\t\t\t\t\t\t\tspan,\n\t\t\t\t\t\t\tthis.nc!,\n\t\t\t\t\t\t\tspanLogger,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcallDepth: currentCallDepth,\n\t\t\t\t\t\t\t\tcurrentService: this.meta.name,\n\t\t\t\t\t\t\t\theader,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst result = await handler(requestContext, message.data);\n\t\t\t\t\t\tmessage.respond(result);\n\t\t\t\t\t\tspan.setStatus({code: SpanStatusCode.OK});\n\t\t\t\t\t} catch (error_) {\n\t\t\t\t\t\tspan.recordException(error_ as Error);\n\t\t\t\t\t\tmessage.respondError(500, (error_ as Error).message);\n\t\t\t\t\t\tspan.setStatus({code: SpanStatusCode.ERROR});\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tspan.end();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\t/**\n\t * Start a new call\n\t */\n\tpublic async call(\n\t\ttarget: string,\n\t\tpayload: Uint8Array,\n\t\toptions?: {\n\t\t\t/**\n\t\t\t * @default 5000 ms\n\t\t\t */\n\t\t\ttimeout?: number;\n\t\t\theader?: Record<string, string>;\n\t\t\tmoleculerTrace?: {\n\t\t\t\ttraceId?: string | undefined;\n\t\t\t\tparentId?: string | undefined;\n\t\t\t};\n\t\t},\n\t): Promise<Uint8Array> {\n\t\tassert(this.nc);\n\n\t\tlet trace:\n\t\t\t| undefined\n\t\t\t| {\n\t\t\t\t\ttraceId: string;\n\t\t\t\t\tparentId: string;\n\t\t\t };\n\t\tif (options?.moleculerTrace) {\n\t\t\t// we have to shorten the moleculer trace id because the jaeger exporter uses only 16 chars\n\t\t\tconst molTraceId = options.moleculerTrace.traceId\n\t\t\t\t?.replaceAll('-', '')\n\t\t\t\t.slice(0, 16);\n\t\t\tconst traceId = Array.from({length: 16})\n\t\t\t\t.fill('0')\n\t\t\t\t.join('')\n\t\t\t\t.concat(molTraceId ?? '');\n\t\t\tconst molParentId = options.moleculerTrace.parentId\n\t\t\t\t?.replaceAll('-', '')\n\t\t\t\t.slice(0, 16);\n\t\t\ttrace = {\n\t\t\t\ttraceId,\n\t\t\t\tparentId: molParentId ?? '',\n\t\t\t};\n\t\t}\n\n\t\treturn doCall(\n\t\t\tthis.nc,\n\t\t\ttarget,\n\t\t\tpayload,\n\t\t\t{\n\t\t\t\tcallDepth: 0,\n\t\t\t\tcontext: undefined,\n\t\t\t\tcurrentService: this.meta.name,\n\t\t\t\theader: options?.header ?? {},\n\t\t\t},\n\t\t\t{\n\t\t\t\ttimeout: options?.timeout,\n\t\t\t\ttrace,\n\t\t\t},\n\t\t);\n\t}\n}\n\nexport class RequestContext {\n\t// eslint-disable-next-line max-params\n\tconstructor(\n\t\treadonly context: Context,\n\t\treadonly span: Span,\n\t\treadonly nc: NatsConnection,\n\t\tprivate readonly logger: Logger,\n\t\treadonly meta: {\n\t\t\tcallDepth: number;\n\t\t\tcurrentService: string;\n\t\t\theader: Record<string, string>;\n\t\t},\n\t) {}\n\n\tpublic getLogger(module?: string) {\n\t\treturn this.logger.child({\n\t\t\tmodule,\n\t\t});\n\t}\n\n\tpublic async call(\n\t\ttarget: string,\n\t\tpayload: Uint8Array,\n\t\toptions?: {\n\t\t\t/**\n\t\t\t * @default 5000 ms\n\t\t\t */\n\t\t\ttimeout?: number;\n\t\t\theader?: Record<string, string>;\n\t\t},\n\t): Promise<Uint8Array> {\n\t\treturn doCall(\n\t\t\tthis.nc,\n\t\t\ttarget,\n\t\t\tpayload,\n\t\t\t{\n\t\t\t\tcallDepth: this.meta.callDepth,\n\t\t\t\tcontext: this.context,\n\t\t\t\tcurrentService: this.meta.currentService,\n\t\t\t\theader: this.meta.header,\n\t\t\t},\n\t\t\toptions,\n\t\t);\n\t}\n}\n\nexport class CallError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tprivate readonly target: string,\n\t\tprivate readonly payload: Uint8Array,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = 'CallError';\n\t}\n}\n\n// eslint-disable-next-line max-params\nasync function doCall(\n\tnc: NatsConnection,\n\ttarget: string,\n\tpayload: Uint8Array,\n\tmeta: {\n\t\tcallDepth: number;\n\t\t/**\n\t\t * The otel context\n\t\t */\n\t\tcontext: Context | undefined;\n\t\tcurrentService: string;\n\t\t/**\n\t\t * Headers from the parent calls\n\t\t */\n\t\theader: Record<string, string>;\n\t},\n\toptions?: {\n\t\t/**\n\t\t * @default 5000 ms\n\t\t */\n\t\ttimeout?: number;\n\t\theader?: Record<string, string>;\n\t\t/**\n\t\t * Optionally pass an existing trace from the moleculer framework\n\t\t */\n\t\ttrace?: {\n\t\t\t/**\n\t\t\t * This is the ID of the whole trace forest and is used to uniquely identify a distributed trace through a system.\n\t\t\t */\n\t\t\ttraceId: string | undefined;\n\t\t\t/**\n\t\t\t * or span id: This is the ID of this request as known by the caller\n\t\t\t */\n\t\t\tparentId: string | undefined;\n\t\t};\n\t},\n): Promise<Uint8Array> {\n\tif (meta.callDepth >= 20) {\n\t\tthrow new Error('max call depth reached: ' + meta.callDepth);\n\t}\n\n\tconst carrierData: Context | {traceparent?: string} = meta.context ?? {};\n\tif (options?.trace && !meta.context) {\n\t\tconst version = Buffer.alloc(1).toString('hex');\n\t\tconst flags = '01'; // means sampled\n\t\tconst header = `${version}-${options.trace.traceId}-${options.trace.parentId}-${flags}`;\n\t\t(carrierData as {traceparent?: string | undefined}).traceparent = header;\n\t}\n\n\tconst callingContext: Context = propagation.extract(\n\t\tcontext.active(),\n\t\tcarrierData,\n\t);\n\tconst tracer = trace.getTracer('default');\n\tconst [service, action] = target.split('.');\n\treturn tracer.startActiveSpan(\n\t\t`call: ${target}`,\n\t\t{\n\t\t\tkind: SpanKind.CLIENT,\n\t\t\tattributes: {\n\t\t\t\t[ATTR_RPC_SERVICE]: service,\n\t\t\t\t[ATTR_RPC_METHOD]: action,\n\t\t\t},\n\t\t},\n\t\tcallingContext,\n\t\tasync (span) => {\n\t\t\t// Add kmicro and otel headers to the nats message headers\n\t\t\tconst natsHeadersMap = headers();\n\t\t\tnatsHeadersMap.set('kmc-depth', (meta.callDepth + 1).toFixed(0));\n\t\t\tpropagation.inject(context.active(), natsHeadersMap, {\n\t\t\t\tset(carrier, key, value) {\n\t\t\t\t\tcarrier.set(key, value);\n\t\t\t\t},\n\t\t\t});\n\t\t\tconst mergedHeaders = {...meta.header, ...options?.header};\n\t\t\tfor (const key in mergedHeaders) {\n\t\t\t\tif (!Object.hasOwn(mergedHeaders, key)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tnatsHeadersMap.set(key, mergedHeaders[key]);\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst result = await nc.request(target, payload, {\n\t\t\t\t\theaders: natsHeadersMap,\n\t\t\t\t\ttimeout: options?.timeout ?? 5000,\n\t\t\t\t});\n\t\t\t\tspan.setStatus({code: SpanStatusCode.OK});\n\t\t\t\tif (result.headers?.get('Nats-Service-Error-Code')) {\n\t\t\t\t\tspan.setStatus({code: SpanStatusCode.ERROR});\n\t\t\t\t\tspan.recordException(result.headers.get('Nats-Service-Error'));\n\t\t\t\t\tthrow new CallError(\n\t\t\t\t\t\t'received error: ' + result.headers.get('Nats-Service-Error'),\n\t\t\t\t\t\ttarget,\n\t\t\t\t\t\tpayload,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn result.data;\n\t\t\t} finally {\n\t\t\t\tspan.end();\n\t\t\t}\n\t\t},\n\t);\n}\n"],"mappings":"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","names":["pino","module","assert","trace","context"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/KMicro.ts"],"sourcesContent":["export * from \"./KMicro.js\";\n","import assert from \"node:assert\";\nimport { type Service, type ServiceGroup, Svcm } from \"@nats-io/services\";\nimport { type NatsConnection, connect, headers } from \"@nats-io/transport-node\";\nimport {\n\ttype Context,\n\ttype Span,\n\tSpanKind,\n\tSpanStatusCode,\n\tcontext,\n\tpropagation,\n\ttrace,\n} from \"@opentelemetry/api\";\nimport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-proto\";\nimport { Resource } from \"@opentelemetry/resources\";\nimport { NodeSDK } from \"@opentelemetry/sdk-node\";\nimport { ATTR_SERVICE_NAME } from \"@opentelemetry/semantic-conventions\";\nimport {\n\tATTR_MESSAGING_SYSTEM,\n\tATTR_RPC_METHOD,\n\tATTR_RPC_SERVICE,\n} from \"@opentelemetry/semantic-conventions/incubating\";\nimport pino, { type Logger } from \"pino\";\n\n/**\n * Use init to create a kmicro instance and directly start (init) it\n */\nexport async function init(\n\tnats: string,\n\tserviceName: string,\n\tversion: string,\n\tdescription?: string,\n) {\n\tconst kmicro = new Kmicro({\n\t\tname: serviceName,\n\t\tversion,\n\t\tdescription,\n\t});\n\tawait kmicro.init(nats);\n\treturn kmicro;\n}\n\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\ninterface Callable {\n\tcall(\n\t\ttarget: string,\n\t\tpayload: Uint8Array,\n\t\toptions?: {\n\t\t\t/**\n\t\t\t * @default 5000 ms\n\t\t\t */\n\t\t\ttimeout?: number;\n\t\t},\n\t): Promise<Uint8Array>;\n}\n\nexport class Kmicro implements Callable {\n\tprivate service: Service | undefined;\n\tprivate group: ServiceGroup | undefined;\n\tprivate nc: NatsConnection | undefined;\n\tprivate otel: NodeSDK | undefined;\n\tprivate readonly pinoLogger: pino.Logger;\n\n\tconstructor(\n\t\tprivate readonly meta: {\n\t\t\tname: string;\n\t\t\tversion: string;\n\t\t\tdescription: string | undefined;\n\t\t},\n\t) {\n\t\tthis.pinoLogger = pino.pino();\n\t}\n\n\tpublic getLogger(module?: string) {\n\t\treturn this.pinoLogger.child({ module });\n\t}\n\n\tpublic async init(natsURI: string) {\n\t\tconst natsUrl = new URL(natsURI);\n\t\tthis.nc = await connect({\n\t\t\tname: this.meta.name,\n\t\t\tuser: natsUrl.username,\n\t\t\tpass: natsUrl.password,\n\t\t\tservers: [natsUrl.host],\n\t\t});\n\t\tconst svc = new Svcm(this.nc);\n\t\tthis.service = await svc.add({\n\t\t\tname: this.meta.name,\n\t\t\tversion: this.meta.version,\n\t\t\tdescription: this.meta.description,\n\t\t});\n\t\tthis.group = this.service.addGroup(this.meta.name);\n\t\tthis.otel = new NodeSDK({\n\t\t\tserviceName: this.meta.name,\n\t\t\ttraceExporter: new OTLPTraceExporter(),\n\t\t\tresource: new Resource({\n\t\t\t\t[ATTR_SERVICE_NAME]: this.meta.name,\n\t\t\t\t[ATTR_MESSAGING_SYSTEM]: \"nats\",\n\t\t\t}),\n\t\t});\n\n\t\tthis.otel.start();\n\t}\n\n\tpublic async stop() {\n\t\tawait this.service?.stop().catch((error: unknown) => {\n\t\t\tconsole.error(error);\n\t\t});\n\t\tawait this.nc?.close().catch((error: unknown) => {\n\t\t\tconsole.error(error);\n\t\t});\n\t\tawait this.otel?.shutdown().catch((error: unknown) => {\n\t\t\tconsole.error(error);\n\t\t});\n\t}\n\n\tpublic addEndpoint(\n\t\tname: string,\n\t\thandler: (\n\t\t\tcontext_: RequestContext,\n\t\t\tdata: Uint8Array,\n\t\t) => Promise<Uint8Array>,\n\t) {\n\t\tassert(this.group);\n\n\t\tthis.group.addEndpoint(name, async (error, message) => {\n\t\t\tassert(this.nc);\n\t\t\tif (error) {\n\t\t\t\tconsole.error(error);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Prevent infinite loops\n\t\t\tconst currentCallDepth = Number.parseInt(\n\t\t\t\tmessage.headers?.get(\"kmc-depth\") ?? \"0\",\n\t\t\t\t10,\n\t\t\t);\n\t\t\tif (currentCallDepth >= 20) {\n\t\t\t\tthrow new Error(`max call depth reached: ${currentCallDepth}`);\n\t\t\t}\n\n\t\t\tconst contextWithOtel: Context = propagation.extract(\n\t\t\t\tcontext.active(),\n\t\t\t\tmessage.headers,\n\t\t\t\t{\n\t\t\t\t\tget(carrier, key) {\n\t\t\t\t\t\treturn carrier?.get(key);\n\t\t\t\t\t},\n\t\t\t\t\tkeys(carrier) {\n\t\t\t\t\t\treturn carrier?.keys() ?? [];\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tconst tracer = trace.getTracer(this.meta.name, this.meta.version);\n\t\t\tconst spanName = `handle: ${this.meta.name}.${name}`;\n\t\t\tawait tracer.startActiveSpan(\n\t\t\t\tspanName,\n\t\t\t\t{\n\t\t\t\t\tkind: SpanKind.SERVER,\n\t\t\t\t},\n\t\t\t\tcontextWithOtel,\n\t\t\t\tasync (span) => {\n\t\t\t\t\tconst spanLogger = this.pinoLogger.child({\n\t\t\t\t\t\taction: name,\n\t\t\t\t\t\tspanId: span.spanContext().spanId,\n\t\t\t\t\t\ttraceId: span.spanContext().traceId,\n\t\t\t\t\t});\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst header: Record<string, string> = {};\n\t\t\t\t\t\tfor (const key of message.headers?.keys() ?? []) {\n\t\t\t\t\t\t\tif (message.headers?.has(key)) {\n\t\t\t\t\t\t\t\theader[key] = message.headers?.get(key);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst requestContext = new RequestContext(\n\t\t\t\t\t\t\tcontextWithOtel,\n\t\t\t\t\t\t\tspan,\n\t\t\t\t\t\t\t// biome-ignore lint/style/noNonNullAssertion: Checked with assert\n\t\t\t\t\t\t\tthis.nc!,\n\t\t\t\t\t\t\tspanLogger,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcallDepth: currentCallDepth,\n\t\t\t\t\t\t\t\tcurrentService: this.meta.name,\n\t\t\t\t\t\t\t\theader,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst result = await handler(requestContext, message.data);\n\t\t\t\t\t\tmessage.respond(result);\n\t\t\t\t\t\tspan.setStatus({ code: SpanStatusCode.OK });\n\t\t\t\t\t} catch (error_) {\n\t\t\t\t\t\tspan.recordException(error_ as Error);\n\t\t\t\t\t\tmessage.respondError(500, (error_ as Error).message);\n\t\t\t\t\t\tspan.setStatus({ code: SpanStatusCode.ERROR });\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tspan.end();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\t/**\n\t * Start a new call\n\t */\n\tpublic async call(\n\t\ttarget: string,\n\t\tpayload: Uint8Array,\n\t\toptions?: {\n\t\t\t/**\n\t\t\t * @default 5000 ms\n\t\t\t */\n\t\t\ttimeout?: number;\n\t\t\theader?: Record<string, string>;\n\t\t\tmoleculerTrace?: {\n\t\t\t\ttraceId?: string | undefined;\n\t\t\t\tparentId?: string | undefined;\n\t\t\t};\n\t\t},\n\t): Promise<Uint8Array> {\n\t\tassert(this.nc);\n\n\t\tlet trace:\n\t\t\t| undefined\n\t\t\t| {\n\t\t\t\t\ttraceId: string;\n\t\t\t\t\tparentId: string;\n\t\t\t };\n\t\tif (options?.moleculerTrace) {\n\t\t\t// we have to shorten the moleculer trace id because the jaeger exporter uses only 16 chars\n\t\t\tconst molTraceId = options.moleculerTrace.traceId\n\t\t\t\t?.replaceAll(\"-\", \"\")\n\t\t\t\t.slice(0, 16);\n\t\t\tconst traceId = Array.from({ length: 16 })\n\t\t\t\t.fill(\"0\")\n\t\t\t\t.join(\"\")\n\t\t\t\t.concat(molTraceId ?? \"\");\n\t\t\tconst molParentId = options.moleculerTrace.parentId\n\t\t\t\t?.replaceAll(\"-\", \"\")\n\t\t\t\t.slice(0, 16);\n\t\t\ttrace = {\n\t\t\t\ttraceId,\n\t\t\t\tparentId: molParentId ?? \"\",\n\t\t\t};\n\t\t}\n\n\t\treturn doCall(\n\t\t\tthis.nc,\n\t\t\ttarget,\n\t\t\tpayload,\n\t\t\t{\n\t\t\t\tcallDepth: 0,\n\t\t\t\tcontext: undefined,\n\t\t\t\tcurrentService: this.meta.name,\n\t\t\t\theader: options?.header ?? {},\n\t\t\t},\n\t\t\t{\n\t\t\t\ttimeout: options?.timeout,\n\t\t\t\ttrace,\n\t\t\t},\n\t\t);\n\t}\n}\n\nexport class RequestContext {\n\t// eslint-disable-next-line max-params\n\tconstructor(\n\t\treadonly context: Context,\n\t\treadonly span: Span,\n\t\treadonly nc: NatsConnection,\n\t\tprivate readonly logger: Logger,\n\t\treadonly meta: {\n\t\t\tcallDepth: number;\n\t\t\tcurrentService: string;\n\t\t\theader: Record<string, string>;\n\t\t},\n\t) {}\n\n\tpublic getLogger(module?: string) {\n\t\treturn this.logger.child({\n\t\t\tmodule,\n\t\t});\n\t}\n\n\tpublic async call(\n\t\ttarget: string,\n\t\tpayload: Uint8Array,\n\t\toptions?: {\n\t\t\t/**\n\t\t\t * @default 5000 ms\n\t\t\t */\n\t\t\ttimeout?: number;\n\t\t\theader?: Record<string, string>;\n\t\t},\n\t): Promise<Uint8Array> {\n\t\treturn doCall(\n\t\t\tthis.nc,\n\t\t\ttarget,\n\t\t\tpayload,\n\t\t\t{\n\t\t\t\tcallDepth: this.meta.callDepth,\n\t\t\t\tcontext: this.context,\n\t\t\t\tcurrentService: this.meta.currentService,\n\t\t\t\theader: this.meta.header,\n\t\t\t},\n\t\t\toptions,\n\t\t);\n\t}\n}\n\nexport class CallError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tprivate readonly target: string,\n\t\tprivate readonly payload: Uint8Array,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"CallError\";\n\t}\n}\n\n// eslint-disable-next-line max-params\nasync function doCall(\n\tnc: NatsConnection,\n\ttarget: string,\n\tpayload: Uint8Array,\n\tmeta: {\n\t\tcallDepth: number;\n\t\t/**\n\t\t * The otel context\n\t\t */\n\t\tcontext: Context | undefined;\n\t\tcurrentService: string;\n\t\t/**\n\t\t * Headers from the parent calls\n\t\t */\n\t\theader: Record<string, string>;\n\t},\n\toptions?: {\n\t\t/**\n\t\t * @default 5000 ms\n\t\t */\n\t\ttimeout?: number;\n\t\theader?: Record<string, string>;\n\t\t/**\n\t\t * Optionally pass an existing trace from the moleculer framework\n\t\t */\n\t\ttrace?: {\n\t\t\t/**\n\t\t\t * This is the ID of the whole trace forest and is used to uniquely identify a distributed trace through a system.\n\t\t\t */\n\t\t\ttraceId: string | undefined;\n\t\t\t/**\n\t\t\t * or span id: This is the ID of this request as known by the caller\n\t\t\t */\n\t\t\tparentId: string | undefined;\n\t\t};\n\t},\n): Promise<Uint8Array> {\n\tif (meta.callDepth >= 20) {\n\t\tthrow new Error(`max call depth reached: ${meta.callDepth}`);\n\t}\n\n\tconst carrierData: Context | { traceparent?: string } = meta.context ?? {};\n\tif (options?.trace && !meta.context) {\n\t\tconst version = Buffer.alloc(1).toString(\"hex\");\n\t\tconst flags = \"01\"; // means sampled\n\t\tconst header = `${version}-${options.trace.traceId}-${options.trace.parentId}-${flags}`;\n\t\t(carrierData as { traceparent?: string | undefined }).traceparent = header;\n\t}\n\n\tconst callingContext: Context = propagation.extract(\n\t\tcontext.active(),\n\t\tcarrierData,\n\t);\n\tconst tracer = trace.getTracer(\"default\");\n\tconst [service, action] = target.split(\".\");\n\treturn tracer.startActiveSpan(\n\t\t`call: ${target}`,\n\t\t{\n\t\t\tkind: SpanKind.CLIENT,\n\t\t\tattributes: {\n\t\t\t\t[ATTR_RPC_SERVICE]: service,\n\t\t\t\t[ATTR_RPC_METHOD]: action,\n\t\t\t},\n\t\t},\n\t\tcallingContext,\n\t\tasync (span) => {\n\t\t\t// Add kmicro and otel headers to the nats message headers\n\t\t\tconst natsHeadersMap = headers();\n\t\t\tnatsHeadersMap.set(\"kmc-depth\", (meta.callDepth + 1).toFixed(0));\n\t\t\tpropagation.inject(context.active(), natsHeadersMap, {\n\t\t\t\tset(carrier, key, value) {\n\t\t\t\t\tcarrier.set(key, value);\n\t\t\t\t},\n\t\t\t});\n\t\t\tconst mergedHeaders = { ...meta.header, ...options?.header };\n\t\t\tfor (const key in mergedHeaders) {\n\t\t\t\tif (!Object.hasOwn(mergedHeaders, key)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (mergedHeaders[key]) {\n\t\t\t\t\tnatsHeadersMap.set(key, mergedHeaders[key]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst result = await nc.request(target, payload, {\n\t\t\t\t\theaders: natsHeadersMap,\n\t\t\t\t\ttimeout: options?.timeout ?? 5000,\n\t\t\t\t});\n\t\t\t\tif (result.headers?.get(\"Nats-Service-Error-Code\")) {\n\t\t\t\t\tspan.setStatus({ code: SpanStatusCode.ERROR });\n\t\t\t\t\tspan.recordException(result.headers.get(\"Nats-Service-Error\"));\n\t\t\t\t\tthrow new CallError(\n\t\t\t\t\t\t`received error: ${result.headers.get(\"Nats-Service-Error\")}`,\n\t\t\t\t\t\ttarget,\n\t\t\t\t\t\tpayload,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tspan.setStatus({ code: SpanStatusCode.OK });\n\t\t\t\treturn result.data;\n\t\t\t} finally {\n\t\t\t\tspan.end();\n\t\t\t}\n\t\t},\n\t);\n}\n"],"mappings":"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","names":["pino","module","assert","trace","context"]}
|
package/dist/index.js
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
// src/KMicro.ts
|
|
2
2
|
import assert from "node:assert";
|
|
3
|
-
import {
|
|
3
|
+
import { Svcm } from "@nats-io/services";
|
|
4
4
|
import { connect, headers } from "@nats-io/transport-node";
|
|
5
5
|
import {
|
|
6
|
-
context,
|
|
7
|
-
propagation,
|
|
8
6
|
SpanKind,
|
|
9
7
|
SpanStatusCode,
|
|
8
|
+
context,
|
|
9
|
+
propagation,
|
|
10
10
|
trace
|
|
11
11
|
} from "@opentelemetry/api";
|
|
12
12
|
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto";
|
|
13
13
|
import { Resource } from "@opentelemetry/resources";
|
|
14
14
|
import { NodeSDK } from "@opentelemetry/sdk-node";
|
|
15
|
+
import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions";
|
|
15
16
|
import {
|
|
16
17
|
ATTR_MESSAGING_SYSTEM,
|
|
17
18
|
ATTR_RPC_METHOD,
|
|
18
|
-
ATTR_RPC_SERVICE
|
|
19
|
-
ATTR_SERVICE_NAME
|
|
19
|
+
ATTR_RPC_SERVICE
|
|
20
20
|
} from "@opentelemetry/semantic-conventions/incubating";
|
|
21
21
|
import pino from "pino";
|
|
22
22
|
async function init(nats, serviceName, version, description) {
|
|
@@ -49,7 +49,7 @@ var Kmicro = class {
|
|
|
49
49
|
pass: natsUrl.password,
|
|
50
50
|
servers: [natsUrl.host]
|
|
51
51
|
});
|
|
52
|
-
const svc = new
|
|
52
|
+
const svc = new Svcm(this.nc);
|
|
53
53
|
this.service = await svc.add({
|
|
54
54
|
name: this.meta.name,
|
|
55
55
|
version: this.meta.version,
|
|
@@ -90,7 +90,7 @@ var Kmicro = class {
|
|
|
90
90
|
10
|
|
91
91
|
);
|
|
92
92
|
if (currentCallDepth >= 20) {
|
|
93
|
-
throw new Error(
|
|
93
|
+
throw new Error(`max call depth reached: ${currentCallDepth}`);
|
|
94
94
|
}
|
|
95
95
|
const contextWithOtel = propagation.extract(
|
|
96
96
|
context.active(),
|
|
@@ -128,6 +128,7 @@ var Kmicro = class {
|
|
|
128
128
|
const requestContext = new RequestContext(
|
|
129
129
|
contextWithOtel,
|
|
130
130
|
span,
|
|
131
|
+
// biome-ignore lint/style/noNonNullAssertion: Checked with assert
|
|
131
132
|
this.nc,
|
|
132
133
|
spanLogger,
|
|
133
134
|
{
|
|
@@ -221,7 +222,7 @@ var CallError = class extends Error {
|
|
|
221
222
|
};
|
|
222
223
|
async function doCall(nc, target, payload, meta, options) {
|
|
223
224
|
if (meta.callDepth >= 20) {
|
|
224
|
-
throw new Error(
|
|
225
|
+
throw new Error(`max call depth reached: ${meta.callDepth}`);
|
|
225
226
|
}
|
|
226
227
|
const carrierData = meta.context ?? {};
|
|
227
228
|
if (options?.trace && !meta.context) {
|
|
@@ -259,23 +260,25 @@ async function doCall(nc, target, payload, meta, options) {
|
|
|
259
260
|
if (!Object.hasOwn(mergedHeaders, key)) {
|
|
260
261
|
continue;
|
|
261
262
|
}
|
|
262
|
-
|
|
263
|
+
if (mergedHeaders[key]) {
|
|
264
|
+
natsHeadersMap.set(key, mergedHeaders[key]);
|
|
265
|
+
}
|
|
263
266
|
}
|
|
264
267
|
try {
|
|
265
268
|
const result = await nc.request(target, payload, {
|
|
266
269
|
headers: natsHeadersMap,
|
|
267
270
|
timeout: options?.timeout ?? 5e3
|
|
268
271
|
});
|
|
269
|
-
span.setStatus({ code: SpanStatusCode.OK });
|
|
270
272
|
if (result.headers?.get("Nats-Service-Error-Code")) {
|
|
271
273
|
span.setStatus({ code: SpanStatusCode.ERROR });
|
|
272
274
|
span.recordException(result.headers.get("Nats-Service-Error"));
|
|
273
275
|
throw new CallError(
|
|
274
|
-
|
|
276
|
+
`received error: ${result.headers.get("Nats-Service-Error")}`,
|
|
275
277
|
target,
|
|
276
278
|
payload
|
|
277
279
|
);
|
|
278
280
|
}
|
|
281
|
+
span.setStatus({ code: SpanStatusCode.OK });
|
|
279
282
|
return result.data;
|
|
280
283
|
} finally {
|
|
281
284
|
span.end();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/KMicro.ts"],"sourcesContent":["import assert from 'node:assert';\nimport {Svc, type Service, type ServiceGroup} from '@nats-io/services';\nimport {connect, headers, type NatsConnection} from '@nats-io/transport-node';\nimport {\n\tcontext,\n\tpropagation,\n\tSpanKind,\n\tSpanStatusCode,\n\ttrace,\n\ttype Context,\n\ttype Span,\n} from '@opentelemetry/api';\nimport {OTLPTraceExporter} from '@opentelemetry/exporter-trace-otlp-proto';\nimport {Resource} from '@opentelemetry/resources';\nimport {NodeSDK} from '@opentelemetry/sdk-node';\nimport {\n\tATTR_MESSAGING_SYSTEM,\n\tATTR_RPC_METHOD,\n\tATTR_RPC_SERVICE,\n\tATTR_SERVICE_NAME,\n} from '@opentelemetry/semantic-conventions/incubating';\nimport pino, {type Logger} from 'pino';\n\n/**\n * Use init to create a kmicro instance and directly start (init) it\n */\nexport async function init(\n\tnats: string,\n\tserviceName: string,\n\tversion: string,\n\tdescription?: string,\n) {\n\tconst kmicro = new Kmicro({\n\t\tname: serviceName,\n\t\tversion,\n\t\tdescription,\n\t});\n\tawait kmicro.init(nats);\n\treturn kmicro;\n}\n\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\ninterface Callable {\n\tcall(\n\t\ttarget: string,\n\t\tpayload: Uint8Array,\n\t\toptions?: {\n\t\t\t/**\n\t\t\t * @default 5000 ms\n\t\t\t */\n\t\t\ttimeout?: number;\n\t\t},\n\t): Promise<Uint8Array>;\n}\n\nexport class Kmicro implements Callable {\n\tprivate service: Service | undefined;\n\tprivate group: ServiceGroup | undefined;\n\tprivate nc: NatsConnection | undefined;\n\tprivate otel: NodeSDK | undefined;\n\tprivate readonly pinoLogger: pino.Logger;\n\n\tconstructor(\n\t\tprivate readonly meta: {\n\t\t\tname: string;\n\t\t\tversion: string;\n\t\t\tdescription: string | undefined;\n\t\t},\n\t) {\n\t\tthis.pinoLogger = pino.pino();\n\t}\n\n\tpublic getLogger(module?: string) {\n\t\treturn this.pinoLogger.child({module});\n\t}\n\n\tpublic async init(natsURI: string) {\n\t\tconst natsUrl = new URL(natsURI);\n\t\tthis.nc = await connect({\n\t\t\tname: this.meta.name,\n\t\t\tuser: natsUrl.username,\n\t\t\tpass: natsUrl.password,\n\t\t\tservers: [natsUrl.host],\n\t\t});\n\t\tconst svc = new Svc(this.nc);\n\t\tthis.service = await svc.add({\n\t\t\tname: this.meta.name,\n\t\t\tversion: this.meta.version,\n\t\t\tdescription: this.meta.description,\n\t\t});\n\t\tthis.group = this.service.addGroup(this.meta.name);\n\t\tthis.otel = new NodeSDK({\n\t\t\tserviceName: this.meta.name,\n\t\t\ttraceExporter: new OTLPTraceExporter(),\n\t\t\tresource: new Resource({\n\t\t\t\t[ATTR_SERVICE_NAME]: this.meta.name,\n\t\t\t\t[ATTR_MESSAGING_SYSTEM]: 'nats',\n\t\t\t}),\n\t\t});\n\n\t\tthis.otel.start();\n\t}\n\n\tpublic async stop() {\n\t\tawait this.service?.stop().catch((error: unknown) => {\n\t\t\tconsole.error(error);\n\t\t});\n\t\tawait this.nc?.close().catch((error: unknown) => {\n\t\t\tconsole.error(error);\n\t\t});\n\t\tawait this.otel?.shutdown().catch((error: unknown) => {\n\t\t\tconsole.error(error);\n\t\t});\n\t}\n\n\tpublic addEndpoint(\n\t\tname: string,\n\t\thandler: (\n\t\t\tcontext_: RequestContext,\n\t\t\tdata: Uint8Array,\n\t\t) => Promise<Uint8Array>,\n\t) {\n\t\tassert(this.group);\n\n\t\tthis.group.addEndpoint(name, async (error, message) => {\n\t\t\tassert(this.nc);\n\t\t\tif (error) {\n\t\t\t\tconsole.error(error);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Prevent infinite loops\n\t\t\tconst currentCallDepth = Number.parseInt(\n\t\t\t\tmessage.headers?.get('kmc-depth') ?? '0',\n\t\t\t\t10,\n\t\t\t);\n\t\t\tif (currentCallDepth >= 20) {\n\t\t\t\tthrow new Error('max call depth reached: ' + currentCallDepth);\n\t\t\t}\n\n\t\t\tconst contextWithOtel: Context = propagation.extract(\n\t\t\t\tcontext.active(),\n\t\t\t\tmessage.headers,\n\t\t\t\t{\n\t\t\t\t\tget(carrier, key) {\n\t\t\t\t\t\treturn carrier?.get(key);\n\t\t\t\t\t},\n\t\t\t\t\tkeys(carrier) {\n\t\t\t\t\t\treturn carrier?.keys() ?? [];\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tconst tracer = trace.getTracer(this.meta.name, this.meta.version);\n\t\t\tconst spanName = `handle: ${this.meta.name}.${name}`;\n\t\t\tawait tracer.startActiveSpan(\n\t\t\t\tspanName,\n\t\t\t\t{\n\t\t\t\t\tkind: SpanKind.SERVER,\n\t\t\t\t},\n\t\t\t\tcontextWithOtel,\n\t\t\t\tasync (span) => {\n\t\t\t\t\tconst spanLogger = this.pinoLogger.child({\n\t\t\t\t\t\taction: name,\n\t\t\t\t\t\tspanId: span.spanContext().spanId,\n\t\t\t\t\t\ttraceId: span.spanContext().traceId,\n\t\t\t\t\t});\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst header: Record<string, string> = {};\n\t\t\t\t\t\tfor (const key of message.headers?.keys() ?? []) {\n\t\t\t\t\t\t\tif (message.headers?.has(key)) {\n\t\t\t\t\t\t\t\theader[key] = message.headers?.get(key);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst requestContext = new RequestContext(\n\t\t\t\t\t\t\tcontextWithOtel,\n\t\t\t\t\t\t\tspan,\n\t\t\t\t\t\t\tthis.nc!,\n\t\t\t\t\t\t\tspanLogger,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcallDepth: currentCallDepth,\n\t\t\t\t\t\t\t\tcurrentService: this.meta.name,\n\t\t\t\t\t\t\t\theader,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst result = await handler(requestContext, message.data);\n\t\t\t\t\t\tmessage.respond(result);\n\t\t\t\t\t\tspan.setStatus({code: SpanStatusCode.OK});\n\t\t\t\t\t} catch (error_) {\n\t\t\t\t\t\tspan.recordException(error_ as Error);\n\t\t\t\t\t\tmessage.respondError(500, (error_ as Error).message);\n\t\t\t\t\t\tspan.setStatus({code: SpanStatusCode.ERROR});\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tspan.end();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\t/**\n\t * Start a new call\n\t */\n\tpublic async call(\n\t\ttarget: string,\n\t\tpayload: Uint8Array,\n\t\toptions?: {\n\t\t\t/**\n\t\t\t * @default 5000 ms\n\t\t\t */\n\t\t\ttimeout?: number;\n\t\t\theader?: Record<string, string>;\n\t\t\tmoleculerTrace?: {\n\t\t\t\ttraceId?: string | undefined;\n\t\t\t\tparentId?: string | undefined;\n\t\t\t};\n\t\t},\n\t): Promise<Uint8Array> {\n\t\tassert(this.nc);\n\n\t\tlet trace:\n\t\t\t| undefined\n\t\t\t| {\n\t\t\t\t\ttraceId: string;\n\t\t\t\t\tparentId: string;\n\t\t\t };\n\t\tif (options?.moleculerTrace) {\n\t\t\t// we have to shorten the moleculer trace id because the jaeger exporter uses only 16 chars\n\t\t\tconst molTraceId = options.moleculerTrace.traceId\n\t\t\t\t?.replaceAll('-', '')\n\t\t\t\t.slice(0, 16);\n\t\t\tconst traceId = Array.from({length: 16})\n\t\t\t\t.fill('0')\n\t\t\t\t.join('')\n\t\t\t\t.concat(molTraceId ?? '');\n\t\t\tconst molParentId = options.moleculerTrace.parentId\n\t\t\t\t?.replaceAll('-', '')\n\t\t\t\t.slice(0, 16);\n\t\t\ttrace = {\n\t\t\t\ttraceId,\n\t\t\t\tparentId: molParentId ?? '',\n\t\t\t};\n\t\t}\n\n\t\treturn doCall(\n\t\t\tthis.nc,\n\t\t\ttarget,\n\t\t\tpayload,\n\t\t\t{\n\t\t\t\tcallDepth: 0,\n\t\t\t\tcontext: undefined,\n\t\t\t\tcurrentService: this.meta.name,\n\t\t\t\theader: options?.header ?? {},\n\t\t\t},\n\t\t\t{\n\t\t\t\ttimeout: options?.timeout,\n\t\t\t\ttrace,\n\t\t\t},\n\t\t);\n\t}\n}\n\nexport class RequestContext {\n\t// eslint-disable-next-line max-params\n\tconstructor(\n\t\treadonly context: Context,\n\t\treadonly span: Span,\n\t\treadonly nc: NatsConnection,\n\t\tprivate readonly logger: Logger,\n\t\treadonly meta: {\n\t\t\tcallDepth: number;\n\t\t\tcurrentService: string;\n\t\t\theader: Record<string, string>;\n\t\t},\n\t) {}\n\n\tpublic getLogger(module?: string) {\n\t\treturn this.logger.child({\n\t\t\tmodule,\n\t\t});\n\t}\n\n\tpublic async call(\n\t\ttarget: string,\n\t\tpayload: Uint8Array,\n\t\toptions?: {\n\t\t\t/**\n\t\t\t * @default 5000 ms\n\t\t\t */\n\t\t\ttimeout?: number;\n\t\t\theader?: Record<string, string>;\n\t\t},\n\t): Promise<Uint8Array> {\n\t\treturn doCall(\n\t\t\tthis.nc,\n\t\t\ttarget,\n\t\t\tpayload,\n\t\t\t{\n\t\t\t\tcallDepth: this.meta.callDepth,\n\t\t\t\tcontext: this.context,\n\t\t\t\tcurrentService: this.meta.currentService,\n\t\t\t\theader: this.meta.header,\n\t\t\t},\n\t\t\toptions,\n\t\t);\n\t}\n}\n\nexport class CallError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tprivate readonly target: string,\n\t\tprivate readonly payload: Uint8Array,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = 'CallError';\n\t}\n}\n\n// eslint-disable-next-line max-params\nasync function doCall(\n\tnc: NatsConnection,\n\ttarget: string,\n\tpayload: Uint8Array,\n\tmeta: {\n\t\tcallDepth: number;\n\t\t/**\n\t\t * The otel context\n\t\t */\n\t\tcontext: Context | undefined;\n\t\tcurrentService: string;\n\t\t/**\n\t\t * Headers from the parent calls\n\t\t */\n\t\theader: Record<string, string>;\n\t},\n\toptions?: {\n\t\t/**\n\t\t * @default 5000 ms\n\t\t */\n\t\ttimeout?: number;\n\t\theader?: Record<string, string>;\n\t\t/**\n\t\t * Optionally pass an existing trace from the moleculer framework\n\t\t */\n\t\ttrace?: {\n\t\t\t/**\n\t\t\t * This is the ID of the whole trace forest and is used to uniquely identify a distributed trace through a system.\n\t\t\t */\n\t\t\ttraceId: string | undefined;\n\t\t\t/**\n\t\t\t * or span id: This is the ID of this request as known by the caller\n\t\t\t */\n\t\t\tparentId: string | undefined;\n\t\t};\n\t},\n): Promise<Uint8Array> {\n\tif (meta.callDepth >= 20) {\n\t\tthrow new Error('max call depth reached: ' + meta.callDepth);\n\t}\n\n\tconst carrierData: Context | {traceparent?: string} = meta.context ?? {};\n\tif (options?.trace && !meta.context) {\n\t\tconst version = Buffer.alloc(1).toString('hex');\n\t\tconst flags = '01'; // means sampled\n\t\tconst header = `${version}-${options.trace.traceId}-${options.trace.parentId}-${flags}`;\n\t\t(carrierData as {traceparent?: string | undefined}).traceparent = header;\n\t}\n\n\tconst callingContext: Context = propagation.extract(\n\t\tcontext.active(),\n\t\tcarrierData,\n\t);\n\tconst tracer = trace.getTracer('default');\n\tconst [service, action] = target.split('.');\n\treturn tracer.startActiveSpan(\n\t\t`call: ${target}`,\n\t\t{\n\t\t\tkind: SpanKind.CLIENT,\n\t\t\tattributes: {\n\t\t\t\t[ATTR_RPC_SERVICE]: service,\n\t\t\t\t[ATTR_RPC_METHOD]: action,\n\t\t\t},\n\t\t},\n\t\tcallingContext,\n\t\tasync (span) => {\n\t\t\t// Add kmicro and otel headers to the nats message headers\n\t\t\tconst natsHeadersMap = headers();\n\t\t\tnatsHeadersMap.set('kmc-depth', (meta.callDepth + 1).toFixed(0));\n\t\t\tpropagation.inject(context.active(), natsHeadersMap, {\n\t\t\t\tset(carrier, key, value) {\n\t\t\t\t\tcarrier.set(key, value);\n\t\t\t\t},\n\t\t\t});\n\t\t\tconst mergedHeaders = {...meta.header, ...options?.header};\n\t\t\tfor (const key in mergedHeaders) {\n\t\t\t\tif (!Object.hasOwn(mergedHeaders, key)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tnatsHeadersMap.set(key, mergedHeaders[key]);\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst result = await nc.request(target, payload, {\n\t\t\t\t\theaders: natsHeadersMap,\n\t\t\t\t\ttimeout: options?.timeout ?? 5000,\n\t\t\t\t});\n\t\t\t\tspan.setStatus({code: SpanStatusCode.OK});\n\t\t\t\tif (result.headers?.get('Nats-Service-Error-Code')) {\n\t\t\t\t\tspan.setStatus({code: SpanStatusCode.ERROR});\n\t\t\t\t\tspan.recordException(result.headers.get('Nats-Service-Error'));\n\t\t\t\t\tthrow new CallError(\n\t\t\t\t\t\t'received error: ' + result.headers.get('Nats-Service-Error'),\n\t\t\t\t\t\ttarget,\n\t\t\t\t\t\tpayload,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn result.data;\n\t\t\t} finally {\n\t\t\t\tspan.end();\n\t\t\t}\n\t\t},\n\t);\n}\n"],"mappings":"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","names":["trace","context"]}
|
|
1
|
+
{"version":3,"sources":["../src/KMicro.ts"],"sourcesContent":["import assert from \"node:assert\";\nimport { type Service, type ServiceGroup, Svcm } from \"@nats-io/services\";\nimport { type NatsConnection, connect, headers } from \"@nats-io/transport-node\";\nimport {\n\ttype Context,\n\ttype Span,\n\tSpanKind,\n\tSpanStatusCode,\n\tcontext,\n\tpropagation,\n\ttrace,\n} from \"@opentelemetry/api\";\nimport { OTLPTraceExporter } from \"@opentelemetry/exporter-trace-otlp-proto\";\nimport { Resource } from \"@opentelemetry/resources\";\nimport { NodeSDK } from \"@opentelemetry/sdk-node\";\nimport { ATTR_SERVICE_NAME } from \"@opentelemetry/semantic-conventions\";\nimport {\n\tATTR_MESSAGING_SYSTEM,\n\tATTR_RPC_METHOD,\n\tATTR_RPC_SERVICE,\n} from \"@opentelemetry/semantic-conventions/incubating\";\nimport pino, { type Logger } from \"pino\";\n\n/**\n * Use init to create a kmicro instance and directly start (init) it\n */\nexport async function init(\n\tnats: string,\n\tserviceName: string,\n\tversion: string,\n\tdescription?: string,\n) {\n\tconst kmicro = new Kmicro({\n\t\tname: serviceName,\n\t\tversion,\n\t\tdescription,\n\t});\n\tawait kmicro.init(nats);\n\treturn kmicro;\n}\n\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\ninterface Callable {\n\tcall(\n\t\ttarget: string,\n\t\tpayload: Uint8Array,\n\t\toptions?: {\n\t\t\t/**\n\t\t\t * @default 5000 ms\n\t\t\t */\n\t\t\ttimeout?: number;\n\t\t},\n\t): Promise<Uint8Array>;\n}\n\nexport class Kmicro implements Callable {\n\tprivate service: Service | undefined;\n\tprivate group: ServiceGroup | undefined;\n\tprivate nc: NatsConnection | undefined;\n\tprivate otel: NodeSDK | undefined;\n\tprivate readonly pinoLogger: pino.Logger;\n\n\tconstructor(\n\t\tprivate readonly meta: {\n\t\t\tname: string;\n\t\t\tversion: string;\n\t\t\tdescription: string | undefined;\n\t\t},\n\t) {\n\t\tthis.pinoLogger = pino.pino();\n\t}\n\n\tpublic getLogger(module?: string) {\n\t\treturn this.pinoLogger.child({ module });\n\t}\n\n\tpublic async init(natsURI: string) {\n\t\tconst natsUrl = new URL(natsURI);\n\t\tthis.nc = await connect({\n\t\t\tname: this.meta.name,\n\t\t\tuser: natsUrl.username,\n\t\t\tpass: natsUrl.password,\n\t\t\tservers: [natsUrl.host],\n\t\t});\n\t\tconst svc = new Svcm(this.nc);\n\t\tthis.service = await svc.add({\n\t\t\tname: this.meta.name,\n\t\t\tversion: this.meta.version,\n\t\t\tdescription: this.meta.description,\n\t\t});\n\t\tthis.group = this.service.addGroup(this.meta.name);\n\t\tthis.otel = new NodeSDK({\n\t\t\tserviceName: this.meta.name,\n\t\t\ttraceExporter: new OTLPTraceExporter(),\n\t\t\tresource: new Resource({\n\t\t\t\t[ATTR_SERVICE_NAME]: this.meta.name,\n\t\t\t\t[ATTR_MESSAGING_SYSTEM]: \"nats\",\n\t\t\t}),\n\t\t});\n\n\t\tthis.otel.start();\n\t}\n\n\tpublic async stop() {\n\t\tawait this.service?.stop().catch((error: unknown) => {\n\t\t\tconsole.error(error);\n\t\t});\n\t\tawait this.nc?.close().catch((error: unknown) => {\n\t\t\tconsole.error(error);\n\t\t});\n\t\tawait this.otel?.shutdown().catch((error: unknown) => {\n\t\t\tconsole.error(error);\n\t\t});\n\t}\n\n\tpublic addEndpoint(\n\t\tname: string,\n\t\thandler: (\n\t\t\tcontext_: RequestContext,\n\t\t\tdata: Uint8Array,\n\t\t) => Promise<Uint8Array>,\n\t) {\n\t\tassert(this.group);\n\n\t\tthis.group.addEndpoint(name, async (error, message) => {\n\t\t\tassert(this.nc);\n\t\t\tif (error) {\n\t\t\t\tconsole.error(error);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Prevent infinite loops\n\t\t\tconst currentCallDepth = Number.parseInt(\n\t\t\t\tmessage.headers?.get(\"kmc-depth\") ?? \"0\",\n\t\t\t\t10,\n\t\t\t);\n\t\t\tif (currentCallDepth >= 20) {\n\t\t\t\tthrow new Error(`max call depth reached: ${currentCallDepth}`);\n\t\t\t}\n\n\t\t\tconst contextWithOtel: Context = propagation.extract(\n\t\t\t\tcontext.active(),\n\t\t\t\tmessage.headers,\n\t\t\t\t{\n\t\t\t\t\tget(carrier, key) {\n\t\t\t\t\t\treturn carrier?.get(key);\n\t\t\t\t\t},\n\t\t\t\t\tkeys(carrier) {\n\t\t\t\t\t\treturn carrier?.keys() ?? [];\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tconst tracer = trace.getTracer(this.meta.name, this.meta.version);\n\t\t\tconst spanName = `handle: ${this.meta.name}.${name}`;\n\t\t\tawait tracer.startActiveSpan(\n\t\t\t\tspanName,\n\t\t\t\t{\n\t\t\t\t\tkind: SpanKind.SERVER,\n\t\t\t\t},\n\t\t\t\tcontextWithOtel,\n\t\t\t\tasync (span) => {\n\t\t\t\t\tconst spanLogger = this.pinoLogger.child({\n\t\t\t\t\t\taction: name,\n\t\t\t\t\t\tspanId: span.spanContext().spanId,\n\t\t\t\t\t\ttraceId: span.spanContext().traceId,\n\t\t\t\t\t});\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst header: Record<string, string> = {};\n\t\t\t\t\t\tfor (const key of message.headers?.keys() ?? []) {\n\t\t\t\t\t\t\tif (message.headers?.has(key)) {\n\t\t\t\t\t\t\t\theader[key] = message.headers?.get(key);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst requestContext = new RequestContext(\n\t\t\t\t\t\t\tcontextWithOtel,\n\t\t\t\t\t\t\tspan,\n\t\t\t\t\t\t\t// biome-ignore lint/style/noNonNullAssertion: Checked with assert\n\t\t\t\t\t\t\tthis.nc!,\n\t\t\t\t\t\t\tspanLogger,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tcallDepth: currentCallDepth,\n\t\t\t\t\t\t\t\tcurrentService: this.meta.name,\n\t\t\t\t\t\t\t\theader,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t);\n\t\t\t\t\t\tconst result = await handler(requestContext, message.data);\n\t\t\t\t\t\tmessage.respond(result);\n\t\t\t\t\t\tspan.setStatus({ code: SpanStatusCode.OK });\n\t\t\t\t\t} catch (error_) {\n\t\t\t\t\t\tspan.recordException(error_ as Error);\n\t\t\t\t\t\tmessage.respondError(500, (error_ as Error).message);\n\t\t\t\t\t\tspan.setStatus({ code: SpanStatusCode.ERROR });\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tspan.end();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\t/**\n\t * Start a new call\n\t */\n\tpublic async call(\n\t\ttarget: string,\n\t\tpayload: Uint8Array,\n\t\toptions?: {\n\t\t\t/**\n\t\t\t * @default 5000 ms\n\t\t\t */\n\t\t\ttimeout?: number;\n\t\t\theader?: Record<string, string>;\n\t\t\tmoleculerTrace?: {\n\t\t\t\ttraceId?: string | undefined;\n\t\t\t\tparentId?: string | undefined;\n\t\t\t};\n\t\t},\n\t): Promise<Uint8Array> {\n\t\tassert(this.nc);\n\n\t\tlet trace:\n\t\t\t| undefined\n\t\t\t| {\n\t\t\t\t\ttraceId: string;\n\t\t\t\t\tparentId: string;\n\t\t\t };\n\t\tif (options?.moleculerTrace) {\n\t\t\t// we have to shorten the moleculer trace id because the jaeger exporter uses only 16 chars\n\t\t\tconst molTraceId = options.moleculerTrace.traceId\n\t\t\t\t?.replaceAll(\"-\", \"\")\n\t\t\t\t.slice(0, 16);\n\t\t\tconst traceId = Array.from({ length: 16 })\n\t\t\t\t.fill(\"0\")\n\t\t\t\t.join(\"\")\n\t\t\t\t.concat(molTraceId ?? \"\");\n\t\t\tconst molParentId = options.moleculerTrace.parentId\n\t\t\t\t?.replaceAll(\"-\", \"\")\n\t\t\t\t.slice(0, 16);\n\t\t\ttrace = {\n\t\t\t\ttraceId,\n\t\t\t\tparentId: molParentId ?? \"\",\n\t\t\t};\n\t\t}\n\n\t\treturn doCall(\n\t\t\tthis.nc,\n\t\t\ttarget,\n\t\t\tpayload,\n\t\t\t{\n\t\t\t\tcallDepth: 0,\n\t\t\t\tcontext: undefined,\n\t\t\t\tcurrentService: this.meta.name,\n\t\t\t\theader: options?.header ?? {},\n\t\t\t},\n\t\t\t{\n\t\t\t\ttimeout: options?.timeout,\n\t\t\t\ttrace,\n\t\t\t},\n\t\t);\n\t}\n}\n\nexport class RequestContext {\n\t// eslint-disable-next-line max-params\n\tconstructor(\n\t\treadonly context: Context,\n\t\treadonly span: Span,\n\t\treadonly nc: NatsConnection,\n\t\tprivate readonly logger: Logger,\n\t\treadonly meta: {\n\t\t\tcallDepth: number;\n\t\t\tcurrentService: string;\n\t\t\theader: Record<string, string>;\n\t\t},\n\t) {}\n\n\tpublic getLogger(module?: string) {\n\t\treturn this.logger.child({\n\t\t\tmodule,\n\t\t});\n\t}\n\n\tpublic async call(\n\t\ttarget: string,\n\t\tpayload: Uint8Array,\n\t\toptions?: {\n\t\t\t/**\n\t\t\t * @default 5000 ms\n\t\t\t */\n\t\t\ttimeout?: number;\n\t\t\theader?: Record<string, string>;\n\t\t},\n\t): Promise<Uint8Array> {\n\t\treturn doCall(\n\t\t\tthis.nc,\n\t\t\ttarget,\n\t\t\tpayload,\n\t\t\t{\n\t\t\t\tcallDepth: this.meta.callDepth,\n\t\t\t\tcontext: this.context,\n\t\t\t\tcurrentService: this.meta.currentService,\n\t\t\t\theader: this.meta.header,\n\t\t\t},\n\t\t\toptions,\n\t\t);\n\t}\n}\n\nexport class CallError extends Error {\n\tconstructor(\n\t\tmessage: string,\n\t\tprivate readonly target: string,\n\t\tprivate readonly payload: Uint8Array,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"CallError\";\n\t}\n}\n\n// eslint-disable-next-line max-params\nasync function doCall(\n\tnc: NatsConnection,\n\ttarget: string,\n\tpayload: Uint8Array,\n\tmeta: {\n\t\tcallDepth: number;\n\t\t/**\n\t\t * The otel context\n\t\t */\n\t\tcontext: Context | undefined;\n\t\tcurrentService: string;\n\t\t/**\n\t\t * Headers from the parent calls\n\t\t */\n\t\theader: Record<string, string>;\n\t},\n\toptions?: {\n\t\t/**\n\t\t * @default 5000 ms\n\t\t */\n\t\ttimeout?: number;\n\t\theader?: Record<string, string>;\n\t\t/**\n\t\t * Optionally pass an existing trace from the moleculer framework\n\t\t */\n\t\ttrace?: {\n\t\t\t/**\n\t\t\t * This is the ID of the whole trace forest and is used to uniquely identify a distributed trace through a system.\n\t\t\t */\n\t\t\ttraceId: string | undefined;\n\t\t\t/**\n\t\t\t * or span id: This is the ID of this request as known by the caller\n\t\t\t */\n\t\t\tparentId: string | undefined;\n\t\t};\n\t},\n): Promise<Uint8Array> {\n\tif (meta.callDepth >= 20) {\n\t\tthrow new Error(`max call depth reached: ${meta.callDepth}`);\n\t}\n\n\tconst carrierData: Context | { traceparent?: string } = meta.context ?? {};\n\tif (options?.trace && !meta.context) {\n\t\tconst version = Buffer.alloc(1).toString(\"hex\");\n\t\tconst flags = \"01\"; // means sampled\n\t\tconst header = `${version}-${options.trace.traceId}-${options.trace.parentId}-${flags}`;\n\t\t(carrierData as { traceparent?: string | undefined }).traceparent = header;\n\t}\n\n\tconst callingContext: Context = propagation.extract(\n\t\tcontext.active(),\n\t\tcarrierData,\n\t);\n\tconst tracer = trace.getTracer(\"default\");\n\tconst [service, action] = target.split(\".\");\n\treturn tracer.startActiveSpan(\n\t\t`call: ${target}`,\n\t\t{\n\t\t\tkind: SpanKind.CLIENT,\n\t\t\tattributes: {\n\t\t\t\t[ATTR_RPC_SERVICE]: service,\n\t\t\t\t[ATTR_RPC_METHOD]: action,\n\t\t\t},\n\t\t},\n\t\tcallingContext,\n\t\tasync (span) => {\n\t\t\t// Add kmicro and otel headers to the nats message headers\n\t\t\tconst natsHeadersMap = headers();\n\t\t\tnatsHeadersMap.set(\"kmc-depth\", (meta.callDepth + 1).toFixed(0));\n\t\t\tpropagation.inject(context.active(), natsHeadersMap, {\n\t\t\t\tset(carrier, key, value) {\n\t\t\t\t\tcarrier.set(key, value);\n\t\t\t\t},\n\t\t\t});\n\t\t\tconst mergedHeaders = { ...meta.header, ...options?.header };\n\t\t\tfor (const key in mergedHeaders) {\n\t\t\t\tif (!Object.hasOwn(mergedHeaders, key)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (mergedHeaders[key]) {\n\t\t\t\t\tnatsHeadersMap.set(key, mergedHeaders[key]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst result = await nc.request(target, payload, {\n\t\t\t\t\theaders: natsHeadersMap,\n\t\t\t\t\ttimeout: options?.timeout ?? 5000,\n\t\t\t\t});\n\t\t\t\tif (result.headers?.get(\"Nats-Service-Error-Code\")) {\n\t\t\t\t\tspan.setStatus({ code: SpanStatusCode.ERROR });\n\t\t\t\t\tspan.recordException(result.headers.get(\"Nats-Service-Error\"));\n\t\t\t\t\tthrow new CallError(\n\t\t\t\t\t\t`received error: ${result.headers.get(\"Nats-Service-Error\")}`,\n\t\t\t\t\t\ttarget,\n\t\t\t\t\t\tpayload,\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tspan.setStatus({ code: SpanStatusCode.OK });\n\t\t\t\treturn result.data;\n\t\t\t} finally {\n\t\t\t\tspan.end();\n\t\t\t}\n\t\t},\n\t);\n}\n"],"mappings":"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","names":["trace","context"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kultify/kmicro-js",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.14",
|
|
4
4
|
"description": "",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
"scripts": {
|
|
13
13
|
"build": "tsup",
|
|
14
14
|
"test": "vitest src/",
|
|
15
|
-
"lint": "
|
|
16
|
-
"ci": "
|
|
15
|
+
"lint": "biome lint",
|
|
16
|
+
"ci": "biome ci && pnpm vitest run",
|
|
17
17
|
"run-nats": "docker run -p 4222:4222 nats -js"
|
|
18
18
|
},
|
|
19
19
|
"engines": {
|
|
@@ -49,25 +49,25 @@
|
|
|
49
49
|
"author": "Kultify GmbH",
|
|
50
50
|
"license": "MIT",
|
|
51
51
|
"dependencies": {
|
|
52
|
-
"@nats-io/services": "3.0.0-
|
|
53
|
-
"@nats-io/transport-node": "3.0.0-
|
|
52
|
+
"@nats-io/services": "3.0.0-23",
|
|
53
|
+
"@nats-io/transport-node": "3.0.0-33",
|
|
54
54
|
"@opentelemetry/api": "^1.9.0",
|
|
55
|
-
"@opentelemetry/core": "^1.
|
|
56
|
-
"@opentelemetry/exporter-trace-otlp-proto": "^0.
|
|
57
|
-
"@opentelemetry/resources": "^1.
|
|
58
|
-
"@opentelemetry/sdk-node": "^0.
|
|
59
|
-
"@opentelemetry/sdk-trace-node": "^1.
|
|
60
|
-
"@opentelemetry/semantic-conventions": "^1.
|
|
61
|
-
"pino": "^9.
|
|
55
|
+
"@opentelemetry/core": "^1.30.0",
|
|
56
|
+
"@opentelemetry/exporter-trace-otlp-proto": "^0.57.0",
|
|
57
|
+
"@opentelemetry/resources": "^1.30.0",
|
|
58
|
+
"@opentelemetry/sdk-node": "^0.57.0",
|
|
59
|
+
"@opentelemetry/sdk-trace-node": "^1.30.0",
|
|
60
|
+
"@opentelemetry/semantic-conventions": "^1.28.0",
|
|
61
|
+
"pino": "^9.6.0"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
|
+
"@biomejs/biome": "1.9.4",
|
|
64
65
|
"@tsconfig/node20": "^20.1.4",
|
|
65
|
-
"@types/node": "^22.
|
|
66
|
+
"@types/node": "^22.10.5",
|
|
66
67
|
"jaeger-client": "^3.19.0",
|
|
67
|
-
"moleculer": "^0.14.
|
|
68
|
+
"moleculer": "^0.14.35",
|
|
68
69
|
"tsup": "^8.3.5",
|
|
69
|
-
"typescript": "5.
|
|
70
|
-
"vitest": "^2.1.
|
|
71
|
-
"xo": "^0.59.3"
|
|
70
|
+
"typescript": "5.7.2",
|
|
71
|
+
"vitest": "^2.1.8"
|
|
72
72
|
}
|
|
73
73
|
}
|