@forgeax/app-shell 0.12.0 → 0.13.0
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/window.d.ts +24 -1
- package/dist/window.js +65 -0
- package/package.json +1 -1
package/dist/window.d.ts
CHANGED
|
@@ -52,8 +52,31 @@ interface CreateBrowserWindowManagerOptions {
|
|
|
52
52
|
readonly host?: BrowserWindowHost;
|
|
53
53
|
readonly closePollIntervalMs?: number;
|
|
54
54
|
}
|
|
55
|
+
/** Product-neutral handle implemented by event-driven native window adapters. */
|
|
56
|
+
interface ExternalWindowHandle {
|
|
57
|
+
show(): void | Promise<void>;
|
|
58
|
+
focus(): void | Promise<void>;
|
|
59
|
+
close(): void | Promise<void>;
|
|
60
|
+
}
|
|
61
|
+
interface ExternalWindowLifecycle {
|
|
62
|
+
created(): void;
|
|
63
|
+
error(): void;
|
|
64
|
+
destroyed(): void;
|
|
65
|
+
}
|
|
66
|
+
/** Adapter seam: products retain native API loading and concrete create policy. */
|
|
67
|
+
interface ExternalWindowHost {
|
|
68
|
+
getByLabel(label: string): Promise<ExternalWindowHandle | null>;
|
|
69
|
+
create(label: string, surface: SurfaceDescriptor, options: DetachWindowOptions | undefined, lifecycle: ExternalWindowLifecycle): Promise<ExternalWindowHandle>;
|
|
70
|
+
}
|
|
71
|
+
interface CreateExternalWindowManagerOptions {
|
|
72
|
+
readonly canDetach: () => boolean;
|
|
73
|
+
readonly loadHost: () => Promise<ExternalWindowHost | undefined>;
|
|
74
|
+
readonly createdTimeoutMs?: number;
|
|
75
|
+
}
|
|
55
76
|
/** Product-neutral browser popup carrier with injected surface URL policy. */
|
|
56
77
|
declare function createBrowserWindowManager(options: CreateBrowserWindowManagerOptions): WindowManager;
|
|
78
|
+
/** Event-driven external-window lifecycle with all native policy injected. */
|
|
79
|
+
declare function createExternalWindowManager(options: CreateExternalWindowManagerOptions): WindowManager;
|
|
57
80
|
/** Stable identity shared by keep-alive registries and physical carriers. */
|
|
58
81
|
declare function surfaceKey(surface: SurfaceDescriptor): string;
|
|
59
82
|
/** Deterministic, injective and carrier-safe label for the complete identity. */
|
|
@@ -63,4 +86,4 @@ declare function encodeSurfaceQuery(surface: SurfaceDescriptor): string;
|
|
|
63
86
|
/** Decode structural identity, or null for a normal shell/invalid entry. */
|
|
64
87
|
declare function decodeSurfaceFromLocation(search?: string): SurfaceDescriptor | null;
|
|
65
88
|
|
|
66
|
-
export { type BrowserPopupWindow, type BrowserWindowHost, type CreateBrowserWindowManagerOptions, type DetachWindowOptions, type DetachedWindowCapability, type DetachedWindowTarget, type SurfaceDescriptor, type SurfaceKind, type SurfacePane, type WindowManager, createBrowserWindowManager, decodeSurfaceFromLocation, encodeSurfaceQuery, surfaceKey, surfaceWindowLabel };
|
|
89
|
+
export { type BrowserPopupWindow, type BrowserWindowHost, type CreateBrowserWindowManagerOptions, type CreateExternalWindowManagerOptions, type DetachWindowOptions, type DetachedWindowCapability, type DetachedWindowTarget, type ExternalWindowHandle, type ExternalWindowHost, type ExternalWindowLifecycle, type SurfaceDescriptor, type SurfaceKind, type SurfacePane, type WindowManager, createBrowserWindowManager, createExternalWindowManager, decodeSurfaceFromLocation, encodeSurfaceQuery, surfaceKey, surfaceWindowLabel };
|
package/dist/window.js
CHANGED
|
@@ -75,6 +75,70 @@ function createBrowserWindowManager(options) {
|
|
|
75
75
|
}
|
|
76
76
|
};
|
|
77
77
|
}
|
|
78
|
+
function createExternalWindowManager(options) {
|
|
79
|
+
const closeListeners = /* @__PURE__ */ new Set();
|
|
80
|
+
const notifyClosed = (surface) => {
|
|
81
|
+
for (const listener of closeListeners) {
|
|
82
|
+
try {
|
|
83
|
+
listener(surface);
|
|
84
|
+
} catch {
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
return {
|
|
89
|
+
canDetach: options.canDetach,
|
|
90
|
+
async openSurfaceWindow(surface, detachOptions) {
|
|
91
|
+
const host = await options.loadHost();
|
|
92
|
+
if (!host) return false;
|
|
93
|
+
const label = surfaceWindowLabel(surface);
|
|
94
|
+
const existing = await host.getByLabel(label);
|
|
95
|
+
if (existing) {
|
|
96
|
+
try {
|
|
97
|
+
await existing.show();
|
|
98
|
+
await existing.focus();
|
|
99
|
+
return true;
|
|
100
|
+
} catch {
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return new Promise((resolve) => {
|
|
104
|
+
let settled = false;
|
|
105
|
+
const finish = (result) => {
|
|
106
|
+
if (settled) return;
|
|
107
|
+
settled = true;
|
|
108
|
+
clearTimeout(timeout);
|
|
109
|
+
resolve(result);
|
|
110
|
+
};
|
|
111
|
+
const timeout = setTimeout(() => finish(true), options.createdTimeoutMs ?? 2e3);
|
|
112
|
+
void host.create(label, surface, detachOptions, {
|
|
113
|
+
created: () => finish(true),
|
|
114
|
+
error: () => finish(false),
|
|
115
|
+
destroyed: () => notifyClosed(surface)
|
|
116
|
+
}).catch(() => finish(false));
|
|
117
|
+
});
|
|
118
|
+
},
|
|
119
|
+
async closeSurfaceWindow(surface) {
|
|
120
|
+
const host = await options.loadHost();
|
|
121
|
+
if (!host) return;
|
|
122
|
+
const existing = await host.getByLabel(surfaceWindowLabel(surface));
|
|
123
|
+
if (!existing) return;
|
|
124
|
+
try {
|
|
125
|
+
await existing.close();
|
|
126
|
+
} catch {
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
async isSurfaceWindowOpen(surface) {
|
|
130
|
+
const host = await options.loadHost();
|
|
131
|
+
if (!host) return false;
|
|
132
|
+
return await host.getByLabel(surfaceWindowLabel(surface)) !== null;
|
|
133
|
+
},
|
|
134
|
+
onSurfaceWindowClosed(listener) {
|
|
135
|
+
closeListeners.add(listener);
|
|
136
|
+
return () => {
|
|
137
|
+
closeListeners.delete(listener);
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
}
|
|
78
142
|
function surfaceKey(surface) {
|
|
79
143
|
const id = surface.id.includes(":") || surface.id.startsWith("~") ? `~${encodeURIComponent(surface.id)}` : surface.id;
|
|
80
144
|
const pane = surface.pane ? `:${surface.pane}` : "";
|
|
@@ -125,6 +189,7 @@ function decodeSurfaceFromLocation(search = typeof window !== "undefined" ? wind
|
|
|
125
189
|
}
|
|
126
190
|
export {
|
|
127
191
|
createBrowserWindowManager,
|
|
192
|
+
createExternalWindowManager,
|
|
128
193
|
decodeSurfaceFromLocation,
|
|
129
194
|
encodeSurfaceQuery,
|
|
130
195
|
surfaceKey,
|