Skip to content

Commit

Permalink
Fix #9 - Rename /global or global to window and export isWindowProxy …
Browse files Browse the repository at this point in the history
…helper instead of isGlobal
  • Loading branch information
WebReflection committed Jun 21, 2023
1 parent e13b3aa commit b493366
Show file tree
Hide file tree
Showing 23 changed files with 135 additions and 118 deletions.
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,34 +89,34 @@ This entry point exports the exact same module except it uses [@ungap/structured
Please keep in mind not all complex types are supported by the polyfill.


### coincident/global
### coincident/window

This entry point exports the same `coincident` module (using *JSON* as default) **but** the *Worker* utility returns an obejct with 3 fields:

* **proxy** it's the usual proxy utility to expose or invoke functions defined in the main counter-part
* **global** it's the proxy that orchestrates access to the *main* world, including the ability to pass callbacks from the *Worker*, with the only caveat these will be inevitably executed asynchronously on the main thread, so that *Promise* or *thenable* work out of the box but *accessors* or defined callbacks will need to be awaited from the worker too. DOM listeners should be also handled with no issues but the `event` can't *preventDefault* or *stopPropagation* as the listener will be asynchronous too. All global/well known *Symbol* also cross boundaries so that `[...global.document.querySelectorAll('*')]` or any other *Symbol* based functionality should be preserved, as long as the `symbol` is known as runtime symbols can't cross paths in any meaningful way.
* **isGlobal** is an utility that helps introspection of global proxies, callbacks, classes, or references
* **window** it's the proxy that orchestrates access to the *main* world, including the ability to pass callbacks from the *Worker*, with the only caveat these will be inevitably executed asynchronously on the main thread, so that *Promise* or *thenable* work out of the box but *accessors* or defined callbacks will need to be awaited from the worker too. DOM listeners should be also handled with no issues but the `event` can't *preventDefault* or *stopPropagation* as the listener will be asynchronous too. All well known *Symbol* also cross boundaries so that `[...window.document.querySelectorAll('*')]` or any other *Symbol* based functionality should be preserved, as long as the `symbol` is known as runtime symbols can't cross paths in any meaningful way.
* **isWindowProxy** is an utility that helps introspection of window proxies, callbacks, classes, or main thread references in general

While the initial utility/behavior is preserved on both sides, the *Worker* can seamlessly use *global* / *main* thread to operate on DOM, *localStorage*, or literally anything else, included *Promise* based operations, DOM listeners, and so on.
While the initial utility/behavior is preserved on both sides, the *Worker* can seamlessly use *window* / *main* thread to operate on DOM, *localStorage*, or literally anything else, included *Promise* based operations, DOM listeners, and so on.


```html
<!-- main page -->
<script type="module">
import coincident from 'coincident/global';
import coincident from 'coincident/window';
const proxy = coincident(new Worker('./worker.js', {type: 'module'}));
</script>
```

```js
// The worker.js !!!
import coincident from 'coincident/global';
import coincident from 'coincident/window';

const {proxy, global, isGlobal} = coincident(self);
const {proxy, window, isWindowProxy} = coincident(self);
// the proxy can expose or answer to main proxy counter part

// ... but here is the fun part ...
const {document} = global;
const {document} = window;
document.body.innerHTML = '<h1>Hello World!</h1>';

document.body.appendChild(
Expand All @@ -129,4 +129,4 @@ document.body.addEventListener('click', event => {
});
```

See the [test/global.js](./test/global.js) file or reach `http://localhost:8080/test/global.html` locally to play around this feature.
See the [test/window.js](./test/window.js) file or reach `http://localhost:8080/test/window.html` locally to play around this feature.
4 changes: 2 additions & 2 deletions es.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion esm/channel.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export default '417f77a3-3f54-4e3f-95fa-50ee1cb1635d';
export default '659055af-b151-4f8b-9b33-ff1e8e4038a6';
6 changes: 3 additions & 3 deletions esm/uhtml.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import $coincident from './global.js';
import $coincident from './window.js';
import init from 'uhtml/init';

/**
* Create once a `Proxy` able to orchestrate synchronous `postMessage` out of the box.
* In workers, returns a `{proxy, global, isGlobal}` namespace to reach globals synchronously.
* In workers, returns a `{proxy, window, isWindowProxy}` namespace to reach main globals synchronously.
* @param {Worker | globalThis} self the context in which code should run
*/
const coincident = (self, ...args) => {
const utility = $coincident(self, ...args);
if (!(self instanceof Worker))
utility.uhtml = init(utility.global);
utility.uhtml = init(utility.window);
return utility;
}

Expand Down
10 changes: 5 additions & 5 deletions esm/global.js → esm/window.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import CHANNEL from './channel.js';
import $coincident from './index.js';
import main from './global/main.js';
import thread from './global/thread.js';
import main from './window/main.js';
import thread from './window/thread.js';

const MAIN = CHANNEL + 'M';
const THREAD = CHANNEL + 'T';
Expand All @@ -11,13 +11,13 @@ const proxies = new WeakMap;
/**
* @typedef {object} Coincident
* @property {ProxyHandler<globalThis>} proxy
* @property {ProxyHandler<Window>} global
* @property {(value: any) => boolean} isGlobal
* @property {ProxyHandler<Window>} window
* @property {(value: any) => boolean} isWindowProxy
*/

/**
* Create once a `Proxy` able to orchestrate synchronous `postMessage` out of the box.
* In workers, returns a `{proxy, global, isGlobal}` namespace to reach globals synchronously.
* In workers, returns a `{proxy, window, isWindowProxy}` namespace to reach main globals synchronously.
* @param {Worker | globalThis} self the context in which code should run
* @returns {ProxyHandler<Worker> | Coincident}
*/
Expand Down
File renamed without changes.
15 changes: 13 additions & 2 deletions esm/global/thread.js → esm/window/thread.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,19 @@ export default (main, MAIN, THREAD) => {

return {
proxy: main,
global: new Proxy([OBJECT, null], proxyHandler),
isGlobal: value => typeof value === OBJECT && !!value && __proxied__ in value
window: new Proxy([OBJECT, null], proxyHandler),
isWindowProxy: value => typeof value === OBJECT && !!value && __proxied__ in value,
// TODO: remove this stuff ASAP
get global() {
console.warn('Deprecated: please access `window` field instead');
return this.window;
},
get isGlobal() {
return function (value) {
console.warn('Deprecated: please access `isWindowProxy` field instead');
return this.isWindowProxy(value);
}.bind(this);
}
};
};

Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,12 @@
"default": "./cjs/index.js"
},
"./global": {
"import": "./esm/global.js",
"default": "./cjs/global.js"
"import": "./esm/window.js",
"default": "./cjs/window.js"
},
"./window": {
"import": "./esm/window.js",
"default": "./cjs/window.js"
},
"./structured": {
"import": "./esm/structured.js",
Expand Down
4 changes: 2 additions & 2 deletions rollup/global.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import {nodeResolve} from '@rollup/plugin-node-resolve';
import terser from '@rollup/plugin-terser';

export default {
input: './esm/global.js',
input: './esm/window.js',
plugins: [
nodeResolve(),
terser()
],
output: {
esModule: true,
file: './global.js',
file: './window.js',
}
};
4 changes: 2 additions & 2 deletions structured.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit b493366

Please sign in to comment.