Why does a ChromeWorker throw "Components is not defined"? - javascript

The documentation on ChromeWorkers says that they have "chrome privileges", and chrome privileges are supposed to mean they can do anything, but when I create a ChromeWorker and try to use Components I get an error that 'Components' is not defined..
So my question is
why is Components not available?
what is available to a ChromeWorker?

You cannot access the Components object because the Components object isn't threadsafe. A ChromeWorker gives you access to everything a Worker has access to, and c-types.

Related

How can I instantiate a new SystemError object in Node.js?

Looking at Node's documentation, SystemError extends the Error class. However, if you attempt to use SystemError directly, Node will throw a ReferenceError saying that SystemError is undefined.
Clearly, according to the docs, it is possible to encounter an instance of SystemError, but it seems impossible to recreate such an error in the usual way (e.g. throw new SystemError(args)).
I would like to test some code which is designed to interact with the specified SystemError API as detailed in the docs, but I have no idea how to recreate a SystemError. Is this even possible?
I think that node.js doesn't put SystemError available in order to avoid anyone (npm packages) to use it. So a SystemError is really a SystemError and not something else.
If you want to test it, generate the error : Try to read a file that doesn't exist for example.
An other soluce would be to recreate a lookalike error because you know every property of it. But it's a workaround actually.
https://nodejs.org/api/errors.html#errors_class_systemerror
In the Github https://github.com/DefinitelyTyped/DefinitelyTyped I couldn't find any interface declaration of SystemError.
Except custom implementations made by node-fetch, voximplant-websdk and alexa-sdk.
https://github.com/DefinitelyTyped/DefinitelyTyped/search?q=systemError&unscoped_q=systemError

How do I access the redux store in Safari?

Context
I'm trying to debug a React application but cannot modify the source code to log redux variables. In chrome I'm able to access the redux store via the associated extension but it seems no such equivalent exists for safari.
Question
How can I access the redux store in Safari? Can I do so using the console?
The simplest solution, unfortunately, is to modify the source code to set a global variable to the Redux store. (It may be worth preemptively modifying any applications you can control to do this, just to make Safari easier to debug.)
Without modifying the source code, it should be possible, although it's awkward. The following instructions work for React 16.12.0.
In Safari's Web Inspector (dev tools), go to the Elements tab and find your React root element (the <div id="root"> or similar that you pass to ReactDOM.render).
Click on it. Web Inspector should show a = $0 next to it, indicating that you can now reference that DOM node in the Web Inspector console as $0.
In the Web Inspector's Console tab, type Object.keys($0) and press Enter to see the internal properties that React adds to the DOM node. For my app, I see ["__reactContainere$8yexuoe6iiv", "_reactRootContainer"].
Dump the internal React object to the console by typing $0["__reactContainere$8yexuoe6iiv"] (substituting your internal property name) and pressing Enter.
Inspect the object properties to find the Redux store: on my app, it's under child, under memoizedProps, under store, but this may depend on the specifics of your React component hierarchy and where and how you mount Redux's <Provider>.
Use the store reference you just found to call Redux's getState. For my app, that means typing $0["__reactContainere$8yexuoe6iiv"].child.memoizedProps.store.getState() and pressing Enter.
A simpler one-line alternative to the above:
document.getElementById('root')['_reactRootContainer']._internalRoot.current.child.memoizedProps.store.getState()
In case you are using Nextjs framework, you can achieve this by opening the console in safari. Type window in it. Expand it. Now just check in the window object property. You will find a key something like '__REDUX' or something like that. In my case it was __NEXT_REDUX_STORE__.
Now after you find it just enter the following in your console.:
__NEXT_REDUX_STORE__.getState();
you can now check your current redux state of your application.
I'm not aware of a safari extension for redux debugging (corrections welcome). This thread suggests that it's due to a lack of a dev-tools API: https://github.com/zalmoxisus/redux-devtools-extension/issues/435
Redux state isn't in the global scope, so you won't be able to access it through the console without modifying the source code.
You could just extract state using the connect function. Then just stringify it?
<pre>JSON.stringify({this.props.store, null, 2})</pre>
Then you could visually see it.
Adding to #josh-kelley's answer...
In 2021, tested with Safari Version 12.1 (14607.1.40.1.4), following line did the trick for me:
document.getElementById('root')['_reactRootContainer']
._internalRoot.current.child.memoizedProps
.children.props.store.getState()
Notice the children.props difference from what #josh had mentioned.
According to its GitHub repository for other browsers use remote-redux-devtools.

