@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/dist/node.cjs
CHANGED
|
@@ -1086,6 +1086,16 @@ var MetadataManager = class {
|
|
|
1086
1086
|
this.registerLoader(dbLoader);
|
|
1087
1087
|
this.logger.info("DatabaseLoader configured", { datasource: this.config.datasource, tableName });
|
|
1088
1088
|
}
|
|
1089
|
+
/**
|
|
1090
|
+
* Set the realtime service for publishing metadata change events.
|
|
1091
|
+
* Should be called after kernel resolves the realtime service.
|
|
1092
|
+
*
|
|
1093
|
+
* @param service - An IRealtimeService instance for event publishing
|
|
1094
|
+
*/
|
|
1095
|
+
setRealtimeService(service) {
|
|
1096
|
+
this.realtimeService = service;
|
|
1097
|
+
this.logger.info("RealtimeService configured for metadata events");
|
|
1098
|
+
}
|
|
1089
1099
|
/**
|
|
1090
1100
|
* Register a new metadata loader (data source)
|
|
1091
1101
|
*/
|
|
@@ -1098,7 +1108,9 @@ var MetadataManager = class {
|
|
|
1098
1108
|
// ==========================================
|
|
1099
1109
|
/**
|
|
1100
1110
|
* Register/save a metadata item by type
|
|
1101
|
-
* Stores in-memory registry and persists to
|
|
1111
|
+
* Stores in-memory registry and persists to database-backed loaders only.
|
|
1112
|
+
* FilesystemLoader (protocol 'file:') is read-only for static metadata and
|
|
1113
|
+
* should not be written to during runtime registration.
|
|
1102
1114
|
*/
|
|
1103
1115
|
async register(type, name, data) {
|
|
1104
1116
|
if (!this.registry.has(type)) {
|
|
@@ -1106,10 +1118,29 @@ var MetadataManager = class {
|
|
|
1106
1118
|
}
|
|
1107
1119
|
this.registry.get(type).set(name, data);
|
|
1108
1120
|
for (const loader of this.loaders.values()) {
|
|
1109
|
-
if (loader.save) {
|
|
1121
|
+
if (loader.save && loader.contract.protocol === "datasource:" && loader.contract.capabilities.write) {
|
|
1110
1122
|
await loader.save(type, name, data);
|
|
1111
1123
|
}
|
|
1112
1124
|
}
|
|
1125
|
+
if (this.realtimeService) {
|
|
1126
|
+
const event = {
|
|
1127
|
+
type: `metadata.${type}.created`,
|
|
1128
|
+
object: type,
|
|
1129
|
+
payload: {
|
|
1130
|
+
metadataType: type,
|
|
1131
|
+
name,
|
|
1132
|
+
definition: data,
|
|
1133
|
+
packageId: data?.packageId
|
|
1134
|
+
},
|
|
1135
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1136
|
+
};
|
|
1137
|
+
try {
|
|
1138
|
+
await this.realtimeService.publish(event);
|
|
1139
|
+
this.logger.debug(`Published metadata.${type}.created event`, { name });
|
|
1140
|
+
} catch (error) {
|
|
1141
|
+
this.logger.warn(`Failed to publish metadata event`, { type, name, error });
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1113
1144
|
}
|
|
1114
1145
|
/**
|
|
1115
1146
|
* Get a metadata item by type and name.
|
|
@@ -1150,7 +1181,8 @@ var MetadataManager = class {
|
|
|
1150
1181
|
return Array.from(items.values());
|
|
1151
1182
|
}
|
|
1152
1183
|
/**
|
|
1153
|
-
* Unregister/remove a metadata item by type and name
|
|
1184
|
+
* Unregister/remove a metadata item by type and name.
|
|
1185
|
+
* Deletes from database-backed loaders only (same rationale as register()).
|
|
1154
1186
|
*/
|
|
1155
1187
|
async unregister(type, name) {
|
|
1156
1188
|
const typeStore = this.registry.get(type);
|
|
@@ -1161,6 +1193,7 @@ var MetadataManager = class {
|
|
|
1161
1193
|
}
|
|
1162
1194
|
}
|
|
1163
1195
|
for (const loader of this.loaders.values()) {
|
|
1196
|
+
if (loader.contract.protocol !== "datasource:" || !loader.contract.capabilities.write) continue;
|
|
1164
1197
|
if (typeof loader.delete === "function") {
|
|
1165
1198
|
try {
|
|
1166
1199
|
await loader.delete(type, name);
|
|
@@ -1169,6 +1202,23 @@ var MetadataManager = class {
|
|
|
1169
1202
|
}
|
|
1170
1203
|
}
|
|
1171
1204
|
}
|
|
1205
|
+
if (this.realtimeService) {
|
|
1206
|
+
const event = {
|
|
1207
|
+
type: `metadata.${type}.deleted`,
|
|
1208
|
+
object: type,
|
|
1209
|
+
payload: {
|
|
1210
|
+
metadataType: type,
|
|
1211
|
+
name
|
|
1212
|
+
},
|
|
1213
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1214
|
+
};
|
|
1215
|
+
try {
|
|
1216
|
+
await this.realtimeService.publish(event);
|
|
1217
|
+
this.logger.debug(`Published metadata.${type}.deleted event`, { name });
|
|
1218
|
+
} catch (error) {
|
|
1219
|
+
this.logger.warn(`Failed to publish metadata event`, { type, name, error });
|
|
1220
|
+
}
|
|
1221
|
+
}
|
|
1172
1222
|
}
|
|
1173
1223
|
/**
|
|
1174
1224
|
* Check if a metadata item exists
|
|
@@ -2514,6 +2564,7 @@ var MetadataPlugin = class {
|
|
|
2514
2564
|
watch: this.options.watch
|
|
2515
2565
|
});
|
|
2516
2566
|
ctx.registerService("metadata", this.manager);
|
|
2567
|
+
console.log("[MetadataPlugin] Registered metadata service, has getRegisteredTypes:", typeof this.manager.getRegisteredTypes);
|
|
2517
2568
|
try {
|
|
2518
2569
|
ctx.getService("manifest").register({
|
|
2519
2570
|
id: "com.objectstack.metadata",
|
|
@@ -2557,6 +2608,52 @@ var MetadataPlugin = class {
|
|
|
2557
2608
|
totalItems: totalLoaded,
|
|
2558
2609
|
registeredTypes: sortedTypes.length
|
|
2559
2610
|
});
|
|
2611
|
+
let driverBridged = false;
|
|
2612
|
+
try {
|
|
2613
|
+
const ql = ctx.getService("objectql");
|
|
2614
|
+
if (ql) {
|
|
2615
|
+
const tableName = this.manager["config"]?.tableName ?? "sys_metadata";
|
|
2616
|
+
const driver = ql.getDriverForObject?.(tableName);
|
|
2617
|
+
if (driver) {
|
|
2618
|
+
ctx.logger.info("[MetadataPlugin] Bridging driver to MetadataManager via ObjectQL routing", {
|
|
2619
|
+
tableName,
|
|
2620
|
+
driver: driver.name
|
|
2621
|
+
});
|
|
2622
|
+
this.manager.setDatabaseDriver(driver);
|
|
2623
|
+
driverBridged = true;
|
|
2624
|
+
} else {
|
|
2625
|
+
ctx.logger.debug("[MetadataPlugin] ObjectQL could not resolve driver for metadata table", { tableName });
|
|
2626
|
+
}
|
|
2627
|
+
}
|
|
2628
|
+
} catch {
|
|
2629
|
+
}
|
|
2630
|
+
if (!driverBridged) {
|
|
2631
|
+
try {
|
|
2632
|
+
const services = ctx.getServices();
|
|
2633
|
+
for (const [serviceName, service] of services) {
|
|
2634
|
+
if (serviceName.startsWith("driver.") && service) {
|
|
2635
|
+
ctx.logger.info("[MetadataPlugin] Bridging driver to MetadataManager (fallback: first driver)", {
|
|
2636
|
+
driverService: serviceName
|
|
2637
|
+
});
|
|
2638
|
+
this.manager.setDatabaseDriver(service);
|
|
2639
|
+
break;
|
|
2640
|
+
}
|
|
2641
|
+
}
|
|
2642
|
+
} catch (e) {
|
|
2643
|
+
ctx.logger.debug("[MetadataPlugin] No driver service found", { error: e.message });
|
|
2644
|
+
}
|
|
2645
|
+
}
|
|
2646
|
+
try {
|
|
2647
|
+
const realtimeService = ctx.getService("realtime");
|
|
2648
|
+
if (realtimeService && typeof realtimeService === "object" && "publish" in realtimeService) {
|
|
2649
|
+
ctx.logger.info("[MetadataPlugin] Bridging realtime service to MetadataManager for event publishing");
|
|
2650
|
+
this.manager.setRealtimeService(realtimeService);
|
|
2651
|
+
}
|
|
2652
|
+
} catch (e) {
|
|
2653
|
+
ctx.logger.debug("[MetadataPlugin] No realtime service found \u2014 metadata events will not be published", {
|
|
2654
|
+
error: e.message
|
|
2655
|
+
});
|
|
2656
|
+
}
|
|
2560
2657
|
};
|
|
2561
2658
|
this.options = {
|
|
2562
2659
|
watch: true,
|