Skip to content

Commit

Permalink
Update threads library
Browse files Browse the repository at this point in the history
  • Loading branch information
lemonmade committed Aug 19, 2024
1 parent 6967f01 commit 1885a67
Show file tree
Hide file tree
Showing 14 changed files with 57 additions and 69 deletions.
15 changes: 7 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,18 +205,17 @@ First, we’ll create the remote environment’s version of `ui-button`. The rem
// which is a small library that was designed to work well with Remote DOM.
import {RemoteMutationObserver} from '@remote-dom/core/elements';
import {createThreadFromInsideIframe, retain} from '@quilted/threads';
import {ThreadNestedWindow} from '@quilted/threads';
const root = document.querySelector('#root');
createThreadFromInsideIframe({
expose: {
new ThreadNestedWindow({
exports: {
// This `render()` method will kick off the process of synchronizing
// changes between environments. It will be called on the host with a
// `RemoteConnection` object, which you’ll generally get from one of
// Remote DOM’s `Receiver` classes.
render(connection) {
retain(connection);
async render(connection) {
const observer = new RemoteMutationObserver(connection);
observer.observe(root);
},
Expand Down Expand Up @@ -290,7 +289,7 @@ Finally, we need to provide a “real” implementation of our `ui-button` eleme
<script type="module">
import {DOMRemoteReceiver} from '@remote-dom/core/receivers';
import {createThreadFromIframe, retain, release} from '@quilted/threads';
import {ThreadIframe} from '@quilted/threads';
const root = document.querySelector('#root');
const iframe = document.querySelector('#remote-iframe');
Expand All @@ -308,8 +307,8 @@ Finally, we need to provide a “real” implementation of our `ui-button` eleme
// Like our previous example, we need to use a library that can serialize
// function properties over `postMessage`.
const thread = createThreadFromIframe(iframe);
thread.render(receiver.connection);
const thread = new ThreadIframe(iframe);
thread.imports.render(receiver.connection);
</script>
</body>
</html>
Expand Down
4 changes: 3 additions & 1 deletion documentation/migrations/remote-ui-to-remote-dom.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ import {RemoteReceiver} from '@remote-dom/core';
import {retain, release} from '@quilted/threads';

// You now need to pass in functions to manage the memory for functions manually,
// where this was previously done automatically in `@remote-ui/rpc`.
// where this was previously done automatically in `@remote-ui/rpc`. If you are
// using the automatic memory management provided by `@quilted/threads`, you can
// omit the `retain` and `release` functions.
const receiver = new RemoteReceiver({retain, release});
sendToRemoteEnvironment(receiver.connection);
```
Expand Down
6 changes: 3 additions & 3 deletions examples/custom-element/app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@

<script type="module">
import {DOMRemoteReceiver} from '@remote-dom/core/receivers';
import {retain, release, createThreadFromIframe} from '@quilted/threads';
import {ThreadIframe} from '@quilted/threads';

const root = document.querySelector('#root');
const iframe = document.querySelector('#remote-iframe');
Expand All @@ -108,13 +108,13 @@
// which lets us communicate over `postMessage` without having to worry about
// most of its complexities. This includes the ability to send functions between
// environments, which we rely on for the `click` event listener.
const thread = createThreadFromIframe(iframe);
const thread = new ThreadIframe(iframe);

// We will call the `render` method on the thread, which will send the iframe
// the `receiver.connection` object. This object, called a `RemoteConnection`,
// allows the remote environment to synchronize its tree of UI elements into
// the `root` element we connected our `receiver` to above.
thread.render(receiver.connection);
thread.imports.render(receiver.connection);
</script>
</body>
</html>
13 changes: 4 additions & 9 deletions examples/custom-element/app/remote.html
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@

<script type="module">
import {RemoteMutationObserver} from '@remote-dom/core/elements';
import {retain, createThreadFromInsideIframe} from '@quilted/threads';
import {ThreadNestedIframe} from '@quilted/threads';

const root = document.querySelector('#root');

Expand All @@ -68,14 +68,9 @@
// This block exposes the `render` method that was used by the host application,
// in `index.html`. We receive the `RemoteConnection` object, and start synchronizing
// changes to the `<div id="root">` element that contains our UI.
createThreadFromInsideIframe({
expose: {
render(connection) {
// `connection` contains functions that were transferred over `postMessage`.
// In order to call these functions later, we need to mark them as used in
// order to prevent garbage collection.
retain(connection);

new ThreadNestedIframe({
exports: {
async render(connection) {
// We use the `RemoteMutationObserver` class, which extends the native DOM
// `MutationObserver`, to send any changes to a tree of DOM elements over
// a `RemoteConnection`.
Expand Down
2 changes: 1 addition & 1 deletion examples/custom-element/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"start": "vite"
},
"dependencies": {
"@quilted/threads": "^2.2.0",
"@quilted/threads": "^3.0.0",
"@remote-dom/core": "workspace:*"
}
}
13 changes: 5 additions & 8 deletions examples/kitchen-sink/app/host.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@ import {
RemoteFragmentRenderer,
createRemoteComponentRenderer,
} from '@remote-dom/preact/host';
import {
createThreadFromIframe,
createThreadFromWebWorker,
} from '@quilted/threads';
import {ThreadIframe, ThreadWebWorker} from '@quilted/threads';

import type {SandboxAPI} from './types.ts';
import {Button, Modal, Stack, Text, ControlPanel} from './host/components.tsx';
Expand All @@ -20,7 +17,7 @@ const uiRoot = document.querySelector('main')!;
// which lets us communicate over `postMessage` without having to worry about
// most of its complexities.
const iframe = document.querySelector('iframe')!;
const iframeSandbox = createThreadFromIframe<never, SandboxAPI>(iframe);
const iframeSandbox = new ThreadIframe<SandboxAPI>(iframe);

// We also use the `@quilted/threads` library to create a “thread” around a Web
// Worker. We’ll run the same example code in both, depending on the `sandbox`
Expand All @@ -31,7 +28,7 @@ const worker = new Worker(
type: 'module',
},
);
const workerSandbox = createThreadFromWebWorker<never, SandboxAPI>(worker);
const workerSandbox = new ThreadWebWorker<SandboxAPI>(worker);

// We will use Preact to render remote elements in this example. The Preact
// helper library lets you do this by mapping the name of a remote element to
Expand Down Expand Up @@ -63,7 +60,7 @@ const components = new Map([
const {receiver, example, sandbox} = createState(
async ({receiver, example, sandbox}) => {
if (sandbox === 'iframe') {
await iframeSandbox.render(receiver.connection, {
await iframeSandbox.imports.render(receiver.connection, {
sandbox,
example,
async alert(content) {
Expand All @@ -74,7 +71,7 @@ const {receiver, example, sandbox} = createState(
},
});
} else {
await workerSandbox.render(receiver.connection, {
await workerSandbox.imports.render(receiver.connection, {
sandbox,
example,
async alert(content) {
Expand Down
3 changes: 1 addition & 2 deletions examples/kitchen-sink/app/host/state.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {signal, effect} from '@preact/signals';
import {SignalRemoteReceiver} from '@remote-dom/preact/host';
import {retain, release} from '@quilted/threads';

import type {RenderExample, RenderSandbox} from '../types.ts';

Expand Down Expand Up @@ -75,7 +74,7 @@ export function createState(
window.history.replaceState({}, '', newURL.toString());

if (cached == null) {
const receiver = new SignalRemoteReceiver({retain, release});
const receiver = new SignalRemoteReceiver();
cached = Promise.resolve(
render({
receiver,
Expand Down
3 changes: 3 additions & 0 deletions examples/kitchen-sink/app/remote/examples/vanilla.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ export function renderUsingVanillaDOM(root: Element, api: RenderAPI) {
typeof Modal
>;

// const button = template.querySelector('#close-button')!;
// button.slot = 'primaryAction';

modal.addEventListener('close', handleClose);

modal.querySelector('ui-text')!.append(countText);
Expand Down
17 changes: 4 additions & 13 deletions examples/kitchen-sink/app/remote/iframe/sandbox.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {RemoteMutationObserver} from '@remote-dom/core/elements';
import {retain, createThreadFromInsideIframe} from '@quilted/threads';
import {ThreadNestedIframe} from '@quilted/threads';

import '../elements.ts';
import {render} from '../render.ts';
Expand All @@ -12,18 +12,9 @@ import type {SandboxAPI} from '../../types.ts';
// This block exposes the `render` method that was used by the host application,
// in `index.html`. We receive the `RemoteConnection` object, and start synchronizing
// changes to the `<div id="root">` element that contains our UI.
createThreadFromInsideIframe<SandboxAPI>({
expose: {
new ThreadNestedIframe<never, SandboxAPI>({
exports: {
async render(connection, api) {
// `connection` contains functions that were transferred over `postMessage`.
// In order to call these functions later, we need to mark them as used in
// order to prevent garbage collection.
retain(connection);

// Similarly, `api.alert` is a function we will call later, so we also need
// to mark it as used.
retain(api.alert);

// We will observe this DOM node, and send any elements within it to be
// reflected on this "host" page.
const root = document.createElement('div');
Expand All @@ -39,7 +30,7 @@ createThreadFromInsideIframe<SandboxAPI>({
const observer = new RemoteMutationObserver(connection);
observer.observe(root);

render(root, api);
await render(root, api);
},
},
});
17 changes: 4 additions & 13 deletions examples/kitchen-sink/app/remote/worker/sandbox.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import '@remote-dom/core/polyfill';
import {retain, createThreadFromWebWorker} from '@quilted/threads';
import {ThreadWebWorker} from '@quilted/threads';

import '../elements.ts';
import {render} from '../render.ts';
Expand All @@ -12,26 +12,17 @@ import type {SandboxAPI} from '../../types.ts';
// This block exposes the `render` method that was used by the host application,
// in `index.html`. We receive the `RemoteConnection` object, and start synchronizing
// changes to a `<remote-root>` element that contains our UI.
createThreadFromWebWorker<SandboxAPI>(self as any as Worker, {
expose: {
new ThreadWebWorker<never, SandboxAPI>(self as any as Worker, {
exports: {
async render(connection, api) {
// `connection` contains functions that were transferred over `postMessage`.
// In order to call these functions later, we need to mark them as used in
// order to prevent garbage collection.
retain(connection);

// Similarly, `api.alert` is a function we will call later, so we also need
// to mark it as used.
retain(api.alert);

// We will observe this DOM node, and send any elements within it to be
// reflected on this "host" page. This element is defined by the Remote DOM
// library, and provides a convenient `connect()` method that starts
// synchronizing its children over a `RemoteConnection`.
const root = document.createElement('remote-root');
root.connect(connection);

render(root, api);
await render(root, api);
},
},
});
2 changes: 1 addition & 1 deletion examples/kitchen-sink/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"dependencies": {
"@preact/preset-vite": "^2.9.0",
"@preact/signals": "^1.3.0",
"@quilted/threads": "^2.2.0",
"@quilted/threads": "^3.0.0",
"@remote-dom/core": "workspace:*",
"@remote-dom/preact": "workspace:*",
"@remote-dom/react": "workspace:*",
Expand Down
6 changes: 4 additions & 2 deletions packages/core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,8 @@ To support functions being passed over `postMessage`, you may need a way to manu
```ts
// This library is not included with Remote DOM, but it pairs
// well with it in allowing you to pass functions between
// JavaScript environments.
// JavaScript environments without leaking memory, by manually
// managing the memory for those functions.
import {retain, release} from '@quilted/threads';
import {RemoteReceiver} from '@remote-dom/core/receivers';

Expand Down Expand Up @@ -519,7 +520,8 @@ Like with `RemoteReceiver`, you can pass the `retain` and `release` options to t
```ts
// This library is not included with Remote DOM, but it pairs
// well with it in allowing you to pass functions between
// JavaScript environments.
// JavaScript environments without leaking memory, by manually
// managing the memory for those functions.
import {retain, release} from '@quilted/threads';
import {DOMRemoteReceiver} from '@remote-dom/core/receivers';

Expand Down
3 changes: 2 additions & 1 deletion packages/signals/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ To support functions being passed over `postMessage`, you may need a way to manu
```ts
// This library is not included with Remote DOM, but it pairs
// well with it in allowing you to pass functions between
// JavaScript environments.
// JavaScript environments without leaking memory, by manually
// managing the memory for those functions.
import {retain, release} from '@quilted/threads';
import {SignalRemoteReceiver} from '@remote-dom/signals';

Expand Down
22 changes: 15 additions & 7 deletions pnpm-lock.yaml

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

0 comments on commit 1885a67

Please sign in to comment.