@objectstack/runtime 4.0.2 → 4.0.3
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/.turbo/turbo-build.log +8 -8
- package/CHANGELOG.md +9 -0
- package/dist/index.cjs +135 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +135 -54
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
- package/src/dispatcher-plugin.ts +93 -59
- package/src/http-dispatcher.ts +83 -7
- package/vitest.config.ts +1 -0
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @objectstack/runtime@4.0.
|
|
2
|
+
> @objectstack/runtime@4.0.3 build /home/runner/work/framework/framework/packages/runtime
|
|
3
3
|
> tsup --config ../../tsup.config.ts
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: src/index.ts
|
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
[34mCLI[39m Cleaning output folder
|
|
11
11
|
[34mESM[39m Build start
|
|
12
12
|
[34mCJS[39m Build start
|
|
13
|
-
[32mESM[39m [1mdist/index.js [22m[
|
|
14
|
-
[32mESM[39m [1mdist/index.js.map [22m[
|
|
15
|
-
[32mESM[39m ⚡️ Build success in
|
|
16
|
-
[32mCJS[39m [1mdist/index.cjs [22m[
|
|
17
|
-
[32mCJS[39m [1mdist/index.cjs.map [22m[
|
|
18
|
-
[32mCJS[39m ⚡️ Build success in
|
|
13
|
+
[32mESM[39m [1mdist/index.js [22m[32m98.02 KB[39m
|
|
14
|
+
[32mESM[39m [1mdist/index.js.map [22m[32m212.66 KB[39m
|
|
15
|
+
[32mESM[39m ⚡️ Build success in 153ms
|
|
16
|
+
[32mCJS[39m [1mdist/index.cjs [22m[32m100.63 KB[39m
|
|
17
|
+
[32mCJS[39m [1mdist/index.cjs.map [22m[32m212.72 KB[39m
|
|
18
|
+
[32mCJS[39m ⚡️ Build success in 153ms
|
|
19
19
|
[34mDTS[39m Build start
|
|
20
|
-
[32mDTS[39m ⚡️ Build success in
|
|
20
|
+
[32mDTS[39m ⚡️ Build success in 3771ms
|
|
21
21
|
[32mDTS[39m [1mdist/index.d.ts [22m[32m26.00 KB[39m
|
|
22
22
|
[32mDTS[39m [1mdist/index.d.cts [22m[32m26.00 KB[39m
|
package/CHANGELOG.md
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -828,6 +828,7 @@ var AppPlugin = class {
|
|
|
828
828
|
// src/http-dispatcher.ts
|
|
829
829
|
var import_core2 = require("@objectstack/core");
|
|
830
830
|
var import_system = require("@objectstack/spec/system");
|
|
831
|
+
var import_shared = require("@objectstack/spec/shared");
|
|
831
832
|
function randomUUID() {
|
|
832
833
|
if (globalThis.crypto && typeof globalThis.crypto.randomUUID === "function") {
|
|
833
834
|
return globalThis.crypto.randomUUID();
|
|
@@ -1112,18 +1113,66 @@ var HttpDispatcher = class {
|
|
|
1112
1113
|
const broker = this.kernel.broker ?? null;
|
|
1113
1114
|
const parts = path.replace(/^\/+/, "").split("/").filter(Boolean);
|
|
1114
1115
|
if (parts[0] === "types") {
|
|
1116
|
+
console.log("[HttpDispatcher] Attempting to resolve MetadataService...");
|
|
1117
|
+
console.log("[HttpDispatcher] Available kernel methods:", {
|
|
1118
|
+
hasGetServiceAsync: typeof this.kernel.getServiceAsync === "function",
|
|
1119
|
+
hasGetService: typeof this.kernel.getService === "function",
|
|
1120
|
+
hasContext: !!this.kernel.context,
|
|
1121
|
+
hasContextGetService: typeof this.kernel.context?.getService === "function"
|
|
1122
|
+
});
|
|
1123
|
+
let metadataService = null;
|
|
1124
|
+
if (typeof this.kernel.getServiceAsync === "function") {
|
|
1125
|
+
try {
|
|
1126
|
+
metadataService = await this.kernel.getServiceAsync("metadata");
|
|
1127
|
+
console.log('[HttpDispatcher] kernel.getServiceAsync("metadata") returned:', !!metadataService);
|
|
1128
|
+
} catch (e) {
|
|
1129
|
+
console.log('[HttpDispatcher] kernel.getServiceAsync("metadata") failed:', e.message);
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
if (!metadataService && typeof this.kernel.getService === "function") {
|
|
1133
|
+
try {
|
|
1134
|
+
metadataService = await this.kernel.getService("metadata");
|
|
1135
|
+
console.log('[HttpDispatcher] kernel.getService("metadata") returned:', !!metadataService);
|
|
1136
|
+
} catch (e) {
|
|
1137
|
+
console.log('[HttpDispatcher] kernel.getService("metadata") failed:', e.message);
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
if (!metadataService && this.kernel.context?.getService) {
|
|
1141
|
+
try {
|
|
1142
|
+
metadataService = await this.kernel.context.getService("metadata");
|
|
1143
|
+
console.log('[HttpDispatcher] kernel.context.getService("metadata") returned:', !!metadataService);
|
|
1144
|
+
} catch (e) {
|
|
1145
|
+
console.log('[HttpDispatcher] kernel.context.getService("metadata") failed:', e.message);
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
console.log("[HttpDispatcher] Final metadataService:", !!metadataService, "has getRegisteredTypes:", typeof metadataService?.getRegisteredTypes);
|
|
1149
|
+
if (metadataService && typeof metadataService.getRegisteredTypes === "function") {
|
|
1150
|
+
try {
|
|
1151
|
+
const types = await metadataService.getRegisteredTypes();
|
|
1152
|
+
console.log("[HttpDispatcher] MetadataService.getRegisteredTypes() returned:", types);
|
|
1153
|
+
return { handled: true, response: this.success({ types }) };
|
|
1154
|
+
} catch (e) {
|
|
1155
|
+
console.warn("[HttpDispatcher] MetadataService.getRegisteredTypes() failed:", e.message, e.stack);
|
|
1156
|
+
}
|
|
1157
|
+
} else {
|
|
1158
|
+
console.log("[HttpDispatcher] MetadataService not available or missing getRegisteredTypes, falling back to protocol service");
|
|
1159
|
+
}
|
|
1115
1160
|
const protocol = await this.resolveService("protocol");
|
|
1116
1161
|
if (protocol && typeof protocol.getMetaTypes === "function") {
|
|
1117
1162
|
const result = await protocol.getMetaTypes({});
|
|
1163
|
+
console.log("[HttpDispatcher] Protocol service returned types:", result);
|
|
1118
1164
|
return { handled: true, response: this.success(result) };
|
|
1119
1165
|
}
|
|
1120
1166
|
if (broker) {
|
|
1121
1167
|
try {
|
|
1122
1168
|
const data = await broker.call("metadata.types", {}, { request: context.request });
|
|
1169
|
+
console.log("[HttpDispatcher] Broker returned types:", data);
|
|
1123
1170
|
return { handled: true, response: this.success(data) };
|
|
1124
|
-
} catch {
|
|
1171
|
+
} catch (e) {
|
|
1172
|
+
console.log("[HttpDispatcher] Broker call failed:", e);
|
|
1125
1173
|
}
|
|
1126
1174
|
}
|
|
1175
|
+
console.warn("[HttpDispatcher] Falling back to hardcoded defaults for metadata types");
|
|
1127
1176
|
return { handled: true, response: this.success({ types: ["object", "app", "plugin"] }) };
|
|
1128
1177
|
}
|
|
1129
1178
|
if (parts.length === 3 && parts[2] === "published" && (!method || method === "GET")) {
|
|
@@ -1180,7 +1229,7 @@ var HttpDispatcher = class {
|
|
|
1180
1229
|
}
|
|
1181
1230
|
return { handled: true, response: this.error("Not found", 404) };
|
|
1182
1231
|
}
|
|
1183
|
-
const singularType =
|
|
1232
|
+
const singularType = (0, import_shared.pluralToSingular)(type);
|
|
1184
1233
|
const protocol = await this.resolveService("protocol");
|
|
1185
1234
|
if (protocol && typeof protocol.getMetaItem === "function") {
|
|
1186
1235
|
try {
|
|
@@ -1212,6 +1261,18 @@ var HttpDispatcher = class {
|
|
|
1212
1261
|
} catch {
|
|
1213
1262
|
}
|
|
1214
1263
|
}
|
|
1264
|
+
const metadataService = await this.getService(import_system.CoreServiceName.enum.metadata);
|
|
1265
|
+
if (metadataService && typeof metadataService.list === "function") {
|
|
1266
|
+
try {
|
|
1267
|
+
const items = await metadataService.list(typeOrName);
|
|
1268
|
+
if (items && items.length > 0) {
|
|
1269
|
+
return { handled: true, response: this.success({ type: typeOrName, items }) };
|
|
1270
|
+
}
|
|
1271
|
+
} catch (e) {
|
|
1272
|
+
const sanitizedType = String(typeOrName).replace(/[\r\n\t]/g, "");
|
|
1273
|
+
console.debug(`[HttpDispatcher] MetadataService.list() failed for type:`, sanitizedType, "error:", e.message);
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1215
1276
|
if (broker) {
|
|
1216
1277
|
try {
|
|
1217
1278
|
if (typeOrName === "objects") {
|
|
@@ -1978,6 +2039,64 @@ var HttpDispatcher = class {
|
|
|
1978
2039
|
};
|
|
1979
2040
|
|
|
1980
2041
|
// src/dispatcher-plugin.ts
|
|
2042
|
+
function mountRouteOnServer(route, server, routePath) {
|
|
2043
|
+
const handler = async (req, res) => {
|
|
2044
|
+
try {
|
|
2045
|
+
const result = await route.handler({
|
|
2046
|
+
body: req.body,
|
|
2047
|
+
params: req.params,
|
|
2048
|
+
query: req.query
|
|
2049
|
+
});
|
|
2050
|
+
if (result.stream && result.events) {
|
|
2051
|
+
res.status(result.status);
|
|
2052
|
+
if (result.headers) {
|
|
2053
|
+
for (const [k, v] of Object.entries(result.headers)) {
|
|
2054
|
+
res.header(k, String(v));
|
|
2055
|
+
}
|
|
2056
|
+
} else {
|
|
2057
|
+
res.header("Content-Type", "text/event-stream");
|
|
2058
|
+
res.header("Cache-Control", "no-cache");
|
|
2059
|
+
res.header("Connection", "keep-alive");
|
|
2060
|
+
}
|
|
2061
|
+
if (typeof res.write === "function" && typeof res.end === "function") {
|
|
2062
|
+
for await (const event of result.events) {
|
|
2063
|
+
res.write(typeof event === "string" ? event : `data: ${JSON.stringify(event)}
|
|
2064
|
+
|
|
2065
|
+
`);
|
|
2066
|
+
}
|
|
2067
|
+
res.end();
|
|
2068
|
+
} else {
|
|
2069
|
+
const events = [];
|
|
2070
|
+
for await (const event of result.events) {
|
|
2071
|
+
events.push(event);
|
|
2072
|
+
}
|
|
2073
|
+
res.json({ events });
|
|
2074
|
+
}
|
|
2075
|
+
} else {
|
|
2076
|
+
res.status(result.status);
|
|
2077
|
+
if (result.body !== void 0) {
|
|
2078
|
+
res.json(result.body);
|
|
2079
|
+
} else {
|
|
2080
|
+
res.end();
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2083
|
+
} catch (err) {
|
|
2084
|
+
errorResponse(err, res);
|
|
2085
|
+
}
|
|
2086
|
+
};
|
|
2087
|
+
const m = route.method.toLowerCase();
|
|
2088
|
+
if (m === "get" && typeof server.get === "function") {
|
|
2089
|
+
server.get(routePath, handler);
|
|
2090
|
+
return true;
|
|
2091
|
+
} else if (m === "post" && typeof server.post === "function") {
|
|
2092
|
+
server.post(routePath, handler);
|
|
2093
|
+
return true;
|
|
2094
|
+
} else if (m === "delete" && typeof server.delete === "function") {
|
|
2095
|
+
server.delete(routePath, handler);
|
|
2096
|
+
return true;
|
|
2097
|
+
}
|
|
2098
|
+
return false;
|
|
2099
|
+
}
|
|
1981
2100
|
function sendResult(result, res) {
|
|
1982
2101
|
if (result.handled) {
|
|
1983
2102
|
if (result.response) {
|
|
@@ -2272,61 +2391,23 @@ function createDispatcherPlugin(config = {}) {
|
|
|
2272
2391
|
if (!server) return;
|
|
2273
2392
|
for (const route of routes) {
|
|
2274
2393
|
const routePath = route.path.startsWith("/api/v1") ? route.path : `${prefix}${route.path}`;
|
|
2275
|
-
|
|
2276
|
-
try {
|
|
2277
|
-
const result = await route.handler({
|
|
2278
|
-
body: req.body,
|
|
2279
|
-
params: req.params,
|
|
2280
|
-
query: req.query
|
|
2281
|
-
});
|
|
2282
|
-
if (result.stream && result.events) {
|
|
2283
|
-
res.status(result.status);
|
|
2284
|
-
if (result.headers) {
|
|
2285
|
-
for (const [k, v] of Object.entries(result.headers)) {
|
|
2286
|
-
res.header(k, v);
|
|
2287
|
-
}
|
|
2288
|
-
} else {
|
|
2289
|
-
res.header("Content-Type", "text/event-stream");
|
|
2290
|
-
res.header("Cache-Control", "no-cache");
|
|
2291
|
-
res.header("Connection", "keep-alive");
|
|
2292
|
-
}
|
|
2293
|
-
if (typeof res.write === "function" && typeof res.end === "function") {
|
|
2294
|
-
for await (const event of result.events) {
|
|
2295
|
-
res.write(typeof event === "string" ? event : `data: ${JSON.stringify(event)}
|
|
2296
|
-
|
|
2297
|
-
`);
|
|
2298
|
-
}
|
|
2299
|
-
res.end();
|
|
2300
|
-
} else {
|
|
2301
|
-
const events = [];
|
|
2302
|
-
for await (const event of result.events) {
|
|
2303
|
-
events.push(event);
|
|
2304
|
-
}
|
|
2305
|
-
res.json({ events });
|
|
2306
|
-
}
|
|
2307
|
-
} else {
|
|
2308
|
-
res.status(result.status);
|
|
2309
|
-
if (result.body !== void 0) {
|
|
2310
|
-
res.json(result.body);
|
|
2311
|
-
} else {
|
|
2312
|
-
res.end();
|
|
2313
|
-
}
|
|
2314
|
-
}
|
|
2315
|
-
} catch (err) {
|
|
2316
|
-
errorResponse(err, res);
|
|
2317
|
-
}
|
|
2318
|
-
};
|
|
2319
|
-
const m = route.method.toLowerCase();
|
|
2320
|
-
if (m === "get" && typeof server.get === "function") {
|
|
2321
|
-
server.get(routePath, handler);
|
|
2322
|
-
} else if (m === "post" && typeof server.post === "function") {
|
|
2323
|
-
server.post(routePath, handler);
|
|
2324
|
-
} else if (m === "delete" && typeof server.delete === "function") {
|
|
2325
|
-
server.delete(routePath, handler);
|
|
2326
|
-
}
|
|
2394
|
+
mountRouteOnServer(route, server, routePath);
|
|
2327
2395
|
}
|
|
2328
2396
|
ctx.logger.info(`[Dispatcher] Registered ${routes.length} AI routes`);
|
|
2329
2397
|
});
|
|
2398
|
+
const cachedRoutes = kernel.__aiRoutes;
|
|
2399
|
+
if (cachedRoutes && Array.isArray(cachedRoutes) && cachedRoutes.length > 0) {
|
|
2400
|
+
let registered = 0;
|
|
2401
|
+
for (const route of cachedRoutes) {
|
|
2402
|
+
const routePath = route.path.startsWith("/api/v1") ? route.path : `${prefix}${route.path}`;
|
|
2403
|
+
if (mountRouteOnServer(route, server, routePath)) {
|
|
2404
|
+
registered++;
|
|
2405
|
+
}
|
|
2406
|
+
}
|
|
2407
|
+
if (registered > 0) {
|
|
2408
|
+
ctx.logger.info(`[Dispatcher] Recovered ${registered} cached AI routes (hook timing fallback)`);
|
|
2409
|
+
}
|
|
2410
|
+
}
|
|
2330
2411
|
}
|
|
2331
2412
|
};
|
|
2332
2413
|
}
|