Skip to content

Commit c409934

Browse files
committed
Extract adapter into a separate package
1 parent 56eab19 commit c409934

File tree

16 files changed

+103
-118
lines changed

16 files changed

+103
-118
lines changed

.changeset/beige-windows-appear.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
---
2-
'@remote-dom/core': minor
3-
'@remote-dom/polyfill': minor
4-
'@remote-dom/preact': minor
5-
'@remote-dom/react': minor
6-
'@remote-dom/signals': minor
2+
'@remote-dom/compat': major
73
---
84

95
Add a `adaptToLegacyRemoteChannel` helper that adapts a Remote DOM `RemoteConnection` object into a `remote-ui` `RemoteChannel`.

examples/kitchen-sink/app/host.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {ThreadIframe, ThreadWebWorker} from '@quilted/threads';
99
import type {SandboxAPI} from './types.ts';
1010
import {Button, Modal, Stack, Text, ControlPanel} from './host/components.tsx';
1111
import {createState} from './host/state.ts';
12-
import {adaptToLegacyRemoteChannel} from '@remote-dom/core/legacy';
12+
import {adaptToLegacyRemoteChannel} from '@remote-dom/compat';
1313

1414
// We will put any remote elements we want to render in this root element.
1515
const uiRoot = document.querySelector('main')!;

