tia-gpc-widget 1.0.9 → 1.1.0
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/README.md +322 -26
- package/dist/loader.js +271 -0
- package/dist/loader.min.js +3 -0
- package/dist/loader.min.js.map +1 -0
- package/dist/tia-gpc-widget.standalone.css +1 -1
- package/dist/tia-gpc-widget.standalone.js +27 -27
- package/dist/tia-gpc-widget.standalone.js.map +1 -1
- package/dist/tia-gpc.cjs.js +27 -12
- package/dist/tia-gpc.cjs.js.map +1 -1
- package/dist/tia-gpc.css +1 -1
- package/dist/tia-gpc.es.js +4985 -2921
- package/dist/tia-gpc.es.js.map +1 -1
- package/dist/version.json +38 -0
- package/package.json +9 -4
package/README.md
CHANGED
|
@@ -51,9 +51,70 @@ Intelligent chat widget for TIA GPC integration. Compatible with **React, HTML,
|
|
|
51
51
|
|
|
52
52
|
---
|
|
53
53
|
|
|
54
|
+
## 🚀 Auto-Update Loader (Recommended)
|
|
55
|
+
|
|
56
|
+
**NEW!** Install once, get updates forever. No more manual version updates!
|
|
57
|
+
|
|
58
|
+
The **TIA GPC Widget Loader** is a small, stable script (~1KB gzipped) that automatically loads the latest version of the widget. Your clients install it **ONCE** and receive all future updates automatically.
|
|
59
|
+
|
|
60
|
+
### Quick Start with Loader
|
|
61
|
+
|
|
62
|
+
```html
|
|
63
|
+
<!DOCTYPE html>
|
|
64
|
+
<html lang="en">
|
|
65
|
+
<head>
|
|
66
|
+
<meta charset="UTF-8">
|
|
67
|
+
<title>My App with TIA GPC</title>
|
|
68
|
+
</head>
|
|
69
|
+
<body>
|
|
70
|
+
<h1>My Application</h1>
|
|
71
|
+
|
|
72
|
+
<!-- TIA GPC Widget Loader (install once, updates forever) -->
|
|
73
|
+
<script src="https://cdn.jsdelivr.net/npm/tia-gpc-widget@latest/dist/loader.min.js"></script>
|
|
74
|
+
|
|
75
|
+
<!-- Widget element -->
|
|
76
|
+
<tia-gpc-widget
|
|
77
|
+
token="your-license-token-here"
|
|
78
|
+
theme="auto"
|
|
79
|
+
position="bottom-right"
|
|
80
|
+
language="en"
|
|
81
|
+
></tia-gpc-widget>
|
|
82
|
+
</body>
|
|
83
|
+
</html>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**Benefits:**
|
|
87
|
+
- ✅ Install once, never update manually again
|
|
88
|
+
- ✅ Automatic updates when you publish new versions
|
|
89
|
+
- ✅ Built-in error handling and retries
|
|
90
|
+
- ✅ Support for stable/beta channels
|
|
91
|
+
- ✅ Extremely small (~1KB gzipped)
|
|
92
|
+
- ✅ Works with all frameworks (HTML, React, Angular, ASP.NET, etc.)
|
|
93
|
+
|
|
94
|
+
[See complete loader documentation and examples →](#loader-advanced-usage)
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
54
98
|
## 📦 Installation
|
|
55
99
|
|
|
56
|
-
### Option 1:
|
|
100
|
+
### Option 1: Auto-Update Loader (Recommended)
|
|
101
|
+
|
|
102
|
+
Use the loader for automatic updates:
|
|
103
|
+
|
|
104
|
+
```html
|
|
105
|
+
<!-- jsDelivr (Recommended) -->
|
|
106
|
+
<script src="https://cdn.jsdelivr.net/npm/tia-gpc-widget@latest/dist/loader.min.js"></script>
|
|
107
|
+
|
|
108
|
+
<!-- unpkg -->
|
|
109
|
+
<script src="https://unpkg.com/tia-gpc-widget@latest/dist/loader.min.js"></script>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Then use the widget as normal:
|
|
113
|
+
```html
|
|
114
|
+
<tia-gpc-widget token="your-token" theme="auto"></tia-gpc-widget>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Option 2: NPM (For React/Node Projects)
|
|
57
118
|
|
|
58
119
|
```bash
|
|
59
120
|
npm install tia-gpc-widget
|
|
@@ -71,37 +132,35 @@ or with pnpm:
|
|
|
71
132
|
pnpm add tia-gpc-widget
|
|
72
133
|
```
|
|
73
134
|
|
|
74
|
-
### Option
|
|
135
|
+
### Option 3: Direct CDN (Legacy - Not Recommended)
|
|
75
136
|
|
|
76
|
-
|
|
137
|
+
⚠️ **Note:** This method is still supported but **not recommended** for new installations.
|
|
138
|
+
It requires manual updates every time we release a new version.
|
|
139
|
+
**Use the Auto-Update Loader instead** (see Option 1 above).
|
|
77
140
|
|
|
78
|
-
#### jsDelivr
|
|
141
|
+
#### jsDelivr - Fixed Version
|
|
79
142
|
|
|
80
143
|
```html
|
|
81
|
-
<!--
|
|
82
|
-
<script src="https://cdn.jsdelivr.net/npm/tia-gpc-widget@1.0.
|
|
83
|
-
|
|
84
|
-
<!-- CSS -->
|
|
85
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tia-gpc-widget@1.0.6/dist/tia-gpc-widget.standalone.css">
|
|
144
|
+
<!-- ⚠️ Legacy method: Requires manual version updates -->
|
|
145
|
+
<script src="https://cdn.jsdelivr.net/npm/tia-gpc-widget@1.0.9/dist/tia-gpc-widget.standalone.js"></script>
|
|
146
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tia-gpc-widget@1.0.9/dist/tia-gpc-widget.standalone.css">
|
|
86
147
|
```
|
|
87
148
|
|
|
88
|
-
#### unpkg
|
|
149
|
+
#### unpkg - Fixed Version
|
|
89
150
|
|
|
90
151
|
```html
|
|
91
|
-
<!--
|
|
92
|
-
<script src="https://unpkg.com/tia-gpc-widget@1.0.
|
|
93
|
-
|
|
94
|
-
<!-- CSS -->
|
|
95
|
-
<link rel="stylesheet" href="https://unpkg.com/tia-gpc-widget@1.0.6/dist/tia-gpc-widget.standalone.css">
|
|
152
|
+
<!-- ⚠️ Legacy method: Requires manual version updates -->
|
|
153
|
+
<script src="https://unpkg.com/tia-gpc-widget@1.0.9/dist/tia-gpc-widget.standalone.js"></script>
|
|
154
|
+
<link rel="stylesheet" href="https://unpkg.com/tia-gpc-widget@1.0.9/dist/tia-gpc-widget.standalone.css">
|
|
96
155
|
```
|
|
97
156
|
|
|
98
|
-
|
|
157
|
+
**Why use the loader instead?**
|
|
158
|
+
- ✅ Automatic updates - no code changes needed
|
|
159
|
+
- ✅ Always get bug fixes and improvements
|
|
160
|
+
- ✅ Smaller initial load (~2KB vs ~420KB until needed)
|
|
161
|
+
- ✅ Built-in error handling and fallbacks
|
|
99
162
|
|
|
100
|
-
|
|
101
|
-
<!-- Always use specific versions in production! -->
|
|
102
|
-
<script src="https://cdn.jsdelivr.net/npm/tia-gpc-widget/dist/tia-gpc-widget.standalone.js"></script>
|
|
103
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tia-gpc-widget/dist/tia-gpc-widget.standalone.css">
|
|
104
|
-
```
|
|
163
|
+
**For existing installations:** See [Migration Guide](MIGRATION.md) to upgrade to the auto-update loader.
|
|
105
164
|
|
|
106
165
|
---
|
|
107
166
|
|
|
@@ -116,9 +175,6 @@ You can include the widget directly from a CDN:
|
|
|
116
175
|
<meta charset="UTF-8">
|
|
117
176
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
118
177
|
<title>My App with TIA GPC</title>
|
|
119
|
-
|
|
120
|
-
<!-- Widget CSS -->
|
|
121
|
-
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tia-gpc-widget@1.0.6/dist/tia-gpc-widget.standalone.css">
|
|
122
178
|
</head>
|
|
123
179
|
<body>
|
|
124
180
|
<h1>My Application</h1>
|
|
@@ -131,8 +187,8 @@ You can include the widget directly from a CDN:
|
|
|
131
187
|
language="en"
|
|
132
188
|
></tia-gpc-widget>
|
|
133
189
|
|
|
134
|
-
<!--
|
|
135
|
-
<script src="https://cdn.jsdelivr.net/npm/tia-gpc-widget@
|
|
190
|
+
<!-- Auto-Update Loader (loads latest version automatically) -->
|
|
191
|
+
<script src="https://cdn.jsdelivr.net/npm/tia-gpc-widget@latest/dist/loader.min.js"></script>
|
|
136
192
|
</body>
|
|
137
193
|
</html>
|
|
138
194
|
```
|
|
@@ -164,6 +220,12 @@ export default App;
|
|
|
164
220
|
|
|
165
221
|
## 📚 Framework Examples
|
|
166
222
|
|
|
223
|
+
> **💡 Important:** The examples below may show both installation methods:
|
|
224
|
+
> - **Recommended:** Auto-Update Loader (install once, updates automatically)
|
|
225
|
+
> - **Legacy:** Direct CDN with fixed version (requires manual updates)
|
|
226
|
+
>
|
|
227
|
+
> **For new installations, always use the Auto-Update Loader** shown in [Option 1](#option-1-auto-update-loader-recommended).
|
|
228
|
+
|
|
167
229
|
### 1. React
|
|
168
230
|
|
|
169
231
|
#### Installation
|
|
@@ -1089,4 +1151,238 @@ For technical support:
|
|
|
1089
1151
|
|
|
1090
1152
|
---
|
|
1091
1153
|
|
|
1154
|
+
## 📚 Loader Advanced Usage
|
|
1155
|
+
|
|
1156
|
+
### What is the Auto-Update Loader?
|
|
1157
|
+
|
|
1158
|
+
The **TIA GPC Widget Loader** is a revolutionary approach to widget distribution that solves the update problem:
|
|
1159
|
+
|
|
1160
|
+
- **Traditional approach**: Clients must manually update the version number in their code every time you release
|
|
1161
|
+
- **Loader approach**: Clients install once, you control which version they receive via `version.json`
|
|
1162
|
+
|
|
1163
|
+
### How it Works
|
|
1164
|
+
|
|
1165
|
+
1. **Client installs the loader** (one time only):
|
|
1166
|
+
```html
|
|
1167
|
+
<script src="https://cdn.jsdelivr.net/npm/tia-gpc-widget@latest/dist/loader.min.js"></script>
|
|
1168
|
+
```
|
|
1169
|
+
|
|
1170
|
+
2. **Loader fetches** `version.json` to determine which widget version to load
|
|
1171
|
+
|
|
1172
|
+
3. **Loader dynamically loads** the appropriate widget version
|
|
1173
|
+
|
|
1174
|
+
4. **You publish a new version**:
|
|
1175
|
+
```bash
|
|
1176
|
+
npm run build # Automatically updates version.json
|
|
1177
|
+
npm publish
|
|
1178
|
+
```
|
|
1179
|
+
|
|
1180
|
+
5. **All clients automatically receive the new version** (within minutes, when CDN syncs)
|
|
1181
|
+
|
|
1182
|
+
### Configuration Options
|
|
1183
|
+
|
|
1184
|
+
#### Loader Attributes
|
|
1185
|
+
|
|
1186
|
+
| Attribute | Type | Default | Description |
|
|
1187
|
+
|-----------|------|---------|-------------|
|
|
1188
|
+
| `data-channel` | `'stable' \| 'beta'` | `'stable'` | Distribution channel |
|
|
1189
|
+
| `data-version` | `string` | `null` | Pin to specific version (disables auto-update) |
|
|
1190
|
+
| `data-debug` | `boolean` | `false` | Enable debug logging |
|
|
1191
|
+
| `data-api-url` | `string` | `null` | Analytics endpoint URL |
|
|
1192
|
+
|
|
1193
|
+
#### Examples
|
|
1194
|
+
|
|
1195
|
+
**Use beta channel:**
|
|
1196
|
+
```html
|
|
1197
|
+
<script
|
|
1198
|
+
src="https://cdn.jsdelivr.net/npm/tia-gpc-widget@latest/dist/loader.min.js"
|
|
1199
|
+
data-channel="beta"
|
|
1200
|
+
></script>
|
|
1201
|
+
```
|
|
1202
|
+
|
|
1203
|
+
**Pin to specific version (no auto-update):**
|
|
1204
|
+
```html
|
|
1205
|
+
<script
|
|
1206
|
+
src="https://cdn.jsdelivr.net/npm/tia-gpc-widget@latest/dist/loader.min.js"
|
|
1207
|
+
data-version="1.0.8"
|
|
1208
|
+
></script>
|
|
1209
|
+
```
|
|
1210
|
+
|
|
1211
|
+
**Enable debug mode:**
|
|
1212
|
+
```html
|
|
1213
|
+
<script
|
|
1214
|
+
src="https://cdn.jsdelivr.net/npm/tia-gpc-widget@latest/dist/loader.min.js"
|
|
1215
|
+
data-debug="true"
|
|
1216
|
+
></script>
|
|
1217
|
+
```
|
|
1218
|
+
|
|
1219
|
+
### Loader Events
|
|
1220
|
+
|
|
1221
|
+
The loader emits custom events you can listen to:
|
|
1222
|
+
|
|
1223
|
+
```javascript
|
|
1224
|
+
// Widget loaded successfully
|
|
1225
|
+
window.addEventListener('tia-gpc-loader-ready', (event) => {
|
|
1226
|
+
console.log('Widget loaded:', event.detail);
|
|
1227
|
+
// event.detail = {
|
|
1228
|
+
// version: "1.0.9",
|
|
1229
|
+
// loadTime: 1234, // milliseconds
|
|
1230
|
+
// attempts: 1,
|
|
1231
|
+
// channel: "stable"
|
|
1232
|
+
// }
|
|
1233
|
+
});
|
|
1234
|
+
|
|
1235
|
+
// Widget failed to load
|
|
1236
|
+
window.addEventListener('tia-gpc-loader-error', (event) => {
|
|
1237
|
+
console.error('Widget error:', event.detail);
|
|
1238
|
+
// event.detail = {
|
|
1239
|
+
// error: "Failed to load...",
|
|
1240
|
+
// attempts: 3,
|
|
1241
|
+
// version: "1.0.9"
|
|
1242
|
+
// }
|
|
1243
|
+
});
|
|
1244
|
+
```
|
|
1245
|
+
|
|
1246
|
+
### Loader API
|
|
1247
|
+
|
|
1248
|
+
The loader exposes a global `TiaGPCLoader` object:
|
|
1249
|
+
|
|
1250
|
+
```javascript
|
|
1251
|
+
// Get loader version
|
|
1252
|
+
console.log(window.TiaGPCLoader.version); // "1.0.0"
|
|
1253
|
+
|
|
1254
|
+
// Reload widget
|
|
1255
|
+
window.TiaGPCLoader.reload();
|
|
1256
|
+
|
|
1257
|
+
// Get configuration
|
|
1258
|
+
console.log(window.TiaGPCLoader.config);
|
|
1259
|
+
```
|
|
1260
|
+
|
|
1261
|
+
### Version Control with version.json
|
|
1262
|
+
|
|
1263
|
+
The `version.json` file controls which version is served to clients:
|
|
1264
|
+
|
|
1265
|
+
```json
|
|
1266
|
+
{
|
|
1267
|
+
"version": "1.0.9",
|
|
1268
|
+
"stable": {
|
|
1269
|
+
"version": "1.0.9",
|
|
1270
|
+
"js": "https://cdn.jsdelivr.net/npm/tia-gpc-widget@1.0.9/dist/tia-gpc-widget.standalone.js",
|
|
1271
|
+
"css": "https://cdn.jsdelivr.net/npm/tia-gpc-widget@1.0.9/dist/tia-gpc-widget.standalone.css",
|
|
1272
|
+
"cdn": "jsdelivr"
|
|
1273
|
+
},
|
|
1274
|
+
"beta": {
|
|
1275
|
+
"version": "1.1.0-beta",
|
|
1276
|
+
"js": "https://cdn.jsdelivr.net/npm/tia-gpc-widget@1.1.0-beta/dist/tia-gpc-widget.standalone.js",
|
|
1277
|
+
"css": "https://cdn.jsdelivr.net/npm/tia-gpc-widget@1.1.0-beta/dist/tia-gpc-widget.standalone.css",
|
|
1278
|
+
"cdn": "jsdelivr"
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
```
|
|
1282
|
+
|
|
1283
|
+
This file is automatically generated when you run `npm run build`.
|
|
1284
|
+
|
|
1285
|
+
### Deployment Workflow
|
|
1286
|
+
|
|
1287
|
+
#### Before (without loader):
|
|
1288
|
+
```bash
|
|
1289
|
+
# 1. Make changes to widget
|
|
1290
|
+
# 2. Build
|
|
1291
|
+
npm run build
|
|
1292
|
+
|
|
1293
|
+
# 3. Publish to npm
|
|
1294
|
+
npm publish
|
|
1295
|
+
|
|
1296
|
+
# ❌ Clients must manually update their code:
|
|
1297
|
+
# <script src="...@1.0.6/..."></script> → <script src="...@1.0.7/..."></script>
|
|
1298
|
+
```
|
|
1299
|
+
|
|
1300
|
+
#### After (with loader):
|
|
1301
|
+
```bash
|
|
1302
|
+
# 1. Make changes to widget
|
|
1303
|
+
# 2. Build (automatically updates version.json)
|
|
1304
|
+
npm run build
|
|
1305
|
+
|
|
1306
|
+
# 3. Publish to npm
|
|
1307
|
+
npm publish
|
|
1308
|
+
|
|
1309
|
+
# ✅ All clients automatically receive the new version!
|
|
1310
|
+
# No manual updates required!
|
|
1311
|
+
```
|
|
1312
|
+
|
|
1313
|
+
### Advanced: Gradual Rollout
|
|
1314
|
+
|
|
1315
|
+
You can manually edit `version.json` to implement gradual rollouts:
|
|
1316
|
+
|
|
1317
|
+
```json
|
|
1318
|
+
{
|
|
1319
|
+
"stable": {
|
|
1320
|
+
"version": "1.0.9",
|
|
1321
|
+
"rollout": {
|
|
1322
|
+
"percentage": 50, // Only 50% of users get this version
|
|
1323
|
+
"whitelist": ["client-id-1", "client-id-2"],
|
|
1324
|
+
"blacklist": ["problematic-client"]
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
```
|
|
1329
|
+
|
|
1330
|
+
Note: Rollout logic must be implemented on your backend.
|
|
1331
|
+
|
|
1332
|
+
### Migration Guide
|
|
1333
|
+
|
|
1334
|
+
#### Migrating from Direct CDN Links
|
|
1335
|
+
|
|
1336
|
+
**Before:**
|
|
1337
|
+
```html
|
|
1338
|
+
<script src="https://cdn.jsdelivr.net/npm/tia-gpc-widget@1.0.6/dist/tia-gpc-widget.standalone.js"></script>
|
|
1339
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tia-gpc-widget@1.0.6/dist/tia-gpc-widget.standalone.css">
|
|
1340
|
+
|
|
1341
|
+
<tia-gpc-widget token="xxx"></tia-gpc-widget>
|
|
1342
|
+
```
|
|
1343
|
+
|
|
1344
|
+
**After:**
|
|
1345
|
+
```html
|
|
1346
|
+
<script src="https://cdn.jsdelivr.net/npm/tia-gpc-widget@latest/dist/loader.min.js"></script>
|
|
1347
|
+
|
|
1348
|
+
<tia-gpc-widget token="xxx"></tia-gpc-widget>
|
|
1349
|
+
```
|
|
1350
|
+
|
|
1351
|
+
That's it! The loader handles everything else.
|
|
1352
|
+
|
|
1353
|
+
### Troubleshooting
|
|
1354
|
+
|
|
1355
|
+
#### Loader not loading widget
|
|
1356
|
+
|
|
1357
|
+
1. Open browser console and check for errors
|
|
1358
|
+
2. Enable debug mode: `data-debug="true"`
|
|
1359
|
+
3. Check network tab for failed requests
|
|
1360
|
+
4. Verify `version.json` is accessible
|
|
1361
|
+
|
|
1362
|
+
#### Widget not updating
|
|
1363
|
+
|
|
1364
|
+
1. Clear browser cache
|
|
1365
|
+
2. Check that `version.json` has the correct version
|
|
1366
|
+
3. Wait for CDN to sync (can take 5-10 minutes)
|
|
1367
|
+
4. Check if client is using `data-version` (which pins to specific version)
|
|
1368
|
+
|
|
1369
|
+
#### Using with Content Security Policy (CSP)
|
|
1370
|
+
|
|
1371
|
+
If your site uses CSP, you may need to add:
|
|
1372
|
+
|
|
1373
|
+
```html
|
|
1374
|
+
<meta http-equiv="Content-Security-Policy" content="
|
|
1375
|
+
script-src 'self' https://cdn.jsdelivr.net https://unpkg.com;
|
|
1376
|
+
style-src 'self' https://cdn.jsdelivr.net https://unpkg.com;
|
|
1377
|
+
connect-src 'self' https://cdn.jsdelivr.net https://unpkg.com;
|
|
1378
|
+
">
|
|
1379
|
+
```
|
|
1380
|
+
|
|
1381
|
+
### Examples
|
|
1382
|
+
|
|
1383
|
+
See complete examples in the `/examples` folder:
|
|
1384
|
+
- `examples/loader-usage.html` - Complete loader demo with all features
|
|
1385
|
+
|
|
1386
|
+
---
|
|
1387
|
+
|
|
1092
1388
|
**Built with ❤️ by the TIA team**
|
package/dist/loader.js
ADDED
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TIA GPC Widget Loader
|
|
3
|
+
* @version 1.0.0
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
(function() {
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const CONFIG = {
|
|
10
|
+
versionUrl: 'https://cdn.jsdelivr.net/npm/tia-gpc-widget@latest/dist/version.json',
|
|
11
|
+
defaultChannel: 'stable',
|
|
12
|
+
timeout: 15000,
|
|
13
|
+
maxRetries: 3,
|
|
14
|
+
retryDelay: 2000,
|
|
15
|
+
fallbackVersion: '1.0.9',
|
|
16
|
+
fallbackCdn: 'https://cdn.jsdelivr.net/npm/tia-gpc-widget'
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
let loadAttempts = 0;
|
|
20
|
+
let loadStartTime = Date.now();
|
|
21
|
+
|
|
22
|
+
const log = {
|
|
23
|
+
info: function(msg, data) {
|
|
24
|
+
console.log('[TIA GPC Loader]', msg, data || '');
|
|
25
|
+
},
|
|
26
|
+
warn: function(msg, data) {
|
|
27
|
+
console.warn('[TIA GPC Loader]', msg, data || '');
|
|
28
|
+
},
|
|
29
|
+
error: function(msg, data) {
|
|
30
|
+
console.error('[TIA GPC Loader]', msg, data || '');
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
function isAlreadyLoaded() {
|
|
35
|
+
return window.TiaGPCWidgetLoaded === true || window.TiaGPC !== undefined;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function getLoaderConfig() {
|
|
39
|
+
const scriptTag = document.currentScript ||
|
|
40
|
+
document.querySelector('script[src*="loader"]');
|
|
41
|
+
|
|
42
|
+
if (!scriptTag) return {};
|
|
43
|
+
|
|
44
|
+
return {
|
|
45
|
+
channel: scriptTag.getAttribute('data-channel') || CONFIG.defaultChannel,
|
|
46
|
+
version: scriptTag.getAttribute('data-version') || null,
|
|
47
|
+
debug: scriptTag.getAttribute('data-debug') === 'true',
|
|
48
|
+
apiUrl: scriptTag.getAttribute('data-api-url') || null
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function emit(eventName, detail) {
|
|
53
|
+
window.dispatchEvent(new CustomEvent(eventName, { detail }));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function loadScript(url, timeout) {
|
|
57
|
+
return new Promise((resolve, reject) => {
|
|
58
|
+
const script = document.createElement('script');
|
|
59
|
+
script.src = url;
|
|
60
|
+
script.async = true;
|
|
61
|
+
script.crossOrigin = 'anonymous';
|
|
62
|
+
|
|
63
|
+
let timeoutId;
|
|
64
|
+
|
|
65
|
+
script.onload = function() {
|
|
66
|
+
clearTimeout(timeoutId);
|
|
67
|
+
resolve();
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
script.onerror = function() {
|
|
71
|
+
clearTimeout(timeoutId);
|
|
72
|
+
reject(new Error(`Failed to load script: ${url}`));
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
timeoutId = setTimeout(() => {
|
|
76
|
+
reject(new Error(`Timeout loading script: ${url}`));
|
|
77
|
+
}, timeout || CONFIG.timeout);
|
|
78
|
+
|
|
79
|
+
document.head.appendChild(script);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function loadStyles(url) {
|
|
84
|
+
return new Promise((resolve, reject) => {
|
|
85
|
+
const existingLink = document.querySelector(`link[href*="${url}"]`);
|
|
86
|
+
if (existingLink) {
|
|
87
|
+
resolve();
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const link = document.createElement('link');
|
|
92
|
+
link.rel = 'stylesheet';
|
|
93
|
+
link.href = url;
|
|
94
|
+
link.crossOrigin = 'anonymous';
|
|
95
|
+
|
|
96
|
+
link.onload = resolve;
|
|
97
|
+
link.onerror = () => reject(new Error(`Failed to load CSS: ${url}`));
|
|
98
|
+
|
|
99
|
+
document.head.appendChild(link);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function fetchVersionInfo(loaderConfig) {
|
|
104
|
+
try {
|
|
105
|
+
if (loaderConfig.version) {
|
|
106
|
+
return buildFallbackUrls(loaderConfig.version);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const response = await fetch(CONFIG.versionUrl, {
|
|
110
|
+
cache: 'no-cache',
|
|
111
|
+
headers: {
|
|
112
|
+
'Cache-Control': 'no-cache, no-store, must-revalidate',
|
|
113
|
+
'Pragma': 'no-cache',
|
|
114
|
+
'Expires': '0'
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
if (!response.ok) {
|
|
119
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const data = await response.json();
|
|
123
|
+
const channelData = data[loaderConfig.channel] || data.stable;
|
|
124
|
+
|
|
125
|
+
return {
|
|
126
|
+
version: data.version,
|
|
127
|
+
js: channelData.js,
|
|
128
|
+
css: channelData.css,
|
|
129
|
+
timestamp: data.timestamp
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
} catch (error) {
|
|
133
|
+
log.warn('Failed to fetch version info, using fallback', error.message);
|
|
134
|
+
return buildFallbackUrls(CONFIG.fallbackVersion);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function buildFallbackUrls(version) {
|
|
139
|
+
const baseUrl = CONFIG.fallbackCdn;
|
|
140
|
+
return {
|
|
141
|
+
version: version,
|
|
142
|
+
js: `${baseUrl}@${version}/dist/tia-gpc-widget.standalone.js`,
|
|
143
|
+
css: `${baseUrl}@${version}/dist/tia-gpc-widget.standalone.css`,
|
|
144
|
+
timestamp: null
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
async function loadWidgetWithRetry(versionInfo, loaderConfig) {
|
|
149
|
+
loadAttempts++;
|
|
150
|
+
|
|
151
|
+
try {
|
|
152
|
+
log.info(`Loading widget v${versionInfo.version} (attempt ${loadAttempts}/${CONFIG.maxRetries})...`);
|
|
153
|
+
|
|
154
|
+
loadStyles(versionInfo.css).catch(err => {
|
|
155
|
+
log.warn('CSS loading failed, continuing anyway', err);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
await loadScript(versionInfo.js, CONFIG.timeout);
|
|
159
|
+
|
|
160
|
+
if (!window.TiaGPC) {
|
|
161
|
+
throw new Error('Widget loaded but TiaGPC global not found');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const loadTime = Date.now() - loadStartTime;
|
|
165
|
+
|
|
166
|
+
log.info(`Widget v${versionInfo.version} loaded successfully in ${loadTime}ms`);
|
|
167
|
+
|
|
168
|
+
window.TiaGPCWidgetLoaded = true;
|
|
169
|
+
window.TiaGPCWidgetVersion = versionInfo.version;
|
|
170
|
+
|
|
171
|
+
emit('tia-gpc-loader-ready', {
|
|
172
|
+
version: versionInfo.version,
|
|
173
|
+
loadTime: loadTime,
|
|
174
|
+
attempts: loadAttempts,
|
|
175
|
+
channel: loaderConfig.channel
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
if (loaderConfig.apiUrl) {
|
|
179
|
+
sendAnalytics(loaderConfig.apiUrl, {
|
|
180
|
+
event: 'widget_loaded',
|
|
181
|
+
version: versionInfo.version,
|
|
182
|
+
loadTime: loadTime,
|
|
183
|
+
url: window.location.href
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return true;
|
|
188
|
+
|
|
189
|
+
} catch (error) {
|
|
190
|
+
log.error(`Failed to load widget (attempt ${loadAttempts})`, error.message);
|
|
191
|
+
|
|
192
|
+
if (loadAttempts < CONFIG.maxRetries) {
|
|
193
|
+
log.info(`Retrying in ${CONFIG.retryDelay}ms...`);
|
|
194
|
+
await new Promise(resolve => setTimeout(resolve, CONFIG.retryDelay));
|
|
195
|
+
return loadWidgetWithRetry(versionInfo, loaderConfig);
|
|
196
|
+
} else {
|
|
197
|
+
emit('tia-gpc-loader-error', {
|
|
198
|
+
error: error.message,
|
|
199
|
+
attempts: loadAttempts,
|
|
200
|
+
version: versionInfo.version
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
throw new Error(`Failed to load widget after ${loadAttempts} attempts: ${error.message}`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function sendAnalytics(apiUrl, data) {
|
|
209
|
+
try {
|
|
210
|
+
fetch(apiUrl, {
|
|
211
|
+
method: 'POST',
|
|
212
|
+
headers: { 'Content-Type': 'application/json' },
|
|
213
|
+
body: JSON.stringify(data)
|
|
214
|
+
}).catch(() => {});
|
|
215
|
+
} catch (e) {
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
async function init() {
|
|
220
|
+
try {
|
|
221
|
+
if (isAlreadyLoaded()) {
|
|
222
|
+
log.warn('Widget already loaded, skipping');
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
log.info('Initializing TIA GPC Widget Loader...');
|
|
227
|
+
|
|
228
|
+
const loaderConfig = getLoaderConfig();
|
|
229
|
+
|
|
230
|
+
if (loaderConfig.debug) {
|
|
231
|
+
log.info('Loader config:', loaderConfig);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const versionInfo = await fetchVersionInfo(loaderConfig);
|
|
235
|
+
|
|
236
|
+
if (loaderConfig.debug) {
|
|
237
|
+
log.info('Version info:', versionInfo);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
await loadWidgetWithRetry(versionInfo, loaderConfig);
|
|
241
|
+
|
|
242
|
+
} catch (error) {
|
|
243
|
+
log.error('Fatal error initializing widget', error);
|
|
244
|
+
|
|
245
|
+
const widgets = document.querySelectorAll('tia-gpc-widget');
|
|
246
|
+
if (widgets.length > 0) {
|
|
247
|
+
widgets.forEach(widget => {
|
|
248
|
+
widget.innerHTML = `
|
|
249
|
+
<div style="padding: 20px; background: #fee; border: 2px solid #c00; border-radius: 8px; font-family: sans-serif;">
|
|
250
|
+
<strong>Error loading TIA GPC Widget</strong>
|
|
251
|
+
<p style="margin: 10px 0 0 0; font-size: 14px;">${error.message}</p>
|
|
252
|
+
</div>
|
|
253
|
+
`;
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (document.readyState === 'loading') {
|
|
260
|
+
document.addEventListener('DOMContentLoaded', init);
|
|
261
|
+
} else {
|
|
262
|
+
init();
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
window.TiaGPCLoader = {
|
|
266
|
+
version: '1.0.0',
|
|
267
|
+
reload: init,
|
|
268
|
+
config: CONFIG
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
})();
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
/*! TIA GPC Widget Loader v1.0.0 | (c) 2025 TIA | UNLICENSED */
|
|
2
|
+
!function(){"use strict";const e={versionUrl:"https://cdn.jsdelivr.net/npm/tia-gpc-widget@latest/dist/version.json",defaultChannel:"stable",timeout:15e3,maxRetries:3,retryDelay:2e3,fallbackVersion:"1.0.9",fallbackCdn:"https://cdn.jsdelivr.net/npm/tia-gpc-widget"};let t=0,n=Date.now();const o=function(e,t){console.log("[TIA GPC Loader]",e,t||"")},i=function(e,t){console.warn("[TIA GPC Loader]",e,t||"")},r=function(e,t){console.error("[TIA GPC Loader]",e,t||"")};function a(e,t){window.dispatchEvent(new CustomEvent(e,{detail:t}))}function s(t){const n=e.fallbackCdn;return{version:t,js:`${n}@${t}/dist/tia-gpc-widget.standalone.js`,css:`${n}@${t}/dist/tia-gpc-widget.standalone.css`,timestamp:null}}async function d(s,c){t++;try{if(o(`Loading widget v${s.version} (attempt ${t}/${e.maxRetries})...`),(l=s.css,new Promise((e,t)=>{if(document.querySelector(`link[href*="${l}"]`))return void e();const n=document.createElement("link");n.rel="stylesheet",n.href=l,n.crossOrigin="anonymous",n.onload=e,n.onerror=()=>t(new Error(`Failed to load CSS: ${l}`)),document.head.appendChild(n)})).catch(e=>{i("CSS loading failed, continuing anyway",e)}),await function(t,n){return new Promise((o,i)=>{const r=document.createElement("script");let a;r.src=t,r.async=!0,r.crossOrigin="anonymous",r.onload=function(){clearTimeout(a),o()},r.onerror=function(){clearTimeout(a),i(new Error(`Failed to load script: ${t}`))},a=setTimeout(()=>{i(new Error(`Timeout loading script: ${t}`))},n||e.timeout),document.head.appendChild(r)})}(s.js,e.timeout),!window.TiaGPC)throw new Error("Widget loaded but TiaGPC global not found");const r=Date.now()-n;return o(`Widget v${s.version} loaded successfully in ${r}ms`),window.TiaGPCWidgetLoaded=!0,window.TiaGPCWidgetVersion=s.version,a("tia-gpc-loader-ready",{version:s.version,loadTime:r,attempts:t,channel:c.channel}),c.apiUrl&&function(e,t){try{fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}).catch(()=>{})}catch(e){}}(c.apiUrl,{event:"widget_loaded",version:s.version,loadTime:r,url:window.location.href}),!0}catch(n){if(r(`Failed to load widget (attempt ${t})`,n.message),t<e.maxRetries)return o(`Retrying in ${e.retryDelay}ms...`),await new Promise(t=>setTimeout(t,e.retryDelay)),d(s,c);throw a("tia-gpc-loader-error",{error:n.message,attempts:t,version:s.version}),new Error(`Failed to load widget after ${t} attempts: ${n.message}`)}var l}async function c(){try{if(!0===window.TiaGPCWidgetLoaded||void 0!==window.TiaGPC)return void i("Widget already loaded, skipping");o("Initializing TIA GPC Widget Loader...");const t=function(){const t=document.currentScript||document.querySelector('script[src*="loader"]');return t?{channel:t.getAttribute("data-channel")||e.defaultChannel,version:t.getAttribute("data-version")||null,debug:"true"===t.getAttribute("data-debug"),apiUrl:t.getAttribute("data-api-url")||null}:{}}();t.debug&&o("Loader config:",t);const n=await async function(t){try{if(t.version)return s(t.version);const n=await fetch(e.versionUrl,{cache:"no-cache",headers:{"Cache-Control":"no-cache, no-store, must-revalidate",Pragma:"no-cache",Expires:"0"}});if(!n.ok)throw new Error(`HTTP ${n.status}: ${n.statusText}`);const o=await n.json(),i=o[t.channel]||o.stable;return{version:o.version,js:i.js,css:i.css,timestamp:o.timestamp}}catch(t){return i("Failed to fetch version info, using fallback",t.message),s(e.fallbackVersion)}}(t);t.debug&&o("Version info:",n),await d(n,t)}catch(e){r("Fatal error initializing widget",e);const t=document.querySelectorAll("tia-gpc-widget");t.length>0&&t.forEach(t=>{t.innerHTML=`\n <div style="padding: 20px; background: #fee; border: 2px solid #c00; border-radius: 8px; font-family: sans-serif;">\n <strong>Error loading TIA GPC Widget</strong>\n <p style="margin: 10px 0 0 0; font-size: 14px;">${e.message}</p>\n </div>\n `})}}"loading"===document.readyState?document.addEventListener("DOMContentLoaded",c):c(),window.TiaGPCLoader={version:"1.0.0",reload:c,config:e}}();
|
|
3
|
+
//# sourceMappingURL=loader.min.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.min.js","names":["CONFIG","versionUrl","defaultChannel","timeout","maxRetries","retryDelay","fallbackVersion","fallbackCdn","loadAttempts","loadStartTime","Date","now","log","msg","data","console","warn","error","emit","eventName","detail","window","dispatchEvent","CustomEvent","buildFallbackUrls","version","baseUrl","js","css","timestamp","async","loadWidgetWithRetry","versionInfo","loaderConfig","url","Promise","resolve","reject","document","querySelector","link","createElement","rel","href","crossOrigin","onload","onerror","Error","head","appendChild","catch","err","script","timeoutId","src","clearTimeout","setTimeout","loadScript","TiaGPC","loadTime","TiaGPCWidgetLoaded","TiaGPCWidgetVersion","attempts","channel","apiUrl","fetch","method","headers","body","JSON","stringify","e","sendAnalytics","event","location","message","init","undefined","scriptTag","currentScript","getAttribute","debug","getLoaderConfig","response","cache","Pragma","Expires","ok","status","statusText","json","channelData","stable","fetchVersionInfo","widgets","querySelectorAll","length","forEach","widget","innerHTML","readyState","addEventListener","TiaGPCLoader","reload","config"],"sources":["0"],"mappings":"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","ignoreList":[]}
|