@checkstack/cache-frontend 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/CHANGELOG.md ADDED
@@ -0,0 +1,37 @@
1
+ # @checkstack/cache-frontend
2
+
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 8d1ef12: ## Infrastructure Configuration Shell & Cache System
8
+
9
+ ### New Packages
10
+
11
+ - **`@checkstack/cache-api`**: Core cache abstractions — `CacheProvider` interface, `createScopedCache` factory for plugin key isolation, `CachePlugin`/`CacheManager` lifecycle interfaces.
12
+ - **`@checkstack/cache-common`**: Shared cache types, RPC contract (`getPlugins`, `getConfiguration`, `updateConfiguration`), access rules, and plugin metadata.
13
+ - **`@checkstack/cache-backend`**: Cache settings RPC router — exposes plugin discovery, configuration read/write endpoints with access-gated authorization.
14
+ - **`@checkstack/cache-frontend`**: Cache configuration tab component for the Infrastructure Settings page.
15
+ - **`@checkstack/infrastructure-common`**: Infrastructure tab registry, routes, and shared types for the IDE-style configuration shell.
16
+ - **`@checkstack/infrastructure-frontend`**: Infrastructure Settings page with vertical tab bar, per-tab access control, and user menu integration.
17
+
18
+ ### Modified Packages
19
+
20
+ - **`@checkstack/backend-api`**: Added `cachePluginRegistry` and `cacheManager` to `RpcContext` and `coreServices`.
21
+ - **`@checkstack/backend`**: Registered cache services in boot sequence, added cache config loading, extended dependency sorter for cache plugin ordering.
22
+ - **`@checkstack/queue-frontend`**: Refactored from standalone `/queue/config` route to an infrastructure tab. Queue settings now live inside the Infrastructure Settings page.
23
+
24
+ ### Architecture
25
+
26
+ The former monolithic Queue Config page is replaced by a pluggable Infrastructure Settings shell (`/infrastructure/config`). Plugins register configuration tabs via `registerInfrastructureTab()` with their own access rules, icons, and components. The shell evaluates per-tab access and only renders tabs the user can see.
27
+
28
+ ### Patch Changes
29
+
30
+ - Updated dependencies [8d1ef12]
31
+ - Updated dependencies [8d1ef12]
32
+ - Updated dependencies [8d1ef12]
33
+ - @checkstack/common@0.7.0
34
+ - @checkstack/cache-common@0.2.0
35
+ - @checkstack/infrastructure-common@0.2.0
36
+ - @checkstack/ui@1.6.0
37
+ - @checkstack/frontend-api@0.3.11
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@checkstack/cache-frontend",
3
+ "version": "0.2.0",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "checkstack": {
7
+ "type": "frontend"
8
+ },
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "import": "./src/index.tsx"
13
+ }
14
+ },
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "dev": "tsc --watch",
18
+ "typecheck": "tsc --noEmit",
19
+ "lint": "bun run lint:code",
20
+ "lint:code": "eslint . --max-warnings 0"
21
+ },
22
+ "dependencies": {
23
+ "@checkstack/cache-common": "0.1.0",
24
+ "@checkstack/common": "0.6.5",
25
+ "@checkstack/frontend-api": "0.3.10",
26
+ "@checkstack/infrastructure-common": "0.1.0",
27
+ "@checkstack/ui": "1.5.1",
28
+ "lucide-react": "^0.468.0",
29
+ "react": "^18.3.1"
30
+ },
31
+ "devDependencies": {
32
+ "@types/react": "^18.3.18",
33
+ "typescript": "^5.7.2",
34
+ "@checkstack/tsconfig": "0.0.5",
35
+ "@checkstack/scripts": "0.1.2"
36
+ }
37
+ }
@@ -0,0 +1,172 @@
1
+ import { useEffect, useState } from "react";
2
+ import { usePluginClient } from "@checkstack/frontend-api";
3
+ import {
4
+ type CachePluginDto,
5
+ CacheApi,
6
+ } from "@checkstack/cache-common";
7
+ import {
8
+ Button,
9
+ Alert,
10
+ AlertTitle,
11
+ AlertDescription,
12
+ Card,
13
+ CardContent,
14
+ CardFooter,
15
+ CardHeader,
16
+ CardTitle,
17
+ PluginConfigForm,
18
+ useToast,
19
+ } from "@checkstack/ui";
20
+ import { AlertTriangle, Save, Info, HardDrive } from "lucide-react";
21
+ import { extractErrorMessage } from "@checkstack/common";
22
+
23
+ /**
24
+ * Cache configuration tab component.
25
+ *
26
+ * Renders inside the Infrastructure Config page as a registered tab.
27
+ * Provides plugin selection and configuration form for the cache backend.
28
+ */
29
+ export const CacheConfigTab = ({ canUpdate }: { canUpdate: boolean }) => {
30
+ const cacheClient = usePluginClient(CacheApi);
31
+ const toast = useToast();
32
+
33
+ // Fetch plugins and configuration
34
+ const { data: pluginsList } = cacheClient.getPlugins.useQuery();
35
+ const { data: configuration, refetch: refetchConfig } =
36
+ cacheClient.getConfiguration.useQuery();
37
+ const updateConfigMutation = cacheClient.updateConfiguration.useMutation();
38
+
39
+ const [selectedPluginId, setSelectedPluginId] = useState<string>("");
40
+ const [config, setConfig] = useState<Record<string, unknown>>({});
41
+
42
+ // Sync state with fetched data
43
+ useEffect(() => {
44
+ if (configuration) {
45
+ setSelectedPluginId(configuration.pluginId);
46
+ setConfig(configuration.config);
47
+ }
48
+ }, [configuration]);
49
+
50
+ const handleSave = async () => {
51
+ if (!selectedPluginId) return;
52
+ try {
53
+ await updateConfigMutation.mutateAsync({
54
+ pluginId: selectedPluginId,
55
+ config,
56
+ });
57
+ toast.success("Cache configuration saved successfully!");
58
+ refetchConfig();
59
+ } catch (error) {
60
+ const message = extractErrorMessage(error);
61
+ toast.error(`Failed to save cache configuration: ${message}`);
62
+ }
63
+ };
64
+
65
+ const isMemoryCache = selectedPluginId === "memory";
66
+ const plugins: CachePluginDto[] = pluginsList ?? [];
67
+ const isSaving = updateConfigMutation.isPending;
68
+
69
+ return (
70
+ <div className="space-y-6">
71
+ <Card>
72
+ <CardHeader>
73
+ <CardTitle>Cache Configuration</CardTitle>
74
+ <p className="text-sm text-muted-foreground">
75
+ Select and configure the cache backend
76
+ </p>
77
+ </CardHeader>
78
+ <CardContent className="space-y-6">
79
+ {isMemoryCache && (
80
+ <Alert variant="warning">
81
+ <AlertTriangle className="h-5 w-5" />
82
+ <div>
83
+ <AlertTitle>In-Memory Cache Warning</AlertTitle>
84
+ <AlertDescription>
85
+ The in-memory cache is suitable for development and
86
+ single-instance deployments only. Data will not be shared
87
+ across multiple instances and will be lost on restart. For
88
+ production environments with multiple instances, consider
89
+ using a persistent cache implementation like Redis.
90
+ </AlertDescription>
91
+ </div>
92
+ </Alert>
93
+ )}
94
+
95
+ <PluginConfigForm
96
+ label="Cache Plugin"
97
+ plugins={plugins}
98
+ selectedPluginId={selectedPluginId}
99
+ onPluginChange={(value) => {
100
+ setSelectedPluginId(value);
101
+ setConfig({});
102
+ }}
103
+ config={config}
104
+ onConfigChange={setConfig}
105
+ disabled={!canUpdate}
106
+ />
107
+ </CardContent>
108
+ <CardFooter className="flex justify-end gap-2">
109
+ <Button onClick={handleSave} disabled={!canUpdate || isSaving}>
110
+ <Save className="mr-2 h-4 w-4" />
111
+ {isSaving ? "Saving..." : "Save Configuration"}
112
+ </Button>
113
+ </CardFooter>
114
+ </Card>
115
+
116
+ {/* Info Card */}
117
+ <Card>
118
+ <CardHeader>
119
+ <CardTitle className="flex items-center gap-2">
120
+ <Info className="h-5 w-5" />
121
+ Cache Usage
122
+ </CardTitle>
123
+ </CardHeader>
124
+ <CardContent className="space-y-4">
125
+ <div className="grid gap-4 md:grid-cols-2">
126
+ <div className="space-y-2">
127
+ <h4 className="flex items-center gap-2 font-medium">
128
+ <HardDrive className="h-4 w-4" />
129
+ How Cache is Used
130
+ </h4>
131
+ <ul className="text-sm text-muted-foreground space-y-1 list-disc list-inside">
132
+ <li>
133
+ <strong>Anomaly Detection</strong>: Stores computed baselines
134
+ for metric comparison
135
+ </li>
136
+ <li>
137
+ <strong>Performance</strong>: Reduces repeated computations
138
+ across health check runs
139
+ </li>
140
+ <li>
141
+ <strong>Plugin Data</strong>: Scoped key-value storage for
142
+ plugin-specific state
143
+ </li>
144
+ </ul>
145
+ </div>
146
+
147
+ <div className="space-y-2">
148
+ <h4 className="flex items-center gap-2 font-medium">
149
+ <AlertTriangle className="h-4 w-4" />
150
+ Configuration Notes
151
+ </h4>
152
+ <ul className="text-sm text-muted-foreground space-y-1 list-disc list-inside">
153
+ <li>
154
+ <strong>Max Entries</strong>: Limits memory usage; oldest
155
+ entries are evicted first
156
+ </li>
157
+ <li>
158
+ <strong>Sweep Interval</strong>: How often expired entries are
159
+ cleaned up
160
+ </li>
161
+ <li>
162
+ <strong>TTL</strong>: Entries expire automatically when set
163
+ with a time-to-live
164
+ </li>
165
+ </ul>
166
+ </div>
167
+ </div>
168
+ </CardContent>
169
+ </Card>
170
+ </div>
171
+ );
172
+ };
package/src/index.tsx ADDED
@@ -0,0 +1,22 @@
1
+ import { createFrontendPlugin } from "@checkstack/frontend-api";
2
+ import { registerInfrastructureTab } from "@checkstack/infrastructure-common";
3
+ import { pluginMetadata, cacheAccess } from "@checkstack/cache-common";
4
+ import { CacheConfigTab } from "./components/CacheConfigTab";
5
+ import { HardDrive } from "lucide-react";
6
+
7
+ // Register cache tab into the Infrastructure Configuration page
8
+ registerInfrastructureTab({
9
+ id: "cache",
10
+ pluginId: pluginMetadata.pluginId,
11
+ label: "Cache",
12
+ icon: HardDrive,
13
+ component: CacheConfigTab,
14
+ readAccess: cacheAccess.settings.read,
15
+ manageAccess: cacheAccess.settings.manage,
16
+ order: 20, // After queue (10)
17
+ });
18
+
19
+ export const cachePlugin = createFrontendPlugin({
20
+ metadata: pluginMetadata,
21
+ // No routes — the cache tab lives inside the infrastructure page
22
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "extends": "@checkstack/tsconfig/frontend.json",
3
+ "include": [
4
+ "src"
5
+ ]
6
+ }