@objectstack/metadata 4.0.2 → 4.0.4
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/README.md +2 -2
- package/dist/index.cjs +100 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -5
- package/dist/index.d.ts +16 -5
- package/dist/index.js +100 -3
- package/dist/index.js.map +1 -1
- package/dist/node.cjs +100 -3
- package/dist/node.cjs.map +1 -1
- package/dist/node.js +100 -3
- package/dist/node.js.map +1 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -28,7 +28,7 @@ It implements the **`IMetadataService`** contract from `@objectstack/spec` and a
|
|
|
28
28
|
│ │ (files) │ │ (HTTP) │ │ (test) │ │
|
|
29
29
|
│ └─────────────┘ └──────────────┘ └───────────────────┘ │
|
|
30
30
|
│ ┌──────────────────────────────────────────────────────┐ │
|
|
31
|
-
│ │ DatabaseLoader (
|
|
31
|
+
│ │ DatabaseLoader (datasource-backed storage) │ │
|
|
32
32
|
│ └──────────────────────────────────────────────────────┘ │
|
|
33
33
|
├─────────────────────────────────────────────────────────────┤
|
|
34
34
|
│ Serializer Layer │
|
|
@@ -61,7 +61,7 @@ Loaders are pluggable data sources that know how to read/write metadata from dif
|
|
|
61
61
|
| `FilesystemLoader` | `file:` | ✅ | ✅ | ✅ | Implemented |
|
|
62
62
|
| `MemoryLoader` | `memory:` | ✅ | ✅ | ❌ | Implemented |
|
|
63
63
|
| `RemoteLoader` | `http:` | ✅ | ✅ | ❌ | Implemented |
|
|
64
|
-
| `DatabaseLoader` | `datasource:` | ✅ | ✅ |
|
|
64
|
+
| `DatabaseLoader` | `datasource:` | ✅ | ✅ | ❌ | Implemented |
|
|
65
65
|
|
|
66
66
|
### 3. Serializers
|
|
67
67
|
|
package/dist/index.cjs
CHANGED
|
@@ -1084,6 +1084,16 @@ var MetadataManager = class {
|
|
|
1084
1084
|
this.registerLoader(dbLoader);
|
|
1085
1085
|
this.logger.info("DatabaseLoader configured", { datasource: this.config.datasource, tableName });
|
|
1086
1086
|
}
|
|
1087
|
+
/**
|
|
1088
|
+
* Set the realtime service for publishing metadata change events.
|
|
1089
|
+
* Should be called after kernel resolves the realtime service.
|
|
1090
|
+
*
|
|
1091
|
+
* @param service - An IRealtimeService instance for event publishing
|
|
1092
|
+
*/
|
|
1093
|
+
setRealtimeService(service) {
|
|
1094
|
+
this.realtimeService = service;
|
|
1095
|
+
this.logger.info("RealtimeService configured for metadata events");
|
|
1096
|
+
}
|
|
1087
1097
|
/**
|
|
1088
1098
|
* Register a new metadata loader (data source)
|
|
1089
1099
|
*/
|
|
@@ -1096,7 +1106,9 @@ var MetadataManager = class {
|
|
|
1096
1106
|
// ==========================================
|
|
1097
1107
|
/**
|
|
1098
1108
|
* Register/save a metadata item by type
|
|
1099
|
-
* Stores in-memory registry and persists to
|
|
1109
|
+
* Stores in-memory registry and persists to database-backed loaders only.
|
|
1110
|
+
* FilesystemLoader (protocol 'file:') is read-only for static metadata and
|
|
1111
|
+
* should not be written to during runtime registration.
|
|
1100
1112
|
*/
|
|
1101
1113
|
async register(type, name, data) {
|
|
1102
1114
|
if (!this.registry.has(type)) {
|
|
@@ -1104,10 +1116,29 @@ var MetadataManager = class {
|
|
|
1104
1116
|
}
|
|
1105
1117
|
this.registry.get(type).set(name, data);
|
|
1106
1118
|
for (const loader of this.loaders.values()) {
|
|
1107
|
-
if (loader.save) {
|
|
1119
|
+
if (loader.save && loader.contract.protocol === "datasource:" && loader.contract.capabilities.write) {
|
|
1108
1120
|
await loader.save(type, name, data);
|
|
1109
1121
|
}
|
|
1110
1122
|
}
|
|
1123
|
+
if (this.realtimeService) {
|
|
1124
|
+
const event = {
|
|
1125
|
+
type: `metadata.${type}.created`,
|
|
1126
|
+
object: type,
|
|
1127
|
+
payload: {
|
|
1128
|
+
metadataType: type,
|
|
1129
|
+
name,
|
|
1130
|
+
definition: data,
|
|
1131
|
+
packageId: data?.packageId
|
|
1132
|
+
},
|
|
1133
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1134
|
+
};
|
|
1135
|
+
try {
|
|
1136
|
+
await this.realtimeService.publish(event);
|
|
1137
|
+
this.logger.debug(`Published metadata.${type}.created event`, { name });
|
|
1138
|
+
} catch (error) {
|
|
1139
|
+
this.logger.warn(`Failed to publish metadata event`, { type, name, error });
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1111
1142
|
}
|
|
1112
1143
|
/**
|
|
1113
1144
|
* Get a metadata item by type and name.
|
|
@@ -1148,7 +1179,8 @@ var MetadataManager = class {
|
|
|
1148
1179
|
return Array.from(items.values());
|
|
1149
1180
|
}
|
|
1150
1181
|
/**
|
|
1151
|
-
* Unregister/remove a metadata item by type and name
|
|
1182
|
+
* Unregister/remove a metadata item by type and name.
|
|
1183
|
+
* Deletes from database-backed loaders only (same rationale as register()).
|
|
1152
1184
|
*/
|
|
1153
1185
|
async unregister(type, name) {
|
|
1154
1186
|
const typeStore = this.registry.get(type);
|
|
@@ -1159,6 +1191,7 @@ var MetadataManager = class {
|
|
|
1159
1191
|
}
|
|
1160
1192
|
}
|
|
1161
1193
|
for (const loader of this.loaders.values()) {
|
|
1194
|
+
if (loader.contract.protocol !== "datasource:" || !loader.contract.capabilities.write) continue;
|
|
1162
1195
|
if (typeof loader.delete === "function") {
|
|
1163
1196
|
try {
|
|
1164
1197
|
await loader.delete(type, name);
|
|
@@ -1167,6 +1200,23 @@ var MetadataManager = class {
|
|
|
1167
1200
|
}
|
|
1168
1201
|
}
|
|
1169
1202
|
}
|
|
1203
|
+
if (this.realtimeService) {
|
|
1204
|
+
const event = {
|
|
1205
|
+
type: `metadata.${type}.deleted`,
|
|
1206
|
+
object: type,
|
|
1207
|
+
payload: {
|
|
1208
|
+
metadataType: type,
|
|
1209
|
+
name
|
|
1210
|
+
},
|
|
1211
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1212
|
+
};
|
|
1213
|
+
try {
|
|
1214
|
+
await this.realtimeService.publish(event);
|
|
1215
|
+
this.logger.debug(`Published metadata.${type}.deleted event`, { name });
|
|
1216
|
+
} catch (error) {
|
|
1217
|
+
this.logger.warn(`Failed to publish metadata event`, { type, name, error });
|
|
1218
|
+
}
|
|
1219
|
+
}
|
|
1170
1220
|
}
|
|
1171
1221
|
/**
|
|
1172
1222
|
* Check if a metadata item exists
|
|
@@ -2512,6 +2562,7 @@ var MetadataPlugin = class {
|
|
|
2512
2562
|
watch: this.options.watch
|
|
2513
2563
|
});
|
|
2514
2564
|
ctx.registerService("metadata", this.manager);
|
|
2565
|
+
console.log("[MetadataPlugin] Registered metadata service, has getRegisteredTypes:", typeof this.manager.getRegisteredTypes);
|
|
2515
2566
|
try {
|
|
2516
2567
|
ctx.getService("manifest").register({
|
|
2517
2568
|
id: "com.objectstack.metadata",
|
|
@@ -2555,6 +2606,52 @@ var MetadataPlugin = class {
|
|
|
2555
2606
|
totalItems: totalLoaded,
|
|
2556
2607
|
registeredTypes: sortedTypes.length
|
|
2557
2608
|
});
|
|
2609
|
+
let driverBridged = false;
|
|
2610
|
+
try {
|
|
2611
|
+
const ql = ctx.getService("objectql");
|
|
2612
|
+
if (ql) {
|
|
2613
|
+
const tableName = this.manager["config"]?.tableName ?? "sys_metadata";
|
|
2614
|
+
const driver = ql.getDriverForObject?.(tableName);
|
|
2615
|
+
if (driver) {
|
|
2616
|
+
ctx.logger.info("[MetadataPlugin] Bridging driver to MetadataManager via ObjectQL routing", {
|
|
2617
|
+
tableName,
|
|
2618
|
+
driver: driver.name
|
|
2619
|
+
});
|
|
2620
|
+
this.manager.setDatabaseDriver(driver);
|
|
2621
|
+
driverBridged = true;
|
|
2622
|
+
} else {
|
|
2623
|
+
ctx.logger.debug("[MetadataPlugin] ObjectQL could not resolve driver for metadata table", { tableName });
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
} catch {
|
|
2627
|
+
}
|
|
2628
|
+
if (!driverBridged) {
|
|
2629
|
+
try {
|
|
2630
|
+
const services = ctx.getServices();
|
|
2631
|
+
for (const [serviceName, service] of services) {
|
|
2632
|
+
if (serviceName.startsWith("driver.") && service) {
|
|
2633
|
+
ctx.logger.info("[MetadataPlugin] Bridging driver to MetadataManager (fallback: first driver)", {
|
|
2634
|
+
driverService: serviceName
|
|
2635
|
+
});
|
|
2636
|
+
this.manager.setDatabaseDriver(service);
|
|
2637
|
+
break;
|
|
2638
|
+
}
|
|
2639
|
+
}
|
|
2640
|
+
} catch (e) {
|
|
2641
|
+
ctx.logger.debug("[MetadataPlugin] No driver service found", { error: e.message });
|
|
2642
|
+
}
|
|
2643
|
+
}
|
|
2644
|
+
try {
|
|
2645
|
+
const realtimeService = ctx.getService("realtime");
|
|
2646
|
+
if (realtimeService && typeof realtimeService === "object" && "publish" in realtimeService) {
|
|
2647
|
+
ctx.logger.info("[MetadataPlugin] Bridging realtime service to MetadataManager for event publishing");
|
|
2648
|
+
this.manager.setRealtimeService(realtimeService);
|
|
2649
|
+
}
|
|
2650
|
+
} catch (e) {
|
|
2651
|
+
ctx.logger.debug("[MetadataPlugin] No realtime service found \u2014 metadata events will not be published", {
|
|
2652
|
+
error: e.message
|
|
2653
|
+
});
|
|
2654
|
+
}
|
|
2558
2655
|
};
|
|
2559
2656
|
this.options = {
|
|
2560
2657
|
watch: true,
|