gemi 0.2.0 → 0.2.1

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.
Files changed (50) hide show
  1. package/dist/app/App.d.ts +24 -10
  2. package/dist/app/App.d.ts.map +1 -1
  3. package/dist/app/flattenViewRoutes.d.ts +12 -0
  4. package/dist/app/flattenViewRoutes.d.ts.map +1 -0
  5. package/dist/app/index.js +198 -89
  6. package/dist/bin/gemi +0 -0
  7. package/dist/client/ClientRouter.d.ts +1 -1
  8. package/dist/client/ClientRouter.d.ts.map +1 -1
  9. package/dist/client/ClientRouterContext.d.ts.map +1 -1
  10. package/dist/client/ServerDataProvider.d.ts +1 -1
  11. package/dist/client/ServerDataProvider.d.ts.map +1 -1
  12. package/dist/client/createRoot.d.ts +3 -0
  13. package/dist/client/createRoot.d.ts.map +1 -0
  14. package/dist/client/helpers/flattenComponentTree.d.ts +3 -0
  15. package/dist/client/helpers/flattenComponentTree.d.ts.map +1 -0
  16. package/dist/client/index-DiGoPyjN.mjs +717 -0
  17. package/dist/client/index.d.ts +2 -2
  18. package/dist/client/index.d.ts.map +1 -1
  19. package/dist/client/index.js +29132 -1288
  20. package/dist/client/init.d.ts +3 -0
  21. package/dist/client/init.d.ts.map +1 -0
  22. package/dist/email/index.js +111 -123
  23. package/dist/http/ApiRouter.d.ts +11 -11
  24. package/dist/http/ApiRouter.d.ts.map +1 -1
  25. package/dist/http/Controller.d.ts +3 -0
  26. package/dist/http/Controller.d.ts.map +1 -1
  27. package/dist/http/Router.d.ts +1 -1
  28. package/dist/http/Router.d.ts.map +1 -1
  29. package/dist/http/ViewRouter.d.ts +2 -2
  30. package/dist/http/ViewRouter.d.ts.map +1 -1
  31. package/dist/http/index.js +8 -4
  32. package/dist/runtime/index.js +8 -0
  33. package/dist/server/imageHandler.d.ts +2 -0
  34. package/dist/server/imageHandler.d.ts.map +1 -0
  35. package/dist/vite/index.js +35 -0
  36. package/package.json +7 -5
  37. package/dist/ApiRouter.d.ts +0 -5
  38. package/dist/ApiRouter.d.ts.map +0 -1
  39. package/dist/Controller.d.ts +0 -3
  40. package/dist/Controller.d.ts.map +0 -1
  41. package/dist/ViewRouter.d.ts +0 -3
  42. package/dist/ViewRouter.d.ts.map +0 -1
  43. package/dist/client/Root.d.ts +0 -2
  44. package/dist/client/Root.d.ts.map +0 -1
  45. package/dist/client/main.d.ts +0 -2
  46. package/dist/client/main.d.ts.map +0 -1
  47. package/dist/index.d.ts +0 -4
  48. package/dist/index.d.ts.map +0 -1
  49. package/dist/types.d.ts +0 -4
  50. package/dist/types.d.ts.map +0 -1
package/dist/app/App.d.ts CHANGED
@@ -7,6 +7,20 @@ import type { ComponentTree } from "../client/types";
7
7
  import type { Plugin } from "./Plugin";
8
8
  import type { Middleware } from "../http/Middleware";
9
9
  import type { ServerWebSocket } from "bun";
