@ait-co/devtools 0.1.6 → 0.1.8
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/mock/index.d.ts +5 -0
- package/dist/mock/index.d.ts.map +1 -1
- package/dist/mock/index.js +11 -1
- package/dist/mock/index.js.map +1 -1
- package/dist/panel/index.js +324 -4
- package/dist/panel/index.js.map +1 -1
- package/package.json +1 -1
package/dist/panel/index.js
CHANGED
|
@@ -71,7 +71,9 @@ const DEFAULT_STATE = {
|
|
|
71
71
|
},
|
|
72
72
|
ads: {
|
|
73
73
|
isLoaded: false,
|
|
74
|
-
nextEvent: "loaded"
|
|
74
|
+
nextEvent: "loaded",
|
|
75
|
+
forceNoFill: false,
|
|
76
|
+
lastEvent: null
|
|
75
77
|
},
|
|
76
78
|
game: {
|
|
77
79
|
profile: {
|
|
@@ -1335,6 +1337,192 @@ function renderDeviceTab() {
|
|
|
1335
1337
|
return container;
|
|
1336
1338
|
}
|
|
1337
1339
|
//#endregion
|
|
1340
|
+
//#region src/mock/ads/index.ts
|
|
1341
|
+
/**
|
|
1342
|
+
* 광고 mock (GoogleAdMob, TossAds, FullScreenAd)
|
|
1343
|
+
*/
|
|
1344
|
+
function withIsSupported(fn) {
|
|
1345
|
+
fn.isSupported = () => true;
|
|
1346
|
+
return fn;
|
|
1347
|
+
}
|
|
1348
|
+
const GoogleAdMob = createMockProxy("GoogleAdMob", {
|
|
1349
|
+
loadAppsInTossAdMob: withIsSupported((args) => {
|
|
1350
|
+
setTimeout(() => {
|
|
1351
|
+
if (aitState.state.ads.forceNoFill) {
|
|
1352
|
+
args.onError(/* @__PURE__ */ new Error("No fill"));
|
|
1353
|
+
return;
|
|
1354
|
+
}
|
|
1355
|
+
aitState.patch("ads", { isLoaded: true });
|
|
1356
|
+
args.onEvent({
|
|
1357
|
+
type: "loaded",
|
|
1358
|
+
data: { adGroupId: args.options?.adGroupId }
|
|
1359
|
+
});
|
|
1360
|
+
}, 200);
|
|
1361
|
+
return () => {};
|
|
1362
|
+
}),
|
|
1363
|
+
showAppsInTossAdMob: withIsSupported((args) => {
|
|
1364
|
+
if (!aitState.state.ads.isLoaded) {
|
|
1365
|
+
args.onError(/* @__PURE__ */ new Error("Ad not loaded"));
|
|
1366
|
+
return () => {};
|
|
1367
|
+
}
|
|
1368
|
+
setTimeout(() => args.onEvent({ type: "requested" }), 50);
|
|
1369
|
+
setTimeout(() => args.onEvent({ type: "show" }), 100);
|
|
1370
|
+
setTimeout(() => args.onEvent({ type: "impression" }), 150);
|
|
1371
|
+
setTimeout(() => {
|
|
1372
|
+
args.onEvent({
|
|
1373
|
+
type: "userEarnedReward",
|
|
1374
|
+
data: {
|
|
1375
|
+
unitType: "coins",
|
|
1376
|
+
unitAmount: 10
|
|
1377
|
+
}
|
|
1378
|
+
});
|
|
1379
|
+
}, 1e3);
|
|
1380
|
+
setTimeout(() => {
|
|
1381
|
+
args.onEvent({ type: "dismissed" });
|
|
1382
|
+
aitState.patch("ads", { isLoaded: false });
|
|
1383
|
+
}, 1500);
|
|
1384
|
+
return () => {};
|
|
1385
|
+
}),
|
|
1386
|
+
isAppsInTossAdMobLoaded: withIsSupported(async (_options) => aitState.state.ads.isLoaded)
|
|
1387
|
+
});
|
|
1388
|
+
createMockProxy("TossAds", {
|
|
1389
|
+
initialize: withIsSupported((_options) => {
|
|
1390
|
+
console.log("[@ait-co/devtools] TossAds.initialize (mock)");
|
|
1391
|
+
}),
|
|
1392
|
+
attach: withIsSupported((_adGroupId, target, _options) => {
|
|
1393
|
+
const el = typeof target === "string" ? document.querySelector(target) : target;
|
|
1394
|
+
if (el) {
|
|
1395
|
+
const placeholder = document.createElement("div");
|
|
1396
|
+
placeholder.style.cssText = "background:#f0f0f0;border:1px dashed #999;padding:16px;text-align:center;color:#666;font-size:14px;";
|
|
1397
|
+
placeholder.textContent = "[@ait-co/devtools] TossAds Placeholder";
|
|
1398
|
+
el.appendChild(placeholder);
|
|
1399
|
+
}
|
|
1400
|
+
}),
|
|
1401
|
+
attachBanner: withIsSupported((_adGroupId, target, _options) => {
|
|
1402
|
+
const el = typeof target === "string" ? document.querySelector(target) : target;
|
|
1403
|
+
if (el) {
|
|
1404
|
+
const placeholder = document.createElement("div");
|
|
1405
|
+
placeholder.style.cssText = "background:#f0f0f0;border:1px dashed #999;padding:12px;text-align:center;color:#666;font-size:12px;";
|
|
1406
|
+
placeholder.textContent = "[@ait-co/devtools] Banner Ad Placeholder";
|
|
1407
|
+
el.appendChild(placeholder);
|
|
1408
|
+
}
|
|
1409
|
+
return { destroy: () => {} };
|
|
1410
|
+
}),
|
|
1411
|
+
destroy: withIsSupported((_slotId) => {}),
|
|
1412
|
+
destroyAll: withIsSupported(() => {})
|
|
1413
|
+
});
|
|
1414
|
+
const loadFullScreenAd = withIsSupported((args) => {
|
|
1415
|
+
setTimeout(() => {
|
|
1416
|
+
if (aitState.state.ads.forceNoFill) {
|
|
1417
|
+
args.onError(/* @__PURE__ */ new Error("No fill"));
|
|
1418
|
+
return;
|
|
1419
|
+
}
|
|
1420
|
+
aitState.patch("ads", { isLoaded: true });
|
|
1421
|
+
args.onEvent({
|
|
1422
|
+
type: "loaded",
|
|
1423
|
+
data: { adGroupId: args.options?.adGroupId }
|
|
1424
|
+
});
|
|
1425
|
+
}, 200);
|
|
1426
|
+
return () => {};
|
|
1427
|
+
});
|
|
1428
|
+
const showFullScreenAd = withIsSupported((args) => {
|
|
1429
|
+
if (!aitState.state.ads.isLoaded) {
|
|
1430
|
+
args.onError(/* @__PURE__ */ new Error("Ad not loaded"));
|
|
1431
|
+
return () => {};
|
|
1432
|
+
}
|
|
1433
|
+
setTimeout(() => args.onEvent({ type: "show" }), 100);
|
|
1434
|
+
setTimeout(() => args.onEvent({ type: "dismissed" }), 1500);
|
|
1435
|
+
return () => {};
|
|
1436
|
+
});
|
|
1437
|
+
//#endregion
|
|
1438
|
+
//#region src/panel/tabs/ads.ts
|
|
1439
|
+
function recordEvent(type) {
|
|
1440
|
+
aitState.patch("ads", { lastEvent: {
|
|
1441
|
+
type,
|
|
1442
|
+
timestamp: Date.now()
|
|
1443
|
+
} });
|
|
1444
|
+
}
|
|
1445
|
+
function recordError(message) {
|
|
1446
|
+
recordEvent(`error: ${message}`);
|
|
1447
|
+
}
|
|
1448
|
+
function statusRow(label, value) {
|
|
1449
|
+
return h("div", { className: "ait-row" }, h("label", {}, label), h("span", { style: "font-family:SF Mono,Menlo,monospace;font-size:11px;color:#aaa" }, value));
|
|
1450
|
+
}
|
|
1451
|
+
function lastEventLine() {
|
|
1452
|
+
const last = aitState.state.ads.lastEvent;
|
|
1453
|
+
if (!last) return h("div", { className: "ait-log-entry" }, h("span", { style: "color:#555" }, "No events yet"));
|
|
1454
|
+
const time = new Date(last.timestamp).toLocaleTimeString();
|
|
1455
|
+
return h("div", { className: "ait-log-entry" }, h("span", {
|
|
1456
|
+
className: "ait-log-type",
|
|
1457
|
+
style: last.type.startsWith("error:") ? "color:#e74c3c" : ""
|
|
1458
|
+
}, last.type), h("span", { className: "ait-log-time" }, time));
|
|
1459
|
+
}
|
|
1460
|
+
function adSection(title, onLoad, onShow, disabled) {
|
|
1461
|
+
const loadBtn = h("button", { className: "ait-btn ait-btn-sm" }, "Load");
|
|
1462
|
+
const showBtn = h("button", { className: "ait-btn ait-btn-sm" }, "Show");
|
|
1463
|
+
if (disabled) {
|
|
1464
|
+
loadBtn.disabled = true;
|
|
1465
|
+
showBtn.disabled = true;
|
|
1466
|
+
}
|
|
1467
|
+
loadBtn.addEventListener("click", onLoad);
|
|
1468
|
+
showBtn.addEventListener("click", onShow);
|
|
1469
|
+
return h("div", { className: "ait-section" }, h("div", { className: "ait-section-title" }, title), h("div", { className: "ait-btn-row" }, loadBtn, showBtn));
|
|
1470
|
+
}
|
|
1471
|
+
function renderAdsTab() {
|
|
1472
|
+
const s = aitState.state;
|
|
1473
|
+
const disabled = !s.panelEditable;
|
|
1474
|
+
const container = h("div");
|
|
1475
|
+
if (disabled) container.appendChild(monitoringNotice());
|
|
1476
|
+
const forceNoFillCb = h("input", {
|
|
1477
|
+
type: "checkbox",
|
|
1478
|
+
className: "ait-checkbox"
|
|
1479
|
+
});
|
|
1480
|
+
forceNoFillCb.checked = s.ads.forceNoFill;
|
|
1481
|
+
if (disabled) forceNoFillCb.disabled = true;
|
|
1482
|
+
forceNoFillCb.addEventListener("change", () => {
|
|
1483
|
+
aitState.patch("ads", { forceNoFill: forceNoFillCb.checked });
|
|
1484
|
+
});
|
|
1485
|
+
container.append(h("div", { className: "ait-section" }, h("div", { className: "ait-section-title" }, "Ads State"), statusRow("isLoaded", String(s.ads.isLoaded)), h("div", { className: "ait-row" }, h("label", {}, "Force \"no fill\""), forceNoFillCb), lastEventLine()), adSection("GoogleAdMob", () => {
|
|
1486
|
+
GoogleAdMob.loadAppsInTossAdMob({
|
|
1487
|
+
onEvent: (e) => recordEvent(e.type),
|
|
1488
|
+
onError: (err) => recordError(err.message)
|
|
1489
|
+
});
|
|
1490
|
+
}, () => {
|
|
1491
|
+
GoogleAdMob.showAppsInTossAdMob({
|
|
1492
|
+
onEvent: (e) => recordEvent(e.type),
|
|
1493
|
+
onError: (err) => recordError(err.message)
|
|
1494
|
+
});
|
|
1495
|
+
}, disabled), adSection("TossAds", () => {
|
|
1496
|
+
if (aitState.state.ads.forceNoFill) {
|
|
1497
|
+
recordError("No fill");
|
|
1498
|
+
return;
|
|
1499
|
+
}
|
|
1500
|
+
aitState.patch("ads", { isLoaded: true });
|
|
1501
|
+
recordEvent("loaded");
|
|
1502
|
+
}, () => {
|
|
1503
|
+
if (!aitState.state.ads.isLoaded) {
|
|
1504
|
+
recordError("Ad not loaded");
|
|
1505
|
+
return;
|
|
1506
|
+
}
|
|
1507
|
+
recordEvent("show");
|
|
1508
|
+
setTimeout(() => {
|
|
1509
|
+
recordEvent("dismissed");
|
|
1510
|
+
aitState.patch("ads", { isLoaded: false });
|
|
1511
|
+
}, 1500);
|
|
1512
|
+
}, disabled), adSection("FullScreenAd", () => {
|
|
1513
|
+
loadFullScreenAd({
|
|
1514
|
+
onEvent: (e) => recordEvent(e.type),
|
|
1515
|
+
onError: (err) => recordError(err.message)
|
|
1516
|
+
});
|
|
1517
|
+
}, () => {
|
|
1518
|
+
showFullScreenAd({
|
|
1519
|
+
onEvent: (e) => recordEvent(e.type),
|
|
1520
|
+
onError: (err) => recordError(err.message)
|
|
1521
|
+
});
|
|
1522
|
+
}, disabled));
|
|
1523
|
+
return container;
|
|
1524
|
+
}
|
|
1525
|
+
//#endregion
|
|
1338
1526
|
//#region src/panel/tabs/analytics.ts
|
|
1339
1527
|
function renderAnalyticsTab() {
|
|
1340
1528
|
const disabled = !aitState.state.panelEditable;
|
|
@@ -1390,7 +1578,119 @@ function renderEventsTab() {
|
|
|
1390
1578
|
return container;
|
|
1391
1579
|
}
|
|
1392
1580
|
//#endregion
|
|
1581
|
+
//#region src/mock/iap/index.ts
|
|
1582
|
+
/**
|
|
1583
|
+
* IAP (인앱결제) mock
|
|
1584
|
+
*/
|
|
1585
|
+
let orderCounter = 0;
|
|
1586
|
+
function generateOrderId() {
|
|
1587
|
+
return `mock-order-${++orderCounter}-${Date.now()}`;
|
|
1588
|
+
}
|
|
1589
|
+
function buildOrderResult(sku) {
|
|
1590
|
+
const product = aitState.state.iap.products.find((p) => p.sku === sku);
|
|
1591
|
+
const amountStr = product?.displayAmount?.replace(/[^0-9]/g, "") ?? "1000";
|
|
1592
|
+
return {
|
|
1593
|
+
orderId: generateOrderId(),
|
|
1594
|
+
displayName: product?.displayName ?? "Mock Product",
|
|
1595
|
+
displayAmount: product?.displayAmount ?? "1,000원",
|
|
1596
|
+
amount: parseInt(amountStr, 10) || 1e3,
|
|
1597
|
+
currency: "KRW",
|
|
1598
|
+
fraction: 0,
|
|
1599
|
+
miniAppIconUrl: product?.iconUrl || null
|
|
1600
|
+
};
|
|
1601
|
+
}
|
|
1602
|
+
async function handlePurchase(sku, processProductGrant, onEvent, onError) {
|
|
1603
|
+
const nextResult = aitState.state.iap.nextResult;
|
|
1604
|
+
await new Promise((r) => setTimeout(r, 300));
|
|
1605
|
+
if (nextResult !== "success") {
|
|
1606
|
+
onError({ code: nextResult });
|
|
1607
|
+
return;
|
|
1608
|
+
}
|
|
1609
|
+
const result = buildOrderResult(sku);
|
|
1610
|
+
try {
|
|
1611
|
+
if (!await processProductGrant({ orderId: result.orderId })) {
|
|
1612
|
+
onError({ code: "PRODUCT_NOT_GRANTED_BY_PARTNER" });
|
|
1613
|
+
return;
|
|
1614
|
+
}
|
|
1615
|
+
} catch (e) {
|
|
1616
|
+
onError(e);
|
|
1617
|
+
return;
|
|
1618
|
+
}
|
|
1619
|
+
aitState.patch("iap", { completedOrders: [...aitState.state.iap.completedOrders, {
|
|
1620
|
+
orderId: result.orderId,
|
|
1621
|
+
sku,
|
|
1622
|
+
status: "COMPLETED",
|
|
1623
|
+
date: (/* @__PURE__ */ new Date()).toISOString()
|
|
1624
|
+
}] });
|
|
1625
|
+
await onEvent({
|
|
1626
|
+
type: "success",
|
|
1627
|
+
data: result
|
|
1628
|
+
});
|
|
1629
|
+
}
|
|
1630
|
+
const IAP = createMockProxy("IAP", {
|
|
1631
|
+
createOneTimePurchaseOrder(params) {
|
|
1632
|
+
handlePurchase(params.options.sku ?? params.options.productId ?? "", params.options.processProductGrant, params.onEvent, params.onError).catch((e) => console.error("[@ait-co/devtools] IAP unexpected error:", e));
|
|
1633
|
+
return () => {};
|
|
1634
|
+
},
|
|
1635
|
+
createSubscriptionPurchaseOrder(params) {
|
|
1636
|
+
handlePurchase(params.options.sku, params.options.processProductGrant, params.onEvent, params.onError).catch((e) => console.error("[@ait-co/devtools] IAP unexpected error:", e));
|
|
1637
|
+
return () => {};
|
|
1638
|
+
},
|
|
1639
|
+
async getProductItemList() {
|
|
1640
|
+
return { products: aitState.state.iap.products.map((p) => ({
|
|
1641
|
+
...p,
|
|
1642
|
+
...p.type === "SUBSCRIPTION" ? { renewalCycle: p.renewalCycle ?? "MONTHLY" } : {}
|
|
1643
|
+
})) };
|
|
1644
|
+
},
|
|
1645
|
+
async getPendingOrders() {
|
|
1646
|
+
return { orders: [...aitState.state.iap.pendingOrders] };
|
|
1647
|
+
},
|
|
1648
|
+
async getCompletedOrRefundedOrders() {
|
|
1649
|
+
return {
|
|
1650
|
+
hasNext: false,
|
|
1651
|
+
nextKey: null,
|
|
1652
|
+
orders: [...aitState.state.iap.completedOrders]
|
|
1653
|
+
};
|
|
1654
|
+
},
|
|
1655
|
+
async completeProductGrant(args) {
|
|
1656
|
+
const idx = aitState.state.iap.pendingOrders.findIndex((o) => o.orderId === args.params.orderId);
|
|
1657
|
+
if (idx !== -1) {
|
|
1658
|
+
const order = aitState.state.iap.pendingOrders[idx];
|
|
1659
|
+
const pendingOrders = aitState.state.iap.pendingOrders.filter((_, i) => i !== idx);
|
|
1660
|
+
const completedOrders = [...aitState.state.iap.completedOrders, {
|
|
1661
|
+
orderId: order.orderId,
|
|
1662
|
+
sku: order.sku,
|
|
1663
|
+
status: "COMPLETED",
|
|
1664
|
+
date: (/* @__PURE__ */ new Date()).toISOString()
|
|
1665
|
+
}];
|
|
1666
|
+
aitState.patch("iap", {
|
|
1667
|
+
pendingOrders,
|
|
1668
|
+
completedOrders
|
|
1669
|
+
});
|
|
1670
|
+
}
|
|
1671
|
+
return true;
|
|
1672
|
+
},
|
|
1673
|
+
async getSubscriptionInfo(_args) {
|
|
1674
|
+
return { subscription: {
|
|
1675
|
+
catalogId: 1,
|
|
1676
|
+
status: "ACTIVE",
|
|
1677
|
+
expiresAt: new Date(Date.now() + 720 * 60 * 60 * 1e3).toISOString(),
|
|
1678
|
+
isAutoRenew: true,
|
|
1679
|
+
gracePeriodExpiresAt: null,
|
|
1680
|
+
isAccessible: true
|
|
1681
|
+
} };
|
|
1682
|
+
}
|
|
1683
|
+
});
|
|
1684
|
+
//#endregion
|
|
1393
1685
|
//#region src/panel/tabs/iap.ts
|
|
1686
|
+
function formatTimestamp(iso) {
|
|
1687
|
+
const d = new Date(iso);
|
|
1688
|
+
if (Number.isNaN(d.getTime())) return iso;
|
|
1689
|
+
return d.toLocaleTimeString();
|
|
1690
|
+
}
|
|
1691
|
+
function shortOrderId(orderId) {
|
|
1692
|
+
return orderId.length > 12 ? `…${orderId.slice(-10)}` : orderId;
|
|
1693
|
+
}
|
|
1394
1694
|
function renderIapTab() {
|
|
1395
1695
|
const s = aitState.state;
|
|
1396
1696
|
const disabled = !s.panelEditable;
|
|
@@ -1405,11 +1705,26 @@ function renderIapTab() {
|
|
|
1405
1705
|
"INTERNAL_ERROR"
|
|
1406
1706
|
];
|
|
1407
1707
|
if (disabled) container.appendChild(monitoringNotice());
|
|
1708
|
+
const pendingOrders = s.iap.pendingOrders;
|
|
1709
|
+
const pendingSection = h("div", { className: "ait-section" }, h("div", { className: "ait-section-title" }, `Pending Orders (${pendingOrders.length})`));
|
|
1710
|
+
if (pendingOrders.length === 0) pendingSection.appendChild(h("div", { className: "ait-log-entry" }, "(no pending orders)"));
|
|
1711
|
+
else for (const o of pendingOrders) {
|
|
1712
|
+
const completeBtn = h("button", { className: "ait-btn ait-btn-sm" }, "Complete");
|
|
1713
|
+
if (disabled) completeBtn.disabled = true;
|
|
1714
|
+
completeBtn.addEventListener("click", () => {
|
|
1715
|
+
IAP.completeProductGrant({ params: { orderId: o.orderId } }).catch((err) => console.error("[@ait-co/devtools] completeProductGrant error:", err));
|
|
1716
|
+
});
|
|
1717
|
+
pendingSection.appendChild(h("div", { className: "ait-log-entry" }, h("span", { className: "ait-log-type" }, "PENDING"), `${o.sku} (${shortOrderId(o.orderId)}) · ${formatTimestamp(o.paymentCompletedDate)} `, completeBtn));
|
|
1718
|
+
}
|
|
1719
|
+
const completedOrders = s.iap.completedOrders;
|
|
1720
|
+
const completedSection = h("div", { className: "ait-section" }, h("div", { className: "ait-section-title" }, `Completed Orders (${completedOrders.length})`));
|
|
1721
|
+
if (completedOrders.length === 0) completedSection.appendChild(h("div", { className: "ait-log-entry" }, "(no completed orders)"));
|
|
1722
|
+
else for (const o of completedOrders) completedSection.appendChild(h("div", { className: "ait-log-entry" }, h("span", { className: "ait-log-type" }, o.status), `${o.sku} (${shortOrderId(o.orderId)}) · ${formatTimestamp(o.date)}`));
|
|
1408
1723
|
container.append(h("div", { className: "ait-section" }, h("div", { className: "ait-section-title" }, "IAP Simulator"), selectRow("Next Purchase Result", results, s.iap.nextResult, (v) => {
|
|
1409
1724
|
aitState.patch("iap", { nextResult: v });
|
|
1410
1725
|
}, disabled)), h("div", { className: "ait-section" }, h("div", { className: "ait-section-title" }, "TossPay"), selectRow("Next Payment Result", ["success", "fail"], s.payment.nextResult, (v) => {
|
|
1411
1726
|
aitState.patch("payment", { nextResult: v });
|
|
1412
|
-
}, disabled)),
|
|
1727
|
+
}, disabled)), pendingSection, completedSection);
|
|
1413
1728
|
return container;
|
|
1414
1729
|
}
|
|
1415
1730
|
//#endregion
|
|
@@ -2154,6 +2469,10 @@ const TABS = [
|
|
|
2154
2469
|
id: "iap",
|
|
2155
2470
|
label: "IAP"
|
|
2156
2471
|
},
|
|
2472
|
+
{
|
|
2473
|
+
id: "ads",
|
|
2474
|
+
label: "Ads"
|
|
2475
|
+
},
|
|
2157
2476
|
{
|
|
2158
2477
|
id: "events",
|
|
2159
2478
|
label: "Events"
|
|
@@ -2175,6 +2494,7 @@ function createTabRenderers(refreshPanel) {
|
|
|
2175
2494
|
device: renderDeviceTab,
|
|
2176
2495
|
viewport: renderViewportTab,
|
|
2177
2496
|
iap: renderIapTab,
|
|
2497
|
+
ads: renderAdsTab,
|
|
2178
2498
|
events: renderEventsTab,
|
|
2179
2499
|
analytics: renderAnalyticsTab,
|
|
2180
2500
|
storage: () => renderStorageTab(refreshPanel)
|
|
@@ -2375,7 +2695,7 @@ function mount() {
|
|
|
2375
2695
|
mockBadge.textContent = aitState.state.panelEditable ? "EDIT" : "READ-ONLY";
|
|
2376
2696
|
refreshPanel();
|
|
2377
2697
|
});
|
|
2378
|
-
const headerRight = h("span", { style: "display:flex;align-items:center;gap:6px" }, mockBadge, h("span", { style: "font-size:11px;color:#666;font-weight:400" }, `v0.1.
|
|
2698
|
+
const headerRight = h("span", { style: "display:flex;align-items:center;gap:6px" }, mockBadge, h("span", { style: "font-size:11px;color:#666;font-weight:400" }, `v0.1.8`), closeBtn);
|
|
2379
2699
|
const header = h("div", { className: "ait-panel-header" }, h("span", {}, "AIT DevTools"), headerRight);
|
|
2380
2700
|
tabsEl = h("div", { className: "ait-panel-tabs" });
|
|
2381
2701
|
for (const tab of TABS) {
|
|
@@ -2414,7 +2734,7 @@ function mount() {
|
|
|
2414
2734
|
});
|
|
2415
2735
|
aitState.subscribe(() => {
|
|
2416
2736
|
try {
|
|
2417
|
-
if (isOpen && (currentTab === "analytics" || currentTab === "storage" || currentTab === "device" || currentTab === "viewport")) refreshPanel();
|
|
2737
|
+
if (isOpen && (currentTab === "analytics" || currentTab === "storage" || currentTab === "device" || currentTab === "viewport" || currentTab === "iap" || currentTab === "ads")) refreshPanel();
|
|
2418
2738
|
} catch (err) {
|
|
2419
2739
|
console.error("[@ait-co/devtools] Error in subscribe callback:", err);
|
|
2420
2740
|
}
|