@returningai/widget-sdk 1.4.1 → 1.4.2
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 +104 -104
- package/README.md +485 -485
- package/dist/rai-widget.iife.js +1 -1
- package/dist/rai-widget.js +80 -26
- package/dist/types/BaseWidget.d.ts +9 -2
- package/package.json +35 -35
package/dist/rai-widget.js
CHANGED
|
@@ -10827,6 +10827,11 @@ const DEFINED_ATTRS = /* @__PURE__ */ new Set([
|
|
|
10827
10827
|
"accent",
|
|
10828
10828
|
"font"
|
|
10829
10829
|
]);
|
|
10830
|
+
function isUserIdentifierAttribute(name) {
|
|
10831
|
+
const normalized = name.toLowerCase();
|
|
10832
|
+
if (!normalized.startsWith("data-")) return false;
|
|
10833
|
+
return !DEFINED_ATTRS.has(normalized.slice(5));
|
|
10834
|
+
}
|
|
10830
10835
|
const WIDGET_GLOBALS = {
|
|
10831
10836
|
store: "RaiStoreWidget",
|
|
10832
10837
|
channel: "RaiChannelWidget",
|
|
@@ -11094,15 +11099,20 @@ class BaseWidget extends HTMLElement {
|
|
|
11094
11099
|
__publicField(this, "intersectionObserver");
|
|
11095
11100
|
// #3
|
|
11096
11101
|
__publicField(this, "themeObserver");
|
|
11097
|
-
__publicField(this, "
|
|
11102
|
+
__publicField(this, "identityAttributeObserver");
|
|
11098
11103
|
__publicField(this, "identitySignature", "");
|
|
11104
|
+
__publicField(this, "hasAttemptedInit", false);
|
|
11105
|
+
__publicField(this, "initGeneration", 0);
|
|
11099
11106
|
__publicField(this, "lottieInstances", []);
|
|
11100
11107
|
this.shadow = this.attachShadow({ mode: "closed" });
|
|
11101
11108
|
}
|
|
11109
|
+
static get observedAttributes() {
|
|
11110
|
+
return ["embed-token", "data-embed-token"];
|
|
11111
|
+
}
|
|
11102
11112
|
connectedCallback() {
|
|
11103
11113
|
this.config = readConfig(this, void 0);
|
|
11104
11114
|
this.identitySignature = identitySignatureForConfig(this.config);
|
|
11105
|
-
this.
|
|
11115
|
+
this.setupIdentityAttributeObserver();
|
|
11106
11116
|
const style = document.createElement("style");
|
|
11107
11117
|
style.textContent = widgetCSS;
|
|
11108
11118
|
this.shadow.appendChild(style);
|
|
@@ -11135,32 +11145,45 @@ class BaseWidget extends HTMLElement {
|
|
|
11135
11145
|
var _a, _b, _c;
|
|
11136
11146
|
(_a = this.intersectionObserver) == null ? void 0 : _a.disconnect();
|
|
11137
11147
|
(_b = this.themeObserver) == null ? void 0 : _b.disconnect();
|
|
11138
|
-
(_c = this.
|
|
11139
|
-
|
|
11148
|
+
(_c = this.identityAttributeObserver) == null ? void 0 : _c.disconnect();
|
|
11149
|
+
this.teardownMountedWidget();
|
|
11140
11150
|
this.clearLottieInstances();
|
|
11141
11151
|
clearState(this.state);
|
|
11142
11152
|
}
|
|
11143
|
-
|
|
11153
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
11154
|
+
if (oldValue === newValue) return;
|
|
11155
|
+
if (name !== "embed-token" && name !== "data-embed-token") return;
|
|
11156
|
+
this.handleIdentityConfigChange();
|
|
11157
|
+
}
|
|
11158
|
+
setupIdentityAttributeObserver() {
|
|
11144
11159
|
var _a;
|
|
11145
|
-
(_a = this.
|
|
11146
|
-
this.
|
|
11147
|
-
|
|
11148
|
-
|
|
11149
|
-
|
|
11150
|
-
if (
|
|
11151
|
-
this.
|
|
11152
|
-
return;
|
|
11153
|
-
}
|
|
11154
|
-
const previousConfig = this.config;
|
|
11155
|
-
this.config = nextConfig;
|
|
11156
|
-
this.identitySignature = nextIdentitySignature;
|
|
11157
|
-
clearStorage(previousConfig);
|
|
11158
|
-
clearStorage(this.config);
|
|
11159
|
-
if (this.state.isAuthenticated || this.state.accessToken || this.state.refreshToken || this.state.iframe) {
|
|
11160
|
-
void this.reload();
|
|
11160
|
+
(_a = this.identityAttributeObserver) == null ? void 0 : _a.disconnect();
|
|
11161
|
+
this.identityAttributeObserver = new MutationObserver((mutations) => {
|
|
11162
|
+
const hasIdentityAttributeChange = mutations.some(
|
|
11163
|
+
(mutation) => mutation.type === "attributes" && !!mutation.attributeName && isUserIdentifierAttribute(mutation.attributeName)
|
|
11164
|
+
);
|
|
11165
|
+
if (hasIdentityAttributeChange) {
|
|
11166
|
+
this.handleIdentityConfigChange();
|
|
11161
11167
|
}
|
|
11162
11168
|
});
|
|
11163
|
-
this.
|
|
11169
|
+
this.identityAttributeObserver.observe(this, { attributes: true });
|
|
11170
|
+
}
|
|
11171
|
+
handleIdentityConfigChange() {
|
|
11172
|
+
if (!this.isConnected || !this.config) return;
|
|
11173
|
+
const nextConfig = readConfig(this, this.config.communityId);
|
|
11174
|
+
const nextIdentitySignature = identitySignatureForConfig(nextConfig);
|
|
11175
|
+
if (nextIdentitySignature === this.identitySignature) {
|
|
11176
|
+
this.config = nextConfig;
|
|
11177
|
+
return;
|
|
11178
|
+
}
|
|
11179
|
+
const previousConfig = this.config;
|
|
11180
|
+
this.config = nextConfig;
|
|
11181
|
+
this.identitySignature = nextIdentitySignature;
|
|
11182
|
+
clearStorage(previousConfig);
|
|
11183
|
+
clearStorage(this.config);
|
|
11184
|
+
if (this.hasAttemptedInit) {
|
|
11185
|
+
void this.reload();
|
|
11186
|
+
}
|
|
11164
11187
|
}
|
|
11165
11188
|
// ── DOM event helper (#1) ─────────────────────────────────────────────
|
|
11166
11189
|
emit(type, detail) {
|
|
@@ -11473,12 +11496,19 @@ class BaseWidget extends HTMLElement {
|
|
|
11473
11496
|
}
|
|
11474
11497
|
// ── Initialization ─────────────────────────────────────────────────────
|
|
11475
11498
|
async init() {
|
|
11499
|
+
const initId = ++this.initGeneration;
|
|
11500
|
+
this.hasAttemptedInit = true;
|
|
11476
11501
|
if (!this.config.communityId) {
|
|
11477
11502
|
this.showError();
|
|
11478
11503
|
return;
|
|
11479
11504
|
}
|
|
11480
11505
|
await fetchErrorSettings(this.config, this.state);
|
|
11506
|
+
if (!this.isCurrentInit(initId)) return;
|
|
11481
11507
|
const launchWidget = () => {
|
|
11508
|
+
var _a;
|
|
11509
|
+
if (!this.isCurrentInit(initId)) return;
|
|
11510
|
+
(_a = this.errorEl) == null ? void 0 : _a.classList.remove("visible");
|
|
11511
|
+
this.shadow.querySelectorAll(".rai-custom-error").forEach((el) => el.remove());
|
|
11482
11512
|
if (this.config.bundleUrl) {
|
|
11483
11513
|
this.mountWidget();
|
|
11484
11514
|
} else {
|
|
@@ -11491,6 +11521,7 @@ class BaseWidget extends HTMLElement {
|
|
|
11491
11521
|
this.state,
|
|
11492
11522
|
() => this.scheduleRefresh()
|
|
11493
11523
|
);
|
|
11524
|
+
if (!this.isCurrentInit(initId)) return;
|
|
11494
11525
|
if (authed2) {
|
|
11495
11526
|
this.emit("rai-authenticated");
|
|
11496
11527
|
launchWidget();
|
|
@@ -11507,6 +11538,7 @@ class BaseWidget extends HTMLElement {
|
|
|
11507
11538
|
this.state,
|
|
11508
11539
|
() => this.scheduleRefresh()
|
|
11509
11540
|
);
|
|
11541
|
+
if (!this.isCurrentInit(initId)) return;
|
|
11510
11542
|
if (authed2) {
|
|
11511
11543
|
this.emit("rai-authenticated");
|
|
11512
11544
|
launchWidget();
|
|
@@ -11522,6 +11554,7 @@ class BaseWidget extends HTMLElement {
|
|
|
11522
11554
|
this.state,
|
|
11523
11555
|
() => this.scheduleRefresh()
|
|
11524
11556
|
);
|
|
11557
|
+
if (!this.isCurrentInit(initId)) return;
|
|
11525
11558
|
if (!refreshed) {
|
|
11526
11559
|
this.showError();
|
|
11527
11560
|
return;
|
|
@@ -11536,6 +11569,7 @@ class BaseWidget extends HTMLElement {
|
|
|
11536
11569
|
this.state,
|
|
11537
11570
|
() => this.scheduleRefresh()
|
|
11538
11571
|
);
|
|
11572
|
+
if (!this.isCurrentInit(initId)) return;
|
|
11539
11573
|
if (authed) {
|
|
11540
11574
|
this.emit("rai-authenticated");
|
|
11541
11575
|
launchWidget();
|
|
@@ -11543,7 +11577,26 @@ class BaseWidget extends HTMLElement {
|
|
|
11543
11577
|
this.showError();
|
|
11544
11578
|
}
|
|
11545
11579
|
}
|
|
11580
|
+
isCurrentInit(initId) {
|
|
11581
|
+
return this.isConnected && initId === this.initGeneration;
|
|
11582
|
+
}
|
|
11583
|
+
teardownMountedWidget() {
|
|
11584
|
+
if (this.cleanupListener) {
|
|
11585
|
+
this.cleanupListener();
|
|
11586
|
+
this.cleanupListener = void 0;
|
|
11587
|
+
}
|
|
11588
|
+
if (this.state.syncTimer) {
|
|
11589
|
+
clearInterval(this.state.syncTimer);
|
|
11590
|
+
this.state.syncTimer = null;
|
|
11591
|
+
}
|
|
11592
|
+
this.state.iframe = null;
|
|
11593
|
+
this.shadow.querySelectorAll("iframe").forEach((el) => el.remove());
|
|
11594
|
+
this.querySelectorAll('[data-rai-widget-root="true"]').forEach(
|
|
11595
|
+
(el) => el.remove()
|
|
11596
|
+
);
|
|
11597
|
+
}
|
|
11546
11598
|
createIframe() {
|
|
11599
|
+
this.teardownMountedWidget();
|
|
11547
11600
|
const iframe = document.createElement("iframe");
|
|
11548
11601
|
iframe.src = this.buildWidgetUrl(this.config);
|
|
11549
11602
|
iframe.allow = "clipboard-write";
|
|
@@ -11581,6 +11634,7 @@ class BaseWidget extends HTMLElement {
|
|
|
11581
11634
|
// ── Bundle mode (no-iframe) ──────────────────────────────────────────
|
|
11582
11635
|
async mountWidget() {
|
|
11583
11636
|
try {
|
|
11637
|
+
this.teardownMountedWidget();
|
|
11584
11638
|
const bundleApiUrl = this.config.v2ApiUrl || resolveV2ApiUrl(this.config.domainKey);
|
|
11585
11639
|
const w = window;
|
|
11586
11640
|
if (!w.DomainKey) {
|
|
@@ -11697,7 +11751,7 @@ class BaseWidget extends HTMLElement {
|
|
|
11697
11751
|
// ── Logout helper ─────────────────────────────────────────────────────
|
|
11698
11752
|
async logoutAndClear() {
|
|
11699
11753
|
await logout(this.config, this.state);
|
|
11700
|
-
this.
|
|
11754
|
+
this.teardownMountedWidget();
|
|
11701
11755
|
this.emit("rai-logout");
|
|
11702
11756
|
}
|
|
11703
11757
|
// ── Public API ────────────────────────────────────────────────────────
|
|
@@ -11710,8 +11764,8 @@ class BaseWidget extends HTMLElement {
|
|
|
11710
11764
|
this.style.height = this.config.height;
|
|
11711
11765
|
clearStorage(previousConfig);
|
|
11712
11766
|
clearStorage(this.config);
|
|
11767
|
+
this.teardownMountedWidget();
|
|
11713
11768
|
clearState(this.state);
|
|
11714
|
-
this.shadow.querySelectorAll("iframe").forEach((el) => el.remove());
|
|
11715
11769
|
await this.init();
|
|
11716
11770
|
}
|
|
11717
11771
|
async logoutPublic() {
|
|
@@ -11832,7 +11886,7 @@ class CustomWidget extends BaseWidget {
|
|
|
11832
11886
|
}
|
|
11833
11887
|
}
|
|
11834
11888
|
}
|
|
11835
|
-
console.log(`[rai-widget] v${"1.4.
|
|
11889
|
+
console.log(`[rai-widget] v${"1.4.2"}`);
|
|
11836
11890
|
class StoreWidgetCompat extends StoreWidget {
|
|
11837
11891
|
}
|
|
11838
11892
|
const WIDGET_REGISTRY = [
|
|
@@ -11896,7 +11950,7 @@ function exposePublicApi() {
|
|
|
11896
11950
|
})();
|
|
11897
11951
|
const widget = container == null ? void 0 : container.querySelector(ALL_WIDGET_SELECTOR);
|
|
11898
11952
|
window.ReturningAIWidget = {
|
|
11899
|
-
version: "1.4.
|
|
11953
|
+
version: "1.4.2",
|
|
11900
11954
|
reload: () => (widget == null ? void 0 : widget.reload()) ?? Promise.resolve(),
|
|
11901
11955
|
logout: () => (widget == null ? void 0 : widget.logoutPublic()) ?? Promise.resolve(),
|
|
11902
11956
|
isAuthenticated: () => (widget == null ? void 0 : widget.isAuthenticated()) ?? false,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { WidgetConfig } from "./types";
|
|
2
2
|
export declare function readConfig(el: Element, existingId?: string): WidgetConfig;
|
|
3
3
|
export declare abstract class BaseWidget extends HTMLElement {
|
|
4
|
+
static get observedAttributes(): string[];
|
|
4
5
|
protected shadow: ShadowRoot;
|
|
5
6
|
protected config: WidgetConfig;
|
|
6
7
|
private state;
|
|
@@ -10,14 +11,18 @@ export declare abstract class BaseWidget extends HTMLElement {
|
|
|
10
11
|
private cleanupListener?;
|
|
11
12
|
private intersectionObserver?;
|
|
12
13
|
private themeObserver?;
|
|
13
|
-
private
|
|
14
|
+
private identityAttributeObserver?;
|
|
14
15
|
private identitySignature;
|
|
16
|
+
private hasAttemptedInit;
|
|
17
|
+
private initGeneration;
|
|
15
18
|
private lottieInstances;
|
|
16
19
|
constructor();
|
|
17
20
|
protected abstract buildWidgetUrl(config: WidgetConfig): string;
|
|
18
21
|
connectedCallback(): void;
|
|
19
22
|
disconnectedCallback(): void;
|
|
20
|
-
|
|
23
|
+
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
|
|
24
|
+
private setupIdentityAttributeObserver;
|
|
25
|
+
private handleIdentityConfigChange;
|
|
21
26
|
private emit;
|
|
22
27
|
/**
|
|
23
28
|
* Apply widget-defined CSS colors before first paint so the loader uses
|
|
@@ -80,6 +85,8 @@ export declare abstract class BaseWidget extends HTMLElement {
|
|
|
80
85
|
private showError;
|
|
81
86
|
private renderCustomError;
|
|
82
87
|
private init;
|
|
88
|
+
private isCurrentInit;
|
|
89
|
+
private teardownMountedWidget;
|
|
83
90
|
private createIframe;
|
|
84
91
|
private mountWidget;
|
|
85
92
|
private scheduleRefresh;
|
package/package.json
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@returningai/widget-sdk",
|
|
3
|
-
"version": "1.4.
|
|
4
|
-
"description": "Shadow DOM isolated widget SDK for ReturningAI",
|
|
5
|
-
"main": "dist/rai-widget.iife.js",
|
|
6
|
-
"module": "dist/rai-widget.js",
|
|
7
|
-
"types": "dist/types/index.d.ts",
|
|
8
|
-
"sideEffects": true,
|
|
9
|
-
"exports": {
|
|
10
|
-
".": {
|
|
11
|
-
"import": "./dist/rai-widget.js",
|
|
12
|
-
"default": "./dist/rai-widget.iife.js"
|
|
13
|
-
}
|
|
14
|
-
},
|
|
15
|
-
"files": [
|
|
16
|
-
"dist",
|
|
17
|
-
"CHANGELOG.md",
|
|
18
|
-
"README.md"
|
|
19
|
-
],
|
|
20
|
-
"scripts": {
|
|
21
|
-
"dev": "vite",
|
|
22
|
-
"build": "vite build",
|
|
23
|
-
"build:min": "vite build --mode production",
|
|
24
|
-
"types": "tsc --emitDeclarationOnly --outDir dist/types",
|
|
25
|
-
"prepublishOnly": "npm run build:min && npm run types"
|
|
26
|
-
},
|
|
27
|
-
"devDependencies": {
|
|
28
|
-
"terser": "^5.46.0",
|
|
29
|
-
"typescript": "^5.3.3",
|
|
30
|
-
"vite": "^5.1.0"
|
|
31
|
-
},
|
|
32
|
-
"dependencies": {
|
|
33
|
-
"lottie-web": "^5.13.0"
|
|
34
|
-
}
|
|
35
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@returningai/widget-sdk",
|
|
3
|
+
"version": "1.4.2",
|
|
4
|
+
"description": "Shadow DOM isolated widget SDK for ReturningAI",
|
|
5
|
+
"main": "dist/rai-widget.iife.js",
|
|
6
|
+
"module": "dist/rai-widget.js",
|
|
7
|
+
"types": "dist/types/index.d.ts",
|
|
8
|
+
"sideEffects": true,
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/rai-widget.js",
|
|
12
|
+
"default": "./dist/rai-widget.iife.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"CHANGELOG.md",
|
|
18
|
+
"README.md"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"dev": "vite",
|
|
22
|
+
"build": "vite build",
|
|
23
|
+
"build:min": "vite build --mode production",
|
|
24
|
+
"types": "tsc --emitDeclarationOnly --outDir dist/types",
|
|
25
|
+
"prepublishOnly": "npm run build:min && npm run types"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"terser": "^5.46.0",
|
|
29
|
+
"typescript": "^5.3.3",
|
|
30
|
+
"vite": "^5.1.0"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"lottie-web": "^5.13.0"
|
|
34
|
+
}
|
|
35
|
+
}
|