next-cache-toolbar 0.1.3 → 0.2.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/dist/cjs/{cache-entry-client-Cg2-NRrZ.js → cache-entry-client-C0CjMKC5.js} +11 -12
- package/dist/cjs/cache-panel-context-client-FIUru-uB.js +115 -0
- package/dist/cjs/cache-panel-head-client-Cs4uyFh7.js +139 -0
- package/dist/cjs/cache-panel-table-client-9aBv-MjJ.js +22 -0
- package/dist/cjs/{cache-panel-trigger-client-ChZncD_2.js → cache-panel-trigger-client-CGeo22Q8.js} +2 -2
- package/dist/cjs/{cache-panel-wrapper-client-DE5QrmN0.js → cache-panel-wrapper-client-2eJisZgJ.js} +2 -2
- package/dist/cjs/cache-refresh-data-client-VWar7JpG.js +48 -0
- package/dist/cjs/{dialog-client-AZHsTC7l.js → dialog-client-ChHtZVMD.js} +16 -16
- package/dist/cjs/getCacheEntries-server-BheTh0n9.js +72 -0
- package/dist/cjs/index.d.ts +13 -1
- package/dist/cjs/index.js +19 -85
- package/dist/es/{cache-entry-client-CtWrVYTN.js → cache-entry-client-Ceh-eYDl.js} +11 -14
- package/dist/es/cache-panel-context-client-DCXKayLF.js +110 -0
- package/dist/es/cache-panel-head-client-BBfig3xH.js +120 -0
- package/dist/es/cache-panel-table-client-C9YfopmF.js +22 -0
- package/dist/es/{cache-panel-trigger-client-GrlxjSO5.js → cache-panel-trigger-client-CGReagL-.js} +2 -2
- package/dist/es/{cache-panel-wrapper-client-BosTuysv.js → cache-panel-wrapper-client-Cv0HcuJC.js} +2 -2
- package/dist/es/cache-refresh-data-client-BjsJkQ5H.js +48 -0
- package/dist/es/{dialog-client-D5Q_DDEF.js → dialog-client-C319YNfG.js} +1 -1
- package/dist/es/getCacheEntries-server-CgNUCSp3.js +72 -0
- package/dist/es/index.d.mts +13 -1
- package/dist/es/index.mjs +18 -84
- package/dist/style.css +1 -2
- package/package.json +3 -3
- package/dist/cjs/cache-panel-context-client-B1EgwMzI.js +0 -33
- package/dist/cjs/cache-panel-head-client-CbhKAPhZ.js +0 -46
- package/dist/cjs/cache-panel-table-client-CuP76AwU.js +0 -56
- package/dist/cjs/refresh-data-button-client-D4e_gWso.js +0 -28
- package/dist/es/cache-panel-context-client-D5NKXXpF.js +0 -28
- package/dist/es/cache-panel-head-client-CZC6pddt.js +0 -46
- package/dist/es/cache-panel-table-client-Qc84cSj6.js +0 -56
- package/dist/es/refresh-data-button-client-DaxVafNg.js +0 -28
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
3
|
import { cva } from 'class-variance-authority';
|
|
4
4
|
import * as React from 'react';
|
|
5
|
-
import { useMemo } from 'react';
|
|
6
5
|
import { clsx } from 'clsx';
|
|
7
6
|
import { twMerge } from 'tailwind-merge';
|
|
8
7
|
import { Slot } from '@radix-ui/react-slot';
|
|
9
|
-
import { D as Dialog, a as DialogTrigger, b as DialogContent } from './dialog-client-
|
|
8
|
+
import { D as Dialog, a as DialogTrigger, b as DialogContent } from './dialog-client-C319YNfG.js';
|
|
10
9
|
import { Braces } from 'lucide-react';
|
|
11
10
|
import JsonView from 'react18-json-view';
|
|
12
11
|
|
|
@@ -121,18 +120,16 @@ const Button = /*#__PURE__*/ React.forwardRef(({ className, variant, size, asChi
|
|
|
121
120
|
});
|
|
122
121
|
Button.displayName = "Button";
|
|
123
122
|
|
|
123
|
+
const getEntryRevalidateLeft = (cacheEntry)=>{
|
|
124
|
+
if (!cacheEntry.data?.headers.date || !cacheEntry.revalidate) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const cacheEntryDate = new Date(cacheEntry.data?.headers.date);
|
|
128
|
+
const msDiff = new Date().getTime() - cacheEntryDate.getTime();
|
|
129
|
+
return Math.floor(cacheEntry.revalidate - msDiff / 1000);
|
|
130
|
+
};
|
|
124
131
|
const CacheEntry = (props)=>{
|
|
125
|
-
const cacheEntryRevalidateLeft =
|
|
126
|
-
if (!props.cacheEntry.data?.headers.date || !props.cacheEntry.revalidate) {
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
const cacheEntryDate = new Date(props.cacheEntry.data?.headers.date);
|
|
130
|
-
const msDiff = new Date().getTime() - cacheEntryDate.getTime();
|
|
131
|
-
return Math.floor(props.cacheEntry.revalidate - msDiff / 1000);
|
|
132
|
-
}, [
|
|
133
|
-
props.cacheEntry.data?.headers.date,
|
|
134
|
-
props.cacheEntry.revalidate
|
|
135
|
-
]);
|
|
132
|
+
const cacheEntryRevalidateLeft = getEntryRevalidateLeft(props.cacheEntry);
|
|
136
133
|
const isStale = cacheEntryRevalidateLeft ? cacheEntryRevalidateLeft < 0 : false;
|
|
137
134
|
return /*#__PURE__*/ jsxs(TableRow, {
|
|
138
135
|
children: [
|
|
@@ -183,4 +180,4 @@ const CacheEntry = (props)=>{
|
|
|
183
180
|
});
|
|
184
181
|
};
|
|
185
182
|
|
|
186
|
-
export { Button as B, CacheEntry as C, TableHead as T, TableBody as a,
|
|
183
|
+
export { Button as B, CacheEntry as C, TableHead as T, TableBody as a, TableRow as b, cn as c, TableCell as d, Table as e, TableHeader as f };
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import React__default, { useState, useMemo, createContext } from 'react';
|
|
4
|
+
|
|
5
|
+
const CachePanelContext = /*#__PURE__*/ createContext({
|
|
6
|
+
entries: [],
|
|
7
|
+
isOpen: false,
|
|
8
|
+
setEntries: ()=>{},
|
|
9
|
+
toggleOpen: ()=>{},
|
|
10
|
+
setSorting: ()=>{},
|
|
11
|
+
addFilter: ()=>{},
|
|
12
|
+
clearFilter: ()=>{}
|
|
13
|
+
});
|
|
14
|
+
const sortCacheEntryByKey = (key, a, b)=>{
|
|
15
|
+
switch(key){
|
|
16
|
+
case "url":
|
|
17
|
+
if (!a.data || !b.data) {
|
|
18
|
+
return 0;
|
|
19
|
+
}
|
|
20
|
+
return a.data.url.localeCompare(b.data.url);
|
|
21
|
+
case "revalidate":
|
|
22
|
+
return (a.revalidate ?? 0) - (b.revalidate ?? 0);
|
|
23
|
+
case "tags":
|
|
24
|
+
if (a.tags.length === 0 || b.tags.length === 0) {
|
|
25
|
+
return 0;
|
|
26
|
+
}
|
|
27
|
+
return a.tags[0]?.localeCompare(b.tags[0] ?? "") ?? 0;
|
|
28
|
+
case "timestamp":
|
|
29
|
+
{
|
|
30
|
+
if (!a.data?.headers.date || !b.data?.headers.date) {
|
|
31
|
+
return 0;
|
|
32
|
+
}
|
|
33
|
+
return new Date(b.data.headers.date).getTime() - new Date(a.data.headers.date).getTime();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const useCachePanelContext = ()=>React__default.useContext(CachePanelContext);
|
|
38
|
+
const CachePanelContextProvider = (props)=>{
|
|
39
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
40
|
+
const [entries, setEntries] = useState(props.entries);
|
|
41
|
+
const [filters, setFilters] = useState();
|
|
42
|
+
const [sorting, setSorting] = useState(undefined);
|
|
43
|
+
const toggleOpen = ()=>{
|
|
44
|
+
setIsOpen(!isOpen);
|
|
45
|
+
};
|
|
46
|
+
const addFilter = (key, value)=>{
|
|
47
|
+
setFilters((prev)=>{
|
|
48
|
+
if (!prev) {
|
|
49
|
+
return {
|
|
50
|
+
[key]: value
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
...prev,
|
|
55
|
+
[key]: value
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
const clearFilter = (key)=>{
|
|
60
|
+
setFilters((prev)=>{
|
|
61
|
+
if (!prev) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
delete prev[key];
|
|
65
|
+
return prev;
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
const derivedEntries = useMemo(()=>{
|
|
69
|
+
let copiedEntries = entries.slice();
|
|
70
|
+
if (filters) {
|
|
71
|
+
copiedEntries = copiedEntries.filter((entry)=>{
|
|
72
|
+
const { tags: tagsFilter, url: urlFilter } = filters;
|
|
73
|
+
if (tagsFilter && !entry[1].tags.some((tag)=>tag.match(tagsFilter))) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
if (urlFilter && !entry[1].data.url.match(urlFilter)) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
return true;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
if (!sorting) {
|
|
83
|
+
return copiedEntries;
|
|
84
|
+
}
|
|
85
|
+
const { key, direction } = sorting;
|
|
86
|
+
return copiedEntries.toSorted((a, b)=>{
|
|
87
|
+
return sortCacheEntryByKey(key, a[1], b[1]) * (direction === "asc" ? 1 : -1);
|
|
88
|
+
});
|
|
89
|
+
}, [
|
|
90
|
+
entries,
|
|
91
|
+
sorting,
|
|
92
|
+
filters
|
|
93
|
+
]);
|
|
94
|
+
return /*#__PURE__*/ jsx(CachePanelContext.Provider, {
|
|
95
|
+
value: {
|
|
96
|
+
isOpen,
|
|
97
|
+
toggleOpen,
|
|
98
|
+
setSorting,
|
|
99
|
+
sorting,
|
|
100
|
+
entries: derivedEntries,
|
|
101
|
+
setEntries,
|
|
102
|
+
filters,
|
|
103
|
+
addFilter,
|
|
104
|
+
clearFilter
|
|
105
|
+
},
|
|
106
|
+
children: props.children
|
|
107
|
+
});
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
export { CachePanelContextProvider as C, useCachePanelContext as u };
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
|
+
import { c as cn, T as TableHead, B as Button } from './cache-entry-client-Ceh-eYDl.js';
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
import { useState, useCallback, useMemo } from 'react';
|
|
6
|
+
import { ArrowDownAZIcon, ArrowUpAZIcon, FilterIcon } from 'lucide-react';
|
|
7
|
+
import { u as useCachePanelContext } from './cache-panel-context-client-DCXKayLF.js';
|
|
8
|
+
|
|
9
|
+
const Input = /*#__PURE__*/ React.forwardRef(({ className, type, ...props }, ref)=>{
|
|
10
|
+
return /*#__PURE__*/ jsx("input", {
|
|
11
|
+
type: type,
|
|
12
|
+
className: cn("nct-flex nct-h-10 nct-w-full nct-rounded-md nct-border nct-border-input nct-bg-background nct-px-3 nct-py-2 nct-text-sm nct-ring-offset-background file:nct-border-0 file:nct-bg-transparent file:nct-text-sm file:nct-font-medium placeholder:nct-text-muted-foreground focus-visible:nct-outline-none focus-visible:nct-ring-2 focus-visible:nct-ring-ring focus-visible:nct-ring-offset-2 disabled:nct-cursor-not-allowed disabled:nct-opacity-50", className),
|
|
13
|
+
ref: ref,
|
|
14
|
+
...props
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
Input.displayName = "Input";
|
|
18
|
+
|
|
19
|
+
const CachePanelHead = ({ sortingProperty, children, className, withFilter = false, ...props })=>{
|
|
20
|
+
const { setSorting, sorting, filters, addFilter, clearFilter } = useCachePanelContext();
|
|
21
|
+
const [filterInputVisible, setFilterInputVisible] = useState(false);
|
|
22
|
+
const inputRef = useCallback((node)=>{
|
|
23
|
+
if (!node) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
node.focus();
|
|
27
|
+
}, []);
|
|
28
|
+
const sortingDirection = useMemo(()=>{
|
|
29
|
+
if (!sorting || sorting.key !== sortingProperty) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
return sorting.direction;
|
|
33
|
+
}, [
|
|
34
|
+
sorting,
|
|
35
|
+
sortingProperty
|
|
36
|
+
]);
|
|
37
|
+
const filterValue = useMemo(()=>{
|
|
38
|
+
if (sortingProperty !== "url" && sortingProperty !== "tags") {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
return filters?.[sortingProperty] ?? "";
|
|
42
|
+
}, [
|
|
43
|
+
sortingProperty,
|
|
44
|
+
filters
|
|
45
|
+
]);
|
|
46
|
+
const onHeadClick = ()=>{
|
|
47
|
+
if (sorting && sorting.key === sortingProperty) {
|
|
48
|
+
setSorting({
|
|
49
|
+
key: sortingProperty,
|
|
50
|
+
direction: sorting.direction === "asc" ? "desc" : "asc"
|
|
51
|
+
});
|
|
52
|
+
} else {
|
|
53
|
+
setSorting({
|
|
54
|
+
key: sortingProperty,
|
|
55
|
+
direction: "asc"
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
const onFilterInputKeyDown = (event)=>{
|
|
60
|
+
if (sortingProperty !== "url" && sortingProperty !== "tags") {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// clear value on esc
|
|
64
|
+
if (event.key === "Escape") {
|
|
65
|
+
clearFilter(sortingProperty);
|
|
66
|
+
setFilterInputVisible(false);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
const onFilterInputChange = (event)=>{
|
|
70
|
+
if (sortingProperty !== "url" && sortingProperty !== "tags") {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
addFilter(sortingProperty, event.target.value);
|
|
74
|
+
};
|
|
75
|
+
const onFilterInputBlur = (event)=>{
|
|
76
|
+
if (sortingProperty !== "url" && sortingProperty !== "tags") {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (event.target.value === "") {
|
|
80
|
+
setFilterInputVisible(false);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
return /*#__PURE__*/ jsx(TableHead, {
|
|
84
|
+
className: cn("group", className),
|
|
85
|
+
...props,
|
|
86
|
+
children: /*#__PURE__*/ jsxs("div", {
|
|
87
|
+
className: cn("nct-flex nct-items-center nct-gap-2 nct-py-2", sorting?.key === sortingProperty && "nct-underline"),
|
|
88
|
+
children: [
|
|
89
|
+
/*#__PURE__*/ jsx("div", {
|
|
90
|
+
onClick: onHeadClick,
|
|
91
|
+
onKeyDown: onHeadClick,
|
|
92
|
+
children: children
|
|
93
|
+
}),
|
|
94
|
+
sortingDirection === "asc" && /*#__PURE__*/ jsx(ArrowDownAZIcon, {}),
|
|
95
|
+
sortingDirection === "desc" && /*#__PURE__*/ jsx(ArrowUpAZIcon, {}),
|
|
96
|
+
withFilter && /*#__PURE__*/ jsxs("div", {
|
|
97
|
+
className: "ml-auto",
|
|
98
|
+
children: [
|
|
99
|
+
!filterInputVisible && /*#__PURE__*/ jsx(Button, {
|
|
100
|
+
variant: "ghost",
|
|
101
|
+
size: "icon",
|
|
102
|
+
className: cn(),
|
|
103
|
+
onClick: ()=>setFilterInputVisible(true),
|
|
104
|
+
children: /*#__PURE__*/ jsx(FilterIcon, {})
|
|
105
|
+
}),
|
|
106
|
+
filterInputVisible && /*#__PURE__*/ jsx(Input, {
|
|
107
|
+
onKeyDown: onFilterInputKeyDown,
|
|
108
|
+
value: filterValue,
|
|
109
|
+
onChange: onFilterInputChange,
|
|
110
|
+
onBlur: onFilterInputBlur,
|
|
111
|
+
ref: inputRef
|
|
112
|
+
})
|
|
113
|
+
]
|
|
114
|
+
})
|
|
115
|
+
]
|
|
116
|
+
})
|
|
117
|
+
});
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
export { CachePanelHead as C };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { a as TableBody, b as TableRow, d as TableCell, C as CacheEntry } from './cache-entry-client-Ceh-eYDl.js';
|
|
4
|
+
import { u as useCachePanelContext } from './cache-panel-context-client-DCXKayLF.js';
|
|
5
|
+
|
|
6
|
+
const CachePanelTable = ()=>{
|
|
7
|
+
const { entries } = useCachePanelContext();
|
|
8
|
+
return /*#__PURE__*/ jsxs(TableBody, {
|
|
9
|
+
children: [
|
|
10
|
+
entries.length === 0 && /*#__PURE__*/ jsx(TableRow, {
|
|
11
|
+
children: /*#__PURE__*/ jsx(TableCell, {
|
|
12
|
+
children: "No cache entries"
|
|
13
|
+
})
|
|
14
|
+
}),
|
|
15
|
+
entries.map(([file, cacheEntry])=>/*#__PURE__*/ jsx(CacheEntry, {
|
|
16
|
+
cacheEntry: cacheEntry
|
|
17
|
+
}, file))
|
|
18
|
+
]
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export { CachePanelTable as C };
|
package/dist/es/{cache-panel-trigger-client-GrlxjSO5.js → cache-panel-trigger-client-CGReagL-.js}
RENAMED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { B as Button } from './cache-entry-client-
|
|
3
|
+
import { B as Button } from './cache-entry-client-Ceh-eYDl.js';
|
|
4
4
|
import 'react';
|
|
5
|
-
import { u as useCachePanelContext } from './cache-panel-context-client-
|
|
5
|
+
import { u as useCachePanelContext } from './cache-panel-context-client-DCXKayLF.js';
|
|
6
6
|
|
|
7
7
|
function CachePanelTrigger(props) {
|
|
8
8
|
const { toggleOpen } = useCachePanelContext();
|
package/dist/es/{cache-panel-wrapper-client-BosTuysv.js → cache-panel-wrapper-client-Cv0HcuJC.js}
RENAMED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
|
-
import {
|
|
3
|
+
import { e as Table } from './cache-entry-client-Ceh-eYDl.js';
|
|
4
4
|
import 'react';
|
|
5
|
-
import { u as useCachePanelContext } from './cache-panel-context-client-
|
|
5
|
+
import { u as useCachePanelContext } from './cache-panel-context-client-DCXKayLF.js';
|
|
6
6
|
|
|
7
7
|
const CacheTable = (props)=>{
|
|
8
8
|
const { isOpen } = useCachePanelContext();
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { g as getCacheFiles } from './getCacheEntries-server-CgNUCSp3.js';
|
|
4
|
+
import { B as Button, c as cn } from './cache-entry-client-Ceh-eYDl.js';
|
|
5
|
+
import { Loader2 } from 'lucide-react';
|
|
6
|
+
import { usePathname } from 'next/navigation';
|
|
7
|
+
import { useTransition, useEffect } from 'react';
|
|
8
|
+
import { u as useCachePanelContext } from './cache-panel-context-client-DCXKayLF.js';
|
|
9
|
+
|
|
10
|
+
function RefreshDataButton({ enabled, interval }) {
|
|
11
|
+
const { setEntries } = useCachePanelContext();
|
|
12
|
+
const [isPending, startTransition] = useTransition();
|
|
13
|
+
const pathname = usePathname();
|
|
14
|
+
const refreshData = ()=>{
|
|
15
|
+
startTransition(async ()=>{
|
|
16
|
+
const files = await getCacheFiles();
|
|
17
|
+
setEntries(files ?? []);
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
useEffect(()=>{
|
|
21
|
+
console.log("pathname changed", pathname);
|
|
22
|
+
refreshData();
|
|
23
|
+
}, [
|
|
24
|
+
pathname
|
|
25
|
+
]);
|
|
26
|
+
useEffect(()=>{
|
|
27
|
+
if (!enabled) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const intervalId = setInterval(refreshData, interval);
|
|
31
|
+
return ()=>clearInterval(intervalId);
|
|
32
|
+
}, [
|
|
33
|
+
enabled,
|
|
34
|
+
interval
|
|
35
|
+
]);
|
|
36
|
+
return /*#__PURE__*/ jsx(Button, {
|
|
37
|
+
variant: "outline",
|
|
38
|
+
size: "icon",
|
|
39
|
+
onClick: refreshData,
|
|
40
|
+
children: /*#__PURE__*/ jsx(Loader2, {
|
|
41
|
+
className: cn("nct-h-4 nct-w-4", {
|
|
42
|
+
"nct-animate-spin": isPending
|
|
43
|
+
})
|
|
44
|
+
})
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { RefreshDataButton as R };
|
|
@@ -3,7 +3,7 @@ import { jsx, jsxs } from 'react/jsx-runtime';
|
|
|
3
3
|
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
4
4
|
import { X } from 'lucide-react';
|
|
5
5
|
import * as React from 'react';
|
|
6
|
-
import { c as cn } from './cache-entry-client-
|
|
6
|
+
import { c as cn } from './cache-entry-client-Ceh-eYDl.js';
|
|
7
7
|
|
|
8
8
|
const Dialog = DialogPrimitive.Root;
|
|
9
9
|
const DialogTrigger = DialogPrimitive.Trigger;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
'use server';
|
|
2
|
+
import { existsSync, promises } from 'fs';
|
|
3
|
+
import { z, ZodError } from 'zod';
|
|
4
|
+
|
|
5
|
+
const stringToJSONSchema = z.string().transform((str, ctx)=>{
|
|
6
|
+
try {
|
|
7
|
+
return JSON.parse(str);
|
|
8
|
+
} catch (e) {
|
|
9
|
+
ctx.addIssue({
|
|
10
|
+
code: "custom",
|
|
11
|
+
message: "Encoded body is not in JSON format",
|
|
12
|
+
path: [
|
|
13
|
+
"data",
|
|
14
|
+
"body"
|
|
15
|
+
]
|
|
16
|
+
});
|
|
17
|
+
return z.NEVER;
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
const nextCacheFileSchema = z.object({
|
|
21
|
+
data: z.object({
|
|
22
|
+
body: z.string(),
|
|
23
|
+
headers: z.record(z.string(), z.string()),
|
|
24
|
+
status: z.number(),
|
|
25
|
+
url: z.string()
|
|
26
|
+
}),
|
|
27
|
+
kind: z.union([
|
|
28
|
+
z.literal("FETCH"),
|
|
29
|
+
z.unknown()
|
|
30
|
+
]),
|
|
31
|
+
revalidate: z.number().optional(),
|
|
32
|
+
tags: z.array(z.string()).optional().default([])
|
|
33
|
+
}).transform((cacheEntry)=>{
|
|
34
|
+
const body = stringToJSONSchema.parse(atob(cacheEntry.data.body));
|
|
35
|
+
return {
|
|
36
|
+
...cacheEntry,
|
|
37
|
+
data: {
|
|
38
|
+
...cacheEntry.data,
|
|
39
|
+
body
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const cachePath = ".next/cache/fetch-cache";
|
|
45
|
+
const getCacheFiles = async ()=>{
|
|
46
|
+
if (!existsSync(cachePath)) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const files = await promises.readdir(cachePath);
|
|
50
|
+
const cacheFiles = new Map();
|
|
51
|
+
for (const file of files){
|
|
52
|
+
// ignore tags-manifest file
|
|
53
|
+
if (file.match(/manifest/)) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
const fileContent = await promises.readFile(`${cachePath}/${file}`);
|
|
58
|
+
const cacheEntry = nextCacheFileSchema.parse(JSON.parse(fileContent.toString()));
|
|
59
|
+
cacheFiles.set(file, cacheEntry);
|
|
60
|
+
} catch (error) {
|
|
61
|
+
if (error instanceof ZodError) {
|
|
62
|
+
const issues = error.issues;
|
|
63
|
+
console.error(`File ${file} do not match the schema`, issues);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
console.error(`Error parsing ${file}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return Array.from(cacheFiles.entries());
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export { getCacheFiles as g };
|
package/dist/es/index.d.mts
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
type Props = {
|
|
4
|
+
/**
|
|
5
|
+
* If true, the cache table will automatically refresh when the pathname changes.
|
|
6
|
+
* @default false
|
|
7
|
+
*/
|
|
8
|
+
autoRefresh?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* The interval in milliseconds to refresh the cache table.
|
|
11
|
+
* @default 10000
|
|
12
|
+
*/
|
|
13
|
+
interval?: number;
|
|
14
|
+
};
|
|
15
|
+
declare function NextCacheToolbar({ autoRefresh, interval, }: Props): Promise<react_jsx_runtime.JSX.Element>;
|
|
4
16
|
|
|
5
17
|
export { NextCacheToolbar };
|
package/dist/es/index.mjs
CHANGED
|
@@ -1,90 +1,21 @@
|
|
|
1
|
-
'use server';
|
|
2
1
|
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
3
|
-
import { d as TableHeader, e as TableRow, T as TableHead } from './cache-entry-client-CtWrVYTN.js';
|
|
4
2
|
import { Braces, PanelBottomCloseIcon } from 'lucide-react';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { C as CachePanelContextProvider } from './cache-panel-context-client-
|
|
8
|
-
import { C as
|
|
9
|
-
import { C as
|
|
10
|
-
import { C as
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
3
|
+
import { g as getCacheFiles } from './getCacheEntries-server-CgNUCSp3.js';
|
|
4
|
+
import { f as TableHeader, b as TableRow, T as TableHead } from './cache-entry-client-Ceh-eYDl.js';
|
|
5
|
+
import { C as CachePanelContextProvider } from './cache-panel-context-client-DCXKayLF.js';
|
|
6
|
+
import { C as CachePanelTable } from './cache-panel-table-client-C9YfopmF.js';
|
|
7
|
+
import { C as CachePanelTrigger } from './cache-panel-trigger-client-CGReagL-.js';
|
|
8
|
+
import { C as CacheTable } from './cache-panel-wrapper-client-Cv0HcuJC.js';
|
|
9
|
+
import { R as RefreshDataButton } from './cache-refresh-data-client-BjsJkQ5H.js';
|
|
10
|
+
import { C as CachePanelHead } from './cache-panel-head-client-BBfig3xH.js';
|
|
13
11
|
|
|
14
|
-
|
|
15
|
-
try {
|
|
16
|
-
return JSON.parse(str);
|
|
17
|
-
} catch (e) {
|
|
18
|
-
ctx.addIssue({
|
|
19
|
-
code: "custom",
|
|
20
|
-
message: "Encoded body is not in JSON format",
|
|
21
|
-
path: [
|
|
22
|
-
"data",
|
|
23
|
-
"body"
|
|
24
|
-
]
|
|
25
|
-
});
|
|
26
|
-
return z.NEVER;
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
const nextCacheFileSchema = z.object({
|
|
30
|
-
data: z.object({
|
|
31
|
-
body: z.string(),
|
|
32
|
-
headers: z.record(z.string(), z.string()),
|
|
33
|
-
status: z.number(),
|
|
34
|
-
url: z.string()
|
|
35
|
-
}),
|
|
36
|
-
kind: z.union([
|
|
37
|
-
z.literal("FETCH"),
|
|
38
|
-
z.unknown()
|
|
39
|
-
]),
|
|
40
|
-
revalidate: z.number().optional(),
|
|
41
|
-
tags: z.array(z.string()).optional().default([])
|
|
42
|
-
}).transform((cacheEntry)=>{
|
|
43
|
-
const body = stringToJSONSchema.parse(atob(cacheEntry.data.body));
|
|
44
|
-
return {
|
|
45
|
-
...cacheEntry,
|
|
46
|
-
data: {
|
|
47
|
-
...cacheEntry.data,
|
|
48
|
-
body
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
const cachePath = ".next/cache/fetch-cache";
|
|
54
|
-
const getCacheFiles = async ()=>{
|
|
55
|
-
if (!existsSync(cachePath)) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
const files = await promises.readdir(cachePath);
|
|
59
|
-
const cacheFiles = new Map();
|
|
60
|
-
for (const file of files){
|
|
61
|
-
// ignore tags-manifest file
|
|
62
|
-
if (file.match(/manifest/)) {
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
try {
|
|
66
|
-
const fileContent = await promises.readFile(`${cachePath}/${file}`);
|
|
67
|
-
const cacheEntry = nextCacheFileSchema.parse(JSON.parse(fileContent.toString()));
|
|
68
|
-
cacheFiles.set(file, cacheEntry);
|
|
69
|
-
} catch (error) {
|
|
70
|
-
if (error instanceof ZodError) {
|
|
71
|
-
const issues = error.issues;
|
|
72
|
-
console.error(`File ${file} do not match the schema`, issues);
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
|
-
console.error(`Error parsing ${file}`);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
return cacheFiles;
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
async function NextCacheToolbar() {
|
|
12
|
+
async function NextCacheToolbar({ autoRefresh = false, interval = 10000 }) {
|
|
82
13
|
const files = await getCacheFiles();
|
|
83
|
-
const cacheEntries = Array.from(files?.entries() ?? []);
|
|
84
14
|
return /*#__PURE__*/ jsx("div", {
|
|
85
15
|
id: "next-cache-toolbar",
|
|
86
16
|
className: "nct-text-primary nct-font-mono",
|
|
87
17
|
children: /*#__PURE__*/ jsxs(CachePanelContextProvider, {
|
|
18
|
+
entries: files ?? [],
|
|
88
19
|
children: [
|
|
89
20
|
/*#__PURE__*/ jsx(CachePanelTrigger, {
|
|
90
21
|
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",
|
|
@@ -99,14 +30,16 @@ async function NextCacheToolbar() {
|
|
|
99
30
|
/*#__PURE__*/ jsx(CachePanelHead, {
|
|
100
31
|
sortingProperty: "url",
|
|
101
32
|
className: "nct-w-[300px]",
|
|
33
|
+
withFilter: true,
|
|
102
34
|
children: "URL"
|
|
103
35
|
}),
|
|
104
36
|
/*#__PURE__*/ jsx(CachePanelHead, {
|
|
105
37
|
sortingProperty: "revalidate",
|
|
106
|
-
children: "Revalidate"
|
|
38
|
+
children: "Revalidate (ms)"
|
|
107
39
|
}),
|
|
108
40
|
/*#__PURE__*/ jsx(CachePanelHead, {
|
|
109
41
|
sortingProperty: "tags",
|
|
42
|
+
withFilter: true,
|
|
110
43
|
children: "Tags"
|
|
111
44
|
}),
|
|
112
45
|
/*#__PURE__*/ jsx(CachePanelHead, {
|
|
@@ -118,7 +51,10 @@ async function NextCacheToolbar() {
|
|
|
118
51
|
children: /*#__PURE__*/ jsxs("div", {
|
|
119
52
|
className: "nct-flex nct-items-center nct-justify-end nct-gap-2",
|
|
120
53
|
children: [
|
|
121
|
-
/*#__PURE__*/ jsx(RefreshDataButton, {
|
|
54
|
+
/*#__PURE__*/ jsx(RefreshDataButton, {
|
|
55
|
+
enabled: autoRefresh,
|
|
56
|
+
interval: interval
|
|
57
|
+
}),
|
|
122
58
|
/*#__PURE__*/ jsx(CachePanelTrigger, {
|
|
123
59
|
children: /*#__PURE__*/ jsx(PanelBottomCloseIcon, {})
|
|
124
60
|
})
|
|
@@ -128,9 +64,7 @@ async function NextCacheToolbar() {
|
|
|
128
64
|
]
|
|
129
65
|
})
|
|
130
66
|
}),
|
|
131
|
-
/*#__PURE__*/ jsx(CachePanelTable, {
|
|
132
|
-
entries: cacheEntries
|
|
133
|
-
})
|
|
67
|
+
/*#__PURE__*/ jsx(CachePanelTable, {})
|
|
134
68
|
]
|
|
135
69
|
})
|
|
136
70
|
]
|