@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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @objectstack/runtime@4.0.2 build /home/runner/work/framework/framework/packages/runtime
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
  CLI Building entry: src/index.ts
@@ -10,13 +10,13 @@
10
10
  CLI Cleaning output folder
11
11
  ESM Build start
12
12
  CJS Build start
13
- ESM dist/index.js 94.32 KB
14
- ESM dist/index.js.map 204.99 KB
15
- ESM ⚡️ Build success in 155ms
16
- CJS dist/index.cjs 96.91 KB
17
- CJS dist/index.cjs.map 205.06 KB
18
- CJS ⚡️ Build success in 156ms
13
+ ESM dist/index.js 98.02 KB
14
+ ESM dist/index.js.map 212.66 KB
15
+ ESM ⚡️ Build success in 153ms
16
+ CJS dist/index.cjs 100.63 KB
17
+ CJS dist/index.cjs.map 212.72 KB
18
+ CJS ⚡️ Build success in 153ms
19
19
  DTS Build start
20
- DTS ⚡️ Build success in 3326ms
20
+ DTS ⚡️ Build success in 3771ms
21
21
  DTS dist/index.d.ts 26.00 KB
22
22
  DTS dist/index.d.cts 26.00 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # @objectstack/runtime
2
2
 
3
+ ## 4.0.3
4
+
5
+ ### Patch Changes
6
+
7
+ - @objectstack/spec@4.0.3
8
+ - @objectstack/core@4.0.3
9
+ - @objectstack/types@4.0.3
10
+ - @objectstack/rest@4.0.3
11
+
3
12
  ## 4.0.2
4
13
 
5
14
  ### Patch Changes
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 = type.endsWith("s") ? type.slice(0, -1) : type;
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
- const handler = async (req, res) => {
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
  }