THRIFT-6040: Switch JS/Node generator and runtime from Q to native Promise#3528
Open
jimexist wants to merge 3 commits into
Open
THRIFT-6040: Switch JS/Node generator and runtime from Q to native Promise#3528jimexist wants to merge 3 commits into
jimexist wants to merge 3 commits into
Conversation
Removes the runtime dependency on the `q` Promise library and switches
the JS/TS code generator to emit native Promise by default.
- Compiler (t_js_generator.cc): in non-ES6 mode the processor emits
`new Promise((resolve) => resolve(handler.fn(args)))` instead of
`Q.fcall(...)`, and the Node client emits `new Promise((resolve, reject)
=> ...)` instead of `Q.defer()` / `_defer.promise`. The non-ES6 JS/TS
imports no longer pull in `Q` by default.
- New compiler flag `js:native_promise=[true|false]` (default `true`).
Setting it to `false` restores the legacy `Q.fcall` / `Q.defer` output
and emits `const Q = require('q');` / `import Q = require('q');`
directly (no longer routed through `thrift.Q`), so legacy users only
need `q` in their own `node_modules`.
- Runtime: removed `exports.Q = require("q")` from
lib/nodejs/lib/thrift/index.js and browser.js, dropped `q` from
dependencies and `@types/q` from devDependencies, and pruned the
matching package-lock.json entries.
- Tests: lib/nodets/test/test_driver.ts and test_handler.ts now use
native `Promise` / `.catch()` instead of `Q.IPromise` / `Q.resolve` /
`.fail()`. Renamed the test case "Q Promise Client Tests" to
"Promise Client Tests". `AsyncThriftTestHandler` return types changed
to `Promise<void>` (the callback delivers the value and the body
returns `Promise.resolve()`, which native Promise types strictly).
Client: js,nodejs
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Native Promise's `.catch(fn)` strictly expects a one-arg callback; Q's `.fail(fn)` was loose about extra args, so `function (error, response)` worked before. TS errors out with TS2345 — drop the unused `response` arg. Client: nodets Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR removes the Node.js runtime dependency on the q Promise library and updates the JS/TS code generator to emit native Promise-based code by default, with an opt-out js:native_promise=false flag to restore legacy Q-shaped output.
Changes:
- Dropped
q(and@types/q) from npm dependencies and removed thethrift.Qruntime export. - Updated the JS/TS generator to default to native
Promisecode paths and added anative_promisegenerator option to toggle legacy Q output/imports. - Updated Node TS tests to use native
PromiseAPIs (Promise.resolve,.catch) and removed Q typing/usages.
Reviewed changes
Copilot reviewed 6 out of 8 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
compiler/cpp/src/thrift/generate/t_js_generator.cc |
Adds native_promise option and switches non-ES6 generated code paths from Q to native Promises by default. |
lib/nodejs/lib/thrift/index.js |
Removes exports.Q from the Node runtime entrypoint. |
lib/nodejs/lib/thrift/browser.js |
Removes exports.Q from the browser runtime entrypoint. |
package.json |
Removes q from dependencies and @types/q from devDependencies. |
package-lock.json |
Prunes q / @types/q entries from the lockfile. |
lib/nodejs/test/package-lock.json |
Prunes q / @types/q entries from the test lockfile. |
lib/nodets/test/test_handler.ts |
Migrates test handlers from Q promises to native Promise return types and helpers. |
lib/nodets/test/test_driver.ts |
Migrates promise-client tests from .fail/Q patterns to .catch/native Promise patterns. |
Files not reviewed (1)
- lib/nodejs/test/package-lock.json: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- t_js_generator.cc: stop emitting an arrow function inside the Promise
constructor for non-ES6 native_promise mode. Use
`new Promise(function(resolve) { resolve(...); }.bind(this))` so the
output stays ES5-compatible and `this` is bound explicitly.
- test_driver.ts: pass the actual `fnName` variable to `.catch(fail(...))`
in `makeAsserter` (was the literal string "fnName"), so failures report
which RPC actually failed.
- test_driver.ts: in the `testException("TException")` / "Xception"
unexpected-resolve branches, call `assert.fail(...)` directly instead
of `fail(...)` which only returned a function and was never invoked.
Client: js,nodets
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Removes the runtime dependency on the
qPromise library and switches the JS/TS code generator to emit nativePromiseby default. Adds ajs:native_promise=[true|false]compiler flag (defaulttrue) so users who still need the old output can opt back in.What changed
Compiler (
compiler/cpp/src/thrift/generate/t_js_generator.cc)new Promise((resolve) => resolve(handler.fn(args)))instead ofQ.fcall(...).new Promise((resolve, reject) => { ... })instead ofQ.defer()/_defer.promise._includesno longer pull inQby default.js:native_promise=[true|false](defaulttrue). Whenfalse, the legacyQ.fcall/Q.deferoutput is restored andQis imported directly viarequire('q')(no longer routed throughthrift.Q), so legacy users only needqin their ownnode_modules.Runtime (
lib/nodejs/lib/thrift/index.js,lib/nodejs/lib/thrift/browser.js)exports.Q = require("q").Dependencies (
package.json,package-lock.json,lib/nodejs/test/package-lock.json)qfromdependenciesand@types/qfromdevDependencies; pruned the matching lockfile entries.Tests (
lib/nodets/test/test_driver.ts,lib/nodets/test/test_handler.ts)Q.IPromise<T>→Promise<T>;Q.resolve(x)→Promise.resolve(x);.fail(...)→.catch(...).import Q = require("q")/import Q = thrift.Q.AsyncThriftTestHandlermethod return types changed toPromise<void>since the callback delivers the value and the body returnsPromise.resolve()(nativePromise<void>is not assignable toPromise<string>etc. under TS strict mode, unlike Q's loose typings)."Q Promise Client Tests"→"Promise Client Tests".Why
qhas been in maintenance mode for years; nativePromiseis available in every supported runtime (node >= 10.18.0perpackage.json). Removing it shrinks the dependency footprint and brings the non-ES6 / Node output in line with what the ES6 generator already emitted. Thenative_promiseflag is an escape hatch for downstream code that still depends on the Q-shaped output.Heads-up for reviewers
npm run lint,npm run test-ts, and a thrift compiler build that regenerates an example service in both default andnative_promise=falsemodes.thrift.Qis gone; downstream code that imported it will break. Users who need to keep it can use the newnative_promise=falsegenerator flag and installqthemselves.Test plan
make stylepassesnpm run lintandnpm run test-tspass.thriftservice is valid JS/TS under bothnative_promisedefaultsnative_promise=falseoutput still works against a project that hasqinstalled🤖 Generated with Claude Code