diff --git a/.github/workflows/bundlesize.yml b/.github/workflows/bundlesize.yml index 6c298295c6..2b77a02d5a 100644 --- a/.github/workflows/bundlesize.yml +++ b/.github/workflows/bundlesize.yml @@ -33,7 +33,7 @@ jobs: - name: Install dependencies run: npm install - name: Bundlesize ${{ matrix.project }} - uses: ipfs/aegir/actions/bundle-size@v28.0.0 + uses: ipfs/aegir/actions/bundle-size@v29.0.0 with: project: ${{ matrix.project }} github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/packages/ipfs-message-port-client/README.md b/packages/ipfs-message-port-client/README.md index 781c524364..fff3d1eb05 100644 --- a/packages/ipfs-message-port-client/README.md +++ b/packages/ipfs-message-port-client/README.md @@ -102,7 +102,7 @@ values instead of copying. > **Note:** Transferring data will empty it on the sender side which can lead to > errors if that data is used again later. To avoid these errors transfer option -> was added so user can explicitily give up reference when it is safe to do so. +> was added so user can explicitly give up reference when it is safe to do so. ```js /** @@ -115,7 +115,7 @@ const example = async (data) => { } ``` -It is however recommended to prefer web native [Blob][] / [File][] intances as +It is however recommended to prefer web native [Blob][] / [File][] instances as most web APIs provide them as option & can be send across without copying underlying memory. diff --git a/packages/ipfs-message-port-client/src/client/transport.js b/packages/ipfs-message-port-client/src/client/transport.js index 83b53aa66d..7d60055693 100644 --- a/packages/ipfs-message-port-client/src/client/transport.js +++ b/packages/ipfs-message-port-client/src/client/transport.js @@ -178,7 +178,7 @@ module.exports = class MessageTransport { input: query.toJSON() }, // @ts-ignore - TS seems to want second arg to postMessage to not be undefined - query.transfer() + [...new Set(query.transfer() || [])] ) } diff --git a/packages/ipfs-message-port-protocol/src/core.js b/packages/ipfs-message-port-protocol/src/core.js index b32559baff..92ffd88aff 100644 --- a/packages/ipfs-message-port-protocol/src/core.js +++ b/packages/ipfs-message-port-protocol/src/core.js @@ -197,7 +197,7 @@ const decodeCallback = ({ port }) => { * @returns {void} */ const callback = (args, transfer = []) => { - port.postMessage(args, transfer) + port.postMessage(args, [...new Set(transfer)]) } return callback diff --git a/packages/ipfs-message-port-server/package.json b/packages/ipfs-message-port-server/package.json index 1bde0cf287..b0b867bd7c 100644 --- a/packages/ipfs-message-port-server/package.json +++ b/packages/ipfs-message-port-server/package.json @@ -50,6 +50,8 @@ "devDependencies": { "@types/it-all": "^1.0.0", "aegir": "^28.2.0", + "cids": "^1.0.0", + "ipfs-utils": "^5.0.0", "rimraf": "^3.0.2", "typescript": "4.0.x" }, diff --git a/packages/ipfs-message-port-server/src/server.js b/packages/ipfs-message-port-server/src/server.js index 87f0ccc619..854f1ddd5d 100644 --- a/packages/ipfs-message-port-server/src/server.js +++ b/packages/ipfs-message-port-server/src/server.js @@ -212,9 +212,12 @@ exports.Server = class Server { if (!query.signal.aborted) { try { const value = await query.result + const transfer = [...new Set(value.transfer || [])] + delete value.transfer + port.postMessage( { type: 'result', id, result: { ok: true, value } }, - value.transfer || [] + transfer ) } catch (error) { port.postMessage({ diff --git a/packages/ipfs-message-port-server/test/transfer.spec.js b/packages/ipfs-message-port-server/test/transfer.spec.js new file mode 100644 index 0000000000..4b1903c1ef --- /dev/null +++ b/packages/ipfs-message-port-server/test/transfer.spec.js @@ -0,0 +1,46 @@ +'use strict' + +/* eslint-env mocha */ +const { encodeCID } = require('ipfs-message-port-protocol/src/cid') +const globalThis = require('ipfs-utils/src/globalthis') + +const CID = require('cids') +const { Server } = require('../src/server') +const { IPFSService } = require('../src/index') + +describe('Server', function () { + this.timeout(10 * 1000) + + it('should be able to transfer multiple of the same CID instances', () => { + const cid = new CID('QmSnuWmxptJZdLJpKRarxBMS2Ju2oANVrgbr2xWbie9b2D') + + return new Promise((resolve, reject) => { + const channel = process.browser + ? new globalThis.MessageChannel() + : new (require('worker_threads').MessageChannel)() + + channel.port1.onmessageerror = reject + channel.port1.onmessage = event => { + const result = event.data.result + result.ok ? resolve(result.value) : reject(new Error(result.error.message)) + } + + const service = new IPFSService() + const server = new Server(service) + const transfer = [] + + server.run = a => a + server.handleQuery( + '', + { + result: { + value: [encodeCID(cid, transfer), encodeCID(cid, transfer)], + transfer: transfer + }, + signal: { aborted: false } + }, + channel.port2 + ) + }) + }) +})