@foam-ai/node-cliengo 0.1.0-alpha.17 → 0.1.0-alpha.19

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.
@@ -23,6 +23,9 @@
23
23
  * - All hooks wrapped in try/catch — never crashes the request pipeline.
24
24
  * - onError/onResponse use async hooks (Fastify 5 forward-compat).
25
25
  * onRequest uses callback style intentionally for context.with() propagation.
26
+ * - Plugin sets Symbol.for('skip-override') (same as fastify-plugin) so hooks
27
+ * fire globally across all encapsulated contexts. Without this, hooks only
28
+ * fire for routes in the same plugin scope — a silent production footgun.
26
29
  */
27
30
  import { type Tracer } from '@opentelemetry/api';
28
31
  import type { FastifyPluginAsync } from '../types';
@@ -24,6 +24,9 @@
24
24
  * - All hooks wrapped in try/catch — never crashes the request pipeline.
25
25
  * - onError/onResponse use async hooks (Fastify 5 forward-compat).
26
26
  * onRequest uses callback style intentionally for context.with() propagation.
27
+ * - Plugin sets Symbol.for('skip-override') (same as fastify-plugin) so hooks
28
+ * fire globally across all encapsulated contexts. Without this, hooks only
29
+ * fire for routes in the same plugin scope — a silent production footgun.
27
30
  */
28
31
  Object.defineProperty(exports, "__esModule", { value: true });
29
32
  exports.getRequestTraceContext = getRequestTraceContext;
@@ -55,7 +58,7 @@ function getRequestTraceContext(request) {
55
58
  }
56
59
  /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment */
57
60
  function createFastifyPlugin(tracer) {
58
- return async (fastify) => {
61
+ const plugin = async (fastify) => {
59
62
  // onRequest uses callback style intentionally — otelContext.with(ctx, done)
60
63
  // propagates the shadow span as the active OTel context via AsyncLocalStorage
61
64
  // to all downstream hooks and the route handler. Async hooks would lose the
@@ -143,5 +146,11 @@ function createFastifyPlugin(tracer) {
143
146
  }
144
147
  });
145
148
  };
149
+ // Equivalent to wrapping with fastify-plugin — breaks Fastify's encapsulation
150
+ // so hooks fire for ALL routes, not just those registered in the same scope.
151
+ // Without this, hooks silently no-op for routes in child contexts.
152
+ plugin[Symbol.for('skip-override')] = true;
153
+ plugin[Symbol.for('fastify.display-name')] = '@foam-ai/node-cliengo';
154
+ return plugin;
146
155
  }
147
156
  /* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment */
@@ -110,8 +110,14 @@ function createInertInstance(serviceName) {
110
110
  buildTraceparent: trace_bridge_1.buildTraceparent,
111
111
  injectSnsAttributes: sns_1.injectSnsAttributes,
112
112
  injectJobData: job_1.injectJobData,
113
- wrapSqsConsumer: async (_s, _m, fn) => fn(),
114
- wrapJobConsumer: async (_s, _j, fn) => fn(),
113
+ wrapSqsConsumer: async (...args) => {
114
+ const fn = typeof args[0] === 'string' ? args[2] : args[3];
115
+ return fn();
116
+ },
117
+ wrapJobConsumer: async (...args) => {
118
+ const fn = typeof args[0] === 'string' ? args[2] : args[3];
119
+ return fn();
120
+ },
115
121
  extractParentContext: () => {
116
122
  const { ROOT_CONTEXT } = require('@opentelemetry/api');
117
123
  return ROOT_CONTEXT;
@@ -381,8 +387,18 @@ function init(serviceName, options = {}) {
381
387
  buildTraceparent: trace_bridge_1.buildTraceparent,
382
388
  injectSnsAttributes: sns_1.injectSnsAttributes,
383
389
  injectJobData: job_1.injectJobData,
384
- wrapSqsConsumer: (s, m, fn) => (0, sqs_1.wrapSqsConsumer)(tracer, s, m, fn, metrics),
385
- wrapJobConsumer: (s, j, fn) => (0, job_1.wrapJobConsumer)(tracer, s, j, fn, metrics),
390
+ wrapSqsConsumer: (...args) => {
391
+ if (typeof args[0] === 'string') {
392
+ return (0, sqs_1.wrapSqsConsumer)(tracer, args[0], args[1], args[2], metrics);
393
+ }
394
+ return (0, sqs_1.wrapSqsConsumer)(tracer, args[1], args[2], args[3], metrics);
395
+ },
396
+ wrapJobConsumer: (...args) => {
397
+ if (typeof args[0] === 'string') {
398
+ return (0, job_1.wrapJobConsumer)(tracer, args[0], args[1], args[2], metrics);
399
+ }
400
+ return (0, job_1.wrapJobConsumer)(tracer, args[1], args[2], args[3], metrics);
401
+ },
386
402
  extractParentContext: trace_bridge_1.extractParentContext,
387
403
  shutdown,
388
404
  };
@@ -96,7 +96,11 @@ export interface FoamInstance {
96
96
  injectJobData<T extends Record<string, unknown>>(data: T): T & {
97
97
  traceparent: string;
98
98
  };
99
+ /** @deprecated Pass (spanName, msg, fn) — the tracer arg is no longer needed. */
100
+ wrapSqsConsumer(tracer: Tracer, spanName: string, msg: SqsMessage, fn: () => Promise<void>): Promise<void>;
99
101
  wrapSqsConsumer(spanName: string, msg: SqsMessage, fn: () => Promise<void>): Promise<void>;
102
+ /** @deprecated Pass (spanName, jobData, fn) — the tracer arg is no longer needed. */
103
+ wrapJobConsumer(tracer: Tracer, spanName: string, jobData: Record<string, unknown>, fn: () => Promise<void>): Promise<void>;
100
104
  wrapJobConsumer(spanName: string, jobData: Record<string, unknown>, fn: () => Promise<void>): Promise<void>;
101
105
  extractParentContext(traceparent: string): Context;
102
106
  shutdown(): Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@foam-ai/node-cliengo",
3
- "version": "0.1.0-alpha.17",
3
+ "version": "0.1.0-alpha.19",
4
4
  "description": "Unified observability (traces, logs, metrics) for Cliengo Node.js services, connecting New Relic APM with Foam's OTel collector.",
5
5
  "main": "dist/node-cliengo/src/index.js",
6
6
  "types": "dist/node-cliengo/src/index.d.ts",