@pro-laico/payload-dev-tools 0.0.0 → 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/components/DevToolbar.d.ts.map +1 -1
- package/dist/components/DevToolbar.js +7 -3
- package/dist/components/DevToolbar.js.map +1 -1
- package/dist/components/DevToolbarClient.d.ts.map +1 -1
- package/dist/components/DevToolbarClient.js +91 -1
- package/dist/components/DevToolbarClient.js.map +1 -1
- package/dist/components/styles.d.ts +1 -1
- package/dist/components/styles.d.ts.map +1 -1
- package/dist/components/styles.js +13 -0
- package/dist/components/styles.js.map +1 -1
- package/dist/endpoints/activateIconSet.d.ts.map +1 -1
- package/dist/endpoints/activateIconSet.js +2 -0
- package/dist/endpoints/activateIconSet.js.map +1 -1
- package/dist/endpoints/draft.d.ts +12 -0
- package/dist/endpoints/draft.d.ts.map +1 -0
- package/dist/endpoints/draft.js +66 -0
- package/dist/endpoints/draft.js.map +1 -0
- package/dist/lib/snapshot.d.ts +15 -0
- package/dist/lib/snapshot.d.ts.map +1 -1
- package/dist/lib/snapshot.js +16 -1
- package/dist/lib/snapshot.js.map +1 -1
- package/dist/next/client.d.ts +5 -0
- package/dist/next/client.d.ts.map +1 -1
- package/dist/next/client.js +80 -0
- package/dist/next/client.js.map +1 -1
- package/dist/next/createDevPage.d.ts.map +1 -1
- package/dist/next/createDevPage.js +10 -1
- package/dist/next/createDevPage.js.map +1 -1
- package/dist/next/pageStyles.d.ts +1 -1
- package/dist/next/pageStyles.d.ts.map +1 -1
- package/dist/next/pageStyles.js +17 -0
- package/dist/next/pageStyles.js.map +1 -1
- package/dist/next/revalidatePanel.d.ts +81 -0
- package/dist/next/revalidatePanel.d.ts.map +1 -0
- package/dist/next/revalidatePanel.js +1094 -0
- package/dist/next/revalidatePanel.js.map +1 -0
- package/dist/next/views.d.ts +6 -0
- package/dist/next/views.d.ts.map +1 -1
- package/dist/next/views.js +16 -0
- package/dist/next/views.js.map +1 -1
- package/dist/plugin.d.ts +1 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +3 -0
- package/dist/plugin.js.map +1 -1
- package/package.json +5 -1
|
@@ -0,0 +1,1094 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import "@xyflow/react/dist/style.css";
|
|
4
|
+
import dagre from "@dagrejs/dagre";
|
|
5
|
+
import { Background, Handle, Position, ReactFlow } from "@xyflow/react";
|
|
6
|
+
import { useMemo, useState } from "react";
|
|
7
|
+
import { BustTagCard } from "./client.js";
|
|
8
|
+
const RICH_TEXT_NODE = '*';
|
|
9
|
+
const clock = (iso)=>iso.slice(11, 19);
|
|
10
|
+
const label = (node)=>node === RICH_TEXT_NODE ? 'richText embeds' : node;
|
|
11
|
+
const readName = (read)=>read.label ?? `${read.kind}:${read.collection ?? read.global ?? '?'}${read.as !== undefined ? `:${read.as}` : ''}${read.list ? `:${read.list}` : ''}${read.draft ? ' (draft)' : ''}`;
|
|
12
|
+
/** Which node a read belongs to, and which collection a tag points at (prefix-aware). */ const readNode = (read)=>read.collection ?? (read.global ? `global:${read.global}` : null);
|
|
13
|
+
const tagCollection = (tag, prefix)=>{
|
|
14
|
+
const bare = prefix && tag.startsWith(`${prefix}:`) ? tag.slice(prefix.length + 1) : tag;
|
|
15
|
+
return bare.split(':')[0] ?? bare;
|
|
16
|
+
};
|
|
17
|
+
/** Observed bake-ins as `edited -> renderer` pairs — colors the schema edges by real usage. */ const bakedPairs = (reads, prefix)=>{
|
|
18
|
+
const pairs = new Set();
|
|
19
|
+
for (const read of reads){
|
|
20
|
+
const renderer = readNode(read);
|
|
21
|
+
if (!renderer) continue;
|
|
22
|
+
for (const embed of read.bakedIn)pairs.add(`${tagCollection(embed.tag, prefix)}->${renderer}`);
|
|
23
|
+
}
|
|
24
|
+
return pairs;
|
|
25
|
+
};
|
|
26
|
+
function GraphNode({ data }) {
|
|
27
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
28
|
+
className: `pdtp-flow-node ${data.selected ? 'pdtp-flow-node-active' : ''}`,
|
|
29
|
+
children: [
|
|
30
|
+
/*#__PURE__*/ _jsx(Handle, {
|
|
31
|
+
type: "target",
|
|
32
|
+
position: Position.Left,
|
|
33
|
+
className: "pdtp-flow-handle"
|
|
34
|
+
}),
|
|
35
|
+
/*#__PURE__*/ _jsx("span", {
|
|
36
|
+
className: "pdtp-mono",
|
|
37
|
+
children: data.title
|
|
38
|
+
}),
|
|
39
|
+
/*#__PURE__*/ _jsxs("span", {
|
|
40
|
+
className: "pdtp-flow-badges",
|
|
41
|
+
children: [
|
|
42
|
+
data.kind !== 'collection' ? /*#__PURE__*/ _jsx("em", {
|
|
43
|
+
children: data.kind === 'global' ? 'global' : 'per-doc'
|
|
44
|
+
}) : null,
|
|
45
|
+
data.reads ? /*#__PURE__*/ _jsxs("em", {
|
|
46
|
+
children: [
|
|
47
|
+
data.reads,
|
|
48
|
+
" reads"
|
|
49
|
+
]
|
|
50
|
+
}) : null,
|
|
51
|
+
data.baked ? /*#__PURE__*/ _jsxs("em", {
|
|
52
|
+
className: "pdtp-flow-warn",
|
|
53
|
+
children: [
|
|
54
|
+
data.baked,
|
|
55
|
+
" baked ⚠"
|
|
56
|
+
]
|
|
57
|
+
}) : null
|
|
58
|
+
]
|
|
59
|
+
}),
|
|
60
|
+
/*#__PURE__*/ _jsx(Handle, {
|
|
61
|
+
type: "source",
|
|
62
|
+
position: Position.Right,
|
|
63
|
+
className: "pdtp-flow-handle"
|
|
64
|
+
})
|
|
65
|
+
]
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
const nodeTypes = {
|
|
69
|
+
pdtp: GraphNode
|
|
70
|
+
};
|
|
71
|
+
/** Left→right layered layout: sources are the things you EDIT, targets the surfaces that
|
|
72
|
+
* go stale. Sized by label so dagre spaces long slugs correctly. */ const layout = (nodes, edges)=>{
|
|
73
|
+
const g = new dagre.graphlib.Graph();
|
|
74
|
+
g.setGraph({
|
|
75
|
+
rankdir: 'LR',
|
|
76
|
+
nodesep: 24,
|
|
77
|
+
ranksep: 120
|
|
78
|
+
});
|
|
79
|
+
g.setDefaultEdgeLabel(()=>({}));
|
|
80
|
+
for (const node of nodes)g.setNode(node.id, {
|
|
81
|
+
width: 30 + node.data.title.length * 8 + (node.data.reads ? 60 : 0),
|
|
82
|
+
height: 40
|
|
83
|
+
});
|
|
84
|
+
for (const edge of edges)g.setEdge(edge.source, edge.target);
|
|
85
|
+
dagre.layout(g);
|
|
86
|
+
return nodes.map((node)=>{
|
|
87
|
+
const pos = g.node(node.id);
|
|
88
|
+
return {
|
|
89
|
+
...node,
|
|
90
|
+
position: {
|
|
91
|
+
x: pos.x - pos.width / 2,
|
|
92
|
+
y: pos.y - pos.height / 2
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
function ExploreTab({ data, selected, onSelect }) {
|
|
98
|
+
const { nodes, edges } = useMemo(()=>{
|
|
99
|
+
const baked = bakedPairs(data.reads, data.prefix);
|
|
100
|
+
const readCounts = new Map();
|
|
101
|
+
const bakedCounts = new Map();
|
|
102
|
+
for (const read of data.reads){
|
|
103
|
+
const node = readNode(read);
|
|
104
|
+
if (!node) continue;
|
|
105
|
+
readCounts.set(node, (readCounts.get(node) ?? 0) + 1);
|
|
106
|
+
if (read.bakedIn.length) bakedCounts.set(node, (bakedCounts.get(node) ?? 0) + 1);
|
|
107
|
+
}
|
|
108
|
+
const ids = [
|
|
109
|
+
...data.graph.collections,
|
|
110
|
+
...data.graph.globals.map((g)=>`global:${g}`)
|
|
111
|
+
];
|
|
112
|
+
const hasRichText = data.graph.edges.some((e)=>e.to === RICH_TEXT_NODE);
|
|
113
|
+
const allIds = hasRichText ? [
|
|
114
|
+
...ids,
|
|
115
|
+
RICH_TEXT_NODE
|
|
116
|
+
] : ids;
|
|
117
|
+
const flowNodes = allIds.map((id)=>({
|
|
118
|
+
id,
|
|
119
|
+
type: 'pdtp',
|
|
120
|
+
position: {
|
|
121
|
+
x: 0,
|
|
122
|
+
y: 0
|
|
123
|
+
},
|
|
124
|
+
data: {
|
|
125
|
+
title: label(id),
|
|
126
|
+
kind: id === RICH_TEXT_NODE ? 'richText' : id.startsWith('global:') ? 'global' : 'collection',
|
|
127
|
+
reads: readCounts.get(id) ?? 0,
|
|
128
|
+
baked: bakedCounts.get(id) ?? 0,
|
|
129
|
+
selected: selected === id
|
|
130
|
+
}
|
|
131
|
+
}));
|
|
132
|
+
// Direction of staleness: editing `edge.to` makes `edge.from` stale — source is the
|
|
133
|
+
// edited side so the graph reads left (cause) → right (effect).
|
|
134
|
+
const flowEdges = data.graph.edges.map((edge)=>{
|
|
135
|
+
const isBaked = baked.has(`${edge.to}->${edge.from}`);
|
|
136
|
+
const active = selected !== null && (edge.to === selected || edge.from === selected);
|
|
137
|
+
const dimmed = selected !== null && !active;
|
|
138
|
+
return {
|
|
139
|
+
id: `${edge.from}|${edge.via}|${edge.to}`,
|
|
140
|
+
source: edge.to,
|
|
141
|
+
target: edge.from,
|
|
142
|
+
animated: isBaked && !dimmed,
|
|
143
|
+
label: active ? `${edge.via} (${edge.kind})` : undefined,
|
|
144
|
+
style: {
|
|
145
|
+
stroke: isBaked ? 'var(--pdtp-warn)' : 'oklch(1 0 0 / 30%)',
|
|
146
|
+
strokeWidth: active ? 2 : 1.25,
|
|
147
|
+
strokeDasharray: edge.kind === 'richText' || edge.to === RICH_TEXT_NODE ? '5 5' : undefined,
|
|
148
|
+
opacity: dimmed ? 0.15 : 1
|
|
149
|
+
},
|
|
150
|
+
labelStyle: {
|
|
151
|
+
fill: 'var(--pdtp-fg)',
|
|
152
|
+
fontSize: 11
|
|
153
|
+
},
|
|
154
|
+
labelBgStyle: {
|
|
155
|
+
fill: 'var(--pdtp-card)'
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
});
|
|
159
|
+
return {
|
|
160
|
+
nodes: layout(flowNodes, flowEdges),
|
|
161
|
+
edges: flowEdges
|
|
162
|
+
};
|
|
163
|
+
}, [
|
|
164
|
+
data,
|
|
165
|
+
selected
|
|
166
|
+
]);
|
|
167
|
+
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
168
|
+
children: [
|
|
169
|
+
/*#__PURE__*/ _jsx("div", {
|
|
170
|
+
className: "pdtp-flow",
|
|
171
|
+
children: /*#__PURE__*/ _jsx(ReactFlow, {
|
|
172
|
+
nodes: nodes,
|
|
173
|
+
edges: edges,
|
|
174
|
+
nodeTypes: nodeTypes,
|
|
175
|
+
colorMode: "dark",
|
|
176
|
+
fitView: true,
|
|
177
|
+
minZoom: 0.3,
|
|
178
|
+
nodesDraggable: true,
|
|
179
|
+
nodesConnectable: false,
|
|
180
|
+
proOptions: {
|
|
181
|
+
hideAttribution: true
|
|
182
|
+
},
|
|
183
|
+
onNodeClick: (_, node)=>onSelect(selected === node.id ? null : node.id),
|
|
184
|
+
onPaneClick: ()=>onSelect(null),
|
|
185
|
+
children: /*#__PURE__*/ _jsx(Background, {
|
|
186
|
+
gap: 24
|
|
187
|
+
})
|
|
188
|
+
})
|
|
189
|
+
}),
|
|
190
|
+
/*#__PURE__*/ _jsxs("p", {
|
|
191
|
+
className: "pdtp-note",
|
|
192
|
+
style: {
|
|
193
|
+
marginTop: 8
|
|
194
|
+
},
|
|
195
|
+
children: [
|
|
196
|
+
"Left → right: editing a node makes its right-hand neighbors stale. ",
|
|
197
|
+
/*#__PURE__*/ _jsx("span", {
|
|
198
|
+
className: "pdtp-warn",
|
|
199
|
+
children: "Amber animated"
|
|
200
|
+
}),
|
|
201
|
+
" edges are OBSERVED bake-ins (populated content — the anti-pattern); grey edges are id-references or not yet observed; dashed = richText (per-doc). Click a node for its full story."
|
|
202
|
+
]
|
|
203
|
+
}),
|
|
204
|
+
selected ? /*#__PURE__*/ _jsx(NodeDetail, {
|
|
205
|
+
node: selected,
|
|
206
|
+
data: data
|
|
207
|
+
}) : null
|
|
208
|
+
]
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* The focused, evidence-based answer for one node — three layers, never conflated:
|
|
213
|
+
*
|
|
214
|
+
* 1. **What a write here busts** — tags, by event kind. Facts from the decision table.
|
|
215
|
+
* 2. **What observably purges right now** — the cached entries that actually carry those
|
|
216
|
+
* tags. This is the truth of "what happens if I edit/create a doc here today".
|
|
217
|
+
* 3. **Potential coupling** — schema edges. A reference alone never propagates a purge
|
|
218
|
+
* (ids are stable); an edge only becomes real when a getter is OBSERVED baking the
|
|
219
|
+
* content in. Each edge is labeled accordingly.
|
|
220
|
+
*/ function NodeDetail({ node, data }) {
|
|
221
|
+
const { graph, rules, reads, prefix } = data;
|
|
222
|
+
const p = prefix ? `${prefix}:` : '';
|
|
223
|
+
const isGlobal = node.startsWith('global:');
|
|
224
|
+
const slug = isGlobal ? node.slice('global:'.length) : node;
|
|
225
|
+
const settings = data.settings[slug];
|
|
226
|
+
const baked = bakedPairs(reads, prefix);
|
|
227
|
+
const makesStale = graph.edges.filter((e)=>e.to === node);
|
|
228
|
+
const staleWhen = graph.edges.filter((e)=>e.from === node);
|
|
229
|
+
const ownRules = rules.filter((r)=>r.on === slug);
|
|
230
|
+
const scopes = Object.entries(settings?.lists ?? {});
|
|
231
|
+
// Observed: entries carrying this collection's DOC tags (own entries + bake-ins)…
|
|
232
|
+
const docTagCarriers = new Map();
|
|
233
|
+
// …and entries carrying its LIST tags (what membership events actually purge).
|
|
234
|
+
const listCarriers = reads.filter((read)=>read.kind === 'ids' && read.collection === slug);
|
|
235
|
+
if (!isGlobal && node !== RICH_TEXT_NODE) {
|
|
236
|
+
for (const read of reads){
|
|
237
|
+
for (const tag of [
|
|
238
|
+
...read.staticTags,
|
|
239
|
+
...read.depTags
|
|
240
|
+
]){
|
|
241
|
+
if (!tag.startsWith(`${p}${slug}:`) || tag.startsWith(`${p}${slug}:list:`) || tag.endsWith(':draft')) continue;
|
|
242
|
+
const isBaked = read.bakedIn.some((b)=>b.tag === tag);
|
|
243
|
+
docTagCarriers.set(tag, [
|
|
244
|
+
...docTagCarriers.get(tag) ?? [],
|
|
245
|
+
{
|
|
246
|
+
name: readName(read),
|
|
247
|
+
baked: isBaked
|
|
248
|
+
}
|
|
249
|
+
]);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if (node === RICH_TEXT_NODE) {
|
|
254
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
255
|
+
className: "pdtp-card",
|
|
256
|
+
style: {
|
|
257
|
+
marginTop: 16
|
|
258
|
+
},
|
|
259
|
+
children: [
|
|
260
|
+
/*#__PURE__*/ _jsxs("h2", {
|
|
261
|
+
children: [
|
|
262
|
+
"richText embeds ",
|
|
263
|
+
/*#__PURE__*/ _jsx("span", {
|
|
264
|
+
className: "pdtp-kind",
|
|
265
|
+
children: "per-doc"
|
|
266
|
+
})
|
|
267
|
+
]
|
|
268
|
+
}),
|
|
269
|
+
/*#__PURE__*/ _jsx("p", {
|
|
270
|
+
className: "pdtp-note",
|
|
271
|
+
style: {
|
|
272
|
+
margin: 0
|
|
273
|
+
},
|
|
274
|
+
children: "Upload/relationship nodes inside rich text resolve per document at read time. Populated nodes bake content in and tag the entry (shown as bake-ins on the owning read); id-only nodes are references — render them through id-keyed getters."
|
|
275
|
+
})
|
|
276
|
+
]
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
// The getters the CODE declares for this node (live source scan), matched against
|
|
280
|
+
// runtime observation so each shows whether it has materialized yet.
|
|
281
|
+
const helperKind = {
|
|
282
|
+
cacheDoc: 'doc',
|
|
283
|
+
cacheIds: 'ids',
|
|
284
|
+
cacheGlobal: 'global'
|
|
285
|
+
};
|
|
286
|
+
const nodeGetters = data.getters.filter((g)=>g.slug === slug && (isGlobal ? g.helper === 'cacheGlobal' : g.helper !== 'cacheGlobal')).map((g)=>{
|
|
287
|
+
const observed = reads.find((read)=>(read.collection ?? read.global) === slug && read.kind === helperKind[g.helper] && (read.list ?? undefined) === (g.list ?? undefined) && (g.label === undefined || read.label === g.label));
|
|
288
|
+
return {
|
|
289
|
+
...g,
|
|
290
|
+
observed
|
|
291
|
+
};
|
|
292
|
+
});
|
|
293
|
+
const vocabulary = isGlobal ? [
|
|
294
|
+
`${p}global:${slug}`,
|
|
295
|
+
`${p}global:${slug}:draft`
|
|
296
|
+
] : [
|
|
297
|
+
`${p}${slug}:{id}`,
|
|
298
|
+
...settings?.idField ? [
|
|
299
|
+
`${p}${slug}:{${settings.idField}}`
|
|
300
|
+
] : [],
|
|
301
|
+
`${p}${slug}`,
|
|
302
|
+
...scopes.map(([scope])=>`${p}${slug}:list:${scope}`),
|
|
303
|
+
'+ :draft variants'
|
|
304
|
+
];
|
|
305
|
+
return /*#__PURE__*/ _jsxs("div", {
|
|
306
|
+
className: "pdtp-card",
|
|
307
|
+
style: {
|
|
308
|
+
marginTop: 16
|
|
309
|
+
},
|
|
310
|
+
children: [
|
|
311
|
+
/*#__PURE__*/ _jsxs("h2", {
|
|
312
|
+
children: [
|
|
313
|
+
label(node),
|
|
314
|
+
" ",
|
|
315
|
+
/*#__PURE__*/ _jsx("span", {
|
|
316
|
+
className: "pdtp-kind",
|
|
317
|
+
children: isGlobal ? 'global' : 'collection'
|
|
318
|
+
})
|
|
319
|
+
]
|
|
320
|
+
}),
|
|
321
|
+
/*#__PURE__*/ _jsxs("p", {
|
|
322
|
+
className: "pdtp-note",
|
|
323
|
+
style: {
|
|
324
|
+
margin: '0 0 12px'
|
|
325
|
+
},
|
|
326
|
+
children: [
|
|
327
|
+
"Tags:",
|
|
328
|
+
' ',
|
|
329
|
+
vocabulary.map((tag)=>/*#__PURE__*/ _jsx("span", {
|
|
330
|
+
className: "pdtp-code",
|
|
331
|
+
style: {
|
|
332
|
+
marginRight: 6
|
|
333
|
+
},
|
|
334
|
+
children: tag
|
|
335
|
+
}, tag))
|
|
336
|
+
]
|
|
337
|
+
}),
|
|
338
|
+
/*#__PURE__*/ _jsx("h3", {
|
|
339
|
+
className: "pdtp-rev-subhead",
|
|
340
|
+
children: "A write here busts…"
|
|
341
|
+
}),
|
|
342
|
+
/*#__PURE__*/ _jsx("ul", {
|
|
343
|
+
className: "pdtp-rev-list",
|
|
344
|
+
children: isGlobal ? /*#__PURE__*/ _jsxs("li", {
|
|
345
|
+
children: [
|
|
346
|
+
"any save → ",
|
|
347
|
+
/*#__PURE__*/ _jsx("span", {
|
|
348
|
+
className: "pdtp-code",
|
|
349
|
+
children: `${p}global:${slug}`
|
|
350
|
+
})
|
|
351
|
+
]
|
|
352
|
+
}) : /*#__PURE__*/ _jsxs(_Fragment, {
|
|
353
|
+
children: [
|
|
354
|
+
/*#__PURE__*/ _jsxs("li", {
|
|
355
|
+
children: [
|
|
356
|
+
"editing a doc → ",
|
|
357
|
+
/*#__PURE__*/ _jsx("span", {
|
|
358
|
+
className: "pdtp-code",
|
|
359
|
+
children: `${p}${slug}:{id}`
|
|
360
|
+
}),
|
|
361
|
+
settings?.idField ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
362
|
+
children: [
|
|
363
|
+
' ',
|
|
364
|
+
"+ ",
|
|
365
|
+
/*#__PURE__*/ _jsx("span", {
|
|
366
|
+
className: "pdtp-code",
|
|
367
|
+
children: `${p}${slug}:{${settings.idField}}`
|
|
368
|
+
})
|
|
369
|
+
]
|
|
370
|
+
}) : null,
|
|
371
|
+
' ',
|
|
372
|
+
/*#__PURE__*/ _jsx("span", {
|
|
373
|
+
className: "pdtp-muted",
|
|
374
|
+
children: "— that one doc, nothing else"
|
|
375
|
+
})
|
|
376
|
+
]
|
|
377
|
+
}),
|
|
378
|
+
/*#__PURE__*/ _jsxs("li", {
|
|
379
|
+
children: [
|
|
380
|
+
"create / delete / publish / unpublish → also ",
|
|
381
|
+
/*#__PURE__*/ _jsx("span", {
|
|
382
|
+
className: "pdtp-code",
|
|
383
|
+
children: `${p}${slug}`
|
|
384
|
+
}),
|
|
385
|
+
scopes.map(([scope])=>/*#__PURE__*/ _jsxs("span", {
|
|
386
|
+
children: [
|
|
387
|
+
' ',
|
|
388
|
+
"+ ",
|
|
389
|
+
/*#__PURE__*/ _jsx("span", {
|
|
390
|
+
className: "pdtp-code",
|
|
391
|
+
children: `${p}${slug}:list:${scope}`
|
|
392
|
+
})
|
|
393
|
+
]
|
|
394
|
+
}, scope)),
|
|
395
|
+
' ',
|
|
396
|
+
/*#__PURE__*/ _jsx("span", {
|
|
397
|
+
className: "pdtp-muted",
|
|
398
|
+
children: "— membership changed"
|
|
399
|
+
})
|
|
400
|
+
]
|
|
401
|
+
}),
|
|
402
|
+
scopes.map(([scope, fields])=>/*#__PURE__*/ _jsxs("li", {
|
|
403
|
+
children: [
|
|
404
|
+
"editing ",
|
|
405
|
+
/*#__PURE__*/ _jsx("span", {
|
|
406
|
+
className: "pdtp-mono",
|
|
407
|
+
children: fields.join(' / ')
|
|
408
|
+
}),
|
|
409
|
+
" → also",
|
|
410
|
+
' ',
|
|
411
|
+
/*#__PURE__*/ _jsx("span", {
|
|
412
|
+
className: "pdtp-code",
|
|
413
|
+
children: `${p}${slug}:list:${scope}`
|
|
414
|
+
}),
|
|
415
|
+
" ",
|
|
416
|
+
/*#__PURE__*/ _jsx("span", {
|
|
417
|
+
className: "pdtp-muted",
|
|
418
|
+
children: "— order/filter changed"
|
|
419
|
+
})
|
|
420
|
+
]
|
|
421
|
+
}, scope)),
|
|
422
|
+
settings?.extraTags.length ? /*#__PURE__*/ _jsxs("li", {
|
|
423
|
+
children: [
|
|
424
|
+
"every published write → also ",
|
|
425
|
+
/*#__PURE__*/ _jsx("span", {
|
|
426
|
+
className: "pdtp-mono",
|
|
427
|
+
children: settings.extraTags.join(', ')
|
|
428
|
+
})
|
|
429
|
+
]
|
|
430
|
+
}) : null,
|
|
431
|
+
ownRules.length ? /*#__PURE__*/ _jsxs("li", {
|
|
432
|
+
children: [
|
|
433
|
+
"rules → also ",
|
|
434
|
+
/*#__PURE__*/ _jsx("span", {
|
|
435
|
+
className: "pdtp-mono",
|
|
436
|
+
children: ownRules.flatMap((r)=>r.bust).join(', ')
|
|
437
|
+
})
|
|
438
|
+
]
|
|
439
|
+
}) : null
|
|
440
|
+
]
|
|
441
|
+
})
|
|
442
|
+
}),
|
|
443
|
+
/*#__PURE__*/ _jsx("h3", {
|
|
444
|
+
className: "pdtp-rev-subhead",
|
|
445
|
+
style: {
|
|
446
|
+
marginTop: 14
|
|
447
|
+
},
|
|
448
|
+
children: "…which currently purges (observed)"
|
|
449
|
+
}),
|
|
450
|
+
docTagCarriers.size ? /*#__PURE__*/ _jsx("ul", {
|
|
451
|
+
className: "pdtp-rev-list",
|
|
452
|
+
children: [
|
|
453
|
+
...docTagCarriers.entries()
|
|
454
|
+
].slice(0, 10).map(([tag, carriers])=>/*#__PURE__*/ _jsxs("li", {
|
|
455
|
+
children: [
|
|
456
|
+
/*#__PURE__*/ _jsx("span", {
|
|
457
|
+
className: "pdtp-code",
|
|
458
|
+
children: tag
|
|
459
|
+
}),
|
|
460
|
+
" →",
|
|
461
|
+
' ',
|
|
462
|
+
carriers.map((c, i)=>/*#__PURE__*/ _jsxs("span", {
|
|
463
|
+
children: [
|
|
464
|
+
i > 0 ? ', ' : '',
|
|
465
|
+
c.name,
|
|
466
|
+
c.baked ? /*#__PURE__*/ _jsx("span", {
|
|
467
|
+
className: "pdtp-warn",
|
|
468
|
+
children: " (baked-in ⚠)"
|
|
469
|
+
}) : /*#__PURE__*/ _jsx("span", {
|
|
470
|
+
className: "pdtp-muted",
|
|
471
|
+
children: " (own entry ✓)"
|
|
472
|
+
})
|
|
473
|
+
]
|
|
474
|
+
}, c.name))
|
|
475
|
+
]
|
|
476
|
+
}, tag))
|
|
477
|
+
}) : !isGlobal ? /*#__PURE__*/ _jsxs("p", {
|
|
478
|
+
className: "pdtp-muted",
|
|
479
|
+
style: {
|
|
480
|
+
margin: 0
|
|
481
|
+
},
|
|
482
|
+
children: [
|
|
483
|
+
"No cached entries carry ",
|
|
484
|
+
slug,
|
|
485
|
+
" doc tags yet — editing a ",
|
|
486
|
+
slug,
|
|
487
|
+
" doc right now purges nothing (its entry materializes, tagged, on first read)."
|
|
488
|
+
]
|
|
489
|
+
}) : null,
|
|
490
|
+
!isGlobal ? /*#__PURE__*/ _jsx("p", {
|
|
491
|
+
className: "pdtp-note",
|
|
492
|
+
children: listCarriers.length ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
493
|
+
children: [
|
|
494
|
+
"Membership events purge: ",
|
|
495
|
+
listCarriers.map((read)=>readName(read)).join(', '),
|
|
496
|
+
' — ',
|
|
497
|
+
"the id-lists re-query; every unchanged card entry survives."
|
|
498
|
+
]
|
|
499
|
+
}) : /*#__PURE__*/ _jsxs(_Fragment, {
|
|
500
|
+
children: [
|
|
501
|
+
"Membership events currently purge ",
|
|
502
|
+
/*#__PURE__*/ _jsx("strong", {
|
|
503
|
+
children: "nothing"
|
|
504
|
+
}),
|
|
505
|
+
" — no id-list read carries",
|
|
506
|
+
' ',
|
|
507
|
+
/*#__PURE__*/ _jsx("span", {
|
|
508
|
+
className: "pdtp-code",
|
|
509
|
+
children: `${p}${slug}`
|
|
510
|
+
}),
|
|
511
|
+
" or a scope yet. Creating or deleting a ",
|
|
512
|
+
slug,
|
|
513
|
+
" doc is invisible to the cache until a `cacheIds` read exists."
|
|
514
|
+
]
|
|
515
|
+
})
|
|
516
|
+
}) : null,
|
|
517
|
+
nodeGetters.length ? /*#__PURE__*/ _jsxs("div", {
|
|
518
|
+
style: {
|
|
519
|
+
marginTop: 14
|
|
520
|
+
},
|
|
521
|
+
children: [
|
|
522
|
+
/*#__PURE__*/ _jsx("h3", {
|
|
523
|
+
className: "pdtp-rev-subhead",
|
|
524
|
+
children: "Getters in your code"
|
|
525
|
+
}),
|
|
526
|
+
/*#__PURE__*/ _jsx("ul", {
|
|
527
|
+
className: "pdtp-rev-list",
|
|
528
|
+
children: nodeGetters.map((g)=>/*#__PURE__*/ _jsxs("li", {
|
|
529
|
+
children: [
|
|
530
|
+
/*#__PURE__*/ _jsx("strong", {
|
|
531
|
+
children: g.getter ? `${g.getter}()` : g.label ?? g.helper
|
|
532
|
+
}),
|
|
533
|
+
' ',
|
|
534
|
+
/*#__PURE__*/ _jsxs("span", {
|
|
535
|
+
className: "pdtp-mono pdtp-muted",
|
|
536
|
+
children: [
|
|
537
|
+
g.helper,
|
|
538
|
+
g.list ? ` · list:${g.list}` : '',
|
|
539
|
+
" · ",
|
|
540
|
+
g.file,
|
|
541
|
+
":",
|
|
542
|
+
g.line
|
|
543
|
+
]
|
|
544
|
+
}),
|
|
545
|
+
' ',
|
|
546
|
+
g.observed ? /*#__PURE__*/ _jsxs("span", {
|
|
547
|
+
className: "pdtp-muted",
|
|
548
|
+
children: [
|
|
549
|
+
"materialized ×",
|
|
550
|
+
g.observed.count,
|
|
551
|
+
g.observed.bakedIn.length ? /*#__PURE__*/ _jsxs("span", {
|
|
552
|
+
className: "pdtp-warn",
|
|
553
|
+
children: [
|
|
554
|
+
" · ",
|
|
555
|
+
g.observed.bakedIn.length,
|
|
556
|
+
" baked-in ⚠"
|
|
557
|
+
]
|
|
558
|
+
}) : null,
|
|
559
|
+
g.observed.undeclared ? /*#__PURE__*/ _jsx("span", {
|
|
560
|
+
className: "pdtp-warn",
|
|
561
|
+
children: " · undeclared scope!"
|
|
562
|
+
}) : null
|
|
563
|
+
]
|
|
564
|
+
}) : /*#__PURE__*/ _jsx("span", {
|
|
565
|
+
className: "pdtp-muted",
|
|
566
|
+
children: "not yet observed"
|
|
567
|
+
})
|
|
568
|
+
]
|
|
569
|
+
}, `${g.file}:${g.line}`))
|
|
570
|
+
}),
|
|
571
|
+
/*#__PURE__*/ _jsx("p", {
|
|
572
|
+
className: "pdtp-note",
|
|
573
|
+
children: "Found by scanning your source for cache-helper calls (literal slugs only) — the payload-icons pattern."
|
|
574
|
+
})
|
|
575
|
+
]
|
|
576
|
+
}) : null,
|
|
577
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
578
|
+
className: "pdtp-rev-cols",
|
|
579
|
+
style: {
|
|
580
|
+
marginTop: 14
|
|
581
|
+
},
|
|
582
|
+
children: [
|
|
583
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
584
|
+
children: [
|
|
585
|
+
/*#__PURE__*/ _jsx("h3", {
|
|
586
|
+
className: "pdtp-rev-subhead",
|
|
587
|
+
children: "Can be referenced by (schema)"
|
|
588
|
+
}),
|
|
589
|
+
makesStale.length ? /*#__PURE__*/ _jsx("ul", {
|
|
590
|
+
className: "pdtp-rev-list",
|
|
591
|
+
children: makesStale.map((edge)=>{
|
|
592
|
+
const observedBaked = baked.has(`${node}->${edge.from}`);
|
|
593
|
+
return /*#__PURE__*/ _jsxs("li", {
|
|
594
|
+
children: [
|
|
595
|
+
/*#__PURE__*/ _jsx("strong", {
|
|
596
|
+
children: edge.from
|
|
597
|
+
}),
|
|
598
|
+
' ',
|
|
599
|
+
/*#__PURE__*/ _jsxs("span", {
|
|
600
|
+
className: "pdtp-mono pdtp-muted",
|
|
601
|
+
children: [
|
|
602
|
+
"via ",
|
|
603
|
+
edge.via,
|
|
604
|
+
" (",
|
|
605
|
+
edge.kind,
|
|
606
|
+
")"
|
|
607
|
+
]
|
|
608
|
+
}),
|
|
609
|
+
' ',
|
|
610
|
+
observedBaked ? /*#__PURE__*/ _jsx("span", {
|
|
611
|
+
className: "pdtp-warn",
|
|
612
|
+
children: "baked-in ⚠ — edits here DO purge those entries"
|
|
613
|
+
}) : /*#__PURE__*/ _jsx("span", {
|
|
614
|
+
className: "pdtp-muted",
|
|
615
|
+
children: "reference only — no purge propagation"
|
|
616
|
+
})
|
|
617
|
+
]
|
|
618
|
+
}, `${edge.from}-${edge.via}`);
|
|
619
|
+
})
|
|
620
|
+
}) : /*#__PURE__*/ _jsx("p", {
|
|
621
|
+
className: "pdtp-muted",
|
|
622
|
+
style: {
|
|
623
|
+
margin: 0
|
|
624
|
+
},
|
|
625
|
+
children: "No schema field references it."
|
|
626
|
+
})
|
|
627
|
+
]
|
|
628
|
+
}),
|
|
629
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
630
|
+
children: [
|
|
631
|
+
/*#__PURE__*/ _jsx("h3", {
|
|
632
|
+
className: "pdtp-rev-subhead",
|
|
633
|
+
children: "References (schema)"
|
|
634
|
+
}),
|
|
635
|
+
staleWhen.length ? /*#__PURE__*/ _jsx("ul", {
|
|
636
|
+
className: "pdtp-rev-list",
|
|
637
|
+
children: staleWhen.map((edge)=>{
|
|
638
|
+
const observedBaked = baked.has(`${edge.to}->${node}`);
|
|
639
|
+
return /*#__PURE__*/ _jsxs("li", {
|
|
640
|
+
children: [
|
|
641
|
+
/*#__PURE__*/ _jsx("strong", {
|
|
642
|
+
children: label(edge.to)
|
|
643
|
+
}),
|
|
644
|
+
' ',
|
|
645
|
+
/*#__PURE__*/ _jsxs("span", {
|
|
646
|
+
className: "pdtp-mono pdtp-muted",
|
|
647
|
+
children: [
|
|
648
|
+
"via ",
|
|
649
|
+
edge.via,
|
|
650
|
+
" (",
|
|
651
|
+
edge.kind,
|
|
652
|
+
")"
|
|
653
|
+
]
|
|
654
|
+
}),
|
|
655
|
+
' ',
|
|
656
|
+
observedBaked ? /*#__PURE__*/ _jsxs("span", {
|
|
657
|
+
className: "pdtp-warn",
|
|
658
|
+
children: [
|
|
659
|
+
"baked-in ⚠ — its edits purge ",
|
|
660
|
+
slug,
|
|
661
|
+
" entries"
|
|
662
|
+
]
|
|
663
|
+
}) : /*#__PURE__*/ _jsxs("span", {
|
|
664
|
+
className: "pdtp-muted",
|
|
665
|
+
children: [
|
|
666
|
+
"id only — its edits never touch ",
|
|
667
|
+
slug,
|
|
668
|
+
" entries"
|
|
669
|
+
]
|
|
670
|
+
})
|
|
671
|
+
]
|
|
672
|
+
}, `${edge.to}-${edge.via}`);
|
|
673
|
+
})
|
|
674
|
+
}) : /*#__PURE__*/ _jsx("p", {
|
|
675
|
+
className: "pdtp-muted",
|
|
676
|
+
style: {
|
|
677
|
+
margin: 0
|
|
678
|
+
},
|
|
679
|
+
children: "References nothing."
|
|
680
|
+
})
|
|
681
|
+
]
|
|
682
|
+
})
|
|
683
|
+
]
|
|
684
|
+
}),
|
|
685
|
+
/*#__PURE__*/ _jsxs("p", {
|
|
686
|
+
className: "pdtp-note",
|
|
687
|
+
children: [
|
|
688
|
+
"A reference (id) never couples two entries — the id is stable, and the referenced doc's freshness lives in its own id-keyed entry. Only",
|
|
689
|
+
' ',
|
|
690
|
+
/*#__PURE__*/ _jsx("span", {
|
|
691
|
+
className: "pdtp-warn",
|
|
692
|
+
children: "baked-in ⚠"
|
|
693
|
+
}),
|
|
694
|
+
" rows propagate purges; refactor those getters to shrink the blast radius."
|
|
695
|
+
]
|
|
696
|
+
})
|
|
697
|
+
]
|
|
698
|
+
});
|
|
699
|
+
}
|
|
700
|
+
// ---------------------------------------------------------------------------
|
|
701
|
+
// Fields tab — the per-field blast-radius table
|
|
702
|
+
// ---------------------------------------------------------------------------
|
|
703
|
+
function FieldsTab({ data }) {
|
|
704
|
+
const entries = Object.entries(data.settings);
|
|
705
|
+
if (!entries.length) return /*#__PURE__*/ _jsx("p", {
|
|
706
|
+
className: "pdtp-muted",
|
|
707
|
+
children: "No collections registered."
|
|
708
|
+
});
|
|
709
|
+
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
710
|
+
children: [
|
|
711
|
+
entries.map(([slug, s])=>/*#__PURE__*/ _jsxs("div", {
|
|
712
|
+
className: "pdtp-card",
|
|
713
|
+
style: {
|
|
714
|
+
marginBottom: 14
|
|
715
|
+
},
|
|
716
|
+
children: [
|
|
717
|
+
/*#__PURE__*/ _jsxs("h2", {
|
|
718
|
+
children: [
|
|
719
|
+
slug,
|
|
720
|
+
' ',
|
|
721
|
+
/*#__PURE__*/ _jsx("span", {
|
|
722
|
+
className: "pdtp-kind",
|
|
723
|
+
children: Object.keys(s.lists).length ? `lists: ${Object.keys(s.lists).join(', ')}` : 'no declared lists'
|
|
724
|
+
})
|
|
725
|
+
]
|
|
726
|
+
}),
|
|
727
|
+
/*#__PURE__*/ _jsxs("table", {
|
|
728
|
+
className: "pdtp-table",
|
|
729
|
+
children: [
|
|
730
|
+
/*#__PURE__*/ _jsx("thead", {
|
|
731
|
+
children: /*#__PURE__*/ _jsxs("tr", {
|
|
732
|
+
children: [
|
|
733
|
+
/*#__PURE__*/ _jsx("th", {
|
|
734
|
+
children: "editing field…"
|
|
735
|
+
}),
|
|
736
|
+
/*#__PURE__*/ _jsx("th", {
|
|
737
|
+
children: "busts"
|
|
738
|
+
})
|
|
739
|
+
]
|
|
740
|
+
})
|
|
741
|
+
}),
|
|
742
|
+
/*#__PURE__*/ _jsx("tbody", {
|
|
743
|
+
children: s.fields.map((field)=>{
|
|
744
|
+
const scopes = Object.entries(s.lists).filter(([, fields])=>fields.includes(field)).map(([scope])=>scope);
|
|
745
|
+
return /*#__PURE__*/ _jsxs("tr", {
|
|
746
|
+
children: [
|
|
747
|
+
/*#__PURE__*/ _jsx("td", {
|
|
748
|
+
className: "pdtp-mono",
|
|
749
|
+
children: field
|
|
750
|
+
}),
|
|
751
|
+
/*#__PURE__*/ _jsxs("td", {
|
|
752
|
+
className: "pdtp-mono",
|
|
753
|
+
children: [
|
|
754
|
+
"doc",
|
|
755
|
+
field === s.idField ? ' + alias (old & new)' : '',
|
|
756
|
+
scopes.length ? ` + ${scopes.map((scope)=>`list:${scope}`).join(' + ')}` : ''
|
|
757
|
+
]
|
|
758
|
+
})
|
|
759
|
+
]
|
|
760
|
+
}, field);
|
|
761
|
+
})
|
|
762
|
+
})
|
|
763
|
+
]
|
|
764
|
+
}),
|
|
765
|
+
/*#__PURE__*/ _jsxs("p", {
|
|
766
|
+
className: "pdtp-note",
|
|
767
|
+
children: [
|
|
768
|
+
"Create / delete / publish / unpublish additionally bust ",
|
|
769
|
+
/*#__PURE__*/ _jsx("span", {
|
|
770
|
+
className: "pdtp-code",
|
|
771
|
+
children: slug
|
|
772
|
+
}),
|
|
773
|
+
Object.keys(s.lists).map((scope)=>/*#__PURE__*/ _jsxs("span", {
|
|
774
|
+
children: [
|
|
775
|
+
' ',
|
|
776
|
+
"+ ",
|
|
777
|
+
/*#__PURE__*/ _jsx("span", {
|
|
778
|
+
className: "pdtp-code",
|
|
779
|
+
children: `${slug}:list:${scope}`
|
|
780
|
+
})
|
|
781
|
+
]
|
|
782
|
+
}, scope)),
|
|
783
|
+
s.extraTags.length ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
784
|
+
children: [
|
|
785
|
+
" · every published write also busts ",
|
|
786
|
+
s.extraTags.join(', ')
|
|
787
|
+
]
|
|
788
|
+
}) : null
|
|
789
|
+
]
|
|
790
|
+
})
|
|
791
|
+
]
|
|
792
|
+
}, slug)),
|
|
793
|
+
data.rules.length ? /*#__PURE__*/ _jsxs("div", {
|
|
794
|
+
className: "pdtp-section",
|
|
795
|
+
children: [
|
|
796
|
+
/*#__PURE__*/ _jsxs("h2", {
|
|
797
|
+
children: [
|
|
798
|
+
"Manual rules ",
|
|
799
|
+
/*#__PURE__*/ _jsx("span", {
|
|
800
|
+
className: "pdtp-kind",
|
|
801
|
+
children: data.rules.length
|
|
802
|
+
})
|
|
803
|
+
]
|
|
804
|
+
}),
|
|
805
|
+
/*#__PURE__*/ _jsx("table", {
|
|
806
|
+
className: "pdtp-table",
|
|
807
|
+
children: /*#__PURE__*/ _jsx("tbody", {
|
|
808
|
+
children: data.rules.map((rule)=>/*#__PURE__*/ _jsxs("tr", {
|
|
809
|
+
children: [
|
|
810
|
+
/*#__PURE__*/ _jsx("td", {
|
|
811
|
+
className: "pdtp-code",
|
|
812
|
+
children: rule.on
|
|
813
|
+
}),
|
|
814
|
+
/*#__PURE__*/ _jsxs("td", {
|
|
815
|
+
className: "pdtp-mono",
|
|
816
|
+
children: [
|
|
817
|
+
"busts ",
|
|
818
|
+
rule.bust.join(', ')
|
|
819
|
+
]
|
|
820
|
+
}),
|
|
821
|
+
/*#__PURE__*/ _jsx("td", {
|
|
822
|
+
className: "pdtp-muted",
|
|
823
|
+
children: rule.whenFields ? `when ${rule.whenFields.join(', ')} change` : 'always'
|
|
824
|
+
})
|
|
825
|
+
]
|
|
826
|
+
}, `${rule.on}-${rule.bust.join(',')}`))
|
|
827
|
+
})
|
|
828
|
+
})
|
|
829
|
+
]
|
|
830
|
+
}) : null
|
|
831
|
+
]
|
|
832
|
+
});
|
|
833
|
+
}
|
|
834
|
+
// ---------------------------------------------------------------------------
|
|
835
|
+
// Reads + Events tabs
|
|
836
|
+
// ---------------------------------------------------------------------------
|
|
837
|
+
function ReadsTab({ data }) {
|
|
838
|
+
return data.reads.length ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
839
|
+
children: [
|
|
840
|
+
/*#__PURE__*/ _jsxs("table", {
|
|
841
|
+
className: "pdtp-table",
|
|
842
|
+
children: [
|
|
843
|
+
/*#__PURE__*/ _jsx("thead", {
|
|
844
|
+
children: /*#__PURE__*/ _jsxs("tr", {
|
|
845
|
+
children: [
|
|
846
|
+
/*#__PURE__*/ _jsx("th", {
|
|
847
|
+
children: "read"
|
|
848
|
+
}),
|
|
849
|
+
/*#__PURE__*/ _jsx("th", {
|
|
850
|
+
children: "tags"
|
|
851
|
+
}),
|
|
852
|
+
/*#__PURE__*/ _jsx("th", {
|
|
853
|
+
children: "health"
|
|
854
|
+
}),
|
|
855
|
+
/*#__PURE__*/ _jsx("th", {
|
|
856
|
+
children: "seen"
|
|
857
|
+
}),
|
|
858
|
+
/*#__PURE__*/ _jsx("th", {
|
|
859
|
+
children: "last"
|
|
860
|
+
})
|
|
861
|
+
]
|
|
862
|
+
})
|
|
863
|
+
}),
|
|
864
|
+
/*#__PURE__*/ _jsx("tbody", {
|
|
865
|
+
children: data.reads.map((read)=>{
|
|
866
|
+
const all = [
|
|
867
|
+
...read.staticTags,
|
|
868
|
+
...read.depTags
|
|
869
|
+
];
|
|
870
|
+
return /*#__PURE__*/ _jsxs("tr", {
|
|
871
|
+
children: [
|
|
872
|
+
/*#__PURE__*/ _jsx("td", {
|
|
873
|
+
className: "pdtp-code",
|
|
874
|
+
children: readName(read)
|
|
875
|
+
}),
|
|
876
|
+
/*#__PURE__*/ _jsx("td", {
|
|
877
|
+
className: "pdtp-mono",
|
|
878
|
+
title: all.join('\n'),
|
|
879
|
+
children: all.length
|
|
880
|
+
}),
|
|
881
|
+
/*#__PURE__*/ _jsxs("td", {
|
|
882
|
+
children: [
|
|
883
|
+
read.undeclared ? /*#__PURE__*/ _jsx("span", {
|
|
884
|
+
className: "pdtp-warn",
|
|
885
|
+
children: "undeclared scope! "
|
|
886
|
+
}) : null,
|
|
887
|
+
read.bakedIn.length ? /*#__PURE__*/ _jsxs("span", {
|
|
888
|
+
className: "pdtp-warn",
|
|
889
|
+
title: read.bakedIn.map((b)=>`${b.via} → ${b.tag}`).join('\n'),
|
|
890
|
+
children: [
|
|
891
|
+
read.bakedIn.length,
|
|
892
|
+
" baked-in ⚠"
|
|
893
|
+
]
|
|
894
|
+
}) : null,
|
|
895
|
+
read.capped ? /*#__PURE__*/ _jsx("span", {
|
|
896
|
+
className: "pdtp-warn",
|
|
897
|
+
children: " capped!"
|
|
898
|
+
}) : null,
|
|
899
|
+
!read.undeclared && !read.bakedIn.length && !read.capped ? /*#__PURE__*/ _jsx("span", {
|
|
900
|
+
className: "pdtp-muted",
|
|
901
|
+
children: "atomic ✓"
|
|
902
|
+
}) : null
|
|
903
|
+
]
|
|
904
|
+
}),
|
|
905
|
+
/*#__PURE__*/ _jsxs("td", {
|
|
906
|
+
className: "pdtp-mono",
|
|
907
|
+
children: [
|
|
908
|
+
"×",
|
|
909
|
+
read.count
|
|
910
|
+
]
|
|
911
|
+
}),
|
|
912
|
+
/*#__PURE__*/ _jsx("td", {
|
|
913
|
+
className: "pdtp-mono",
|
|
914
|
+
children: clock(read.lastAt)
|
|
915
|
+
})
|
|
916
|
+
]
|
|
917
|
+
}, readName(read));
|
|
918
|
+
})
|
|
919
|
+
})
|
|
920
|
+
]
|
|
921
|
+
}),
|
|
922
|
+
/*#__PURE__*/ _jsx("p", {
|
|
923
|
+
className: "pdtp-note",
|
|
924
|
+
children: "Hover a tag count for the full list, a baked-in badge for the field paths. Reads record on cache miss (a hit never re-executes the getter)."
|
|
925
|
+
})
|
|
926
|
+
]
|
|
927
|
+
}) : /*#__PURE__*/ _jsx("p", {
|
|
928
|
+
className: "pdtp-muted",
|
|
929
|
+
children: "Nothing materialized yet — reads appear here the first time a cacheDoc/cacheIds/cacheGlobal getter runs."
|
|
930
|
+
});
|
|
931
|
+
}
|
|
932
|
+
function EventsTab({ data, endpointPath }) {
|
|
933
|
+
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
934
|
+
children: [
|
|
935
|
+
data.events.length ? /*#__PURE__*/ _jsxs("table", {
|
|
936
|
+
className: "pdtp-table",
|
|
937
|
+
children: [
|
|
938
|
+
/*#__PURE__*/ _jsx("thead", {
|
|
939
|
+
children: /*#__PURE__*/ _jsxs("tr", {
|
|
940
|
+
children: [
|
|
941
|
+
/*#__PURE__*/ _jsx("th", {
|
|
942
|
+
children: "at"
|
|
943
|
+
}),
|
|
944
|
+
/*#__PURE__*/ _jsx("th", {
|
|
945
|
+
children: "trigger"
|
|
946
|
+
}),
|
|
947
|
+
/*#__PURE__*/ _jsx("th", {
|
|
948
|
+
children: "busted"
|
|
949
|
+
})
|
|
950
|
+
]
|
|
951
|
+
})
|
|
952
|
+
}),
|
|
953
|
+
/*#__PURE__*/ _jsx("tbody", {
|
|
954
|
+
children: data.events.map((event)=>/*#__PURE__*/ _jsxs("tr", {
|
|
955
|
+
children: [
|
|
956
|
+
/*#__PURE__*/ _jsx("td", {
|
|
957
|
+
className: "pdtp-mono",
|
|
958
|
+
children: clock(event.at)
|
|
959
|
+
}),
|
|
960
|
+
/*#__PURE__*/ _jsxs("td", {
|
|
961
|
+
children: [
|
|
962
|
+
/*#__PURE__*/ _jsxs("span", {
|
|
963
|
+
className: "pdtp-code",
|
|
964
|
+
children: [
|
|
965
|
+
event.trigger.operation,
|
|
966
|
+
" ",
|
|
967
|
+
event.trigger.slug,
|
|
968
|
+
event.trigger.id !== undefined ? `:${event.trigger.id}` : ''
|
|
969
|
+
]
|
|
970
|
+
}),
|
|
971
|
+
event.trigger.lane === 'draft' ? /*#__PURE__*/ _jsx("span", {
|
|
972
|
+
className: "pdtp-muted",
|
|
973
|
+
children: " draft"
|
|
974
|
+
}) : null
|
|
975
|
+
]
|
|
976
|
+
}),
|
|
977
|
+
/*#__PURE__*/ _jsxs("td", {
|
|
978
|
+
className: "pdtp-mono",
|
|
979
|
+
title: event.busted.map((b)=>`${b.tag} (${b.reason})`).join('\n'),
|
|
980
|
+
children: [
|
|
981
|
+
event.busted.slice(0, 4).map((b)=>b.tag).join(', '),
|
|
982
|
+
event.busted.length > 4 ? ` +${event.busted.length - 4}` : ''
|
|
983
|
+
]
|
|
984
|
+
})
|
|
985
|
+
]
|
|
986
|
+
}, `${event.at}-${event.trigger.slug}-${event.trigger.id ?? ''}`))
|
|
987
|
+
})
|
|
988
|
+
]
|
|
989
|
+
}) : /*#__PURE__*/ _jsx("p", {
|
|
990
|
+
className: "pdtp-muted",
|
|
991
|
+
children: "No busts recorded yet — edit something in the admin panel."
|
|
992
|
+
}),
|
|
993
|
+
endpointPath ? /*#__PURE__*/ _jsx(BustTagCard, {
|
|
994
|
+
endpointPath: endpointPath
|
|
995
|
+
}) : null
|
|
996
|
+
]
|
|
997
|
+
});
|
|
998
|
+
}
|
|
999
|
+
// ---------------------------------------------------------------------------
|
|
1000
|
+
// The tabbed panel
|
|
1001
|
+
// ---------------------------------------------------------------------------
|
|
1002
|
+
const TABS = [
|
|
1003
|
+
{
|
|
1004
|
+
key: 'explore',
|
|
1005
|
+
title: 'Explore'
|
|
1006
|
+
},
|
|
1007
|
+
{
|
|
1008
|
+
key: 'fields',
|
|
1009
|
+
title: 'Fields'
|
|
1010
|
+
},
|
|
1011
|
+
{
|
|
1012
|
+
key: 'reads',
|
|
1013
|
+
title: 'Reads'
|
|
1014
|
+
},
|
|
1015
|
+
{
|
|
1016
|
+
key: 'events',
|
|
1017
|
+
title: 'Events'
|
|
1018
|
+
}
|
|
1019
|
+
];
|
|
1020
|
+
/** The `/dev/revalidate` panel — tabbed so a grown project stays navigable: Explore (the
|
|
1021
|
+
* interactive dependency graph + per-node lookup), Fields (the per-field blast-radius
|
|
1022
|
+
* tables), Reads (observed cache entries with atomic-health badges), Events (the bust
|
|
1023
|
+
* log + manual bust box). */ export function RevalidatePanel({ data, endpointPath }) {
|
|
1024
|
+
const [tab, setTab] = useState('explore');
|
|
1025
|
+
const [selected, setSelected] = useState(null);
|
|
1026
|
+
return /*#__PURE__*/ _jsxs(_Fragment, {
|
|
1027
|
+
children: [
|
|
1028
|
+
!data.observing ? /*#__PURE__*/ _jsx("p", {
|
|
1029
|
+
className: "pdtp-warn",
|
|
1030
|
+
style: {
|
|
1031
|
+
marginTop: 0
|
|
1032
|
+
},
|
|
1033
|
+
children: "Observation is off (`observe: false`) — the graph is static config analysis only; reads and events aren't recorded."
|
|
1034
|
+
}) : null,
|
|
1035
|
+
/*#__PURE__*/ _jsx("div", {
|
|
1036
|
+
className: "pdtp-seg",
|
|
1037
|
+
style: {
|
|
1038
|
+
marginBottom: 20
|
|
1039
|
+
},
|
|
1040
|
+
children: TABS.map(({ key, title })=>/*#__PURE__*/ _jsxs("button", {
|
|
1041
|
+
type: "button",
|
|
1042
|
+
className: tab === key ? 'pdtp-active' : '',
|
|
1043
|
+
onClick: ()=>setTab(key),
|
|
1044
|
+
children: [
|
|
1045
|
+
title,
|
|
1046
|
+
key === 'reads' && data.reads.length ? ` · ${data.reads.length}` : '',
|
|
1047
|
+
key === 'events' && data.events.length ? ` · ${data.events.length}` : ''
|
|
1048
|
+
]
|
|
1049
|
+
}, key))
|
|
1050
|
+
}),
|
|
1051
|
+
tab === 'explore' ? /*#__PURE__*/ _jsx(ExploreTab, {
|
|
1052
|
+
data: data,
|
|
1053
|
+
selected: selected,
|
|
1054
|
+
onSelect: setSelected
|
|
1055
|
+
}) : null,
|
|
1056
|
+
tab === 'fields' ? /*#__PURE__*/ _jsx(FieldsTab, {
|
|
1057
|
+
data: data
|
|
1058
|
+
}) : null,
|
|
1059
|
+
tab === 'reads' ? /*#__PURE__*/ _jsx(ReadsTab, {
|
|
1060
|
+
data: data
|
|
1061
|
+
}) : null,
|
|
1062
|
+
tab === 'events' ? /*#__PURE__*/ _jsx(EventsTab, {
|
|
1063
|
+
data: data,
|
|
1064
|
+
endpointPath: endpointPath
|
|
1065
|
+
}) : null,
|
|
1066
|
+
/*#__PURE__*/ _jsxs("p", {
|
|
1067
|
+
className: "pdtp-note",
|
|
1068
|
+
children: [
|
|
1069
|
+
"Machine-readable: ",
|
|
1070
|
+
/*#__PURE__*/ _jsxs("span", {
|
|
1071
|
+
className: "pdtp-code",
|
|
1072
|
+
children: [
|
|
1073
|
+
"GET ",
|
|
1074
|
+
endpointPath ?? '/api/revalidate-map'
|
|
1075
|
+
]
|
|
1076
|
+
}),
|
|
1077
|
+
" serves all of this as JSON",
|
|
1078
|
+
data.prefix ? /*#__PURE__*/ _jsxs(_Fragment, {
|
|
1079
|
+
children: [
|
|
1080
|
+
' ',
|
|
1081
|
+
"· tag prefix ",
|
|
1082
|
+
/*#__PURE__*/ _jsx("span", {
|
|
1083
|
+
className: "pdtp-code",
|
|
1084
|
+
children: data.prefix
|
|
1085
|
+
})
|
|
1086
|
+
]
|
|
1087
|
+
}) : null
|
|
1088
|
+
]
|
|
1089
|
+
})
|
|
1090
|
+
]
|
|
1091
|
+
});
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
//# sourceMappingURL=revalidatePanel.js.map
|