Skip to content

Commit f482e30

Browse files
Claudehotlong
andauthored
Fix metadata unregister and rollback functionality
Fixed multiple issues with metadata management: 1. rollback(): Now updates in-memory registry after restoring from history 2. unregister(): Now deletes from both in-memory registry AND all loaders 3. unregisterPackage(): Now uses unregister() to ensure proper cleanup 4. Added delete() methods to MemoryLoader and DatabaseLoader These changes ensure that unregister operations properly remove metadata from all storage locations, and rollback operations update the in-memory state correctly. Fixes: - packages/metadata/src/metadata-manager.ts:1354-1358 (rollback registry update) - packages/metadata/src/metadata-manager.ts:223-244 (unregister loader cleanup) - packages/metadata/src/metadata-manager.ts:344-361 (unregisterPackage refactor) - packages/metadata/src/loaders/memory-loader.ts:104-115 (delete method) - packages/metadata/src/loaders/database-loader.ts:594-616 (delete method) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent cf50b78 commit f482e30

3 files changed

Lines changed: 66 additions & 9 deletions

File tree

packages/metadata/src/loaders/database-loader.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,30 @@ export class DatabaseLoader implements MetadataLoader {
590590
);
591591
}
592592
}
593+
594+
/**
595+
* Delete a metadata item from the database
596+
*/
597+
async delete(type: string, name: string): Promise<void> {
598+
await this.ensureSchema();
599+
600+
// Find the existing record to get its ID
601+
const existing = await this.driver.findOne(this.tableName, {
602+
object: this.tableName,
603+
where: this.baseFilter(type, name),
604+
});
605+
606+
if (!existing) {
607+
// Item doesn't exist, nothing to delete
608+
return;
609+
}
610+
611+
// Delete from the main metadata table
612+
await this.driver.delete(this.tableName, {
613+
object: this.tableName,
614+
where: this.baseFilter(type, name),
615+
});
616+
}
593617
}
594618

595619
/**

packages/metadata/src/loaders/memory-loader.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ export class MemoryLoader implements MetadataLoader {
9191
if (!this.storage.has(type)) {
9292
this.storage.set(type, new Map());
9393
}
94-
94+
9595
this.storage.get(type)!.set(name, data);
9696

9797
return {
@@ -100,4 +100,17 @@ export class MemoryLoader implements MetadataLoader {
100100
saveTime: 0,
101101
};
102102
}
103+
104+
/**
105+
* Delete a metadata item from memory storage
106+
*/
107+
async delete(type: string, name: string): Promise<void> {
108+
const typeStore = this.storage.get(type);
109+
if (typeStore) {
110+
typeStore.delete(name);
111+
if (typeStore.size === 0) {
112+
this.storage.delete(type);
113+
}
114+
}
115+
}
103116
}

packages/metadata/src/metadata-manager.ts

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -221,13 +221,26 @@ export class MetadataManager implements IMetadataService {
221221
* Unregister/remove a metadata item by type and name
222222
*/
223223
async unregister(type: string, name: string): Promise<void> {
224+
// Remove from in-memory registry
224225
const typeStore = this.registry.get(type);
225226
if (typeStore) {
226227
typeStore.delete(name);
227228
if (typeStore.size === 0) {
228229
this.registry.delete(type);
229230
}
230231
}
232+
233+
// Also delete from all loaders that support deletion
234+
for (const loader of this.loaders.values()) {
235+
// Check if the loader has a delete method
236+
if (typeof (loader as any).delete === 'function') {
237+
try {
238+
await (loader as any).delete(type, name);
239+
} catch (error) {
240+
this.logger.warn(`Failed to delete ${type}/${name} from loader ${loader.contract.name}`, { error });
241+
}
242+
}
243+
}
231244
}
232245

233246
/**
@@ -329,20 +342,21 @@ export class MetadataManager implements IMetadataService {
329342
* Unregister all metadata items from a specific package
330343
*/
331344
async unregisterPackage(packageName: string): Promise<void> {
345+
// Collect all items to delete (type and name pairs)
346+
const itemsToDelete: Array<{ type: string; name: string }> = [];
347+
332348
for (const [type, typeStore] of this.registry) {
333-
const toDelete: string[] = [];
334349
for (const [name, data] of typeStore) {
335350
const meta = data as any;
336351
if (meta?.packageId === packageName || meta?.package === packageName) {
337-
toDelete.push(name);
352+
itemsToDelete.push({ type, name });
338353
}
339354
}
340-
for (const name of toDelete) {
341-
typeStore.delete(name);
342-
}
343-
if (typeStore.size === 0) {
344-
this.registry.delete(type);
345-
}
355+
}
356+
357+
// Delete each item using unregister() to ensure deletion from both registry and loaders
358+
for (const { type, name } of itemsToDelete) {
359+
await this.unregister(type, name);
346360
}
347361
}
348362

@@ -1351,6 +1365,12 @@ export class MetadataManager implements IMetadataService {
13511365
options?.recordedBy
13521366
);
13531367

1368+
// Update in-memory registry with the restored metadata
1369+
if (!this.registry.has(type)) {
1370+
this.registry.set(type, new Map());
1371+
}
1372+
this.registry.get(type)!.set(name, restoredMetadata);
1373+
13541374
return restoredMetadata;
13551375
}
13561376

0 commit comments

Comments
 (0)