examples/kitchen-sink/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"dependencies": {
1010
"@preact/signals": "^1.3.0",
1111
"@quilted/threads": "^3.0.0",
12+
"@remote-dom/compat": "workspace:*",
1213
"@remote-dom/core": "workspace:*",
1314
"@remote-dom/preact": "workspace:*",
1415
"@remote-dom/react": "workspace:*",

examples/kitchen-sink/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
},
88
"include": ["app"],
99
"references": [
10+
{"path": "../../packages/compat"},
1011
{"path": "../../packages/core"},
1112
{"path": "../../packages/preact"},
1213
{"path": "../../packages/react"},

packages/compat/README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# `@remote-dom/compat`
2+
3+
The `@remote-dom/compat` package provides helpers for adapting between Remote DOM and [`remote-ui`, the previous version of this project](https://github.com/Shopify/remote-dom/discussions/267). These utilities are offered to help you transition to Remote DOM, while continuing to support existing code that expects `remote-ui`-style APIs.
4+
5+
## Progressive migration from `remote-ui`’s `RemoteChannel` to Remote DOM’s `RemoteConnection`
6+
7+
The `RemoteChannel` and `RemoteConnection` types from `remote-ui` and Remote DOM serve the same purpose: they describe the minimal interface that a remote environment needs to communicate with a host. In Remote DOM, the `RemoteConnection` type has been enhanced in backwards-incompatible ways, in order to support [method calling](#remote-methods), batched updates, and more.
8+
9+
In `remote-ui`, you typically get a `RemoteChannel` function by accessing the `receiver` property on a `RemoteReceiver`, like this:
10+
11+
```ts
12+
import {createRemoteReceiver} from '@remote-ui/core';
13+
14+
const receiver = createRemoteReceiver();
15+
const channel = receiver.receive;
16+
17+
// Do something with the channel, typically by sending it to a remote environment:
18+
sendChannelToRemoteEnvironment(channel);
19+
```
20+
21+
You can migrate to use a Remote DOM [`RemoteReceiver`](#remotereceiver), [`DOMRemoteReceiver`](#domremotereceiver), or [`SignalRemoteReceiver`](/packages/signals/README.md#signalremotereceiver) class, while still supporting the `RemoteChannel` API, by using the `adaptToLegacyRemoteChannel()` function:
22+
23+
You can adapt a `RemoteConnection` to a `RemoteChannel` using this library’s `adaptToLegacyRemoteChannel()` function. This function takes a `RemoteConnection` and returns a `RemoteChannel`, which allows you to use a Remote DOM receiver class on the host, even if the remote environment is using `remote-ui`. This same technique works regardless of whether you are using the [`RemoteReceiver`](#remotereceiver), [`DOMRemoteReceiver`](#domremotereceiver), or [`SignalRemoteReceiver`](/packages/signals/README.md#signalremotereceiver) class.
24+
25+
```ts
26+
import {DOMRemoteReceiver} from '@remote-dom/core/receivers';
27+
import {adaptToLegacyRemoteChannel} from '@remote-dom/compat';
28+
29+
const receiver = new DOMRemoteReceiver();
30+
const channel = adaptToLegacyRemoteChannel(receiver.connection);
31+
32+
// Same as before: do something with the channel
33+
sendChannelToRemoteEnvironment(channel);
34+
```
35+
36+
If you use `remote-ui`’s React bindings to render your UI on the host, you will also need to update that code to make use of the new Remote DOM versions of those bindings (available for [Preact](/packages/preact/README.md#host) and [React](/packages/react/README.md#host)). With this change made, though, you can now seamlessly support code written with `remote-ui` or Remote DOM, by using the more powerful Remote DOM receiver classes on the host and adapting them for legacy code.

packages/compat/package.json

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"name": "@remote-dom/compat",
3+
"type": "module",
4+
"license": "MIT",
5+
"publishConfig": {
6+
"access": "public",
7+
"@remote-dom/registry": "https://registry.npmjs.org"
8+
},
9+
"version": "1.0.0",
10+
"engines": {
11+
"node": ">=14.0.0"
12+
},
13+
"repository": {
14+
"type": "git",
15+
"url": "https://github.com/Shopify/remote-dom",
16+
"directory": "packages/compat"
17+
},
18+
"exports": {
19+
".": {
20+
"types": "./build/typescript/index.d.ts",
21+
"quilt:source": "./source/index.ts",
22+
"quilt:esnext": "./build/esnext/index.esnext",
23+
"import": "./build/esm/index.mjs",
24+
"require": "./build/cjs/index.cjs"
25+
}
26+
},
27+
"types": "./build/typescript/index.d.ts",
28+
"scripts": {
29+
"build": "rollup --config ./rollup.config.js"
30+
},
31+
"dependencies": {
32+
"@remote-dom/core": "workspace:^1.5.2",
33+
"@remote-ui/core": "^2.0.0"
34+
},
35+
"browserslist": [
36+
"defaults and not dead"
37+
]
38+
}

packages/compat/rollup.config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import {quiltPackage} from '@quilted/rollup/package';
2+
3+
export default quiltPackage({commonjs: true});
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import type {
1919
RemoteElementSerialization,
2020
RemoteConnection,
2121
RemoteNodeSerialization,
22-
} from '../types.ts';
22+
} from '@remote-dom/core';
2323
import {
2424
ROOT_ID,
2525
NODE_TYPE_TEXT,
@@ -28,7 +28,7 @@ import {
2828
MUTATION_TYPE_REMOVE_CHILD,
2929
MUTATION_TYPE_UPDATE_PROPERTY,
3030
MUTATION_TYPE_UPDATE_TEXT,
31-
} from '../constants.ts';
31+
} from '@remote-dom/core';
3232

3333
export interface LegacyRemoteChannelElementMap {
3434
[key: string]: string;
@@ -56,7 +56,7 @@ export interface LegacyRemoteChannelOptions {
5656
* @example
5757
* ```tsx
5858
* import {DOMRemoteReceiver} from '@remote-dom/core/receivers';
59-
* import {adaptToLegacyRemoteChannel} from '@remote-dom/core/legacy';
59+
* import {adaptToLegacyRemoteChannel} from '@remote-dom/compat';
6060
*
6161
* const receiver = new DOMRemoteReceiver();
6262
* const channel = adaptToLegacyRemoteChannel(receiver.connection);

packages/compat/source/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export {adaptToLegacyRemoteChannel} from './adapter/host';

packages/core/source/legacy/tests/host.test.ts renamed to packages/compat/source/tests/adapter.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import '../../polyfill.ts';
1+
import '@remote-dom/core/polyfill';
22

33
import {describe, expect, it, vi, type Mocked} from 'vitest';
44

5-
import {adaptToLegacyRemoteChannel} from '../../legacy/host.ts';
5+
import {adaptToLegacyRemoteChannel} from '../adapter/host.ts';
66

77
import {
88
ACTION_INSERT_CHILD,
@@ -23,9 +23,9 @@ import {
2323
NODE_TYPE_ELEMENT,
2424
NODE_TYPE_TEXT,
2525
ROOT_ID,
26-
} from '../../constants';
26+
} from '@remote-dom/core';
2727

28-
import {RemoteReceiver} from '../../receivers/RemoteReceiver.ts';
28+
import {RemoteReceiver} from '@remote-dom/core/receivers';
2929

3030
describe('adaptToLegacyRemoteChannel()', () => {
3131
describe('ACTION_MOUNT', () => {

0 commit comments

Comments
 (0)