@returningai/widget-sdk 1.8.4 → 1.8.5
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/CHANGELOG.md +10 -0
- package/dist/rai-banner.iife.js +1 -1
- package/dist/rai-banner.js +1 -1
- package/dist/rai-widget.iife.js +2 -2
- package/dist/rai-widget.js +193 -35
- package/dist/types/BaseWidget.d.ts +1 -0
- package/dist/types/core/bundle-readiness.d.ts +19 -2
- package/dist/types/core/widget-error-presentation.d.ts +15 -0
- package/package.json +3 -2
package/dist/rai-widget.js
CHANGED
|
@@ -12823,6 +12823,31 @@ function subscribeAuthSession(config, state, onSnapshot) {
|
|
|
12823
12823
|
};
|
|
12824
12824
|
}
|
|
12825
12825
|
const BUNDLE_READY_TIMEOUT_MS = 3e4;
|
|
12826
|
+
class BundleReadinessTimeoutError extends Error {
|
|
12827
|
+
constructor(phase, message) {
|
|
12828
|
+
super(message);
|
|
12829
|
+
__publicField(this, "phase");
|
|
12830
|
+
this.name = "BundleReadinessTimeoutError";
|
|
12831
|
+
this.phase = phase;
|
|
12832
|
+
}
|
|
12833
|
+
}
|
|
12834
|
+
function isBundleReadinessTimeoutError(error) {
|
|
12835
|
+
return error instanceof BundleReadinessTimeoutError;
|
|
12836
|
+
}
|
|
12837
|
+
function createDefaultEnvironment() {
|
|
12838
|
+
const visibilityDocument = typeof document === "undefined" ? void 0 : document;
|
|
12839
|
+
const pageWindow = typeof window === "undefined" ? void 0 : window;
|
|
12840
|
+
return {
|
|
12841
|
+
isHidden: () => (visibilityDocument == null ? void 0 : visibilityDocument.visibilityState) === "hidden",
|
|
12842
|
+
now: () => Date.now(),
|
|
12843
|
+
setTimeout: (callback, delayMs) => globalThis.setTimeout(callback, delayMs),
|
|
12844
|
+
clearTimeout: (timerId) => globalThis.clearTimeout(timerId),
|
|
12845
|
+
addVisibilityChangeListener: (listener) => visibilityDocument == null ? void 0 : visibilityDocument.addEventListener("visibilitychange", listener),
|
|
12846
|
+
removeVisibilityChangeListener: (listener) => visibilityDocument == null ? void 0 : visibilityDocument.removeEventListener("visibilitychange", listener),
|
|
12847
|
+
addPageShowListener: (listener) => pageWindow == null ? void 0 : pageWindow.addEventListener("pageshow", listener),
|
|
12848
|
+
removePageShowListener: (listener) => pageWindow == null ? void 0 : pageWindow.removeEventListener("pageshow", listener)
|
|
12849
|
+
};
|
|
12850
|
+
}
|
|
12826
12851
|
function isPromiseLike(value) {
|
|
12827
12852
|
return (typeof value === "object" || typeof value === "function") && value !== null && typeof value.then === "function";
|
|
12828
12853
|
}
|
|
@@ -12832,28 +12857,101 @@ function isReadyHandle(value) {
|
|
|
12832
12857
|
}
|
|
12833
12858
|
return isPromiseLike(value.ready);
|
|
12834
12859
|
}
|
|
12835
|
-
function
|
|
12860
|
+
function waitWithActiveTimeTimeout(promise, timeoutMs, timeoutError, environment) {
|
|
12836
12861
|
return new Promise((resolve, reject) => {
|
|
12837
|
-
|
|
12838
|
-
|
|
12839
|
-
|
|
12862
|
+
let settled = false;
|
|
12863
|
+
let remainingMs = Math.max(0, timeoutMs);
|
|
12864
|
+
let visibleStartedAt = null;
|
|
12865
|
+
let timeoutId = null;
|
|
12866
|
+
const clearActiveTimer = () => {
|
|
12867
|
+
if (timeoutId !== null) {
|
|
12868
|
+
environment.clearTimeout(timeoutId);
|
|
12869
|
+
timeoutId = null;
|
|
12870
|
+
}
|
|
12871
|
+
};
|
|
12872
|
+
const cleanup = () => {
|
|
12873
|
+
clearActiveTimer();
|
|
12874
|
+
environment.removeVisibilityChangeListener(handleVisibilityChange);
|
|
12875
|
+
};
|
|
12876
|
+
const finish = (callback) => {
|
|
12877
|
+
if (settled) return;
|
|
12878
|
+
settled = true;
|
|
12879
|
+
cleanup();
|
|
12880
|
+
callback();
|
|
12881
|
+
};
|
|
12882
|
+
const pauseDeadline = () => {
|
|
12883
|
+
clearActiveTimer();
|
|
12884
|
+
if (visibleStartedAt === null) return;
|
|
12885
|
+
remainingMs = Math.max(
|
|
12886
|
+
0,
|
|
12887
|
+
remainingMs - Math.max(0, environment.now() - visibleStartedAt)
|
|
12888
|
+
);
|
|
12889
|
+
visibleStartedAt = null;
|
|
12890
|
+
};
|
|
12891
|
+
const startDeadline = () => {
|
|
12892
|
+
if (settled || environment.isHidden() || timeoutId !== null) return;
|
|
12893
|
+
if (remainingMs <= 0) {
|
|
12894
|
+
finish(() => reject(timeoutError()));
|
|
12895
|
+
return;
|
|
12896
|
+
}
|
|
12897
|
+
visibleStartedAt = environment.now();
|
|
12898
|
+
timeoutId = environment.setTimeout(() => {
|
|
12899
|
+
timeoutId = null;
|
|
12900
|
+
if (environment.isHidden()) {
|
|
12901
|
+
visibleStartedAt = null;
|
|
12902
|
+
return;
|
|
12903
|
+
}
|
|
12904
|
+
visibleStartedAt = null;
|
|
12905
|
+
finish(() => reject(timeoutError()));
|
|
12906
|
+
}, remainingMs);
|
|
12907
|
+
};
|
|
12908
|
+
function handleVisibilityChange() {
|
|
12909
|
+
if (environment.isHidden()) {
|
|
12910
|
+
pauseDeadline();
|
|
12911
|
+
} else {
|
|
12912
|
+
startDeadline();
|
|
12913
|
+
}
|
|
12914
|
+
}
|
|
12915
|
+
environment.addVisibilityChangeListener(handleVisibilityChange);
|
|
12916
|
+
startDeadline();
|
|
12840
12917
|
Promise.resolve(promise).then(
|
|
12841
12918
|
(value) => {
|
|
12842
|
-
|
|
12843
|
-
resolve(value);
|
|
12919
|
+
finish(() => resolve(value));
|
|
12844
12920
|
},
|
|
12845
12921
|
(error) => {
|
|
12846
|
-
|
|
12847
|
-
reject(error);
|
|
12922
|
+
finish(() => reject(error));
|
|
12848
12923
|
}
|
|
12849
12924
|
);
|
|
12850
12925
|
});
|
|
12851
12926
|
}
|
|
12852
|
-
function
|
|
12853
|
-
return
|
|
12927
|
+
function scheduleForegroundRecovery(recover, environment = createDefaultEnvironment()) {
|
|
12928
|
+
if (!environment.isHidden()) return () => {
|
|
12929
|
+
};
|
|
12930
|
+
let active = true;
|
|
12931
|
+
const cleanup = () => {
|
|
12932
|
+
if (!active) return;
|
|
12933
|
+
active = false;
|
|
12934
|
+
environment.removeVisibilityChangeListener(handleForeground);
|
|
12935
|
+
environment.removePageShowListener(handleForeground);
|
|
12936
|
+
};
|
|
12937
|
+
const handleForeground = () => {
|
|
12938
|
+
if (!active || environment.isHidden()) return;
|
|
12939
|
+
cleanup();
|
|
12940
|
+
recover();
|
|
12941
|
+
};
|
|
12942
|
+
environment.addVisibilityChangeListener(handleForeground);
|
|
12943
|
+
environment.addPageShowListener(handleForeground);
|
|
12944
|
+
return cleanup;
|
|
12945
|
+
}
|
|
12946
|
+
function resolveBundleMountResult(mountResult, timeoutMs = BUNDLE_READY_TIMEOUT_MS, environment = createDefaultEnvironment()) {
|
|
12947
|
+
return isPromiseLike(mountResult) ? waitWithActiveTimeTimeout(
|
|
12854
12948
|
mountResult,
|
|
12855
12949
|
timeoutMs,
|
|
12856
|
-
|
|
12950
|
+
() => new BundleReadinessTimeoutError(
|
|
12951
|
+
"mount",
|
|
12952
|
+
`Widget bundle mount did not resolve within ${timeoutMs}ms`
|
|
12953
|
+
),
|
|
12954
|
+
environment
|
|
12857
12955
|
) : Promise.resolve(mountResult);
|
|
12858
12956
|
}
|
|
12859
12957
|
function createBundleMountCleanup(mountResult) {
|
|
@@ -12869,19 +12967,24 @@ function createBundleMountCleanup(mountResult) {
|
|
|
12869
12967
|
unmount.call(mountResult);
|
|
12870
12968
|
};
|
|
12871
12969
|
}
|
|
12872
|
-
async function waitForBundleMountReadiness(mountResult, firstPaint, timeoutMs = BUNDLE_READY_TIMEOUT_MS) {
|
|
12970
|
+
async function waitForBundleMountReadiness(mountResult, firstPaint, timeoutMs = BUNDLE_READY_TIMEOUT_MS, environment = createDefaultEnvironment()) {
|
|
12873
12971
|
const resolvedMountResult = await resolveBundleMountResult(
|
|
12874
12972
|
mountResult,
|
|
12875
|
-
timeoutMs
|
|
12973
|
+
timeoutMs,
|
|
12974
|
+
environment
|
|
12876
12975
|
);
|
|
12877
12976
|
if (!isReadyHandle(resolvedMountResult)) {
|
|
12878
12977
|
await firstPaint;
|
|
12879
12978
|
return "first-paint";
|
|
12880
12979
|
}
|
|
12881
|
-
await
|
|
12980
|
+
await waitWithActiveTimeTimeout(
|
|
12882
12981
|
resolvedMountResult.ready,
|
|
12883
12982
|
timeoutMs,
|
|
12884
|
-
|
|
12983
|
+
() => new BundleReadinessTimeoutError(
|
|
12984
|
+
"deep-ready",
|
|
12985
|
+
`Widget bundle did not report deep readiness within ${timeoutMs}ms`
|
|
12986
|
+
),
|
|
12987
|
+
environment
|
|
12885
12988
|
);
|
|
12886
12989
|
return "deep-ready";
|
|
12887
12990
|
}
|
|
@@ -13610,6 +13713,45 @@ function ensureWidgetPreconnects(origins, targetDocument) {
|
|
|
13610
13713
|
documentTarget.head.appendChild(link);
|
|
13611
13714
|
}
|
|
13612
13715
|
}
|
|
13716
|
+
const USER_LOOKUP_ERRORS = /* @__PURE__ */ new Set([
|
|
13717
|
+
"User not found",
|
|
13718
|
+
"Missing required user identifier fields",
|
|
13719
|
+
"Missing user identifier fields"
|
|
13720
|
+
]);
|
|
13721
|
+
function selectWidgetErrorPresentation({
|
|
13722
|
+
failureKind,
|
|
13723
|
+
customMessage,
|
|
13724
|
+
lastAuthError
|
|
13725
|
+
}) {
|
|
13726
|
+
if (failureKind === "bundle") {
|
|
13727
|
+
const message = "Widget failed to load. Please try again.";
|
|
13728
|
+
return {
|
|
13729
|
+
useCustomMessage: false,
|
|
13730
|
+
displayMessage: message,
|
|
13731
|
+
emittedMessage: message
|
|
13732
|
+
};
|
|
13733
|
+
}
|
|
13734
|
+
const useCustomMessage = Boolean(
|
|
13735
|
+
customMessage && (lastAuthError === null || (lastAuthError.error ? USER_LOOKUP_ERRORS.has(lastAuthError.error) : false))
|
|
13736
|
+
);
|
|
13737
|
+
if (useCustomMessage) {
|
|
13738
|
+
return {
|
|
13739
|
+
useCustomMessage: true,
|
|
13740
|
+
displayMessage: customMessage,
|
|
13741
|
+
emittedMessage: customMessage,
|
|
13742
|
+
hint: lastAuthError == null ? void 0 : lastAuthError.hint,
|
|
13743
|
+
status: lastAuthError == null ? void 0 : lastAuthError.status
|
|
13744
|
+
};
|
|
13745
|
+
}
|
|
13746
|
+
const emittedMessage = (lastAuthError == null ? void 0 : lastAuthError.error) || "Authentication failed";
|
|
13747
|
+
return {
|
|
13748
|
+
useCustomMessage: false,
|
|
13749
|
+
displayMessage: (lastAuthError == null ? void 0 : lastAuthError.hint) ? `${emittedMessage}: ${lastAuthError.hint}` : (lastAuthError == null ? void 0 : lastAuthError.error) ? emittedMessage : "Authentication failed. Please try again later.",
|
|
13750
|
+
emittedMessage,
|
|
13751
|
+
hint: lastAuthError == null ? void 0 : lastAuthError.hint,
|
|
13752
|
+
status: lastAuthError == null ? void 0 : lastAuthError.status
|
|
13753
|
+
};
|
|
13754
|
+
}
|
|
13613
13755
|
const widgetCSS = ':host{display:block;position:relative;width:100%;height:100%}.rai-loader{position:absolute;top:0;left:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:.75rem;width:100%;height:100%;background:var(--rai-loading-background, var(--background-5, var(--rai-loader-bg, #ffffff)));border-radius:8px;z-index:10;transition:opacity .3s ease-out;font-family:var(--rai-loader-font, "Roboto", system-ui, -apple-system, sans-serif)}.rai-loader.fade-out{opacity:0;pointer-events:none}.rai-loader-pending-settings{visibility:hidden}.rai-loader-text{margin:.5rem 0 0;font-family:var(--rai-loading-text-font, var(--rai-loader-font, "Roboto", system-ui, -apple-system, sans-serif));font-size:var(--rai-loading-text-size, 1.125rem);line-height:1.75rem;font-weight:var(--rai-loading-text-weight, 400);font-style:var(--rai-loading-text-style, normal);text-decoration:var(--rai-loading-text-decoration, none);letter-spacing:normal;color:var(--rai-loading-text-color, var(--accent-1, var(--rai-accent, #000000)));text-align:center}@media (min-width: 768px){.rai-loader-text{font-size:var(--rai-loading-text-size, 1.5rem);line-height:2rem}}.rai-error{display:none;position:absolute;top:0;left:0;width:100%;height:100%;align-items:center;justify-content:center;flex-direction:column;gap:12px;background:var(--rai-error-bg, #1a1a1a);border-radius:8px;padding:24px;box-sizing:border-box;text-align:center;color:var(--rai-error-text, #9ca3af);font-family:system-ui,-apple-system,sans-serif;z-index:10}.rai-error.visible{display:flex}iframe{display:block;border:none;opacity:0;transition:opacity .3s ease-in}iframe.loaded{opacity:1}.rai-lottie-loader{width:100px;height:100px}.rai-lottie-loader svg{width:100%!important;height:100%!important}.rai-lottie-spinner{width:32px;height:32px;margin:34px auto;border:3px solid var(--rai-text4, #6b7280);border-top-color:var(--rai-accent, #000000);border-radius:50%;animation:rai-spin .7s linear infinite}@keyframes rai-spin{to{transform:rotate(360deg)}}.rai-sdk-loader{position:relative;width:75px;height:100px}.rai-sdk-loader__bar{position:absolute;bottom:0;width:10px;height:50%;background:var(--rai-accent, #000000);transform-origin:center bottom;box-shadow:1px 1px #0003}.rai-sdk-loader__bar:nth-child(1){left:0;transform:scaleY(.2);animation:rai-sdk-barUp1 4s infinite}.rai-sdk-loader__bar:nth-child(2){left:15px;transform:scaleY(.4);animation:rai-sdk-barUp2 4s infinite}.rai-sdk-loader__bar:nth-child(3){left:30px;transform:scaleY(.6);animation:rai-sdk-barUp3 4s infinite}.rai-sdk-loader__bar:nth-child(4){left:45px;transform:scaleY(.8);animation:rai-sdk-barUp4 4s infinite}.rai-sdk-loader__bar:nth-child(5){left:60px;transform:scale(1);animation:rai-sdk-barUp5 4s infinite}.rai-sdk-loader__ball{position:absolute;bottom:10px;left:0;width:10px;height:10px;background:var(--rai-accent, #000000);border-radius:50%;animation:rai-sdk-ball 4s infinite}@keyframes rai-sdk-ball{0%{transform:translate(0)}5%{transform:translate(8px,-14px)}10%{transform:translate(15px,-10px)}17%{transform:translate(23px,-24px)}20%{transform:translate(30px,-20px)}27%{transform:translate(38px,-34px)}30%{transform:translate(45px,-30px)}37%{transform:translate(53px,-44px)}40%{transform:translate(60px,-40px)}50%{transform:translate(60px)}57%{transform:translate(53px,-14px)}60%{transform:translate(45px,-10px)}67%{transform:translate(37px,-24px)}70%{transform:translate(30px,-20px)}77%{transform:translate(22px,-34px)}80%{transform:translate(15px,-30px)}87%{transform:translate(7px,-44px)}90%{transform:translateY(-40px)}to{transform:translate(0)}}@keyframes rai-sdk-barUp1{0%{transform:scaleY(.2)}40%{transform:scaleY(.2)}50%{transform:scale(1)}90%{transform:scale(1)}to{transform:scaleY(.2)}}@keyframes rai-sdk-barUp2{0%{transform:scaleY(.4)}40%{transform:scaleY(.4)}50%{transform:scaleY(.8)}90%{transform:scaleY(.8)}to{transform:scaleY(.4)}}@keyframes rai-sdk-barUp3{0%{transform:scaleY(.6)}to{transform:scaleY(.6)}}@keyframes rai-sdk-barUp4{0%{transform:scaleY(.8)}40%{transform:scaleY(.8)}50%{transform:scaleY(.4)}90%{transform:scaleY(.4)}to{transform:scaleY(.8)}}@keyframes rai-sdk-barUp5{0%{transform:scale(1)}40%{transform:scale(1)}50%{transform:scaleY(.2)}90%{transform:scaleY(.2)}to{transform:scale(1)}}#loading-square{width:75px;aspect-ratio:1;display:flex;color:var(--rai-accent, #000000);background:linear-gradient(currentColor 0 0) right / 51% 100%,linear-gradient(currentColor 0 0) bottom / 100% 51%;background-repeat:no-repeat;animation:l16-0 2s infinite linear .25s}#loading-square>div{width:50%;height:50%;background:currentColor;animation:l16-1 .5s infinite linear}@keyframes l16-0{0%,12.49%{transform:rotate(0)}12.5%,37.49%{transform:rotate(90deg)}37.5%,62.49%{transform:rotate(180deg)}62.5%,87.49%{transform:rotate(270deg)}87.5%,to{transform:rotate(360deg)}}@keyframes l16-1{0%{transform:perspective(80px) rotate3d(-1,-1,0,0)}80%,to{transform:perspective(80px) rotate3d(-1,-1,0,-180deg)}}#loading-circle{width:75px;aspect-ratio:1;display:grid;grid:50%/50%;color:var(--rai-accent, #000000);border-radius:50%;--_g: no-repeat linear-gradient(currentColor 0 0);background:var(--_g),var(--_g),var(--_g);background-size:50.1% 50.1%;animation:l9-0 1.5s infinite steps(1) alternate,l9-0-0 3s infinite steps(1) alternate}#loading-circle>div{background:var(--rai-text4, #6b7280);border-top-left-radius:100px;transform:perspective(150px) rotateY(0) rotateX(0);transform-origin:bottom right;animation:l9-1 1.5s infinite linear alternate}@keyframes l9-0{0%{background-position:0 100%,100% 100%,100% 0}33%{background-position:100% 100%,100% 100%,100% 0}66%{background-position:100% 0,100% 0,100% 0}}@keyframes l9-0-0{0%{transform:scaleX(1) rotate(0)}50%{transform:scaleX(-1) rotate(-90deg)}}@keyframes l9-1{16.5%{transform:perspective(150px) rotateX(-90deg) rotateY(0) rotateX(0);filter:grayscale(.8)}33%{transform:perspective(150px) rotateX(-180deg) rotateY(0) rotateX(0)}66%{transform:perspective(150px) rotateX(-180deg) rotateY(-180deg) rotateX(0)}to{transform:perspective(150px) rotateX(-180deg) rotateY(-180deg) rotateX(-180deg);filter:grayscale(.8)}}.rai-custom-error{position:absolute;top:0;left:0;width:100%;height:100%;z-index:10}.tiptap strong.tw-font-bold,.tiptap b.tw-font-bold{font-weight:700}.tiptap em.tw-font-italic,.tiptap i.tw-font-italic{font-style:italic}.tiptap a.tiptap-rich-text-link{color:#3b82f6;text-decoration:underline;position:relative;display:inline-block;width:fit-content}.tiptap a.tiptap-rich-text-link:hover{color:#3b82f6cc;text-decoration:none}.tiptap a.tiptap-rich-text-link:not([title=""]):before{content:attr(title);position:absolute;top:-2rem;left:50%;transform:translate(-50%);white-space:nowrap;border-radius:.25rem;background-color:#000;padding:.25rem .5rem;color:#fff;opacity:0;transition:opacity .2s;pointer-events:none}.tiptap a.tiptap-rich-text-link:not([title=""]):hover:before{opacity:1}.tiptap p[style*="text-align: left"]{text-align:left}.tiptap p[style*="text-align: center"]{text-align:center}.tiptap p[style*="text-align: right"]{text-align:right}.tiptap p[style*="text-align: justify"]{text-align:justify}.tiptap u{text-decoration:underline}.tiptap.ProseMirror{background-color:transparent;height:fit-content!important;word-wrap:break-word;white-space:pre-wrap;white-space:break-spaces;-webkit-font-variant-ligatures:none;font-variant-ligatures:none;font-feature-settings:"liga" 0;padding:0;width:100%;overflow-y:auto}.tiptap{line-height:1.6;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif}.tiptap p{margin:.5em 0}.tiptap p:first-child{margin-top:0}.tiptap p:last-child{margin-bottom:0}.tiptap img{max-width:100%;height:auto;display:block}.tiptap p[style*="text-align: left"] img{margin-left:0;margin-right:auto}.tiptap p[style*="text-align: center"] img{margin-left:auto;margin-right:auto}.tiptap p[style*="text-align: right"] img{margin-left:auto;margin-right:0}.rai-retry-btn{padding:8px 20px;border:none;border-radius:6px;background:var(--rai-accent, #000000);color:var(--rai-error-bg, #ffffff);font-size:14px;font-family:system-ui,-apple-system,sans-serif;cursor:pointer}.rai-retry-btn:hover{opacity:.85}';
|
|
13614
13756
|
const DEFINED_ATTRS = /* @__PURE__ */ new Set([
|
|
13615
13757
|
"community-id",
|
|
@@ -14007,6 +14149,7 @@ class BaseWidget extends HTMLElement {
|
|
|
14007
14149
|
__publicField(this, "bannerNode", null);
|
|
14008
14150
|
__publicField(this, "releaseAutoThemeDisableLease");
|
|
14009
14151
|
__publicField(this, "bundleUnmount");
|
|
14152
|
+
__publicField(this, "cancelBundleForegroundRecovery");
|
|
14010
14153
|
__publicField(this, "authSession");
|
|
14011
14154
|
this.shadow = this.attachShadow({ mode: "closed" });
|
|
14012
14155
|
}
|
|
@@ -14062,15 +14205,17 @@ class BaseWidget extends HTMLElement {
|
|
|
14062
14205
|
}
|
|
14063
14206
|
}
|
|
14064
14207
|
disconnectedCallback() {
|
|
14065
|
-
var _a, _b, _c, _d;
|
|
14208
|
+
var _a, _b, _c, _d, _e;
|
|
14066
14209
|
(_a = this.intersectionObserver) == null ? void 0 : _a.disconnect();
|
|
14067
14210
|
(_b = this.themeObserver) == null ? void 0 : _b.disconnect();
|
|
14068
14211
|
(_c = this.identityAttributeObserver) == null ? void 0 : _c.disconnect();
|
|
14212
|
+
(_d = this.cancelBundleForegroundRecovery) == null ? void 0 : _d.call(this);
|
|
14213
|
+
this.cancelBundleForegroundRecovery = void 0;
|
|
14069
14214
|
this.teardownMountedWidget();
|
|
14070
14215
|
this.clearLottieInstances();
|
|
14071
14216
|
this.restoreLoaderHeight();
|
|
14072
14217
|
this.removeBanner();
|
|
14073
|
-
(
|
|
14218
|
+
(_e = this.authSession) == null ? void 0 : _e.release();
|
|
14074
14219
|
this.authSession = void 0;
|
|
14075
14220
|
clearState(this.state);
|
|
14076
14221
|
}
|
|
@@ -14498,25 +14643,24 @@ class BaseWidget extends HTMLElement {
|
|
|
14498
14643
|
if (container.children.length > 0) finish();
|
|
14499
14644
|
});
|
|
14500
14645
|
}
|
|
14501
|
-
showError() {
|
|
14646
|
+
showError(failureKind = "authentication") {
|
|
14502
14647
|
this.hideLoader();
|
|
14503
14648
|
const settings = this.state.errorSettings;
|
|
14504
|
-
const
|
|
14505
|
-
|
|
14506
|
-
|
|
14507
|
-
|
|
14649
|
+
const presentation = selectWidgetErrorPresentation({
|
|
14650
|
+
failureKind,
|
|
14651
|
+
customMessage: settings == null ? void 0 : settings.errorMessage,
|
|
14652
|
+
lastAuthError: this.state.lastAuthError
|
|
14653
|
+
});
|
|
14654
|
+
if (presentation.useCustomMessage) {
|
|
14508
14655
|
this.renderCustomError(settings);
|
|
14509
14656
|
} else if (this.errorEl) {
|
|
14510
|
-
if (
|
|
14511
|
-
this.msgEl.textContent = lastAuthError.hint ? `${lastAuthError.error}: ${lastAuthError.hint}` : lastAuthError.error;
|
|
14512
|
-
}
|
|
14657
|
+
if (this.msgEl) this.msgEl.textContent = presentation.displayMessage;
|
|
14513
14658
|
this.errorEl.classList.add("visible");
|
|
14514
14659
|
}
|
|
14515
|
-
const emittedMessage = shouldUseCustomMessage ? settings.errorMessage : (lastAuthError == null ? void 0 : lastAuthError.error) || "Authentication failed";
|
|
14516
14660
|
this.emit("rai-error", {
|
|
14517
|
-
message: emittedMessage,
|
|
14518
|
-
hint:
|
|
14519
|
-
status:
|
|
14661
|
+
message: presentation.emittedMessage,
|
|
14662
|
+
hint: presentation.hint,
|
|
14663
|
+
status: presentation.status
|
|
14520
14664
|
});
|
|
14521
14665
|
}
|
|
14522
14666
|
renderCustomError(settings) {
|
|
@@ -14672,7 +14816,9 @@ class BaseWidget extends HTMLElement {
|
|
|
14672
14816
|
}
|
|
14673
14817
|
// ── Initialization ─────────────────────────────────────────────────────
|
|
14674
14818
|
async init() {
|
|
14675
|
-
var _a;
|
|
14819
|
+
var _a, _b;
|
|
14820
|
+
(_a = this.cancelBundleForegroundRecovery) == null ? void 0 : _a.call(this);
|
|
14821
|
+
this.cancelBundleForegroundRecovery = void 0;
|
|
14676
14822
|
const initId = ++this.initGeneration;
|
|
14677
14823
|
this.hasAttemptedInit = true;
|
|
14678
14824
|
if (!this.config.communityId) {
|
|
@@ -14772,7 +14918,7 @@ class BaseWidget extends HTMLElement {
|
|
|
14772
14918
|
launchWidget();
|
|
14773
14919
|
return;
|
|
14774
14920
|
}
|
|
14775
|
-
(
|
|
14921
|
+
(_b = this.authSession) == null ? void 0 : _b.publish();
|
|
14776
14922
|
const refreshed = await finishStartup(
|
|
14777
14923
|
this.authSession ? this.authSession.run(
|
|
14778
14924
|
"refresh",
|
|
@@ -14896,7 +15042,7 @@ class BaseWidget extends HTMLElement {
|
|
|
14896
15042
|
return { bundleApiUrl, colorMode };
|
|
14897
15043
|
}
|
|
14898
15044
|
async mountWidget(initId) {
|
|
14899
|
-
var _a;
|
|
15045
|
+
var _a, _b;
|
|
14900
15046
|
let container = null;
|
|
14901
15047
|
let cleanupBundleMount;
|
|
14902
15048
|
try {
|
|
@@ -15017,7 +15163,19 @@ class BaseWidget extends HTMLElement {
|
|
|
15017
15163
|
container == null ? void 0 : container.remove();
|
|
15018
15164
|
(_a = this.releaseAutoThemeDisableLease) == null ? void 0 : _a.call(this);
|
|
15019
15165
|
this.releaseAutoThemeDisableLease = void 0;
|
|
15020
|
-
|
|
15166
|
+
if (isBundleReadinessTimeoutError(err) && document.visibilityState === "hidden") {
|
|
15167
|
+
(_b = this.cancelBundleForegroundRecovery) == null ? void 0 : _b.call(this);
|
|
15168
|
+
let scheduledRecovery;
|
|
15169
|
+
scheduledRecovery = scheduleForegroundRecovery(() => {
|
|
15170
|
+
if (this.cancelBundleForegroundRecovery === scheduledRecovery) {
|
|
15171
|
+
this.cancelBundleForegroundRecovery = void 0;
|
|
15172
|
+
}
|
|
15173
|
+
if (this.isConnected) void this.init();
|
|
15174
|
+
});
|
|
15175
|
+
this.cancelBundleForegroundRecovery = scheduledRecovery;
|
|
15176
|
+
return;
|
|
15177
|
+
}
|
|
15178
|
+
this.showError("bundle");
|
|
15021
15179
|
}
|
|
15022
15180
|
}
|
|
15023
15181
|
// ── Token scheduling ──────────────────────────────────────────────────
|
|
@@ -15253,7 +15411,7 @@ class CustomWidget extends BaseWidget {
|
|
|
15253
15411
|
}
|
|
15254
15412
|
}
|
|
15255
15413
|
}
|
|
15256
|
-
console.log(`[rai-widget] v${"1.8.
|
|
15414
|
+
console.log(`[rai-widget] v${"1.8.5"}`);
|
|
15257
15415
|
class StoreWidgetCompat extends StoreWidget {
|
|
15258
15416
|
}
|
|
15259
15417
|
const WIDGET_REGISTRY = [
|
|
@@ -15317,7 +15475,7 @@ function exposePublicApi() {
|
|
|
15317
15475
|
})();
|
|
15318
15476
|
const widget = container == null ? void 0 : container.querySelector(ALL_WIDGET_SELECTOR);
|
|
15319
15477
|
window.ReturningAIWidget = {
|
|
15320
|
-
version: "1.8.
|
|
15478
|
+
version: "1.8.5",
|
|
15321
15479
|
reload: () => (widget == null ? void 0 : widget.reload()) ?? Promise.resolve(),
|
|
15322
15480
|
logout: () => (widget == null ? void 0 : widget.logoutPublic()) ?? Promise.resolve(),
|
|
15323
15481
|
isAuthenticated: () => (widget == null ? void 0 : widget.isAuthenticated()) ?? false,
|
|
@@ -22,6 +22,7 @@ export declare abstract class BaseWidget extends HTMLElement {
|
|
|
22
22
|
private bannerNode;
|
|
23
23
|
private releaseAutoThemeDisableLease?;
|
|
24
24
|
private bundleUnmount?;
|
|
25
|
+
private cancelBundleForegroundRecovery?;
|
|
25
26
|
private authSession?;
|
|
26
27
|
constructor();
|
|
27
28
|
registerCallback<K extends keyof ReturningAIWidgetCallbackMap>(callbackName: K, callback: ReturningAIWidgetCallbackMap[K]): void;
|
|
@@ -6,7 +6,24 @@ export interface BundleMountUnmountHandle {
|
|
|
6
6
|
unmount: () => void;
|
|
7
7
|
}
|
|
8
8
|
export type BundleMountReadiness = "deep-ready" | "first-paint";
|
|
9
|
-
export
|
|
9
|
+
export type BundleReadinessPhase = "mount" | "deep-ready";
|
|
10
|
+
export interface BundleReadinessEnvironment {
|
|
11
|
+
isHidden: () => boolean;
|
|
12
|
+
now: () => number;
|
|
13
|
+
setTimeout: (callback: () => void, delayMs: number) => unknown;
|
|
14
|
+
clearTimeout: (timerId: unknown) => void;
|
|
15
|
+
addVisibilityChangeListener: (listener: () => void) => void;
|
|
16
|
+
removeVisibilityChangeListener: (listener: () => void) => void;
|
|
17
|
+
addPageShowListener: (listener: () => void) => void;
|
|
18
|
+
removePageShowListener: (listener: () => void) => void;
|
|
19
|
+
}
|
|
20
|
+
export declare class BundleReadinessTimeoutError extends Error {
|
|
21
|
+
readonly phase: BundleReadinessPhase;
|
|
22
|
+
constructor(phase: BundleReadinessPhase, message: string);
|
|
23
|
+
}
|
|
24
|
+
export declare function isBundleReadinessTimeoutError(error: unknown): error is BundleReadinessTimeoutError;
|
|
25
|
+
export declare function scheduleForegroundRecovery(recover: () => void, environment?: BundleReadinessEnvironment): () => void;
|
|
26
|
+
export declare function resolveBundleMountResult(mountResult: unknown, timeoutMs?: number, environment?: BundleReadinessEnvironment): Promise<unknown>;
|
|
10
27
|
export declare function createBundleMountCleanup(mountResult: unknown): (() => void) | undefined;
|
|
11
28
|
/**
|
|
12
29
|
* Wait for the strongest readiness signal a bundle provides.
|
|
@@ -17,4 +34,4 @@ export declare function createBundleMountCleanup(mountResult: unknown): (() => v
|
|
|
17
34
|
* to an object with a `ready` promise. Legacy bundles keep the first-paint
|
|
18
35
|
* behavior unchanged.
|
|
19
36
|
*/
|
|
20
|
-
export declare function waitForBundleMountReadiness(mountResult: unknown, firstPaint: PromiseLike<void>, timeoutMs?: number): Promise<BundleMountReadiness>;
|
|
37
|
+
export declare function waitForBundleMountReadiness(mountResult: unknown, firstPaint: PromiseLike<void>, timeoutMs?: number, environment?: BundleReadinessEnvironment): Promise<BundleMountReadiness>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { WidgetState } from "../types";
|
|
2
|
+
export type WidgetFailureKind = "authentication" | "bundle";
|
|
3
|
+
export interface WidgetErrorPresentationInput {
|
|
4
|
+
failureKind: WidgetFailureKind;
|
|
5
|
+
customMessage?: string | null;
|
|
6
|
+
lastAuthError: WidgetState["lastAuthError"];
|
|
7
|
+
}
|
|
8
|
+
export interface WidgetErrorPresentation {
|
|
9
|
+
useCustomMessage: boolean;
|
|
10
|
+
displayMessage: string;
|
|
11
|
+
emittedMessage: string;
|
|
12
|
+
hint?: string;
|
|
13
|
+
status?: number;
|
|
14
|
+
}
|
|
15
|
+
export declare function selectWidgetErrorPresentation({ failureKind, customMessage, lastAuthError, }: WidgetErrorPresentationInput): WidgetErrorPresentation;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@returningai/widget-sdk",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.5",
|
|
4
4
|
"description": "Shadow DOM isolated widget SDK for ReturningAI",
|
|
5
5
|
"main": "dist/rai-widget.iife.js",
|
|
6
6
|
"module": "dist/rai-widget.js",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"build:all": "npm run build && npm run build:banner",
|
|
26
26
|
"build:all:min": "npm run build:min && npm run build:banner:min",
|
|
27
27
|
"types": "tsc --emitDeclarationOnly --outDir dist/types && cp src/jsx.d.ts dist/types/jsx.d.ts",
|
|
28
|
-
"test": "npm run test:host-callback && npm run test:bundle-readiness && npm run test:bundle-runtime-cache && npm run test:bundle-token-sync && npm run test:auth-bootstrap && npm run test:auth-error-reporting && npm run test:auth-refresh-state && npm run test:auth-session-coordinator && npm run test:startup-performance && npm run test:jsx-types",
|
|
28
|
+
"test": "npm run test:host-callback && npm run test:bundle-readiness && npm run test:bundle-runtime-cache && npm run test:bundle-token-sync && npm run test:auth-bootstrap && npm run test:auth-error-reporting && npm run test:auth-refresh-state && npm run test:auth-session-coordinator && npm run test:startup-performance && npm run test:widget-error-presentation && npm run test:jsx-types",
|
|
29
29
|
"test:host-callback": "rm -rf test/.tmp && tsc -p test/tsconfig.json && node test/.tmp/test/postmessage-host-callback.test.js",
|
|
30
30
|
"test:bundle-readiness": "rm -rf test/.tmp && tsc -p test/tsconfig.json && node test/.tmp/test/bundle-readiness.test.js",
|
|
31
31
|
"test:bundle-runtime-cache": "rm -rf test/.tmp && tsc -p test/tsconfig.json && node test/.tmp/test/bundle-runtime-cache.test.js",
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"test:auth-refresh-state": "rm -rf test/.tmp && tsc -p test/tsconfig.json && node test/.tmp/test/auth-refresh-state.test.js",
|
|
36
36
|
"test:auth-session-coordinator": "rm -rf test/.tmp && tsc -p test/tsconfig.json && node test/.tmp/test/auth-session-coordinator.test.js",
|
|
37
37
|
"test:startup-performance": "rm -rf test/.tmp && tsc -p test/tsconfig.json && node test/.tmp/test/startup-performance.test.js",
|
|
38
|
+
"test:widget-error-presentation": "rm -rf test/.tmp && tsc -p test/tsconfig.json && node test/.tmp/test/widget-error-presentation.test.js",
|
|
38
39
|
"test:jsx-types": "tsc --noEmit --strict --lib ES2020,DOM --skipLibCheck false src/jsx.d.ts",
|
|
39
40
|
"coverage:repowise": "rm -rf coverage && npm run coverage:host-callback && npm run coverage:bundle-readiness && npm run test:jsx-types",
|
|
40
41
|
"coverage:host-callback": "rm -rf test/.tmp && tsc -p test/tsconfig.json && c8 --reporter=lcov --reports-dir=coverage/host-callback --exclude-after-remap --exclude='**/*.test.ts' node test/.tmp/test/postmessage-host-callback.test.js && node scripts/name-lcov-test.mjs coverage/host-callback/lcov.info test/postmessage-host-callback.test.ts",
|