@remote-ui/react
Advanced tools
Comparing version 2.0.9 to 3.0.0-alpha.0
export { RemoteReceiver } from '@remote-ui/core'; | ||
export { RemoteRenderer } from './Renderer'; | ||
export { RemoteRenderer } from './RemoteRenderer'; | ||
export type { ReactPropsFromRemoteComponentType, ReactComponentTypeFromRemoteComponentType, } from '../types'; | ||
@@ -4,0 +4,0 @@ export { RemoteReceiverContext, ControllerContext } from './context'; |
@@ -5,4 +5,4 @@ "use strict"; | ||
Object.defineProperty(exports, "RemoteReceiver", { enumerable: true, get: function () { return core_1.RemoteReceiver; } }); | ||
var Renderer_1 = require("./Renderer"); | ||
Object.defineProperty(exports, "RemoteRenderer", { enumerable: true, get: function () { return Renderer_1.RemoteRenderer; } }); | ||
var RemoteRenderer_1 = require("./RemoteRenderer"); | ||
Object.defineProperty(exports, "RemoteRenderer", { enumerable: true, get: function () { return RemoteRenderer_1.RemoteRenderer; } }); | ||
var context_1 = require("./context"); | ||
@@ -9,0 +9,0 @@ Object.defineProperty(exports, "RemoteReceiverContext", { enumerable: true, get: function () { return context_1.RemoteReceiverContext; } }); |
import React from 'react'; | ||
import type { Serialized, RemoteReceiver, RemoteComponent as RemoteComponentDescription } from '@remote-ui/core'; | ||
import { Controller } from './controller'; | ||
import type { Controller } from './controller'; | ||
interface Props { | ||
@@ -5,0 +5,0 @@ receiver: RemoteReceiver; |
import React from 'react'; | ||
import type { RemoteReceiver } from '@remote-ui/core'; | ||
import type { ComponentMapping } from './controller'; | ||
import { RemoteReceiver } from '@remote-ui/core'; | ||
import { ComponentMapping } from './controller'; | ||
interface Props { | ||
@@ -5,0 +5,0 @@ receiver: RemoteReceiver; |
@@ -31,6 +31,3 @@ "use strict"; | ||
const { children } = hooks_1.useAttached(receiver, receiver.root); | ||
return react_1.createElement(react_1.Fragment, {}, ...children.map((child) => { | ||
var _a; | ||
return 'type' in child ? (react_1.default.createElement(RemoteComponent_1.RemoteComponent, { key: child.id, component: child, receiver: receiver, controller: controller, __type__: (_a = controller.get(child.type)) === null || _a === void 0 ? void 0 : _a.__type__ })) : (react_1.default.createElement(RemoteText_1.RemoteText, { key: child.id, text: child, receiver: receiver })); | ||
})); | ||
return react_1.createElement(react_1.Fragment, {}, ...children.map((child) => 'type' in child ? (react_1.default.createElement(RemoteComponent_1.RemoteComponent, { key: child.id, component: child, receiver: receiver, controller: controller })) : (react_1.default.createElement(RemoteText_1.RemoteText, { key: child.id, text: child, receiver: receiver })))); | ||
}); |
@@ -41,3 +41,3 @@ "use strict"; | ||
for (const key in oldProps) { | ||
if (!Reflect.has(oldProps, key) || key === 'children') { | ||
if (!has(oldProps, key) || key === 'children') { | ||
continue; | ||
@@ -66,3 +66,3 @@ } | ||
for (const key in newProps) { | ||
if (!Reflect.has(newProps, key) || key === 'children') { | ||
if (!has(newProps, key) || key === 'children') { | ||
continue; | ||
@@ -88,3 +88,3 @@ } | ||
remoteRoot.removeChild(child); | ||
}, | ||
}, | ||
// Update children | ||
@@ -102,3 +102,3 @@ appendInitialChild(parent, child) { | ||
parent.removeChild(child); | ||
}, | ||
}, | ||
// Deferred callbacks | ||
@@ -128,2 +128,6 @@ scheduleDeferredCallback() { }, | ||
commitMount() { } })); | ||
const { hasOwnProperty } = {}; | ||
function has(object, property) { | ||
return hasOwnProperty.call(object, property); | ||
} | ||
exports.default = reconciler; |
{ | ||
"name": "@remote-ui/react", | ||
"version": "2.0.9", | ||
"version": "3.0.0-alpha.0", | ||
"publishConfig": { | ||
@@ -34,9 +34,9 @@ "access": "public", | ||
"dependencies": { | ||
"@remote-ui/core": "^1.5.4", | ||
"@remote-ui/rpc": "^1.0.11", | ||
"@remote-ui/web-workers": "^1.2.7", | ||
"@remote-ui/core": "^1.6.0-alpha.0", | ||
"@remote-ui/rpc": "^1.1.0-alpha.0", | ||
"@remote-ui/web-workers": "^1.3.0-alpha.0", | ||
"@types/react": ">=16.8.0 <17.0.0", | ||
"react-reconciler": "^0.25.0" | ||
}, | ||
"gitHead": "74cd705c6d0644a915ae96a7c98f5b24856abf96" | ||
"gitHead": "95b058fdbc84958f3e10bb4dfd8029a6f0189078" | ||
} |
@@ -25,3 +25,3 @@ # `@remote-ui/react` | ||
The main entrypoint for this package, `@remote-ui/react`, provides the custom React renderer that outputs instructions to a [`@remote-ui/core` `RemoteRoot`](../core#remoteroot) object. This lets you use the remote-ui system for communicating patch updates to host components over a bridge, but have React help manage your stateful application logic. To run a React ap against a `RemoteRoot`, use the `render` function exported by this library, passing in the remote root and your root React component: | ||
The main entrypoint for this package, `@remote-ui/react`, provides the custom React renderer that outputs instructions to a [`@remote-ui/core` `RemoteRoot`](../core#remoteroot) object. This lets you use the remote-ui system for communicating patch updates to host components over a bridge, but have React help manage your stateful application logic. To run a React app against a `RemoteRoot`, use the `render` function exported by this library, passing in the remote root and your root React component: | ||
@@ -32,6 +32,6 @@ ```tsx | ||
// For convenience, this library re-exports several values from @remote-ui/core, like RemoteRoot | ||
// For convenience, this library re-exports several values from @remote-ui/core, like createRemoteRoot | ||
import {render, createRemoteRoot} from '@remote-ui/react'; | ||
// a host component — see implementation below for getting strong | ||
// a remote component — see implementation below for getting strong | ||
// typing on the available props. | ||
@@ -74,6 +74,6 @@ const Button = 'Button'; | ||
```tsx | ||
import {createRemoteComponent as coreCreateRemoteComponent} from '@remote-ui/core'; | ||
import {createRemoteComponent} from '@remote-ui/core'; | ||
import {createRemoteReactComponent} from '@remote-ui/react'; | ||
const Button = coreCreateRemoteComponent<'Button', {onPress(): void}>('Button'); | ||
const Button = createRemoteComponent<'Button', {onPress(): void}>('Button'); | ||
const ReactButton = createRemoteReactComponent(Button); | ||
@@ -87,7 +87,82 @@ | ||
TODO: explain exports of `@remote-ui/react/host`. | ||
This package provides a second entrypoint, `@remote-ui/react/host`, with a collection of utilities for implementing the host side of a remote-ui environment in a React application. These utilities work for any React renderer, but will most commonly be used in applications that use `react-dom` or `react-native`. These host utilities take care of receiving the patch updates from a remote context, and maps the resulting component tree to a set of React components you provide. | ||
To show these utilities in action, we’ll use the same `Button` example we have looked at for the remote APIs. The host environment for those examples needs to be able to render the real `Button` component with the props received from the remote environment. To do so, we first create our host-side `Button` component (we’ll assume we are in a DOM environment, so this component will render an HTML button): | ||
```tsx | ||
import React from 'react'; | ||
export function Button({onPress, children}) { | ||
return ( | ||
<button type="button" onClick={() => onPress()}> | ||
{children} | ||
</button> | ||
); | ||
} | ||
``` | ||
The React component we will use to render our remote component tree needs to know how to map from a component name to component implementation. To do this, pass your host components to `createController()`, a function provided by this library: | ||
```tsx | ||
import React, {useMemo} from 'react'; | ||
import {createController} from '@remote-ui/react/host'; | ||
import {Button} from './Button'; | ||
function MyRemoteRenderer() { | ||
const controller = useMemo(() => createController({Button}), []); | ||
// ... | ||
} | ||
``` | ||
In addition to the `controller`, we need to create a [`RemoteReceiver` object](../core#remotereceiver). This object is responsible for accepting updates from the remote context, and turning them back into a tree of UI components on the host: | ||
```tsx | ||
import React, {useMemo, useEffect} from 'react'; | ||
import {createController, RemoteReceiver} from '@remote-ui/react/host'; | ||
import {Button} from './Button'; | ||
function MyRemoteRenderer() { | ||
const controller = useMemo(() => createController({Button}), []); | ||
const receiver = useMemo(() => new RemoteReceiver(), []); | ||
useEffect(() => { | ||
// You’ll usually send the receiver.receive function to the remote | ||
// context, and use it to construct a `@remote-ui/core` `RemoteRoot` | ||
// object | ||
sendReceiverToRemoteContext(receiver.receive); | ||
}, [receiver]); | ||
// ... | ||
} | ||
``` | ||
Finally, you can pass these two objects to the `RemoteRenderer` component provided by this entrypoint, which will start listening for changes to the `receiver`, and render the host React component equivalent of the remote component tree. | ||
```tsx | ||
import React, {useMemo, useEffect} from 'react'; | ||
import { | ||
createController, | ||
RemoteReceiver, | ||
RemoteRenderer, | ||
} from '@remote-ui/react/host'; | ||
import {Button} from './Button'; | ||
function MyRemoteRenderer() { | ||
const controller = useMemo(() => createController({Button}), []); | ||
const receiver = useMemo(() => new RemoteReceiver(), []); | ||
useEffect(() => { | ||
sendReceiverToRemoteContext(receiver.receive); | ||
}, [receiver]); | ||
return <RemoteRenderer receiver={receiver} controller={controller} />; | ||
} | ||
``` | ||
### Other exports | ||
This package exports a helper type for extracting information from components created by `createRemoteComponent`: | ||
This package exports a helper type for extracting information from components created by `createRemoteReactComponent`: | ||
@@ -98,8 +173,10 @@ - `ReactPropsFromRemoteComponentType` accepts any type as a type argument and, if it is a remote component, returns its prop types when used as a React component. | ||
import { | ||
createRemoteComponent, | ||
createRemoteReactComponent, | ||
ReactPropsFromRemoteComponentType, | ||
} from '@remote-ui/react'; | ||
const Button = createRemoteComponent<'Button', {onPress?(): void}>('Button'); | ||
const Button = createRemoteReactComponent<'Button', {onPress?(): void}>( | ||
'Button', | ||
); | ||
type ButtonProps = ReactPropsFromRemoteComponentType<typeof Button>; // {onPress?(): void; children: ReactNode} | ||
``` |
export {RemoteReceiver} from '@remote-ui/core'; | ||
export {RemoteRenderer} from './Renderer'; | ||
export {RemoteRenderer} from './RemoteRenderer'; | ||
export type { | ||
@@ -5,0 +5,0 @@ ReactPropsFromRemoteComponentType, |
@@ -72,3 +72,3 @@ import reactReconciler from 'react-reconciler'; | ||
for (const key in oldProps) { | ||
if (!Reflect.has(oldProps, key) || key === 'children') { | ||
if (!has(oldProps, key) || key === 'children') { | ||
continue; | ||
@@ -98,3 +98,3 @@ } | ||
for (const key in newProps) { | ||
if (!Reflect.has(newProps, key) || key === 'children') { | ||
if (!has(newProps, key) || key === 'children') { | ||
continue; | ||
@@ -128,12 +128,12 @@ } | ||
appendInitialChild(parent, child) { | ||
(parent as any).appendChild(child); | ||
parent.appendChild(child); | ||
}, | ||
appendChild(parent, child) { | ||
(parent as any).appendChild(child); | ||
parent.appendChild(child); | ||
}, | ||
insertBefore(parent, newChild, beforeChild) { | ||
(parent as any).insertChildBefore(newChild, beforeChild); | ||
parent.insertChildBefore(newChild, beforeChild); | ||
}, | ||
removeChild(parent, child) { | ||
(parent as any).removeChild(child); | ||
parent.removeChild(child); | ||
}, | ||
@@ -172,2 +172,7 @@ | ||
const {hasOwnProperty} = {}; | ||
function has(object: object, property: string | number | symbol) { | ||
return hasOwnProperty.call(object, property); | ||
} | ||
export default reconciler; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
481240
135
2995
178
2