-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathmetadata-facade.ts
More file actions
108 lines (96 loc) · 3.24 KB
/
Copy pathmetadata-facade.ts
File metadata and controls
108 lines (96 loc) · 3.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.
import { SchemaRegistry } from './registry.js';
/**
* MetadataFacade
*
* Provides a clean, injectable interface over SchemaRegistry.
* Registered as the 'metadata' kernel service to eliminate
* downstream packages needing to manually wrap SchemaRegistry.
*
* Implements the async IMetadataService interface.
* Internally delegates to SchemaRegistry (in-memory) with Promise wrappers.
*
* Each facade is bound to a specific SchemaRegistry instance — passed in the
* constructor — so that multi-kernel servers can give every kernel its own
* metadata surface without leaking state across tenants.
*/
export class MetadataFacade {
constructor(private registry: SchemaRegistry) {}
/**
* Register a metadata item
*/
async register(type: string, name: string, data: any): Promise<void> {
const definition = typeof data === 'object' && data !== null
? { ...data, name: data.name ?? name }
: data;
// Pass through the item's own source package id (when stamped by an
// artifact loader) so provenance survives re-registration. Never
// synthesize one here — unstamped items are runtime-authored by
// definition and must not become artifact-backed (protocol.ts
// isArtifactBacked gates write authorization on _packageId).
const packageId = definition?._packageId;
if (type === 'object') {
this.registry.registerItem(type, definition, 'name' as any, packageId);
} else {
this.registry.registerItem(type, definition, definition.id ? 'id' as any : 'name' as any, packageId);
}
}
/**
* Get a metadata item by type and name
*/
async get(type: string, name: string): Promise<any> {
const item = this.registry.getItem(type, name) as any;
return item?.content ?? item;
}
/**
* Get the raw entry (with metadata wrapper)
*/
getEntry(type: string, name: string): any {
return this.registry.getItem(type, name);
}
/**
* List all items of a type
*/
async list(type: string): Promise<any[]> {
const items = this.registry.listItems(type);
return items.map((item: any) => item?.content ?? item);
}
/**
* Unregister a metadata item
*/
async unregister(type: string, name: string): Promise<void> {
this.registry.unregisterItem(type, name);
}
/**
* Check if a metadata item exists
*/
async exists(type: string, name: string): Promise<boolean> {
const item = this.registry.getItem(type, name);
return item !== undefined && item !== null;
}
/**
* List all names of metadata items of a given type
*/
async listNames(type: string): Promise<string[]> {
const items = this.registry.listItems(type);
return items.map((item: any) => item?.name ?? item?.content?.name ?? '').filter(Boolean);
}
/**
* Unregister all metadata from a package
*/
async unregisterPackage(packageName: string): Promise<void> {
this.registry.unregisterObjectsByPackage(packageName);
}
/**
* Convenience: get object definition
*/
async getObject(name: string): Promise<any> {
return this.registry.getObject(name);
}
/**
* Convenience: list all objects
*/
async listObjects(): Promise<any[]> {
return this.registry.getAllObjects();
}
}