10
+ import { ComponentType } from "react";
11
+ interface RenderParams {
12
+ styles: string[];
13
+ views: Record<string, string>;
14
+ manifest: Record<string, any>;
15
+ serverManifest: Record<string, any>;
16
+ }
17
+ interface AppParams {
18
+ viewRouter: new (app: App) => ViewRouter;
19
+ apiRouter: new (app: App) => ApiRouter;
20
+ plugins?: (new () => Plugin)[];
21
+ middlewareAliases?: Record<string, new () => Middleware>;
22
+ root: ComponentType;
23
+ }
10
24
  export declare class App {
11
25
  private flatViewRoutes;
12
26
  private flatApiRoutes;
@@ -14,17 +28,17 @@ export declare class App {
14
28
  name: string;
15
29
  private appId;
16
30
  private componentTree;
17
- private middlewareAliases;
18
- constructor(params: {
19
- viewRouter: new (app: App) => ViewRouter;
20
- apiRouter: new (app: App) => ApiRouter;
21
- plugins?: (new () => Plugin)[];
22
- middlewareAliases?: Record<string, new () => Middleware>;
23
- });
31
+ middlewareAliases: Record<string, new () => Middleware>;
32
+ devVersion: number;
33
+ private params;
34
+ private apiRouter;
35
+ private viewRouter;
36
+ private Root;
37
+ constructor(params: AppParams);
38
+ private prepare;
24
39
  printName(): void;
25
40
  getComponentTree(): ComponentTree;
26
41
  private flattenApiRoutes;
27
- private flattenViewRoutes;
28
42
  private resolvePageData;
29
43
  handleRequest(req: Request): Promise<{
30
44
  kind: string;
@@ -50,7 +64,6 @@ export declare class App {
50
64
  headers: Record<string, any>;
51
65
  head?: undefined;
52
66
  status?: undefined;
53
- buildId?: undefined;
54
67
  } | {
55
68
  kind: string;
56
69
  data: {
@@ -78,9 +91,9 @@ export declare class App {
78
91
  ETag: string;
79
92
  };
80
93
  status: number;
81
- buildId: string;
82
94
  meta?: undefined;
83
95
  }>;
96
+ fetch(req: Request, renderParams: RenderParams): Promise<Response>;
84
97
  private handleWebSocketMessage;
85
98
  private handleWebSocketOpen;
86
99
  private handleWebSocketClose;
@@ -90,4 +103,5 @@ export declare class App {
90
103
  close: (ws: ServerWebSocket, code: number, reason: string) => void;
91
104
  };
92
105
  }
106
+ export {};
93
107
  //# sourceMappingURL=App.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../app/App.ts"],"names":[],"mappings":";;;AAEA,OAAO,KAAK,EAGV,SAAS,EACV,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,UAAU,EAGX,MAAM,oBAAoB,CAAC;AAI5B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,KAAK,CAAC;AAkD3C,qBAAa,GAAG;IACd,OAAO,CAAC,cAAc,CAGf;IACP,OAAO,CAAC,aAAa,CAA2B;IAChD,OAAO,CAAC,aAAa,CAAgC;IAC9C,IAAI,SAAS;IACpB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,iBAAiB,CAA4C;gBAEzD,MAAM,EAAE;QAClB,UAAU,EAAE,KAAK,GAAG,EAAE,GAAG,KAAK,UAAU,CAAC;QACzC,SAAS,EAAE,KAAK,GAAG,EAAE,GAAG,KAAK,SAAS,CAAC;QACvC,OAAO,CAAC,EAAE,CAAC,UAAU,MAAM,CAAC,EAAE,CAAC;QAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,UAAU,CAAC,CAAC;KAC1D;IAoCM,SAAS;IAIT,gBAAgB;IAIvB,OAAO,CAAC,gBAAgB;IA6DxB,OAAO,CAAC,iBAAiB;YA6EX,eAAe;IAwDvB,aAAa,CAAC,GAAG,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAwJhC,OAAO,CAAC,sBAAsB,CAGtB;IACR,OAAO,CAAC,mBAAmB,CAEzB;IACF,OAAO,CAAC,oBAAoB,CAM1B;IAEF,SAAS;sBAdH,eAAe,WACV,MAAM,GAAG,MAAM;mBAES,eAAe;oBAI5C,eAAe,QACb,MAAM,UACJ,MAAM;MASd;CACH"}
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../app/App.ts"],"names":[],"mappings":";;;AAAA,OAAO,KAAK,EAGV,SAAS,EACV,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAsB,MAAM,oBAAoB,CAAC;AAKpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIrD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,KAAK,CAAC;AAM3C,OAAO,EAAE,aAAa,EAA2B,MAAM,OAAO,CAAC;AAE/D,UAAU,YAAY;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CACrC;AAoCD,UAAU,SAAS;IACjB,UAAU,EAAE,KAAK,GAAG,EAAE,GAAG,KAAK,UAAU,CAAC;IACzC,SAAS,EAAE,KAAK,GAAG,EAAE,GAAG,KAAK,SAAS,CAAC;IACvC,OAAO,CAAC,EAAE,CAAC,UAAU,MAAM,CAAC,EAAE,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,UAAU,CAAC,CAAC;IACzD,IAAI,EAAE,aAAa,CAAC;CACrB;AAED,qBAAa,GAAG;IACd,OAAO,CAAC,cAAc,CAGf;IACP,OAAO,CAAC,aAAa,CAA2B;IAChD,OAAO,CAAC,aAAa,CAAgC;IAC9C,IAAI,SAAS;IACpB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,aAAa,CAAgB;IAC9B,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,UAAU,CAAC,CAAM;IAC7D,UAAU,SAAK;IACtB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,IAAI,CAAgB;gBAEhB,MAAM,EAAE,SAAS;IAY7B,OAAO,CAAC,OAAO;IAqCR,SAAS;IAIT,gBAAgB;IAIvB,OAAO,CAAC,gBAAgB;YA6DV,eAAe;IAyDvB,aAAa,CAAC,GAAG,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAuJ1B,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,YAAY;IAyGpD,OAAO,CAAC,sBAAsB,CAGtB;IACR,OAAO,CAAC,mBAAmB,CAEzB;IACF,OAAO,CAAC,oBAAoB,CAM1B;IAEF,SAAS;sBAdH,eAAe,WACV,MAAM,GAAG,MAAM;mBAES,eAAe;oBAI5C,eAAe,QACb,MAAM,UACJ,MAAM;MASd;CACH"}
@@ -0,0 +1,12 @@
1
+ import type { ComponentTree } from "../client/types";
2
+ import { type ViewChildren, type ViewRouteExec } from "../http/ViewRouter";
3
+ import type { App } from "./App";
4
+ export declare function flattenViewRoutes(routes: ViewChildren, app: App): {
5
+ flatRoutes: Record<string, {
6
+ exec: ViewRouteExec[];
7
+ middleware: any[];
8
+ }>;
9
+ routeManifest: Record<string, string[]>;
10
+ componentTree: ComponentTree;
11
+ };
12
+ //# sourceMappingURL=flattenViewRoutes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flattenViewRoutes.d.ts","sourceRoot":"","sources":["../../app/flattenViewRoutes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,aAAa,EACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAEjC,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,GAAG;;cAGpD,aAAa,EAAE;oBAAc,GAAG,EAAE;;;;EAwE7C"}
package/dist/app/index.js CHANGED
@@ -1311,7 +1311,91 @@ class RequestBreakerError extends Error {
1311
1311
  import {AsyncLocalStorage} from "async_hooks";
1312
1312
  var requestContext = new AsyncLocalStorage;
1313
1313
 
1314
+ // app/flattenViewRoutes.ts
1315
+ function flattenViewRoutes(routes, app) {
1316
+ const flatRoutes = {};
1317
+ const routeManifest = {};
1318
+ const componentTree = [];
1319
+ for (const [rootPath, viewConfigOrViewRouter] of Object.entries(routes)) {
1320
+ let children;
1321
+ let rootHandler = async () => ({});
1322
+ let rootMiddleware = [];
1323
+ let layoutViewPath = null;
1324
+ if ("prepare" in viewConfigOrViewRouter) {
1325
+ const result2 = viewConfigOrViewRouter.prepare();
1326
+ children = result2.children;
1327
+ rootHandler = result2.exec;
1328
+ flatRoutes[rootPath] = {
1329
+ exec: [rootHandler],
1330
+ middleware: result2.middlewares
1331
+ };
1332
+ if (Object.keys(children).length > 0) {
1333
+ layoutViewPath = result2.viewPath;
1334
+ } else {
1335
+ routeManifest[rootPath] = [result2.viewPath];
1336
+ componentTree.push([result2.viewPath]);
1337
+ }
1338
+ } else {
1339
+ const router = new viewConfigOrViewRouter(app);
1340
+ const middlewares = router.middlewares.map((alias) => {
1341
+ if (app.middlewareAliases?.[alias]) {
1342
+ const middleware = new app.middlewareAliases[alias];
1343
+ return middleware.run;
1344
+ }
1345
+ }).filter(Boolean);
1346
+ rootMiddleware.push(router.middleware, ...middlewares);
1347
+ children = router.routes;
1348
+ }
1349
+ const result = flattenViewRoutes(children, app);
1350
+ if (layoutViewPath) {
1351
+ componentTree.push({ [layoutViewPath]: result.componentTree });
1352
+ } else {
1353
+ componentTree.push(...result.componentTree);
1354
+ }
1355
+ for (const [path, handlers] of Object.entries(result.flatRoutes)) {
1356
+ const subPath = path === "/" ? "" : path;
1357
+ const _rootPath = rootPath === "/" ? "" : rootPath;
1358
+ const finalPath = `${_rootPath}${subPath}` === "" ? "/" : `${_rootPath}${subPath}`;
1359
+ flatRoutes[finalPath] = {
1360
+ exec: [rootHandler, ...handlers.exec],
1361
+ middleware: [...rootMiddleware, ...handlers.middleware]
1362
+ };
1363
+ if (layoutViewPath) {
1364
+ routeManifest[finalPath] = [
1365
+ layoutViewPath,
1366
+ ...result.routeManifest[path] ?? []
1367
+ ];
1368
+ } else {
1369
+ routeManifest[finalPath] = [...result.routeManifest[path] ?? []];
1370
+ }
1371
+ }
1372
+ }
1373
+ return {
1374
+ flatRoutes,
1375
+ routeManifest,
1376
+ componentTree
1377
+ };
1378
+ }
1379
+
1380
+ // client/helpers/flattenComponentTree.ts
1381
+ function flattenComponentTree(componentTree) {
1382
+ const out = [];
1383
+ for (const section of componentTree.flat()) {
1384
+ if (typeof section === "string") {
1385
+ out.push(section);
1386
+ } else {
1387
+ for (const [key, value] of Object.entries(section)) {
1388
+ out.push(key);
1389
+ out.push(...flattenComponentTree(value));
1390
+ }
1391
+ }
1392
+ }
1393
+ return out;
1394
+ }
1395
+
1314
1396
  // app/App.ts
1397
+ import {renderToReadableStream} from "react-dom/server.browser";
1398
+ import {createElement, Fragment} from "react";
1315
1399
  var prepareViewData = function(result) {
1316
1400
  return result.reduce((acc, next) => {
1317
1401
  return {
@@ -1326,23 +1410,11 @@ var prepareViewData = function(result) {
1326
1410
  head: {
1327
1411
  ...acc.head,
1328
1412
  title: next?.head?.title ?? acc.head?.title ?? "Gemi App",
1329
- meta: [...acc.head.meta, ...next?.head?.meta ?? []],
1330
- link: [...acc.head.link, ...next?.head?.link ?? []]
1413
+ meta: [...acc.head?.meta ?? [], ...next?.head?.meta ?? []],
1414
+ link: [...acc.head?.link ?? [], ...next?.head?.link ?? []]
1331
1415
  }
1332
1416
  };
1333
- }, { pageData: {}, headers: {}, head: defaultHead });
1334
- };
1335
- var defaultHead = {
1336
- title: "The UI Agents",
1337
- meta: [
1338
- { charSet: "utf-8" },
1339
- { name: "viewport", content: "width=device-width, initial-scale=1" },
1340
- {
1341
- name: "description",
1342
- content: "Fastest way to start your B2B SaaS journey. Immediately access to high quality templates and slingshot your startup into the future."
1343
- }
1344
- ],
1345
- link: [{ rel: "icon", href: "/favicon.ico" }]
1417
+ }, { pageData: {}, headers: {}, head: {} });
1346
1418
  };
1347
1419
 
1348
1420
  class App {
@@ -1353,13 +1425,29 @@ class App {
1353
1425
  appId;
1354
1426
  componentTree;
1355
1427
  middlewareAliases = {};
1428
+ devVersion = 0;
1429
+ params;
1430
+ apiRouter;
1431
+ viewRouter;
1432
+ Root;
1356
1433
  constructor(params) {
1434
+ console.log("[App] initialized");
1435
+ this.params = params;
1436
+ this.apiRouter = params.apiRouter;
1437
+ this.viewRouter = params.viewRouter;
1438
+ this.Root = params.root;
1439
+ this.prepare();
1440
+ console.log("[App] routes are prepared");
1441
+ this.appId = generateETag(Date.now());
1442
+ }
1443
+ prepare() {
1444
+ const params = this.params;
1357
1445
  this.middlewareAliases = params.middlewareAliases ?? {};
1358
1446
  let viewRouters = {
1359
- "/": params.viewRouter
1447
+ "/": this.viewRouter
1360
1448
  };
1361
1449
  let apiRouters = {
1362
- "/": params.apiRouter
1450
+ "/": this.apiRouter
1363
1451
  };
1364
1452
  for (const Plugin of params.plugins ?? []) {
1365
1453
  const plugin = new Plugin;
@@ -1376,12 +1464,11 @@ class App {
1376
1464
  };
1377
1465
  }
1378
1466
  }
1379
- const { flatRoutes, routeManifest, componentTree } = this.flattenViewRoutes(viewRouters);
1467
+ const { flatRoutes, routeManifest, componentTree } = flattenViewRoutes(viewRouters, this);
1380
1468
  this.componentTree = componentTree;
1381
1469
  this.routeManifest = routeManifest;
1382
1470
  this.flatViewRoutes = flatRoutes;
1383
1471
  this.flatApiRoutes = this.flattenApiRoutes(apiRouters);
1384
- this.appId = generateETag(Date.now());
1385
1472
  }
1386
1473
  printName() {
1387
1474
  console.log(this.name);
@@ -1441,70 +1528,6 @@ class App {
1441
1528
  }
1442
1529
  return flatApiRoutes;
1443
1530
  }
1444
- flattenViewRoutes(routes) {
1445
- const flatRoutes = {};
1446
- const routeManifest = {};
1447
- const componentTree = [];
1448
- for (const [rootPath, viewConfigOrViewRouter] of Object.entries(routes)) {
1449
- let children;
1450
- let rootHandler = async () => ({});
1451
- let rootMiddleware = [];
1452
- let layoutViewPath = null;
1453
- if ("prepare" in viewConfigOrViewRouter) {
1454
- const result2 = viewConfigOrViewRouter.prepare();
1455
- children = result2.children;
1456
- rootHandler = result2.exec;
1457
- flatRoutes[rootPath] = {
1458
- exec: [rootHandler],
1459
- middleware: result2.middlewares
1460
- };
1461
- if (Object.keys(children).length > 0) {
1462
- layoutViewPath = result2.viewPath;
1463
- } else {
1464
- routeManifest[rootPath] = [result2.viewPath];
1465
- componentTree.push([result2.viewPath]);
1466
- }
1467
- } else {
1468
- const router = new viewConfigOrViewRouter(this);
1469
- const middlewares = router.middlewares.map((alias) => {
1470
- if (this.middlewareAliases?.[alias]) {
1471
- const middleware = new this.middlewareAliases[alias];
1472
- return middleware.run;
1473
- }
1474
- }).filter(Boolean);
1475
- rootMiddleware.push(router.middleware, ...middlewares);
1476
- children = router.routes;
1477
- }
1478
- const result = this.flattenViewRoutes(children);
1479
- if (layoutViewPath) {
1480
- componentTree.push({ [layoutViewPath]: result.componentTree });
1481
- } else {
1482
- componentTree.push(...result.componentTree);
1483
- }
1484
- for (const [path, handlers] of Object.entries(result.flatRoutes)) {
1485
- const subPath = path === "/" ? "" : path;
1486
- const _rootPath = rootPath === "/" ? "" : rootPath;
1487
- const finalPath = `${_rootPath}${subPath}` === "" ? "/" : `${_rootPath}${subPath}`;
1488
- flatRoutes[finalPath] = {
1489
- exec: [rootHandler, ...handlers.exec],
1490
- middleware: [...rootMiddleware, ...handlers.middleware]
1491
- };
1492
- if (layoutViewPath) {
1493
- routeManifest[finalPath] = [
1494
- layoutViewPath,
1495
- ...result.routeManifest[path] ?? []
1496
- ];
1497
- } else {
1498
- routeManifest[finalPath] = [...result.routeManifest[path] ?? []];
1499
- }
1500
- }
1501
- }
1502
- return {
1503
- flatRoutes,
1504
- routeManifest,
1505
- componentTree
1506
- };
1507
- }
1508
1531
  async resolvePageData(req) {
1509
1532
  const url = new URL(req.url);
1510
1533
  let handlers = [];
@@ -1528,15 +1551,16 @@ class App {
1528
1551
  ...await middleware(req2, ctx)
1529
1552
  };
1530
1553
  };
1531
- }, (req2, ctx) => Promise.resolve({}));
1554
+ }, (_req, _ctx) => Promise.resolve({}));
1532
1555
  const reqCtx = new Map;
