@braine/quantum-query 1.2.1 → 1.2.3
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 +26 -0
- package/dist/index.cjs +235 -68
- package/dist/index.d.cts +8 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +236 -69
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -132,6 +132,32 @@ const user = await api.get<User>('/me');
|
|
|
132
132
|
|
|
133
133
|
---
|
|
134
134
|
|
|
135
|
+
## 🔐 Authentication (Built-in)
|
|
136
|
+
|
|
137
|
+
No more interceptors. We handle token injection and **automatic refresh on 401** errors out of the box.
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
const client = createClient({
|
|
141
|
+
baseURL: 'https://api.myapp.com',
|
|
142
|
+
auth: {
|
|
143
|
+
// 1. Inject Token
|
|
144
|
+
getToken: () => localStorage.getItem('token'),
|
|
145
|
+
|
|
146
|
+
// 2. Refresh & Retry (Auto-called on 401)
|
|
147
|
+
onTokenExpired: async (client) => {
|
|
148
|
+
const newToken = await refreshToken();
|
|
149
|
+
localStorage.setItem('token', newToken);
|
|
150
|
+
return newToken; // Original request is automatically retried
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
// 3. Redirect on Fail
|
|
154
|
+
onAuthFailed: () => window.location.href = '/login'
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
135
161
|
## 🛡️ Data Integrity (Runtime Safety)
|
|
136
162
|
|
|
137
163
|
Don't trust the backend. Validate it. We support **Zod**, **Valibot**, or **Yup** schemas directly in the hook.
|
package/dist/index.cjs
CHANGED
|
@@ -793,6 +793,21 @@ var QueryCache = class {
|
|
|
793
793
|
this.deduplicationCache.set(key, promise);
|
|
794
794
|
return promise;
|
|
795
795
|
};
|
|
796
|
+
/**
|
|
797
|
+
* Invalidate all queries
|
|
798
|
+
*/
|
|
799
|
+
invalidateAll = () => {
|
|
800
|
+
for (const key of this.signals.keys()) {
|
|
801
|
+
this.signals.get(key)?.set(void 0);
|
|
802
|
+
}
|
|
803
|
+
};
|
|
804
|
+
/**
|
|
805
|
+
* Remove a specific query from cache
|
|
806
|
+
*/
|
|
807
|
+
remove = (queryKey) => {
|
|
808
|
+
const key = this.generateKey(queryKey);
|
|
809
|
+
this.signals.delete(key);
|
|
810
|
+
};
|
|
796
811
|
/**
|
|
797
812
|
* Invalidate queries matching the key prefix
|
|
798
813
|
* Marks them as undefined to trigger refetches without breaking subscriptions
|
|
@@ -1448,7 +1463,7 @@ function useQueryCache() {
|
|
|
1448
1463
|
const [cache, setCache] = (0, import_react7.useState)(client.getAll());
|
|
1449
1464
|
(0, import_react7.useEffect)(() => {
|
|
1450
1465
|
const interval = setInterval(() => {
|
|
1451
|
-
setCache(
|
|
1466
|
+
setCache(new Map(client.getAll()));
|
|
1452
1467
|
}, 500);
|
|
1453
1468
|
return () => clearInterval(interval);
|
|
1454
1469
|
}, [client]);
|
|
@@ -1459,8 +1474,17 @@ function useQueryCache() {
|
|
|
1459
1474
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
1460
1475
|
function QuantumDevTools() {
|
|
1461
1476
|
const [isOpen, setIsOpen] = (0, import_react8.useState)(false);
|
|
1477
|
+
const [filter, setFilter] = (0, import_react8.useState)("");
|
|
1462
1478
|
const cache = useQueryCache();
|
|
1463
1479
|
const client = useQueryClient();
|
|
1480
|
+
const entries = (0, import_react8.useMemo)(() => Array.from(cache.entries()), [cache]);
|
|
1481
|
+
const filteredEntries = (0, import_react8.useMemo)(() => {
|
|
1482
|
+
if (!filter) return entries;
|
|
1483
|
+
const search = filter.toLowerCase();
|
|
1484
|
+
return entries.filter(
|
|
1485
|
+
([_, entry]) => entry.key.some((k) => String(k).toLowerCase().includes(search))
|
|
1486
|
+
);
|
|
1487
|
+
}, [entries, filter]);
|
|
1464
1488
|
if (!isOpen) {
|
|
1465
1489
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1466
1490
|
"button",
|
|
@@ -1468,22 +1492,28 @@ function QuantumDevTools() {
|
|
|
1468
1492
|
onClick: () => setIsOpen(true),
|
|
1469
1493
|
style: {
|
|
1470
1494
|
position: "fixed",
|
|
1471
|
-
bottom: "
|
|
1472
|
-
right: "
|
|
1473
|
-
background: "#
|
|
1474
|
-
color: "#
|
|
1475
|
-
|
|
1495
|
+
bottom: "20px",
|
|
1496
|
+
right: "20px",
|
|
1497
|
+
background: "#111",
|
|
1498
|
+
color: "#b0fb5d",
|
|
1499
|
+
// Quantum Green
|
|
1500
|
+
border: "1px solid #333",
|
|
1476
1501
|
borderRadius: "50%",
|
|
1477
|
-
width: "
|
|
1478
|
-
height: "
|
|
1502
|
+
width: "48px",
|
|
1503
|
+
height: "48px",
|
|
1479
1504
|
cursor: "pointer",
|
|
1480
1505
|
zIndex: 9999,
|
|
1481
|
-
boxShadow: "0
|
|
1506
|
+
boxShadow: "0 8px 32px rgba(0, 0, 0, 0.4)",
|
|
1482
1507
|
fontSize: "20px",
|
|
1483
1508
|
display: "flex",
|
|
1484
1509
|
alignItems: "center",
|
|
1485
|
-
justifyContent: "center"
|
|
1510
|
+
justifyContent: "center",
|
|
1511
|
+
transition: "transform 0.2s",
|
|
1512
|
+
fontFamily: "monospace"
|
|
1486
1513
|
},
|
|
1514
|
+
onMouseEnter: (e) => e.currentTarget.style.transform = "scale(1.1)",
|
|
1515
|
+
onMouseLeave: (e) => e.currentTarget.style.transform = "scale(1)",
|
|
1516
|
+
title: "Open Quantum DevTools",
|
|
1487
1517
|
children: "\u26A1\uFE0F"
|
|
1488
1518
|
}
|
|
1489
1519
|
);
|
|
@@ -1493,27 +1523,39 @@ function QuantumDevTools() {
|
|
|
1493
1523
|
bottom: 0,
|
|
1494
1524
|
right: 0,
|
|
1495
1525
|
width: "100%",
|
|
1496
|
-
maxWidth: "
|
|
1497
|
-
height: "
|
|
1498
|
-
background: "#
|
|
1499
|
-
color: "#
|
|
1500
|
-
borderTopLeftRadius: "
|
|
1501
|
-
boxShadow: "0 -
|
|
1526
|
+
maxWidth: "650px",
|
|
1527
|
+
height: "450px",
|
|
1528
|
+
background: "#0a0a0a",
|
|
1529
|
+
color: "#e0e0e0",
|
|
1530
|
+
borderTopLeftRadius: "12px",
|
|
1531
|
+
boxShadow: "0 -10px 40px rgba(0,0,0,0.5)",
|
|
1502
1532
|
zIndex: 9999,
|
|
1503
1533
|
display: "flex",
|
|
1504
1534
|
flexDirection: "column",
|
|
1505
|
-
fontFamily: "monospace"
|
|
1535
|
+
fontFamily: "'JetBrains Mono', 'Fira Code', monospace",
|
|
1536
|
+
fontSize: "13px",
|
|
1537
|
+
border: "1px solid #333"
|
|
1506
1538
|
}, children: [
|
|
1507
1539
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
|
|
1508
|
-
padding: "
|
|
1509
|
-
borderBottom: "1px solid #
|
|
1540
|
+
padding: "12px 16px",
|
|
1541
|
+
borderBottom: "1px solid #222",
|
|
1510
1542
|
display: "flex",
|
|
1511
1543
|
justifyContent: "space-between",
|
|
1512
1544
|
alignItems: "center",
|
|
1513
|
-
background: "#
|
|
1514
|
-
borderTopLeftRadius: "
|
|
1545
|
+
background: "#111",
|
|
1546
|
+
borderTopLeftRadius: "12px"
|
|
1515
1547
|
}, children: [
|
|
1516
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.
|
|
1548
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
|
1549
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: "#b0fb5d", fontSize: "16px" }, children: "\u26A1\uFE0F" }),
|
|
1550
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { fontWeight: 600, letterSpacing: "-0.5px" }, children: "Quantum DevTools" }),
|
|
1551
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: {
|
|
1552
|
+
background: "#222",
|
|
1553
|
+
padding: "2px 6px",
|
|
1554
|
+
borderRadius: "4px",
|
|
1555
|
+
fontSize: "10px",
|
|
1556
|
+
color: "#666"
|
|
1557
|
+
}, children: "v1.2.2" })
|
|
1558
|
+
] }),
|
|
1517
1559
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1518
1560
|
"button",
|
|
1519
1561
|
{
|
|
@@ -1521,58 +1563,166 @@ function QuantumDevTools() {
|
|
|
1521
1563
|
style: {
|
|
1522
1564
|
background: "transparent",
|
|
1523
1565
|
border: "none",
|
|
1524
|
-
color: "#
|
|
1566
|
+
color: "#666",
|
|
1567
|
+
cursor: "pointer",
|
|
1568
|
+
fontSize: "20px",
|
|
1569
|
+
padding: "4px",
|
|
1570
|
+
lineHeight: 1
|
|
1571
|
+
},
|
|
1572
|
+
children: "\xD7"
|
|
1573
|
+
}
|
|
1574
|
+
)
|
|
1575
|
+
] }),
|
|
1576
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
|
|
1577
|
+
padding: "8px 16px",
|
|
1578
|
+
borderBottom: "1px solid #222",
|
|
1579
|
+
background: "#0f0f0f",
|
|
1580
|
+
display: "flex",
|
|
1581
|
+
gap: "12px"
|
|
1582
|
+
}, children: [
|
|
1583
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1584
|
+
"input",
|
|
1585
|
+
{
|
|
1586
|
+
type: "text",
|
|
1587
|
+
placeholder: "Filter queries...",
|
|
1588
|
+
value: filter,
|
|
1589
|
+
onChange: (e) => setFilter(e.target.value),
|
|
1590
|
+
style: {
|
|
1591
|
+
background: "#1a1a1a",
|
|
1592
|
+
border: "1px solid #333",
|
|
1593
|
+
color: "#fff",
|
|
1594
|
+
padding: "6px 10px",
|
|
1595
|
+
borderRadius: "4px",
|
|
1596
|
+
flex: 1,
|
|
1597
|
+
fontSize: "12px",
|
|
1598
|
+
outline: "none"
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
),
|
|
1602
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1603
|
+
"button",
|
|
1604
|
+
{
|
|
1605
|
+
onClick: () => client.invalidateAll(),
|
|
1606
|
+
title: "Invalidate All Queries",
|
|
1607
|
+
style: {
|
|
1608
|
+
background: "#222",
|
|
1609
|
+
border: "1px solid #333",
|
|
1610
|
+
color: "#d69e2e",
|
|
1611
|
+
borderRadius: "4px",
|
|
1612
|
+
padding: "0 12px",
|
|
1525
1613
|
cursor: "pointer",
|
|
1526
|
-
fontSize: "
|
|
1614
|
+
fontSize: "12px",
|
|
1615
|
+
fontWeight: 500
|
|
1527
1616
|
},
|
|
1528
|
-
children: "\
|
|
1617
|
+
children: "\u21BB Invalidate All"
|
|
1529
1618
|
}
|
|
1530
1619
|
)
|
|
1531
1620
|
] }),
|
|
1532
1621
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
|
|
1533
1622
|
flex: 1,
|
|
1534
1623
|
overflowY: "auto",
|
|
1535
|
-
padding: "
|
|
1624
|
+
padding: "8px",
|
|
1536
1625
|
display: "flex",
|
|
1537
1626
|
flexDirection: "column",
|
|
1538
|
-
gap: "8px"
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1627
|
+
gap: "8px",
|
|
1628
|
+
background: "#050505"
|
|
1629
|
+
}, children: entries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
|
|
1630
|
+
padding: "40px",
|
|
1631
|
+
textAlign: "center",
|
|
1632
|
+
color: "#444",
|
|
1633
|
+
fontStyle: "italic"
|
|
1634
|
+
}, children: "No active queries in cache." }) : filteredEntries.map(([keyHash, entry]) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1635
|
+
QueryItem,
|
|
1636
|
+
{
|
|
1637
|
+
entry,
|
|
1638
|
+
client,
|
|
1639
|
+
isStale: client.isStale(entry.key)
|
|
1640
|
+
},
|
|
1641
|
+
keyHash
|
|
1642
|
+
)) })
|
|
1643
|
+
] });
|
|
1644
|
+
}
|
|
1645
|
+
function QueryItem({ entry, client, isStale }) {
|
|
1646
|
+
const [expanded, setExpanded] = (0, import_react8.useState)(false);
|
|
1647
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
|
|
1648
|
+
background: "#111",
|
|
1649
|
+
borderRadius: "6px",
|
|
1650
|
+
border: "1px solid #222",
|
|
1651
|
+
overflow: "hidden"
|
|
1652
|
+
}, children: [
|
|
1653
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
1654
|
+
"div",
|
|
1655
|
+
{
|
|
1656
|
+
onClick: () => setExpanded(!expanded),
|
|
1657
|
+
style: {
|
|
1658
|
+
padding: "8px 12px",
|
|
1659
|
+
display: "flex",
|
|
1660
|
+
alignItems: "center",
|
|
1661
|
+
justifyContent: "space-between",
|
|
1662
|
+
cursor: "pointer",
|
|
1663
|
+
background: expanded ? "#161616" : "transparent"
|
|
1664
|
+
},
|
|
1665
|
+
children: [
|
|
1666
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: "10px", alignItems: "center", overflow: "hidden" }, children: [
|
|
1667
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: {
|
|
1668
|
+
color: isStale ? "#d69e2e" : "#b0fb5d",
|
|
1669
|
+
fontSize: "14px",
|
|
1670
|
+
fontWeight: "bold",
|
|
1671
|
+
minWidth: "10px"
|
|
1672
|
+
}, children: isStale ? "\u2022" : "\u2022" }),
|
|
1673
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: {
|
|
1674
|
+
color: "#e0e0e0",
|
|
1675
|
+
fontWeight: 500,
|
|
1676
|
+
whiteSpace: "nowrap",
|
|
1677
|
+
overflow: "hidden",
|
|
1678
|
+
textOverflow: "ellipsis"
|
|
1679
|
+
}, children: [
|
|
1680
|
+
"['",
|
|
1681
|
+
entry.key.join("', '"),
|
|
1682
|
+
"']"
|
|
1683
|
+
] })
|
|
1684
|
+
] }),
|
|
1685
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: "8px", alignItems: "center" }, children: [
|
|
1686
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: {
|
|
1687
|
+
fontSize: "10px",
|
|
1688
|
+
padding: "2px 6px",
|
|
1689
|
+
borderRadius: "3px",
|
|
1690
|
+
background: isStale ? "rgba(214, 158, 46, 0.15)" : "rgba(176, 251, 93, 0.15)",
|
|
1691
|
+
color: isStale ? "#d69e2e" : "#b0fb5d",
|
|
1692
|
+
border: `1px solid ${isStale ? "rgba(214, 158, 46, 0.3)" : "rgba(176, 251, 93, 0.3)"}`
|
|
1693
|
+
}, children: isStale ? "STALE" : "FRESH" }),
|
|
1694
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: "#666", fontSize: "10px" }, children: expanded ? "\u25BC" : "\u25B6" })
|
|
1695
|
+
] })
|
|
1696
|
+
]
|
|
1697
|
+
}
|
|
1698
|
+
),
|
|
1699
|
+
expanded && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
|
|
1700
|
+
padding: "10px",
|
|
1701
|
+
borderTop: "1px solid #222",
|
|
1702
|
+
background: "#0a0a0a"
|
|
1544
1703
|
}, children: [
|
|
1545
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
color: "#000"
|
|
1553
|
-
}, children: client.isStale(entry.key) ? "STALE" : "FRESH" }) })
|
|
1554
|
-
] }),
|
|
1555
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
|
|
1556
|
-
fontSize: "11px",
|
|
1557
|
-
color: "#ddd",
|
|
1558
|
-
whiteSpace: "pre-wrap",
|
|
1559
|
-
maxHeight: "100px",
|
|
1560
|
-
overflow: "hidden",
|
|
1561
|
-
opacity: 0.8
|
|
1562
|
-
}, children: JSON.stringify(entry.data, null, 2) }),
|
|
1563
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { marginTop: "8px", display: "flex", gap: "8px" }, children: [
|
|
1704
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
|
|
1705
|
+
display: "flex",
|
|
1706
|
+
gap: "8px",
|
|
1707
|
+
marginBottom: "10px",
|
|
1708
|
+
borderBottom: "1px solid #222",
|
|
1709
|
+
paddingBottom: "8px"
|
|
1710
|
+
}, children: [
|
|
1564
1711
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1565
1712
|
"button",
|
|
1566
1713
|
{
|
|
1567
|
-
onClick: () =>
|
|
1714
|
+
onClick: (e) => {
|
|
1715
|
+
e.stopPropagation();
|
|
1716
|
+
client.invalidate(entry.key);
|
|
1717
|
+
},
|
|
1568
1718
|
style: {
|
|
1569
|
-
background: "#
|
|
1570
|
-
border: "
|
|
1571
|
-
color: "#
|
|
1572
|
-
padding: "4px
|
|
1573
|
-
borderRadius: "
|
|
1719
|
+
background: "#222",
|
|
1720
|
+
border: "1px solid #333",
|
|
1721
|
+
color: "#d69e2e",
|
|
1722
|
+
padding: "4px 10px",
|
|
1723
|
+
borderRadius: "4px",
|
|
1574
1724
|
cursor: "pointer",
|
|
1575
|
-
fontSize: "
|
|
1725
|
+
fontSize: "11px"
|
|
1576
1726
|
},
|
|
1577
1727
|
children: "Invalidate"
|
|
1578
1728
|
}
|
|
@@ -1580,23 +1730,40 @@ function QuantumDevTools() {
|
|
|
1580
1730
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1581
1731
|
"button",
|
|
1582
1732
|
{
|
|
1583
|
-
onClick: () => {
|
|
1584
|
-
|
|
1733
|
+
onClick: (e) => {
|
|
1734
|
+
e.stopPropagation();
|
|
1735
|
+
client.remove(entry.key);
|
|
1585
1736
|
},
|
|
1586
1737
|
style: {
|
|
1587
|
-
background: "#
|
|
1588
|
-
border: "
|
|
1589
|
-
color: "#
|
|
1590
|
-
padding: "4px
|
|
1591
|
-
borderRadius: "
|
|
1738
|
+
background: "#222",
|
|
1739
|
+
border: "1px solid #333",
|
|
1740
|
+
color: "#ff4d4f",
|
|
1741
|
+
padding: "4px 10px",
|
|
1742
|
+
borderRadius: "4px",
|
|
1592
1743
|
cursor: "pointer",
|
|
1593
|
-
fontSize: "
|
|
1744
|
+
fontSize: "11px"
|
|
1594
1745
|
},
|
|
1595
|
-
children: "
|
|
1746
|
+
children: "Remove"
|
|
1596
1747
|
}
|
|
1597
1748
|
)
|
|
1749
|
+
] }),
|
|
1750
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { position: "relative" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("pre", { style: {
|
|
1751
|
+
margin: 0,
|
|
1752
|
+
fontSize: "11px",
|
|
1753
|
+
color: "#a0a0a0",
|
|
1754
|
+
overflowX: "auto",
|
|
1755
|
+
fontFamily: "monospace"
|
|
1756
|
+
}, children: JSON.stringify(entry.data, null, 2) }) }),
|
|
1757
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
|
|
1758
|
+
marginTop: "8px",
|
|
1759
|
+
fontSize: "10px",
|
|
1760
|
+
color: "#444",
|
|
1761
|
+
textAlign: "right"
|
|
1762
|
+
}, children: [
|
|
1763
|
+
"Updated: ",
|
|
1764
|
+
new Date(entry.updatedAt).toLocaleTimeString()
|
|
1598
1765
|
] })
|
|
1599
|
-
] }
|
|
1766
|
+
] })
|
|
1600
1767
|
] });
|
|
1601
1768
|
}
|
|
1602
1769
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/index.d.cts
CHANGED
|
@@ -183,6 +183,14 @@ declare class QueryCache {
|
|
|
183
183
|
* If a request for the same key is already in flight, returns the existing promise.
|
|
184
184
|
*/
|
|
185
185
|
fetch: <T>(queryKey: QueryKeyInput, fn: () => Promise<T>) => Promise<T>;
|
|
186
|
+
/**
|
|
187
|
+
* Invalidate all queries
|
|
188
|
+
*/
|
|
189
|
+
invalidateAll: () => void;
|
|
190
|
+
/**
|
|
191
|
+
* Remove a specific query from cache
|
|
192
|
+
*/
|
|
193
|
+
remove: (queryKey: QueryKeyInput) => void;
|
|
186
194
|
/**
|
|
187
195
|
* Invalidate queries matching the key prefix
|
|
188
196
|
* Marks them as undefined to trigger refetches without breaking subscriptions
|
package/dist/index.d.ts
CHANGED
|
@@ -183,6 +183,14 @@ declare class QueryCache {
|
|
|
183
183
|
* If a request for the same key is already in flight, returns the existing promise.
|
|
184
184
|
*/
|
|
185
185
|
fetch: <T>(queryKey: QueryKeyInput, fn: () => Promise<T>) => Promise<T>;
|
|
186
|
+
/**
|
|
187
|
+
* Invalidate all queries
|
|
188
|
+
*/
|
|
189
|
+
invalidateAll: () => void;
|
|
190
|
+
/**
|
|
191
|
+
* Remove a specific query from cache
|
|
192
|
+
*/
|
|
193
|
+
remove: (queryKey: QueryKeyInput) => void;
|
|
186
194
|
/**
|
|
187
195
|
* Invalidate queries matching the key prefix
|
|
188
196
|
* Marks them as undefined to trigger refetches without breaking subscriptions
|
package/dist/index.js
CHANGED
|
@@ -745,6 +745,21 @@ var QueryCache = class {
|
|
|
745
745
|
this.deduplicationCache.set(key, promise);
|
|
746
746
|
return promise;
|
|
747
747
|
};
|
|
748
|
+
/**
|
|
749
|
+
* Invalidate all queries
|
|
750
|
+
*/
|
|
751
|
+
invalidateAll = () => {
|
|
752
|
+
for (const key of this.signals.keys()) {
|
|
753
|
+
this.signals.get(key)?.set(void 0);
|
|
754
|
+
}
|
|
755
|
+
};
|
|
756
|
+
/**
|
|
757
|
+
* Remove a specific query from cache
|
|
758
|
+
*/
|
|
759
|
+
remove = (queryKey) => {
|
|
760
|
+
const key = this.generateKey(queryKey);
|
|
761
|
+
this.signals.delete(key);
|
|
762
|
+
};
|
|
748
763
|
/**
|
|
749
764
|
* Invalidate queries matching the key prefix
|
|
750
765
|
* Marks them as undefined to trigger refetches without breaking subscriptions
|
|
@@ -1391,7 +1406,7 @@ function useInfiniteQuery({
|
|
|
1391
1406
|
}
|
|
1392
1407
|
|
|
1393
1408
|
// src/addon/query/devtools.tsx
|
|
1394
|
-
import { useState as useState5 } from "react";
|
|
1409
|
+
import { useState as useState5, useMemo } from "react";
|
|
1395
1410
|
|
|
1396
1411
|
// src/addon/query/useQueryCache.ts
|
|
1397
1412
|
import { useState as useState4, useEffect as useEffect5 } from "react";
|
|
@@ -1400,7 +1415,7 @@ function useQueryCache() {
|
|
|
1400
1415
|
const [cache, setCache] = useState4(client.getAll());
|
|
1401
1416
|
useEffect5(() => {
|
|
1402
1417
|
const interval = setInterval(() => {
|
|
1403
|
-
setCache(
|
|
1418
|
+
setCache(new Map(client.getAll()));
|
|
1404
1419
|
}, 500);
|
|
1405
1420
|
return () => clearInterval(interval);
|
|
1406
1421
|
}, [client]);
|
|
@@ -1411,8 +1426,17 @@ function useQueryCache() {
|
|
|
1411
1426
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
1412
1427
|
function QuantumDevTools() {
|
|
1413
1428
|
const [isOpen, setIsOpen] = useState5(false);
|
|
1429
|
+
const [filter, setFilter] = useState5("");
|
|
1414
1430
|
const cache = useQueryCache();
|
|
1415
1431
|
const client = useQueryClient();
|
|
1432
|
+
const entries = useMemo(() => Array.from(cache.entries()), [cache]);
|
|
1433
|
+
const filteredEntries = useMemo(() => {
|
|
1434
|
+
if (!filter) return entries;
|
|
1435
|
+
const search = filter.toLowerCase();
|
|
1436
|
+
return entries.filter(
|
|
1437
|
+
([_, entry]) => entry.key.some((k) => String(k).toLowerCase().includes(search))
|
|
1438
|
+
);
|
|
1439
|
+
}, [entries, filter]);
|
|
1416
1440
|
if (!isOpen) {
|
|
1417
1441
|
return /* @__PURE__ */ jsx2(
|
|
1418
1442
|
"button",
|
|
@@ -1420,22 +1444,28 @@ function QuantumDevTools() {
|
|
|
1420
1444
|
onClick: () => setIsOpen(true),
|
|
1421
1445
|
style: {
|
|
1422
1446
|
position: "fixed",
|
|
1423
|
-
bottom: "
|
|
1424
|
-
right: "
|
|
1425
|
-
background: "#
|
|
1426
|
-
color: "#
|
|
1427
|
-
|
|
1447
|
+
bottom: "20px",
|
|
1448
|
+
right: "20px",
|
|
1449
|
+
background: "#111",
|
|
1450
|
+
color: "#b0fb5d",
|
|
1451
|
+
// Quantum Green
|
|
1452
|
+
border: "1px solid #333",
|
|
1428
1453
|
borderRadius: "50%",
|
|
1429
|
-
width: "
|
|
1430
|
-
height: "
|
|
1454
|
+
width: "48px",
|
|
1455
|
+
height: "48px",
|
|
1431
1456
|
cursor: "pointer",
|
|
1432
1457
|
zIndex: 9999,
|
|
1433
|
-
boxShadow: "0
|
|
1458
|
+
boxShadow: "0 8px 32px rgba(0, 0, 0, 0.4)",
|
|
1434
1459
|
fontSize: "20px",
|
|
1435
1460
|
display: "flex",
|
|
1436
1461
|
alignItems: "center",
|
|
1437
|
-
justifyContent: "center"
|
|
1462
|
+
justifyContent: "center",
|
|
1463
|
+
transition: "transform 0.2s",
|
|
1464
|
+
fontFamily: "monospace"
|
|
1438
1465
|
},
|
|
1466
|
+
onMouseEnter: (e) => e.currentTarget.style.transform = "scale(1.1)",
|
|
1467
|
+
onMouseLeave: (e) => e.currentTarget.style.transform = "scale(1)",
|
|
1468
|
+
title: "Open Quantum DevTools",
|
|
1439
1469
|
children: "\u26A1\uFE0F"
|
|
1440
1470
|
}
|
|
1441
1471
|
);
|
|
@@ -1445,27 +1475,39 @@ function QuantumDevTools() {
|
|
|
1445
1475
|
bottom: 0,
|
|
1446
1476
|
right: 0,
|
|
1447
1477
|
width: "100%",
|
|
1448
|
-
maxWidth: "
|
|
1449
|
-
height: "
|
|
1450
|
-
background: "#
|
|
1451
|
-
color: "#
|
|
1452
|
-
borderTopLeftRadius: "
|
|
1453
|
-
boxShadow: "0 -
|
|
1478
|
+
maxWidth: "650px",
|
|
1479
|
+
height: "450px",
|
|
1480
|
+
background: "#0a0a0a",
|
|
1481
|
+
color: "#e0e0e0",
|
|
1482
|
+
borderTopLeftRadius: "12px",
|
|
1483
|
+
boxShadow: "0 -10px 40px rgba(0,0,0,0.5)",
|
|
1454
1484
|
zIndex: 9999,
|
|
1455
1485
|
display: "flex",
|
|
1456
1486
|
flexDirection: "column",
|
|
1457
|
-
fontFamily: "monospace"
|
|
1487
|
+
fontFamily: "'JetBrains Mono', 'Fira Code', monospace",
|
|
1488
|
+
fontSize: "13px",
|
|
1489
|
+
border: "1px solid #333"
|
|
1458
1490
|
}, children: [
|
|
1459
1491
|
/* @__PURE__ */ jsxs("div", { style: {
|
|
1460
|
-
padding: "
|
|
1461
|
-
borderBottom: "1px solid #
|
|
1492
|
+
padding: "12px 16px",
|
|
1493
|
+
borderBottom: "1px solid #222",
|
|
1462
1494
|
display: "flex",
|
|
1463
1495
|
justifyContent: "space-between",
|
|
1464
1496
|
alignItems: "center",
|
|
1465
|
-
background: "#
|
|
1466
|
-
borderTopLeftRadius: "
|
|
1497
|
+
background: "#111",
|
|
1498
|
+
borderTopLeftRadius: "12px"
|
|
1467
1499
|
}, children: [
|
|
1468
|
-
/* @__PURE__ */
|
|
1500
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
|
|
1501
|
+
/* @__PURE__ */ jsx2("span", { style: { color: "#b0fb5d", fontSize: "16px" }, children: "\u26A1\uFE0F" }),
|
|
1502
|
+
/* @__PURE__ */ jsx2("span", { style: { fontWeight: 600, letterSpacing: "-0.5px" }, children: "Quantum DevTools" }),
|
|
1503
|
+
/* @__PURE__ */ jsx2("span", { style: {
|
|
1504
|
+
background: "#222",
|
|
1505
|
+
padding: "2px 6px",
|
|
1506
|
+
borderRadius: "4px",
|
|
1507
|
+
fontSize: "10px",
|
|
1508
|
+
color: "#666"
|
|
1509
|
+
}, children: "v1.2.2" })
|
|
1510
|
+
] }),
|
|
1469
1511
|
/* @__PURE__ */ jsx2(
|
|
1470
1512
|
"button",
|
|
1471
1513
|
{
|
|
@@ -1473,58 +1515,166 @@ function QuantumDevTools() {
|
|
|
1473
1515
|
style: {
|
|
1474
1516
|
background: "transparent",
|
|
1475
1517
|
border: "none",
|
|
1476
|
-
color: "#
|
|
1518
|
+
color: "#666",
|
|
1519
|
+
cursor: "pointer",
|
|
1520
|
+
fontSize: "20px",
|
|
1521
|
+
padding: "4px",
|
|
1522
|
+
lineHeight: 1
|
|
1523
|
+
},
|
|
1524
|
+
children: "\xD7"
|
|
1525
|
+
}
|
|
1526
|
+
)
|
|
1527
|
+
] }),
|
|
1528
|
+
/* @__PURE__ */ jsxs("div", { style: {
|
|
1529
|
+
padding: "8px 16px",
|
|
1530
|
+
borderBottom: "1px solid #222",
|
|
1531
|
+
background: "#0f0f0f",
|
|
1532
|
+
display: "flex",
|
|
1533
|
+
gap: "12px"
|
|
1534
|
+
}, children: [
|
|
1535
|
+
/* @__PURE__ */ jsx2(
|
|
1536
|
+
"input",
|
|
1537
|
+
{
|
|
1538
|
+
type: "text",
|
|
1539
|
+
placeholder: "Filter queries...",
|
|
1540
|
+
value: filter,
|
|
1541
|
+
onChange: (e) => setFilter(e.target.value),
|
|
1542
|
+
style: {
|
|
1543
|
+
background: "#1a1a1a",
|
|
1544
|
+
border: "1px solid #333",
|
|
1545
|
+
color: "#fff",
|
|
1546
|
+
padding: "6px 10px",
|
|
1547
|
+
borderRadius: "4px",
|
|
1548
|
+
flex: 1,
|
|
1549
|
+
fontSize: "12px",
|
|
1550
|
+
outline: "none"
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
),
|
|
1554
|
+
/* @__PURE__ */ jsx2(
|
|
1555
|
+
"button",
|
|
1556
|
+
{
|
|
1557
|
+
onClick: () => client.invalidateAll(),
|
|
1558
|
+
title: "Invalidate All Queries",
|
|
1559
|
+
style: {
|
|
1560
|
+
background: "#222",
|
|
1561
|
+
border: "1px solid #333",
|
|
1562
|
+
color: "#d69e2e",
|
|
1563
|
+
borderRadius: "4px",
|
|
1564
|
+
padding: "0 12px",
|
|
1477
1565
|
cursor: "pointer",
|
|
1478
|
-
fontSize: "
|
|
1566
|
+
fontSize: "12px",
|
|
1567
|
+
fontWeight: 500
|
|
1479
1568
|
},
|
|
1480
|
-
children: "\
|
|
1569
|
+
children: "\u21BB Invalidate All"
|
|
1481
1570
|
}
|
|
1482
1571
|
)
|
|
1483
1572
|
] }),
|
|
1484
1573
|
/* @__PURE__ */ jsx2("div", { style: {
|
|
1485
1574
|
flex: 1,
|
|
1486
1575
|
overflowY: "auto",
|
|
1487
|
-
padding: "
|
|
1576
|
+
padding: "8px",
|
|
1488
1577
|
display: "flex",
|
|
1489
1578
|
flexDirection: "column",
|
|
1490
|
-
gap: "8px"
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1579
|
+
gap: "8px",
|
|
1580
|
+
background: "#050505"
|
|
1581
|
+
}, children: entries.length === 0 ? /* @__PURE__ */ jsx2("div", { style: {
|
|
1582
|
+
padding: "40px",
|
|
1583
|
+
textAlign: "center",
|
|
1584
|
+
color: "#444",
|
|
1585
|
+
fontStyle: "italic"
|
|
1586
|
+
}, children: "No active queries in cache." }) : filteredEntries.map(([keyHash, entry]) => /* @__PURE__ */ jsx2(
|
|
1587
|
+
QueryItem,
|
|
1588
|
+
{
|
|
1589
|
+
entry,
|
|
1590
|
+
client,
|
|
1591
|
+
isStale: client.isStale(entry.key)
|
|
1592
|
+
},
|
|
1593
|
+
keyHash
|
|
1594
|
+
)) })
|
|
1595
|
+
] });
|
|
1596
|
+
}
|
|
1597
|
+
function QueryItem({ entry, client, isStale }) {
|
|
1598
|
+
const [expanded, setExpanded] = useState5(false);
|
|
1599
|
+
return /* @__PURE__ */ jsxs("div", { style: {
|
|
1600
|
+
background: "#111",
|
|
1601
|
+
borderRadius: "6px",
|
|
1602
|
+
border: "1px solid #222",
|
|
1603
|
+
overflow: "hidden"
|
|
1604
|
+
}, children: [
|
|
1605
|
+
/* @__PURE__ */ jsxs(
|
|
1606
|
+
"div",
|
|
1607
|
+
{
|
|
1608
|
+
onClick: () => setExpanded(!expanded),
|
|
1609
|
+
style: {
|
|
1610
|
+
padding: "8px 12px",
|
|
1611
|
+
display: "flex",
|
|
1612
|
+
alignItems: "center",
|
|
1613
|
+
justifyContent: "space-between",
|
|
1614
|
+
cursor: "pointer",
|
|
1615
|
+
background: expanded ? "#161616" : "transparent"
|
|
1616
|
+
},
|
|
1617
|
+
children: [
|
|
1618
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "10px", alignItems: "center", overflow: "hidden" }, children: [
|
|
1619
|
+
/* @__PURE__ */ jsx2("span", { style: {
|
|
1620
|
+
color: isStale ? "#d69e2e" : "#b0fb5d",
|
|
1621
|
+
fontSize: "14px",
|
|
1622
|
+
fontWeight: "bold",
|
|
1623
|
+
minWidth: "10px"
|
|
1624
|
+
}, children: isStale ? "\u2022" : "\u2022" }),
|
|
1625
|
+
/* @__PURE__ */ jsxs("span", { style: {
|
|
1626
|
+
color: "#e0e0e0",
|
|
1627
|
+
fontWeight: 500,
|
|
1628
|
+
whiteSpace: "nowrap",
|
|
1629
|
+
overflow: "hidden",
|
|
1630
|
+
textOverflow: "ellipsis"
|
|
1631
|
+
}, children: [
|
|
1632
|
+
"['",
|
|
1633
|
+
entry.key.join("', '"),
|
|
1634
|
+
"']"
|
|
1635
|
+
] })
|
|
1636
|
+
] }),
|
|
1637
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "8px", alignItems: "center" }, children: [
|
|
1638
|
+
/* @__PURE__ */ jsx2("span", { style: {
|
|
1639
|
+
fontSize: "10px",
|
|
1640
|
+
padding: "2px 6px",
|
|
1641
|
+
borderRadius: "3px",
|
|
1642
|
+
background: isStale ? "rgba(214, 158, 46, 0.15)" : "rgba(176, 251, 93, 0.15)",
|
|
1643
|
+
color: isStale ? "#d69e2e" : "#b0fb5d",
|
|
1644
|
+
border: `1px solid ${isStale ? "rgba(214, 158, 46, 0.3)" : "rgba(176, 251, 93, 0.3)"}`
|
|
1645
|
+
}, children: isStale ? "STALE" : "FRESH" }),
|
|
1646
|
+
/* @__PURE__ */ jsx2("span", { style: { color: "#666", fontSize: "10px" }, children: expanded ? "\u25BC" : "\u25B6" })
|
|
1647
|
+
] })
|
|
1648
|
+
]
|
|
1649
|
+
}
|
|
1650
|
+
),
|
|
1651
|
+
expanded && /* @__PURE__ */ jsxs("div", { style: {
|
|
1652
|
+
padding: "10px",
|
|
1653
|
+
borderTop: "1px solid #222",
|
|
1654
|
+
background: "#0a0a0a"
|
|
1496
1655
|
}, children: [
|
|
1497
|
-
/* @__PURE__ */ jsxs("div", { style: {
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
color: "#000"
|
|
1505
|
-
}, children: client.isStale(entry.key) ? "STALE" : "FRESH" }) })
|
|
1506
|
-
] }),
|
|
1507
|
-
/* @__PURE__ */ jsx2("div", { style: {
|
|
1508
|
-
fontSize: "11px",
|
|
1509
|
-
color: "#ddd",
|
|
1510
|
-
whiteSpace: "pre-wrap",
|
|
1511
|
-
maxHeight: "100px",
|
|
1512
|
-
overflow: "hidden",
|
|
1513
|
-
opacity: 0.8
|
|
1514
|
-
}, children: JSON.stringify(entry.data, null, 2) }),
|
|
1515
|
-
/* @__PURE__ */ jsxs("div", { style: { marginTop: "8px", display: "flex", gap: "8px" }, children: [
|
|
1656
|
+
/* @__PURE__ */ jsxs("div", { style: {
|
|
1657
|
+
display: "flex",
|
|
1658
|
+
gap: "8px",
|
|
1659
|
+
marginBottom: "10px",
|
|
1660
|
+
borderBottom: "1px solid #222",
|
|
1661
|
+
paddingBottom: "8px"
|
|
1662
|
+
}, children: [
|
|
1516
1663
|
/* @__PURE__ */ jsx2(
|
|
1517
1664
|
"button",
|
|
1518
1665
|
{
|
|
1519
|
-
onClick: () =>
|
|
1666
|
+
onClick: (e) => {
|
|
1667
|
+
e.stopPropagation();
|
|
1668
|
+
client.invalidate(entry.key);
|
|
1669
|
+
},
|
|
1520
1670
|
style: {
|
|
1521
|
-
background: "#
|
|
1522
|
-
border: "
|
|
1523
|
-
color: "#
|
|
1524
|
-
padding: "4px
|
|
1525
|
-
borderRadius: "
|
|
1671
|
+
background: "#222",
|
|
1672
|
+
border: "1px solid #333",
|
|
1673
|
+
color: "#d69e2e",
|
|
1674
|
+
padding: "4px 10px",
|
|
1675
|
+
borderRadius: "4px",
|
|
1526
1676
|
cursor: "pointer",
|
|
1527
|
-
fontSize: "
|
|
1677
|
+
fontSize: "11px"
|
|
1528
1678
|
},
|
|
1529
1679
|
children: "Invalidate"
|
|
1530
1680
|
}
|
|
@@ -1532,23 +1682,40 @@ function QuantumDevTools() {
|
|
|
1532
1682
|
/* @__PURE__ */ jsx2(
|
|
1533
1683
|
"button",
|
|
1534
1684
|
{
|
|
1535
|
-
onClick: () => {
|
|
1536
|
-
|
|
1685
|
+
onClick: (e) => {
|
|
1686
|
+
e.stopPropagation();
|
|
1687
|
+
client.remove(entry.key);
|
|
1537
1688
|
},
|
|
1538
1689
|
style: {
|
|
1539
|
-
background: "#
|
|
1540
|
-
border: "
|
|
1541
|
-
color: "#
|
|
1542
|
-
padding: "4px
|
|
1543
|
-
borderRadius: "
|
|
1690
|
+
background: "#222",
|
|
1691
|
+
border: "1px solid #333",
|
|
1692
|
+
color: "#ff4d4f",
|
|
1693
|
+
padding: "4px 10px",
|
|
1694
|
+
borderRadius: "4px",
|
|
1544
1695
|
cursor: "pointer",
|
|
1545
|
-
fontSize: "
|
|
1696
|
+
fontSize: "11px"
|
|
1546
1697
|
},
|
|
1547
|
-
children: "
|
|
1698
|
+
children: "Remove"
|
|
1548
1699
|
}
|
|
1549
1700
|
)
|
|
1701
|
+
] }),
|
|
1702
|
+
/* @__PURE__ */ jsx2("div", { style: { position: "relative" }, children: /* @__PURE__ */ jsx2("pre", { style: {
|
|
1703
|
+
margin: 0,
|
|
1704
|
+
fontSize: "11px",
|
|
1705
|
+
color: "#a0a0a0",
|
|
1706
|
+
overflowX: "auto",
|
|
1707
|
+
fontFamily: "monospace"
|
|
1708
|
+
}, children: JSON.stringify(entry.data, null, 2) }) }),
|
|
1709
|
+
/* @__PURE__ */ jsxs("div", { style: {
|
|
1710
|
+
marginTop: "8px",
|
|
1711
|
+
fontSize: "10px",
|
|
1712
|
+
color: "#444",
|
|
1713
|
+
textAlign: "right"
|
|
1714
|
+
}, children: [
|
|
1715
|
+
"Updated: ",
|
|
1716
|
+
new Date(entry.updatedAt).toLocaleTimeString()
|
|
1550
1717
|
] })
|
|
1551
|
-
] }
|
|
1718
|
+
] })
|
|
1552
1719
|
] });
|
|
1553
1720
|
}
|
|
1554
1721
|
export {
|