@tutti-os/browser-node 0.0.1

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/dist/index.js ADDED
@@ -0,0 +1,165 @@
1
+ import {
2
+ createBrowserNodeI18nRuntime
3
+ } from "./chunk-IS2USG4D.js";
4
+ import {
5
+ resolveBrowserAddressInput,
6
+ resolveBrowserNavigationUrl
7
+ } from "./chunk-LVVPDNEF.js";
8
+
9
+ // src/core/runtimeStore.ts
10
+ var defaultBrowserNodeRuntimeState = {
11
+ canGoBack: false,
12
+ canGoForward: false,
13
+ error: null,
14
+ isAttachedToWindow: false,
15
+ isLoading: false,
16
+ isOccluded: false,
17
+ lifecycle: "cold",
18
+ title: null,
19
+ url: null
20
+ };
21
+ var chromiumErrorPageUrlPrefix = "chrome-error://";
22
+ function isChromiumErrorPageUrl(value) {
23
+ return value?.trim().startsWith(chromiumErrorPageUrlPrefix) === true;
24
+ }
25
+ function normalizePublishedBrowserValue(value) {
26
+ const trimmed = value?.trim() ?? "";
27
+ if (trimmed.length === 0 || trimmed === "about:blank" || isChromiumErrorPageUrl(trimmed)) {
28
+ return null;
29
+ }
30
+ return trimmed;
31
+ }
32
+ function shouldClearLoadError({
33
+ isLoading,
34
+ url
35
+ }) {
36
+ return isLoading && !isChromiumErrorPageUrl(url);
37
+ }
38
+ function createBrowserNodeRuntimeStore() {
39
+ const listeners = /* @__PURE__ */ new Set();
40
+ let runtimeByNodeId = {};
41
+ const notify = () => {
42
+ for (const listener of listeners) {
43
+ listener();
44
+ }
45
+ };
46
+ return {
47
+ applyEvent(event) {
48
+ if (event.type === "open-url") {
49
+ return;
50
+ }
51
+ if (event.type === "closed") {
52
+ if (!runtimeByNodeId[event.nodeId]) {
53
+ return;
54
+ }
55
+ const next2 = { ...runtimeByNodeId };
56
+ delete next2[event.nodeId];
57
+ runtimeByNodeId = next2;
58
+ notify();
59
+ return;
60
+ }
61
+ const previous = runtimeByNodeId[event.nodeId] ?? defaultBrowserNodeRuntimeState;
62
+ const next = event.type === "state" ? resolveNextState(previous, event) : {
63
+ ...previous,
64
+ error: {
65
+ code: event.code,
66
+ diagnosticMessage: event.diagnosticMessage,
67
+ params: event.params
68
+ }
69
+ };
70
+ runtimeByNodeId = {
71
+ ...runtimeByNodeId,
72
+ [event.nodeId]: next
73
+ };
74
+ notify();
75
+ },
76
+ clearAll() {
77
+ if (Object.keys(runtimeByNodeId).length === 0) {
78
+ return;
79
+ }
80
+ runtimeByNodeId = {};
81
+ notify();
82
+ },
83
+ clearNode(nodeId) {
84
+ const normalized = nodeId.trim();
85
+ if (normalized.length === 0 || !runtimeByNodeId[normalized]) {
86
+ return;
87
+ }
88
+ const next = { ...runtimeByNodeId };
89
+ delete next[normalized];
90
+ runtimeByNodeId = next;
91
+ notify();
92
+ },
93
+ getNodeState(nodeId) {
94
+ return runtimeByNodeId[nodeId] ?? defaultBrowserNodeRuntimeState;
95
+ },
96
+ getSnapshot() {
97
+ return runtimeByNodeId;
98
+ },
99
+ subscribe(listener) {
100
+ listeners.add(listener);
101
+ return () => {
102
+ listeners.delete(listener);
103
+ };
104
+ }
105
+ };
106
+ }
107
+ function resolveNextState(previous, event) {
108
+ const nextUrl = normalizePublishedBrowserValue(event.url) ?? (event.lifecycle !== "cold" ? previous.url : null);
109
+ const nextTitle = normalizePublishedBrowserValue(event.title) ?? (event.lifecycle !== "cold" ? previous.title : null);
110
+ return {
111
+ ...previous,
112
+ canGoBack: event.canGoBack,
113
+ canGoForward: event.canGoForward,
114
+ error: shouldClearLoadError({
115
+ isLoading: event.isLoading,
116
+ url: event.url
117
+ }) ? null : previous.error,
118
+ isAttachedToWindow: event.isAttachedToWindow ?? previous.isAttachedToWindow,
119
+ isLoading: event.isLoading,
120
+ isOccluded: event.isOccluded,
121
+ lifecycle: event.lifecycle,
122
+ title: nextTitle,
123
+ url: nextUrl
124
+ };
125
+ }
126
+
127
+ // src/core/feature.ts
128
+ function createBrowserNodeFeature({
129
+ hostApi,
130
+ i18n,
131
+ reportDiagnostic,
132
+ resolveSearchUrl,
133
+ runtimeStore = createBrowserNodeRuntimeStore()
134
+ }) {
135
+ let listenerCount = 0;
136
+ let disconnect = null;
137
+ const connect = () => {
138
+ listenerCount += 1;
139
+ if (!disconnect) {
140
+ disconnect = hostApi.onEvent((event) => runtimeStore.applyEvent(event));
141
+ }
142
+ return () => {
143
+ listenerCount = Math.max(0, listenerCount - 1);
144
+ if (listenerCount === 0) {
145
+ disconnect?.();
146
+ disconnect = null;
147
+ }
148
+ };
149
+ };
150
+ return {
151
+ connect,
152
+ hostApi,
153
+ i18n: createBrowserNodeI18nRuntime(i18n),
154
+ reportDiagnostic,
155
+ resolveAddressInput(rawInput) {
156
+ return resolveBrowserAddressInput(rawInput, { resolveSearchUrl });
157
+ },
158
+ runtimeStore
159
+ };
160
+ }
161
+ export {
162
+ createBrowserNodeFeature,
163
+ resolveBrowserNavigationUrl
164
+ };
165
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/runtimeStore.ts","../src/core/feature.ts"],"sourcesContent":["import type { BrowserNodeEvent, BrowserNodeRuntimeState } from \"./types.ts\";\n\nexport interface BrowserNodeRuntimeStore {\n applyEvent(event: BrowserNodeEvent): void;\n clearAll(): void;\n clearNode(nodeId: string): void;\n getNodeState(nodeId: string): BrowserNodeRuntimeState;\n getSnapshot(): Record<string, BrowserNodeRuntimeState | undefined>;\n subscribe(listener: () => void): () => void;\n}\n\nconst defaultBrowserNodeRuntimeState: BrowserNodeRuntimeState = {\n canGoBack: false,\n canGoForward: false,\n error: null,\n isAttachedToWindow: false,\n isLoading: false,\n isOccluded: false,\n lifecycle: \"cold\",\n title: null,\n url: null\n};\n\nconst chromiumErrorPageUrlPrefix = \"chrome-error://\";\n\nfunction isChromiumErrorPageUrl(value: string | null | undefined): boolean {\n return value?.trim().startsWith(chromiumErrorPageUrlPrefix) === true;\n}\n\nfunction normalizePublishedBrowserValue(\n value: string | null | undefined\n): string | null {\n const trimmed = value?.trim() ?? \"\";\n if (\n trimmed.length === 0 ||\n trimmed === \"about:blank\" ||\n isChromiumErrorPageUrl(trimmed)\n ) {\n return null;\n }\n return trimmed;\n}\n\nfunction shouldClearLoadError({\n isLoading,\n url\n}: {\n isLoading: boolean;\n url: string | null;\n}): boolean {\n return isLoading && !isChromiumErrorPageUrl(url);\n}\n\nexport function createBrowserNodeRuntimeStore(): BrowserNodeRuntimeStore {\n const listeners = new Set<() => void>();\n let runtimeByNodeId: Record<string, BrowserNodeRuntimeState | undefined> = {};\n\n const notify = () => {\n for (const listener of listeners) {\n listener();\n }\n };\n\n return {\n applyEvent(event) {\n if (event.type === \"open-url\") {\n return;\n }\n\n if (event.type === \"closed\") {\n if (!runtimeByNodeId[event.nodeId]) {\n return;\n }\n const next = { ...runtimeByNodeId };\n delete next[event.nodeId];\n runtimeByNodeId = next;\n notify();\n return;\n }\n\n const previous =\n runtimeByNodeId[event.nodeId] ?? defaultBrowserNodeRuntimeState;\n const next =\n event.type === \"state\"\n ? resolveNextState(previous, event)\n : {\n ...previous,\n error: {\n code: event.code,\n diagnosticMessage: event.diagnosticMessage,\n params: event.params\n }\n };\n\n runtimeByNodeId = {\n ...runtimeByNodeId,\n [event.nodeId]: next\n };\n notify();\n },\n clearAll() {\n if (Object.keys(runtimeByNodeId).length === 0) {\n return;\n }\n runtimeByNodeId = {};\n notify();\n },\n clearNode(nodeId) {\n const normalized = nodeId.trim();\n if (normalized.length === 0 || !runtimeByNodeId[normalized]) {\n return;\n }\n const next = { ...runtimeByNodeId };\n delete next[normalized];\n runtimeByNodeId = next;\n notify();\n },\n getNodeState(nodeId) {\n return runtimeByNodeId[nodeId] ?? defaultBrowserNodeRuntimeState;\n },\n getSnapshot() {\n return runtimeByNodeId;\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n }\n };\n}\n\nfunction resolveNextState(\n previous: BrowserNodeRuntimeState,\n event: Extract<BrowserNodeEvent, { type: \"state\" }>\n): BrowserNodeRuntimeState {\n const nextUrl =\n normalizePublishedBrowserValue(event.url) ??\n (event.lifecycle !== \"cold\" ? previous.url : null);\n const nextTitle =\n normalizePublishedBrowserValue(event.title) ??\n (event.lifecycle !== \"cold\" ? previous.title : null);\n\n return {\n ...previous,\n canGoBack: event.canGoBack,\n canGoForward: event.canGoForward,\n error: shouldClearLoadError({\n isLoading: event.isLoading,\n url: event.url\n })\n ? null\n : previous.error,\n isAttachedToWindow: event.isAttachedToWindow ?? previous.isAttachedToWindow,\n isLoading: event.isLoading,\n isOccluded: event.isOccluded,\n lifecycle: event.lifecycle,\n title: nextTitle,\n url: nextUrl\n };\n}\n","import type { I18nRuntime } from \"@tutti-os/ui-i18n-runtime\";\nimport { createBrowserNodeI18nRuntime } from \"../i18n/browserNodeI18n.ts\";\nimport type { BrowserNodeI18nRuntime } from \"../i18n/browserNodeI18n.ts\";\nimport type { BrowserNodeHostApi } from \"./types.ts\";\nimport {\n createBrowserNodeRuntimeStore,\n type BrowserNodeRuntimeStore\n} from \"./runtimeStore.ts\";\nimport {\n resolveBrowserAddressInput,\n type BrowserAddressInputResolution,\n type BrowserSearchUrlResolver\n} from \"./url.ts\";\n\nexport interface BrowserNodeFeature {\n hostApi: BrowserNodeHostApi;\n i18n: BrowserNodeI18nRuntime;\n reportDiagnostic?: BrowserNodeDiagnosticReporter;\n resolveAddressInput(rawInput: string): BrowserAddressInputResolution;\n runtimeStore: BrowserNodeRuntimeStore;\n connect(): () => void;\n}\n\nexport interface BrowserNodeDiagnosticPayload {\n details?: Record<string, unknown>;\n event: string;\n level?: \"debug\" | \"info\" | \"warn\" | \"error\";\n}\n\nexport type BrowserNodeDiagnosticReporter = (\n payload: BrowserNodeDiagnosticPayload\n) => void;\n\nexport interface CreateBrowserNodeFeatureInput {\n hostApi: BrowserNodeHostApi;\n i18n?: I18nRuntime<string>;\n reportDiagnostic?: BrowserNodeDiagnosticReporter;\n resolveSearchUrl?: BrowserSearchUrlResolver;\n runtimeStore?: BrowserNodeRuntimeStore;\n}\n\nexport function createBrowserNodeFeature({\n hostApi,\n i18n,\n reportDiagnostic,\n resolveSearchUrl,\n runtimeStore = createBrowserNodeRuntimeStore()\n}: CreateBrowserNodeFeatureInput): BrowserNodeFeature {\n let listenerCount = 0;\n let disconnect: (() => void) | null = null;\n\n const connect = () => {\n listenerCount += 1;\n if (!disconnect) {\n disconnect = hostApi.onEvent((event) => runtimeStore.applyEvent(event));\n }\n\n return () => {\n listenerCount = Math.max(0, listenerCount - 1);\n if (listenerCount === 0) {\n disconnect?.();\n disconnect = null;\n }\n };\n };\n\n return {\n connect,\n hostApi,\n i18n: createBrowserNodeI18nRuntime(i18n),\n reportDiagnostic,\n resolveAddressInput(rawInput) {\n return resolveBrowserAddressInput(rawInput, { resolveSearchUrl });\n },\n runtimeStore\n };\n}\n"],"mappings":"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","names":["next"]}
@@ -0,0 +1,41 @@
1
+ import { JSX, ReactNode, HTMLAttributes } from 'react';
2
+ import { BrowserNodeFeature, BrowserNodeNavigationPolicy, BrowserNodeSessionMode } from '../index.js';
3
+ import '@tutti-os/ui-i18n-runtime';
4
+ import '../i18n/index.js';
5
+
6
+ interface BrowserNodeProps {
7
+ defaultUrl: string;
8
+ feature: BrowserNodeFeature;
9
+ navigationPolicy?: BrowserNodeNavigationPolicy | null;
10
+ nodeId: string;
11
+ onFocusRequest?: () => void;
12
+ onNavigated?: (url: string) => void;
13
+ profileId?: string | null;
14
+ sessionMode?: BrowserNodeSessionMode;
15
+ sessionPartition?: string | null;
16
+ showHeader?: boolean;
17
+ syncDefaultUrl?: boolean;
18
+ }
19
+ declare function BrowserNode({ defaultUrl, feature, navigationPolicy, nodeId, onFocusRequest, onNavigated, profileId, sessionMode, sessionPartition, showHeader, syncDefaultUrl }: BrowserNodeProps): JSX.Element;
20
+ declare function BrowserNodeHeader({ canGoBack, canGoForward, className, defaultActions, draftUrl, dragHandleProps, feature, isCold, isLoading, onCloseRequest, onDraftUrlChange, onFocusRequest, onGoBack, onGoForward, onOpenExternal, onReload, onSubmitUrl, withBorder }: {
21
+ canGoBack: boolean;
22
+ canGoForward: boolean;
23
+ className?: string;
24
+ defaultActions?: ReactNode;
25
+ draftUrl: string;
26
+ dragHandleProps?: HTMLAttributes<HTMLElement>;
27
+ feature: BrowserNodeFeature;
28
+ isCold?: boolean;
29
+ isLoading: boolean;
30
+ onCloseRequest?: () => void;
31
+ onDraftUrlChange: (nextUrl: string) => void;
32
+ onFocusRequest?: () => void;
33
+ onGoBack: () => void;
34
+ onGoForward: () => void;
35
+ onOpenExternal?: () => void;
36
+ onReload: () => void;
37
+ onSubmitUrl: () => void;
38
+ withBorder?: boolean;
39
+ }): JSX.Element;
40
+
41
+ export { BrowserNode, BrowserNodeHeader, type BrowserNodeProps };
@@ -0,0 +1,11 @@
1
+ import {
2
+ BrowserNode,
3
+ BrowserNodeHeader
4
+ } from "../chunk-2GEY55PS.js";
5
+ import "../chunk-UTXZLRPE.js";
6
+ import "../chunk-LVVPDNEF.js";
7
+ export {
8
+ BrowserNode,
9
+ BrowserNodeHeader
10
+ };
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,32 @@
1
+ interface BrowserNodeBridgeError {
2
+ code: string;
3
+ message: string;
4
+ params?: Record<string, unknown>;
5
+ }
6
+ type BrowserNodeBridgeResult<T> = {
7
+ ok: true;
8
+ value: T;
9
+ } | {
10
+ ok: false;
11
+ error: BrowserNodeBridgeError;
12
+ };
13
+ interface BrowserNodeBridgeCallPayload {
14
+ args: unknown;
15
+ method: string;
16
+ }
17
+ interface BrowserNodeBridgeMeta {
18
+ runtime: "electron";
19
+ version: string;
20
+ }
21
+ interface BrowserNodeBridgeMethodDescriptor {
22
+ readonly defaultErrorCode?: string;
23
+ readonly hostPatterns: readonly string[];
24
+ readonly name: string;
25
+ }
26
+ type BrowserNodeBridgeCallable = (args?: unknown) => Promise<BrowserNodeBridgeResult<unknown>>;
27
+ interface BrowserNodeBridgeApiTree {
28
+ meta: BrowserNodeBridgeMeta;
29
+ [key: string]: unknown;
30
+ }
31
+
32
+ export type { BrowserNodeBridgeApiTree as B, BrowserNodeBridgeCallPayload as a, BrowserNodeBridgeCallable as b, BrowserNodeBridgeError as c, BrowserNodeBridgeMeta as d, BrowserNodeBridgeMethodDescriptor as e, BrowserNodeBridgeResult as f };
@@ -0,0 +1,55 @@
1
+ import { ReactNode } from 'react';
2
+ import { WorkbenchFrame, WorkbenchHostExternalStateSource, WorkbenchHostDockEntry, WorkbenchHostNodeDefinition, WorkbenchContribution, WorkbenchHostLaunchRequest, WorkbenchHostLaunchResult } from '@tutti-os/workbench-surface';
3
+ import { BrowserNodeFeature } from '../index.js';
4
+ import '@tutti-os/ui-i18n-runtime';
5
+ import '../i18n/index.js';
6
+
7
+ interface BrowserNodeOpenUrlActivationPayload {
8
+ title?: string;
9
+ url: string;
10
+ }
11
+ interface BrowserNodeExternalState {
12
+ title?: string | null;
13
+ url?: string | null;
14
+ }
15
+ interface CreateBrowserNodeDefinitionInput {
16
+ defaultUrl: string;
17
+ dockIcon?: ReactNode;
18
+ feature: BrowserNodeFeature;
19
+ frame?: WorkbenchFrame;
20
+ onNavigated?: (input: {
21
+ nodeId: string;
22
+ url: string;
23
+ }) => void;
24
+ typeId?: string;
25
+ }
26
+ interface CreateBrowserDockEntryInput {
27
+ dockIcon?: ReactNode;
28
+ feature: BrowserNodeFeature;
29
+ id?: string;
30
+ order?: number;
31
+ sectionId?: string;
32
+ typeId?: string;
33
+ }
34
+ interface CreateBrowserWorkbenchLaunchHandlerInput {
35
+ browserInstancePrefix?: string;
36
+ typeId?: string;
37
+ }
38
+ interface CreateBrowserWorkbenchContributionInput {
39
+ contributionId?: string;
40
+ defaultUrl: string;
41
+ dockEntry?: Omit<CreateBrowserDockEntryInput, "feature">;
42
+ externalStateSource?: WorkbenchHostExternalStateSource<BrowserNodeExternalState | null, unknown>;
43
+ feature: BrowserNodeFeature;
44
+ launch?: CreateBrowserWorkbenchLaunchHandlerInput;
45
+ node?: Omit<CreateBrowserNodeDefinitionInput, "defaultUrl" | "feature">;
46
+ typeId?: string;
47
+ }
48
+ declare const defaultBrowserNodeTypeId = "browser";
49
+ declare function createBrowserNodeDefinition({ defaultUrl, feature, frame, onNavigated, typeId }: CreateBrowserNodeDefinitionInput): WorkbenchHostNodeDefinition<BrowserNodeExternalState>;
50
+ declare function createBrowserDockEntry(input: CreateBrowserDockEntryInput): WorkbenchHostDockEntry;
51
+ declare function createBrowserDockIconImage(src: string): ReactNode;
52
+ declare function createBrowserWorkbenchLaunchHandler({ browserInstancePrefix, typeId }?: CreateBrowserWorkbenchLaunchHandlerInput): (request: WorkbenchHostLaunchRequest) => WorkbenchHostLaunchResult | null;
53
+ declare function createBrowserWorkbenchContribution({ contributionId, defaultUrl, dockEntry, externalStateSource, feature, launch, node, typeId }: CreateBrowserWorkbenchContributionInput): WorkbenchContribution;
54
+
55
+ export { type BrowserNodeExternalState, type BrowserNodeOpenUrlActivationPayload, type CreateBrowserDockEntryInput, type CreateBrowserNodeDefinitionInput, type CreateBrowserWorkbenchContributionInput, type CreateBrowserWorkbenchLaunchHandlerInput, createBrowserDockEntry, createBrowserDockIconImage, createBrowserNodeDefinition, createBrowserWorkbenchContribution, createBrowserWorkbenchLaunchHandler, defaultBrowserNodeTypeId };
@@ -0,0 +1,194 @@
1
+ import {
2
+ BrowserNode,
3
+ BrowserNodeWorkbenchHeader
4
+ } from "../chunk-2GEY55PS.js";
5
+ import "../chunk-UTXZLRPE.js";
6
+ import "../chunk-LVVPDNEF.js";
7
+
8
+ // src/workbench/index.ts
9
+ import { createElement } from "react";
10
+ var defaultBrowserNodeFrame = {
11
+ height: 560,
12
+ width: 920,
13
+ x: 220,
14
+ y: 120
15
+ };
16
+ var defaultBrowserNodeTypeId = "browser";
17
+ function createBrowserNodeDefinition({
18
+ defaultUrl,
19
+ feature,
20
+ frame = defaultBrowserNodeFrame,
21
+ onNavigated,
22
+ typeId = defaultBrowserNodeTypeId
23
+ }) {
24
+ return {
25
+ frame,
26
+ instance: {
27
+ mode: "multi"
28
+ },
29
+ renderBody: (context) => createElement(BrowserNode, {
30
+ defaultUrl: resolveBrowserNodeInitialUrl({
31
+ activation: context.activation,
32
+ defaultUrl,
33
+ externalNodeState: context.externalNodeState
34
+ }),
35
+ feature,
36
+ nodeId: context.node.id,
37
+ onFocusRequest: context.isFocused ? void 0 : () => context.focus(),
38
+ onNavigated: onNavigated ? (url) => onNavigated({
39
+ nodeId: context.node.id,
40
+ url
41
+ }) : void 0,
42
+ showHeader: false,
43
+ syncDefaultUrl: true
44
+ }),
45
+ renderHeader: ({
46
+ defaultActions,
47
+ activation,
48
+ dragHandleProps,
49
+ externalNodeState,
50
+ isFocused,
51
+ node,
52
+ windowActions
53
+ }) => createElement(BrowserNodeWorkbenchHeader, {
54
+ defaultActions,
55
+ defaultUrl: resolveBrowserNodeInitialUrl({
56
+ activation,
57
+ defaultUrl,
58
+ externalNodeState
59
+ }),
60
+ dragHandleProps,
61
+ feature,
62
+ nodeId: node.id,
63
+ onCloseRequest: () => {
64
+ void feature.hostApi.close({ nodeId: node.id }).catch(() => void 0);
65
+ },
66
+ onFocusRequest: isFocused ? void 0 : () => windowActions.focus()
67
+ }),
68
+ title: feature.i18n.t("title"),
69
+ typeId,
70
+ window: {
71
+ closable: true,
72
+ defaultOpen: false,
73
+ minimizedDock: {
74
+ capturePreview: ({ node }) => feature.hostApi.capturePreview?.({ nodeId: node.id }) ?? null,
75
+ kind: "snapshot"
76
+ },
77
+ minimizable: true,
78
+ restoreOnLoad: true
79
+ }
80
+ };
81
+ }
82
+ function createBrowserDockEntry(input) {
83
+ return {
84
+ capturePopupItemPreview: ({ node }) => input.feature.hostApi.capturePreview?.({ nodeId: node.id }) ?? null,
85
+ icon: input.dockIcon ?? null,
86
+ id: input.id ?? defaultBrowserNodeTypeId,
87
+ label: input.feature.i18n.t("dockLabel"),
88
+ launchBehavior: "enabled",
89
+ matchNode: (node) => node.data.typeId === (input.typeId ?? defaultBrowserNodeTypeId),
90
+ order: input.order,
91
+ resolvePopupItem: ({ node }) => {
92
+ const runtime = input.feature.runtimeStore.getNodeState(node.id);
93
+ return {
94
+ subtitle: runtime.url?.trim() || node.data.instanceId,
95
+ title: runtime.title?.trim() || node.title
96
+ };
97
+ },
98
+ sectionId: input.sectionId,
99
+ typeId: input.typeId ?? defaultBrowserNodeTypeId,
100
+ visibility: "always"
101
+ };
102
+ }
103
+ function createBrowserDockIconImage(src) {
104
+ return createElement("img", {
105
+ alt: "",
106
+ "aria-hidden": "true",
107
+ "data-browser-node-dock-icon": "true",
108
+ draggable: false,
109
+ src
110
+ });
111
+ }
112
+ function createBrowserWorkbenchLaunchHandler({
113
+ browserInstancePrefix,
114
+ typeId = defaultBrowserNodeTypeId
115
+ } = {}) {
116
+ let nextBrowserInstanceSequence = 1;
117
+ const instancePrefix = browserInstancePrefix ?? globalThis.crypto?.randomUUID?.() ?? typeId;
118
+ return (request) => {
119
+ if (request.typeId !== typeId) {
120
+ return null;
121
+ }
122
+ const instanceId = `${typeId}-${instancePrefix}-${nextBrowserInstanceSequence++}`;
123
+ return {
124
+ dockEntryId: request.dockEntryId ?? typeId,
125
+ framePolicy: "cascade",
126
+ instanceId,
127
+ typeId
128
+ };
129
+ };
130
+ }
131
+ function createBrowserWorkbenchContribution({
132
+ contributionId,
133
+ defaultUrl,
134
+ dockEntry,
135
+ externalStateSource,
136
+ feature,
137
+ launch,
138
+ node,
139
+ typeId = defaultBrowserNodeTypeId
140
+ }) {
141
+ return {
142
+ dockEntries: [
143
+ createBrowserDockEntry({
144
+ ...dockEntry,
145
+ feature,
146
+ typeId
147
+ })
148
+ ],
149
+ externalStateSource,
150
+ id: contributionId ?? typeId,
151
+ nodes: [
152
+ createBrowserNodeDefinition({
153
+ ...node,
154
+ defaultUrl,
155
+ feature,
156
+ typeId
157
+ })
158
+ ],
159
+ onLaunchRequest: createBrowserWorkbenchLaunchHandler({
160
+ ...launch,
161
+ typeId
162
+ })
163
+ };
164
+ }
165
+ function resolveBrowserNodeInitialUrl({
166
+ activation,
167
+ defaultUrl,
168
+ externalNodeState
169
+ }) {
170
+ return readBrowserOpenUrlActivationPayload(activation)?.url ?? normalizeBrowserNodeInitialUrl(externalNodeState?.url) ?? defaultUrl;
171
+ }
172
+ function normalizeBrowserNodeInitialUrl(value) {
173
+ const trimmed = value?.trim() ?? "";
174
+ return trimmed.length > 0 ? trimmed : null;
175
+ }
176
+ function readBrowserOpenUrlActivationPayload(activation) {
177
+ if (activation?.type !== "open-url" || !activation.payload || typeof activation.payload !== "object") {
178
+ return null;
179
+ }
180
+ const typed = activation.payload;
181
+ return typeof typed.url === "string" ? {
182
+ title: typeof typed.title === "string" ? typed.title : void 0,
183
+ url: typed.url
184
+ } : null;
185
+ }
186
+ export {
187
+ createBrowserDockEntry,
188
+ createBrowserDockIconImage,
189
+ createBrowserNodeDefinition,
190
+ createBrowserWorkbenchContribution,
191
+ createBrowserWorkbenchLaunchHandler,
192
+ defaultBrowserNodeTypeId
193
+ };
194
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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 \"@tutti-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 onNavigated?: (input: { nodeId: string; url: string }) => void;\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 onNavigated,\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 onNavigated: onNavigated\n ? (url) =>\n onNavigated({\n nodeId: context.node.id,\n url\n })\n : undefined,\n showHeader: false,\n syncDefaultUrl: true\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 minimizedDock: {\n capturePreview: ({ node }) =>\n feature.hostApi.capturePreview?.({ nodeId: node.id }) ?? null,\n kind: \"snapshot\"\n },\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 ADDED
@@ -0,0 +1,89 @@
1
+ {
2
+ "name": "@tutti-os/browser-node",
3
+ "version": "0.0.1",
4
+ "private": false,
5
+ "type": "module",
6
+ "types": "./dist/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./dist/index.js"
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
+ },
16
+ "./bridge": {
17
+ "types": "./dist/bridge/index.d.ts",
18
+ "import": "./dist/bridge/index.js"
19
+ },
20
+ "./electron-main": {
21
+ "types": "./dist/electron-main/index.d.ts",
22
+ "import": "./dist/electron-main/index.js"
23
+ },
24
+ "./electron-preload": {
25
+ "types": "./dist/electron-preload/index.d.ts",
26
+ "import": "./dist/electron-preload/index.js"
27
+ },
28
+ "./i18n": {
29
+ "types": "./dist/i18n/index.d.ts",
30
+ "import": "./dist/i18n/index.js"
31
+ },
32
+ "./react": {
33
+ "types": "./dist/react/index.d.ts",
34
+ "import": "./dist/react/index.js"
35
+ },
36
+ "./workbench": {
37
+ "types": "./dist/workbench/index.d.ts",
38
+ "import": "./dist/workbench/index.js"
39
+ }
40
+ },
41
+ "files": [
42
+ "dist",
43
+ "README.md"
44
+ ],
45
+ "repository": {
46
+ "type": "git",
47
+ "url": "git+https://github.com/tutti-os/tutti.git",
48
+ "directory": "packages/browser/workbench-node"
49
+ },
50
+ "dependencies": {
51
+ "@tutti-os/ui-i18n-runtime": "0.0.1",
52
+ "@tutti-os/ui-react-hooks": "0.0.1",
53
+ "@tutti-os/ui-system": "0.0.1",
54
+ "@tutti-os/workbench-surface": "0.0.1",
55
+ "ws": "^8.21.0"
56
+ },
57
+ "devDependencies": {
58
+ "@types/node": "^24.0.1",
59
+ "@types/react": "^19.1.6",
60
+ "@types/react-dom": "^19.1.5",
61
+ "@types/ws": "^8.18.1",
62
+ "electron": "^35.7.5",
63
+ "react": "^19.1.0",
64
+ "react-dom": "^19.1.0",
65
+ "typescript": "^5.8.3",
66
+ "@tutti-os/config-tsconfig": "0.0.0"
67
+ },
68
+ "peerDependencies": {
69
+ "electron": "^35.7.5",
70
+ "react": "^19.1.0",
71
+ "react-dom": "^19.1.0"
72
+ },
73
+ "peerDependenciesMeta": {
74
+ "electron": {
75
+ "optional": true
76
+ }
77
+ },
78
+ "nextop": {
79
+ "tailwindSourceRoot": "src"
80
+ },
81
+ "publishConfig": {
82
+ "access": "public"
83
+ },
84
+ "scripts": {
85
+ "build": "tsup --config tsup.config.ts && node ../../../tools/scripts/copy-package-assets.mjs src/assets dist/assets",
86
+ "test": "node --test --experimental-strip-types ./src/**/*.test.ts",
87
+ "typecheck": "tsc --noEmit -p tsconfig.json"
88
+ }
89
+ }