@nextop-os/browser-node 0.0.23 → 0.0.25

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.
package/README.md CHANGED
@@ -15,6 +15,7 @@ configure a package-owned loopback preview proxy through
15
15
 
16
16
  For Workbench hosts, the package also exposes a dock helper through
17
17
  `@nextop-os/browser-node/workbench`. `createBrowserDockEntry(...)` wires the
18
- default Browser dock icon and label, matches Browser nodes back to the dock
19
- entry, and restores popup title, URL subtitle, and preview capture from the
20
- Browser runtime state.
18
+ dock label, matches Browser nodes back to the dock entry, and restores popup
19
+ title, URL subtitle, and preview capture from the Browser runtime state.
20
+ Hosts that want the package-owned default dock visual can import it explicitly
21
+ from `@nextop-os/browser-node/assets/workspace-dock-website.png`.
@@ -0,0 +1,3 @@
1
+ declare const src: string;
2
+
3
+ export default src;
@@ -13,6 +13,7 @@ import {
13
13
  RefreshIcon,
14
14
  cn
15
15
  } from "@nextop-os/ui-system";
16
+ import { useState } from "react";
16
17
 
17
18
  // src/react/useBrowserNodeController.ts
18
19
  import { useEffect, useMemo } from "react";
@@ -703,6 +704,11 @@ function BrowserNodeHeader({
703
704
  onSubmitUrl,
704
705
  withBorder = true
705
706
  }) {
707
+ const [reloadAnimationKey, setReloadAnimationKey] = useState(0);
708
+ const handleReload = () => {
709
+ setReloadAnimationKey((currentKey) => currentKey + 1);
710
+ onReload();
711
+ };
706
712
  return /* @__PURE__ */ jsxs(
707
713
  "div",
708
714
  {
@@ -727,7 +733,7 @@ function BrowserNodeHeader({
727
733
  disabled: !canGoBack,
728
734
  label: feature.i18n.t("actions.back"),
729
735
  onClick: onGoBack,
730
- children: /* @__PURE__ */ jsx(ArrowLeftIcon, { className: "size-4" })
736
+ children: /* @__PURE__ */ jsx(ArrowLeftIcon, { className: "size-[15px]" })
731
737
  }
732
738
  ),
733
739
  /* @__PURE__ */ jsx(
@@ -736,15 +742,24 @@ function BrowserNodeHeader({
736
742
  disabled: !canGoForward,
737
743
  label: feature.i18n.t("actions.forward"),
738
744
  onClick: onGoForward,
739
- children: /* @__PURE__ */ jsx(ArrowRightIcon, { className: "size-4" })
745
+ children: /* @__PURE__ */ jsx(ArrowRightIcon, { className: "size-[15px]" })
740
746
  }
741
747
  ),
742
748
  /* @__PURE__ */ jsx(
743
749
  BrowserNodeHeaderButton,
744
750
  {
745
751
  label: feature.i18n.t("actions.reload"),
746
- onClick: onReload,
747
- children: /* @__PURE__ */ jsx(RefreshIcon, { className: "size-4" })
752
+ onClick: handleReload,
753
+ children: /* @__PURE__ */ jsx(
754
+ RefreshIcon,
755
+ {
756
+ className: cn(
757
+ "size-[15px]",
758
+ reloadAnimationKey > 0 && "motion-safe:animate-[spin_520ms_cubic-bezier(0.4,0,0.2,1)_1_reverse]"
759
+ )
760
+ },
761
+ reloadAnimationKey
762
+ )
748
763
  }
749
764
  )
750
765
  ] }),
@@ -773,7 +788,7 @@ function BrowserNodeHeader({
773
788
  Input,
774
789
  {
775
790
  "aria-label": feature.i18n.t("addressLabel"),
776
- className: "pl-8 pr-8 focus-visible:ring-0 focus-visible:ring-offset-0",
791
+ className: "pl-8 pr-8 focus-visible:border-input focus-visible:ring-0 focus-visible:ring-offset-0",
777
792
  placeholder: feature.i18n.t("addressPlaceholder"),
778
793
  size: "sm",
779
794
  value: draftUrl,
@@ -836,7 +851,7 @@ function BrowserNodeHeaderButton({
836
851
  "aria-label": label,
837
852
  className: "rounded-md",
838
853
  disabled,
839
- size: "icon",
854
+ size: "icon-sm",
840
855
  title: label,
841
856
  type: "button",
842
857
  variant: "chrome",
@@ -851,4 +866,4 @@ export {
851
866
  BrowserNodeWorkbenchHeader,
852
867
  BrowserNodeHeader
853
868
  };
854
- //# sourceMappingURL=chunk-3ERRS74C.js.map
869
+ //# sourceMappingURL=chunk-AGQVWZYP.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 { useState } from \"react\";\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 const [reloadAnimationKey, setReloadAnimationKey] = useState(0);\n\n const handleReload = (): void => {\n setReloadAnimationKey((currentKey) => currentKey + 1);\n onReload();\n };\n\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-[15px]\" />\n </BrowserNodeHeaderButton>\n <BrowserNodeHeaderButton\n disabled={!canGoForward}\n label={feature.i18n.t(\"actions.forward\")}\n onClick={onGoForward}\n >\n <ArrowRightIcon className=\"size-[15px]\" />\n </BrowserNodeHeaderButton>\n <BrowserNodeHeaderButton\n label={feature.i18n.t(\"actions.reload\")}\n onClick={handleReload}\n >\n <RefreshIcon\n key={reloadAnimationKey}\n className={cn(\n \"size-[15px]\",\n reloadAnimationKey > 0 &&\n \"motion-safe:animate-[spin_520ms_cubic-bezier(0.4,0,0.2,1)_1_reverse]\"\n )}\n />\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:border-input 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-sm\"\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-3ERRS74C.js";
4
+ } from "../chunk-AGQVWZYP.js";
5
5
  import "../chunk-OTK5YBCK.js";
6
6
  export {
7
7
  BrowserNode,
@@ -44,7 +44,8 @@ interface CreateBrowserWorkbenchContributionInput {
44
44
  declare const defaultBrowserNodeTypeId = "browser";
45
45
  declare function createBrowserNodeDefinition({ defaultUrl, feature, frame, typeId }: CreateBrowserNodeDefinitionInput): WorkbenchHostNodeDefinition<BrowserNodeExternalState>;
46
46
  declare function createBrowserDockEntry(input: CreateBrowserDockEntryInput): WorkbenchHostDockEntry;
47
+ declare function createBrowserDockIconImage(src: string): ReactNode;
47
48
  declare function createBrowserWorkbenchLaunchHandler({ browserInstancePrefix, typeId }?: CreateBrowserWorkbenchLaunchHandlerInput): (request: WorkbenchHostLaunchRequest) => WorkbenchHostLaunchResult | null;
48
49
  declare function createBrowserWorkbenchContribution({ contributionId, defaultUrl, dockEntry, externalStateSource, feature, launch, node, typeId }: CreateBrowserWorkbenchContributionInput): WorkbenchContribution;
49
50
 
50
- export { type BrowserNodeExternalState, type BrowserNodeOpenUrlActivationPayload, type CreateBrowserDockEntryInput, type CreateBrowserNodeDefinitionInput, type CreateBrowserWorkbenchContributionInput, type CreateBrowserWorkbenchLaunchHandlerInput, createBrowserDockEntry, createBrowserNodeDefinition, createBrowserWorkbenchContribution, createBrowserWorkbenchLaunchHandler, defaultBrowserNodeTypeId };
51
+ export { type BrowserNodeExternalState, type BrowserNodeOpenUrlActivationPayload, type CreateBrowserDockEntryInput, type CreateBrowserNodeDefinitionInput, type CreateBrowserWorkbenchContributionInput, type CreateBrowserWorkbenchLaunchHandlerInput, createBrowserDockEntry, createBrowserDockIconImage, createBrowserNodeDefinition, createBrowserWorkbenchContribution, createBrowserWorkbenchLaunchHandler, defaultBrowserNodeTypeId };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  BrowserNode,
3
3
  BrowserNodeWorkbenchHeader
4
- } from "../chunk-3ERRS74C.js";
4
+ } from "../chunk-AGQVWZYP.js";
5
5
  import "../chunk-OTK5YBCK.js";
6
6
 
7
7
  // src/workbench/index.ts
@@ -13,10 +13,6 @@ var defaultBrowserNodeFrame = {
13
13
  y: 120
14
14
  };
15
15
  var defaultBrowserNodeTypeId = "browser";
16
- var defaultBrowserNodeDockIconUrl = new URL(
17
- "../assets/workspace-dock-website.png",
18
- import.meta.url
19
- ).href;
20
16
  function createBrowserNodeDefinition({
21
17
  defaultUrl,
22
18
  feature,
@@ -75,7 +71,7 @@ function createBrowserNodeDefinition({
75
71
  function createBrowserDockEntry(input) {
76
72
  return {
77
73
  capturePopupItemPreview: ({ node }) => input.feature.hostApi.capturePreview?.({ nodeId: node.id }) ?? null,
78
- icon: input.dockIcon ?? createElement(BrowserNodeDockIcon),
74
+ icon: input.dockIcon ?? null,
79
75
  id: input.id ?? defaultBrowserNodeTypeId,
80
76
  label: input.feature.i18n.t("dockLabel"),
81
77
  launchBehavior: "enabled",
@@ -93,6 +89,15 @@ function createBrowserDockEntry(input) {
93
89
  visibility: "always"
94
90
  };
95
91
  }
92
+ function createBrowserDockIconImage(src) {
93
+ return createElement("img", {
94
+ alt: "",
95
+ "aria-hidden": "true",
96
+ "data-browser-node-dock-icon": "true",
97
+ draggable: false,
98
+ src
99
+ });
100
+ }
96
101
  function createBrowserWorkbenchLaunchHandler({
97
102
  browserInstancePrefix,
98
103
  typeId = defaultBrowserNodeTypeId
@@ -157,15 +162,6 @@ function normalizeBrowserNodeInitialUrl(value) {
157
162
  const trimmed = value?.trim() ?? "";
158
163
  return trimmed.length > 0 ? trimmed : null;
159
164
  }
160
- function BrowserNodeDockIcon() {
161
- return createElement("img", {
162
- alt: "",
163
- "aria-hidden": "true",
164
- "data-browser-node-dock-icon": "true",
165
- draggable: false,
166
- src: defaultBrowserNodeDockIconUrl
167
- });
168
- }
169
165
  function readBrowserOpenUrlActivationPayload(activation) {
170
166
  if (activation?.type !== "open-url" || !activation.payload || typeof activation.payload !== "object") {
171
167
  return null;
@@ -178,6 +174,7 @@ function readBrowserOpenUrlActivationPayload(activation) {
178
174
  }
179
175
  export {
180
176
  createBrowserDockEntry,
177
+ createBrowserDockIconImage,
181
178
  createBrowserNodeDefinition,
182
179
  createBrowserWorkbenchContribution,
183
180
  createBrowserWorkbenchLaunchHandler,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/workbench/index.ts"],"sourcesContent":["import { createElement, type ReactNode } from \"react\";\nimport type {\n WorkbenchContribution,\n WorkbenchHostActivation,\n WorkbenchHostDockEntry,\n WorkbenchHostExternalStateSource,\n WorkbenchFrame,\n WorkbenchHostLaunchRequest,\n WorkbenchHostLaunchResult,\n WorkbenchHostNodeDefinition\n} from \"@nextop-os/workbench-surface\";\nimport type { BrowserNodeFeature } from \"../core/feature.ts\";\nimport {\n BrowserNode,\n BrowserNodeWorkbenchHeader\n} from \"../react/BrowserNode.tsx\";\n\nexport interface BrowserNodeOpenUrlActivationPayload {\n title?: string;\n url: string;\n}\n\nexport interface BrowserNodeExternalState {\n title?: string | null;\n url?: string | null;\n}\n\nexport interface CreateBrowserNodeDefinitionInput {\n defaultUrl: string;\n dockIcon?: ReactNode;\n feature: BrowserNodeFeature;\n frame?: WorkbenchFrame;\n typeId?: string;\n}\n\nexport interface CreateBrowserDockEntryInput {\n dockIcon?: ReactNode;\n feature: BrowserNodeFeature;\n id?: string;\n order?: number;\n sectionId?: string;\n typeId?: string;\n}\n\nexport interface CreateBrowserWorkbenchLaunchHandlerInput {\n browserInstancePrefix?: string;\n typeId?: string;\n}\n\nexport interface CreateBrowserWorkbenchContributionInput {\n contributionId?: string;\n defaultUrl: string;\n dockEntry?: Omit<CreateBrowserDockEntryInput, \"feature\">;\n externalStateSource?: WorkbenchHostExternalStateSource<\n BrowserNodeExternalState | null,\n unknown\n >;\n feature: BrowserNodeFeature;\n launch?: CreateBrowserWorkbenchLaunchHandlerInput;\n node?: Omit<CreateBrowserNodeDefinitionInput, \"defaultUrl\" | \"feature\">;\n typeId?: string;\n}\n\nconst defaultBrowserNodeFrame: WorkbenchFrame = {\n height: 560,\n width: 920,\n x: 220,\n y: 120\n};\n\nexport const defaultBrowserNodeTypeId = \"browser\";\nconst defaultBrowserNodeDockIconUrl = new URL(\n \"../assets/workspace-dock-website.png\",\n import.meta.url\n).href;\n\nexport function createBrowserNodeDefinition({\n defaultUrl,\n feature,\n frame = defaultBrowserNodeFrame,\n typeId = defaultBrowserNodeTypeId\n}: CreateBrowserNodeDefinitionInput): WorkbenchHostNodeDefinition<BrowserNodeExternalState> {\n return {\n frame,\n instance: {\n mode: \"multi\"\n },\n renderBody: (context) =>\n createElement(BrowserNode, {\n defaultUrl: resolveBrowserNodeInitialUrl({\n activation: context.activation,\n defaultUrl,\n externalNodeState: context.externalNodeState\n }),\n feature,\n nodeId: context.node.id,\n onFocusRequest: context.isFocused ? undefined : () => context.focus(),\n showHeader: false\n }),\n renderHeader: ({\n defaultActions,\n activation,\n dragHandleProps,\n externalNodeState,\n isFocused,\n node,\n windowActions\n }) =>\n createElement(BrowserNodeWorkbenchHeader, {\n defaultActions,\n defaultUrl: resolveBrowserNodeInitialUrl({\n activation,\n defaultUrl,\n externalNodeState\n }),\n dragHandleProps,\n feature,\n nodeId: node.id,\n onCloseRequest: () => {\n void feature.hostApi\n .close({ nodeId: node.id })\n .catch(() => undefined);\n },\n onFocusRequest: isFocused ? undefined : () => windowActions.focus()\n }),\n title: feature.i18n.t(\"title\"),\n typeId,\n window: {\n closable: true,\n defaultOpen: false,\n minimizable: true,\n restoreOnLoad: true\n }\n };\n}\n\nexport function createBrowserDockEntry(\n input: CreateBrowserDockEntryInput\n): WorkbenchHostDockEntry {\n return {\n capturePopupItemPreview: ({ node }) =>\n input.feature.hostApi.capturePreview?.({ nodeId: node.id }) ?? null,\n icon: input.dockIcon ?? createElement(BrowserNodeDockIcon),\n id: input.id ?? defaultBrowserNodeTypeId,\n label: input.feature.i18n.t(\"dockLabel\"),\n launchBehavior: \"enabled\",\n matchNode: (node) =>\n node.data.typeId === (input.typeId ?? defaultBrowserNodeTypeId),\n order: input.order,\n resolvePopupItem: ({ node }) => {\n const runtime = input.feature.runtimeStore.getNodeState(node.id);\n return {\n subtitle: runtime.url?.trim() || node.data.instanceId,\n title: runtime.title?.trim() || node.title\n };\n },\n sectionId: input.sectionId,\n typeId: input.typeId ?? defaultBrowserNodeTypeId,\n visibility: \"always\"\n };\n}\n\nexport function createBrowserWorkbenchLaunchHandler({\n browserInstancePrefix,\n typeId = defaultBrowserNodeTypeId\n}: CreateBrowserWorkbenchLaunchHandlerInput = {}): (\n request: WorkbenchHostLaunchRequest\n) => WorkbenchHostLaunchResult | null {\n let nextBrowserInstanceSequence = 1;\n const instancePrefix =\n browserInstancePrefix ?? globalThis.crypto?.randomUUID?.() ?? typeId;\n\n return (request) => {\n if (request.typeId !== typeId) {\n return null;\n }\n\n const instanceId = `${typeId}-${instancePrefix}-${nextBrowserInstanceSequence++}`;\n return {\n dockEntryId: request.dockEntryId ?? typeId,\n framePolicy: \"cascade\",\n instanceId,\n typeId\n };\n };\n}\n\nexport function createBrowserWorkbenchContribution({\n contributionId,\n defaultUrl,\n dockEntry,\n externalStateSource,\n feature,\n launch,\n node,\n typeId = defaultBrowserNodeTypeId\n}: CreateBrowserWorkbenchContributionInput): WorkbenchContribution {\n return {\n dockEntries: [\n createBrowserDockEntry({\n ...dockEntry,\n feature,\n typeId\n })\n ],\n externalStateSource,\n id: contributionId ?? typeId,\n nodes: [\n createBrowserNodeDefinition({\n ...node,\n defaultUrl,\n feature,\n typeId\n })\n ],\n onLaunchRequest: createBrowserWorkbenchLaunchHandler({\n ...launch,\n typeId\n })\n };\n}\n\nfunction resolveBrowserNodeInitialUrl({\n activation,\n defaultUrl,\n externalNodeState\n}: {\n activation: WorkbenchHostActivation | null;\n defaultUrl: string;\n externalNodeState?: BrowserNodeExternalState | null;\n}): string {\n return (\n readBrowserOpenUrlActivationPayload(activation)?.url ??\n normalizeBrowserNodeInitialUrl(externalNodeState?.url) ??\n defaultUrl\n );\n}\n\nfunction normalizeBrowserNodeInitialUrl(\n value: string | null | undefined\n): string | null {\n const trimmed = value?.trim() ?? \"\";\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction BrowserNodeDockIcon() {\n return createElement(\"img\", {\n alt: \"\",\n \"aria-hidden\": \"true\",\n \"data-browser-node-dock-icon\": \"true\",\n draggable: false,\n src: defaultBrowserNodeDockIconUrl\n });\n}\n\nfunction readBrowserOpenUrlActivationPayload(\n activation: WorkbenchHostActivation | null\n): BrowserNodeOpenUrlActivationPayload | null {\n if (\n activation?.type !== \"open-url\" ||\n !activation.payload ||\n typeof activation.payload !== \"object\"\n ) {\n return null;\n }\n\n const typed =\n activation.payload as Partial<BrowserNodeOpenUrlActivationPayload>;\n return typeof typed.url === \"string\"\n ? {\n title: typeof typed.title === \"string\" ? typed.title : undefined,\n url: typed.url\n }\n : null;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/workbench/index.ts"],"sourcesContent":["import { createElement, type ReactNode } from \"react\";\nimport type {\n WorkbenchContribution,\n WorkbenchHostActivation,\n WorkbenchHostDockEntry,\n WorkbenchHostExternalStateSource,\n WorkbenchFrame,\n WorkbenchHostLaunchRequest,\n WorkbenchHostLaunchResult,\n WorkbenchHostNodeDefinition\n} from \"@nextop-os/workbench-surface\";\nimport type { BrowserNodeFeature } from \"../core/feature.ts\";\nimport {\n BrowserNode,\n BrowserNodeWorkbenchHeader\n} from \"../react/BrowserNode.tsx\";\n\nexport interface BrowserNodeOpenUrlActivationPayload {\n title?: string;\n url: string;\n}\n\nexport interface BrowserNodeExternalState {\n title?: string | null;\n url?: string | null;\n}\n\nexport interface CreateBrowserNodeDefinitionInput {\n defaultUrl: string;\n dockIcon?: ReactNode;\n feature: BrowserNodeFeature;\n frame?: WorkbenchFrame;\n typeId?: string;\n}\n\nexport interface CreateBrowserDockEntryInput {\n dockIcon?: ReactNode;\n feature: BrowserNodeFeature;\n id?: string;\n order?: number;\n sectionId?: string;\n typeId?: string;\n}\n\nexport interface CreateBrowserWorkbenchLaunchHandlerInput {\n browserInstancePrefix?: string;\n typeId?: string;\n}\n\nexport interface CreateBrowserWorkbenchContributionInput {\n contributionId?: string;\n defaultUrl: string;\n dockEntry?: Omit<CreateBrowserDockEntryInput, \"feature\">;\n externalStateSource?: WorkbenchHostExternalStateSource<\n BrowserNodeExternalState | null,\n unknown\n >;\n feature: BrowserNodeFeature;\n launch?: CreateBrowserWorkbenchLaunchHandlerInput;\n node?: Omit<CreateBrowserNodeDefinitionInput, \"defaultUrl\" | \"feature\">;\n typeId?: string;\n}\n\nconst defaultBrowserNodeFrame: WorkbenchFrame = {\n height: 560,\n width: 920,\n x: 220,\n y: 120\n};\n\nexport const defaultBrowserNodeTypeId = \"browser\";\n\nexport function createBrowserNodeDefinition({\n defaultUrl,\n feature,\n frame = defaultBrowserNodeFrame,\n typeId = defaultBrowserNodeTypeId\n}: CreateBrowserNodeDefinitionInput): WorkbenchHostNodeDefinition<BrowserNodeExternalState> {\n return {\n frame,\n instance: {\n mode: \"multi\"\n },\n renderBody: (context) =>\n createElement(BrowserNode, {\n defaultUrl: resolveBrowserNodeInitialUrl({\n activation: context.activation,\n defaultUrl,\n externalNodeState: context.externalNodeState\n }),\n feature,\n nodeId: context.node.id,\n onFocusRequest: context.isFocused ? undefined : () => context.focus(),\n showHeader: false\n }),\n renderHeader: ({\n defaultActions,\n activation,\n dragHandleProps,\n externalNodeState,\n isFocused,\n node,\n windowActions\n }) =>\n createElement(BrowserNodeWorkbenchHeader, {\n defaultActions,\n defaultUrl: resolveBrowserNodeInitialUrl({\n activation,\n defaultUrl,\n externalNodeState\n }),\n dragHandleProps,\n feature,\n nodeId: node.id,\n onCloseRequest: () => {\n void feature.hostApi\n .close({ nodeId: node.id })\n .catch(() => undefined);\n },\n onFocusRequest: isFocused ? undefined : () => windowActions.focus()\n }),\n title: feature.i18n.t(\"title\"),\n typeId,\n window: {\n closable: true,\n defaultOpen: false,\n minimizable: true,\n restoreOnLoad: true\n }\n };\n}\n\nexport function createBrowserDockEntry(\n input: CreateBrowserDockEntryInput\n): WorkbenchHostDockEntry {\n return {\n capturePopupItemPreview: ({ node }) =>\n input.feature.hostApi.capturePreview?.({ nodeId: node.id }) ?? null,\n icon: input.dockIcon ?? null,\n id: input.id ?? defaultBrowserNodeTypeId,\n label: input.feature.i18n.t(\"dockLabel\"),\n launchBehavior: \"enabled\",\n matchNode: (node) =>\n node.data.typeId === (input.typeId ?? defaultBrowserNodeTypeId),\n order: input.order,\n resolvePopupItem: ({ node }) => {\n const runtime = input.feature.runtimeStore.getNodeState(node.id);\n return {\n subtitle: runtime.url?.trim() || node.data.instanceId,\n title: runtime.title?.trim() || node.title\n };\n },\n sectionId: input.sectionId,\n typeId: input.typeId ?? defaultBrowserNodeTypeId,\n visibility: \"always\"\n };\n}\n\nexport function createBrowserDockIconImage(src: string): ReactNode {\n return createElement(\"img\", {\n alt: \"\",\n \"aria-hidden\": \"true\",\n \"data-browser-node-dock-icon\": \"true\",\n draggable: false,\n src\n });\n}\n\nexport function createBrowserWorkbenchLaunchHandler({\n browserInstancePrefix,\n typeId = defaultBrowserNodeTypeId\n}: CreateBrowserWorkbenchLaunchHandlerInput = {}): (\n request: WorkbenchHostLaunchRequest\n) => WorkbenchHostLaunchResult | null {\n let nextBrowserInstanceSequence = 1;\n const instancePrefix =\n browserInstancePrefix ?? globalThis.crypto?.randomUUID?.() ?? typeId;\n\n return (request) => {\n if (request.typeId !== typeId) {\n return null;\n }\n\n const instanceId = `${typeId}-${instancePrefix}-${nextBrowserInstanceSequence++}`;\n return {\n dockEntryId: request.dockEntryId ?? typeId,\n framePolicy: \"cascade\",\n instanceId,\n typeId\n };\n };\n}\n\nexport function createBrowserWorkbenchContribution({\n contributionId,\n defaultUrl,\n dockEntry,\n externalStateSource,\n feature,\n launch,\n node,\n typeId = defaultBrowserNodeTypeId\n}: CreateBrowserWorkbenchContributionInput): WorkbenchContribution {\n return {\n dockEntries: [\n createBrowserDockEntry({\n ...dockEntry,\n feature,\n typeId\n })\n ],\n externalStateSource,\n id: contributionId ?? typeId,\n nodes: [\n createBrowserNodeDefinition({\n ...node,\n defaultUrl,\n feature,\n typeId\n })\n ],\n onLaunchRequest: createBrowserWorkbenchLaunchHandler({\n ...launch,\n typeId\n })\n };\n}\n\nfunction resolveBrowserNodeInitialUrl({\n activation,\n defaultUrl,\n externalNodeState\n}: {\n activation: WorkbenchHostActivation | null;\n defaultUrl: string;\n externalNodeState?: BrowserNodeExternalState | null;\n}): string {\n return (\n readBrowserOpenUrlActivationPayload(activation)?.url ??\n normalizeBrowserNodeInitialUrl(externalNodeState?.url) ??\n defaultUrl\n );\n}\n\nfunction normalizeBrowserNodeInitialUrl(\n value: string | null | undefined\n): string | null {\n const trimmed = value?.trim() ?? \"\";\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction readBrowserOpenUrlActivationPayload(\n activation: WorkbenchHostActivation | null\n): BrowserNodeOpenUrlActivationPayload | null {\n if (\n activation?.type !== \"open-url\" ||\n !activation.payload ||\n typeof activation.payload !== \"object\"\n ) {\n return null;\n }\n\n const typed =\n activation.payload as Partial<BrowserNodeOpenUrlActivationPayload>;\n return typeof typed.url === \"string\"\n ? {\n title: typeof typed.title === \"string\" ? typed.title : undefined,\n url: typed.url\n }\n : null;\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextop-os/browser-node",
3
- "version": "0.0.23",
3
+ "version": "0.0.25",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
@@ -9,6 +9,10 @@
9
9
  "types": "./dist/index.d.ts",
10
10
  "import": "./dist/index.js"
11
11
  },
12
+ "./assets/workspace-dock-website.png": {
13
+ "types": "./dist/assets/workspace-dock-website.d.ts",
14
+ "default": "./dist/assets/workspace-dock-website.png"
15
+ },
12
16
  "./bridge": {
13
17
  "types": "./dist/bridge/index.d.ts",
14
18
  "import": "./dist/bridge/index.js"
@@ -44,10 +48,10 @@
44
48
  "directory": "packages/browser/workbench-node"
45
49
  },
46
50
  "dependencies": {
47
- "@nextop-os/ui-i18n-runtime": "0.0.23",
48
- "@nextop-os/ui-react-hooks": "0.0.23",
49
- "@nextop-os/ui-system": "0.0.23",
50
- "@nextop-os/workbench-surface": "0.0.23",
51
+ "@nextop-os/ui-i18n-runtime": "0.0.25",
52
+ "@nextop-os/ui-react-hooks": "0.0.25",
53
+ "@nextop-os/ui-system": "0.0.25",
54
+ "@nextop-os/workbench-surface": "0.0.25",
51
55
  "ws": "^8.21.0"
52
56
  },
53
57
  "devDependencies": {
@@ -78,7 +82,7 @@
78
82
  "access": "public"
79
83
  },
80
84
  "scripts": {
81
- "build": "tsup --config tsup.config.ts",
85
+ "build": "tsup --config tsup.config.ts && node ../../../tools/scripts/copy-package-assets.mjs src/assets dist/assets",
82
86
  "test": "node --test --experimental-strip-types ./src/**/*.test.ts",
83
87
  "typecheck": "tsc --noEmit -p tsconfig.json"
84
88
  }
@@ -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 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"]}