@nextop-os/browser-node 0.0.17 → 0.0.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,6 +7,7 @@ import {
7
7
  ArrowLeftIcon,
8
8
  ArrowRightIcon,
9
9
  Button,
10
+ Input,
10
11
  LaunchIcon,
11
12
  LoadingIcon,
12
13
  RefreshIcon,
@@ -583,7 +584,7 @@ function BrowserNode({
583
584
  profileId,
584
585
  sessionMode
585
586
  });
586
- return /* @__PURE__ */ jsxs("div", { className: "flex h-full min-h-0 flex-col overflow-hidden bg-background", children: [
587
+ return /* @__PURE__ */ jsxs("div", { className: "flex h-full min-h-0 flex-col overflow-hidden bg-[var(--background-panel)]", children: [
587
588
  showHeader ? /* @__PURE__ */ jsx(
588
589
  BrowserNodeHeader,
589
590
  {
@@ -609,12 +610,12 @@ function BrowserNode({
609
610
  }
610
611
  }
611
612
  ) : null,
612
- /* @__PURE__ */ jsxs("div", { className: "relative min-h-0 flex-1 overflow-hidden bg-background", children: [
613
+ /* @__PURE__ */ jsxs("div", { className: "relative min-h-0 flex-1 overflow-hidden bg-[var(--background-panel)]", children: [
613
614
  shouldRenderWebview ? /* @__PURE__ */ jsx(
614
615
  "webview",
615
616
  {
616
617
  ref: setWebviewRef,
617
- className: "absolute inset-0 h-full w-full border-0 bg-background",
618
+ className: "absolute inset-0 h-full w-full border-0 bg-[var(--background-panel)]",
618
619
  "data-browser-node-webview": "true",
619
620
  partition: webviewPartition,
620
621
  src: webviewSrc
@@ -706,7 +707,7 @@ function BrowserNodeHeader({
706
707
  "div",
707
708
  {
708
709
  className: cn(
709
- "flex h-[var(--workbench-header-height,38px)] min-h-[var(--workbench-header-height,38px)] items-center gap-2 bg-[var(--workbench-window-header-bg)] px-2 pl-3",
710
+ "flex h-[var(--workbench-header-height,38px)] min-h-[var(--workbench-header-height,38px)] items-center gap-2 bg-[var(--background-panel)] px-2 pl-3",
710
711
  withBorder ? "border-b border-border" : null,
711
712
  className
712
713
  ),
@@ -760,26 +761,27 @@ function BrowserNodeHeader({
760
761
  /* @__PURE__ */ jsxs(
761
762
  "form",
762
763
  {
763
- className: "nodrag flex h-8 min-h-8 min-w-0 flex-1 items-center gap-1.5 rounded-md border border-border bg-[var(--workbench-field-bg)] px-2 focus-within:ring-2 focus-within:ring-ring/60",
764
+ className: "nodrag relative min-w-0 flex-1",
764
765
  onSubmit: (event) => {
765
766
  event.preventDefault();
766
767
  event.stopPropagation();
767
768
  onSubmitUrl();
768
769
  },
769
770
  children: [
770
- /* @__PURE__ */ jsx(LaunchIcon, { className: "size-4 shrink-0 text-muted-foreground" }),
771
+ /* @__PURE__ */ jsx(LaunchIcon, { className: "pointer-events-none absolute left-2 top-1/2 z-[1] size-4 -translate-y-1/2 text-[var(--text-tertiary)]" }),
771
772
  /* @__PURE__ */ jsx(
772
- "input",
773
+ Input,
773
774
  {
774
775
  "aria-label": feature.i18n.t("addressLabel"),
775
- className: "h-full min-w-0 flex-1 border-0 bg-transparent text-[13px] leading-none text-foreground outline-none placeholder:text-muted-foreground",
776
+ className: "pl-8 pr-8 focus-visible:ring-0 focus-visible:ring-offset-0",
776
777
  placeholder: feature.i18n.t("addressPlaceholder"),
778
+ size: "sm",
777
779
  value: draftUrl,
778
780
  onChange: (event) => onDraftUrlChange(event.target.value),
779
781
  onFocus: onFocusRequest
780
782
  }
781
783
  ),
782
- isLoading ? /* @__PURE__ */ jsx(LoadingIcon, { className: "size-4 shrink-0 animate-spin text-muted-foreground" }) : null
784
+ isLoading ? /* @__PURE__ */ jsx(LoadingIcon, { className: "pointer-events-none absolute right-2 top-1/2 z-[1] size-4 -translate-y-1/2 animate-spin text-[var(--text-tertiary)]" }) : null
783
785
  ]
784
786
  }
785
787
  ),
@@ -849,4 +851,4 @@ export {
849
851
  BrowserNodeWorkbenchHeader,
850
852
  BrowserNodeHeader
851
853
  };
852
- //# sourceMappingURL=chunk-XCKUTY7D.js.map
854
+ //# sourceMappingURL=chunk-3ERRS74C.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/react/BrowserNode.tsx","../src/react/useBrowserNodeController.ts","../src/core/nodeController.ts","../src/react/useBrowserNodeWebview.ts","../src/core/webviewController.ts"],"sourcesContent":["import {\n ArrowLeftIcon,\n ArrowRightIcon,\n Button,\n Input,\n LaunchIcon,\n LoadingIcon,\n RefreshIcon,\n cn\n} from \"@nextop-os/ui-system\";\nimport type { HTMLAttributes, JSX, ReactNode } from \"react\";\nimport type { BrowserNodeFeature } from \"../core/feature.ts\";\nimport type {\n BrowserNodeRuntimeError,\n BrowserNodeSessionMode\n} from \"../core/types.ts\";\nimport { useBrowserNodeController } from \"./useBrowserNodeController.ts\";\nimport { useBrowserNodeWebview } from \"./useBrowserNodeWebview.ts\";\n\nexport interface BrowserNodeProps {\n defaultUrl: string;\n feature: BrowserNodeFeature;\n nodeId: string;\n onFocusRequest?: () => void;\n profileId?: string | null;\n sessionMode?: BrowserNodeSessionMode;\n showHeader?: boolean;\n}\n\nexport function BrowserNode({\n defaultUrl,\n feature,\n nodeId,\n onFocusRequest,\n profileId = null,\n sessionMode = \"shared\",\n showHeader = true\n}: BrowserNodeProps): JSX.Element {\n const { controller, state } = useBrowserNodeController({\n defaultUrl,\n feature,\n nodeId,\n profileId,\n sessionMode\n });\n const runtime = state.runtime;\n const errorMessage = runtime.error\n ? formatBrowserNodeErrorMessage(feature, runtime.error)\n : null;\n const {\n shouldRenderWebview,\n setWebviewRef,\n webviewKey,\n webviewPartition,\n webviewSrc\n } = useBrowserNodeWebview({\n feature,\n initialUrl: state.displayUrl,\n lifecycle: runtime.lifecycle,\n nodeId,\n onGuestInteraction: onFocusRequest,\n profileId,\n sessionMode\n });\n\n return (\n <div className=\"flex h-full min-h-0 flex-col overflow-hidden bg-[var(--background-panel)]\">\n {showHeader ? (\n <BrowserNodeHeader\n canGoBack={runtime.canGoBack}\n canGoForward={runtime.canGoForward}\n draftUrl={state.draftUrl}\n feature={feature}\n isCold={runtime.lifecycle === \"cold\"}\n isLoading={runtime.isLoading}\n onDraftUrlChange={(nextUrl) => controller.setDraftUrl(nextUrl)}\n onFocusRequest={onFocusRequest}\n onSubmitUrl={() => {\n void controller.submitDraftUrl().catch(() => undefined);\n }}\n onGoBack={() => {\n void controller.goBack().catch(() => undefined);\n }}\n onGoForward={() => {\n void controller.goForward().catch(() => undefined);\n }}\n onReload={() => {\n void controller.reload().catch(() => undefined);\n }}\n />\n ) : null}\n <div className=\"relative min-h-0 flex-1 overflow-hidden bg-[var(--background-panel)]\">\n {shouldRenderWebview ? (\n <webview\n key={webviewKey}\n ref={setWebviewRef}\n className=\"absolute inset-0 h-full w-full border-0 bg-[var(--background-panel)]\"\n data-browser-node-webview=\"true\"\n partition={webviewPartition}\n src={webviewSrc}\n />\n ) : null}\n {errorMessage ? (\n <div className=\"pointer-events-none absolute inset-0 z-10 flex items-center justify-end p-3 text-center\">\n <div\n className=\"max-w-[min(320px,100%)] rounded-md border border-border bg-card/95 px-3 py-2 text-sm text-card-foreground shadow-panel\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <div className=\"font-medium\">{feature.i18n.t(\"loadFailed\")}</div>\n <div className=\"mt-1 text-xs text-muted-foreground\">\n {errorMessage}\n </div>\n </div>\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n\nexport interface BrowserNodeWorkbenchHeaderProps {\n className?: string;\n defaultActions?: ReactNode;\n defaultUrl: string;\n dragHandleProps?: HTMLAttributes<HTMLElement>;\n feature: BrowserNodeFeature;\n nodeId: string;\n onCloseRequest?: () => void;\n onFocusRequest?: () => void;\n}\n\nexport function BrowserNodeWorkbenchHeader({\n className,\n defaultActions,\n defaultUrl,\n dragHandleProps,\n feature,\n nodeId,\n onCloseRequest,\n onFocusRequest\n}: BrowserNodeWorkbenchHeaderProps): JSX.Element {\n const { controller, state } = useBrowserNodeController({\n defaultUrl,\n feature,\n nodeId\n });\n const runtime = state.runtime;\n\n return (\n <BrowserNodeHeader\n canGoBack={runtime.canGoBack}\n canGoForward={runtime.canGoForward}\n className={className}\n defaultActions={defaultActions}\n draftUrl={state.draftUrl}\n dragHandleProps={dragHandleProps}\n feature={feature}\n isCold={runtime.lifecycle === \"cold\"}\n isLoading={runtime.isLoading}\n onCloseRequest={onCloseRequest}\n onDraftUrlChange={(nextUrl) => controller.setDraftUrl(nextUrl)}\n onFocusRequest={onFocusRequest}\n onSubmitUrl={() => {\n void controller.submitDraftUrl().catch(() => undefined);\n }}\n onGoBack={() => {\n void controller.goBack().catch(() => undefined);\n }}\n onGoForward={() => {\n void controller.goForward().catch(() => undefined);\n }}\n onReload={() => {\n void controller.reload().catch(() => undefined);\n }}\n withBorder={false}\n />\n );\n}\n\nexport function BrowserNodeHeader({\n canGoBack,\n canGoForward,\n className,\n defaultActions,\n draftUrl,\n dragHandleProps,\n feature,\n isCold = false,\n isLoading,\n onCloseRequest,\n onDraftUrlChange,\n onFocusRequest,\n onGoBack,\n onGoForward,\n onReload,\n onSubmitUrl,\n withBorder = true\n}: {\n canGoBack: boolean;\n canGoForward: boolean;\n className?: string;\n defaultActions?: ReactNode;\n draftUrl: string;\n dragHandleProps?: HTMLAttributes<HTMLElement>;\n feature: BrowserNodeFeature;\n isCold?: boolean;\n isLoading: boolean;\n onCloseRequest?: () => void;\n onDraftUrlChange: (nextUrl: string) => void;\n onFocusRequest?: () => void;\n onGoBack: () => void;\n onGoForward: () => void;\n onReload: () => void;\n onSubmitUrl: () => void;\n withBorder?: boolean;\n}): JSX.Element {\n return (\n <div\n className={cn(\n \"flex h-[var(--workbench-header-height,38px)] min-h-[var(--workbench-header-height,38px)] items-center gap-2 bg-[var(--background-panel)] px-2 pl-3\",\n withBorder ? \"border-b border-border\" : null,\n className\n )}\n data-browser-node-header=\"true\"\n onDoubleClick={(event) => {\n if (\n event.target instanceof Element &&\n event.target.closest(\".nodrag\")\n ) {\n return;\n }\n event.stopPropagation();\n dragHandleProps?.onDoubleClick?.(event);\n }}\n >\n <div className=\"inline-flex items-center gap-1\">\n <BrowserNodeHeaderButton\n disabled={!canGoBack}\n label={feature.i18n.t(\"actions.back\")}\n onClick={onGoBack}\n >\n <ArrowLeftIcon className=\"size-4\" />\n </BrowserNodeHeaderButton>\n <BrowserNodeHeaderButton\n disabled={!canGoForward}\n label={feature.i18n.t(\"actions.forward\")}\n onClick={onGoForward}\n >\n <ArrowRightIcon className=\"size-4\" />\n </BrowserNodeHeaderButton>\n <BrowserNodeHeaderButton\n label={feature.i18n.t(\"actions.reload\")}\n onClick={onReload}\n >\n <RefreshIcon className=\"size-4\" />\n </BrowserNodeHeaderButton>\n </div>\n <div\n {...dragHandleProps}\n className=\"h-full w-8 shrink-0 cursor-grab active:cursor-grabbing\"\n data-browser-node-drag-gutter=\"true\"\n data-node-drag-handle=\"true\"\n aria-hidden=\"true\"\n />\n <form\n className=\"nodrag relative min-w-0 flex-1\"\n onSubmit={(event) => {\n event.preventDefault();\n event.stopPropagation();\n onSubmitUrl();\n }}\n >\n <LaunchIcon className=\"pointer-events-none absolute left-2 top-1/2 z-[1] size-4 -translate-y-1/2 text-[var(--text-tertiary)]\" />\n <Input\n aria-label={feature.i18n.t(\"addressLabel\")}\n className=\"pl-8 pr-8 focus-visible:ring-0 focus-visible:ring-offset-0\"\n placeholder={feature.i18n.t(\"addressPlaceholder\")}\n size=\"sm\"\n value={draftUrl}\n onChange={(event) => onDraftUrlChange(event.target.value)}\n onFocus={onFocusRequest}\n />\n {isLoading ? (\n <LoadingIcon className=\"pointer-events-none absolute right-2 top-1/2 z-[1] size-4 -translate-y-1/2 animate-spin text-[var(--text-tertiary)]\" />\n ) : null}\n </form>\n {defaultActions ? (\n <div className=\"nodrag flex shrink-0 items-center gap-1.5\">\n {isCold ? (\n <span\n className=\"inline-flex h-[26px] min-w-7 items-center justify-center rounded-md bg-muted/80 px-2 text-[10px] font-semibold lowercase tracking-[0.08em] text-muted-foreground\"\n aria-label={feature.i18n.t(\"coldStatus\")}\n >\n {feature.i18n.t(\"coldStatus\")}\n </span>\n ) : null}\n <span\n className=\"contents\"\n onClickCapture={(event) => {\n if (\n !onCloseRequest ||\n !(event.target instanceof Element) ||\n !event.target.closest('[data-workbench-action=\"close\"]')\n ) {\n return;\n }\n onCloseRequest();\n }}\n >\n {defaultActions}\n </span>\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction formatBrowserNodeErrorMessage(\n feature: BrowserNodeFeature,\n error: BrowserNodeRuntimeError\n): string {\n switch (error.code) {\n case \"invalid-url\":\n return feature.i18n.t(\"errors.invalidUrl\", error.params);\n case \"navigation-failed\":\n return feature.i18n.t(\"errors.navigationFailed\", error.params);\n case \"unsupported-protocol\":\n return feature.i18n.t(\"errors.unsupportedProtocol\", error.params);\n case \"unsupported-url\":\n return feature.i18n.t(\"errors.unsupportedUrl\", error.params);\n }\n}\n\nfunction BrowserNodeHeaderButton({\n children,\n disabled,\n label,\n onClick\n}: {\n children: ReactNode;\n disabled?: boolean;\n label: string;\n onClick: () => void;\n}) {\n return (\n <Button\n aria-label={label}\n className=\"rounded-md\"\n disabled={disabled}\n size=\"icon\"\n title={label}\n type=\"button\"\n variant=\"chrome\"\n onClick={onClick}\n >\n {children}\n </Button>\n );\n}\n","import { useEffect, useMemo } from \"react\";\nimport { useExternalStoreSnapshot } from \"@nextop-os/ui-react-hooks\";\nimport type { BrowserNodeFeature } from \"../core/feature.ts\";\nimport {\n acquireBrowserNodeController,\n type BrowserNodeControllerState\n} from \"../core/nodeController.ts\";\nimport type { BrowserNodeSessionMode } from \"../core/types.ts\";\n\nexport function useBrowserNodeController(input: {\n defaultUrl: string;\n feature: BrowserNodeFeature;\n nodeId: string;\n profileId?: string | null;\n sessionMode?: BrowserNodeSessionMode;\n}) {\n const controller = useMemo(\n () =>\n acquireBrowserNodeController({\n defaultUrl: input.defaultUrl,\n feature: input.feature,\n nodeId: input.nodeId,\n profileId: input.profileId ?? null,\n sessionMode: input.sessionMode ?? \"shared\"\n }),\n [\n input.defaultUrl,\n input.feature,\n input.nodeId,\n input.profileId,\n input.sessionMode\n ]\n );\n\n useEffect(() => {\n controller.retain();\n return () => {\n controller.release();\n };\n }, [controller]);\n const state = useExternalStoreSnapshot<BrowserNodeControllerState>({\n getSnapshot() {\n return controller.getState();\n },\n subscribe(listener) {\n return controller.subscribe(listener);\n }\n });\n\n return {\n controller,\n state\n };\n}\n","import type { BrowserNodeFeature } from \"./feature.ts\";\nimport type {\n BrowserNodeRuntimeState,\n BrowserNodeSessionMode\n} from \"./types.ts\";\n\nexport interface BrowserNodeControllerState {\n displayUrl: string;\n draftUrl: string;\n runtime: BrowserNodeRuntimeState;\n}\n\nexport interface BrowserNodeController {\n getState(): BrowserNodeControllerState;\n goBack(): Promise<void>;\n goForward(): Promise<void>;\n reload(): Promise<void>;\n release(): void;\n retain(): void;\n setDraftUrl(nextUrl: string): void;\n subscribe(listener: () => void): () => void;\n submitDraftUrl(): Promise<void>;\n}\n\ninterface BrowserNodeControllerContext {\n defaultUrl: string;\n feature: BrowserNodeFeature;\n nodeId: string;\n profileId: string | null;\n sessionMode: BrowserNodeSessionMode;\n}\n\ninterface BrowserNodeControllerEntry {\n connectedRelease: (() => void) | null;\n controller: BrowserNodeController;\n context: BrowserNodeControllerContext;\n lastColdActivationUrl: string | null;\n listeners: Set<() => void>;\n pendingColdActivationUrl: string | null;\n refCount: number;\n runtimeUnsubscribe: (() => void) | null;\n state: BrowserNodeControllerState;\n}\n\nconst controllerRegistry = new Map<string, BrowserNodeControllerEntry>();\n\nexport function acquireBrowserNodeController(input: {\n defaultUrl: string;\n feature: BrowserNodeFeature;\n nodeId: string;\n profileId?: string | null;\n sessionMode?: BrowserNodeSessionMode;\n}): BrowserNodeController {\n const existing = controllerRegistry.get(input.nodeId);\n const entry =\n existing ??\n createBrowserNodeControllerEntry({\n defaultUrl: input.defaultUrl,\n feature: input.feature,\n nodeId: input.nodeId,\n profileId: input.profileId ?? null,\n sessionMode: input.sessionMode ?? \"shared\"\n });\n\n entry.context = {\n defaultUrl: input.defaultUrl,\n feature: input.feature,\n nodeId: input.nodeId,\n profileId: input.profileId ?? null,\n sessionMode: input.sessionMode ?? \"shared\"\n };\n\n if (!existing) {\n controllerRegistry.set(input.nodeId, entry);\n }\n\n reconcileBrowserNodeControllerState(entry, {\n allowAutoActivate: false,\n notifyListeners: false\n });\n\n return entry.controller;\n}\n\nfunction createBrowserNodeControllerEntry(\n context: BrowserNodeControllerContext\n): BrowserNodeControllerEntry {\n const runtime = context.feature.runtimeStore.getNodeState(context.nodeId);\n const displayUrl = resolveBrowserNodeDisplayUrl(runtime, context.defaultUrl);\n const entry = {\n connectedRelease: null,\n controller: null as unknown as BrowserNodeController,\n context,\n lastColdActivationUrl: null,\n listeners: new Set(),\n pendingColdActivationUrl: null,\n refCount: 0,\n runtimeUnsubscribe: null,\n state: {\n displayUrl,\n draftUrl: displayUrl,\n runtime\n }\n } as BrowserNodeControllerEntry;\n\n entry.controller = {\n getState() {\n return entry.state;\n },\n goBack() {\n return entry.context.feature.hostApi.goBack({\n nodeId: entry.context.nodeId\n });\n },\n goForward() {\n return entry.context.feature.hostApi.goForward({\n nodeId: entry.context.nodeId\n });\n },\n reload() {\n return entry.context.feature.hostApi.reload({\n nodeId: entry.context.nodeId\n });\n },\n release() {\n entry.refCount = Math.max(0, entry.refCount - 1);\n if (entry.refCount > 0) {\n return;\n }\n\n entry.connectedRelease?.();\n entry.connectedRelease = null;\n entry.runtimeUnsubscribe?.();\n entry.runtimeUnsubscribe = null;\n controllerRegistry.delete(entry.context.nodeId);\n },\n retain() {\n entry.refCount += 1;\n if (entry.refCount > 1) {\n return;\n }\n\n if (!controllerRegistry.has(entry.context.nodeId)) {\n controllerRegistry.set(entry.context.nodeId, entry);\n }\n entry.connectedRelease = entry.context.feature.connect();\n entry.runtimeUnsubscribe = entry.context.feature.runtimeStore.subscribe(\n () => {\n reconcileBrowserNodeControllerState(entry, {\n allowAutoActivate: true,\n notifyListeners: true\n });\n }\n );\n reconcileBrowserNodeControllerState(entry, {\n allowAutoActivate: true,\n notifyListeners: true\n });\n },\n setDraftUrl(nextUrl) {\n if (entry.state.draftUrl === nextUrl) {\n return;\n }\n\n entry.state = {\n ...entry.state,\n draftUrl: nextUrl\n };\n notifyBrowserNodeControllerListeners(entry);\n },\n subscribe(listener) {\n entry.listeners.add(listener);\n return () => {\n entry.listeners.delete(listener);\n };\n },\n async submitDraftUrl() {\n const resolved = entry.context.feature.resolveAddressInput(\n entry.state.draftUrl\n );\n if (!resolved.url) {\n return;\n }\n\n if (entry.state.draftUrl !== resolved.url) {\n entry.state = {\n ...entry.state,\n draftUrl: resolved.url\n };\n notifyBrowserNodeControllerListeners(entry);\n }\n\n await entry.context.feature.hostApi.navigate({\n nodeId: entry.context.nodeId,\n url: resolved.url\n });\n }\n };\n\n return entry;\n}\n\nfunction notifyBrowserNodeControllerListeners(\n entry: BrowserNodeControllerEntry\n): void {\n for (const listener of entry.listeners) {\n listener();\n }\n}\n\nfunction resolveBrowserNodeDisplayUrl(\n runtime: BrowserNodeRuntimeState,\n defaultUrl: string\n): string {\n const resolvedRuntimeUrl = runtime.url?.trim() ?? \"\";\n return resolvedRuntimeUrl.length > 0 ? resolvedRuntimeUrl : defaultUrl;\n}\n\nfunction reconcileBrowserNodeControllerState(\n entry: BrowserNodeControllerEntry,\n options: {\n allowAutoActivate: boolean;\n notifyListeners: boolean;\n }\n): void {\n const runtime = entry.context.feature.runtimeStore.getNodeState(\n entry.context.nodeId\n );\n const displayUrl = resolveBrowserNodeDisplayUrl(\n runtime,\n entry.context.defaultUrl\n );\n const nextDraftUrl =\n displayUrl !== entry.state.displayUrl ? displayUrl : entry.state.draftUrl;\n\n const changed =\n entry.state.runtime !== runtime ||\n entry.state.displayUrl !== displayUrl ||\n entry.state.draftUrl !== nextDraftUrl;\n\n if (changed) {\n entry.state = {\n displayUrl,\n draftUrl: nextDraftUrl,\n runtime\n };\n if (options.notifyListeners) {\n notifyBrowserNodeControllerListeners(entry);\n }\n }\n\n if (options.allowAutoActivate) {\n void maybeActivateColdBrowserNode(entry).catch(() => undefined);\n }\n}\n\nasync function maybeActivateColdBrowserNode(\n entry: BrowserNodeControllerEntry\n): Promise<void> {\n const { defaultUrl, feature, nodeId, profileId, sessionMode } = entry.context;\n const trimmedUrl = defaultUrl.trim();\n if (\n trimmedUrl.length === 0 ||\n entry.state.runtime.lifecycle !== \"cold\" ||\n entry.state.runtime.isLoading ||\n entry.state.runtime.error !== null ||\n entry.pendingColdActivationUrl === trimmedUrl ||\n entry.lastColdActivationUrl === trimmedUrl\n ) {\n return;\n }\n\n entry.pendingColdActivationUrl = trimmedUrl;\n try {\n await feature.hostApi.activate({\n nodeId,\n profileId,\n sessionMode,\n url: trimmedUrl\n });\n entry.lastColdActivationUrl = trimmedUrl;\n } finally {\n if (entry.pendingColdActivationUrl === trimmedUrl) {\n entry.pendingColdActivationUrl = null;\n }\n }\n}\n","import { useCallback, useEffect, useMemo } from \"react\";\nimport { useExternalStoreSnapshot } from \"@nextop-os/ui-react-hooks\";\nimport {\n acquireBrowserNodeWebviewController,\n type BrowserNodeWebviewControllerState\n} from \"../core/webviewController.ts\";\nimport type { BrowserNodeFeature } from \"../core/feature.ts\";\nimport type {\n BrowserNodeLifecycle,\n BrowserNodeSessionMode\n} from \"../core/types.ts\";\nimport type { BrowserNodeWebviewTag } from \"./webviewTag.ts\";\n\nexport function useBrowserNodeWebview({\n feature,\n initialUrl,\n lifecycle,\n nodeId,\n onGuestInteraction,\n profileId,\n sessionMode\n}: {\n feature: BrowserNodeFeature;\n initialUrl: string;\n lifecycle: BrowserNodeLifecycle;\n nodeId: string;\n onGuestInteraction?: () => void;\n profileId: string | null;\n sessionMode: BrowserNodeSessionMode;\n}): {\n shouldRenderWebview: boolean;\n setWebviewRef: (element: BrowserNodeWebviewTag | null) => void;\n webviewKey: string;\n webviewPartition: string;\n webviewSrc: string;\n} {\n const controller = useMemo(\n () =>\n acquireBrowserNodeWebviewController({\n feature,\n initialUrl,\n lifecycle,\n nodeId,\n onGuestInteraction,\n profileId,\n sessionMode\n }),\n [\n feature,\n initialUrl,\n lifecycle,\n nodeId,\n onGuestInteraction,\n profileId,\n sessionMode\n ]\n );\n\n useEffect(() => {\n controller.retain();\n return () => {\n controller.release();\n };\n }, [controller]);\n\n useEffect(() => {\n controller.sync();\n }, [\n controller,\n initialUrl,\n lifecycle,\n nodeId,\n onGuestInteraction,\n profileId,\n sessionMode\n ]);\n const state = useExternalStoreSnapshot<BrowserNodeWebviewControllerState>({\n getSnapshot() {\n return controller.getState();\n },\n subscribe(listener) {\n return controller.subscribe(listener);\n }\n });\n\n const setWebviewRef = useCallback(\n (element: BrowserNodeWebviewTag | null) => {\n controller.setWebview(element);\n },\n [controller]\n );\n\n return {\n shouldRenderWebview: state.shouldRenderWebview,\n setWebviewRef,\n webviewKey: state.webviewKey,\n webviewPartition: state.webviewPartition,\n webviewSrc: state.webviewSrc\n };\n}\n","import type { BrowserNodeFeature } from \"./feature.ts\";\nimport { resolveBrowserSessionPartition } from \"./session.ts\";\nimport type { BrowserNodeLifecycle, BrowserNodeSessionMode } from \"./types.ts\";\nimport type { BrowserNodeWebviewTag } from \"../react/webviewTag.ts\";\n\nconst browserGuestUnregisterGraceMs = 250;\n\nexport interface BrowserNodeWebviewControllerState {\n shouldRenderWebview: boolean;\n webviewKey: string;\n webviewPartition: string;\n webviewSrc: string;\n}\n\nexport interface BrowserNodeWebviewController {\n getState(): BrowserNodeWebviewControllerState;\n release(): void;\n retain(): void;\n setWebview(element: BrowserNodeWebviewTag | null): void;\n sync(): void;\n subscribe(listener: () => void): () => void;\n}\n\ninterface BrowserNodeWebviewControllerContext {\n feature: BrowserNodeFeature;\n initialUrl: string;\n lifecycle: BrowserNodeLifecycle;\n nodeId: string;\n onGuestInteraction?: () => void;\n profileId: string | null;\n sessionMode: BrowserNodeSessionMode;\n}\n\ninterface BrowserNodeWebviewControllerEntry {\n attachedListeners: Array<{\n event: string;\n listener: EventListener;\n }>;\n context: BrowserNodeWebviewControllerContext;\n controller: BrowserNodeWebviewController;\n listeners: Set<() => void>;\n refCount: number;\n registeredGuestId: number | null;\n registeringGuestId: number | null;\n state: BrowserNodeWebviewControllerState;\n webview: BrowserNodeWebviewTag | null;\n}\n\nconst webviewControllerRegistry = new Map<\n string,\n BrowserNodeWebviewControllerEntry\n>();\nconst pendingGuestIdsByNodeId = new Map<string, number>();\nconst pendingUnregisterTimersByNodeId = new Map<\n string,\n ReturnType<typeof globalThis.setTimeout>\n>();\n\nexport function acquireBrowserNodeWebviewController(input: {\n feature: BrowserNodeFeature;\n initialUrl: string;\n lifecycle: BrowserNodeLifecycle;\n nodeId: string;\n onGuestInteraction?: () => void;\n profileId: string | null;\n sessionMode: BrowserNodeSessionMode;\n}): BrowserNodeWebviewController {\n const existing = webviewControllerRegistry.get(input.nodeId);\n const entry =\n existing ??\n createBrowserNodeWebviewControllerEntry({\n feature: input.feature,\n initialUrl: input.initialUrl,\n lifecycle: input.lifecycle,\n nodeId: input.nodeId,\n onGuestInteraction: input.onGuestInteraction,\n profileId: input.profileId,\n sessionMode: input.sessionMode\n });\n\n entry.context = {\n feature: input.feature,\n initialUrl: input.initialUrl,\n lifecycle: input.lifecycle,\n nodeId: input.nodeId,\n onGuestInteraction: input.onGuestInteraction,\n profileId: input.profileId,\n sessionMode: input.sessionMode\n };\n if (!existing) {\n webviewControllerRegistry.set(input.nodeId, entry);\n }\n return entry.controller;\n}\n\nfunction createBrowserNodeWebviewControllerEntry(\n context: BrowserNodeWebviewControllerContext\n): BrowserNodeWebviewControllerEntry {\n const state = resolveBrowserNodeWebviewControllerState(context);\n const entry = {\n attachedListeners: [],\n context,\n controller: null as unknown as BrowserNodeWebviewController,\n listeners: new Set(),\n refCount: 0,\n registeredGuestId: null,\n registeringGuestId: null,\n state,\n webview: null\n } as BrowserNodeWebviewControllerEntry;\n\n entry.controller = {\n getState() {\n return entry.state;\n },\n release() {\n entry.refCount = Math.max(0, entry.refCount - 1);\n if (entry.refCount > 0) {\n return;\n }\n scheduleBrowserNodeGuestUnregister(entry);\n detachBrowserNodeWebview(entry);\n webviewControllerRegistry.delete(entry.context.nodeId);\n },\n retain() {\n entry.refCount += 1;\n if (entry.refCount > 1) {\n return;\n }\n reconcileBrowserNodeWebviewControllerState(entry, {\n allowHostEffects: true,\n notifyListeners: true,\n rebindWebview: true\n });\n },\n setWebview(element) {\n if (entry.webview === element) {\n return;\n }\n detachBrowserNodeWebview(entry);\n entry.webview = element;\n attachBrowserNodeWebview(entry);\n },\n sync() {\n reconcileBrowserNodeWebviewControllerState(entry, {\n allowHostEffects: true,\n notifyListeners: true,\n rebindWebview: true\n });\n },\n subscribe(listener) {\n entry.listeners.add(listener);\n return () => {\n entry.listeners.delete(listener);\n };\n }\n };\n\n return entry;\n}\n\nfunction resolveBrowserNodeWebviewControllerState(\n context: BrowserNodeWebviewControllerContext\n): BrowserNodeWebviewControllerState {\n const webviewPartition = resolveBrowserSessionPartition({\n profileId: context.profileId,\n sessionMode: context.sessionMode\n });\n return {\n shouldRenderWebview: context.lifecycle !== \"cold\",\n webviewKey: `${context.nodeId}:${webviewPartition}`,\n webviewPartition,\n webviewSrc: resolveBrowserWebviewSrc(context.initialUrl)\n };\n}\n\nfunction reconcileBrowserNodeWebviewControllerState(\n entry: BrowserNodeWebviewControllerEntry,\n options: {\n allowHostEffects: boolean;\n notifyListeners: boolean;\n rebindWebview: boolean;\n }\n): void {\n const nextState = resolveBrowserNodeWebviewControllerState(entry.context);\n const changed =\n entry.state.shouldRenderWebview !== nextState.shouldRenderWebview ||\n entry.state.webviewKey !== nextState.webviewKey ||\n entry.state.webviewPartition !== nextState.webviewPartition ||\n entry.state.webviewSrc !== nextState.webviewSrc;\n\n if (options.allowHostEffects) {\n if (entry.context.lifecycle === \"cold\") {\n scheduleBrowserNodeGuestUnregister(entry);\n } else {\n clearPendingBrowserNodeGuestUnregister(entry.context.nodeId);\n void entry.context.feature.hostApi\n .prepareSession({\n nodeId: entry.context.nodeId,\n profileId: entry.context.profileId,\n sessionMode: entry.context.sessionMode\n })\n .catch(() => undefined);\n }\n }\n\n if (!changed && !options.rebindWebview) {\n return;\n }\n\n if (changed) {\n entry.state = nextState;\n }\n detachBrowserNodeWebview(entry);\n attachBrowserNodeWebview(entry);\n if (changed && options.notifyListeners) {\n notifyBrowserNodeWebviewControllerListeners(entry);\n }\n}\n\nfunction resolveBrowserWebviewSrc(url: string): string {\n const trimmed = url.trim();\n return trimmed.length > 0 ? trimmed : \"about:blank\";\n}\n\nfunction notifyBrowserNodeWebviewControllerListeners(\n entry: BrowserNodeWebviewControllerEntry\n): void {\n for (const listener of entry.listeners) {\n listener();\n }\n}\n\nfunction clearPendingBrowserNodeGuestUnregister(nodeId: string): void {\n const timerId = pendingUnregisterTimersByNodeId.get(nodeId);\n if (timerId !== undefined) {\n globalThis.clearTimeout(timerId);\n pendingUnregisterTimersByNodeId.delete(nodeId);\n }\n pendingGuestIdsByNodeId.delete(nodeId);\n}\n\nfunction scheduleBrowserNodeGuestUnregister(\n entry: BrowserNodeWebviewControllerEntry\n): void {\n const guestId = entry.registeredGuestId;\n const nodeId = entry.context.nodeId;\n entry.registeringGuestId = null;\n if (guestId === null) {\n clearPendingBrowserNodeGuestUnregister(nodeId);\n return;\n }\n\n entry.registeredGuestId = null;\n clearPendingBrowserNodeGuestUnregister(nodeId);\n pendingGuestIdsByNodeId.set(nodeId, guestId);\n const timerId = globalThis.setTimeout(() => {\n pendingUnregisterTimersByNodeId.delete(nodeId);\n const pendingGuestId = pendingGuestIdsByNodeId.get(nodeId);\n pendingGuestIdsByNodeId.delete(nodeId);\n if (\n typeof pendingGuestId !== \"number\" ||\n !Number.isFinite(pendingGuestId)\n ) {\n return;\n }\n\n void entry.context.feature.hostApi\n .unregisterGuest({\n nodeId: entry.context.nodeId,\n webContentsId: pendingGuestId\n })\n .catch(() => undefined);\n }, browserGuestUnregisterGraceMs);\n pendingUnregisterTimersByNodeId.set(nodeId, timerId);\n}\n\nfunction detachBrowserNodeWebview(\n entry: BrowserNodeWebviewControllerEntry\n): void {\n if (!entry.webview) {\n entry.attachedListeners = [];\n return;\n }\n for (const record of entry.attachedListeners) {\n entry.webview.removeEventListener(record.event, record.listener);\n }\n entry.attachedListeners = [];\n}\n\nfunction attachBrowserNodeWebview(\n entry: BrowserNodeWebviewControllerEntry\n): void {\n const webview = entry.webview;\n if (!webview || !entry.state.shouldRenderWebview) {\n return;\n }\n\n const registerGuest = async (): Promise<void> => {\n const guestId = webview.getWebContentsId?.();\n if (\n typeof guestId !== \"number\" ||\n !Number.isFinite(guestId) ||\n guestId <= 0 ||\n entry.registeredGuestId === guestId ||\n entry.registeringGuestId === guestId\n ) {\n return;\n }\n\n clearPendingBrowserNodeGuestUnregister(entry.context.nodeId);\n entry.registeringGuestId = guestId;\n try {\n await entry.context.feature.hostApi.registerGuest({\n nodeId: entry.context.nodeId,\n profileId: entry.context.profileId,\n sessionMode: entry.context.sessionMode,\n webContentsId: guestId\n });\n entry.registeredGuestId = guestId;\n } finally {\n if (entry.registeringGuestId === guestId) {\n entry.registeringGuestId = null;\n }\n }\n };\n\n const handleDidAttach: EventListener = () => {\n void registerGuest().catch(() => undefined);\n };\n const handleDomReady: EventListener = () => {\n void registerGuest().catch(() => undefined);\n };\n const handleGuestInteraction: EventListener = () => {\n entry.context.onGuestInteraction?.();\n };\n\n const records = [\n { event: \"did-attach\", listener: handleDidAttach },\n { event: \"dom-ready\", listener: handleDomReady },\n { event: \"focus\", listener: handleGuestInteraction },\n { event: \"ipc-message\", listener: handleGuestInteraction }\n ];\n for (const record of records) {\n webview.addEventListener(record.event, record.listener);\n }\n entry.attachedListeners = records;\n}\n"],"mappings":"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","names":["useEffect","useMemo","useExternalStoreSnapshot","useMemo","useEffect","useExternalStoreSnapshot"]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  BrowserNode,
3
3
  BrowserNodeHeader
4
- } from "../chunk-XCKUTY7D.js";
4
+ } from "../chunk-3ERRS74C.js";
5
5
  import "../chunk-OTK5YBCK.js";
6
6
  export {
7
7
  BrowserNode,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  BrowserNode,
3
3
  BrowserNodeWorkbenchHeader
4
- } from "../chunk-XCKUTY7D.js";
4
+ } from "../chunk-3ERRS74C.js";
5
5
  import "../chunk-OTK5YBCK.js";
6
6
 
7
7
  // src/workbench/index.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextop-os/browser-node",
3
- "version": "0.0.17",
3
+ "version": "0.0.19",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
@@ -44,10 +44,10 @@
44
44
  "directory": "packages/browser/workbench-node"
45
45
  },
46
46
  "dependencies": {
47
- "@nextop-os/ui-i18n-runtime": "0.0.17",
48
- "@nextop-os/ui-react-hooks": "0.0.17",
49
- "@nextop-os/ui-system": "0.0.17",
50
- "@nextop-os/workbench-surface": "0.0.17",
47
+ "@nextop-os/ui-i18n-runtime": "0.0.19",
48
+ "@nextop-os/ui-react-hooks": "0.0.19",
49
+ "@nextop-os/ui-system": "0.0.19",
50
+ "@nextop-os/workbench-surface": "0.0.19",
51
51
  "ws": "^8.21.0"
52
52
  },
53
53
  "devDependencies": {
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/react/BrowserNode.tsx","../src/react/useBrowserNodeController.ts","../src/core/nodeController.ts","../src/react/useBrowserNodeWebview.ts","../src/core/webviewController.ts"],"sourcesContent":["import {\n ArrowLeftIcon,\n ArrowRightIcon,\n Button,\n LaunchIcon,\n LoadingIcon,\n RefreshIcon,\n cn\n} from \"@nextop-os/ui-system\";\nimport type { HTMLAttributes, JSX, ReactNode } from \"react\";\nimport type { BrowserNodeFeature } from \"../core/feature.ts\";\nimport type {\n BrowserNodeRuntimeError,\n BrowserNodeSessionMode\n} from \"../core/types.ts\";\nimport { useBrowserNodeController } from \"./useBrowserNodeController.ts\";\nimport { useBrowserNodeWebview } from \"./useBrowserNodeWebview.ts\";\n\nexport interface BrowserNodeProps {\n defaultUrl: string;\n feature: BrowserNodeFeature;\n nodeId: string;\n onFocusRequest?: () => void;\n profileId?: string | null;\n sessionMode?: BrowserNodeSessionMode;\n showHeader?: boolean;\n}\n\nexport function BrowserNode({\n defaultUrl,\n feature,\n nodeId,\n onFocusRequest,\n profileId = null,\n sessionMode = \"shared\",\n showHeader = true\n}: BrowserNodeProps): JSX.Element {\n const { controller, state } = useBrowserNodeController({\n defaultUrl,\n feature,\n nodeId,\n profileId,\n sessionMode\n });\n const runtime = state.runtime;\n const errorMessage = runtime.error\n ? formatBrowserNodeErrorMessage(feature, runtime.error)\n : null;\n const {\n shouldRenderWebview,\n setWebviewRef,\n webviewKey,\n webviewPartition,\n webviewSrc\n } = useBrowserNodeWebview({\n feature,\n initialUrl: state.displayUrl,\n lifecycle: runtime.lifecycle,\n nodeId,\n onGuestInteraction: onFocusRequest,\n profileId,\n sessionMode\n });\n\n return (\n <div className=\"flex h-full min-h-0 flex-col overflow-hidden bg-background\">\n {showHeader ? (\n <BrowserNodeHeader\n canGoBack={runtime.canGoBack}\n canGoForward={runtime.canGoForward}\n draftUrl={state.draftUrl}\n feature={feature}\n isCold={runtime.lifecycle === \"cold\"}\n isLoading={runtime.isLoading}\n onDraftUrlChange={(nextUrl) => controller.setDraftUrl(nextUrl)}\n onFocusRequest={onFocusRequest}\n onSubmitUrl={() => {\n void controller.submitDraftUrl().catch(() => undefined);\n }}\n onGoBack={() => {\n void controller.goBack().catch(() => undefined);\n }}\n onGoForward={() => {\n void controller.goForward().catch(() => undefined);\n }}\n onReload={() => {\n void controller.reload().catch(() => undefined);\n }}\n />\n ) : null}\n <div className=\"relative min-h-0 flex-1 overflow-hidden bg-background\">\n {shouldRenderWebview ? (\n <webview\n key={webviewKey}\n ref={setWebviewRef}\n className=\"absolute inset-0 h-full w-full border-0 bg-background\"\n data-browser-node-webview=\"true\"\n partition={webviewPartition}\n src={webviewSrc}\n />\n ) : null}\n {errorMessage ? (\n <div className=\"pointer-events-none absolute inset-0 z-10 flex items-center justify-end p-3 text-center\">\n <div\n className=\"max-w-[min(320px,100%)] rounded-md border border-border bg-card/95 px-3 py-2 text-sm text-card-foreground shadow-panel\"\n role=\"status\"\n aria-live=\"polite\"\n >\n <div className=\"font-medium\">{feature.i18n.t(\"loadFailed\")}</div>\n <div className=\"mt-1 text-xs text-muted-foreground\">\n {errorMessage}\n </div>\n </div>\n </div>\n ) : null}\n </div>\n </div>\n );\n}\n\nexport interface BrowserNodeWorkbenchHeaderProps {\n className?: string;\n defaultActions?: ReactNode;\n defaultUrl: string;\n dragHandleProps?: HTMLAttributes<HTMLElement>;\n feature: BrowserNodeFeature;\n nodeId: string;\n onCloseRequest?: () => void;\n onFocusRequest?: () => void;\n}\n\nexport function BrowserNodeWorkbenchHeader({\n className,\n defaultActions,\n defaultUrl,\n dragHandleProps,\n feature,\n nodeId,\n onCloseRequest,\n onFocusRequest\n}: BrowserNodeWorkbenchHeaderProps): JSX.Element {\n const { controller, state } = useBrowserNodeController({\n defaultUrl,\n feature,\n nodeId\n });\n const runtime = state.runtime;\n\n return (\n <BrowserNodeHeader\n canGoBack={runtime.canGoBack}\n canGoForward={runtime.canGoForward}\n className={className}\n defaultActions={defaultActions}\n draftUrl={state.draftUrl}\n dragHandleProps={dragHandleProps}\n feature={feature}\n isCold={runtime.lifecycle === \"cold\"}\n isLoading={runtime.isLoading}\n onCloseRequest={onCloseRequest}\n onDraftUrlChange={(nextUrl) => controller.setDraftUrl(nextUrl)}\n onFocusRequest={onFocusRequest}\n onSubmitUrl={() => {\n void controller.submitDraftUrl().catch(() => undefined);\n }}\n onGoBack={() => {\n void controller.goBack().catch(() => undefined);\n }}\n onGoForward={() => {\n void controller.goForward().catch(() => undefined);\n }}\n onReload={() => {\n void controller.reload().catch(() => undefined);\n }}\n withBorder={false}\n />\n );\n}\n\nexport function BrowserNodeHeader({\n canGoBack,\n canGoForward,\n className,\n defaultActions,\n draftUrl,\n dragHandleProps,\n feature,\n isCold = false,\n isLoading,\n onCloseRequest,\n onDraftUrlChange,\n onFocusRequest,\n onGoBack,\n onGoForward,\n onReload,\n onSubmitUrl,\n withBorder = true\n}: {\n canGoBack: boolean;\n canGoForward: boolean;\n className?: string;\n defaultActions?: ReactNode;\n draftUrl: string;\n dragHandleProps?: HTMLAttributes<HTMLElement>;\n feature: BrowserNodeFeature;\n isCold?: boolean;\n isLoading: boolean;\n onCloseRequest?: () => void;\n onDraftUrlChange: (nextUrl: string) => void;\n onFocusRequest?: () => void;\n onGoBack: () => void;\n onGoForward: () => void;\n onReload: () => void;\n onSubmitUrl: () => void;\n withBorder?: boolean;\n}): JSX.Element {\n return (\n <div\n className={cn(\n \"flex h-[var(--workbench-header-height,38px)] min-h-[var(--workbench-header-height,38px)] items-center gap-2 bg-[var(--workbench-window-header-bg)] px-2 pl-3\",\n withBorder ? \"border-b border-border\" : null,\n className\n )}\n data-browser-node-header=\"true\"\n onDoubleClick={(event) => {\n if (\n event.target instanceof Element &&\n event.target.closest(\".nodrag\")\n ) {\n return;\n }\n event.stopPropagation();\n dragHandleProps?.onDoubleClick?.(event);\n }}\n >\n <div className=\"inline-flex items-center gap-1\">\n <BrowserNodeHeaderButton\n disabled={!canGoBack}\n label={feature.i18n.t(\"actions.back\")}\n onClick={onGoBack}\n >\n <ArrowLeftIcon className=\"size-4\" />\n </BrowserNodeHeaderButton>\n <BrowserNodeHeaderButton\n disabled={!canGoForward}\n label={feature.i18n.t(\"actions.forward\")}\n onClick={onGoForward}\n >\n <ArrowRightIcon className=\"size-4\" />\n </BrowserNodeHeaderButton>\n <BrowserNodeHeaderButton\n label={feature.i18n.t(\"actions.reload\")}\n onClick={onReload}\n >\n <RefreshIcon className=\"size-4\" />\n </BrowserNodeHeaderButton>\n </div>\n <div\n {...dragHandleProps}\n className=\"h-full w-8 shrink-0 cursor-grab active:cursor-grabbing\"\n data-browser-node-drag-gutter=\"true\"\n data-node-drag-handle=\"true\"\n aria-hidden=\"true\"\n />\n <form\n className=\"nodrag flex h-8 min-h-8 min-w-0 flex-1 items-center gap-1.5 rounded-md border border-border bg-[var(--workbench-field-bg)] px-2 focus-within:ring-2 focus-within:ring-ring/60\"\n onSubmit={(event) => {\n event.preventDefault();\n event.stopPropagation();\n onSubmitUrl();\n }}\n >\n <LaunchIcon className=\"size-4 shrink-0 text-muted-foreground\" />\n <input\n aria-label={feature.i18n.t(\"addressLabel\")}\n className=\"h-full min-w-0 flex-1 border-0 bg-transparent text-[13px] leading-none text-foreground outline-none placeholder:text-muted-foreground\"\n placeholder={feature.i18n.t(\"addressPlaceholder\")}\n value={draftUrl}\n onChange={(event) => onDraftUrlChange(event.target.value)}\n onFocus={onFocusRequest}\n />\n {isLoading ? (\n <LoadingIcon className=\"size-4 shrink-0 animate-spin text-muted-foreground\" />\n ) : null}\n </form>\n {defaultActions ? (\n <div className=\"nodrag flex shrink-0 items-center gap-1.5\">\n {isCold ? (\n <span\n className=\"inline-flex h-[26px] min-w-7 items-center justify-center rounded-md bg-muted/80 px-2 text-[10px] font-semibold lowercase tracking-[0.08em] text-muted-foreground\"\n aria-label={feature.i18n.t(\"coldStatus\")}\n >\n {feature.i18n.t(\"coldStatus\")}\n </span>\n ) : null}\n <span\n className=\"contents\"\n onClickCapture={(event) => {\n if (\n !onCloseRequest ||\n !(event.target instanceof Element) ||\n !event.target.closest('[data-workbench-action=\"close\"]')\n ) {\n return;\n }\n onCloseRequest();\n }}\n >\n {defaultActions}\n </span>\n </div>\n ) : null}\n </div>\n );\n}\n\nfunction formatBrowserNodeErrorMessage(\n feature: BrowserNodeFeature,\n error: BrowserNodeRuntimeError\n): string {\n switch (error.code) {\n case \"invalid-url\":\n return feature.i18n.t(\"errors.invalidUrl\", error.params);\n case \"navigation-failed\":\n return feature.i18n.t(\"errors.navigationFailed\", error.params);\n case \"unsupported-protocol\":\n return feature.i18n.t(\"errors.unsupportedProtocol\", error.params);\n case \"unsupported-url\":\n return feature.i18n.t(\"errors.unsupportedUrl\", error.params);\n }\n}\n\nfunction BrowserNodeHeaderButton({\n children,\n disabled,\n label,\n onClick\n}: {\n children: ReactNode;\n disabled?: boolean;\n label: string;\n onClick: () => void;\n}) {\n return (\n <Button\n aria-label={label}\n className=\"rounded-md\"\n disabled={disabled}\n size=\"icon\"\n title={label}\n type=\"button\"\n variant=\"chrome\"\n onClick={onClick}\n >\n {children}\n </Button>\n );\n}\n","import { useEffect, useMemo } from \"react\";\nimport { useExternalStoreSnapshot } from \"@nextop-os/ui-react-hooks\";\nimport type { BrowserNodeFeature } from \"../core/feature.ts\";\nimport {\n acquireBrowserNodeController,\n type BrowserNodeControllerState\n} from \"../core/nodeController.ts\";\nimport type { BrowserNodeSessionMode } from \"../core/types.ts\";\n\nexport function useBrowserNodeController(input: {\n defaultUrl: string;\n feature: BrowserNodeFeature;\n nodeId: string;\n profileId?: string | null;\n sessionMode?: BrowserNodeSessionMode;\n}) {\n const controller = useMemo(\n () =>\n acquireBrowserNodeController({\n defaultUrl: input.defaultUrl,\n feature: input.feature,\n nodeId: input.nodeId,\n profileId: input.profileId ?? null,\n sessionMode: input.sessionMode ?? \"shared\"\n }),\n [\n input.defaultUrl,\n input.feature,\n input.nodeId,\n input.profileId,\n input.sessionMode\n ]\n );\n\n useEffect(() => {\n controller.retain();\n return () => {\n controller.release();\n };\n }, [controller]);\n const state = useExternalStoreSnapshot<BrowserNodeControllerState>({\n getSnapshot() {\n return controller.getState();\n },\n subscribe(listener) {\n return controller.subscribe(listener);\n }\n });\n\n return {\n controller,\n state\n };\n}\n","import type { BrowserNodeFeature } from \"./feature.ts\";\nimport type {\n BrowserNodeRuntimeState,\n BrowserNodeSessionMode\n} from \"./types.ts\";\n\nexport interface BrowserNodeControllerState {\n displayUrl: string;\n draftUrl: string;\n runtime: BrowserNodeRuntimeState;\n}\n\nexport interface BrowserNodeController {\n getState(): BrowserNodeControllerState;\n goBack(): Promise<void>;\n goForward(): Promise<void>;\n reload(): Promise<void>;\n release(): void;\n retain(): void;\n setDraftUrl(nextUrl: string): void;\n subscribe(listener: () => void): () => void;\n submitDraftUrl(): Promise<void>;\n}\n\ninterface BrowserNodeControllerContext {\n defaultUrl: string;\n feature: BrowserNodeFeature;\n nodeId: string;\n profileId: string | null;\n sessionMode: BrowserNodeSessionMode;\n}\n\ninterface BrowserNodeControllerEntry {\n connectedRelease: (() => void) | null;\n controller: BrowserNodeController;\n context: BrowserNodeControllerContext;\n lastColdActivationUrl: string | null;\n listeners: Set<() => void>;\n pendingColdActivationUrl: string | null;\n refCount: number;\n runtimeUnsubscribe: (() => void) | null;\n state: BrowserNodeControllerState;\n}\n\nconst controllerRegistry = new Map<string, BrowserNodeControllerEntry>();\n\nexport function acquireBrowserNodeController(input: {\n defaultUrl: string;\n feature: BrowserNodeFeature;\n nodeId: string;\n profileId?: string | null;\n sessionMode?: BrowserNodeSessionMode;\n}): BrowserNodeController {\n const existing = controllerRegistry.get(input.nodeId);\n const entry =\n existing ??\n createBrowserNodeControllerEntry({\n defaultUrl: input.defaultUrl,\n feature: input.feature,\n nodeId: input.nodeId,\n profileId: input.profileId ?? null,\n sessionMode: input.sessionMode ?? \"shared\"\n });\n\n entry.context = {\n defaultUrl: input.defaultUrl,\n feature: input.feature,\n nodeId: input.nodeId,\n profileId: input.profileId ?? null,\n sessionMode: input.sessionMode ?? \"shared\"\n };\n\n if (!existing) {\n controllerRegistry.set(input.nodeId, entry);\n }\n\n reconcileBrowserNodeControllerState(entry, {\n allowAutoActivate: false,\n notifyListeners: false\n });\n\n return entry.controller;\n}\n\nfunction createBrowserNodeControllerEntry(\n context: BrowserNodeControllerContext\n): BrowserNodeControllerEntry {\n const runtime = context.feature.runtimeStore.getNodeState(context.nodeId);\n const displayUrl = resolveBrowserNodeDisplayUrl(runtime, context.defaultUrl);\n const entry = {\n connectedRelease: null,\n controller: null as unknown as BrowserNodeController,\n context,\n lastColdActivationUrl: null,\n listeners: new Set(),\n pendingColdActivationUrl: null,\n refCount: 0,\n runtimeUnsubscribe: null,\n state: {\n displayUrl,\n draftUrl: displayUrl,\n runtime\n }\n } as BrowserNodeControllerEntry;\n\n entry.controller = {\n getState() {\n return entry.state;\n },\n goBack() {\n return entry.context.feature.hostApi.goBack({\n nodeId: entry.context.nodeId\n });\n },\n goForward() {\n return entry.context.feature.hostApi.goForward({\n nodeId: entry.context.nodeId\n });\n },\n reload() {\n return entry.context.feature.hostApi.reload({\n nodeId: entry.context.nodeId\n });\n },\n release() {\n entry.refCount = Math.max(0, entry.refCount - 1);\n if (entry.refCount > 0) {\n return;\n }\n\n entry.connectedRelease?.();\n entry.connectedRelease = null;\n entry.runtimeUnsubscribe?.();\n entry.runtimeUnsubscribe = null;\n controllerRegistry.delete(entry.context.nodeId);\n },\n retain() {\n entry.refCount += 1;\n if (entry.refCount > 1) {\n return;\n }\n\n if (!controllerRegistry.has(entry.context.nodeId)) {\n controllerRegistry.set(entry.context.nodeId, entry);\n }\n entry.connectedRelease = entry.context.feature.connect();\n entry.runtimeUnsubscribe = entry.context.feature.runtimeStore.subscribe(\n () => {\n reconcileBrowserNodeControllerState(entry, {\n allowAutoActivate: true,\n notifyListeners: true\n });\n }\n );\n reconcileBrowserNodeControllerState(entry, {\n allowAutoActivate: true,\n notifyListeners: true\n });\n },\n setDraftUrl(nextUrl) {\n if (entry.state.draftUrl === nextUrl) {\n return;\n }\n\n entry.state = {\n ...entry.state,\n draftUrl: nextUrl\n };\n notifyBrowserNodeControllerListeners(entry);\n },\n subscribe(listener) {\n entry.listeners.add(listener);\n return () => {\n entry.listeners.delete(listener);\n };\n },\n async submitDraftUrl() {\n const resolved = entry.context.feature.resolveAddressInput(\n entry.state.draftUrl\n );\n if (!resolved.url) {\n return;\n }\n\n if (entry.state.draftUrl !== resolved.url) {\n entry.state = {\n ...entry.state,\n draftUrl: resolved.url\n };\n notifyBrowserNodeControllerListeners(entry);\n }\n\n await entry.context.feature.hostApi.navigate({\n nodeId: entry.context.nodeId,\n url: resolved.url\n });\n }\n };\n\n return entry;\n}\n\nfunction notifyBrowserNodeControllerListeners(\n entry: BrowserNodeControllerEntry\n): void {\n for (const listener of entry.listeners) {\n listener();\n }\n}\n\nfunction resolveBrowserNodeDisplayUrl(\n runtime: BrowserNodeRuntimeState,\n defaultUrl: string\n): string {\n const resolvedRuntimeUrl = runtime.url?.trim() ?? \"\";\n return resolvedRuntimeUrl.length > 0 ? resolvedRuntimeUrl : defaultUrl;\n}\n\nfunction reconcileBrowserNodeControllerState(\n entry: BrowserNodeControllerEntry,\n options: {\n allowAutoActivate: boolean;\n notifyListeners: boolean;\n }\n): void {\n const runtime = entry.context.feature.runtimeStore.getNodeState(\n entry.context.nodeId\n );\n const displayUrl = resolveBrowserNodeDisplayUrl(\n runtime,\n entry.context.defaultUrl\n );\n const nextDraftUrl =\n displayUrl !== entry.state.displayUrl ? displayUrl : entry.state.draftUrl;\n\n const changed =\n entry.state.runtime !== runtime ||\n entry.state.displayUrl !== displayUrl ||\n entry.state.draftUrl !== nextDraftUrl;\n\n if (changed) {\n entry.state = {\n displayUrl,\n draftUrl: nextDraftUrl,\n runtime\n };\n if (options.notifyListeners) {\n notifyBrowserNodeControllerListeners(entry);\n }\n }\n\n if (options.allowAutoActivate) {\n void maybeActivateColdBrowserNode(entry).catch(() => undefined);\n }\n}\n\nasync function maybeActivateColdBrowserNode(\n entry: BrowserNodeControllerEntry\n): Promise<void> {\n const { defaultUrl, feature, nodeId, profileId, sessionMode } = entry.context;\n const trimmedUrl = defaultUrl.trim();\n if (\n trimmedUrl.length === 0 ||\n entry.state.runtime.lifecycle !== \"cold\" ||\n entry.state.runtime.isLoading ||\n entry.state.runtime.error !== null ||\n entry.pendingColdActivationUrl === trimmedUrl ||\n entry.lastColdActivationUrl === trimmedUrl\n ) {\n return;\n }\n\n entry.pendingColdActivationUrl = trimmedUrl;\n try {\n await feature.hostApi.activate({\n nodeId,\n profileId,\n sessionMode,\n url: trimmedUrl\n });\n entry.lastColdActivationUrl = trimmedUrl;\n } finally {\n if (entry.pendingColdActivationUrl === trimmedUrl) {\n entry.pendingColdActivationUrl = null;\n }\n }\n}\n","import { useCallback, useEffect, useMemo } from \"react\";\nimport { useExternalStoreSnapshot } from \"@nextop-os/ui-react-hooks\";\nimport {\n acquireBrowserNodeWebviewController,\n type BrowserNodeWebviewControllerState\n} from \"../core/webviewController.ts\";\nimport type { BrowserNodeFeature } from \"../core/feature.ts\";\nimport type {\n BrowserNodeLifecycle,\n BrowserNodeSessionMode\n} from \"../core/types.ts\";\nimport type { BrowserNodeWebviewTag } from \"./webviewTag.ts\";\n\nexport function useBrowserNodeWebview({\n feature,\n initialUrl,\n lifecycle,\n nodeId,\n onGuestInteraction,\n profileId,\n sessionMode\n}: {\n feature: BrowserNodeFeature;\n initialUrl: string;\n lifecycle: BrowserNodeLifecycle;\n nodeId: string;\n onGuestInteraction?: () => void;\n profileId: string | null;\n sessionMode: BrowserNodeSessionMode;\n}): {\n shouldRenderWebview: boolean;\n setWebviewRef: (element: BrowserNodeWebviewTag | null) => void;\n webviewKey: string;\n webviewPartition: string;\n webviewSrc: string;\n} {\n const controller = useMemo(\n () =>\n acquireBrowserNodeWebviewController({\n feature,\n initialUrl,\n lifecycle,\n nodeId,\n onGuestInteraction,\n profileId,\n sessionMode\n }),\n [\n feature,\n initialUrl,\n lifecycle,\n nodeId,\n onGuestInteraction,\n profileId,\n sessionMode\n ]\n );\n\n useEffect(() => {\n controller.retain();\n return () => {\n controller.release();\n };\n }, [controller]);\n\n useEffect(() => {\n controller.sync();\n }, [\n controller,\n initialUrl,\n lifecycle,\n nodeId,\n onGuestInteraction,\n profileId,\n sessionMode\n ]);\n const state = useExternalStoreSnapshot<BrowserNodeWebviewControllerState>({\n getSnapshot() {\n return controller.getState();\n },\n subscribe(listener) {\n return controller.subscribe(listener);\n }\n });\n\n const setWebviewRef = useCallback(\n (element: BrowserNodeWebviewTag | null) => {\n controller.setWebview(element);\n },\n [controller]\n );\n\n return {\n shouldRenderWebview: state.shouldRenderWebview,\n setWebviewRef,\n webviewKey: state.webviewKey,\n webviewPartition: state.webviewPartition,\n webviewSrc: state.webviewSrc\n };\n}\n","import type { BrowserNodeFeature } from \"./feature.ts\";\nimport { resolveBrowserSessionPartition } from \"./session.ts\";\nimport type { BrowserNodeLifecycle, BrowserNodeSessionMode } from \"./types.ts\";\nimport type { BrowserNodeWebviewTag } from \"../react/webviewTag.ts\";\n\nconst browserGuestUnregisterGraceMs = 250;\n\nexport interface BrowserNodeWebviewControllerState {\n shouldRenderWebview: boolean;\n webviewKey: string;\n webviewPartition: string;\n webviewSrc: string;\n}\n\nexport interface BrowserNodeWebviewController {\n getState(): BrowserNodeWebviewControllerState;\n release(): void;\n retain(): void;\n setWebview(element: BrowserNodeWebviewTag | null): void;\n sync(): void;\n subscribe(listener: () => void): () => void;\n}\n\ninterface BrowserNodeWebviewControllerContext {\n feature: BrowserNodeFeature;\n initialUrl: string;\n lifecycle: BrowserNodeLifecycle;\n nodeId: string;\n onGuestInteraction?: () => void;\n profileId: string | null;\n sessionMode: BrowserNodeSessionMode;\n}\n\ninterface BrowserNodeWebviewControllerEntry {\n attachedListeners: Array<{\n event: string;\n listener: EventListener;\n }>;\n context: BrowserNodeWebviewControllerContext;\n controller: BrowserNodeWebviewController;\n listeners: Set<() => void>;\n refCount: number;\n registeredGuestId: number | null;\n registeringGuestId: number | null;\n state: BrowserNodeWebviewControllerState;\n webview: BrowserNodeWebviewTag | null;\n}\n\nconst webviewControllerRegistry = new Map<\n string,\n BrowserNodeWebviewControllerEntry\n>();\nconst pendingGuestIdsByNodeId = new Map<string, number>();\nconst pendingUnregisterTimersByNodeId = new Map<\n string,\n ReturnType<typeof globalThis.setTimeout>\n>();\n\nexport function acquireBrowserNodeWebviewController(input: {\n feature: BrowserNodeFeature;\n initialUrl: string;\n lifecycle: BrowserNodeLifecycle;\n nodeId: string;\n onGuestInteraction?: () => void;\n profileId: string | null;\n sessionMode: BrowserNodeSessionMode;\n}): BrowserNodeWebviewController {\n const existing = webviewControllerRegistry.get(input.nodeId);\n const entry =\n existing ??\n createBrowserNodeWebviewControllerEntry({\n feature: input.feature,\n initialUrl: input.initialUrl,\n lifecycle: input.lifecycle,\n nodeId: input.nodeId,\n onGuestInteraction: input.onGuestInteraction,\n profileId: input.profileId,\n sessionMode: input.sessionMode\n });\n\n entry.context = {\n feature: input.feature,\n initialUrl: input.initialUrl,\n lifecycle: input.lifecycle,\n nodeId: input.nodeId,\n onGuestInteraction: input.onGuestInteraction,\n profileId: input.profileId,\n sessionMode: input.sessionMode\n };\n if (!existing) {\n webviewControllerRegistry.set(input.nodeId, entry);\n }\n return entry.controller;\n}\n\nfunction createBrowserNodeWebviewControllerEntry(\n context: BrowserNodeWebviewControllerContext\n): BrowserNodeWebviewControllerEntry {\n const state = resolveBrowserNodeWebviewControllerState(context);\n const entry = {\n attachedListeners: [],\n context,\n controller: null as unknown as BrowserNodeWebviewController,\n listeners: new Set(),\n refCount: 0,\n registeredGuestId: null,\n registeringGuestId: null,\n state,\n webview: null\n } as BrowserNodeWebviewControllerEntry;\n\n entry.controller = {\n getState() {\n return entry.state;\n },\n release() {\n entry.refCount = Math.max(0, entry.refCount - 1);\n if (entry.refCount > 0) {\n return;\n }\n scheduleBrowserNodeGuestUnregister(entry);\n detachBrowserNodeWebview(entry);\n webviewControllerRegistry.delete(entry.context.nodeId);\n },\n retain() {\n entry.refCount += 1;\n if (entry.refCount > 1) {\n return;\n }\n reconcileBrowserNodeWebviewControllerState(entry, {\n allowHostEffects: true,\n notifyListeners: true,\n rebindWebview: true\n });\n },\n setWebview(element) {\n if (entry.webview === element) {\n return;\n }\n detachBrowserNodeWebview(entry);\n entry.webview = element;\n attachBrowserNodeWebview(entry);\n },\n sync() {\n reconcileBrowserNodeWebviewControllerState(entry, {\n allowHostEffects: true,\n notifyListeners: true,\n rebindWebview: true\n });\n },\n subscribe(listener) {\n entry.listeners.add(listener);\n return () => {\n entry.listeners.delete(listener);\n };\n }\n };\n\n return entry;\n}\n\nfunction resolveBrowserNodeWebviewControllerState(\n context: BrowserNodeWebviewControllerContext\n): BrowserNodeWebviewControllerState {\n const webviewPartition = resolveBrowserSessionPartition({\n profileId: context.profileId,\n sessionMode: context.sessionMode\n });\n return {\n shouldRenderWebview: context.lifecycle !== \"cold\",\n webviewKey: `${context.nodeId}:${webviewPartition}`,\n webviewPartition,\n webviewSrc: resolveBrowserWebviewSrc(context.initialUrl)\n };\n}\n\nfunction reconcileBrowserNodeWebviewControllerState(\n entry: BrowserNodeWebviewControllerEntry,\n options: {\n allowHostEffects: boolean;\n notifyListeners: boolean;\n rebindWebview: boolean;\n }\n): void {\n const nextState = resolveBrowserNodeWebviewControllerState(entry.context);\n const changed =\n entry.state.shouldRenderWebview !== nextState.shouldRenderWebview ||\n entry.state.webviewKey !== nextState.webviewKey ||\n entry.state.webviewPartition !== nextState.webviewPartition ||\n entry.state.webviewSrc !== nextState.webviewSrc;\n\n if (options.allowHostEffects) {\n if (entry.context.lifecycle === \"cold\") {\n scheduleBrowserNodeGuestUnregister(entry);\n } else {\n clearPendingBrowserNodeGuestUnregister(entry.context.nodeId);\n void entry.context.feature.hostApi\n .prepareSession({\n nodeId: entry.context.nodeId,\n profileId: entry.context.profileId,\n sessionMode: entry.context.sessionMode\n })\n .catch(() => undefined);\n }\n }\n\n if (!changed && !options.rebindWebview) {\n return;\n }\n\n if (changed) {\n entry.state = nextState;\n }\n detachBrowserNodeWebview(entry);\n attachBrowserNodeWebview(entry);\n if (changed && options.notifyListeners) {\n notifyBrowserNodeWebviewControllerListeners(entry);\n }\n}\n\nfunction resolveBrowserWebviewSrc(url: string): string {\n const trimmed = url.trim();\n return trimmed.length > 0 ? trimmed : \"about:blank\";\n}\n\nfunction notifyBrowserNodeWebviewControllerListeners(\n entry: BrowserNodeWebviewControllerEntry\n): void {\n for (const listener of entry.listeners) {\n listener();\n }\n}\n\nfunction clearPendingBrowserNodeGuestUnregister(nodeId: string): void {\n const timerId = pendingUnregisterTimersByNodeId.get(nodeId);\n if (timerId !== undefined) {\n globalThis.clearTimeout(timerId);\n pendingUnregisterTimersByNodeId.delete(nodeId);\n }\n pendingGuestIdsByNodeId.delete(nodeId);\n}\n\nfunction scheduleBrowserNodeGuestUnregister(\n entry: BrowserNodeWebviewControllerEntry\n): void {\n const guestId = entry.registeredGuestId;\n const nodeId = entry.context.nodeId;\n entry.registeringGuestId = null;\n if (guestId === null) {\n clearPendingBrowserNodeGuestUnregister(nodeId);\n return;\n }\n\n entry.registeredGuestId = null;\n clearPendingBrowserNodeGuestUnregister(nodeId);\n pendingGuestIdsByNodeId.set(nodeId, guestId);\n const timerId = globalThis.setTimeout(() => {\n pendingUnregisterTimersByNodeId.delete(nodeId);\n const pendingGuestId = pendingGuestIdsByNodeId.get(nodeId);\n pendingGuestIdsByNodeId.delete(nodeId);\n if (\n typeof pendingGuestId !== \"number\" ||\n !Number.isFinite(pendingGuestId)\n ) {\n return;\n }\n\n void entry.context.feature.hostApi\n .unregisterGuest({\n nodeId: entry.context.nodeId,\n webContentsId: pendingGuestId\n })\n .catch(() => undefined);\n }, browserGuestUnregisterGraceMs);\n pendingUnregisterTimersByNodeId.set(nodeId, timerId);\n}\n\nfunction detachBrowserNodeWebview(\n entry: BrowserNodeWebviewControllerEntry\n): void {\n if (!entry.webview) {\n entry.attachedListeners = [];\n return;\n }\n for (const record of entry.attachedListeners) {\n entry.webview.removeEventListener(record.event, record.listener);\n }\n entry.attachedListeners = [];\n}\n\nfunction attachBrowserNodeWebview(\n entry: BrowserNodeWebviewControllerEntry\n): void {\n const webview = entry.webview;\n if (!webview || !entry.state.shouldRenderWebview) {\n return;\n }\n\n const registerGuest = async (): Promise<void> => {\n const guestId = webview.getWebContentsId?.();\n if (\n typeof guestId !== \"number\" ||\n !Number.isFinite(guestId) ||\n guestId <= 0 ||\n entry.registeredGuestId === guestId ||\n entry.registeringGuestId === guestId\n ) {\n return;\n }\n\n clearPendingBrowserNodeGuestUnregister(entry.context.nodeId);\n entry.registeringGuestId = guestId;\n try {\n await entry.context.feature.hostApi.registerGuest({\n nodeId: entry.context.nodeId,\n profileId: entry.context.profileId,\n sessionMode: entry.context.sessionMode,\n webContentsId: guestId\n });\n entry.registeredGuestId = guestId;\n } finally {\n if (entry.registeringGuestId === guestId) {\n entry.registeringGuestId = null;\n }\n }\n };\n\n const handleDidAttach: EventListener = () => {\n void registerGuest().catch(() => undefined);\n };\n const handleDomReady: EventListener = () => {\n void registerGuest().catch(() => undefined);\n };\n const handleGuestInteraction: EventListener = () => {\n entry.context.onGuestInteraction?.();\n };\n\n const records = [\n { event: \"did-attach\", listener: handleDidAttach },\n { event: \"dom-ready\", listener: handleDomReady },\n { event: \"focus\", listener: handleGuestInteraction },\n { event: \"ipc-message\", listener: handleGuestInteraction }\n ];\n for (const record of records) {\n webview.addEventListener(record.event, record.listener);\n }\n entry.attachedListeners = records;\n}\n"],"mappings":"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","names":["useEffect","useMemo","useExternalStoreSnapshot","useMemo","useEffect","useExternalStoreSnapshot"]}