realtymaps/promise-ftp

How do you set the Promise library since removal of bluebird

kriswest opened this issue · 9 comments

Hey,

Since the removal of bluebird in Dec 2015, how are you expected to set the Promise reference (we're using bluebird). I was hoping to do without modifying the promise-ftp source...

We note promise-sftp still depends on bluebird:
├─┬ promise-ftp@1.2.14
│ └─┬ ftp@0.3.10
│ ├─┬ readable-stream@1.1.14
│ │ └── isarray@0.0.1
│ └── xregexp@2.0.0
├── promise-ftp-common@1.1.5
├─┬ promise-sftp@0.9.6
│ ├── bluebird@2.10.2
│ └─┬ ssh2@0.4.13 (git://github.com/realtymaps/ssh2.git#b3db686863df02a0d2d1c9e6fa213b26c8111303)
│ ├─┬ readable-stream@1.0.34
│ │ └── isarray@0.0.1
│ └─┬ ssh2-streams@0.0.14
│ ├── asn1@0.2.3
│ ├── jsbn@0.1.0
│ ├─┬ readable-stream@1.0.34
│ │ └── isarray@0.0.1
│ └── streamsearch@0.1.2

I'm not sure what you mean by "set the Promise reference". What is it you're trying to do?

In node 4.x and higher, Promise is a global that is already defined, so using a library like bluebird is unnecessary. (That's the reason it was removed.) However, I've been considering switching back to using bluebird promises, since it seems bluebird promises are more performant, plus it would work with node < 4.0. If I do that, however, I will probably use bluebird 3.x rather than 2.x, which could cause compatibility problems if your project is still using bluebird 2.x.

Hmm, we're using node 4.3.1 but its not finding Promise as a global:

$ node --version
v4.3.1
$ node -e 'console.log(process.versions.v8);'
4.5.103.35

Unhandled exception in host API:
name: ReferenceError
message: Promise is not defined
stack: ReferenceError: Promise is not defined
at PromiseFtp.connect (/data/ringr-api/node_modules/promise-ftp/dist/promiseFtp.js:84:16)

We're trying to use both promise-ftp and promise-sftp, promise-sft still
has it as a dependency:

dependencies:
{ bluebird: '2.x',
ssh2: 'git://github.com/realtymaps/ssh2.git' },

Would it make sense to test for the Promise as a global and require it if
not found? Will mean bringing the dependency back, but possibly not using
it, e.g.:
var Promise = Promise || require('bluebird')

Are their any flags that we need to pass to node to enable the native
promise implementation?

What do you get from node -e 'console.log(typeof Promise);'?

$ node -e 'console.log(typeof Promise);'
function

On 23 June 2016 at 19:35, Joe Ibershoff notifications@github.com wrote:

What do you get from node -e 'console.log(typeof Promise);'?


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
#9 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/ABn3hGqMC51jw_9jzURRzLaPY9E3g7DVks5qOtHugaJpZM4I80qy
.

Regards,

Dr Kris West

Tel (UK): +44 (0)203 289 4553
Support hotline: +44 (0)203 397 4093

Skype: kriswest

So you do get the global -- but it must be getting unset somewhere. Possibly by bluebird 2.x in promise-sftp? I'm not sure why bluebird would unset the global though.

If you don't mind, let's do a test. I'd like to try to hone in on exactly where you are losing the Promise global. Sprinkle some if ((typeof Promise) != 'function') throw new Error('Promise has been unset before here!'); lines into your app, and see what you get in the stacktrace. I'd put that before and after you require promise-sftp, or if you want to go whole hog, then intersperse that around each of your requires. in the entry file for your app. Once you see a stacktrace and where it points, if it's an outside require that seems to be the trigger, then our test is complete. If it's one of your files, go into that file and put in another of those debug lines between each of your requires. Repeat until you know exactly which require statement causes the problem.

Many thanks - we've just spotted that the system level node install is behind the one in user space, which is probably the root cause. I'll get that sorted out, retested and get back to you if we're still seeing the same issue. If a module is unsetting the reference I'll debug as expected and try to find it.

Aha, yep sounds like you've probably nailed it. Please let me know either way.

Yep that was it - sorry to bother you and thanks for the speedy responses (closing).

Ever considered merging with promise-sftp and presenting as a single module? We're essentially writing a wrapper to do that so we can offer FTP/SFTP/FTPS integration in a data service for file export.

I originally set out to do that, yes, and in fact did some extra work to add promise-sftp methods that mimic regular promise-ftp methods just to make them more easily interchangeable. I think I had trouble figuring out how to mimic the preserveCwd option from promise-ftp in the promise-sftp context. There are also lots of sftp methods that can't be mimicked in promise-ftp, so I figured rather than cater to the lowest common denominator, I preferred to keep them separate.

For many use cases, if you don't care about any of the mutually exclusive options, it would be easy to just do something like:

if (useSftp) {
  var ftpClient = new PromiseSftp()
} else {
  ftpClient = new PromiseFtp()
}
// everything from here on can be the same either way, if you stick to interoperable methods only
ftpClient.connect(configOptions)
...

without actually needing a wrapper or combined module. So the effort didn't seem worth it to me for our needs. With that said, if you'd like to open-source your wrapper code, I'd be happy to either link to it in the readme or maintain it under our umbrella.