Skip to content

Commit f578909

Browse files
rekmarksclaude
andcommitted
refactor(omnium): Simplify CapletController state structure
Consolidate CapletControllerState from multiple top-level keys (installed, manifests, subclusters, installedAt) into a single `caplets: Record<CapletId, InstalledCaplet>` structure. Changes: - Add ControllerStorage abstraction using Immer for state management - Controllers work with typed state object instead of storage keys - Only modified top-level keys are persisted (via Immer patches) - Remove state corruption checks (no longer possible with atomic storage) - Fix makeFacet type - use string | symbol instead of keyof MethodGuard - Update PLAN.md to reflect new storage architecture 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent f1e6f12 commit f578909

File tree

12 files changed

+932
-403
lines changed

12 files changed

+932
-403
lines changed

packages/omnium-gatherum/PLAN.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,11 @@ capabilities.
106106
- `NamespacedStorage`: Scoped storage interface with automatic key prefixing
107107
- `controllers/storage/chrome-storage.ts`: `makeChromeStorageAdapter()` for Chrome Storage API
108108
- `controllers/storage/namespaced-storage.ts`: `makeNamespacedStorage()` factory
109-
- Storage keys automatically prefixed: `${namespace}.${key}` (e.g., `caplet.com.example.test.manifest`)
109+
- `controllers/storage/controller-storage.ts`: `makeControllerStorage()` for controller state management
110+
- Controllers work with a typed `state` object instead of managing storage keys directly
111+
- Uses Immer for immutable updates with change tracking
112+
- Only persists modified top-level keys (via Immer patches)
113+
- Storage keys automatically prefixed: `${namespace}.${key}` (e.g., `caplet.caplets`)
110114
111115
- [x] **Caplet Manifest Schema**
112116
@@ -126,11 +130,11 @@ capabilities.
126130
- `list()`: Get all installed caplets
127131
- `get(capletId)`: Get specific caplet
128132
- `getByService(serviceName)`: Find caplet providing a service
129-
- Storage keys (within `caplet` namespace):
130-
- `installed`: Array of installed caplet IDs
131-
- `${capletId}.manifest`: CapletManifest JSON
132-
- `${capletId}.subclusterId`: Associated subcluster ID
133-
- `${capletId}.installedAt`: Installation timestamp
133+
- State structure (`CapletControllerState`):
134+
- `caplets`: `Record<CapletId, InstalledCaplet>` - all caplet data in a single record
135+
- Uses `ControllerStorage<CapletControllerState>` for state management
136+
- Synchronous reads via `storage.state.caplets[id]`
137+
- Async updates via `storage.update(draft => { ... })`
134138
135139
- [x] **Dev Console Integration**
136140

packages/omnium-gatherum/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
"@metamask/streams": "workspace:^",
5454
"@metamask/superstruct": "^3.2.1",
5555
"@metamask/utils": "^11.4.2",
56+
"immer": "^10.1.1",
5657
"react": "^17.0.2",
5758
"react-dom": "^17.0.2",
5859
"semver": "^7.7.1",

packages/omnium-gatherum/src/background.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,14 @@ import { ChromeRuntimeDuplexStream } from '@metamask/streams/browser';
1717

1818
import {
1919
makeChromeStorageAdapter,
20-
makeNamespacedStorage,
20+
makeControllerStorage,
2121
makeCapletController,
2222
} from './controllers/index.ts';
23-
import type { CapletManifest, LaunchResult } from './controllers/index.ts';
23+
import type {
24+
CapletControllerState,
25+
CapletManifest,
26+
LaunchResult,
27+
} from './controllers/index.ts';
2428

2529
defineGlobals();
2630

@@ -120,9 +124,16 @@ async function main(): Promise<void> {
120124
return kernelP;
121125
};
122126

123-
// Create storage adapter and namespaced storage for caplets
127+
// Create storage adapter and state storage for caplets
124128
const storageAdapter = makeChromeStorageAdapter();
125-
const capletStorage = makeNamespacedStorage('caplet', storageAdapter);
129+
const defaultCapletState: CapletControllerState = {
130+
caplets: {},
131+
};
132+
const capletStorage = await makeControllerStorage({
133+
namespace: 'caplet',
134+
adapter: storageAdapter,
135+
defaultState: defaultCapletState,
136+
});
126137

127138
// Create CapletController with attenuated kernel access
128139
const capletController = makeCapletController(

0 commit comments

Comments
 (0)