Skip to content

Commit b84efbd

Browse files
committed
feat(diagnostics): allow re-registration with equivalent tracingChannel function
1 parent 11e890d commit b84efbd

2 files changed

Lines changed: 23 additions & 1 deletion

File tree

src/__tests__/diagnostics-test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,20 @@ describe('diagnostics', () => {
5252
}),
5353
).to.throw(/different `diagnostics_channel` module/);
5454
});
55+
56+
it('re-registration accepts a wrapper sharing the same tracingChannel fn', () => {
57+
enableDiagnosticsChannel(sharedFakeDc);
58+
const first = getChannels();
59+
invariant(first !== undefined);
60+
61+
// Models an ESM Module Namespace object: distinct outer reference, but
62+
// the `tracingChannel` property is strictly the same function as the
63+
// default export's, so it routes to the same underlying channel cache.
64+
const namespaceLike = { tracingChannel: sharedFakeDc.tracingChannel };
65+
expect(namespaceLike).to.not.equal(sharedFakeDc);
66+
expect(namespaceLike.tracingChannel).to.equal(sharedFakeDc.tracingChannel);
67+
68+
expect(() => enableDiagnosticsChannel(namespaceLike)).to.not.throw();
69+
expect(getChannels()).to.equal(first);
70+
});
5571
});

src/diagnostics.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ export function getChannels(): GraphQLChannels | undefined {
9999
* - `graphql:subscribe`
100100
* - `graphql:resolve`
101101
*
102+
* Re-registration is tolerated when the incoming `dc` exposes the same
103+
* `tracingChannel` function as the previously registered one
102104
* @throws {Error} If a different `diagnostics_channel` module is registered.
103105
*
104106
* @example
@@ -115,7 +117,11 @@ export function getChannels(): GraphQLChannels | undefined {
115117
*/
116118
export function enableDiagnosticsChannel(dc: MinimalDiagnosticsChannel): void {
117119
if (registeredDc !== undefined) {
118-
if (registeredDc !== dc) {
120+
// Compare `tracingChannel` function identity rather than module identity
121+
// so consumers that pass an ESM Module Namespace object and consumers
122+
// that pass the default export of the same underlying module are
123+
// treated as equivalent
124+
if (registeredDc.tracingChannel !== dc.tracingChannel) {
119125
throw new Error(
120126
'enableDiagnosticsChannel was called with a different `diagnostics_channel` module than the one previously registered. graphql-js can only publish to one module at a time; ensure all APMs share the same `node:diagnostics_channel` import.',
121127
);

0 commit comments

Comments
 (0)