1533
1556
  const result = await requestContext.run(reqCtx, async () => {
1534
1557
  await reqWithMiddlewares(req, reqCtx);
1535
- return await Promise.all(handlers.map((fn) => fn(req, params)));
1558
+ return await Promise.all(handlers.map((fn) => fn(req, params, this)));
1536
1559
  });
1537
1560
  let is404 = false;
1538
1561
  for (const res of result) {
1539
- if (Object.values(res.data ?? {})[0]?.status === 404) {
1562
+ const [data] = Object.values(res.data ?? {});
1563
+ if (data?.status === 404) {
1540
1564
  is404 = true;
1541
1565
  break;
1542
1566
  }
@@ -1582,7 +1606,7 @@ class App {
1582
1606
  if (exec) {
1583
1607
  let result = {};
1584
1608
  try {
1585
- result = await exec(req, params);
1609
+ result = await exec(req, params, this);
1586
1610
  } catch (err) {
1587
1611
  if (err instanceof RequestBreakerError) {
1588
1612
  return {
@@ -1673,11 +1697,96 @@ class App {
1673
1697
  ETag: this.appId,
1674
1698
  ...cookieHeaders
1675
1699
  },
1676
- status: is404 ? 404 : 200,
1677
- buildId: this.appId
1700
+ status: is404 ? 404 : 200
1678
1701
  };
1679
1702
  }
1680
1703
  }
1704
+ async fetch(req, renderParams) {
1705
+ const result = await this.handleRequest(req);
1706
+ if (result.kind === "viewError") {
1707
+ const { kind, ...payload } = result;
1708
+ return new Response(null, {
1709
+ ...payload
1710
+ });
1711
+ }
1712
+ if (result.kind === "apiError") {
1713
+ const { kind, data, ...payload } = result;
1714
+ return new Response(JSON.stringify(data), {
1715
+ ...payload
1716
+ });
1717
+ }
1718
+ if (!result) {
1719
+ return new Response("Not found", { status: 404 });
1720
+ }
1721
+ if (result.kind === "viewData") {
1722
+ const { data, headers, head } = result;
1723
+ return new Response(JSON.stringify({
1724
+ data,
1725
+ head
1726
+ }), {
1727
+ headers: {
1728
+ ...headers,
1729
+ "Content-Type": "application/json"
1730
+ }
1731
+ });
1732
+ }
1733
+ if (result.kind === "view") {
1734
+ const { data, headers, head, status } = result;
1735
+ const { styles, views, manifest, serverManifest, ...renderOptions } = renderParams;
1736
+ const viewImportMap = {};
1737
+ let appDir = null;
1738
+ const template = (viewName, path) => `"${viewName}": () => import("${path}")`;
1739
+ const templates = [];
1740
+ for (const fileName of flattenComponentTree(this.componentTree)) {
1741
+ if (!manifest) {
1742
+ appDir = `${process.env.APP_DIR}`;
1743
+ const mod = await import(`${appDir}/views/${fileName}.tsx`);
1744
+ viewImportMap[fileName] = mod.default;
1745
+ templates.push(template(fileName, `${appDir}/views/${fileName}.tsx`));
1746
+ } else {
1747
+ const { file } = serverManifest[`app/views/${fileName}.tsx`];
1748
+ const mod = await import(`${process.env.DIST_DIR}/server/${file}`);
1749
+ viewImportMap[fileName] = mod.default;
1750
+ const clientFile = manifest[`app/views/${fileName}.tsx`];
1751
+ if (clientFile) {
1752
+ templates.push(template(fileName, `/${clientFile.file}`));
1753
+ }
1754
+ }
1755
+ }
1756
+ const loaders = `{${templates.join(",")}}`;
1757
+ const stream = await renderToReadableStream(createElement(Fragment, {
1758
+ children: [
1759
+ styles,
1760
+ createElement(this.Root, {
1761
+ head,
1762
+ data,
1763
+ viewImportMap
1764
+ })
1765
+ ]
1766
+ }), {
1767
+ bootstrapScriptContent: `window.__GEMI_DATA__ = ${JSON.stringify(data)}; window.loaders=${loaders}`,
1768
+ ...renderOptions
1769
+ });
1770
+ return new Response(stream, {
1771
+ status,
1772
+ headers: {
1773
+ "Content-Type": "text/html",
1774
+ ...headers
1775
+ }
1776
+ });
1777
+ }
1778
+ if (result.kind === "api") {
1779
+ const { data, headers, status } = result;
1780
+ return new Response(JSON.stringify(data), {
1781
+ status,
1782
+ headers: {
1783
+ "Content-Type": "application/json",
1784
+ ...headers
1785
+ }
1786
+ });
1787
+ }
1788
+ return new Response("Not found", { status: 404 });
1789
+ }
1681
1790
  handleWebSocketMessage = (ws, message) => {
1682
1791
  };
1683
1792
  handleWebSocketOpen = (ws) => {
package/dist/bin/gemi CHANGED
Binary file
@@ -1,4 +1,4 @@
1
1
  export declare const ClientRouter: (props: {
2
- components: any;
2
+ viewImportMap?: Record<string, any>;
3
3
  }) => import("react/jsx-runtime").JSX.Element;
4
4
  //# sourceMappingURL=ClientRouter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ClientRouter.d.ts","sourceRoot":"","sources":["../../client/ClientRouter.tsx"],"names":[],"mappings":"AA4FA,eAAO,MAAM,YAAY,UAAW;IAAE,UAAU,EAAE,GAAG,CAAA;CAAE,4CAoCtD,CAAC"}
1
+ {"version":3,"file":"ClientRouter.d.ts","sourceRoot":"","sources":["../../client/ClientRouter.tsx"],"names":[],"mappings":"AA2HA,eAAO,MAAM,YAAY,UAAW;IAClC,aAAa,CAAC,EAAE,OAAO,MAAM,EAAE,GAAG,CAAC,CAAC;CACrC,4CAwBA,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ClientRouterContext.d.ts","sourceRoot":"","sources":["../../client/ClientRouterContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,EAAE,EACP,KAAK,QAAQ,EAEd,MAAM,SAAS,CAAC;AACjB,OAAO,EAOL,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACvB,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAG3C,UAAU,wBAAwB;IAChC,kBAAkB,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACtC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;IACxD,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,GAAG,CAAC;IAClC,eAAe,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,eAAO,MAAM,mBAAmB,mDAE/B,CAAC;AAEF,UAAU,yBAAyB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACxC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,eAAO,MAAM,oBAAoB,UACxB,kBAAkB,yBAAyB,CAAC,4CA0GpD,CAAC;AAUF,wBAAgB,WAAW,aAS1B;AAED,wBAAgB,SAAS,2BAGxB;AAED,wBAAgB,SAAS;eAGJ,EAAE,UAAU,GAAG;EAsBnC;AAED,eAAO,MAAM,IAAI,UACR,KAAK,eAAe,GAAG,CAAC,EAAE,MAAM,CAAC,GAAG;IAAE,IAAI,EAAE,EAAE,CAAA;CAAE,4CA0BxD,CAAC"}
1
+ {"version":3,"file":"ClientRouterContext.d.ts","sourceRoot":"","sources":["../../client/ClientRouterContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,EAAE,EACP,KAAK,QAAQ,EAEd,MAAM,SAAS,CAAC;AACjB,OAAO,EAOL,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACvB,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,UAAU,wBAAwB;IAChC,kBAAkB,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACtC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;IACxD,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,GAAG,CAAC;IAClC,eAAe,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,eAAO,MAAM,mBAAmB,mDAE/B,CAAC;AAEF,UAAU,yBAAyB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACxC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,eAAO,MAAM,oBAAoB,UACxB,kBAAkB,yBAAyB,CAAC,4CA2GpD,CAAC;AAUF,wBAAgB,WAAW,aAU1B;AAED,wBAAgB,SAAS,2BAGxB;AAED,wBAAgB,SAAS;eAGJ,EAAE,UAAU,GAAG;EAsBnC;AAED,eAAO,MAAM,IAAI,UACR,KAAK,eAAe,GAAG,CAAC,EAAE,MAAM,CAAC,GAAG;IAAE,IAAI,EAAE,EAAE,CAAA;CAAE,4CA0BxD,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { type PropsWithChildren } from "react";
2
2
  import type { ComponentTree } from "./types";
3
3
  type Data = Record<string, any>;
4
- interface ServerDataContextValue {
4
+ export interface ServerDataContextValue {
5
5
  routeManifest: Record<string, string[]>;
6
6
  pageData: Record<string, Record<string, Data>>;
7
7
  router: {
@@ -1 +1 @@
1
- {"version":3,"file":"ServerDataProvider.d.ts","sourceRoot":"","sources":["../../client/ServerDataProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAEhC,UAAU,sBAAsB;IAC9B,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACxC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IAC/C,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC5B,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,OAAO,CAAC;KAChB,CAAC;IACF,aAAa,EAAE,aAAa,CAAC;IAC7B,IAAI,EAAE;QACJ,IAAI,EAAE;YACJ,IAAI,EAAE,MAAM,CAAC;YACb,KAAK,EAAE,MAAM,CAAC;YACd,QAAQ,EAAE,KAAK,CAAC;gBACd,cAAc,EAAE,MAAM,CAAC;gBACvB,IAAI,EAAE,MAAM,CAAC;aACd,CAAC,CAAC;YACH,UAAU,EAAE,MAAM,CAAC;YACnB,EAAE,EAAE,MAAM,CAAC;SACZ,CAAC;KACH,CAAC;CACH;AAED,eAAO,MAAM,iBAAiB,iDAA8C,CAAC;AAE7E,UAAU,uBAAuB;IAC/B,KAAK,CAAC,EAAE,sBAAsB,CAAC;CAChC;AAED,eAAO,MAAM,kBAAkB,UACtB,kBAAkB,uBAAuB,CAAC,4CAelD,CAAC"}
1
+ {"version":3,"file":"ServerDataProvider.d.ts","sourceRoot":"","sources":["../../client/ServerDataProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAEhC,MAAM,WAAW,sBAAsB;IACrC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACxC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IAC/C,MAAM,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC5B,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,OAAO,CAAC;KAChB,CAAC;IACF,aAAa,EAAE,aAAa,CAAC;IAC7B,IAAI,EAAE;QACJ,IAAI,EAAE;YACJ,IAAI,EAAE,MAAM,CAAC;YACb,KAAK,EAAE,MAAM,CAAC;YACd,QAAQ,EAAE,KAAK,CAAC;gBACd,cAAc,EAAE,MAAM,CAAC;gBACvB,IAAI,EAAE,MAAM,CAAC;aACd,CAAC,CAAC;YACH,UAAU,EAAE,MAAM,CAAC;YACnB,EAAE,EAAE,MAAM,CAAC;SACZ,CAAC;KACH,CAAC;CACH;AAED,eAAO,MAAM,iBAAiB,iDAA8C,CAAC;AAE7E,UAAU,uBAAuB;IAC/B,KAAK,CAAC,EAAE,sBAAsB,CAAC;CAChC;AAED,eAAO,MAAM,kBAAkB,UACtB,kBAAkB,uBAAuB,CAAC,4CAgBlD,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type ComponentType } from "react";
2
+ export declare function createRoot(RootLayout: ComponentType<any>): (props: any) => import("react/jsx-runtime").JSX.Element;
3
+ //# sourceMappingURL=createRoot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createRoot.d.ts","sourceRoot":"","sources":["../../client/createRoot.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAK3C,wBAAgB,UAAU,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,CAAC,WACxC,GAAG,6CAOnB"}
@@ -0,0 +1,3 @@
1
+ import type { ComponentTree } from "../types";
2
+ export declare function flattenComponentTree(componentTree: ComponentTree): any[];
3
+ //# sourceMappingURL=flattenComponentTree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flattenComponentTree.d.ts","sourceRoot":"","sources":["../../../client/helpers/flattenComponentTree.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,aAAa,SAahE"}