@adobe/uix-guest 0.6.3
Sign up to get free protection for your applications and to get access to all the features.
- package/LICENSE +201 -0
- package/README.md +1 -0
- package/dist/debug-guest.d.ts +8 -0
- package/dist/debug-guest.d.ts.map +1 -0
- package/dist/esm/index.js +155 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/guest-server.d.ts +53 -0
- package/dist/guest-server.d.ts.map +1 -0
- package/dist/guest-ui.d.ts +102 -0
- package/dist/guest-ui.d.ts.map +1 -0
- package/dist/guest.d.ts +160 -0
- package/dist/guest.d.ts.map +1 -0
- package/dist/iife/index.js +761 -0
- package/dist/iife/index.js.map +1 -0
- package/dist/index.d.ts +105 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +172 -0
- package/dist/index.js.map +1 -0
- package/package.json +39 -0
- package/src/debug-guest.ts +42 -0
- package/src/guest-server.ts +56 -0
- package/src/guest-ui.ts +123 -0
- package/src/guest.ts +255 -0
- package/src/index.ts +142 -0
- package/tsconfig.json +20 -0
@@ -0,0 +1,56 @@
|
|
1
|
+
/*
|
2
|
+
Copyright 2022 Adobe. All rights reserved.
|
3
|
+
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License. You may obtain a copy
|
5
|
+
of the License at http://www.apache.org/licenses/LICENSE-2.0
|
6
|
+
|
7
|
+
Unless required by applicable law or agreed to in writing, software distributed under
|
8
|
+
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
9
|
+
OF ANY KIND, either express or implied. See the License for the specific language
|
10
|
+
governing permissions and limitations under the License.
|
11
|
+
*/
|
12
|
+
|
13
|
+
import type { GuestApis } from "@adobe/uix-core";
|
14
|
+
import type { SharedContext } from "./guest";
|
15
|
+
import { Guest } from "./guest";
|
16
|
+
|
17
|
+
/**
|
18
|
+
* A Guest to be used in the "main" or primary frame of an extension, the frame
|
19
|
+
* the Host loads first.
|
20
|
+
*
|
21
|
+
* @remarks This is the Guest object returned from {@link register}. It can
|
22
|
+
* expose internal methods to the Host via the {@link GuestServer.register}
|
23
|
+
* method.
|
24
|
+
*
|
25
|
+
*
|
26
|
+
* @public
|
27
|
+
*/
|
28
|
+
export class GuestServer<Outgoing extends GuestApis> extends Guest<Outgoing> {
|
29
|
+
private localMethods: Outgoing;
|
30
|
+
protected getLocalMethods() {
|
31
|
+
return {
|
32
|
+
...super.getLocalMethods(),
|
33
|
+
apis: this.localMethods,
|
34
|
+
};
|
35
|
+
}
|
36
|
+
/**
|
37
|
+
* {@inheritDoc BaseGuest.sharedContext}
|
38
|
+
*/
|
39
|
+
sharedContext: SharedContext;
|
40
|
+
/**
|
41
|
+
* {@inheritdoc BaseGuest.host}
|
42
|
+
*/
|
43
|
+
host: Guest<Outgoing>["host"];
|
44
|
+
/**
|
45
|
+
* Pass an interface of methods which Host may call as callbacks.
|
46
|
+
*
|
47
|
+
* @remarks It is preferable to use {@link register} to obtain a guest object
|
48
|
+
* and register local methods in one step. The returned guest object will be
|
49
|
+
* pre-registered and connected.
|
50
|
+
* @public
|
51
|
+
*/
|
52
|
+
async register(implementedMethods: Outgoing) {
|
53
|
+
this.localMethods = implementedMethods;
|
54
|
+
return this._connect();
|
55
|
+
}
|
56
|
+
}
|
package/src/guest-ui.ts
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
/*
|
2
|
+
Copyright 2022 Adobe. All rights reserved.
|
3
|
+
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License. You may obtain a copy
|
5
|
+
of the License at http://www.apache.org/licenses/LICENSE-2.0
|
6
|
+
|
7
|
+
Unless required by applicable law or agreed to in writing, software distributed under
|
8
|
+
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
9
|
+
OF ANY KIND, either express or implied. See the License for the specific language
|
10
|
+
governing permissions and limitations under the License.
|
11
|
+
*/
|
12
|
+
|
13
|
+
import type { RemoteHostApis, VirtualApi } from "@adobe/uix-core";
|
14
|
+
import {
|
15
|
+
Guest,
|
16
|
+
GuestConfig,
|
17
|
+
GuestEventBeforeConnect,
|
18
|
+
GuestEventConnected,
|
19
|
+
GuestEventContextChange,
|
20
|
+
GuestEventError,
|
21
|
+
} from "./guest";
|
22
|
+
|
23
|
+
/**
|
24
|
+
* A Guest to be used in an extension-controlled frame, usually to display UI.
|
25
|
+
*
|
26
|
+
* @typeParam Incoming - Optional interface of host methods. If using
|
27
|
+
* TypeScript, supply this type parameter and a promisified version of the
|
28
|
+
* interface will be available at {@link Guest.host}
|
29
|
+
*
|
30
|
+
* @remarks
|
31
|
+
* This is the object returned when calling {@link @adobe/uix-guest#attach}. It
|
32
|
+
* represents an additional frame or runtime created by the host application, on
|
33
|
+
* behalf of the extension's control frame which is running the {@link
|
34
|
+
* GuestServer}. It is a "secondary" guest object, which a host won't use before
|
35
|
+
* the control frame has connected. It exposes a subset of the functionality of
|
36
|
+
* the {@link GuestServer}.
|
37
|
+
*
|
38
|
+
* Unlike the {@link GuestServer}, it cannot register methods or update the
|
39
|
+
* {@link Guest.sharedContext}, but it remains in sync with the GuestServer and
|
40
|
+
* can access the {@link Guest.sharedContext} of the control frame, as well as
|
41
|
+
* any of the published methods on the host.
|
42
|
+
*
|
43
|
+
* Extensible host apps using the React bindings will likely render GuestUI
|
44
|
+
* frames using the {@link @adobe/uix-host-react#GuestUIFrame} component.
|
45
|
+
*
|
46
|
+
* @example
|
47
|
+
* When an extensible app renders this page, {@link @adobe/uix-guest#attach}
|
48
|
+
* creates a GuestUI. Once it attaches to the host, it
|
49
|
+
* ```javascript
|
50
|
+
* import React, { useEffect, useState } from "react";
|
51
|
+
* import { attach } from "@adobe/uix-guest";
|
52
|
+
* import { Tooltip } from "./tooltip";
|
53
|
+
*
|
54
|
+
* export default function PopupOverlay(props) {
|
55
|
+
* // how large am I?
|
56
|
+
* const [dimensions, setDimensions] = useState(
|
57
|
+
* document.body.getBoundingClientRect()
|
58
|
+
* );
|
59
|
+
* // if possible, use language preloaded in query parameters
|
60
|
+
* const [language, setLanguage] = useState(props.params.lang)
|
61
|
+
*
|
62
|
+
* // attach only once, in a useEffect
|
63
|
+
* useEffect(() => {
|
64
|
+
* attach({
|
65
|
+
* id: "my-extension-id",
|
66
|
+
* debug: true,
|
67
|
+
* })
|
68
|
+
* .then(guestUI => {
|
69
|
+
* // this event fires whenever the host, or the control frame, changes
|
70
|
+
* // any sharedContext value
|
71
|
+
* guestUI.addEventListener("contextchange", ({ detail: { context }}) => {
|
72
|
+
* setLanguage(context.lang)
|
73
|
+
* });
|
74
|
+
* // how large does the host want me to be?
|
75
|
+
* return guestUI.host.tooltips.getDimensions()
|
76
|
+
* .then(setDimensions)
|
77
|
+
* })
|
78
|
+
* .catch((e) => {
|
79
|
+
* console.error("ui attach failed", e);
|
80
|
+
* });
|
81
|
+
* }, []);
|
82
|
+
* // render UI! Due to the setup and useState, this component will re-render
|
83
|
+
* // once attach() is complete.
|
84
|
+
* return (
|
85
|
+
* <Tooltip {...props.params} lang={language} dimensions={dimensions} />
|
86
|
+
* );
|
87
|
+
* }
|
88
|
+
* ```
|
89
|
+
*
|
90
|
+
* @public
|
91
|
+
*/
|
92
|
+
export class GuestUI<IHost extends VirtualApi> extends Guest<IHost> {
|
93
|
+
/**
|
94
|
+
* {@inheritDoc Guest."constructor"}
|
95
|
+
*/
|
96
|
+
constructor(config: GuestConfig) {
|
97
|
+
super(config);
|
98
|
+
}
|
99
|
+
/**
|
100
|
+
* {@inheritDoc Guest.contextchange}
|
101
|
+
* @eventProperty
|
102
|
+
*/
|
103
|
+
public contextchange: GuestEventContextChange;
|
104
|
+
/**
|
105
|
+
* {@inheritDoc Guest.beforeconnect}
|
106
|
+
* @eventProperty
|
107
|
+
*/
|
108
|
+
public beforeconnect: GuestEventBeforeConnect;
|
109
|
+
/**
|
110
|
+
* {@inheritDoc Guest.connected}
|
111
|
+
* @eventProperty
|
112
|
+
*/
|
113
|
+
public connected: GuestEventConnected;
|
114
|
+
/**
|
115
|
+
* {@inheritDoc Guest.error}
|
116
|
+
* @eventProperty
|
117
|
+
*/
|
118
|
+
public error: GuestEventError;
|
119
|
+
/**
|
120
|
+
* {@inheritDoc Guest.host}
|
121
|
+
*/
|
122
|
+
host: RemoteHostApis<IHost>;
|
123
|
+
}
|
package/src/guest.ts
ADDED
@@ -0,0 +1,255 @@
|
|
1
|
+
/*
|
2
|
+
Copyright 2022 Adobe. All rights reserved.
|
3
|
+
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License. You may obtain a copy
|
5
|
+
of the License at http://www.apache.org/licenses/LICENSE-2.0
|
6
|
+
|
7
|
+
Unless required by applicable law or agreed to in writing, software distributed under
|
8
|
+
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
9
|
+
OF ANY KIND, either express or implied. See the License for the specific language
|
10
|
+
governing permissions and limitations under the License.
|
11
|
+
*/
|
12
|
+
|
13
|
+
/* eslint @typescript-eslint/no-explicit-any: "off" */
|
14
|
+
import { Connection, connectToParent } from "penpal";
|
15
|
+
import type {
|
16
|
+
RemoteHostApis,
|
17
|
+
HostConnection,
|
18
|
+
NamedEvent,
|
19
|
+
VirtualApi,
|
20
|
+
} from "@adobe/uix-core";
|
21
|
+
import {
|
22
|
+
Emitter,
|
23
|
+
makeNamespaceProxy,
|
24
|
+
timeoutPromise,
|
25
|
+
quietConsole,
|
26
|
+
} from "@adobe/uix-core";
|
27
|
+
import { debugGuest } from "./debug-guest.js";
|
28
|
+
|
29
|
+
/**
|
30
|
+
* @public
|
31
|
+
*/
|
32
|
+
export type GuestEvent<
|
33
|
+
Type extends string = string,
|
34
|
+
Detail = Record<string, unknown>
|
35
|
+
> = NamedEvent<
|
36
|
+
Type,
|
37
|
+
Detail &
|
38
|
+
Record<string, unknown> & {
|
39
|
+
guest: Guest;
|
40
|
+
}
|
41
|
+
>;
|
42
|
+
|
43
|
+
/**
|
44
|
+
* @public
|
45
|
+
*/
|
46
|
+
export type GuestEventContextChange = GuestEvent<
|
47
|
+
"contextchange",
|
48
|
+
{ context: Record<string, unknown> }
|
49
|
+
>;
|
50
|
+
|
51
|
+
/** @public */
|
52
|
+
export type GuestEventBeforeConnect = GuestEvent<"beforeconnect">;
|
53
|
+
/** @public */
|
54
|
+
export type GuestEventConnected = GuestEvent<
|
55
|
+
"connected",
|
56
|
+
{ connection: Connection }
|
57
|
+
>;
|
58
|
+
/** @public */
|
59
|
+
export type GuestEventError = GuestEvent<"error", { error: Error }>;
|
60
|
+
|
61
|
+
/**
|
62
|
+
* @public
|
63
|
+
*/
|
64
|
+
export type GuestEvents =
|
65
|
+
| GuestEventContextChange
|
66
|
+
| GuestEventBeforeConnect
|
67
|
+
| GuestEventConnected
|
68
|
+
| GuestEventError;
|
69
|
+
|
70
|
+
/**
|
71
|
+
* @public
|
72
|
+
*/
|
73
|
+
export interface GuestConfig {
|
74
|
+
/**
|
75
|
+
* String slug identifying extension. This may need to use IDs from an
|
76
|
+
* external system in the future.
|
77
|
+
*/
|
78
|
+
id: string;
|
79
|
+
/**
|
80
|
+
* Set debug flags on all libraries that have them, and add loggers to SDK
|
81
|
+
* objects. Log a lot to the console.
|
82
|
+
*/
|
83
|
+
debug?: boolean;
|
84
|
+
/**
|
85
|
+
* Time out and stop trying to reach the host after this many milliseconds
|
86
|
+
*/
|
87
|
+
timeout?: number;
|
88
|
+
}
|
89
|
+
|
90
|
+
/**
|
91
|
+
* A `Map` representing the {@link @adobe/uix-host#HostConfig.sharedContext}
|
92
|
+
* object.
|
93
|
+
*
|
94
|
+
* @remarks While the Host object is a plain JavaScript object. the `sharedContext` in the Guest object implements the {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map | Map} interface.
|
95
|
+
*
|
96
|
+
* @example
|
97
|
+
* In the host app window, the Host object shares context:
|
98
|
+
* ```javascript
|
99
|
+
*host.shareContext({
|
100
|
+
* someAuthToken: 'abc'
|
101
|
+
*});
|
102
|
+
* ```
|
103
|
+
*
|
104
|
+
* After the `contentchange` event has fired in the guest window:
|
105
|
+
* ```javascript
|
106
|
+
* guest.sharedContext.get('someAuthToken') === 'abc'
|
107
|
+
* ```
|
108
|
+
* @public
|
109
|
+
*/
|
110
|
+
export class SharedContext {
|
111
|
+
private _map: Map<string, unknown>;
|
112
|
+
constructor(values: Record<string, unknown>) {
|
113
|
+
this.reset(values);
|
114
|
+
}
|
115
|
+
private reset(values: Record<string, unknown>) {
|
116
|
+
this._map = new Map(Object.entries(values));
|
117
|
+
}
|
118
|
+
/**
|
119
|
+
* @public
|
120
|
+
* Retrieve a copy of a value from the {@link @adobe/uix-host#HostConfig.sharedContext} object. *Note that this is not a reference to any actual objects from the parent. If the parent updates an "inner object" inside the SharedContext, that change will not be reflected in the Guest!*
|
121
|
+
*/
|
122
|
+
get(key: string) {
|
123
|
+
return this._map.get(key);
|
124
|
+
}
|
125
|
+
}
|
126
|
+
|
127
|
+
/**
|
128
|
+
* Generic Guest object, with methods shared by all types of Guest.
|
129
|
+
* @internal
|
130
|
+
*/
|
131
|
+
export class Guest<
|
132
|
+
Incoming extends object = VirtualApi
|
133
|
+
> extends Emitter<GuestEvents> {
|
134
|
+
/**
|
135
|
+
* Shared context has been set or updated.
|
136
|
+
* @eventProperty
|
137
|
+
*/
|
138
|
+
public contextchange: GuestEventContextChange;
|
139
|
+
/**
|
140
|
+
* About to attempt connection to the host.
|
141
|
+
* @eventProperty
|
142
|
+
*/
|
143
|
+
public beforeconnect: GuestEventBeforeConnect;
|
144
|
+
/**
|
145
|
+
* Host connection has been established.
|
146
|
+
* @eventProperty
|
147
|
+
*/
|
148
|
+
public connected: GuestEventConnected;
|
149
|
+
/**
|
150
|
+
* Host connection has failed.
|
151
|
+
* @eventProperty
|
152
|
+
*/
|
153
|
+
public error: GuestEventError;
|
154
|
+
/**
|
155
|
+
* {@inheritdoc SharedContext}
|
156
|
+
*/
|
157
|
+
sharedContext: SharedContext;
|
158
|
+
private debugLogger: Console = quietConsole;
|
159
|
+
|
160
|
+
/**
|
161
|
+
* @param config - Initializer for guest object, including ID.
|
162
|
+
*/
|
163
|
+
constructor(config: GuestConfig) {
|
164
|
+
super(config.id);
|
165
|
+
if (typeof config.timeout === "number") {
|
166
|
+
this.timeout = config.timeout;
|
167
|
+
}
|
168
|
+
if (config.debug) {
|
169
|
+
this.debugLogger = debugGuest(this);
|
170
|
+
}
|
171
|
+
this.addEventListener("contextchange", (event) => {
|
172
|
+
this.sharedContext = new SharedContext(event.detail.context);
|
173
|
+
});
|
174
|
+
}
|
175
|
+
/**
|
176
|
+
* Proxy object for calling methods on the host.
|
177
|
+
*
|
178
|
+
* @remarks Any APIs exposed to the extension via {@link @adobe/uix-host#Port.provide}
|
179
|
+
* can be called on this object. Because these methods are called with RPC,
|
180
|
+
* they are all asynchronous, The return types of all Host methods will be
|
181
|
+
* Promises which resolve to the value the Host method returns.
|
182
|
+
* @public
|
183
|
+
*/
|
184
|
+
host: RemoteHostApis<Incoming> = makeNamespaceProxy<Incoming>(
|
185
|
+
async (address) => {
|
186
|
+
await this.hostConnectionPromise;
|
187
|
+
try {
|
188
|
+
const result = await timeoutPromise(
|
189
|
+
10000,
|
190
|
+
this.hostConnection.invokeHostMethod(address)
|
191
|
+
);
|
192
|
+
return result;
|
193
|
+
} catch (e) {
|
194
|
+
const error =
|
195
|
+
e instanceof Error ? e : new Error(e as unknown as string);
|
196
|
+
const methodError = new Error(
|
197
|
+
`Host method call host.${address.path.join(".")}() failed: ${
|
198
|
+
error.message
|
199
|
+
}`
|
200
|
+
);
|
201
|
+
this.debugLogger.error(methodError);
|
202
|
+
throw methodError;
|
203
|
+
}
|
204
|
+
}
|
205
|
+
);
|
206
|
+
private timeout = 10000;
|
207
|
+
private hostConnectionPromise: Promise<RemoteHostApis<HostConnection>>;
|
208
|
+
private hostConnection!: RemoteHostApis<HostConnection>;
|
209
|
+
/** @internal */
|
210
|
+
protected getLocalMethods() {
|
211
|
+
return {
|
212
|
+
emit: (...args: Parameters<typeof this.emit>) => {
|
213
|
+
this.debugLogger.log(`Event "${args[0]}" emitted from host`);
|
214
|
+
this.emit(...args);
|
215
|
+
},
|
216
|
+
};
|
217
|
+
}
|
218
|
+
/**
|
219
|
+
* Accept a connection from the Host.
|
220
|
+
* @returns A Promise that resolves when the Host has established a connection.
|
221
|
+
* @deprecated It is preferable to use {@link register} for primary frames,
|
222
|
+
* and {@link attach} for UI frames and other secondary frames, than to
|
223
|
+
* instantiate a Guest and then call `.connect()` on it. The latter style
|
224
|
+
* returns an object that cannot be used until it is connected, and therefore
|
225
|
+
* risks errors.
|
226
|
+
* @public
|
227
|
+
*/
|
228
|
+
async connect() {
|
229
|
+
return this._connect();
|
230
|
+
}
|
231
|
+
|
232
|
+
/**
|
233
|
+
* @internal
|
234
|
+
*/
|
235
|
+
async _connect() {
|
236
|
+
this.emit("beforeconnect", { guest: this });
|
237
|
+
try {
|
238
|
+
const connection = connectToParent<HostConnection<Incoming>>({
|
239
|
+
timeout: this.timeout,
|
240
|
+
methods: this.getLocalMethods(),
|
241
|
+
});
|
242
|
+
|
243
|
+
this.hostConnectionPromise = connection.promise;
|
244
|
+
this.hostConnection = await this.hostConnectionPromise;
|
245
|
+
this.sharedContext = new SharedContext(
|
246
|
+
await this.hostConnection.getSharedContext()
|
247
|
+
);
|
248
|
+
this.debugLogger.log("retrieved sharedContext", this.sharedContext);
|
249
|
+
this.emit("connected", { guest: this, connection });
|
250
|
+
} catch (e) {
|
251
|
+
this.emit("error", { guest: this, error: e });
|
252
|
+
this.debugLogger.error("Connection failed!", e);
|
253
|
+
}
|
254
|
+
}
|
255
|
+
}
|
package/src/index.ts
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
/*
|
2
|
+
Copyright 2022 Adobe. All rights reserved.
|
3
|
+
This file is licensed to you under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License. You may obtain a copy
|
5
|
+
of the License at http://www.apache.org/licenses/LICENSE-2.0
|
6
|
+
|
7
|
+
Unless required by applicable law or agreed to in writing, software distributed under
|
8
|
+
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
|
9
|
+
OF ANY KIND, either express or implied. See the License for the specific language
|
10
|
+
governing permissions and limitations under the License.
|
11
|
+
*/
|
12
|
+
|
13
|
+
/**
|
14
|
+
* @packageDocumentation
|
15
|
+
* Tools for UI Extensions meant to run inside extensible apps. Connects
|
16
|
+
* Extensions running in their own window contexts with the host app, allowing
|
17
|
+
* the host and guest to exchange method, events, and signals.
|
18
|
+
*
|
19
|
+
* @remarks The core object of this library, which extensions use for
|
20
|
+
* communication, is the Guest object. There are two variants of the Guest
|
21
|
+
* object {@link GuestServer} for the bootstrap frame which your extension keeps
|
22
|
+
* running in the background, and {@link GuestUI} for frames meant to be
|
23
|
+
* displayed in the host application. An extension must have one GuestServer
|
24
|
+
* frame, and the host app may choose to use one or more GuestUI frames.
|
25
|
+
*
|
26
|
+
* @example Creating and connecting a GuestServer with {@link register}
|
27
|
+
* ```typescript
|
28
|
+
* import { register } from "@adobe/uix-guest";
|
29
|
+
*
|
30
|
+
* const server = await register({
|
31
|
+
* // Must match extension ID from registry
|
32
|
+
* id: "My Custom View Extension",
|
33
|
+
* // enable logging in dev build
|
34
|
+
* debug: process.env.NODE_ENV !== "production",
|
35
|
+
* // Host can access these methods from its Port to this guest
|
36
|
+
* methods: {
|
37
|
+
* // Methods must be namespaced by one or more levels
|
38
|
+
* myCustomView: {
|
39
|
+
* async documentIsViewable(docId) {
|
40
|
+
* const doc = await callMyRuntimeAction(docId);
|
41
|
+
* return someValidation(doc);
|
42
|
+
* },
|
43
|
+
* renderView(docId, depth) {
|
44
|
+
* // Use a host method
|
45
|
+
* const tooltip = await server.host.editor.requestTooltip({
|
46
|
+
* type: 'frame',
|
47
|
+
* url: new URL(`/show/${docId}`, location).href
|
48
|
+
* })
|
49
|
+
* }
|
50
|
+
* },
|
51
|
+
* },
|
52
|
+
* })
|
53
|
+
* ```
|
54
|
+
*
|
55
|
+
* @example Connecting to an existing GuestServer with a GuestUI
|
56
|
+
* ```typescript
|
57
|
+
* import { attach } from "@adobe/uix-guest";
|
58
|
+
*
|
59
|
+
* const ui = await attach({
|
60
|
+
* id: "My Custom View Extension",
|
61
|
+
* })
|
62
|
+
*
|
63
|
+
* // when editing is done:
|
64
|
+
* const saved = await ui.host.editor.saveChanges();
|
65
|
+
* if (!saved) {
|
66
|
+
* const editorState = ui.sharedContext.get('editorState');
|
67
|
+
* if (editorState.tooltips[ui.id].invalid === true) {
|
68
|
+
* putGuestUIInInvalidState();
|
69
|
+
* }
|
70
|
+
* } else {
|
71
|
+
* ui.host.editor.dismissTooltip();
|
72
|
+
* }
|
73
|
+
* ```
|
74
|
+
*
|
75
|
+
*/
|
76
|
+
import type { Guest, GuestConfig } from "./guest.js";
|
77
|
+
import { GuestUI } from "./guest-ui.js";
|
78
|
+
import { GuestServer } from "./guest-server.js";
|
79
|
+
import { GuestApis } from "@adobe/uix-core";
|
80
|
+
|
81
|
+
/**
|
82
|
+
* {@inheritdoc GuestConfig}
|
83
|
+
* @public
|
84
|
+
*/
|
85
|
+
type GuestConfigWithMethods<Outgoing extends GuestApis> = GuestConfig & {
|
86
|
+
methods: Outgoing;
|
87
|
+
};
|
88
|
+
|
89
|
+
/**
|
90
|
+
* Create and immediately return a {@link GuestServer}.
|
91
|
+
*
|
92
|
+
* @deprecated Use {@link attach} or {@link register}, which return Promises
|
93
|
+
* that resolve once the guest is connected.
|
94
|
+
* @public
|
95
|
+
*/
|
96
|
+
export function createGuest(config: GuestConfig) {
|
97
|
+
const guest = new GuestServer(config);
|
98
|
+
return guest;
|
99
|
+
}
|
100
|
+
|
101
|
+
/**
|
102
|
+
* Connect to a running {@link GuestServer} to share its context and render UI.
|
103
|
+
*
|
104
|
+
* @remarks Creates a guest object that shares most of the GuestServer API,
|
105
|
+
* except it cannot register its own methods. Use `attach()` in an app or
|
106
|
+
* document that is meant to render a UI in the host application; it will have
|
107
|
+
* access to the sharedContext object shared by the host and GuestServer.
|
108
|
+
*
|
109
|
+
* @public
|
110
|
+
*/
|
111
|
+
export async function attach(config: GuestConfig) {
|
112
|
+
const guest = new GuestUI(config);
|
113
|
+
await guest._connect();
|
114
|
+
return guest;
|
115
|
+
}
|
116
|
+
|
117
|
+
/**
|
118
|
+
* Initiate a connection to the host app and its extension points.
|
119
|
+
*
|
120
|
+
* @remarks Creates the "main" {@link GuestServer}, which runs in the background
|
121
|
+
* without UI. Registers methods passed in the `methods` parameter, then
|
122
|
+
* resolves the returned Promise with the connected GuestServer object.
|
123
|
+
*
|
124
|
+
* @public
|
125
|
+
*/
|
126
|
+
export async function register<Outgoing extends GuestApis>(
|
127
|
+
config: GuestConfigWithMethods<Outgoing>
|
128
|
+
) {
|
129
|
+
const guest = new GuestServer(config);
|
130
|
+
await guest.register(config.methods);
|
131
|
+
return guest;
|
132
|
+
}
|
133
|
+
|
134
|
+
// backwards compatibility
|
135
|
+
export {
|
136
|
+
Guest,
|
137
|
+
Guest as BaseGuest,
|
138
|
+
GuestUI,
|
139
|
+
GuestUI as UIGuest,
|
140
|
+
GuestServer,
|
141
|
+
GuestServer as PrimaryGuest,
|
142
|
+
};
|
package/tsconfig.json
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
{
|
2
|
+
"$schema": "http://json.schemastore.org/tsconfig",
|
3
|
+
"extends": "../../tsconfig-base.json",
|
4
|
+
"compilerOptions": {
|
5
|
+
"outDir": "dist",
|
6
|
+
"rootDir": "src"
|
7
|
+
},
|
8
|
+
"include": [
|
9
|
+
"src/**/*"
|
10
|
+
],
|
11
|
+
"exclude": [
|
12
|
+
"src/**/*.test.tsx?"
|
13
|
+
],
|
14
|
+
"references": [
|
15
|
+
{
|
16
|
+
"path": "../uix-core"
|
17
|
+
}
|
18
|
+
]
|
19
|
+
}
|
20
|
+
|