Use ESM in a service worker file (import/export)

I am trying to use a service worker file which is also an ESM module.
The register method has an extra argument accepting an options object which has a type field whose valid values seem to be classic and module, but when I use:
navigator.serviceWorker.register('worker.js', { type: 'module' });
// `worker.mjs` doesn't work either
// The file exists in both cases!
I get an unspecified DOMException with no message in Chrome.
I figured what the valid values for type were by reading the spec, specifically this:
https://html.spec.whatwg.org/multipage/workers.html#workertype
It seems to me like my code is valid.
As a sanity check, I also tried to explicity set type to classic and the service worker registration then goes through fine. If I set it to an invalid value, I get a TypeError telling me so, so it's not like the browser is not yet aware of type: module. It is treated as a special case, it just throws a DOMException with no message.
Am I using the type field correctly? Is it still too early and it is not supported in browsers?
This is dumb! Chrome will print just DOMException into the console (not even expansible) when logging the error object and Object.keys on that object instance returns [], but when I specifically print e.message the culprit is revealed:
type 'module' in RegistrationOptions is not implemented yet.See https://crbug.com/824647 for details.
Not amused by Chrome.
On browsers, bare names can't be used to identify modules unless you also have a module map (aka import map, this link has much more info) that maps the bare name to a module.
If worker.js is in the same location as the page loading it, then:
navigator.serviceWorker.register('./worker.js', { type: 'module' });
// -------------------------------^^
Or of course, add a module map.

Get access to Angular service instance from JavaScript code

What I'm trying to do is have some testing assertions based on the data in the Angular service, i.e. we're trying to create E2E tests and the tool we're using allows us to execute arbitrary JavaScript code for assertions, so for that I need to know if it's possible to get access to the Angular service instance.
How can I get access to an Angular service instance from plain JS code?
That is, if my Angular app is deployed, and I open the app in the browser, then open Chrome DevTools, can I get access to the service instance of the my Angular service that was provided to all components?
I know it's possible to get access to your component by through ng.probe($0) etc. but not sure about services.
From what I have searched so far, it seems like we have to do use the Injector class and then use it's .get() method to get access to one of the Angular service instances but I'm not sure how would I get access to the Injector class/instance itself?
Here's what I tried: ng.probe($0) ($0 being the <app-root> of my app) and then I see that the return value has an .injector property, I tried to call ng.probe($0).injector.get('MyServiceName') and got an error for: Uncaught Error: No provider for MyServiceName!.
(Even though I'm trying ng.probe above, I would love to know how to get access to the injector without ng.probe because during execution of the automated testing i.e. prod mode, I don't think I'll be able to do ng.probe($0))
So I'm not sure if I'm trying to access it the right way? Any ideas?
I'm using Angular 4.
This works for me in Angular 7 using ng.probe():
window.ng.probe(window.getAllAngularRootElements()[0])
.injector.view.root.ngModule._providers
.find(p => p && p.constructor && p.constructor.name === 'MyServiceName');
And I guess it is not possible to do it another way without ng.probe()

Aurelia failed binding not throwing error?

I was wondering if aurelia should throw error on failed binding ? I use durandal a lot, and a useful feature was "binder.throwOnErrors = true;" If a binding failed it would throw an error in the console.
But in aurelia, say i got a "version" var in my VM. If i bind
${non-existing-var}
or even
${non-existing-object.non-existing-property}
it won't say anything.
So far aurelia is good, but sometimes it's a real pain to dig the template and to figure why the binding ain't working.
I've tried to dig in the aurelia-binding class, but could not find any clue.
Thank you :)
I also use the default configuration (i see [Debug] logs in the console)
aurelia.use
.standardConfiguration()
.developmentLogging();
Aurelia does not throw when an attempt is made to bind to an null/undefined property (or chain of properties). This is intentional- Aurelia supports binding to things that aren't yet defined but will become defined later.
Other developers have requested an option log these occurrences be added. This request is tracked here.

Categories