Skip to content

Commit

Permalink
fix: reconnect even though onDisconnect is not triggered (#27)
Browse files Browse the repository at this point in the history
* fix: dark mode

* fix: reconnect even though onDisconnect is not triggered
  • Loading branch information
tmkx authored Feb 2, 2024
1 parent 74cd4b6 commit 6a16ada
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 23 deletions.
8 changes: 6 additions & 2 deletions apps/ai-assistant/src/content-scripts/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,11 @@ export const App = () => {
<div
ref={containerRef}
tabIndex={visible ? undefined : -1}
className={clsx('absolute transition-opacity', visible ? 'opacity-100' : 'opacity-0 pointer-events-none')}
className={clsx(
'absolute transition-opacity',
isDarkMode && 'dark',
visible ? 'opacity-100' : 'opacity-0 pointer-events-none'
)}
style={rootStyle}
>
<DialogTrigger isOpen={visible && !!selectedText && !!content} onOpenChange={setVisible}>
Expand Down Expand Up @@ -164,7 +168,7 @@ export const App = () => {
</div>
<Popover className="w-96 p-4">
<div>{selectedText}</div>
<div className="h-[1px] my-3 bg-slate-200" />
<div className="h-[1px] my-3 bg-slate-200/20" />
<div>{content}</div>
</Popover>
</DialogTrigger>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { PortalContainerContext } from '@/components/shared';
import { isPageInDark } from '@webx-kit/runtime/content-scripts/env';
import { useContext } from 'react';
import { createPortal } from 'react-dom';

Expand All @@ -9,7 +10,10 @@ export const Provider = (props: React.PropsWithChildren<unknown>) => {
<>
{props.children}
{window.__webxRoot
? createPortal(<div ref={portalContainerContextRef} />, window.__webxRoot as unknown as HTMLElement)
? createPortal(
<div ref={portalContainerContextRef} className={isPageInDark() ? 'dark' : undefined} />,
window.__webxRoot as unknown as HTMLElement
)
: null}
</>
);
Expand Down
1 change: 1 addition & 0 deletions apps/ai-assistant/tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import plugin from 'tailwindcss/plugin';

const config: Config = {
content: ['./src/**/*.{ts,tsx}'],
darkMode: 'class',
theme: {
extend: {},
},
Expand Down
59 changes: 39 additions & 20 deletions packages/messaging/src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,6 @@ export function createMessaging(port: Port, options?: CreateMessagingOptions): M
let active = false;
const offListeners: VoidFunction[] = [];

// chrome.runtime.Port will [auto disconnect](https://developer.chrome.com/docs/extensions/develop/concepts/messaging?hl=en#port-lifetime)
// so that we need to ensure that there is an active connection
function ensureActive() {
if (active) return;
active = true;
Expand All @@ -183,36 +181,57 @@ export function createMessaging(port: Port, options?: CreateMessagingOptions): M
}
ensureActive();

function reconnectIfDisconnected<T extends () => any>(fn: T, errorHandler: (error: unknown) => ReturnType<T>) {
try {
// chrome.runtime.Port will [auto disconnect](https://developer.chrome.com/docs/extensions/develop/concepts/messaging?hl=en#port-lifetime)
// so that we need to ensure that there is an active connection
ensureActive();
return fn();
} catch (err) {
try {
// When the background is inactive while the page is paused (e.g. during debugging)
// onDisconnect will not be triggered
if (err instanceof Error && err.message.includes('disconnected')) {
dispose();
ensureActive();
return fn();
}
throw err;
} catch (finalErr) {
return errorHandler(finalErr);
}
}
}

const messaging: Messaging = {
name: port.name,
request<T>(data: unknown) {
const resolvers = withResolvers<T>();
const id = randomID();
ongoingRequestResolvers.set(id, resolvers);
try {
ensureActive();
reconnectIfDisconnected(() => {
port.postMessage({ t: 'r', i: id, d: data } satisfies Packet);
} catch (err) {
resolvers.reject(err);
}
}, resolvers.reject);
return resolvers.promise;
},
stream(data, observer) {
const id = randomID();
ongoingStreamObservers.set(id, observer);
try {
ensureActive();
port.postMessage({ t: 's', i: id, d: data } satisfies Packet);
return () => {
if (!ongoingStreamObservers.has(id)) return;
port.postMessage({ t: 's', i: id, d: null } satisfies Packet);
};
} catch (err) {
queueMicrotask(() => {
observer.error?.(err);
});
return noop;
}
return reconnectIfDisconnected(
() => {
port.postMessage({ t: 's', i: id, d: data } satisfies Packet);
return () => {
if (!ongoingStreamObservers.has(id)) return;
port.postMessage({ t: 's', i: id, d: null } satisfies Packet);
};
},
(err) => {
queueMicrotask(() => {
observer.error?.(err);
});
return noop;
}
);
},
dispose,
};
Expand Down

0 comments on commit 6a16ada

Please sign in to comment.