comlink
comlink copied to clipboard
Add wrapChain function
This PR adds support for the method chaining:
await nock('http://localhost')
.intercept('/notes', 'GET')
.reply(200, [
{ id: 1, title: 'hello' },
]);
await (new Thing()
.prop
.method()
.value = 2
);
I've added this functionality in a separate wrapChain() function, because while almost fully back-compatible with the wrap() function, it has a breaking change:
Messages are passed between contexts only after you await/call then().
For example this works with wrap():
const thing = Comlink.wrap(this.port1);
Comlink.expose((f) => f(), port2);
it("works with wrap", function(done) {
thing(done);
});
But with the new implementation, thing(done) isn't enough to actually call a function.
An example of changed wrap() test:
it("will wrap marked parameter values, simple function", async function() {
const thing = Comlink.wrapChain(this.port1);
Comlink.expose(async function(f) {
- await f();
+ return await f();
}, this.port2);
- await new Promise(async resolve => {
- thing(Comlink.proxy(_ => resolve()));
- });
+ expect(await thing(Comlink.proxy(_ => 1))).to.equal(1);
});
If this breaking change is acceptable (with a major version bump), I can update this PR and merge those two wrap functions.
This is great!
@surma - Got time to take a look?
Here's the version with the breaking change to wrap() instead of introducing the wrapChain():
https://github.com/GoogleChromeLabs/comlink/compare/master...CvX:wrap-chain-breaking
Woohoo! 🎉
Any thoughts on this PR? It would help us with https://github.com/embermap/ember-cli-fastboot-testing/pull/61
Hey, apologies for being so quiet. I’m currently a bit swamped, but I’ll put this on the top of my priority list for when I have a bit of downtime. Please be patient! Thank you :)
Okay, I finally had some time to look at this.
I definitely see the value of supporting chain-style APIs, especially with their increasing popularity. However, it’s a significant code increase (1K, ~300B gzip’d) that and I don’t think I want every Comlink user to pay.
I could, however, see providing your wrapChain() (or something similar) in a separate module, similar to node-adapter.ts.
What do you think?
Would the breaking change version (https://github.com/GoogleChromeLabs/comlink/compare/master...CvX:wrap-chain-breaking) be out of the question?
It does preserve compatibility with the usual cases (await new Proxy() await proxy.method() proxied().then(…))
What it breaks, are only cases without then. I don’t have the data, but I guess that would affect relatively small portion of conlink users? It would require a major version bump and a clear path of upgrade though.
But if that isn’t a viable option, a separate module would do.
As I said, my concerns are mostly about file size, not necessarily breaking changes. A separate module is definitely my preferred way forward.
Hm, the byte size difference between the gzipped umd/comlink.min.js on the wrap-chain-breaking branch and the master is currently 88 bytes (and with a minimal amount of code golf I was able to reduce that to 77).
I'd say a downside of a separate module is an increased API surface. You'd have to decide which comlink "flavor" to use in each case.
E.g. when you begin with a simple call await thing(), and you want to expand it later to await thing().otherThing(). You'd have to import the chain module and change the wrap() call. It adds friction (in theory, not sure how comlink-heavy real world projects are 😅)
Hi @surma - Any updates on this one?
Apologies. I’ll get back to this soon. Chrome Dev Summit is happening and, uh, it’s stressful 😅 Please don’t give up on me and keep pinging if you think I forgot.
Hi @surma - I hope you're recovered from the Dev Summit! Just pinging you again, per your request 😃
Hey @surma - Checking in again. Any updates on this one?