@salesforce/experimental-mfe-bridge 2.2.1-rc.2 → 2.2.1-rc.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.esm.js +61 -19
- package/package.json +4 -2
package/dist/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @salesforce/experimental-mfe-bridge v2.2.1-rc.
|
|
1
|
+
/*! @salesforce/experimental-mfe-bridge v2.2.1-rc.7 (2026-06-16) */
|
|
2
2
|
/**
|
|
3
3
|
* EmbeddingResizer - Handles dynamic iframe/container resizing
|
|
4
4
|
* Uses ResizeObserver to monitor element size changes and notify the host
|
|
@@ -119,6 +119,15 @@ class EmbeddingResizer {
|
|
|
119
119
|
* Auto-handles theme synchronization and error telemetry
|
|
120
120
|
*/
|
|
121
121
|
const GRAPHQL_TIMEOUT_MS = 30_000;
|
|
122
|
+
/** Parses `value` as a URL and returns its `.origin`, or `null` if it does not parse. */
|
|
123
|
+
function extractOrigin(value) {
|
|
124
|
+
try {
|
|
125
|
+
return new URL(value).origin;
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
122
131
|
class ExternalEmbedBridge extends EventTarget {
|
|
123
132
|
#connected = false;
|
|
124
133
|
#hostAppOrigin = null;
|
|
@@ -130,6 +139,14 @@ class ExternalEmbedBridge extends EventTarget {
|
|
|
130
139
|
#graphqlCounter = 0;
|
|
131
140
|
constructor() {
|
|
132
141
|
super();
|
|
142
|
+
// Abort init if hostMetaData is missing/invalid — widget surfaces a clear failure
|
|
143
|
+
// instead of running half-initialised.
|
|
144
|
+
const failures = this.#readMetadataFromUrl();
|
|
145
|
+
if (failures.length > 0) {
|
|
146
|
+
// eslint-disable-next-line no-console
|
|
147
|
+
console.error("[Bridge] Bridge could not be established:\n - " + failures.join("\n - "));
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
133
150
|
window.addEventListener("message", (e) => this.#handleHostMessage(e));
|
|
134
151
|
this.#setupErrorCapture();
|
|
135
152
|
this.#sendToHost("bridge-ready");
|
|
@@ -137,16 +154,44 @@ class ExternalEmbedBridge extends EventTarget {
|
|
|
137
154
|
// eslint-disable-next-line no-console
|
|
138
155
|
console.log("[Bridge] Initialized and ready for communication");
|
|
139
156
|
}
|
|
157
|
+
/** Populates #instanceId and #hostAppOrigin from the iframe URL's `hostMetaData`
|
|
158
|
+
* query param. Returns failure reasons (empty = success). */
|
|
159
|
+
#readMetadataFromUrl() {
|
|
160
|
+
const raw = new URLSearchParams(window.location.search).get("hostMetaData");
|
|
161
|
+
if (!raw)
|
|
162
|
+
return ["`hostMetaData` query param is missing"];
|
|
163
|
+
let parsed;
|
|
164
|
+
try {
|
|
165
|
+
parsed = JSON.parse(raw);
|
|
166
|
+
}
|
|
167
|
+
catch (e) {
|
|
168
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
169
|
+
return [`\`hostMetaData\` is not valid JSON: ${message}`];
|
|
170
|
+
}
|
|
171
|
+
const instanceId = typeof parsed?.instanceId === "string" ? parsed.instanceId : "";
|
|
172
|
+
const rawHostAppOrigin = typeof parsed?.hostAppOrigin === "string" ? parsed.hostAppOrigin : "";
|
|
173
|
+
const hostAppOrigin = rawHostAppOrigin ? extractOrigin(rawHostAppOrigin) : "";
|
|
174
|
+
const failures = [];
|
|
175
|
+
if (!instanceId)
|
|
176
|
+
failures.push("`instanceId` is missing or empty");
|
|
177
|
+
if (!rawHostAppOrigin) {
|
|
178
|
+
failures.push("`hostAppOrigin` is missing or empty");
|
|
179
|
+
}
|
|
180
|
+
else if (!hostAppOrigin) {
|
|
181
|
+
failures.push("`hostAppOrigin` is not a valid URL");
|
|
182
|
+
}
|
|
183
|
+
if (failures.length === 0) {
|
|
184
|
+
this.#instanceId = instanceId;
|
|
185
|
+
this.#hostAppOrigin = hostAppOrigin;
|
|
186
|
+
}
|
|
187
|
+
return failures;
|
|
188
|
+
}
|
|
140
189
|
#handleHostMessage(event) {
|
|
141
|
-
if (event.source !== window.parent)
|
|
142
|
-
return;
|
|
143
|
-
if (this.#hostAppOrigin && event.origin !== this.#hostAppOrigin)
|
|
190
|
+
if (event.source !== window.parent || event.origin !== this.#hostAppOrigin)
|
|
144
191
|
return;
|
|
145
192
|
const payload = event.data || {};
|
|
146
193
|
const { type, data, id } = payload;
|
|
147
|
-
if (typeof type !== "string" || !type.startsWith("salesforce-"))
|
|
148
|
-
return;
|
|
149
|
-
if (this.#instanceId && id !== this.#instanceId)
|
|
194
|
+
if (typeof type !== "string" || !type.startsWith("salesforce-") || id !== this.#instanceId)
|
|
150
195
|
return;
|
|
151
196
|
// eslint-disable-next-line no-console
|
|
152
197
|
console.log("[Bridge] host->widget", type, data);
|
|
@@ -158,7 +203,7 @@ class ExternalEmbedBridge extends EventTarget {
|
|
|
158
203
|
this.#handleDataUpdate(data);
|
|
159
204
|
break;
|
|
160
205
|
case "salesforce-shell-ready":
|
|
161
|
-
this.#handleConnectionReady(
|
|
206
|
+
this.#handleConnectionReady();
|
|
162
207
|
break;
|
|
163
208
|
case "salesforce-bridge-graphql-response":
|
|
164
209
|
this.#handleGraphQLResponse(data);
|
|
@@ -176,10 +221,8 @@ class ExternalEmbedBridge extends EventTarget {
|
|
|
176
221
|
// use super to escape the override
|
|
177
222
|
super.dispatchEvent(new CustomEvent("data", { detail: payload }));
|
|
178
223
|
}
|
|
179
|
-
#handleConnectionReady(
|
|
224
|
+
#handleConnectionReady() {
|
|
180
225
|
this.#connected = true;
|
|
181
|
-
this.#hostAppOrigin = origin;
|
|
182
|
-
this.#instanceId = id;
|
|
183
226
|
// use super to escape the override
|
|
184
227
|
super.dispatchEvent(new CustomEvent("connected"));
|
|
185
228
|
}
|
|
@@ -231,18 +274,12 @@ class ExternalEmbedBridge extends EventTarget {
|
|
|
231
274
|
});
|
|
232
275
|
this.#resizer.start();
|
|
233
276
|
}
|
|
234
|
-
#getHostAppOrigin(type) {
|
|
235
|
-
return this.#hostAppOrigin || (type === "bridge-ready" ? "*" : null);
|
|
236
|
-
}
|
|
237
277
|
#sendToHost(type, data) {
|
|
238
|
-
const origin = this.#getHostAppOrigin(type);
|
|
239
|
-
if (!origin)
|
|
240
|
-
return;
|
|
241
278
|
try {
|
|
242
|
-
const message =
|
|
279
|
+
const message = { type, data, id: this.#instanceId };
|
|
243
280
|
// eslint-disable-next-line no-console
|
|
244
281
|
console.log("[Bridge] Sending message to host:", message);
|
|
245
|
-
window.parent.postMessage(message,
|
|
282
|
+
window.parent.postMessage(message, this.#hostAppOrigin);
|
|
246
283
|
}
|
|
247
284
|
catch (error) {
|
|
248
285
|
// eslint-disable-next-line no-console
|
|
@@ -284,6 +321,11 @@ class ExternalEmbedBridge extends EventTarget {
|
|
|
284
321
|
// Override dispatchEvent to forward custom events to the host via post message
|
|
285
322
|
dispatchEvent(event) {
|
|
286
323
|
const result = super.dispatchEvent(event);
|
|
324
|
+
if (!this.#connected) {
|
|
325
|
+
// eslint-disable-next-line no-console
|
|
326
|
+
console.warn("[Bridge] dispatchEvent: bridge not connected, dropping", event.type);
|
|
327
|
+
return result;
|
|
328
|
+
}
|
|
287
329
|
this.#sendToHost("custom-event", {
|
|
288
330
|
eventType: event.type,
|
|
289
331
|
detail: event.detail,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/experimental-mfe-bridge",
|
|
3
|
-
"version": "2.2.1-rc.
|
|
3
|
+
"version": "2.2.1-rc.7",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "EventTarget-Based Embed ↔ Host Communication for UI Embedding",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
@@ -25,10 +25,12 @@
|
|
|
25
25
|
"clean": "rimraf dist"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"utils": "2.2.1-rc.
|
|
28
|
+
"utils": "2.2.1-rc.7"
|
|
29
29
|
},
|
|
30
30
|
"files": [
|
|
31
31
|
"dist/",
|
|
32
|
+
"!dist/__tests__/",
|
|
33
|
+
"!dist/__mocks__/",
|
|
32
34
|
"!dist/*.test.js",
|
|
33
35
|
"!dist/*.map",
|
|
34
36
|
"README.md",
|