@adobe/uix-host 0.6.5 → 0.7.1-nightly.20230114

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/host.d.ts CHANGED
@@ -163,7 +163,7 @@ export declare class Host extends Emitter<HostEvents> {
163
163
  private cachedCapabilityLists;
164
164
  private runtimeContainer;
165
165
  private guestOptions;
166
- private debugLogger;
166
+ private logger;
167
167
  private sharedContext;
168
168
  constructor(config: HostConfig);
169
169
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,7 +1,6 @@
1
1
  'use strict';
2
2
 
3
3
  var uixCore = require('@adobe/uix-core');
4
- var penpal = require('penpal');
5
4
 
6
5
  // src/host.ts
7
6
  var defaultOptions = {
@@ -14,7 +13,6 @@ var Port = class extends uixCore.Emitter {
14
13
  this.hostApis = {};
15
14
  this.isLoaded = false;
16
15
  this.subscriptions = [];
17
- this.uiConnections = /* @__PURE__ */ new Map();
18
16
  const { timeout, debug } = { ...defaultOptions, ...config.options || {} };
19
17
  this.timeout = timeout;
20
18
  this.debug = debug;
@@ -25,16 +23,19 @@ var Port = class extends uixCore.Emitter {
25
23
  this.subscriptions.push(
26
24
  config.events.addEventListener("contextchange", async (event) => {
27
25
  this.sharedContext = event.detail.context;
28
- await this.connect();
29
- await this.guest.emit("contextchange", { context: this.sharedContext });
26
+ await this.load();
27
+ await this.guestServer.getRemoteApi().emit("contextchange", { context: this.sharedContext });
30
28
  })
31
29
  );
32
30
  }
31
+ get apis() {
32
+ if (this.isReady() && this.guestServer) {
33
+ const server = this.guestServer.getRemoteApi();
34
+ return server && server.apis;
35
+ }
36
+ }
33
37
  attachUI(iframe) {
34
- const uniqueId = Math.random().toString(36);
35
- const uiConnection = this.attachFrame(iframe);
36
- this.uiConnections.set(uniqueId, uiConnection);
37
- return uiConnection;
38
+ return this.attachFrame(iframe);
38
39
  }
39
40
  hasCapabilities(requiredMethods) {
40
41
  this.assertReady();
@@ -59,8 +60,7 @@ var Port = class extends uixCore.Emitter {
59
60
  }
60
61
  return this.apis;
61
62
  } catch (e) {
62
- this.apis = null;
63
- this.guest = null;
63
+ this.guestServer = null;
64
64
  this.error = e instanceof Error ? e : new Error(String(e));
65
65
  throw e;
66
66
  }
@@ -70,12 +70,6 @@ var Port = class extends uixCore.Emitter {
70
70
  this.emit("hostprovide", { guestPort: this, apis });
71
71
  }
72
72
  async unload() {
73
- if (this.connection) {
74
- await this.connection.destroy();
75
- }
76
- for (const connection of this.uiConnections.values()) {
77
- await connection.destroy();
78
- }
79
73
  if (this.frame && this.frame.parentElement) {
80
74
  this.frame.parentElement.removeChild(this.frame);
81
75
  this.frame = void 0;
@@ -93,34 +87,34 @@ var Port = class extends uixCore.Emitter {
93
87
  this.assert(this.isReady(), () => "Attempted to interact before loaded");
94
88
  }
95
89
  attachFrame(iframe) {
96
- return penpal.connectToChild({
90
+ return uixCore.connectIframe(
97
91
  iframe,
98
- debug: this.debug,
99
- childOrigin: this.url.origin,
100
- timeout: this.timeout,
101
- methods: {
92
+ {
93
+ logger: this.logger,
94
+ targetOrigin: "*",
95
+ timeout: this.timeout
96
+ },
97
+ {
102
98
  getSharedContext: () => this.sharedContext,
103
99
  invokeHostMethod: (address) => this.invokeHostMethod(address)
104
100
  }
105
- });
101
+ );
106
102
  }
107
103
  async connect() {
108
104
  this.frame = this.runtimeContainer.ownerDocument.createElement("iframe");
109
105
  this.frame.setAttribute("src", this.url.href);
110
106
  this.frame.setAttribute("data-uix-guest", "true");
111
107
  this.runtimeContainer.appendChild(this.frame);
112
- if (this.debugLogger) {
113
- this.debugLogger.info(
108
+ if (this.logger) {
109
+ this.logger.info(
114
110
  `Guest ${this.id} attached iframe of ${this.url.href}`,
115
111
  this
116
112
  );
117
113
  }
118
- this.connection = this.attachFrame(this.frame);
119
- this.guest = await this.connection.promise;
120
- this.apis = this.guest.apis || {};
114
+ this.guestServer = await this.attachFrame(this.frame);
121
115
  this.isLoaded = true;
122
- if (this.debugLogger) {
123
- this.debugLogger.info(
116
+ if (this.logger) {
117
+ this.logger.info(
124
118
  `Guest ${this.id} established connection, received methods`,
125
119
  this.apis,
126
120
  this
@@ -161,7 +155,7 @@ var Port = class extends uixCore.Emitter {
161
155
  try {
162
156
  methodCallee = this.getHostMethodCallee(address, privateMethods);
163
157
  } catch (e) {
164
- this.debugLogger.warn("Private method not found!", address);
158
+ this.logger.warn("Private method not found!", address);
165
159
  }
166
160
  }
167
161
  if (!methodCallee) {
@@ -224,7 +218,7 @@ var _Host = class extends uixCore.Emitter {
224
218
  this.loading = false;
225
219
  this.guests = /* @__PURE__ */ new Map();
226
220
  this.cachedCapabilityLists = /* @__PURE__ */ new WeakMap();
227
- this.debugLogger = uixCore.quietConsole;
221
+ this.logger = uixCore.quietConsole;
228
222
  const { guestOptions = {} } = config;
229
223
  this.guestOptions = {
230
224
  ...guestOptions,
@@ -234,7 +228,7 @@ var _Host = class extends uixCore.Emitter {
234
228
  this.sharedContext = config.sharedContext || {};
235
229
  this.runtimeContainer = config.runtimeContainer;
236
230
  if (config.debug) {
237
- this.debugLogger = debugHost(this);
231
+ this.logger = debugHost(this);
238
232
  }
239
233
  }
240
234
  getLoadedGuests(filterOrCapabilities) {
@@ -303,7 +297,7 @@ var _Host = class extends uixCore.Emitter {
303
297
  ...this.guestOptions,
304
298
  ...options
305
299
  },
306
- debugLogger: this.debugLogger,
300
+ logger: this.logger,
307
301
  sharedContext: this.sharedContext,
308
302
  events: this
309
303
  });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/host.ts","../src/port.ts","../src/debug-host.ts","../src/extensions-provider/extension-registry.ts","../src/extensions-provider/composition.ts","../src/extensions-provider/mute.ts"],"names":["Emitter","log","event","host","window"],"mappings":"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","sourcesContent":["/*\nCopyright 2022 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nimport type {\n Extension,\n GuestConnection,\n NamedEvent,\n Emits,\n GuestApis,\n} from \"@adobe/uix-core\";\nimport type { CapabilitySpec } from \"./port.js\";\nimport { Emitter, quietConsole } from \"@adobe/uix-core\";\nimport { Port, PortOptions } from \"./port.js\";\nimport { debugHost } from \"./debug-host.js\";\n\n/**\n * Dictionary of {@link Port} objects by extension ID.\n * @public\n */\nexport type PortMap = Map<string, GuestConnection>;\n\n/** @public */\nexport type HostEvent<\n Type extends string = string,\n Detail = Record<string, unknown>\n> = NamedEvent<Type, Detail & Record<string, unknown> & { host: Host }>;\n/** @public */\ntype HostGuestEvent<Type extends string> = HostEvent<\n `guest${Type}`,\n { guest: GuestConnection }\n>;\n\n/**\n * All guests requested by host have been loaded and connected.\n * @public\n */\nexport type HostEventLoadAllGuests = HostEvent<\n \"loadallguests\",\n { failed: GuestConnection[]; loaded: GuestConnection[] }\n>;\n\n/**\n * Shared context has been set or updated; all guests receive this event too.\n * @public\n */\n\nexport type HostEventContextChange = HostEvent<\n \"contextchange\",\n { context: SharedContextValues }\n>;\n\n/**\n * An error has occurred during loading or unloading of guests.\n * @public\n */\nexport type HostEventError = HostEvent<\"error\", { error: Error }>;\n\n/** @public */\nexport type HostEvents =\n | HostGuestEvent<\"beforeload\">\n | HostGuestEvent<\"load\">\n | HostEvent<\"beforeunload\">\n | HostEvent<\"unload\">\n | HostEventLoadAllGuests\n | HostEventContextChange\n | HostEventError;\n\n/** @public */\nexport type InstalledExtensions = Record<Extension[\"id\"], Extension[\"url\"]>;\n/** @public */\nexport type ExtensionsProvider = () => Promise<InstalledExtensions>;\n\n/**\n * Values for shared context. Must be a plain object, serializable to JSON.\n * @public\n */\nexport type SharedContextValues = Record<string, unknown>;\n\n/** @public */\nexport interface HostConfig {\n /**\n * Human-readable \"slug\" name of the extensible area--often an entire app.\n * This string serves as a namespace for extension points within the area.\n */\n hostName: string;\n /**\n * A DOM element _outside_ of the React root. This is necessary to preserve\n * the lifetime of the iframes which are running extension objects; if they\n * live inside the React root, then React could unexpectedly re-render the\n * iframe tags themselves at any time, causing a reload of the frame.\n */\n runtimeContainer?: HTMLElement;\n /**\n * Copiously log lifecycle events.\n */\n debug?: boolean;\n /**\n * Default options to use for every guest Port.\n *\n * If `config.debug` is true, then the guest options will have `debug: true`\n * unless `debug: false` is explicitly passed in `guestOptions`.\n */\n guestOptions?: PortOptions;\n /**\n * A read-only dictionary of values that the host will supply to all the\n * guests.\n */\n sharedContext?: SharedContextValues;\n}\n\n/**\n * Callback to use to filter the list returned from {@link Host.(getLoadedGuests:2)}\n * @public\n */\ntype GuestFilter = (item: GuestConnection) => boolean;\n\nconst passAllGuests = () => true;\n\n/**\n * Manager object for connecting to {@link @adobe/uix-guest#GuestServer |\n * GuestServers} and {@link @adobe/uix-guest#GuestUI | GuestUIs}, providing and\n * receiving their APIs, and providing them to the app for interacting with UI.\n *\n * @remarks\n * The Host object is the main connection manager for all UIX Guests.\n * Making an app extensible requires creating a Host object.\n *\n * The extensible app using the Hostis responsible for providing a list of\n * extension references to the Host object. Use {@link\n * createExtensionRegistryProvider} for that purpose. Once you have retrieved a\n * list of extensions available to the host app, pass it to {@link Host.load}.\n *\n * When a Host creates a Guest, it must create an `<iframe>` element to contain\n * the Guest's main {@link @adobe/uix-guest#GuestServer} runtime, which runs\n * invisibly in the background. To do this, the Host creates a hidden container\n * in the body of the document. It is a `<div>` element with the attribute\n * `data-uix-guest-container`. Loaded GuestServers will be injected into this\n * hidden element and removed as necessary. When {@link Host.unload} is called,\n * the Host removes the hidden container from the document after unloading.\n *\n * @public\n */\nexport class Host extends Emitter<HostEvents> {\n /**\n * {@inheritDoc HostEventLoadAllGuests}\n * @eventProperty\n */\n public loadallguests: HostEventLoadAllGuests;\n\n /**\n * One guest has loaded.\n * @eventProperty\n */\n public guestload: HostGuestEvent<\"load\">;\n\n /**\n * About to attempt to load and connect to a Guest.\n * @eventProperty\n */\n public guestbeforeload: HostGuestEvent<\"beforeload\">;\n\n /**\n * About to unload a guest and remove its {@link @adobe/uix-guest#GuestServer}\n * instance as well as all its {@link @adobe/uix-guest#GuestUI} instances.\n * @eventProperty\n */\n public guestbeforeunload: HostGuestEvent<\"beforeunload\">;\n\n /**\n * Unloaded a guest and removed its {@link @adobe/uix-guest#GuestServer}\n * instance as well as all its {@link @adobe/uix-guest#GuestUI} instances.\n * @eventProperty\n */\n public guestunload: HostGuestEvent<\"unload\">;\n\n /**\n * {@inheritDoc HostEventContextChange}\n * @eventProperty\n */\n public contextchange: HostEventContextChange;\n\n /**\n * {@inheritDoc HostEventError}\n * @eventProperty\n */\n public error: HostEventError;\n\n private static containerStyle = {\n position: \"fixed\",\n width: \"1px\",\n height: \"1px\",\n pointerEvents: \"none\",\n opacity: 0,\n top: 0,\n left: \"-1px\",\n };\n /**\n * Unique string identifying the Host object.\n */\n hostName: string;\n /**\n * `true` if any extension in {@link Host.guests} has created a {@link\n * @adobe/uix-guest#GuestServer}, but the Guest has not yet loaded.\n */\n loading = false;\n /**\n * A Map of of the loaded guests.\n */\n guests: PortMap = new Map();\n private cachedCapabilityLists: WeakMap<object, GuestConnection[]> =\n new WeakMap();\n private runtimeContainer: HTMLElement;\n private guestOptions: PortOptions;\n private debugLogger: Console = quietConsole;\n private sharedContext: SharedContextValues;\n constructor(config: HostConfig) {\n super(config.hostName);\n const { guestOptions = {} } = config;\n this.guestOptions = {\n ...guestOptions,\n debug: guestOptions.debug === false ? false : !!config.debug,\n };\n this.hostName = config.hostName;\n this.sharedContext = config.sharedContext || {};\n this.runtimeContainer = config.runtimeContainer;\n if (config.debug) {\n this.debugLogger = debugHost(this);\n }\n }\n /**\n * Return all loaded guests.\n */\n getLoadedGuests(): GuestConnection[];\n /**\n * Return loaded guests which satisfy the passed test function.\n */\n getLoadedGuests(filter: GuestFilter): GuestConnection[];\n /**\n * Return loaded guests which expose the provided {@link CapabilitySpec}.\n */\n getLoadedGuests<Apis extends GuestApis>(\n capabilities: CapabilitySpec<Apis>\n ): GuestConnection[];\n getLoadedGuests<Apis extends GuestApis = never>(\n filterOrCapabilities?: CapabilitySpec<Apis> | GuestFilter\n ): GuestConnection[] {\n if (typeof filterOrCapabilities === \"object\") {\n return this.getLoadedGuestsWith<Apis>(filterOrCapabilities);\n }\n const filter = filterOrCapabilities || passAllGuests;\n const result = [];\n for (const guest of this.guests.values()) {\n if (guest.isReady() && filter(guest)) {\n result.push(guest);\n }\n }\n return result;\n }\n /**\n * Set the object of shared values that all Guests can access via {@link @adobe/uix-guest#GuestServer.sharedContext}.\n * This overwrites any previous object.\n *\n * @example Exposes `authToken` to all Guests. Guests can call `this.sharedContext.get('authToken')` to retrieve this value.\n * ```javascript\n * host.shareContext({\n * authToken: '82ba19b'\n * });\n * ```\n *\n * @example Overwrites the previous sharedContext, deleting `authToken` and providing `secret` and `auth` instead.\n * ```javascript\n * host.shareContext({\n * secret: 'squirrel',\n * auth: false\n * });\n * ```\n */\n shareContext(context: SharedContextValues): void;\n /**\n * Update the object of shared values that all Guests can access via {@link\n * @adobe/uix-guest#GuestServer.sharedContext}. This method takes a callback\n * which receives the previous context and may return an entirely new context,\n * or new values merged with the old context.\n *\n * @remarks This callback pattern allows the shared context values to be\n * mutable while the internal context object references are immutable, which\n * is important for synchronizing. with guests.\n *\n * @example Overwrites a context object based on the previous one.\n * ```javascript\n * host.shareContext(oldContext => ({\n * counter: oldContext.counter + 1\n * }))\n * ```\n *\n * @example Updates a context while preserving other existing values.\n * ```javascript\n * host.shareContext(oldContext => ({\n * ...oldContext,\n * counter: oldContext.counter + 1\n * }))\n * ```\n */\n shareContext(\n setter: (context: SharedContextValues) => SharedContextValues\n ): void;\n shareContext(\n setter: (context: SharedContextValues) => SharedContextValues\n ): void;\n shareContext(\n setterOrContext:\n | ((context: SharedContextValues) => SharedContextValues)\n | SharedContextValues\n ) {\n if (typeof setterOrContext === \"function\") {\n this.sharedContext = setterOrContext(this.sharedContext);\n } else {\n this.sharedContext = setterOrContext;\n }\n this.emit(\"contextchange\", {\n host: this,\n context: this.sharedContext,\n });\n }\n /**\n * Load extension into host application from provided extension description.\n * Returned promise resolves when all extensions are loaded and registered.\n *\n * @param extensions - List of extension descriptors. Normally, the Host should receive this value from an {@link ExtensionsProvider}.\n * @param options - Custom options to be used as defaults for each {@link Port} object created for each guest.\n * @returns Promise which resolves when all guests have been loaded.\n */\n async load(\n extensions: InstalledExtensions,\n options?: PortOptions\n ): Promise<void> {\n this.runtimeContainer =\n this.runtimeContainer || this.createRuntimeContainer(window);\n const failed: GuestConnection[] = [];\n const loaded: GuestConnection[] = [];\n this.loading = true;\n await Promise.all(\n Object.entries(extensions).map(async ([id, url]) => {\n const port = await this.loadOneGuest(id, url, options);\n (port.error ? failed : loaded).push(port);\n })\n );\n this.loading = false;\n this.emit(\"loadallguests\", { host: this, failed, loaded });\n }\n /**\n * Unload all extensions and remove their frames/workers. Use this to unmount\n * a UI or when switching to a different extensible UI.\n */\n async unload(): Promise<void> {\n this.emit(\"beforeunload\", { host: this });\n await Promise.all([...this.guests.values()].map((guest) => guest.unload()));\n this.guests.clear();\n this.runtimeContainer.parentElement.removeChild(this.runtimeContainer);\n this.emit(\"unload\", { host: this });\n }\n private createRuntimeContainer(window: Window) {\n const { document } = window;\n const container = document.createElement(\"div\");\n container.setAttribute(\"data-uix-guest-container\", this.hostName);\n Object.assign(container.style, Host.containerStyle);\n document.body.appendChild(container);\n return container;\n }\n private async loadOneGuest(\n id: string,\n urlString: string,\n options: PortOptions = {}\n ): Promise<GuestConnection> {\n let guest = this.guests.get(id);\n if (!guest) {\n const url = new URL(urlString);\n guest = new Port({\n owner: this.hostName,\n id,\n url,\n runtimeContainer: this.runtimeContainer,\n options: {\n ...this.guestOptions,\n ...options,\n },\n debugLogger: this.debugLogger,\n sharedContext: this.sharedContext,\n events: this as Emits,\n });\n this.guests.set(id, guest);\n }\n this.emit(\"guestbeforeload\", { guest, host: this });\n try {\n await guest.load();\n } catch (e: unknown) {\n const error = e instanceof Error ? e : new Error(String(e));\n this.emit(\"error\", { host: this, guest, error });\n console.warn(\"Failed to load extension at endpoint %s\", guest.url);\n return guest;\n }\n // this new guest might have new capabilities, so the identities of the\n // cached capability sets will need to change, to alert subscribers\n this.cachedCapabilityLists = new WeakMap();\n this.emit(\"guestload\", { guest, host: this });\n return guest;\n }\n private getLoadedGuestsWith<Apis extends GuestApis>(\n capabilities: CapabilitySpec<Apis>\n ) {\n if (this.cachedCapabilityLists.has(capabilities)) {\n return this.cachedCapabilityLists.get(capabilities);\n }\n const guestsWithCapabilities = this.getLoadedGuests((guest) =>\n guest.hasCapabilities(capabilities)\n );\n this.cachedCapabilityLists.set(capabilities, guestsWithCapabilities);\n return guestsWithCapabilities;\n }\n}\n","/*\nCopyright 2022 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nimport type {\n Emits,\n GuestConnection,\n HostMethodAddress,\n NamedEvent,\n RemoteHostApis,\n GuestApis,\n Unsubscriber,\n} from \"@adobe/uix-core\";\nimport { Emitter } from \"@adobe/uix-core\";\nimport { Connection, connectToChild, Methods } from \"penpal\";\n\n/**\n * A specifier for methods to be expected on a remote interface.\n *\n * @remarks\n * A CapabilitySpec is a description of an interface, like a very simplified\n * type definition. It specifies an object structure and the paths in that\n * structure that must be functions. (It doesn't specify anything about the\n * signatures or return values of those functions.)\n *\n * Use CapabilitySpec objects as queries, or filters, to get a subset of\n * installed extensions which have registered methods which match the spec.\n *\n * @example\n * As an extensible app developer, you are making an extension point for spell\n * check. Your code expects extensions to register an API `spellCheck` with\n * methods called `spellCheck.correct(text)` and `spellCheck.suggest(text)`.\n *\n * ```javascript\n * async function correctText(text) {\n * const spellCheckers = host.getLoadedGuests({\n * spellCheck: [\n * 'correct',\n * 'suggest'\n * ]\n * });\n * let correcting = text;\n * for (const checker of spellCheckers) {\n * correcting = await checker.apis.spellCheck.correct(correcting);\n * }\n * return Promise.all(checkers.map(checker =>\n * checker.apis.spellCheck.suggest(correcting)\n * ));\n * }\n * ```\n *\n * @public\n */\nexport type CapabilitySpec<T extends GuestApis> = {\n [Name in keyof T]: (keyof T[Name])[];\n};\n\n/**\n * Interface for decoupling of guest Penpal object\n * @internal\n */\ninterface GuestProxyWrapper {\n /**\n * Methods from guest\n */\n apis: RemoteHostApis;\n /**\n * Emit an event in the guest frame\n */\n emit(type: string, detail: unknown): Promise<void>;\n}\n\n/** @public */\ntype PortEvent<\n GuestApi,\n Type extends string = string,\n Detail = Record<string, unknown>\n> = NamedEvent<\n Type,\n Detail &\n Record<string, unknown> & {\n guestPort: Port<GuestApi>;\n }\n>;\n\n/** @public */\nexport type PortEvents<\n GuestApi,\n HostApi extends Record<string, unknown> = Record<string, unknown>\n> =\n | PortEvent<GuestApi, \"hostprovide\">\n | PortEvent<GuestApi, \"unload\">\n | PortEvent<GuestApi, \"beforecallhostmethod\", HostMethodAddress<HostApi>>;\n\n/** @public */\nexport type PortOptions = {\n /**\n * Time in milliseconds to wait for the guest to connect before throwing.\n */\n timeout?: number;\n /**\n * Set true to log copiously in the console.\n */\n debug?: boolean;\n};\n\nconst defaultOptions = {\n timeout: 10000,\n debug: false,\n};\n\n/**\n * A Port is the Host-maintained object representing an extension running as a\n * guest. It exposes methods registered by the Guest, and can provide Host\n * methods back to the guest.\n *\n * @remarks\n * When the Host object loads extensions via {@link Host.load}, it creates a\n * Port object for each extension. When retrieving and filtering extensions\n * via {@link Host.(getLoadedGuests:2)}, a list of Port objects is returned. From\n * the point of view of the extensible app using the Host object, extensions\n * are always Port objects, which expose the methods registered by the\n * extension at the {@link Port.apis} property.\n *\n * @privateRemarks\n * We've gone through several possible names for this object. GuestProxy,\n * GuestInterface, GuestConnection, etc. \"Port\" is not ideal, but it conflicted\n * the least with other types we defined in early drafts. It's definitely\n * something we should review.\n * @public\n */\nexport class Port<GuestApi>\n extends Emitter<PortEvents<GuestApi>>\n implements GuestConnection\n{\n // #region Properties (15)\n\n private connection: Connection<RemoteHostApis<GuestApi>>;\n private debug: boolean;\n private debugLogger?: Console;\n private frame: HTMLIFrameElement;\n private guest: GuestProxyWrapper;\n private hostApis: RemoteHostApis = {};\n private isLoaded = false;\n private runtimeContainer: HTMLElement;\n private sharedContext: Record<string, unknown>;\n private subscriptions: Unsubscriber[] = [];\n private timeout: number;\n\n /**\n * Dictionary of namespaced methods that were registered by this guest at the\n * time of connection, using {@link @adobe/uix-guest#register}.\n *\n * @remarks\n * These methods are proxy methods; you can only pass serializable objects to\n * them, not class instances, methods or callbacks.\n * @public\n */\n public apis: RemoteHostApis;\n /**\n * If any errors occurred during the loading of guests, this property will\n * contain the error that was raised.\n * @public\n */\n error?: Error;\n private uiConnections: Map<string, Connection<RemoteHostApis<GuestApi>>> =\n new Map();\n /**\n * The URL of the guest provided by the extension registry. The Host will\n * load this URL in the background, in the invisible the bootstrap frame, so\n * this URL must point to a page that calls {@link @adobe/uix-guest#register}\n * when it loads.\n */\n url: URL;\n\n // #endregion Properties (15)\n\n // #region Constructors (1)\n\n constructor(config: {\n owner: string;\n id: string;\n url: URL;\n /**\n * An alternate DOM element to use for invisible iframes. Will create its\n * own if this option is not populated with a DOM element.\n */\n runtimeContainer: HTMLElement;\n options: PortOptions;\n debugLogger?: Console;\n /**\n * Initial object to populate the shared context with. Once the guest\n * connects, it will be able to access these properties.\n */\n sharedContext: Record<string, unknown>;\n events: Emits;\n }) {\n super(config.id);\n const { timeout, debug } = { ...defaultOptions, ...(config.options || {}) };\n this.timeout = timeout;\n this.debug = debug;\n this.id = config.id;\n this.url = config.url;\n this.runtimeContainer = config.runtimeContainer;\n this.sharedContext = config.sharedContext;\n this.subscriptions.push(\n config.events.addEventListener(\"contextchange\", async (event) => {\n this.sharedContext = (\n (event as CustomEvent).detail as unknown as Record<string, unknown>\n ).context as Record<string, unknown>;\n await this.connect();\n await this.guest.emit(\"contextchange\", { context: this.sharedContext });\n })\n );\n }\n\n // #endregion Constructors (1)\n\n // #region Public Methods (6)\n\n /**\n * Connect an iframe element which is displaying another page in the extension\n * with the extension's bootstrap frame, so they can share context and events.\n */\n public attachUI(iframe: HTMLIFrameElement) {\n const uniqueId = Math.random().toString(36);\n const uiConnection = this.attachFrame(iframe);\n this.uiConnections.set(uniqueId, uiConnection);\n return uiConnection;\n }\n\n /**\n * Returns true if the guest has registered methods matching the provided\n * capability spec. A capability spec is simply an object whose properties are\n * declared in an array of keys, description the names of the functions and\n * methods that the Port will expose.\n */\n public hasCapabilities(requiredMethods: CapabilitySpec<GuestApis>) {\n this.assertReady();\n return Object.keys(requiredMethods).every((key) => {\n if (!Reflect.has(this.apis, key)) {\n return false;\n }\n const api = this.apis[key];\n const methodList = requiredMethods[\n key as keyof typeof requiredMethods\n ] as string[];\n return methodList.every(\n (methodName: string) =>\n Reflect.has(api, methodName) &&\n typeof api[methodName as keyof typeof api] === \"function\"\n );\n });\n }\n\n /**\n * True when al extensions have loaded.\n */\n public isReady(): boolean {\n return this.isLoaded && !this.error;\n }\n\n /**\n * Loads the extension. Returns a promise which resolves when the extension\n * has loaded. The Host calls this method after retrieving extensions.\n */\n public async load() {\n try {\n if (!this.apis) {\n await this.connect();\n }\n return this.apis;\n } catch (e) {\n this.apis = null;\n this.guest = null;\n this.error = e instanceof Error ? e : new Error(String(e));\n throw e;\n }\n }\n\n /**\n * The host-side equivalent of {@link @adobe/uix-guest#register}. Pass a set\n * of methods down to the guest as proxies.\n */\n public provide(apis: RemoteHostApis) {\n Object.assign(this.hostApis, apis);\n this.emit(\"hostprovide\", { guestPort: this, apis });\n }\n\n /**\n * Disconnect from the extension.\n */\n public async unload(): Promise<void> {\n if (this.connection) {\n await this.connection.destroy();\n }\n for (const connection of this.uiConnections.values()) {\n await connection.destroy();\n }\n if (this.frame && this.frame.parentElement) {\n this.frame.parentElement.removeChild(this.frame);\n this.frame = undefined;\n }\n this.emit(\"unload\", { guestPort: this });\n }\n\n // #endregion Public Methods (6)\n\n // #region Private Methods (6)\n\n private assert(\n condition: boolean,\n errorMessage: () => string\n ): asserts condition {\n if (!condition) {\n throw new Error(\n `Error in guest extension \"${this.id}\": ${errorMessage()}`\n );\n }\n }\n\n private assertReady() {\n this.assert(this.isReady(), () => \"Attempted to interact before loaded\");\n }\n\n private attachFrame(iframe: HTMLIFrameElement) {\n return connectToChild<RemoteHostApis<GuestApi>>({\n iframe,\n debug: this.debug,\n childOrigin: this.url.origin,\n timeout: this.timeout,\n methods: {\n getSharedContext: () => this.sharedContext,\n invokeHostMethod: (address: HostMethodAddress) =>\n this.invokeHostMethod(address),\n },\n });\n }\n\n private async connect() {\n this.frame = this.runtimeContainer.ownerDocument.createElement(\"iframe\");\n this.frame.setAttribute(\"src\", this.url.href);\n this.frame.setAttribute(\"data-uix-guest\", \"true\");\n this.runtimeContainer.appendChild(this.frame);\n if (this.debugLogger) {\n this.debugLogger.info(\n `Guest ${this.id} attached iframe of ${this.url.href}`,\n this\n );\n }\n this.connection = this.attachFrame(this.frame);\n this.guest = (await this.connection\n .promise) as unknown as GuestProxyWrapper;\n this.apis = this.guest.apis || {};\n this.isLoaded = true;\n if (this.debugLogger) {\n this.debugLogger.info(\n `Guest ${this.id} established connection, received methods`,\n this.apis,\n this\n );\n }\n }\n\n private getHostMethodCallee<T = unknown>(\n { name, path }: HostMethodAddress,\n methodSource: RemoteHostApis\n ): Methods {\n const dots = (level: number) =>\n `uix.host.${path.slice(0, level).join(\".\")}`;\n const methodCallee = path.reduce((current, prop, level) => {\n this.assert(\n Reflect.has(current, prop),\n () => `${dots(level)} has no property \"${prop}\"`\n );\n const next = current[prop];\n this.assert(\n typeof next === \"object\",\n () =>\n `${dots(\n level\n )}.${prop} is not an object; namespaces must be objects with methods`\n );\n return next as RemoteHostApis<GuestApi>;\n }, methodSource);\n this.assert(\n typeof methodCallee[name] === \"function\" &&\n Reflect.has(methodCallee, name),\n () => `\"${dots(path.length - 1)}.${name}\" is not a function`\n );\n return methodCallee;\n }\n\n private invokeHostMethod<T = unknown>(\n address: HostMethodAddress,\n privateMethods?: RemoteHostApis\n ): T {\n const { name, path, args = [] } = address;\n this.assert(name && typeof name === \"string\", () => \"Method name required\");\n this.assert(\n path.length > 0,\n () =>\n `Cannot call a method directly on the host; \".${name}()\" must be in a namespace.`\n );\n let methodCallee;\n if (privateMethods) {\n try {\n methodCallee = this.getHostMethodCallee(address, privateMethods);\n } catch (e) {\n this.debugLogger.warn(\"Private method not found!\", address);\n }\n }\n if (!methodCallee) {\n methodCallee = this.getHostMethodCallee(address, this.hostApis);\n }\n const method = methodCallee[name] as (...args: unknown[]) => T;\n this.emit(\"beforecallhostmethod\", { guestPort: this, name, path, args });\n return method.apply(methodCallee, [\n { id: this.id, url: this.url },\n ...args,\n ]) as T;\n }\n\n // #endregion Private Methods (6)\n}\n","/*\nCopyright 2022 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\n/* eslint-disable @typescript-eslint/restrict-template-expressions */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/**\n * Adapter to attach console logging listeners to a Host running in an app\n * @hidden\n */\nimport {\n debugEmitter,\n EmitterDebugLogger,\n Emits,\n GuestConnection,\n} from \"@adobe/uix-core\";\nimport type { PortEvents } from \"./port.js\";\nimport type { HostEventLoadAllGuests, HostEvents } from \"./host.js\";\n\ntype GenericPortEvents = PortEvents<Record<string, unknown>>;\n\ntype Portlike = GuestConnection & Emits<GenericPortEvents>;\n\nexport function debugHost(host: Emits<HostEvents>): EmitterDebugLogger {\n const hostLogger = debugEmitter(host, {\n theme: \"blue medium\",\n type: \"Host\",\n });\n hostLogger\n .listen(\"guestbeforeload\", (log, event) => {\n const { detail } = event;\n const guest = detail.guest as Portlike;\n log.info(event, `Guest ID ${guest.id}`);\n const portLogger = debugEmitter(guest, {\n theme: \"green medium\",\n type: \"Port\",\n id: `${host.id} ➔ ${guest.id}`,\n });\n portLogger\n .listen(\"hostprovide\", (log, event) => {\n log.info(\"received APIs\", event.detail.apis);\n })\n .listen(\"beforecallhostmethod\", (log, event) => {\n log.info(event.detail);\n })\n .listen(\"unload\", (log, event) => {\n log.info(event.detail);\n log.detach();\n });\n })\n .listen(\"guestload\", (log, e) => {\n log.info(e.detail.guest.id, e.detail.guest);\n })\n .listen(\"error\", (log, e) => {\n log.error(`Error: ${e.detail.error.message}`, e);\n })\n .listen(\n \"loadallguests\",\n (log, { detail: { failed, loaded, host } }: HostEventLoadAllGuests) => {\n if (failed.length > 0) {\n log.error(\"%d guests failed to load!\", failed.length);\n }\n log.info(\"%d guests loaded\", loaded.length, host);\n }\n )\n .listen(\"unload\", (log) => {\n log.info(\"Unloaded guest and container.\");\n log.detach();\n });\n return hostLogger;\n}\n","/*\nCopyright 2022 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nimport { InstalledExtensions, ExtensionsProvider } from \"../host.js\";\n\ninterface ExtensionDefinition {\n name: string;\n title: string;\n description: string;\n icon: string;\n publisher: string;\n endpoints: Record<string, EndpointDefinition>;\n xrInfo: ExtensionInfo;\n status: string;\n}\n\ntype EndpointDefinition = Record<string, Array<OperationDefinition>>;\n\ninterface ExtensionInfo {\n supportEmail: string;\n appId: string;\n}\n\ninterface OperationDefinition {\n href: string;\n metadata: OperationMetadata;\n}\n\ninterface OperationMetadata {\n services: Array<object>;\n profile: OperationProfile;\n}\n\ninterface OperationProfile {\n client_id: string;\n scope: string;\n}\n\n/** @public */\nexport interface ExtensionRegistryEndpointRegistration {\n service: string;\n extensionPoint: string;\n version: string;\n}\n\n/** @public */\nexport interface ExtensionRegistryExtensionRegistration\n extends ExtensionRegistryEndpointRegistration {\n imsOrg: string;\n}\n\n/** @public */\nexport interface ExtensionRegistryConnection {\n baseUrl?: string;\n apiKey: string;\n auth: {\n schema: \"Basic\" | \"Bearer\";\n imsToken: string;\n };\n}\n\n/** @public */\nexport interface ExtensionRegistryConfig\n extends ExtensionRegistryExtensionRegistration,\n ExtensionRegistryConnection {}\n\nfunction buildEndpointPath(\n config: ExtensionRegistryEndpointRegistration\n): string {\n return `${config.service}/${config.extensionPoint}/${config.version}`;\n}\n\nfunction ensureProtocolSpecified(url: string) {\n if (url.startsWith(\"https://\")) {\n return url;\n }\n if (url.startsWith(\"http://\")) {\n return url;\n }\n return `https://${url}`;\n}\n\nasync function fetchExtensionsFromRegistry(\n config: ExtensionRegistryConfig\n): Promise<Array<ExtensionDefinition>> {\n const resp = await fetch(\n `${ensureProtocolSpecified(\n config.baseUrl || \"appregistry.adobe.io\"\n )}/myxchng/v1/org/${encodeURIComponent(\n config.imsOrg\n )}/xtn/${buildEndpointPath(config)}?auth=true`,\n {\n headers: {\n Accept: \"application/json\",\n Authorization: `${config.auth.schema} ${config.auth.imsToken}`, // todo: check if auth schema needed (initial implementation was without it)\n \"X-Api-Key\": config.apiKey,\n },\n }\n );\n\n if (resp.status != 200) {\n throw new Error(\n `extension registry returned non-200 response (${\n resp.status\n }): ${await resp.text()}`\n );\n }\n\n return await resp.json();\n}\n\nfunction extensionRegistryExtensionsProvider(\n config: ExtensionRegistryConfig\n): Promise<InstalledExtensions> {\n const erEndpoint = buildEndpointPath(config);\n return fetchExtensionsFromRegistry(config).then((out) =>\n out.reduce((a, e: ExtensionDefinition) => {\n if (e.status !== \"PUBLISHED\") {\n return a;\n }\n\n return {\n ...a,\n // todo: make safer way to extract href\n [e.name]: e.endpoints[erEndpoint].view[0].href,\n };\n }, {})\n );\n\n return Promise.resolve({});\n}\n\n/**\n * Create a callback that fetches extensions from the registry.\n * @public\n */\nexport function createExtensionRegistryProvider(\n config: ExtensionRegistryConfig\n): ExtensionsProvider {\n return function () {\n return extensionRegistryExtensionsProvider(config);\n };\n}\n","/*\nCopyright 2022 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nimport { InstalledExtensions, ExtensionsProvider } from \"../host.js\";\n\n/**\n * Combine multiple {@link @adobe/uix-host#ExtensionsProvider} callbacks into a\n * single callback, which aggregates and dedupes all extensions from all\n * providers into one namespaced object.\n * @public\n */\nexport function combineExtensionsFromProviders(\n ...providers: Array<ExtensionsProvider>\n): ExtensionsProvider {\n return () =>\n Promise.all(providers.map((ep: ExtensionsProvider) => ep())).then(\n (extensionsBatches: Array<InstalledExtensions>) => {\n return Object.assign({}, ...extensionsBatches);\n }\n );\n}\n","/*\nCopyright 2022 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nimport { ExtensionsProvider } from \"../host.js\";\n\n/**\n * Mute any errors produced by provider.\n * This function would execute given provider and return its results as is, if any error occurs this provider will log it\n * any return an empty array of extensions.\n * @public\n */\nexport function mutedProvider(\n provider: ExtensionsProvider\n): ExtensionsProvider {\n return async () => {\n try {\n return await provider();\n } catch (error) {\n console.error(`Extension provider has failed: ${error.message}`, {\n error,\n });\n return {};\n }\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/host.ts","../src/port.ts","../src/debug-host.ts","../src/extensions-provider/extension-registry.ts","../src/extensions-provider/composition.ts","../src/extensions-provider/mute.ts"],"names":["Emitter","log","event","host","window"],"mappings":"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","sourcesContent":["/*\nCopyright 2022 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nimport type {\n Extension,\n GuestConnection,\n NamedEvent,\n Emits,\n GuestApis,\n} from \"@adobe/uix-core\";\nimport type { CapabilitySpec } from \"./port.js\";\nimport { Emitter, quietConsole } from \"@adobe/uix-core\";\nimport { Port, PortOptions } from \"./port.js\";\nimport { debugHost } from \"./debug-host.js\";\n\n/**\n * Dictionary of {@link Port} objects by extension ID.\n * @public\n */\nexport type PortMap = Map<string, GuestConnection>;\n\n/** @public */\nexport type HostEvent<\n Type extends string = string,\n Detail = Record<string, unknown>\n> = NamedEvent<Type, Detail & Record<string, unknown> & { host: Host }>;\n/** @public */\ntype HostGuestEvent<Type extends string> = HostEvent<\n `guest${Type}`,\n { guest: GuestConnection }\n>;\n\n/**\n * All guests requested by host have been loaded and connected.\n * @public\n */\nexport type HostEventLoadAllGuests = HostEvent<\n \"loadallguests\",\n { failed: GuestConnection[]; loaded: GuestConnection[] }\n>;\n\n/**\n * Shared context has been set or updated; all guests receive this event too.\n * @public\n */\n\nexport type HostEventContextChange = HostEvent<\n \"contextchange\",\n { context: SharedContextValues }\n>;\n\n/**\n * An error has occurred during loading or unloading of guests.\n * @public\n */\nexport type HostEventError = HostEvent<\"error\", { error: Error }>;\n\n/** @public */\nexport type HostEvents =\n | HostGuestEvent<\"beforeload\">\n | HostGuestEvent<\"load\">\n | HostEvent<\"beforeunload\">\n | HostEvent<\"unload\">\n | HostEventLoadAllGuests\n | HostEventContextChange\n | HostEventError;\n\n/** @public */\nexport type InstalledExtensions = Record<Extension[\"id\"], Extension[\"url\"]>;\n/** @public */\nexport type ExtensionsProvider = () => Promise<InstalledExtensions>;\n\n/**\n * Values for shared context. Must be a plain object, serializable to JSON.\n * @public\n */\nexport type SharedContextValues = Record<string, unknown>;\n\n/** @public */\nexport interface HostConfig {\n /**\n * Human-readable \"slug\" name of the extensible area--often an entire app.\n * This string serves as a namespace for extension points within the area.\n */\n hostName: string;\n /**\n * A DOM element _outside_ of the React root. This is necessary to preserve\n * the lifetime of the iframes which are running extension objects; if they\n * live inside the React root, then React could unexpectedly re-render the\n * iframe tags themselves at any time, causing a reload of the frame.\n */\n runtimeContainer?: HTMLElement;\n /**\n * Copiously log lifecycle events.\n */\n debug?: boolean;\n /**\n * Default options to use for every guest Port.\n *\n * If `config.debug` is true, then the guest options will have `debug: true`\n * unless `debug: false` is explicitly passed in `guestOptions`.\n */\n guestOptions?: PortOptions;\n /**\n * A read-only dictionary of values that the host will supply to all the\n * guests.\n */\n sharedContext?: SharedContextValues;\n}\n\n/**\n * Callback to use to filter the list returned from {@link Host.(getLoadedGuests:2)}\n * @public\n */\ntype GuestFilter = (item: GuestConnection) => boolean;\n\nconst passAllGuests = () => true;\n\n/**\n * Manager object for connecting to {@link @adobe/uix-guest#GuestServer |\n * GuestServers} and {@link @adobe/uix-guest#GuestUI | GuestUIs}, providing and\n * receiving their APIs, and providing them to the app for interacting with UI.\n *\n * @remarks\n * The Host object is the main connection manager for all UIX Guests.\n * Making an app extensible requires creating a Host object.\n *\n * The extensible app using the Hostis responsible for providing a list of\n * extension references to the Host object. Use {@link\n * createExtensionRegistryProvider} for that purpose. Once you have retrieved a\n * list of extensions available to the host app, pass it to {@link Host.load}.\n *\n * When a Host creates a Guest, it must create an `<iframe>` element to contain\n * the Guest's main {@link @adobe/uix-guest#GuestServer} runtime, which runs\n * invisibly in the background. To do this, the Host creates a hidden container\n * in the body of the document. It is a `<div>` element with the attribute\n * `data-uix-guest-container`. Loaded GuestServers will be injected into this\n * hidden element and removed as necessary. When {@link Host.unload} is called,\n * the Host removes the hidden container from the document after unloading.\n *\n * @public\n */\nexport class Host extends Emitter<HostEvents> {\n /**\n * {@inheritDoc HostEventLoadAllGuests}\n * @eventProperty\n */\n public loadallguests: HostEventLoadAllGuests;\n\n /**\n * One guest has loaded.\n * @eventProperty\n */\n public guestload: HostGuestEvent<\"load\">;\n\n /**\n * About to attempt to load and connect to a Guest.\n * @eventProperty\n */\n public guestbeforeload: HostGuestEvent<\"beforeload\">;\n\n /**\n * About to unload a guest and remove its {@link @adobe/uix-guest#GuestServer}\n * instance as well as all its {@link @adobe/uix-guest#GuestUI} instances.\n * @eventProperty\n */\n public guestbeforeunload: HostGuestEvent<\"beforeunload\">;\n\n /**\n * Unloaded a guest and removed its {@link @adobe/uix-guest#GuestServer}\n * instance as well as all its {@link @adobe/uix-guest#GuestUI} instances.\n * @eventProperty\n */\n public guestunload: HostGuestEvent<\"unload\">;\n\n /**\n * {@inheritDoc HostEventContextChange}\n * @eventProperty\n */\n public contextchange: HostEventContextChange;\n\n /**\n * {@inheritDoc HostEventError}\n * @eventProperty\n */\n public error: HostEventError;\n\n private static containerStyle = {\n position: \"fixed\",\n width: \"1px\",\n height: \"1px\",\n pointerEvents: \"none\",\n opacity: 0,\n top: 0,\n left: \"-1px\",\n };\n /**\n * Unique string identifying the Host object.\n */\n hostName: string;\n /**\n * `true` if any extension in {@link Host.guests} has created a {@link\n * @adobe/uix-guest#GuestServer}, but the Guest has not yet loaded.\n */\n loading = false;\n /**\n * A Map of of the loaded guests.\n */\n guests: PortMap = new Map();\n private cachedCapabilityLists: WeakMap<object, GuestConnection[]> =\n new WeakMap();\n private runtimeContainer: HTMLElement;\n private guestOptions: PortOptions;\n private logger: Console = quietConsole;\n private sharedContext: SharedContextValues;\n constructor(config: HostConfig) {\n super(config.hostName);\n const { guestOptions = {} } = config;\n this.guestOptions = {\n ...guestOptions,\n debug: guestOptions.debug === false ? false : !!config.debug,\n };\n this.hostName = config.hostName;\n this.sharedContext = config.sharedContext || {};\n this.runtimeContainer = config.runtimeContainer;\n if (config.debug) {\n this.logger = debugHost(this);\n }\n }\n /**\n * Return all loaded guests.\n */\n getLoadedGuests(): GuestConnection[];\n /**\n * Return loaded guests which satisfy the passed test function.\n */\n getLoadedGuests(filter: GuestFilter): GuestConnection[];\n /**\n * Return loaded guests which expose the provided {@link CapabilitySpec}.\n */\n getLoadedGuests<Apis extends GuestApis>(\n capabilities: CapabilitySpec<Apis>\n ): GuestConnection[];\n getLoadedGuests<Apis extends GuestApis = never>(\n filterOrCapabilities?: CapabilitySpec<Apis> | GuestFilter\n ): GuestConnection[] {\n if (typeof filterOrCapabilities === \"object\") {\n return this.getLoadedGuestsWith<Apis>(filterOrCapabilities);\n }\n const filter = filterOrCapabilities || passAllGuests;\n const result = [];\n for (const guest of this.guests.values()) {\n if (guest.isReady() && filter(guest)) {\n result.push(guest);\n }\n }\n return result;\n }\n /**\n * Set the object of shared values that all Guests can access via {@link @adobe/uix-guest#GuestServer.sharedContext}.\n * This overwrites any previous object.\n *\n * @example Exposes `authToken` to all Guests. Guests can call `this.sharedContext.get('authToken')` to retrieve this value.\n * ```javascript\n * host.shareContext({\n * authToken: '82ba19b'\n * });\n * ```\n *\n * @example Overwrites the previous sharedContext, deleting `authToken` and providing `secret` and `auth` instead.\n * ```javascript\n * host.shareContext({\n * secret: 'squirrel',\n * auth: false\n * });\n * ```\n */\n shareContext(context: SharedContextValues): void;\n /**\n * Update the object of shared values that all Guests can access via {@link\n * @adobe/uix-guest#GuestServer.sharedContext}. This method takes a callback\n * which receives the previous context and may return an entirely new context,\n * or new values merged with the old context.\n *\n * @remarks This callback pattern allows the shared context values to be\n * mutable while the internal context object references are immutable, which\n * is important for synchronizing. with guests.\n *\n * @example Overwrites a context object based on the previous one.\n * ```javascript\n * host.shareContext(oldContext => ({\n * counter: oldContext.counter + 1\n * }))\n * ```\n *\n * @example Updates a context while preserving other existing values.\n * ```javascript\n * host.shareContext(oldContext => ({\n * ...oldContext,\n * counter: oldContext.counter + 1\n * }))\n * ```\n */\n shareContext(\n setter: (context: SharedContextValues) => SharedContextValues\n ): void;\n shareContext(\n setter: (context: SharedContextValues) => SharedContextValues\n ): void;\n shareContext(\n setterOrContext:\n | ((context: SharedContextValues) => SharedContextValues)\n | SharedContextValues\n ) {\n if (typeof setterOrContext === \"function\") {\n this.sharedContext = setterOrContext(this.sharedContext);\n } else {\n this.sharedContext = setterOrContext;\n }\n this.emit(\"contextchange\", {\n host: this,\n context: this.sharedContext,\n });\n }\n /**\n * Load extension into host application from provided extension description.\n * Returned promise resolves when all extensions are loaded and registered.\n *\n * @param extensions - List of extension descriptors. Normally, the Host should receive this value from an {@link ExtensionsProvider}.\n * @param options - Custom options to be used as defaults for each {@link Port} object created for each guest.\n * @returns Promise which resolves when all guests have been loaded.\n */\n async load(\n extensions: InstalledExtensions,\n options?: PortOptions\n ): Promise<void> {\n this.runtimeContainer =\n this.runtimeContainer || this.createRuntimeContainer(window);\n const failed: GuestConnection[] = [];\n const loaded: GuestConnection[] = [];\n this.loading = true;\n await Promise.all(\n Object.entries(extensions).map(async ([id, url]) => {\n const port = await this.loadOneGuest(id, url, options);\n (port.error ? failed : loaded).push(port);\n })\n );\n this.loading = false;\n this.emit(\"loadallguests\", { host: this, failed, loaded });\n }\n /**\n * Unload all extensions and remove their frames/workers. Use this to unmount\n * a UI or when switching to a different extensible UI.\n */\n async unload(): Promise<void> {\n this.emit(\"beforeunload\", { host: this });\n await Promise.all([...this.guests.values()].map((guest) => guest.unload()));\n this.guests.clear();\n this.runtimeContainer.parentElement.removeChild(this.runtimeContainer);\n this.emit(\"unload\", { host: this });\n }\n private createRuntimeContainer(window: Window) {\n const { document } = window;\n const container = document.createElement(\"div\");\n container.setAttribute(\"data-uix-guest-container\", this.hostName);\n Object.assign(container.style, Host.containerStyle);\n document.body.appendChild(container);\n return container;\n }\n private async loadOneGuest(\n id: string,\n urlString: string,\n options: PortOptions = {}\n ): Promise<GuestConnection> {\n let guest = this.guests.get(id);\n if (!guest) {\n const url = new URL(urlString);\n guest = new Port({\n owner: this.hostName,\n id,\n url,\n runtimeContainer: this.runtimeContainer,\n options: {\n ...this.guestOptions,\n ...options,\n },\n logger: this.logger,\n sharedContext: this.sharedContext,\n events: this as Emits,\n });\n this.guests.set(id, guest);\n }\n this.emit(\"guestbeforeload\", { guest, host: this });\n try {\n await guest.load();\n } catch (e: unknown) {\n const error = e instanceof Error ? e : new Error(String(e));\n this.emit(\"error\", { host: this, guest, error });\n console.warn(\"Failed to load extension at endpoint %s\", guest.url);\n return guest;\n }\n // this new guest might have new capabilities, so the identities of the\n // cached capability sets will need to change, to alert subscribers\n this.cachedCapabilityLists = new WeakMap();\n this.emit(\"guestload\", { guest, host: this });\n return guest;\n }\n private getLoadedGuestsWith<Apis extends GuestApis>(\n capabilities: CapabilitySpec<Apis>\n ) {\n if (this.cachedCapabilityLists.has(capabilities)) {\n return this.cachedCapabilityLists.get(capabilities);\n }\n const guestsWithCapabilities = this.getLoadedGuests((guest) =>\n guest.hasCapabilities(capabilities)\n );\n this.cachedCapabilityLists.set(capabilities, guestsWithCapabilities);\n return guestsWithCapabilities;\n }\n}\n","/*\nCopyright 2022 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nimport type {\n Emits,\n GuestConnection,\n HostMethodAddress,\n NamedEvent,\n RemoteHostApis,\n GuestApis,\n CrossRealmObject,\n Unsubscriber,\n VirtualApi,\n} from \"@adobe/uix-core\";\nimport { Emitter, connectIframe } from \"@adobe/uix-core\";\n\n/**\n * A specifier for methods to be expected on a remote interface.\n *\n * @remarks\n * A CapabilitySpec is a description of an interface, like a very simplified\n * type definition. It specifies an object structure and the paths in that\n * structure that must be functions. (It doesn't specify anything about the\n * signatures or return values of those functions.)\n *\n * Use CapabilitySpec objects as queries, or filters, to get a subset of\n * installed extensions which have registered methods which match the spec.\n *\n * @example\n * As an extensible app developer, you are making an extension point for spell\n * check. Your code expects extensions to register an API `spellCheck` with\n * methods called `spellCheck.correct(text)` and `spellCheck.suggest(text)`.\n *\n * ```javascript\n * async function correctText(text) {\n * const spellCheckers = host.getLoadedGuests({\n * spellCheck: [\n * 'correct',\n * 'suggest'\n * ]\n * });\n * let correcting = text;\n * for (const checker of spellCheckers) {\n * correcting = await checker.apis.spellCheck.correct(correcting);\n * }\n * return Promise.all(checkers.map(checker =>\n * checker.apis.spellCheck.suggest(correcting)\n * ));\n * }\n * ```\n *\n * @public\n */\nexport type CapabilitySpec<T extends GuestApis> = {\n [Name in keyof T]: (keyof T[Name])[];\n};\n\n/**\n * Interface for decoupling of guest Penpal object\n * @internal\n */\ninterface GuestProxyWrapper {\n // #region Properties (1)\n\n /**\n * Methods from guest\n */\n apis: RemoteHostApis;\n\n // #endregion Properties (1)\n\n // #region Public Methods (1)\n\n /**\n * Emit an event in the guest frame\n */\n emit(type: string, detail: unknown): Promise<void>;\n\n // #endregion Public Methods (1)\n}\n\n/** @public */\ntype PortEvent<\n GuestApi,\n Type extends string = string,\n Detail = Record<string, unknown>\n> = NamedEvent<\n Type,\n Detail &\n Record<string, unknown> & {\n guestPort: Port<GuestApi>;\n }\n>;\n\n/** @public */\nexport type PortEvents<\n GuestApi,\n HostApi extends Record<string, unknown> = Record<string, unknown>\n> =\n | PortEvent<GuestApi, \"hostprovide\">\n | PortEvent<GuestApi, \"unload\">\n | PortEvent<GuestApi, \"beforecallhostmethod\", HostMethodAddress<HostApi>>;\n\n/** @public */\nexport type PortOptions = {\n /**\n * Time in milliseconds to wait for the guest to connect before throwing.\n */\n timeout?: number;\n /**\n * Set true to log copiously in the console.\n */\n debug?: boolean;\n};\n\nconst defaultOptions = {\n timeout: 10000,\n debug: false,\n};\n\n/**\n * A Port is the Host-maintained object representing an extension running as a\n * guest. It exposes methods registered by the Guest, and can provide Host\n * methods back to the guest.\n *\n * @remarks\n * When the Host object loads extensions via {@link Host.load}, it creates a\n * Port object for each extension. When retrieving and filtering extensions\n * via {@link Host.(getLoadedGuests:2)}, a list of Port objects is returned. From\n * the point of view of the extensible app using the Host object, extensions\n * are always Port objects, which expose the methods registered by the\n * extension at the {@link Port.apis} property.\n *\n * @privateRemarks\n * We've gone through several possible names for this object. GuestProxy,\n * GuestInterface, GuestConnection, etc. \"Port\" is not ideal, but it conflicted\n * the least with other types we defined in early drafts. It's definitely\n * something we should review.\n * @public\n */\nexport class Port<GuestApi>\n extends Emitter<PortEvents<GuestApi>>\n implements GuestConnection\n{\n public get apis() {\n if (this.isReady() && this.guestServer) {\n const server = this.guestServer.getRemoteApi();\n return server && server.apis;\n }\n }\n\n // #region Properties (13)\n\n private debug: boolean;\n private logger?: Console;\n private frame: HTMLIFrameElement;\n private hostApis: RemoteHostApis = {};\n private isLoaded = false;\n private runtimeContainer: HTMLElement;\n private sharedContext: Record<string, unknown>;\n private subscriptions: Unsubscriber[] = [];\n private timeout: number;\n\n /**\n * Dictionary of namespaced methods that were registered by this guest at the\n * time of connection, using {@link @adobe/uix-guest#register}.\n *\n * @remarks\n * These methods are proxy methods; you can only pass serializable objects to\n * them, not class instances, methods or callbacks.\n * @public\n */\n /**\n * If any errors occurred during the loading of guests, this property will\n * contain the error that was raised.\n * @public\n */\n error?: Error;\n /**\n * The URL of the guest provided by the extension registry. The Host will\n * load this URL in the background, in the invisible the bootstrap frame, so\n * this URL must point to a page that calls {@link @adobe/uix-guest#register}\n * when it loads.\n */\n public url: URL;\n private guestServer: CrossRealmObject<GuestProxyWrapper>;\n\n // #endregion Properties (13)\n\n // #region Constructors (1)\n\n constructor(config: {\n owner: string;\n id: string;\n url: URL;\n /**\n * An alternate DOM element to use for invisible iframes. Will create its\n * own if this option is not populated with a DOM element.\n */\n runtimeContainer: HTMLElement;\n options: PortOptions;\n logger?: Console;\n /**\n * Initial object to populate the shared context with. Once the guest\n * connects, it will be able to access these properties.\n */\n sharedContext: Record<string, unknown>;\n events: Emits;\n }) {\n super(config.id);\n const { timeout, debug } = { ...defaultOptions, ...(config.options || {}) };\n this.timeout = timeout;\n this.debug = debug;\n this.id = config.id;\n this.url = config.url;\n this.runtimeContainer = config.runtimeContainer;\n this.sharedContext = config.sharedContext;\n this.subscriptions.push(\n config.events.addEventListener(\"contextchange\", async (event) => {\n this.sharedContext = (\n (event as CustomEvent).detail as unknown as Record<string, unknown>\n ).context as Record<string, unknown>;\n await this.load();\n await this.guestServer\n .getRemoteApi()\n .emit(\"contextchange\", { context: this.sharedContext });\n })\n );\n }\n\n // #endregion Constructors (1)\n\n // #region Public Methods (6)\n\n /**\n * Connect an iframe element which is displaying another page in the extension\n * with the extension's bootstrap frame, so they can share context and events.\n */\n public attachUI(iframe: HTMLIFrameElement) {\n return this.attachFrame(iframe);\n }\n\n /**\n * Returns true if the guest has registered methods matching the provided\n * capability spec. A capability spec is simply an object whose properties are\n * declared in an array of keys, description the names of the functions and\n * methods that the Port will expose.\n */\n public hasCapabilities(requiredMethods: CapabilitySpec<GuestApis>) {\n this.assertReady();\n return Object.keys(requiredMethods).every((key) => {\n if (!Reflect.has(this.apis, key)) {\n return false;\n }\n const api = this.apis[key];\n const methodList = requiredMethods[\n key as keyof typeof requiredMethods\n ] as string[];\n return methodList.every(\n (methodName: string) =>\n Reflect.has(api, methodName) &&\n typeof api[methodName as keyof typeof api] === \"function\"\n );\n });\n }\n\n /**\n * True when al extensions have loaded.\n */\n public isReady(): boolean {\n return this.isLoaded && !this.error;\n }\n\n /**\n * Loads the extension. Returns a promise which resolves when the extension\n * has loaded. The Host calls this method after retrieving extensions.\n */\n public async load() {\n try {\n if (!this.apis) {\n await this.connect();\n }\n return this.apis;\n } catch (e) {\n this.guestServer = null;\n this.error = e instanceof Error ? e : new Error(String(e));\n throw e;\n }\n }\n\n /**\n * The host-side equivalent of {@link @adobe/uix-guest#register}. Pass a set\n * of methods down to the guest as proxies.\n */\n public provide(apis: RemoteHostApis) {\n Object.assign(this.hostApis, apis);\n this.emit(\"hostprovide\", { guestPort: this, apis });\n }\n\n /**\n * Disconnect from the extension.\n */\n public async unload(): Promise<void> {\n if (this.frame && this.frame.parentElement) {\n this.frame.parentElement.removeChild(this.frame);\n this.frame = undefined;\n }\n this.emit(\"unload\", { guestPort: this });\n }\n\n // #endregion Public Methods (6)\n\n // #region Private Methods (6)\n\n private assert(\n condition: boolean,\n errorMessage: () => string\n ): asserts condition {\n if (!condition) {\n throw new Error(\n `Error in guest extension \"${this.id}\": ${errorMessage()}`\n );\n }\n }\n\n private assertReady() {\n this.assert(this.isReady(), () => \"Attempted to interact before loaded\");\n }\n\n private attachFrame<T = unknown>(iframe: HTMLIFrameElement) {\n return connectIframe<T>(\n iframe,\n {\n logger: this.logger,\n targetOrigin: \"*\",\n timeout: this.timeout,\n },\n {\n getSharedContext: () => this.sharedContext,\n invokeHostMethod: (address: HostMethodAddress) =>\n this.invokeHostMethod(address),\n }\n );\n }\n\n private async connect() {\n this.frame = this.runtimeContainer.ownerDocument.createElement(\"iframe\");\n this.frame.setAttribute(\"src\", this.url.href);\n this.frame.setAttribute(\"data-uix-guest\", \"true\");\n this.runtimeContainer.appendChild(this.frame);\n if (this.logger) {\n this.logger.info(\n `Guest ${this.id} attached iframe of ${this.url.href}`,\n this\n );\n }\n this.guestServer = await this.attachFrame<GuestProxyWrapper>(this.frame);\n this.isLoaded = true;\n if (this.logger) {\n this.logger.info(\n `Guest ${this.id} established connection, received methods`,\n this.apis,\n this\n );\n }\n }\n\n private getHostMethodCallee<T = unknown>(\n { name, path }: HostMethodAddress,\n methodSource: RemoteHostApis\n ): RemoteHostApis<VirtualApi> {\n const dots = (level: number) =>\n `uix.host.${path.slice(0, level).join(\".\")}`;\n const methodCallee = path.reduce((current, prop, level) => {\n this.assert(\n Reflect.has(current, prop),\n () => `${dots(level)} has no property \"${prop}\"`\n );\n const next = current[prop];\n this.assert(\n typeof next === \"object\",\n () =>\n `${dots(\n level\n )}.${prop} is not an object; namespaces must be objects with methods`\n );\n return next as RemoteHostApis<GuestApi>;\n }, methodSource);\n this.assert(\n typeof methodCallee[name] === \"function\" &&\n Reflect.has(methodCallee, name),\n () => `\"${dots(path.length - 1)}.${name}\" is not a function`\n );\n return methodCallee;\n }\n\n private invokeHostMethod<T = unknown>(\n address: HostMethodAddress,\n privateMethods?: RemoteHostApis\n ): T {\n const { name, path, args = [] } = address;\n this.assert(name && typeof name === \"string\", () => \"Method name required\");\n this.assert(\n path.length > 0,\n () =>\n `Cannot call a method directly on the host; \".${name}()\" must be in a namespace.`\n );\n let methodCallee;\n if (privateMethods) {\n try {\n methodCallee = this.getHostMethodCallee(address, privateMethods);\n } catch (e) {\n this.logger.warn(\"Private method not found!\", address);\n }\n }\n if (!methodCallee) {\n methodCallee = this.getHostMethodCallee(address, this.hostApis);\n }\n const method = methodCallee[name] as (...args: unknown[]) => T;\n this.emit(\"beforecallhostmethod\", { guestPort: this, name, path, args });\n return method.apply(methodCallee, [\n { id: this.id, url: this.url },\n ...args,\n ]) as T;\n }\n\n // #endregion Private Methods (6)\n}\n","/*\nCopyright 2022 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\n/* eslint-disable @typescript-eslint/restrict-template-expressions */\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/**\n * Adapter to attach console logging listeners to a Host running in an app\n * @hidden\n */\nimport {\n debugEmitter,\n EmitterDebugLogger,\n Emits,\n GuestConnection,\n} from \"@adobe/uix-core\";\nimport type { PortEvents } from \"./port.js\";\nimport type { HostEventLoadAllGuests, HostEvents } from \"./host.js\";\n\ntype GenericPortEvents = PortEvents<Record<string, unknown>>;\n\ntype Portlike = GuestConnection & Emits<GenericPortEvents>;\n\nexport function debugHost(host: Emits<HostEvents>): EmitterDebugLogger {\n const hostLogger = debugEmitter(host, {\n theme: \"blue medium\",\n type: \"Host\",\n });\n hostLogger\n .listen(\"guestbeforeload\", (log, event) => {\n const { detail } = event;\n const guest = detail.guest as Portlike;\n log.info(event, `Guest ID ${guest.id}`);\n const portLogger = debugEmitter(guest, {\n theme: \"green medium\",\n type: \"Port\",\n id: `${host.id} ➔ ${guest.id}`,\n });\n portLogger\n .listen(\"hostprovide\", (log, event) => {\n log.info(\"received APIs\", event.detail.apis);\n })\n .listen(\"beforecallhostmethod\", (log, event) => {\n log.info(event.detail);\n })\n .listen(\"unload\", (log, event) => {\n log.info(event.detail);\n log.detach();\n });\n })\n .listen(\"guestload\", (log, e) => {\n log.info(e.detail.guest.id, e.detail.guest);\n })\n .listen(\"error\", (log, e) => {\n log.error(`Error: ${e.detail.error.message}`, e);\n })\n .listen(\n \"loadallguests\",\n (log, { detail: { failed, loaded, host } }: HostEventLoadAllGuests) => {\n if (failed.length > 0) {\n log.error(\"%d guests failed to load!\", failed.length);\n }\n log.info(\"%d guests loaded\", loaded.length, host);\n }\n )\n .listen(\"unload\", (log) => {\n log.info(\"Unloaded guest and container.\");\n log.detach();\n });\n return hostLogger;\n}\n","/*\nCopyright 2022 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nimport { InstalledExtensions, ExtensionsProvider } from \"../host.js\";\n\ninterface ExtensionDefinition {\n name: string;\n title: string;\n description: string;\n icon: string;\n publisher: string;\n endpoints: Record<string, EndpointDefinition>;\n xrInfo: ExtensionInfo;\n status: string;\n}\n\ntype EndpointDefinition = Record<string, Array<OperationDefinition>>;\n\ninterface ExtensionInfo {\n supportEmail: string;\n appId: string;\n}\n\ninterface OperationDefinition {\n href: string;\n metadata: OperationMetadata;\n}\n\ninterface OperationMetadata {\n services: Array<object>;\n profile: OperationProfile;\n}\n\ninterface OperationProfile {\n client_id: string;\n scope: string;\n}\n\n/** @public */\nexport interface ExtensionRegistryEndpointRegistration {\n service: string;\n extensionPoint: string;\n version: string;\n}\n\n/** @public */\nexport interface ExtensionRegistryExtensionRegistration\n extends ExtensionRegistryEndpointRegistration {\n imsOrg: string;\n}\n\n/** @public */\nexport interface ExtensionRegistryConnection {\n baseUrl?: string;\n apiKey: string;\n auth: {\n schema: \"Basic\" | \"Bearer\";\n imsToken: string;\n };\n}\n\n/** @public */\nexport interface ExtensionRegistryConfig\n extends ExtensionRegistryExtensionRegistration,\n ExtensionRegistryConnection {}\n\nfunction buildEndpointPath(\n config: ExtensionRegistryEndpointRegistration\n): string {\n return `${config.service}/${config.extensionPoint}/${config.version}`;\n}\n\nfunction ensureProtocolSpecified(url: string) {\n if (url.startsWith(\"https://\")) {\n return url;\n }\n if (url.startsWith(\"http://\")) {\n return url;\n }\n return `https://${url}`;\n}\n\nasync function fetchExtensionsFromRegistry(\n config: ExtensionRegistryConfig\n): Promise<Array<ExtensionDefinition>> {\n const resp = await fetch(\n `${ensureProtocolSpecified(\n config.baseUrl || \"appregistry.adobe.io\"\n )}/myxchng/v1/org/${encodeURIComponent(\n config.imsOrg\n )}/xtn/${buildEndpointPath(config)}?auth=true`,\n {\n headers: {\n Accept: \"application/json\",\n Authorization: `${config.auth.schema} ${config.auth.imsToken}`, // todo: check if auth schema needed (initial implementation was without it)\n \"X-Api-Key\": config.apiKey,\n },\n }\n );\n\n if (resp.status != 200) {\n throw new Error(\n `extension registry returned non-200 response (${\n resp.status\n }): ${await resp.text()}`\n );\n }\n\n return await resp.json();\n}\n\nfunction extensionRegistryExtensionsProvider(\n config: ExtensionRegistryConfig\n): Promise<InstalledExtensions> {\n const erEndpoint = buildEndpointPath(config);\n return fetchExtensionsFromRegistry(config).then((out) =>\n out.reduce((a, e: ExtensionDefinition) => {\n if (e.status !== \"PUBLISHED\") {\n return a;\n }\n\n return {\n ...a,\n // todo: make safer way to extract href\n [e.name]: e.endpoints[erEndpoint].view[0].href,\n };\n }, {})\n );\n\n return Promise.resolve({});\n}\n\n/**\n * Create a callback that fetches extensions from the registry.\n * @public\n */\nexport function createExtensionRegistryProvider(\n config: ExtensionRegistryConfig\n): ExtensionsProvider {\n return function () {\n return extensionRegistryExtensionsProvider(config);\n };\n}\n","/*\nCopyright 2022 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nimport { InstalledExtensions, ExtensionsProvider } from \"../host.js\";\n\n/**\n * Combine multiple {@link @adobe/uix-host#ExtensionsProvider} callbacks into a\n * single callback, which aggregates and dedupes all extensions from all\n * providers into one namespaced object.\n * @public\n */\nexport function combineExtensionsFromProviders(\n ...providers: Array<ExtensionsProvider>\n): ExtensionsProvider {\n return () =>\n Promise.all(providers.map((ep: ExtensionsProvider) => ep())).then(\n (extensionsBatches: Array<InstalledExtensions>) => {\n return Object.assign({}, ...extensionsBatches);\n }\n );\n}\n","/*\nCopyright 2022 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nimport { ExtensionsProvider } from \"../host.js\";\n\n/**\n * Mute any errors produced by provider.\n * This function would execute given provider and return its results as is, if any error occurs this provider will log it\n * any return an empty array of extensions.\n * @public\n */\nexport function mutedProvider(\n provider: ExtensionsProvider\n): ExtensionsProvider {\n return async () => {\n try {\n return await provider();\n } catch (error) {\n console.error(`Extension provider has failed: ${error.message}`, {\n error,\n });\n return {};\n }\n };\n}\n"]}
package/dist/port.d.ts CHANGED
@@ -1,6 +1,5 @@
1
- import type { Emits, GuestConnection, HostMethodAddress, NamedEvent, RemoteHostApis, GuestApis } from "@adobe/uix-core";
1
+ import type { Emits, GuestConnection, HostMethodAddress, NamedEvent, RemoteHostApis, GuestApis, CrossRealmObject } from "@adobe/uix-core";
2
2
  import { Emitter } from "@adobe/uix-core";
3
- import { Connection } from "penpal";
4
3
  /**
5
4
  * A specifier for methods to be expected on a remote interface.
6
5
  *
@@ -79,11 +78,12 @@ export declare type PortOptions = {
79
78
  * @public
80
79
  */
81
80
  export declare class Port<GuestApi> extends Emitter<PortEvents<GuestApi>> implements GuestConnection {
82
- private connection;
81
+ get apis(): {
82
+ [x: string]: {};
83
+ };
83
84
  private debug;
84
- private debugLogger?;
85
+ private logger?;
85
86
  private frame;
86
- private guest;
87
87
  private hostApis;
88
88
  private isLoaded;
89
89
  private runtimeContainer;
@@ -99,14 +99,12 @@ export declare class Port<GuestApi> extends Emitter<PortEvents<GuestApi>> implem
99
99
  * them, not class instances, methods or callbacks.
100
100
  * @public
101
101
  */
102
- apis: RemoteHostApis;
103
102
  /**
104
103
  * If any errors occurred during the loading of guests, this property will
105
104
  * contain the error that was raised.
106
105
  * @public
107
106
  */
108
107
  error?: Error;
109
- private uiConnections;
110
108
  /**
111
109
  * The URL of the guest provided by the extension registry. The Host will
112
110
  * load this URL in the background, in the invisible the bootstrap frame, so
@@ -114,6 +112,7 @@ export declare class Port<GuestApi> extends Emitter<PortEvents<GuestApi>> implem
114
112
  * when it loads.
115
113
  */
116
114
  url: URL;
115
+ private guestServer;
117
116
  constructor(config: {
118
117
  owner: string;
119
118
  id: string;
@@ -124,7 +123,7 @@ export declare class Port<GuestApi> extends Emitter<PortEvents<GuestApi>> implem
124
123
  */
125
124
  runtimeContainer: HTMLElement;
126
125
  options: PortOptions;
127
- debugLogger?: Console;
126
+ logger?: Console;
128
127
  /**
129
128
  * Initial object to populate the shared context with. Once the guest
130
129
  * connects, it will be able to access these properties.
@@ -136,7 +135,7 @@ export declare class Port<GuestApi> extends Emitter<PortEvents<GuestApi>> implem
136
135
  * Connect an iframe element which is displaying another page in the extension
137
136
  * with the extension's bootstrap frame, so they can share context and events.
138
137
  */
139
- attachUI(iframe: HTMLIFrameElement): Connection<RemoteHostApis<GuestApi>>;
138
+ attachUI(iframe: HTMLIFrameElement): Promise<CrossRealmObject<unknown>>;
140
139
  /**
141
140
  * Returns true if the guest has registered methods matching the provided
142
141
  * capability spec. A capability spec is simply an object whose properties are
@@ -152,7 +151,9 @@ export declare class Port<GuestApi> extends Emitter<PortEvents<GuestApi>> implem
152
151
  * Loads the extension. Returns a promise which resolves when the extension
153
152
  * has loaded. The Host calls this method after retrieving extensions.
154
153
  */
155
- load(): Promise<RemoteHostApis<import("@adobe/uix-core").VirtualApi>>;
154
+ load(): Promise<{
155
+ [x: string]: {};
156
+ }>;
156
157
  /**
157
158
  * The host-side equivalent of {@link @adobe/uix-guest#register}. Pass a set
158
159
  * of methods down to the guest as proxies.
@@ -1 +1 @@
1
- {"version":3,"file":"port.d.ts","sourceRoot":"","sources":["../src/port.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"port.d.ts","sourceRoot":"","sources":["../src/port.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/uix-host",
3
- "version": "0.6.5",
3
+ "version": "0.7.1-nightly.20230114",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -18,8 +18,7 @@
18
18
  ],
19
19
  "bugs": "https://github.com/adobe/uix-sdk/issues",
20
20
  "dependencies": {
21
- "@adobe/uix-core": "^0.6.5",
22
- "penpal": "~6.2.2"
21
+ "@adobe/uix-core": "^0.7.1-nightly.20230114"
23
22
  },
24
23
  "files": [
25
24
  "README.md",
package/src/host.ts CHANGED
@@ -220,7 +220,7 @@ export class Host extends Emitter<HostEvents> {
220
220
  new WeakMap();
221
221
  private runtimeContainer: HTMLElement;
222
222
  private guestOptions: PortOptions;
223
- private debugLogger: Console = quietConsole;
223
+ private logger: Console = quietConsole;
224
224
  private sharedContext: SharedContextValues;
225
225
  constructor(config: HostConfig) {
226
226
  super(config.hostName);
@@ -233,7 +233,7 @@ export class Host extends Emitter<HostEvents> {
233
233
  this.sharedContext = config.sharedContext || {};
234
234
  this.runtimeContainer = config.runtimeContainer;
235
235
  if (config.debug) {
236
- this.debugLogger = debugHost(this);
236
+ this.logger = debugHost(this);
237
237
  }
238
238
  }
239
239
  /**
@@ -393,7 +393,7 @@ export class Host extends Emitter<HostEvents> {
393
393
  ...this.guestOptions,
394
394
  ...options,
395
395
  },
396
- debugLogger: this.debugLogger,
396
+ logger: this.logger,
397
397
  sharedContext: this.sharedContext,
398
398
  events: this as Emits,
399
399
  });
package/src/port.ts CHANGED
@@ -17,10 +17,11 @@ import type {
17
17
  NamedEvent,
18
18
  RemoteHostApis,
19
19
  GuestApis,
20
+ CrossRealmObject,
20
21
  Unsubscriber,
22
+ VirtualApi,
21
23
  } from "@adobe/uix-core";
22
- import { Emitter } from "@adobe/uix-core";
23
- import { Connection, connectToChild, Methods } from "penpal";
24
+ import { Emitter, connectIframe } from "@adobe/uix-core";
24
25
 
25
26
  /**
26
27
  * A specifier for methods to be expected on a remote interface.
@@ -68,14 +69,23 @@ export type CapabilitySpec<T extends GuestApis> = {
68
69
  * @internal
69
70
  */
70
71
  interface GuestProxyWrapper {
72
+ // #region Properties (1)
73
+
71
74
  /**
72
75
  * Methods from guest
73
76
  */
74
77
  apis: RemoteHostApis;
78
+
79
+ // #endregion Properties (1)
80
+
81
+ // #region Public Methods (1)
82
+
75
83
  /**
76
84
  * Emit an event in the guest frame
77
85
  */
78
86
  emit(type: string, detail: unknown): Promise<void>;
87
+
88
+ // #endregion Public Methods (1)
79
89
  }
80
90
 
81
91
  /** @public */
@@ -141,13 +151,18 @@ export class Port<GuestApi>
141
151
  extends Emitter<PortEvents<GuestApi>>
142
152
  implements GuestConnection
143
153
  {
144
- // #region Properties (15)
154
+ public get apis() {
155
+ if (this.isReady() && this.guestServer) {
156
+ const server = this.guestServer.getRemoteApi();
157
+ return server && server.apis;
158
+ }
159
+ }
160
+
161
+ // #region Properties (13)
145
162
 
146
- private connection: Connection<RemoteHostApis<GuestApi>>;
147
163
  private debug: boolean;
148
- private debugLogger?: Console;
164
+ private logger?: Console;
149
165
  private frame: HTMLIFrameElement;
150
- private guest: GuestProxyWrapper;
151
166
  private hostApis: RemoteHostApis = {};
152
167
  private isLoaded = false;
153
168
  private runtimeContainer: HTMLElement;
@@ -164,24 +179,22 @@ export class Port<GuestApi>
164
179
  * them, not class instances, methods or callbacks.
165
180
  * @public
166
181
  */
167
- public apis: RemoteHostApis;
168
182
  /**
169
183
  * If any errors occurred during the loading of guests, this property will
170
184
  * contain the error that was raised.
171
185
  * @public
172
186
  */
173
187
  error?: Error;
174
- private uiConnections: Map<string, Connection<RemoteHostApis<GuestApi>>> =
175
- new Map();
176
188
  /**
177
189
  * The URL of the guest provided by the extension registry. The Host will
178
190
  * load this URL in the background, in the invisible the bootstrap frame, so
179
191
  * this URL must point to a page that calls {@link @adobe/uix-guest#register}
180
192
  * when it loads.
181
193
  */
182
- url: URL;
194
+ public url: URL;
195
+ private guestServer: CrossRealmObject<GuestProxyWrapper>;
183
196
 
184
- // #endregion Properties (15)
197
+ // #endregion Properties (13)
185
198
 
186
199
  // #region Constructors (1)
187
200
 
@@ -195,7 +208,7 @@ export class Port<GuestApi>
195
208
  */
196
209
  runtimeContainer: HTMLElement;
197
210
  options: PortOptions;
198
- debugLogger?: Console;
211
+ logger?: Console;
199
212
  /**
200
213
  * Initial object to populate the shared context with. Once the guest
201
214
  * connects, it will be able to access these properties.
@@ -216,8 +229,10 @@ export class Port<GuestApi>
216
229
  this.sharedContext = (
217
230
  (event as CustomEvent).detail as unknown as Record<string, unknown>
218
231
  ).context as Record<string, unknown>;
219
- await this.connect();
220
- await this.guest.emit("contextchange", { context: this.sharedContext });
232
+ await this.load();
233
+ await this.guestServer
234
+ .getRemoteApi()
235
+ .emit("contextchange", { context: this.sharedContext });
221
236
  })
222
237
  );
223
238
  }
@@ -231,10 +246,7 @@ export class Port<GuestApi>
231
246
  * with the extension's bootstrap frame, so they can share context and events.
232
247
  */
233
248
  public attachUI(iframe: HTMLIFrameElement) {
234
- const uniqueId = Math.random().toString(36);
235
- const uiConnection = this.attachFrame(iframe);
236
- this.uiConnections.set(uniqueId, uiConnection);
237
- return uiConnection;
249
+ return this.attachFrame(iframe);
238
250
  }
239
251
 
240
252
  /**
@@ -279,8 +291,7 @@ export class Port<GuestApi>
279
291
  }
280
292
  return this.apis;
281
293
  } catch (e) {
282
- this.apis = null;
283
- this.guest = null;
294
+ this.guestServer = null;
284
295
  this.error = e instanceof Error ? e : new Error(String(e));
285
296
  throw e;
286
297
  }
@@ -299,12 +310,6 @@ export class Port<GuestApi>
299
310
  * Disconnect from the extension.
300
311
  */
301
312
  public async unload(): Promise<void> {
302
- if (this.connection) {
303
- await this.connection.destroy();
304
- }
305
- for (const connection of this.uiConnections.values()) {
306
- await connection.destroy();
307
- }
308
313
  if (this.frame && this.frame.parentElement) {
309
314
  this.frame.parentElement.removeChild(this.frame);
310
315
  this.frame = undefined;
@@ -331,18 +336,20 @@ export class Port<GuestApi>
331
336
  this.assert(this.isReady(), () => "Attempted to interact before loaded");
332
337
  }
333
338
 
334
- private attachFrame(iframe: HTMLIFrameElement) {
335
- return connectToChild<RemoteHostApis<GuestApi>>({
339
+ private attachFrame<T = unknown>(iframe: HTMLIFrameElement) {
340
+ return connectIframe<T>(
336
341
  iframe,
337
- debug: this.debug,
338
- childOrigin: this.url.origin,
339
- timeout: this.timeout,
340
- methods: {
342
+ {
343
+ logger: this.logger,
344
+ targetOrigin: "*",
345
+ timeout: this.timeout,
346
+ },
347
+ {
341
348
  getSharedContext: () => this.sharedContext,
342
349
  invokeHostMethod: (address: HostMethodAddress) =>
343
350
  this.invokeHostMethod(address),
344
- },
345
- });
351
+ }
352
+ );
346
353
  }
347
354
 
348
355
  private async connect() {
@@ -350,19 +357,16 @@ export class Port<GuestApi>
350
357
  this.frame.setAttribute("src", this.url.href);
351
358
  this.frame.setAttribute("data-uix-guest", "true");
352
359
  this.runtimeContainer.appendChild(this.frame);
353
- if (this.debugLogger) {
354
- this.debugLogger.info(
360
+ if (this.logger) {
361
+ this.logger.info(
355
362
  `Guest ${this.id} attached iframe of ${this.url.href}`,
356
363
  this
357
364
  );
358
365
  }
359
- this.connection = this.attachFrame(this.frame);
360
- this.guest = (await this.connection
361
- .promise) as unknown as GuestProxyWrapper;
362
- this.apis = this.guest.apis || {};
366
+ this.guestServer = await this.attachFrame<GuestProxyWrapper>(this.frame);
363
367
  this.isLoaded = true;
364
- if (this.debugLogger) {
365
- this.debugLogger.info(
368
+ if (this.logger) {
369
+ this.logger.info(
366
370
  `Guest ${this.id} established connection, received methods`,
367
371
  this.apis,
368
372
  this
@@ -373,7 +377,7 @@ export class Port<GuestApi>
373
377
  private getHostMethodCallee<T = unknown>(
374
378
  { name, path }: HostMethodAddress,
375
379
  methodSource: RemoteHostApis
376
- ): Methods {
380
+ ): RemoteHostApis<VirtualApi> {
377
381
  const dots = (level: number) =>
378
382
  `uix.host.${path.slice(0, level).join(".")}`;
379
383
  const methodCallee = path.reduce((current, prop, level) => {
@@ -415,7 +419,7 @@ export class Port<GuestApi>
415
419
  try {
416
420
  methodCallee = this.getHostMethodCallee(address, privateMethods);
417
421
  } catch (e) {
418
- this.debugLogger.warn("Private method not found!", address);
422
+ this.logger.warn("Private method not found!", address);
419
423
  }
420
424
  }
421
425
  if (!methodCallee) {