Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remote-dom ui_extensions changes customer accounts #2510

Open
wants to merge 15 commits into
base: unstable
Choose a base branch
from
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -48,10 +48,15 @@
"@shopify/loom-plugin-prettier": "^2.0.0",
"@shopify/typescript-configs": "^5.1.0",
"eslint": "^8.28.0",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"nodemon": "^2.0.4",
"prettier": "^2.8.0",
"react": ">=18.0.0",
"typescript": "^4.9.0"
},
"packageManager": "[email protected]+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
"packageManager": "[email protected]+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e",
"resolutions": {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because of loom, we need to address this

"jest": "^29.7.0"
}
}
6 changes: 5 additions & 1 deletion packages/ui-extensions-react/package.json
Original file line number Diff line number Diff line change
@@ -63,7 +63,10 @@
"dependencies": {
"@remote-ui/async-subscription": "^2.1.12",
"@remote-ui/react": "^5.0.2",
"@types/react": ">=18.2.67"
"@types/react": ">=18.2.67",
"@remote-dom/core": "^1.6.0",
"@remote-dom/react": "^1.2.1",
"react-dom": "^18.3.1"
},
"peerDependencies": {
"@shopify/ui-extensions": "0.0.0-unstable",
@@ -82,6 +85,7 @@
"@quilted/react-testing": "^0.5.31",
"@shopify/ui-extensions": "0.0.0-unstable",
"react": "^18.0.0",
"@types/react-dom": "^18.3.0",
"react-reconciler": "0.29.0",
"react-test-renderer": "^18.2.0"
},
2 changes: 2 additions & 0 deletions packages/ui-extensions-react/src/surfaces/checkout/render.tsx
Original file line number Diff line number Diff line change
@@ -47,6 +47,8 @@ export function reactExtension<Target extends RenderExtensionTarget>(
<ExtensionApiContext.Provider value={api}>
<ErrorBoundary>{element}</ErrorBoundary>
</ExtensionApiContext.Provider>,
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignoring for now since we need checkout's changes here so the types are in line

// @ts-ignore
root,
() => {
resolve();
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import '@remote-dom/react/polyfill';
import type {ReactElement, PropsWithChildren} from 'react';
import {Component} from 'react';
import {render as remoteRender} from '@remote-ui/react';
import {extension} from '@shopify/ui-extensions/customer-account';
import type {
ExtensionTargets,
@@ -10,6 +10,8 @@ import type {

import {ExtensionApiContext} from './context';

import {createRoot} from 'react-dom/client';

/**
* Registers your React-based UI Extension to run for the selected extension target.
* Additionally, this function will automatically provide the extension API as React
@@ -26,6 +28,7 @@ import {ExtensionApiContext} from './context';
* which allows you to perform initial asynchronous work like fetching data from your
* own backend.
*/

export function reactExtension<Target extends RenderExtensionTarget>(
target: Target,
render: (
@@ -40,18 +43,16 @@ export function reactExtension<Target extends RenderExtensionTarget>(
target as any,
async (root, api) => {
const element = await render(api as ApiForRenderExtension<Target>);

await new Promise<void>((resolve, reject) => {
await new Promise((resolve, reject) => {
try {
remoteRender(
createRoot(root).render(
<ExtensionApiContext.Provider value={api}>
<ErrorBoundary>{element}</ErrorBoundary>
</ExtensionApiContext.Provider>,
root,
() => {
resolve();
},
);
setTimeout(() => {
resolve(null);
}, 0);
} catch (error) {
// Workaround for https://github.com/Shopify/ui-extensions/issues/325
// eslint-disable-next-line no-console
3 changes: 2 additions & 1 deletion packages/ui-extensions/package.json
Original file line number Diff line number Diff line change
@@ -64,7 +64,8 @@
"sideEffects": false,
"dependencies": {
"@remote-ui/async-subscription": "^2.1.12",
"@remote-ui/core": "^2.2.4"
"@remote-ui/core": "^2.2.4",
"@remote-dom/core": "^1.6.0"
},
"devDependencies": {
"@shopify/generate-docs": "0.16.4",
20 changes: 5 additions & 15 deletions packages/ui-extensions/src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import type {
RemoteRoot,
RemoteChannel,
RemoteComponentType,
} from '@remote-ui/core';
import {RemoteConnection, RemoteRootElement} from '@remote-dom/core/elements';
import type {RemoteChannel, RemoteComponentType} from '@remote-ui/core';

export interface RenderExtensionConnection<
AllowedComponents extends RemoteComponentType<
@@ -11,7 +8,7 @@ export interface RenderExtensionConnection<
any
> = RemoteComponentType<any, any, any>,
> {
readonly channel: RemoteChannel;
readonly channel: RemoteChannel | RemoteConnection;
readonly components: AllowedComponents;
}

@@ -29,15 +26,8 @@ export interface RenderExtension<
): void | Promise<void>;
}

export interface RenderExtensionWithRemoteRoot<
Api,
AllowedComponents extends RemoteComponentType<
string,
any,
any
> = RemoteComponentType<any, any, any>,
> {
(root: RemoteRoot<AllowedComponents, AllowedComponents>, api: Api):
export interface RenderExtensionWithRemoteRoot<Api> {
(root: RemoteRootElement, api: Api):
| void
| Promise<void>
| Promise<() => void>;
34 changes: 17 additions & 17 deletions packages/ui-extensions/src/utilities/registration.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import {createRemoteRoot} from '@remote-ui/core';

import type {
RenderExtensionConnection,
RenderExtension,
RenderExtensionWithRemoteRoot,
} from '../extension';

import {
RemoteConnection,
BatchingRemoteConnection,
RemoteRootElement,
} from '@remote-dom/core/elements';

export interface ExtensionRegistrationFunction<ExtensionTargets> {
<Target extends keyof ExtensionTargets>(
target: Target,
@@ -16,11 +20,8 @@ export interface ExtensionRegistrationFunction<ExtensionTargets> {
export interface ExtensionRegistrationFunctionWithRoot<ExtensionTargets> {
<Target extends keyof ExtensionTargets>(
target: Target,
implementation: ExtensionTargets[Target] extends RenderExtension<
infer Api,
infer Components
>
? RenderExtensionWithRemoteRoot<Api, Components>
implementation: ExtensionTargets[Target] extends RenderExtension<infer Api>
? RenderExtensionWithRemoteRoot<Api>
: ExtensionTargets[Target],
): ExtensionTargets[Target];
}
@@ -46,15 +47,14 @@ export function createExtensionRegistrationFunction<
return (implementation as any)(...args);
}

const [{channel, components}, api] = args as [
RenderExtensionConnection,
any,
];
const [{channel}, api] = args as [RenderExtensionConnection, any];

const root = createRemoteRoot(channel, {
components,
strict: true,
});
const batchingConnection = new BatchingRemoteConnection(
channel as RemoteConnection,
);

const root = document.createElement('remote-root') as RemoteRootElement;
document.body.append(root);

let renderResult = (implementation as any)(root, api);

@@ -66,7 +66,8 @@ export function createExtensionRegistrationFunction<
renderResult = await renderResult;
}

root.mount();
root.connect(batchingConnection);
batchingConnection.flush();

return renderResult;
}
@@ -75,6 +76,5 @@ export function createExtensionRegistrationFunction<

return extension as any;
};

return extensionWrapper;
}
1,680 changes: 1,048 additions & 632 deletions yarn.lock

Large diffs are not rendered by default.