From ddf2cfd48df38fb40ad56b38c7da887cbd508b3a Mon Sep 17 00:00:00 2001 From: Ryohei Ikegami Date: Fri, 31 Jul 2015 14:26:57 +0900 Subject: [PATCH 1/5] Support remote Promise in renderer --- atom/browser/lib/rpc-server.coffee | 3 +++ atom/renderer/api/lib/remote.coffee | 1 + 2 files changed, 4 insertions(+) diff --git a/atom/browser/lib/rpc-server.coffee b/atom/browser/lib/rpc-server.coffee index ab86a0c45518..d1e3267784e5 100644 --- a/atom/browser/lib/rpc-server.coffee +++ b/atom/browser/lib/rpc-server.coffee @@ -10,6 +10,7 @@ valueToMeta = (sender, value) -> meta.type = 'buffer' if Buffer.isBuffer value meta.type = 'value' if value is null meta.type = 'array' if Array.isArray value + meta.type = 'promise' if Promise.resolve(value) == value # Treat the arguments object as array. meta.type = 'array' if meta.type is 'object' and value.callee? and value.length? @@ -29,6 +30,8 @@ valueToMeta = (sender, value) -> meta.members.push {name: prop, type: typeof field} for prop, field of value else if meta.type is 'buffer' meta.value = Array::slice.call value, 0 + else if meta.type is 'promise' + meta.then = valueToMeta(sender, value.then.bind(value)) else meta.type = 'value' meta.value = value diff --git a/atom/renderer/api/lib/remote.coffee b/atom/renderer/api/lib/remote.coffee index b159125b7949..5ad7c80ca01f 100644 --- a/atom/renderer/api/lib/remote.coffee +++ b/atom/renderer/api/lib/remote.coffee @@ -44,6 +44,7 @@ metaToValue = (meta) -> when 'value' then meta.value when 'array' then (metaToValue(el) for el in meta.members) when 'buffer' then new Buffer(meta.value) + when 'promise' then Promise.resolve(then: metaToValue(meta.then)) when 'error' throw new Error("#{meta.message}\n#{meta.stack}") else From c7d1f4f6b2dc028869ba46fbe6c81a01906b3be6 Mon Sep 17 00:00:00 2001 From: Ryohei Ikegami Date: Fri, 31 Jul 2015 14:32:07 +0900 Subject: [PATCH 2/5] Add spec for remote Promise --- spec/api-ipc-spec.coffee | 9 +++++++++ spec/fixtures/module/promise.js | 3 +++ 2 files changed, 12 insertions(+) create mode 100644 spec/fixtures/module/promise.js diff --git a/spec/api-ipc-spec.coffee b/spec/api-ipc-spec.coffee index d7f77b14ce2e..04da0026e6bd 100644 --- a/spec/api-ipc-spec.coffee +++ b/spec/api-ipc-spec.coffee @@ -52,6 +52,15 @@ describe 'ipc module', -> print_name = remote.require path.join(fixtures, 'module', 'print_name.js') assert.equal print_name.print(buf), 'Buffer' + describe 'remote promise in renderer', -> + it 'can be used as promise', (done) -> + promise = remote.require path.join(fixtures, 'module', 'promise.js') + promise.toPromise(1234) + .then (value) => value * 2 + .then (value) => + assert.equal value, 2468 + done() + describe 'ipc.sender.send', -> it 'should work when sending an object containing id property', (done) -> obj = id: 1, name: 'ly' diff --git a/spec/fixtures/module/promise.js b/spec/fixtures/module/promise.js new file mode 100644 index 000000000000..a82acc4b11a5 --- /dev/null +++ b/spec/fixtures/module/promise.js @@ -0,0 +1,3 @@ +exports.toPromise = function (value) { + return Promise.resolve(value); +}; From 92af275f98dfbbd936ab29d1d810705dfc02baf9 Mon Sep 17 00:00:00 2001 From: Ryohei Ikegami Date: Fri, 31 Jul 2015 14:45:22 +0900 Subject: [PATCH 3/5] Support remote Promise in browser --- atom/browser/lib/rpc-server.coffee | 1 + atom/renderer/api/lib/remote.coffee | 2 ++ 2 files changed, 3 insertions(+) diff --git a/atom/browser/lib/rpc-server.coffee b/atom/browser/lib/rpc-server.coffee index d1e3267784e5..8c9671816631 100644 --- a/atom/browser/lib/rpc-server.coffee +++ b/atom/browser/lib/rpc-server.coffee @@ -50,6 +50,7 @@ unwrapArgs = (sender, args) -> when 'remote-object' then objectsRegistry.get meta.id when 'array' then unwrapArgs sender, meta.value when 'buffer' then new Buffer(meta.value) + when 'promise' then Promise.resolve(then: metaToValue(meta.then)) when 'object' ret = v8Util.createObjectWithName meta.name for member in meta.members diff --git a/atom/renderer/api/lib/remote.coffee b/atom/renderer/api/lib/remote.coffee index 5ad7c80ca01f..7370440c6c2d 100644 --- a/atom/renderer/api/lib/remote.coffee +++ b/atom/renderer/api/lib/remote.coffee @@ -20,6 +20,8 @@ wrapArgs = (args, visited=[]) -> type: 'array', value: wrapArgs(value, visited) else if Buffer.isBuffer value type: 'buffer', value: Array::slice.call(value, 0) + else if Promise.resolve(value) == value + type: 'promise', then: valueToMeta(value.then.bind(value)) else if value? and typeof value is 'object' and v8Util.getHiddenValue value, 'atomId' type: 'remote-object', id: v8Util.getHiddenValue value, 'atomId' else if value? and typeof value is 'object' From 428ad20807f867f1c8e14237111f6edca542df83 Mon Sep 17 00:00:00 2001 From: Ryohei Ikegami Date: Fri, 31 Jul 2015 14:45:53 +0900 Subject: [PATCH 4/5] Change spec to test Promise in both side --- spec/api-ipc-spec.coffee | 7 +++---- spec/fixtures/module/promise.js | 8 +++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/spec/api-ipc-spec.coffee b/spec/api-ipc-spec.coffee index 04da0026e6bd..7c6148b559b0 100644 --- a/spec/api-ipc-spec.coffee +++ b/spec/api-ipc-spec.coffee @@ -52,11 +52,10 @@ describe 'ipc module', -> print_name = remote.require path.join(fixtures, 'module', 'print_name.js') assert.equal print_name.print(buf), 'Buffer' - describe 'remote promise in renderer', -> - it 'can be used as promise', (done) -> + describe 'remote promise', -> + it 'can be used as promise in each side', (done) -> promise = remote.require path.join(fixtures, 'module', 'promise.js') - promise.toPromise(1234) - .then (value) => value * 2 + promise.twicePromise(Promise.resolve(1234)) .then (value) => assert.equal value, 2468 done() diff --git a/spec/fixtures/module/promise.js b/spec/fixtures/module/promise.js index a82acc4b11a5..2e52ed374400 100644 --- a/spec/fixtures/module/promise.js +++ b/spec/fixtures/module/promise.js @@ -1,3 +1,5 @@ -exports.toPromise = function (value) { - return Promise.resolve(value); -}; +exports.twicePromise = function (promise) { + return promise.then(function (value) { + return value * 2; + }); +} From c8a794ac3474a034fd32ab74071222a87948be32 Mon Sep 17 00:00:00 2001 From: Ryohei Ikegami Date: Sat, 1 Aug 2015 12:20:16 +0900 Subject: [PATCH 5/5] Use constructor name to check if Promise --- atom/browser/lib/rpc-server.coffee | 2 +- atom/renderer/api/lib/remote.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/atom/browser/lib/rpc-server.coffee b/atom/browser/lib/rpc-server.coffee index 8c9671816631..3eba472570a7 100644 --- a/atom/browser/lib/rpc-server.coffee +++ b/atom/browser/lib/rpc-server.coffee @@ -10,7 +10,7 @@ valueToMeta = (sender, value) -> meta.type = 'buffer' if Buffer.isBuffer value meta.type = 'value' if value is null meta.type = 'array' if Array.isArray value - meta.type = 'promise' if Promise.resolve(value) == value + meta.type = 'promise' if value? and value.constructor.name is 'Promise' # Treat the arguments object as array. meta.type = 'array' if meta.type is 'object' and value.callee? and value.length? diff --git a/atom/renderer/api/lib/remote.coffee b/atom/renderer/api/lib/remote.coffee index 7370440c6c2d..29a24b1789ef 100644 --- a/atom/renderer/api/lib/remote.coffee +++ b/atom/renderer/api/lib/remote.coffee @@ -20,7 +20,7 @@ wrapArgs = (args, visited=[]) -> type: 'array', value: wrapArgs(value, visited) else if Buffer.isBuffer value type: 'buffer', value: Array::slice.call(value, 0) - else if Promise.resolve(value) == value + else if value? and value.constructor.name is 'Promise' type: 'promise', then: valueToMeta(value.then.bind(value)) else if value? and typeof value is 'object' and v8Util.getHiddenValue value, 'atomId' type: 'remote-object', id: v8Util.getHiddenValue value, 'atomId'