Comments (24)
So there’s 2 things that stand out to me:
- In the iframe you are exposing the
Comunication
class(!), not an instance. Then in theLoginCmpstComponent
you are creating a new instance in thelogin()
method, which never gets used? Not quite sure what your intention was here. - Because you exposed the
Comunication
class, theapi
constant in the parent would be that class. You could use it likeconst instanceOfComunication = await new api();
, yet you are using it kinda like an instance (although I am not sure why you are accessingprototype
.)
Hope this helps.
from comlink.
Hi Surma,
thanks for your reply.
My idea is when the iframe do login it increment the counter com.inc();
.
The main application (is an angular2 app) check what is the value of the counter calling get counter()
.
If I understood well what you suggesting is to do that in the main app:
public async main() {
const ifr = document.querySelector('iframe');
const api = Comlink.proxy(Comlink.windowEndpoint(ifr.contentWindow));
const instanceOfComunication = await new api();
alert(instanceOfComunication.counter());
}
But also in that way typescript is not happy because it complain: Cannot use 'new' with an expression whose type lacks a call or construct signature.
I think that we cant use await with new.
from comlink.
Oh my bad. I didn’t see you were using Comlink.expose({Comunication})
and not Comlink.expose(Comunication)
.
So you’d have to use const instanceOfComunication = await new api.Comunication();
from comlink.
but this is the point! api doesn't have a Comunication
so the main project will complain saying:
property 'Comunication' does not exist on type 'Function'.
from comlink.
api
is a proxy. It should never throw that error. Something must be missing.
Here’s a glitch for you to look at: https://glitch.com/edit/#!/comlink-issue-7?path=index.html
from comlink.
oh no no sorry my bad. is just the typescript runtime compiler that is complaining because Comunication
do not exists and I don't know how to tell him to ignore the compilation of that line
from comlink.
const instanceOfComunication = await new (api as any).Comunication();
😉
from comlink.
Last question. Is it correct in the iframe doing that:
constructor() {
Comlink.expose({Comunication}, Comlink.windowEndpoint(self.parent));
}
public login(value: any): void {
this.displayErrorMessage = false;
this.userService
.authenticate(new Login(value.username, value.password))
.subscribe((response: any) => {
const com: Comunication = new Comunication(); <---
com.inc(); <----
}, err => this.displayErrorMessage = true);
}
Because looks like that it's still complaining
from comlink.
I am not sure. I don’t think so. You are exposing the class. The login
you are creating a new instance of that class. And you are creating yet another instance in the parent using Comlink. I think you might want a Singleton here.
from comlink.
I tried but still no luck:
LIBRARY:
import {Comlink} from 'comlinkjs';
export class Comunication {
private static instance: Comunication;
private _counter;
constructor() {
this._counter = 0;
}
public static getInstance() {
if (!Comunication.instance) {
Comunication.instance = new Comunication();
// ... any one time initialization goes here ...
}
return Comunication.instance;
}
public get counter() {
return this._counter;
}
public inc() {
this._counter++;
}
}
Comlink.expose({Comunication}, Comlink.windowEndpoint(self.parent));
IFRAME COMPONENT:
const add = Comunication.getInstance();
add.inc();
PARENT:
public async main() {
const ifr = document.querySelector('iframe');
await new Promise(resolve => ifr.onload = resolve);
const api = Comlink.proxy(Comlink.windowEndpoint(ifr.contentWindow));
const instanceOfComunication = await (api as any).Comunication.getInstance();
console.log(await instanceOfComunication.counter);
await instanceOfComunication.inc();
console.log(await instanceOfComunication.counter);
}
No able to find the method .inc()
from comlink.
You need to use return Comlink.proxyValue(Comunication.instance)
. Only values created with new
are implicitly proxied.
I should write an example for this!
from comlink.
Also heads up: I am about to remote windowEndpoint
in the next release.
from comlink.
Sorry I don't understanf . Instead to do:
const api = Comlink.proxy(Comlink.windowEndpoint(ifr.contentWindow));
I should do what?
from comlink.
Take a look at the examples. I updated them.
from comlink.
You mean just to change:
const api = Comlink.proxy(Comlink.windowEndpoint(ifr.contentWindow));
in that:
const api = Comlink.proxy(ifr.contentWindow);
??
Before you said that:
You need to use
return Comlink.proxyValue(Comunication.instance).
Only values created with new are implicitly proxied.
from comlink.
Those are two completely separate things. You need to use proxyValue
in your getInstance()
method and – once you update to Comlink 2.0 – need to remove windowEndpoint
.
from comlink.
omg I don't have any clue what I've to change. Do you prefer that I create a simple repro on my github? I'm using angularcli
from comlink.
You only need to change the two things in mentioned in my last post:
- use
proxyValue
in yourgetInstance()
method - don’t use
windowEndpoint
from comlink.
Here you go: https://glitch.com/edit/#!/comlink-issue-7
from comlink.
So with 1.2 it doesn't work:
Code:
Library:
import {Comlink} from 'comlinkjs';
export class Comunication {
private static instance: Comunication;
private _counter;
constructor() {
this._counter = 0;
}
public static getInstance() {
if (!Comunication.instance) {
Comunication.instance = new Comunication();
}
return Comlink.proxyValue(Comunication.instance);
}
public get counter() {
return this._counter;
}
public inc() {
this._counter++;
}
}
Comlink.expose({Comunication}, Comlink.windowEndpoint(self.parent));
Iframe:
const add: any = Comunication.getInstance();
add.inc();
Main:
const ifr = document.querySelector('iframe');
await new Promise(resolve => ifr.onload = resolve);
const api = Comlink.proxy(Comlink.windowEndpoint(ifr.contentWindow));
const instanceOfComunication = await (api as any).Comunication.getInstance();
console.log(await instanceOfComunication.counter);
await instanceOfComunication.inc();
console.log(await instanceOfComunication.counter);
}
Uncaught (in promise): TypeError: Promise resolver null is not a function
TypeError: Promise resolver null is not a function
Maybe when you release 2.0 I can apply your change and it will work?
from comlink.
2.0 is already released. And as I said, you need to remove windowEndpoint
once you switch to 2.0, not before.
from comlink.
Did you take a look at my glitch? I wrote it so you can study it and compare with your code.
from comlink.
Yep I applied all the changes apart
const api = Comlink.proxy(Comlink.windowEndpoint(ifr.contentWindow));
vs
const api = Comlink.proxy(ifr.contentWindow);
Comlink.expose({Comunication}, Comlink.windowEndpoint(self.parent));
vs
Comlink.expose({Comunication}, self.parent);
because my npm still doesn't find 2.0.0
from comlink.
ok updated to 2.0.0
now we have a cors problem:
the iframe is on localhost:4200
and the parent on localhost:4201
both are running with the --cors flag
SecurityError: Blocked a frame with origin "http://localhost:4201" from accessing a cross-origin frame.
Error: Blocked a frame with origin "http://localhost:4201" from accessing a cross-origin frame.
at isWindow (comlink.es6.js:116)
at Object.expose (comlink.es6.js:41)
at Object.../../../../../src/app/common/comlink/Comunication.ts (Comunication.ts:27)
This is the place in your code where is breaking:
function isWindow(endpoint) {
return endpoint.constructor.name === 'Window';
}
from comlink.
Related Issues (20)
- Web Worker Hangs if Imported File Contains Top-Level `Await` HOT 6
- Service worker example: stops working when SW is suspended HOT 9
- Set operation is not awaitable HOT 2
- Possible to communicate between web workers? HOT 1
- How to transfer result buffers HOT 2
- [feat] DeasyncEndpoint HOT 2
- Move from Karma to Playwright? HOT 1
- Do I need to use transfer inside a proxy? HOT 1
- Add support for async transferHandle serializer/deserializer HOT 2
- Significant performance optimizations possible in `requestResponseMessage` HOT 4
- Push notifications from web worker HOT 5
- Memory leak when terminating worker with ongoing call HOT 2
- Worker Pool for similar tasks HOT 2
- Sharing constructed objects within a remote context HOT 1
- How to implement comlink in Next.js 14 App Route HOT 2
- Feature request: Automatic proxy of arguments HOT 3
- Having issues when using comlink with react (storing in react state) HOT 3
- Exposed function deadlocks if called too early
- Returning a collection - transferHandlers to be called
- How to prevent auto `releaseProxy`?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from comlink.