next-cache-toolbar 0.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/LICENSE.md +21 -0
- package/dist/cjs/cache-entry-client-BvxljHoj.js +145 -0
- package/dist/cjs/cache-panel-context-client-B1EgwMzI.js +33 -0
- package/dist/cjs/cache-panel-head-client-DU8vr6PU.js +46 -0
- package/dist/cjs/cache-panel-table-client-DTc9oH8H.js +56 -0
- package/dist/cjs/cache-panel-trigger-client-I91XFsXW.js +76 -0
- package/dist/cjs/cache-panel-wrapper-client-CN5_PBpp.js +20 -0
- package/dist/cjs/index.d.ts +5 -0
- package/dist/cjs/index.js +115 -0
- package/dist/cjs/refresh-data-button-client-B9jg9KlD.js +29 -0
- package/dist/es/cache-entry-client-UcY_Onfg.js +120 -0
- package/dist/es/cache-panel-context-client-D5NKXXpF.js +28 -0
- package/dist/es/cache-panel-head-client-DCJPailN.js +46 -0
- package/dist/es/cache-panel-table-client-DUbKWZdy.js +56 -0
- package/dist/es/cache-panel-trigger-client-D3ag_ezj.js +55 -0
- package/dist/es/cache-panel-wrapper-client-BFFOMRXO.js +20 -0
- package/dist/es/index.d.mts +5 -0
- package/dist/es/index.mjs +113 -0
- package/dist/es/refresh-data-button-client-Bh7PpxMP.js +29 -0
- package/dist/style.css +1 -0
- package/package.json +78 -0
- package/readme.md +28 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2022 Paco Coursey
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
3
|
+
var React = require('react');
|
|
4
|
+
var classVarianceAuthority = require('class-variance-authority');
|
|
5
|
+
var clsx = require('clsx');
|
|
6
|
+
var tailwindMerge = require('tailwind-merge');
|
|
7
|
+
|
|
8
|
+
function _interopNamespace(e) {
|
|
9
|
+
if (e && e.__esModule) return e;
|
|
10
|
+
var n = Object.create(null);
|
|
11
|
+
if (e) {
|
|
12
|
+
Object.keys(e).forEach(function (k) {
|
|
13
|
+
if (k !== 'default') {
|
|
14
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
15
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
16
|
+
enumerable: true,
|
|
17
|
+
get: function () { return e[k]; }
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
n.default = e;
|
|
23
|
+
return n;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
27
|
+
|
|
28
|
+
function cn(...inputs) {
|
|
29
|
+
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const Table = /*#__PURE__*/ React__namespace.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsxRuntime.jsx("table", {
|
|
33
|
+
ref: ref,
|
|
34
|
+
className: cn("nct-w-full nct-caption-bottom nct-text-sm", className),
|
|
35
|
+
...props
|
|
36
|
+
}));
|
|
37
|
+
Table.displayName = "Table";
|
|
38
|
+
const TableHeader = /*#__PURE__*/ React__namespace.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsxRuntime.jsx("thead", {
|
|
39
|
+
ref: ref,
|
|
40
|
+
className: cn("[&_tr]:nct-border-b", className),
|
|
41
|
+
...props
|
|
42
|
+
}));
|
|
43
|
+
TableHeader.displayName = "TableHeader";
|
|
44
|
+
const TableBody = /*#__PURE__*/ React__namespace.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsxRuntime.jsx("tbody", {
|
|
45
|
+
ref: ref,
|
|
46
|
+
className: cn("[&_tr:last-child]:nct-border-0", className),
|
|
47
|
+
...props
|
|
48
|
+
}));
|
|
49
|
+
TableBody.displayName = "TableBody";
|
|
50
|
+
const TableFooter = /*#__PURE__*/ React__namespace.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsxRuntime.jsx("tfoot", {
|
|
51
|
+
ref: ref,
|
|
52
|
+
className: cn("nct-border-t nct-bg-muted/50 nct-font-medium [&>tr]:last:nct-border-b-0", className),
|
|
53
|
+
...props
|
|
54
|
+
}));
|
|
55
|
+
TableFooter.displayName = "TableFooter";
|
|
56
|
+
const TableRow = /*#__PURE__*/ React__namespace.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsxRuntime.jsx("tr", {
|
|
57
|
+
ref: ref,
|
|
58
|
+
className: cn("nct-border-b nct-transition-colors hover:nct-bg-muted/50 data-[state=selected]:nct-bg-muted", className),
|
|
59
|
+
...props
|
|
60
|
+
}));
|
|
61
|
+
TableRow.displayName = "TableRow";
|
|
62
|
+
const TableHead = /*#__PURE__*/ React__namespace.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsxRuntime.jsx("th", {
|
|
63
|
+
ref: ref,
|
|
64
|
+
className: cn("nct-h-12 nct-px-4 nct-text-left nct-align-middle nct-font-medium nct-text-muted-foreground [&:has([role=checkbox])]:nct-pr-0", className),
|
|
65
|
+
...props
|
|
66
|
+
}));
|
|
67
|
+
TableHead.displayName = "TableHead";
|
|
68
|
+
const TableCell = /*#__PURE__*/ React__namespace.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsxRuntime.jsx("td", {
|
|
69
|
+
ref: ref,
|
|
70
|
+
className: cn("nct-p-4 nct-align-middle [&:has([role=checkbox])]:nct-pr-0", className),
|
|
71
|
+
...props
|
|
72
|
+
}));
|
|
73
|
+
TableCell.displayName = "TableCell";
|
|
74
|
+
const TableCaption = /*#__PURE__*/ React__namespace.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsxRuntime.jsx("caption", {
|
|
75
|
+
ref: ref,
|
|
76
|
+
className: cn("nct-mt-4 nct-text-sm nct-text-muted-foreground", className),
|
|
77
|
+
...props
|
|
78
|
+
}));
|
|
79
|
+
TableCaption.displayName = "TableCaption";
|
|
80
|
+
|
|
81
|
+
const badgeVariants = classVarianceAuthority.cva("nct-inline-flex nct-items-center nct-rounded-full nct-border nct-px-2.5 nct-py-0.5 nct-text-xs nct-font-semibold nct-transition-colors focus:nct-outline-none focus:nct-ring-2 focus:nct-ring-ring focus:nct-ring-offset-2", {
|
|
82
|
+
variants: {
|
|
83
|
+
variant: {
|
|
84
|
+
default: "nct-border-transparent nct-bg-primary nct-text-primary-foreground hover:nct-bg-primary/80",
|
|
85
|
+
secondary: "nct-border-transparent nct-bg-secondary nct-text-secondary-foreground hover:nct-bg-secondary/80",
|
|
86
|
+
destructive: "nct-border-transparent nct-bg-destructive nct-text-destructive-foreground hover:nct-bg-destructive/80",
|
|
87
|
+
outline: "nct-text-foreground"
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
defaultVariants: {
|
|
91
|
+
variant: "default"
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
function Badge({ className, variant, ...props }) {
|
|
95
|
+
return /*#__PURE__*/ jsxRuntime.jsx("div", {
|
|
96
|
+
className: cn(badgeVariants({
|
|
97
|
+
variant
|
|
98
|
+
}), className),
|
|
99
|
+
...props
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const CacheEntry = (props)=>{
|
|
104
|
+
const cacheEntryRevalidateLeft = React.useMemo(()=>{
|
|
105
|
+
if (!props.cacheEntry.data?.headers.date || !props.cacheEntry.revalidate) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const cacheEntryDate = new Date(props.cacheEntry.data?.headers.date);
|
|
109
|
+
const msDiff = new Date().getTime() - cacheEntryDate.getTime();
|
|
110
|
+
return Math.floor(props.cacheEntry.revalidate - msDiff / 1000);
|
|
111
|
+
}, [
|
|
112
|
+
props.cacheEntry.data?.headers.date,
|
|
113
|
+
props.cacheEntry.revalidate
|
|
114
|
+
]);
|
|
115
|
+
const isStale = cacheEntryRevalidateLeft ? cacheEntryRevalidateLeft < 0 : false;
|
|
116
|
+
return /*#__PURE__*/ jsxRuntime.jsxs(TableRow, {
|
|
117
|
+
children: [
|
|
118
|
+
/*#__PURE__*/ jsxRuntime.jsx(TableCell, {
|
|
119
|
+
className: "nct-truncate nct-max-w-[25vw]",
|
|
120
|
+
children: props.cacheEntry.data?.url
|
|
121
|
+
}),
|
|
122
|
+
/*#__PURE__*/ jsxRuntime.jsx(TableCell, {
|
|
123
|
+
title: cacheEntryRevalidateLeft?.toString() ?? "-",
|
|
124
|
+
children: isStale ? /*#__PURE__*/ jsxRuntime.jsx(Badge, {
|
|
125
|
+
children: "STALE"
|
|
126
|
+
}) : props.cacheEntry.revalidate ?? "-"
|
|
127
|
+
}),
|
|
128
|
+
/*#__PURE__*/ jsxRuntime.jsx(TableCell, {
|
|
129
|
+
className: "nct-break-before-all",
|
|
130
|
+
children: props.cacheEntry.tags.join("\n")
|
|
131
|
+
}),
|
|
132
|
+
/*#__PURE__*/ jsxRuntime.jsx(TableCell, {
|
|
133
|
+
children: props.cacheEntry.data?.headers.date
|
|
134
|
+
})
|
|
135
|
+
]
|
|
136
|
+
});
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
exports.CacheEntry = CacheEntry;
|
|
140
|
+
exports.Table = Table;
|
|
141
|
+
exports.TableBody = TableBody;
|
|
142
|
+
exports.TableHead = TableHead;
|
|
143
|
+
exports.TableHeader = TableHeader;
|
|
144
|
+
exports.TableRow = TableRow;
|
|
145
|
+
exports.cn = cn;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
3
|
+
var React = require('react');
|
|
4
|
+
|
|
5
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
6
|
+
|
|
7
|
+
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
8
|
+
|
|
9
|
+
const CachePanelContext = /*#__PURE__*/ React.createContext({
|
|
10
|
+
isOpen: false,
|
|
11
|
+
toggleOpen: ()=>{},
|
|
12
|
+
setSorting: ()=>{}
|
|
13
|
+
});
|
|
14
|
+
const useCachePanelContext = ()=>React__default.default.useContext(CachePanelContext);
|
|
15
|
+
const CachePanelContextProvider = ({ children })=>{
|
|
16
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
17
|
+
const [sorting, setSorting] = React.useState(undefined);
|
|
18
|
+
const toggleOpen = ()=>{
|
|
19
|
+
setIsOpen(!isOpen);
|
|
20
|
+
};
|
|
21
|
+
return /*#__PURE__*/ jsxRuntime.jsx(CachePanelContext.Provider, {
|
|
22
|
+
value: {
|
|
23
|
+
isOpen,
|
|
24
|
+
toggleOpen,
|
|
25
|
+
setSorting,
|
|
26
|
+
sorting
|
|
27
|
+
},
|
|
28
|
+
children: children
|
|
29
|
+
});
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
exports.CachePanelContextProvider = CachePanelContextProvider;
|
|
33
|
+
exports.useCachePanelContext = useCachePanelContext;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
3
|
+
var cacheEntryClient = require('./cache-entry-client-BvxljHoj.js');
|
|
4
|
+
var lucideReact = require('lucide-react');
|
|
5
|
+
var React = require('react');
|
|
6
|
+
var cachePanelContextClient = require('./cache-panel-context-client-B1EgwMzI.js');
|
|
7
|
+
|
|
8
|
+
const CachePanelHead = ({ sortingProperty, children, ...props })=>{
|
|
9
|
+
const { setSorting, sorting } = cachePanelContextClient.useCachePanelContext();
|
|
10
|
+
const sortingDirection = React.useMemo(()=>{
|
|
11
|
+
if (!sorting || sorting.key !== sortingProperty) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
return sorting.direction;
|
|
15
|
+
}, [
|
|
16
|
+
sorting,
|
|
17
|
+
sortingProperty
|
|
18
|
+
]);
|
|
19
|
+
const onHeadClick = ()=>{
|
|
20
|
+
if (sorting && sorting.key === sortingProperty) {
|
|
21
|
+
setSorting({
|
|
22
|
+
key: sortingProperty,
|
|
23
|
+
direction: sorting.direction === "asc" ? "desc" : "asc"
|
|
24
|
+
});
|
|
25
|
+
} else {
|
|
26
|
+
setSorting({
|
|
27
|
+
key: sortingProperty,
|
|
28
|
+
direction: "asc"
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
return /*#__PURE__*/ jsxRuntime.jsx(cacheEntryClient.TableHead, {
|
|
33
|
+
onClick: onHeadClick,
|
|
34
|
+
...props,
|
|
35
|
+
children: /*#__PURE__*/ jsxRuntime.jsxs("div", {
|
|
36
|
+
className: cacheEntryClient.cn("nct-flex nct-items-center nct-gap-2", sorting?.key === sortingProperty && "nct-underline"),
|
|
37
|
+
children: [
|
|
38
|
+
children,
|
|
39
|
+
sortingDirection === "asc" && /*#__PURE__*/ jsxRuntime.jsx(lucideReact.ArrowDownAZIcon, {}),
|
|
40
|
+
sortingDirection === "desc" && /*#__PURE__*/ jsxRuntime.jsx(lucideReact.ArrowUpAZIcon, {})
|
|
41
|
+
]
|
|
42
|
+
})
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
exports.CachePanelHead = CachePanelHead;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
3
|
+
var cacheEntryClient = require('./cache-entry-client-BvxljHoj.js');
|
|
4
|
+
var React = require('react');
|
|
5
|
+
var cachePanelContextClient = require('./cache-panel-context-client-B1EgwMzI.js');
|
|
6
|
+
|
|
7
|
+
const sortCacheEntryByKey = (key, a, b)=>{
|
|
8
|
+
switch(key){
|
|
9
|
+
case "url":
|
|
10
|
+
if (!a.data || !b.data) {
|
|
11
|
+
return 0;
|
|
12
|
+
}
|
|
13
|
+
return a.data.url.localeCompare(b.data.url);
|
|
14
|
+
case "revalidate":
|
|
15
|
+
return (a.revalidate ?? 0) - (b.revalidate ?? 0);
|
|
16
|
+
case "tags":
|
|
17
|
+
if (a.tags.length === 0 || b.tags.length === 0) {
|
|
18
|
+
return 0;
|
|
19
|
+
}
|
|
20
|
+
return a.tags[0]?.localeCompare(b.tags[0] ?? "") ?? 0;
|
|
21
|
+
case "timestamp":
|
|
22
|
+
{
|
|
23
|
+
if (!a.data?.headers.date || !b.data?.headers.date) {
|
|
24
|
+
return 0;
|
|
25
|
+
}
|
|
26
|
+
return new Date(b.data.headers.date).getTime() - new Date(a.data.headers.date).getTime();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
const CachePanelTable = ({ entries })=>{
|
|
31
|
+
const { sorting } = cachePanelContextClient.useCachePanelContext();
|
|
32
|
+
const sortedEntries = React.useMemo(()=>{
|
|
33
|
+
if (!sorting) {
|
|
34
|
+
return entries;
|
|
35
|
+
}
|
|
36
|
+
const { key, direction } = sorting;
|
|
37
|
+
return entries.toSorted((a, b)=>{
|
|
38
|
+
return sortCacheEntryByKey(key, a[1], b[1]) * (direction === "asc" ? 1 : -1);
|
|
39
|
+
});
|
|
40
|
+
}, [
|
|
41
|
+
entries,
|
|
42
|
+
sorting
|
|
43
|
+
]);
|
|
44
|
+
return /*#__PURE__*/ jsxRuntime.jsxs(cacheEntryClient.TableBody, {
|
|
45
|
+
children: [
|
|
46
|
+
sortedEntries.length === 0 && /*#__PURE__*/ jsxRuntime.jsx("div", {
|
|
47
|
+
children: "No cache entries"
|
|
48
|
+
}),
|
|
49
|
+
sortedEntries.map(([file, cacheEntry])=>/*#__PURE__*/ jsxRuntime.jsx(cacheEntryClient.CacheEntry, {
|
|
50
|
+
cacheEntry: cacheEntry
|
|
51
|
+
}, file))
|
|
52
|
+
]
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
exports.CachePanelTable = CachePanelTable;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
3
|
+
var React = require('react');
|
|
4
|
+
var reactSlot = require('@radix-ui/react-slot');
|
|
5
|
+
var classVarianceAuthority = require('class-variance-authority');
|
|
6
|
+
var cacheEntryClient = require('./cache-entry-client-BvxljHoj.js');
|
|
7
|
+
var cachePanelContextClient = require('./cache-panel-context-client-B1EgwMzI.js');
|
|
8
|
+
|
|
9
|
+
function _interopNamespace(e) {
|
|
10
|
+
if (e && e.__esModule) return e;
|
|
11
|
+
var n = Object.create(null);
|
|
12
|
+
if (e) {
|
|
13
|
+
Object.keys(e).forEach(function (k) {
|
|
14
|
+
if (k !== 'default') {
|
|
15
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
16
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: function () { return e[k]; }
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
n.default = e;
|
|
24
|
+
return n;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
28
|
+
|
|
29
|
+
const buttonVariants = classVarianceAuthority.cva("nct-inline-flex nct-items-center nct-justify-center nct-whitespace-nowrap nct-rounded-md nct-text-sm nct-font-medium nct-ring-offset-background nct-transition-colors focus-visible:nct-outline-none focus-visible:nct-ring-2 focus-visible:nct-ring-ring focus-visible:nct-ring-offset-2 disabled:nct-pointer-events-none disabled:nct-opacity-50", {
|
|
30
|
+
variants: {
|
|
31
|
+
variant: {
|
|
32
|
+
default: "nct-bg-primary nct-text-primary-foreground hover:nct-bg-primary/90",
|
|
33
|
+
destructive: "nct-bg-destructive nct-text-destructive-foreground hover:nct-bg-destructive/90",
|
|
34
|
+
outline: "nct-border nct-border-input nct-bg-background hover:nct-bg-accent hover:nct-text-accent-foreground",
|
|
35
|
+
secondary: "nct-bg-secondary nct-text-secondary-foreground hover:nct-bg-secondary/80",
|
|
36
|
+
ghost: "hover:nct-bg-accent hover:nct-text-accent-foreground",
|
|
37
|
+
link: "nct-text-primary nct-underline-offset-4 hover:nct-underline"
|
|
38
|
+
},
|
|
39
|
+
size: {
|
|
40
|
+
default: "nct-h-10 nct-px-4 nct-py-2",
|
|
41
|
+
sm: "nct-h-9 nct-rounded-md nct-px-3",
|
|
42
|
+
lg: "nct-h-11 nct-rounded-md nct-px-8",
|
|
43
|
+
icon: "nct-h-10 nct-w-10"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
defaultVariants: {
|
|
47
|
+
variant: "default",
|
|
48
|
+
size: "default"
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
const Button = /*#__PURE__*/ React__namespace.forwardRef(({ className, variant, size, asChild = false, ...props }, ref)=>{
|
|
52
|
+
const Comp = asChild ? reactSlot.Slot : "button";
|
|
53
|
+
return /*#__PURE__*/ jsxRuntime.jsx(Comp, {
|
|
54
|
+
className: cacheEntryClient.cn(buttonVariants({
|
|
55
|
+
variant,
|
|
56
|
+
size,
|
|
57
|
+
className
|
|
58
|
+
})),
|
|
59
|
+
ref: ref,
|
|
60
|
+
...props
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
Button.displayName = "Button";
|
|
64
|
+
|
|
65
|
+
function CachePanelTrigger(props) {
|
|
66
|
+
const { toggleOpen } = cachePanelContextClient.useCachePanelContext();
|
|
67
|
+
return /*#__PURE__*/ jsxRuntime.jsx(Button, {
|
|
68
|
+
variant: "ghost",
|
|
69
|
+
size: "icon",
|
|
70
|
+
onClick: toggleOpen,
|
|
71
|
+
...props
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
exports.Button = Button;
|
|
76
|
+
exports.CachePanelTrigger = CachePanelTrigger;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
3
|
+
var cacheEntryClient = require('./cache-entry-client-BvxljHoj.js');
|
|
4
|
+
require('react');
|
|
5
|
+
var cachePanelContextClient = require('./cache-panel-context-client-B1EgwMzI.js');
|
|
6
|
+
|
|
7
|
+
const CacheTable = (props)=>{
|
|
8
|
+
const { isOpen } = cachePanelContextClient.useCachePanelContext();
|
|
9
|
+
if (!isOpen) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
return /*#__PURE__*/ jsxRuntime.jsx("div", {
|
|
13
|
+
className: "nct-fixed nct-bottom-0 nct-inset-x-0 nct-z-50 nct-bg-background nct-overflow-x-auto nct-max-h-[35vh]",
|
|
14
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(cacheEntryClient.Table, {
|
|
15
|
+
children: props.children
|
|
16
|
+
})
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
exports.CacheTable = CacheTable;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
'use server';
|
|
2
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
3
|
+
|
|
4
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
|
+
var cacheEntryClient = require('./cache-entry-client-BvxljHoj.js');
|
|
6
|
+
var lucideReact = require('lucide-react');
|
|
7
|
+
var fs = require('fs');
|
|
8
|
+
var promises = require('node:fs/promises');
|
|
9
|
+
var zod = require('zod');
|
|
10
|
+
var cachePanelContextClient = require('./cache-panel-context-client-B1EgwMzI.js');
|
|
11
|
+
var cachePanelHeadClient = require('./cache-panel-head-client-DU8vr6PU.js');
|
|
12
|
+
var cachePanelTableClient = require('./cache-panel-table-client-DTc9oH8H.js');
|
|
13
|
+
var cachePanelTriggerClient = require('./cache-panel-trigger-client-I91XFsXW.js');
|
|
14
|
+
var cachePanelWrapperClient = require('./cache-panel-wrapper-client-CN5_PBpp.js');
|
|
15
|
+
var refreshDataButtonClient = require('./refresh-data-button-client-B9jg9KlD.js');
|
|
16
|
+
|
|
17
|
+
const nextCacheFileSchema = zod.z.object({
|
|
18
|
+
data: zod.z.object({
|
|
19
|
+
body: zod.z.string(),
|
|
20
|
+
headers: zod.z.record(zod.z.string(), zod.z.string()),
|
|
21
|
+
status: zod.z.number(),
|
|
22
|
+
url: zod.z.string()
|
|
23
|
+
}).optional(),
|
|
24
|
+
kind: zod.z.union([
|
|
25
|
+
zod.z.literal("FETCH"),
|
|
26
|
+
zod.z.unknown()
|
|
27
|
+
]),
|
|
28
|
+
revalidate: zod.z.number().optional(),
|
|
29
|
+
tags: zod.z.array(zod.z.string()).optional().default([])
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const cachePath = ".next/cache/fetch-cache";
|
|
33
|
+
const getCacheFiles = async ()=>{
|
|
34
|
+
if (!fs.existsSync(cachePath)) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
const files = await promises.readdir(cachePath);
|
|
39
|
+
const cacheFiles = new Map();
|
|
40
|
+
for (const file of files){
|
|
41
|
+
const fileContent = await promises.readFile(`${cachePath}/${file}`);
|
|
42
|
+
const body = JSON.parse(fileContent.toString());
|
|
43
|
+
const cacheEntry = nextCacheFileSchema.parse(body);
|
|
44
|
+
if (!cacheEntry.data) {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
cacheFiles.set(file, cacheEntry);
|
|
48
|
+
}
|
|
49
|
+
return cacheFiles;
|
|
50
|
+
} catch (error) {
|
|
51
|
+
console.error(error);
|
|
52
|
+
throw Error("Error reading cache files");
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
async function NextCacheToolbar() {
|
|
57
|
+
const files = await getCacheFiles();
|
|
58
|
+
const cacheEntries = Array.from(files?.entries() ?? []);
|
|
59
|
+
return /*#__PURE__*/ jsxRuntime.jsx("div", {
|
|
60
|
+
className: "dark",
|
|
61
|
+
children: /*#__PURE__*/ jsxRuntime.jsxs(cachePanelContextClient.CachePanelContextProvider, {
|
|
62
|
+
children: [
|
|
63
|
+
/*#__PURE__*/ jsxRuntime.jsx(cachePanelTriggerClient.CachePanelTrigger, {
|
|
64
|
+
className: "nct-fixed nct-rounded-full nct-bottom-4 nct-right-4 nct-bg-gradient-to-r nct-from-fuchsia-500 nct-to-cyan-500",
|
|
65
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(lucideReact.Braces, {})
|
|
66
|
+
}),
|
|
67
|
+
/*#__PURE__*/ jsxRuntime.jsxs(cachePanelWrapperClient.CacheTable, {
|
|
68
|
+
children: [
|
|
69
|
+
/*#__PURE__*/ jsxRuntime.jsx(cacheEntryClient.TableHeader, {
|
|
70
|
+
className: "nct-sticky nct-top-0 nct-bg-background",
|
|
71
|
+
children: /*#__PURE__*/ jsxRuntime.jsxs(cacheEntryClient.TableRow, {
|
|
72
|
+
children: [
|
|
73
|
+
/*#__PURE__*/ jsxRuntime.jsx(cachePanelHeadClient.CachePanelHead, {
|
|
74
|
+
sortingProperty: "url",
|
|
75
|
+
className: "nct-w-[300px]",
|
|
76
|
+
children: "URL"
|
|
77
|
+
}),
|
|
78
|
+
/*#__PURE__*/ jsxRuntime.jsx(cachePanelHeadClient.CachePanelHead, {
|
|
79
|
+
sortingProperty: "revalidate",
|
|
80
|
+
children: "Revalidate"
|
|
81
|
+
}),
|
|
82
|
+
/*#__PURE__*/ jsxRuntime.jsx(cachePanelHeadClient.CachePanelHead, {
|
|
83
|
+
sortingProperty: "tags",
|
|
84
|
+
children: "Tags"
|
|
85
|
+
}),
|
|
86
|
+
/*#__PURE__*/ jsxRuntime.jsx(cachePanelHeadClient.CachePanelHead, {
|
|
87
|
+
sortingProperty: "timestamp",
|
|
88
|
+
className: "nct-w-[300px]",
|
|
89
|
+
children: "Timestamp"
|
|
90
|
+
}),
|
|
91
|
+
/*#__PURE__*/ jsxRuntime.jsx(cacheEntryClient.TableHead, {
|
|
92
|
+
children: /*#__PURE__*/ jsxRuntime.jsxs("div", {
|
|
93
|
+
className: "nct-flex nct-items-center nct-justify-end nct-gap-2",
|
|
94
|
+
children: [
|
|
95
|
+
/*#__PURE__*/ jsxRuntime.jsx(refreshDataButtonClient.RefreshDataButton, {}),
|
|
96
|
+
/*#__PURE__*/ jsxRuntime.jsx(cachePanelTriggerClient.CachePanelTrigger, {
|
|
97
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(lucideReact.PanelBottomCloseIcon, {})
|
|
98
|
+
})
|
|
99
|
+
]
|
|
100
|
+
})
|
|
101
|
+
})
|
|
102
|
+
]
|
|
103
|
+
})
|
|
104
|
+
}),
|
|
105
|
+
/*#__PURE__*/ jsxRuntime.jsx(cachePanelTableClient.CachePanelTable, {
|
|
106
|
+
entries: cacheEntries
|
|
107
|
+
})
|
|
108
|
+
]
|
|
109
|
+
})
|
|
110
|
+
]
|
|
111
|
+
})
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
exports.NextCacheToolbar = NextCacheToolbar;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
3
|
+
var cachePanelTriggerClient = require('./cache-panel-trigger-client-I91XFsXW.js');
|
|
4
|
+
var cacheEntryClient = require('./cache-entry-client-BvxljHoj.js');
|
|
5
|
+
var lucideReact = require('lucide-react');
|
|
6
|
+
var navigation = require('next/navigation');
|
|
7
|
+
var React = require('react');
|
|
8
|
+
|
|
9
|
+
function RefreshDataButton() {
|
|
10
|
+
const [isPending, startTransition] = React.useTransition();
|
|
11
|
+
const router = navigation.useRouter();
|
|
12
|
+
const refresh = ()=>{
|
|
13
|
+
startTransition(()=>{
|
|
14
|
+
router.refresh();
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
return /*#__PURE__*/ jsxRuntime.jsx(cachePanelTriggerClient.Button, {
|
|
18
|
+
variant: "outline",
|
|
19
|
+
size: "icon",
|
|
20
|
+
onClick: refresh,
|
|
21
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(lucideReact.Loader2, {
|
|
22
|
+
className: cacheEntryClient.cn("nct-h-4 nct-w-4", {
|
|
23
|
+
"nct-animate-spin": isPending
|
|
24
|
+
})
|
|
25
|
+
})
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
exports.RefreshDataButton = RefreshDataButton;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { useMemo } from 'react';
|
|
5
|
+
import { cva } from 'class-variance-authority';
|
|
6
|
+
import { clsx } from 'clsx';
|
|
7
|
+
import { twMerge } from 'tailwind-merge';
|
|
8
|
+
|
|
9
|
+
function cn(...inputs) {
|
|
10
|
+
return twMerge(clsx(inputs));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const Table = /*#__PURE__*/ React.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsx("table", {
|
|
14
|
+
ref: ref,
|
|
15
|
+
className: cn("nct-w-full nct-caption-bottom nct-text-sm", className),
|
|
16
|
+
...props
|
|
17
|
+
}));
|
|
18
|
+
Table.displayName = "Table";
|
|
19
|
+
const TableHeader = /*#__PURE__*/ React.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsx("thead", {
|
|
20
|
+
ref: ref,
|
|
21
|
+
className: cn("[&_tr]:nct-border-b", className),
|
|
22
|
+
...props
|
|
23
|
+
}));
|
|
24
|
+
TableHeader.displayName = "TableHeader";
|
|
25
|
+
const TableBody = /*#__PURE__*/ React.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsx("tbody", {
|
|
26
|
+
ref: ref,
|
|
27
|
+
className: cn("[&_tr:last-child]:nct-border-0", className),
|
|
28
|
+
...props
|
|
29
|
+
}));
|
|
30
|
+
TableBody.displayName = "TableBody";
|
|
31
|
+
const TableFooter = /*#__PURE__*/ React.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsx("tfoot", {
|
|
32
|
+
ref: ref,
|
|
33
|
+
className: cn("nct-border-t nct-bg-muted/50 nct-font-medium [&>tr]:last:nct-border-b-0", className),
|
|
34
|
+
...props
|
|
35
|
+
}));
|
|
36
|
+
TableFooter.displayName = "TableFooter";
|
|
37
|
+
const TableRow = /*#__PURE__*/ React.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsx("tr", {
|
|
38
|
+
ref: ref,
|
|
39
|
+
className: cn("nct-border-b nct-transition-colors hover:nct-bg-muted/50 data-[state=selected]:nct-bg-muted", className),
|
|
40
|
+
...props
|
|
41
|
+
}));
|
|
42
|
+
TableRow.displayName = "TableRow";
|
|
43
|
+
const TableHead = /*#__PURE__*/ React.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsx("th", {
|
|
44
|
+
ref: ref,
|
|
45
|
+
className: cn("nct-h-12 nct-px-4 nct-text-left nct-align-middle nct-font-medium nct-text-muted-foreground [&:has([role=checkbox])]:nct-pr-0", className),
|
|
46
|
+
...props
|
|
47
|
+
}));
|
|
48
|
+
TableHead.displayName = "TableHead";
|
|
49
|
+
const TableCell = /*#__PURE__*/ React.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsx("td", {
|
|
50
|
+
ref: ref,
|
|
51
|
+
className: cn("nct-p-4 nct-align-middle [&:has([role=checkbox])]:nct-pr-0", className),
|
|
52
|
+
...props
|
|
53
|
+
}));
|
|
54
|
+
TableCell.displayName = "TableCell";
|
|
55
|
+
const TableCaption = /*#__PURE__*/ React.forwardRef(({ className, ...props }, ref)=>/*#__PURE__*/ jsx("caption", {
|
|
56
|
+
ref: ref,
|
|
57
|
+
className: cn("nct-mt-4 nct-text-sm nct-text-muted-foreground", className),
|
|
58
|
+
...props
|
|
59
|
+
}));
|
|
60
|
+
TableCaption.displayName = "TableCaption";
|
|
61
|
+
|
|
62
|
+
const badgeVariants = cva("nct-inline-flex nct-items-center nct-rounded-full nct-border nct-px-2.5 nct-py-0.5 nct-text-xs nct-font-semibold nct-transition-colors focus:nct-outline-none focus:nct-ring-2 focus:nct-ring-ring focus:nct-ring-offset-2", {
|
|
63
|
+
variants: {
|
|
64
|
+
variant: {
|
|
65
|
+
default: "nct-border-transparent nct-bg-primary nct-text-primary-foreground hover:nct-bg-primary/80",
|
|
66
|
+
secondary: "nct-border-transparent nct-bg-secondary nct-text-secondary-foreground hover:nct-bg-secondary/80",
|
|
67
|
+
destructive: "nct-border-transparent nct-bg-destructive nct-text-destructive-foreground hover:nct-bg-destructive/80",
|
|
68
|
+
outline: "nct-text-foreground"
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
defaultVariants: {
|
|
72
|
+
variant: "default"
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
function Badge({ className, variant, ...props }) {
|
|
76
|
+
return /*#__PURE__*/ jsx("div", {
|
|
77
|
+
className: cn(badgeVariants({
|
|
78
|
+
variant
|
|
79
|
+
}), className),
|
|
80
|
+
...props
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const CacheEntry = (props)=>{
|
|
85
|
+
const cacheEntryRevalidateLeft = useMemo(()=>{
|
|
86
|
+
if (!props.cacheEntry.data?.headers.date || !props.cacheEntry.revalidate) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const cacheEntryDate = new Date(props.cacheEntry.data?.headers.date);
|
|
90
|
+
const msDiff = new Date().getTime() - cacheEntryDate.getTime();
|
|
91
|
+
return Math.floor(props.cacheEntry.revalidate - msDiff / 1000);
|
|
92
|
+
}, [
|
|
93
|
+
props.cacheEntry.data?.headers.date,
|
|
94
|
+
props.cacheEntry.revalidate
|
|
95
|
+
]);
|
|
96
|
+
const isStale = cacheEntryRevalidateLeft ? cacheEntryRevalidateLeft < 0 : false;
|
|
97
|
+
return /*#__PURE__*/ jsxs(TableRow, {
|
|
98
|
+
children: [
|
|
99
|
+
/*#__PURE__*/ jsx(TableCell, {
|
|
100
|
+
className: "nct-truncate nct-max-w-[25vw]",
|
|
101
|
+
children: props.cacheEntry.data?.url
|
|
102
|
+
}),
|
|
103
|
+
/*#__PURE__*/ jsx(TableCell, {
|
|
104
|
+
title: cacheEntryRevalidateLeft?.toString() ?? "-",
|
|
105
|
+
children: isStale ? /*#__PURE__*/ jsx(Badge, {
|
|
106
|
+
children: "STALE"
|
|
107
|
+
}) : props.cacheEntry.revalidate ?? "-"
|
|
108
|
+
}),
|
|
109
|
+
/*#__PURE__*/ jsx(TableCell, {
|
|
110
|
+
className: "nct-break-before-all",
|
|
111
|
+
children: props.cacheEntry.tags.join("\n")
|
|
112
|
+
}),
|
|
113
|
+
/*#__PURE__*/ jsx(TableCell, {
|
|
114
|
+
children: props.cacheEntry.data?.headers.date
|
|
115
|
+
})
|
|
116
|
+
]
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
export { CacheEntry as C, TableHead as T, TableBody as a, Table as b, cn as c, TableHeader as d, TableRow as e };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import React__default, { useState, createContext } from 'react';
|
|
4
|
+
|
|
5
|
+
const CachePanelContext = /*#__PURE__*/ createContext({
|
|
6
|
+
isOpen: false,
|
|
7
|
+
toggleOpen: ()=>{},
|
|
8
|
+
setSorting: ()=>{}
|
|
9
|
+
});
|
|
10
|
+
const useCachePanelContext = ()=>React__default.useContext(CachePanelContext);
|
|
11
|
+
const CachePanelContextProvider = ({ children })=>{
|
|
12
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
13
|
+
const [sorting, setSorting] = useState(undefined);
|
|
14
|
+
const toggleOpen = ()=>{
|
|
15
|
+
setIsOpen(!isOpen);
|
|
16
|
+
};
|
|
17
|
+
return /*#__PURE__*/ jsx(CachePanelContext.Provider, {
|
|
18
|
+
value: {
|
|
19
|
+
isOpen,
|
|
20
|
+
toggleOpen,
|
|
21
|
+
setSorting,
|
|
22
|
+
sorting
|
|
23
|
+
},
|
|
24
|
+
children: children
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export { CachePanelContextProvider as C, useCachePanelContext as u };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
|
+
import { T as TableHead, c as cn } from './cache-entry-client-UcY_Onfg.js';
|
|
4
|
+
import { ArrowDownAZIcon, ArrowUpAZIcon } from 'lucide-react';
|
|
5
|
+
import { useMemo } from 'react';
|
|
6
|
+
import { u as useCachePanelContext } from './cache-panel-context-client-D5NKXXpF.js';
|
|
7
|
+
|
|
8
|
+
const CachePanelHead = ({ sortingProperty, children, ...props })=>{
|
|
9
|
+
const { setSorting, sorting } = useCachePanelContext();
|
|
10
|
+
const sortingDirection = useMemo(()=>{
|
|
11
|
+
if (!sorting || sorting.key !== sortingProperty) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
return sorting.direction;
|
|
15
|
+
}, [
|
|
16
|
+
sorting,
|
|
17
|
+
sortingProperty
|
|
18
|
+
]);
|
|
19
|
+
const onHeadClick = ()=>{
|
|
20
|
+
if (sorting && sorting.key === sortingProperty) {
|
|
21
|
+
setSorting({
|
|
22
|
+
key: sortingProperty,
|
|
23
|
+
direction: sorting.direction === "asc" ? "desc" : "asc"
|
|
24
|
+
});
|
|
25
|
+
} else {
|
|
26
|
+
setSorting({
|
|
27
|
+
key: sortingProperty,
|
|
28
|
+
direction: "asc"
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
return /*#__PURE__*/ jsx(TableHead, {
|
|
33
|
+
onClick: onHeadClick,
|
|
34
|
+
...props,
|
|
35
|
+
children: /*#__PURE__*/ jsxs("div", {
|
|
36
|
+
className: cn("nct-flex nct-items-center nct-gap-2", sorting?.key === sortingProperty && "nct-underline"),
|
|
37
|
+
children: [
|
|
38
|
+
children,
|
|
39
|
+
sortingDirection === "asc" && /*#__PURE__*/ jsx(ArrowDownAZIcon, {}),
|
|
40
|
+
sortingDirection === "desc" && /*#__PURE__*/ jsx(ArrowUpAZIcon, {})
|
|
41
|
+
]
|
|
42
|
+
})
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export { CachePanelHead as C };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { a as TableBody, C as CacheEntry } from './cache-entry-client-UcY_Onfg.js';
|
|
4
|
+
import { useMemo } from 'react';
|
|
5
|
+
import { u as useCachePanelContext } from './cache-panel-context-client-D5NKXXpF.js';
|
|
6
|
+
|
|
7
|
+
const sortCacheEntryByKey = (key, a, b)=>{
|
|
8
|
+
switch(key){
|
|
9
|
+
case "url":
|
|
10
|
+
if (!a.data || !b.data) {
|
|
11
|
+
return 0;
|
|
12
|
+
}
|
|
13
|
+
return a.data.url.localeCompare(b.data.url);
|
|
14
|
+
case "revalidate":
|
|
15
|
+
return (a.revalidate ?? 0) - (b.revalidate ?? 0);
|
|
16
|
+
case "tags":
|
|
17
|
+
if (a.tags.length === 0 || b.tags.length === 0) {
|
|
18
|
+
return 0;
|
|
19
|
+
}
|
|
20
|
+
return a.tags[0]?.localeCompare(b.tags[0] ?? "") ?? 0;
|
|
21
|
+
case "timestamp":
|
|
22
|
+
{
|
|
23
|
+
if (!a.data?.headers.date || !b.data?.headers.date) {
|
|
24
|
+
return 0;
|
|
25
|
+
}
|
|
26
|
+
return new Date(b.data.headers.date).getTime() - new Date(a.data.headers.date).getTime();
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
const CachePanelTable = ({ entries })=>{
|
|
31
|
+
const { sorting } = useCachePanelContext();
|
|
32
|
+
const sortedEntries = useMemo(()=>{
|
|
33
|
+
if (!sorting) {
|
|
34
|
+
return entries;
|
|
35
|
+
}
|
|
36
|
+
const { key, direction } = sorting;
|
|
37
|
+
return entries.toSorted((a, b)=>{
|
|
38
|
+
return sortCacheEntryByKey(key, a[1], b[1]) * (direction === "asc" ? 1 : -1);
|
|
39
|
+
});
|
|
40
|
+
}, [
|
|
41
|
+
entries,
|
|
42
|
+
sorting
|
|
43
|
+
]);
|
|
44
|
+
return /*#__PURE__*/ jsxs(TableBody, {
|
|
45
|
+
children: [
|
|
46
|
+
sortedEntries.length === 0 && /*#__PURE__*/ jsx("div", {
|
|
47
|
+
children: "No cache entries"
|
|
48
|
+
}),
|
|
49
|
+
sortedEntries.map(([file, cacheEntry])=>/*#__PURE__*/ jsx(CacheEntry, {
|
|
50
|
+
cacheEntry: cacheEntry
|
|
51
|
+
}, file))
|
|
52
|
+
]
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export { CachePanelTable as C };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { Slot } from '@radix-ui/react-slot';
|
|
5
|
+
import { cva } from 'class-variance-authority';
|
|
6
|
+
import { c as cn } from './cache-entry-client-UcY_Onfg.js';
|
|
7
|
+
import { u as useCachePanelContext } from './cache-panel-context-client-D5NKXXpF.js';
|
|
8
|
+
|
|
9
|
+
const buttonVariants = cva("nct-inline-flex nct-items-center nct-justify-center nct-whitespace-nowrap nct-rounded-md nct-text-sm nct-font-medium nct-ring-offset-background nct-transition-colors focus-visible:nct-outline-none focus-visible:nct-ring-2 focus-visible:nct-ring-ring focus-visible:nct-ring-offset-2 disabled:nct-pointer-events-none disabled:nct-opacity-50", {
|
|
10
|
+
variants: {
|
|
11
|
+
variant: {
|
|
12
|
+
default: "nct-bg-primary nct-text-primary-foreground hover:nct-bg-primary/90",
|
|
13
|
+
destructive: "nct-bg-destructive nct-text-destructive-foreground hover:nct-bg-destructive/90",
|
|
14
|
+
outline: "nct-border nct-border-input nct-bg-background hover:nct-bg-accent hover:nct-text-accent-foreground",
|
|
15
|
+
secondary: "nct-bg-secondary nct-text-secondary-foreground hover:nct-bg-secondary/80",
|
|
16
|
+
ghost: "hover:nct-bg-accent hover:nct-text-accent-foreground",
|
|
17
|
+
link: "nct-text-primary nct-underline-offset-4 hover:nct-underline"
|
|
18
|
+
},
|
|
19
|
+
size: {
|
|
20
|
+
default: "nct-h-10 nct-px-4 nct-py-2",
|
|
21
|
+
sm: "nct-h-9 nct-rounded-md nct-px-3",
|
|
22
|
+
lg: "nct-h-11 nct-rounded-md nct-px-8",
|
|
23
|
+
icon: "nct-h-10 nct-w-10"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
defaultVariants: {
|
|
27
|
+
variant: "default",
|
|
28
|
+
size: "default"
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
const Button = /*#__PURE__*/ React.forwardRef(({ className, variant, size, asChild = false, ...props }, ref)=>{
|
|
32
|
+
const Comp = asChild ? Slot : "button";
|
|
33
|
+
return /*#__PURE__*/ jsx(Comp, {
|
|
34
|
+
className: cn(buttonVariants({
|
|
35
|
+
variant,
|
|
36
|
+
size,
|
|
37
|
+
className
|
|
38
|
+
})),
|
|
39
|
+
ref: ref,
|
|
40
|
+
...props
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
Button.displayName = "Button";
|
|
44
|
+
|
|
45
|
+
function CachePanelTrigger(props) {
|
|
46
|
+
const { toggleOpen } = useCachePanelContext();
|
|
47
|
+
return /*#__PURE__*/ jsx(Button, {
|
|
48
|
+
variant: "ghost",
|
|
49
|
+
size: "icon",
|
|
50
|
+
onClick: toggleOpen,
|
|
51
|
+
...props
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export { Button as B, CachePanelTrigger as C };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { b as Table } from './cache-entry-client-UcY_Onfg.js';
|
|
4
|
+
import 'react';
|
|
5
|
+
import { u as useCachePanelContext } from './cache-panel-context-client-D5NKXXpF.js';
|
|
6
|
+
|
|
7
|
+
const CacheTable = (props)=>{
|
|
8
|
+
const { isOpen } = useCachePanelContext();
|
|
9
|
+
if (!isOpen) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
return /*#__PURE__*/ jsx("div", {
|
|
13
|
+
className: "nct-fixed nct-bottom-0 nct-inset-x-0 nct-z-50 nct-bg-background nct-overflow-x-auto nct-max-h-[35vh]",
|
|
14
|
+
children: /*#__PURE__*/ jsx(Table, {
|
|
15
|
+
children: props.children
|
|
16
|
+
})
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export { CacheTable as C };
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
'use server';
|
|
2
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
|
+
import { d as TableHeader, e as TableRow, T as TableHead } from './cache-entry-client-UcY_Onfg.js';
|
|
4
|
+
import { Braces, PanelBottomCloseIcon } from 'lucide-react';
|
|
5
|
+
import { existsSync } from 'fs';
|
|
6
|
+
import { readdir, readFile } from 'node:fs/promises';
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
import { C as CachePanelContextProvider } from './cache-panel-context-client-D5NKXXpF.js';
|
|
9
|
+
import { C as CachePanelHead } from './cache-panel-head-client-DCJPailN.js';
|
|
10
|
+
import { C as CachePanelTable } from './cache-panel-table-client-DUbKWZdy.js';
|
|
11
|
+
import { C as CachePanelTrigger } from './cache-panel-trigger-client-D3ag_ezj.js';
|
|
12
|
+
import { C as CacheTable } from './cache-panel-wrapper-client-BFFOMRXO.js';
|
|
13
|
+
import { R as RefreshDataButton } from './refresh-data-button-client-Bh7PpxMP.js';
|
|
14
|
+
|
|
15
|
+
const nextCacheFileSchema = z.object({
|
|
16
|
+
data: z.object({
|
|
17
|
+
body: z.string(),
|
|
18
|
+
headers: z.record(z.string(), z.string()),
|
|
19
|
+
status: z.number(),
|
|
20
|
+
url: z.string()
|
|
21
|
+
}).optional(),
|
|
22
|
+
kind: z.union([
|
|
23
|
+
z.literal("FETCH"),
|
|
24
|
+
z.unknown()
|
|
25
|
+
]),
|
|
26
|
+
revalidate: z.number().optional(),
|
|
27
|
+
tags: z.array(z.string()).optional().default([])
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const cachePath = ".next/cache/fetch-cache";
|
|
31
|
+
const getCacheFiles = async ()=>{
|
|
32
|
+
if (!existsSync(cachePath)) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
try {
|
|
36
|
+
const files = await readdir(cachePath);
|
|
37
|
+
const cacheFiles = new Map();
|
|
38
|
+
for (const file of files){
|
|
39
|
+
const fileContent = await readFile(`${cachePath}/${file}`);
|
|
40
|
+
const body = JSON.parse(fileContent.toString());
|
|
41
|
+
const cacheEntry = nextCacheFileSchema.parse(body);
|
|
42
|
+
if (!cacheEntry.data) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
cacheFiles.set(file, cacheEntry);
|
|
46
|
+
}
|
|
47
|
+
return cacheFiles;
|
|
48
|
+
} catch (error) {
|
|
49
|
+
console.error(error);
|
|
50
|
+
throw Error("Error reading cache files");
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
async function NextCacheToolbar() {
|
|
55
|
+
const files = await getCacheFiles();
|
|
56
|
+
const cacheEntries = Array.from(files?.entries() ?? []);
|
|
57
|
+
return /*#__PURE__*/ jsx("div", {
|
|
58
|
+
className: "dark",
|
|
59
|
+
children: /*#__PURE__*/ jsxs(CachePanelContextProvider, {
|
|
60
|
+
children: [
|
|
61
|
+
/*#__PURE__*/ jsx(CachePanelTrigger, {
|
|
62
|
+
className: "nct-fixed nct-rounded-full nct-bottom-4 nct-right-4 nct-bg-gradient-to-r nct-from-fuchsia-500 nct-to-cyan-500",
|
|
63
|
+
children: /*#__PURE__*/ jsx(Braces, {})
|
|
64
|
+
}),
|
|
65
|
+
/*#__PURE__*/ jsxs(CacheTable, {
|
|
66
|
+
children: [
|
|
67
|
+
/*#__PURE__*/ jsx(TableHeader, {
|
|
68
|
+
className: "nct-sticky nct-top-0 nct-bg-background",
|
|
69
|
+
children: /*#__PURE__*/ jsxs(TableRow, {
|
|
70
|
+
children: [
|
|
71
|
+
/*#__PURE__*/ jsx(CachePanelHead, {
|
|
72
|
+
sortingProperty: "url",
|
|
73
|
+
className: "nct-w-[300px]",
|
|
74
|
+
children: "URL"
|
|
75
|
+
}),
|
|
76
|
+
/*#__PURE__*/ jsx(CachePanelHead, {
|
|
77
|
+
sortingProperty: "revalidate",
|
|
78
|
+
children: "Revalidate"
|
|
79
|
+
}),
|
|
80
|
+
/*#__PURE__*/ jsx(CachePanelHead, {
|
|
81
|
+
sortingProperty: "tags",
|
|
82
|
+
children: "Tags"
|
|
83
|
+
}),
|
|
84
|
+
/*#__PURE__*/ jsx(CachePanelHead, {
|
|
85
|
+
sortingProperty: "timestamp",
|
|
86
|
+
className: "nct-w-[300px]",
|
|
87
|
+
children: "Timestamp"
|
|
88
|
+
}),
|
|
89
|
+
/*#__PURE__*/ jsx(TableHead, {
|
|
90
|
+
children: /*#__PURE__*/ jsxs("div", {
|
|
91
|
+
className: "nct-flex nct-items-center nct-justify-end nct-gap-2",
|
|
92
|
+
children: [
|
|
93
|
+
/*#__PURE__*/ jsx(RefreshDataButton, {}),
|
|
94
|
+
/*#__PURE__*/ jsx(CachePanelTrigger, {
|
|
95
|
+
children: /*#__PURE__*/ jsx(PanelBottomCloseIcon, {})
|
|
96
|
+
})
|
|
97
|
+
]
|
|
98
|
+
})
|
|
99
|
+
})
|
|
100
|
+
]
|
|
101
|
+
})
|
|
102
|
+
}),
|
|
103
|
+
/*#__PURE__*/ jsx(CachePanelTable, {
|
|
104
|
+
entries: cacheEntries
|
|
105
|
+
})
|
|
106
|
+
]
|
|
107
|
+
})
|
|
108
|
+
]
|
|
109
|
+
})
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export { NextCacheToolbar };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { B as Button } from './cache-panel-trigger-client-D3ag_ezj.js';
|
|
4
|
+
import { c as cn } from './cache-entry-client-UcY_Onfg.js';
|
|
5
|
+
import { Loader2 } from 'lucide-react';
|
|
6
|
+
import { useRouter } from 'next/navigation';
|
|
7
|
+
import { useTransition } from 'react';
|
|
8
|
+
|
|
9
|
+
function RefreshDataButton() {
|
|
10
|
+
const [isPending, startTransition] = useTransition();
|
|
11
|
+
const router = useRouter();
|
|
12
|
+
const refresh = ()=>{
|
|
13
|
+
startTransition(()=>{
|
|
14
|
+
router.refresh();
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
return /*#__PURE__*/ jsx(Button, {
|
|
18
|
+
variant: "outline",
|
|
19
|
+
size: "icon",
|
|
20
|
+
onClick: refresh,
|
|
21
|
+
children: /*#__PURE__*/ jsx(Loader2, {
|
|
22
|
+
className: cn("nct-h-4 nct-w-4", {
|
|
23
|
+
"nct-animate-spin": isPending
|
|
24
|
+
})
|
|
25
|
+
})
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export { RefreshDataButton as R };
|
package/dist/style.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! tailwindcss v3.4.1 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}:host,html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:var(--font-sans),ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}:root{--background:0 0% 100%;--foreground:222.2 47.4% 11.2%;--muted:210 40% 96.1%;--muted-foreground:215.4 16.3% 46.9%;--popover:0 0% 100%;--popover-foreground:222.2 47.4% 11.2%;--border:214.3 31.8% 91.4%;--input:214.3 31.8% 91.4%;--card:0 0% 100%;--card-foreground:222.2 47.4% 11.2%;--primary:222.2 47.4% 11.2%;--primary-foreground:210 40% 98%;--secondary:210 40% 96.1%;--secondary-foreground:222.2 47.4% 11.2%;--accent:210 40% 96.1%;--accent-foreground:222.2 47.4% 11.2%;--destructive:0 100% 50%;--destructive-foreground:210 40% 98%;--ring:215 20.2% 65.1%;--radius:0.5rem}.dark{--background:224 71% 4%;--foreground:213 31% 91%;--muted:223 47% 11%;--muted-foreground:215.4 16.3% 56.9%;--accent:216 34% 17%;--accent-foreground:210 40% 98%;--popover:224 71% 4%;--popover-foreground:215 20.2% 65.1%;--border:216 34% 17%;--input:216 34% 17%;--card:224 71% 4%;--card-foreground:213 31% 91%;--primary:210 40% 98%;--primary-foreground:222.2 47.4% 1.2%;--secondary:222.2 47.4% 11.2%;--secondary-foreground:210 40% 98%;--destructive:0 63% 31%;--destructive-foreground:210 40% 98%;--ring:216 34% 17%;--radius:0.5rem}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.nct-fixed{position:fixed}.nct-sticky{position:sticky}.nct-inset-x-0{left:0;right:0}.nct-bottom-0{bottom:0}.nct-bottom-4{bottom:1rem}.nct-right-4{right:1rem}.nct-top-0{top:0}.nct-z-50{z-index:50}.nct-mt-4{margin-top:1rem}.nct-flex{display:flex}.nct-inline-flex{display:inline-flex}.nct-h-10{height:2.5rem}.nct-h-11{height:2.75rem}.nct-h-12{height:3rem}.nct-h-4{height:1rem}.nct-h-9{height:2.25rem}.nct-max-h-\[35vh\]{max-height:35vh}.nct-w-10{width:2.5rem}.nct-w-4{width:1rem}.nct-w-\[300px\]{width:300px}.nct-w-full{width:100%}.nct-max-w-\[25vw\]{max-width:25vw}.nct-caption-bottom{caption-side:bottom}@keyframes nct-spin{to{transform:rotate(1turn)}}.nct-animate-spin{animation:nct-spin 1s linear infinite}.nct-break-before-all{-moz-column-break-before:all;break-before:all}.nct-items-center{align-items:center}.nct-justify-end{justify-content:flex-end}.nct-justify-center{justify-content:center}.nct-gap-2{gap:.5rem}.nct-overflow-hidden{overflow:hidden}.nct-overflow-x-auto{overflow-x:auto}.nct-truncate{overflow:hidden;text-overflow:ellipsis}.nct-truncate,.nct-whitespace-nowrap{white-space:nowrap}.nct-rounded-full{border-radius:9999px}.nct-rounded-md{border-radius:calc(var(--radius) - 2px)}.nct-border{border-width:1px}.nct-border-b{border-bottom-width:1px}.nct-border-t{border-top-width:1px}.nct-border-input{border-color:hsl(var(--input))}.nct-border-transparent{border-color:#0000}.nct-bg-background{background-color:hsl(var(--background))}.nct-bg-destructive{background-color:hsl(var(--destructive))}.nct-bg-muted\/50{background-color:hsl(var(--muted)/.5)}.nct-bg-popover{background-color:hsl(var(--popover))}.nct-bg-primary{background-color:hsl(var(--primary))}.nct-bg-secondary{background-color:hsl(var(--secondary))}.nct-bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.nct-from-fuchsia-500{--tw-gradient-from:#d946ef var(--tw-gradient-from-position);--tw-gradient-to:#d946ef00 var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-from),var(--tw-gradient-to)}.nct-to-cyan-500{--tw-gradient-to:#06b6d4 var(--tw-gradient-to-position)}.nct-p-4{padding:1rem}.nct-px-2{padding-left:.5rem;padding-right:.5rem}.nct-px-2\.5{padding-left:.625rem;padding-right:.625rem}.nct-px-3{padding-left:.75rem;padding-right:.75rem}.nct-px-4{padding-left:1rem;padding-right:1rem}.nct-px-8{padding-left:2rem;padding-right:2rem}.nct-py-0{padding-top:0;padding-bottom:0}.nct-py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.nct-py-1{padding-top:.25rem;padding-bottom:.25rem}.nct-py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.nct-py-2{padding-top:.5rem;padding-bottom:.5rem}.nct-text-left{text-align:left}.nct-align-middle{vertical-align:middle}.nct-text-sm{font-size:.875rem;line-height:1.25rem}.nct-text-xs{font-size:.75rem;line-height:1rem}.nct-font-medium{font-weight:500}.nct-font-semibold{font-weight:600}.nct-text-destructive-foreground{color:hsl(var(--destructive-foreground))}.nct-text-foreground{color:hsl(var(--foreground))}.nct-text-muted-foreground{color:hsl(var(--muted-foreground))}.nct-text-popover-foreground{color:hsl(var(--popover-foreground))}.nct-text-primary{color:hsl(var(--primary))}.nct-text-primary-foreground{color:hsl(var(--primary-foreground))}.nct-text-secondary-foreground{color:hsl(var(--secondary-foreground))}.nct-underline{text-decoration-line:underline}.nct-underline-offset-4{text-underline-offset:4px}.nct-shadow-md{--tw-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a;--tw-shadow-colored:0 4px 6px -1px var(--tw-shadow-color),0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.nct-ring-offset-background{--tw-ring-offset-color:hsl(var(--background))}.nct-transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0) scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1)) rotate(var(--tw-enter-rotate,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0) scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1)) rotate(var(--tw-exit-rotate,0))}}.nct-animate-in{animation-name:enter;animation-duration:.15s;--tw-enter-opacity:initial;--tw-enter-scale:initial;--tw-enter-rotate:initial;--tw-enter-translate-x:initial;--tw-enter-translate-y:initial}.nct-fade-in-0{--tw-enter-opacity:0}.nct-zoom-in-95{--tw-enter-scale:.95}.hover\:nct-bg-accent:hover{background-color:hsl(var(--accent))}.hover\:nct-bg-destructive\/80:hover{background-color:hsl(var(--destructive)/.8)}.hover\:nct-bg-destructive\/90:hover{background-color:hsl(var(--destructive)/.9)}.hover\:nct-bg-muted\/50:hover{background-color:hsl(var(--muted)/.5)}.hover\:nct-bg-primary\/80:hover{background-color:hsl(var(--primary)/.8)}.hover\:nct-bg-primary\/90:hover{background-color:hsl(var(--primary)/.9)}.hover\:nct-bg-secondary\/80:hover{background-color:hsl(var(--secondary)/.8)}.hover\:nct-text-accent-foreground:hover{color:hsl(var(--accent-foreground))}.hover\:nct-underline:hover{text-decoration-line:underline}.focus\:nct-outline-none:focus{outline:2px solid #0000;outline-offset:2px}.focus\:nct-ring-2:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\:nct-ring-ring:focus{--tw-ring-color:hsl(var(--ring))}.focus\:nct-ring-offset-2:focus{--tw-ring-offset-width:2px}.focus-visible\:nct-outline-none:focus-visible{outline:2px solid #0000;outline-offset:2px}.focus-visible\:nct-ring-2:focus-visible{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus-visible\:nct-ring-ring:focus-visible{--tw-ring-color:hsl(var(--ring))}.focus-visible\:nct-ring-offset-2:focus-visible{--tw-ring-offset-width:2px}.disabled\:nct-pointer-events-none:disabled{pointer-events:none}.disabled\:nct-opacity-50:disabled{opacity:.5}.data-\[state\=selected\]\:nct-bg-muted[data-state=selected]{background-color:hsl(var(--muted))}.data-\[state\=closed\]\:nct-animate-out[data-state=closed]{animation-name:exit;animation-duration:.15s;--tw-exit-opacity:initial;--tw-exit-scale:initial;--tw-exit-rotate:initial;--tw-exit-translate-x:initial;--tw-exit-translate-y:initial}.data-\[state\=closed\]\:nct-fade-out-0[data-state=closed]{--tw-exit-opacity:0}.data-\[state\=closed\]\:nct-zoom-out-95[data-state=closed]{--tw-exit-scale:.95}.data-\[side\=bottom\]\:nct-slide-in-from-top-2[data-side=bottom]{--tw-enter-translate-y:-0.5rem}.data-\[side\=left\]\:nct-slide-in-from-right-2[data-side=left]{--tw-enter-translate-x:0.5rem}.data-\[side\=right\]\:nct-slide-in-from-left-2[data-side=right]{--tw-enter-translate-x:-0.5rem}.data-\[side\=top\]\:nct-slide-in-from-bottom-2[data-side=top]{--tw-enter-translate-y:0.5rem}.\[\&\:has\(\[role\=checkbox\]\)\]\:nct-pr-0:has([role=checkbox]){padding-right:0}.\[\&\>tr\]\:last\:nct-border-b-0:last-child>tr{border-bottom-width:0}.\[\&_tr\:last-child\]\:nct-border-0 tr:last-child{border-width:0}.\[\&_tr\]\:nct-border-b tr{border-bottom-width:1px}
|
package/package.json
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "next-cache-toolbar",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Toolbar with all cached data in Next.js app router",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"prepublish": "npm run build",
|
|
7
|
+
"build": "rimraf dist && bunchee && tailwindcss -i src/style.css -o dist/style.css --minify",
|
|
8
|
+
"dev": "concurrently --names 'compile,tailwind,type-check' --prefix-colors 'green,white,white' --kill-others 'npm run dev:compile' 'npm run dev:tailwind' 'npm run dev:type-check'",
|
|
9
|
+
"dev:type-check": "tsc --watch --preserveWatchOutput --noEmit",
|
|
10
|
+
"dev:compile": "bunchee --watch",
|
|
11
|
+
"dev:tailwind": "tailwindcss -i src/style.css -o dist/style.css --watch"
|
|
12
|
+
},
|
|
13
|
+
"author": "Kajetan Szymczak <kajtszymczak@gmail.com>",
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=18",
|
|
16
|
+
"pnpm": ">=8"
|
|
17
|
+
},
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@radix-ui/react-slot": "^1.0.2",
|
|
21
|
+
"@radix-ui/react-tooltip": "^1.0.7",
|
|
22
|
+
"class-variance-authority": "^0.7.0",
|
|
23
|
+
"clsx": "^2.1.0",
|
|
24
|
+
"lucide-react": "^0.344.0",
|
|
25
|
+
"next": "^14",
|
|
26
|
+
"react": "^18",
|
|
27
|
+
"react-dom": "^18",
|
|
28
|
+
"tailwind-merge": "^2.2.1",
|
|
29
|
+
"tailwindcss-animate": "^1.0.7",
|
|
30
|
+
"zod": "^3.22.4"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"@biomejs/biome": "^1.5.3",
|
|
34
|
+
"@types/node": "^18.19.21",
|
|
35
|
+
"@types/react": "^18",
|
|
36
|
+
"@types/react-dom": "^18",
|
|
37
|
+
"autoprefixer": "^10.4.18",
|
|
38
|
+
"bunchee": "^4.4.8",
|
|
39
|
+
"concurrently": "^8.2.2",
|
|
40
|
+
"npm-run-all": "^4.1.5",
|
|
41
|
+
"postcss": "^8.4.35",
|
|
42
|
+
"rimraf": "^5.0.5",
|
|
43
|
+
"tailwindcss": "^3.4.1",
|
|
44
|
+
"turbo": "^1.12.4",
|
|
45
|
+
"typescript": "^5"
|
|
46
|
+
},
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"next": "^14",
|
|
49
|
+
"react": "^18",
|
|
50
|
+
"react-dom": "^18"
|
|
51
|
+
},
|
|
52
|
+
"files": [
|
|
53
|
+
"dist"
|
|
54
|
+
],
|
|
55
|
+
"main": "./dist/cjs/index.js",
|
|
56
|
+
"module": "./dist/es/index.mjs",
|
|
57
|
+
"types": "./dist/cjs/index.d.ts",
|
|
58
|
+
"exports": {
|
|
59
|
+
".": {
|
|
60
|
+
"import": {
|
|
61
|
+
"types": "./dist/es/index.d.mts",
|
|
62
|
+
"default": "./dist/es/index.mjs"
|
|
63
|
+
},
|
|
64
|
+
"require": {
|
|
65
|
+
"types": "./dist/cjs/index.d.ts",
|
|
66
|
+
"default": "./dist/cjs/index.js"
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"./style.css": {
|
|
70
|
+
"import": {
|
|
71
|
+
"default": "./dist/style.css"
|
|
72
|
+
},
|
|
73
|
+
"require": {
|
|
74
|
+
"default": "./dist/style.css"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# next-cache-toolbar  [](https://www.npmjs.com/package/next-cache-toolbar)
|
|
2
|
+
|
|
3
|
+
A toolbar that helps to identify [data cache](https://nextjs.org/docs/app/building-your-application/caching#data-cache) entries
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
## Use
|
|
8
|
+
|
|
9
|
+
`next-cache-toolbar` requires to use [app router](https://nextjs.org/docs/app/building-your-application/caching#data-cache) and [next-themes](
|
|
10
|
+
You'll need to update your `app/layout.jsx` to use next-themes. The simplest `layout` looks like this:
|
|
11
|
+
|
|
12
|
+
```js
|
|
13
|
+
// app/layout.jsx
|
|
14
|
+
import "next-cache-toolbar/style.css";
|
|
15
|
+
|
|
16
|
+
export default function Layout({ children }) {
|
|
17
|
+
return (
|
|
18
|
+
<html>
|
|
19
|
+
<head />
|
|
20
|
+
<body>
|
|
21
|
+
{children}
|
|
22
|
+
{process.env.NODE_ENV === "development" && <NextCacheToolbar />}
|
|
23
|
+
</body>
|
|
24
|
+
</html>
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|