gemi 0.2.0 → 0.2.2

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 +196 -89
  6. package/dist/bin/gemi +0 -0
  7. package/dist/client/ClientRouter.d.ts +3 -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 +29142 -1291
  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 +8 -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;IAU7B,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,27 @@ 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
+ this.params = params;
1435
+ this.apiRouter = params.apiRouter;
1436
+ this.viewRouter = params.viewRouter;
1437
+ this.Root = params.root;
1438
+ this.prepare();
1439
+ this.appId = generateETag(Date.now());
1440
+ }
1441
+ prepare() {
1442
+ const params = this.params;
1357
1443
  this.middlewareAliases = params.middlewareAliases ?? {};
1358
1444
  let viewRouters = {
1359
- "/": params.viewRouter
1445
+ "/": this.viewRouter
1360
1446
  };
1361
1447
  let apiRouters = {
1362
- "/": params.apiRouter
1448
+ "/": this.apiRouter
1363
1449
  };
1364
1450
  for (const Plugin of params.plugins ?? []) {
1365
1451
  const plugin = new Plugin;
@@ -1376,12 +1462,11 @@ class App {
1376
1462
  };
1377
1463
  }
1378
1464
  }
1379
- const { flatRoutes, routeManifest, componentTree } = this.flattenViewRoutes(viewRouters);
1465
+ const { flatRoutes, routeManifest, componentTree } = flattenViewRoutes(viewRouters, this);
1380
1466
  this.componentTree = componentTree;
1381
1467
  this.routeManifest = routeManifest;
1382
1468
  this.flatViewRoutes = flatRoutes;
1383
1469
  this.flatApiRoutes = this.flattenApiRoutes(apiRouters);
1384
- this.appId = generateETag(Date.now());
1385
1470
  }
1386
1471
  printName() {
1387
1472
  console.log(this.name);
@@ -1441,70 +1526,6 @@ class App {
1441
1526
  }
1442
1527
  return flatApiRoutes;
1443
1528
  }
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
1529
  async resolvePageData(req) {
1509
1530
  const url = new URL(req.url);
1510
1531
  let handlers = [];
@@ -1528,15 +1549,16 @@ class App {
1528
1549
  ...await middleware(req2, ctx)
1529
1550
  };
1530
1551
  };
1531
- }, (req2, ctx) => Promise.resolve({}));
1552
+ }, (_req, _ctx) => Promise.resolve({}));
1532
1553
  const reqCtx = new Map;
1533
1554
  const result = await requestContext.run(reqCtx, async () => {
1534
1555
  await reqWithMiddlewares(req, reqCtx);
1535
- return await Promise.all(handlers.map((fn) => fn(req, params)));
1556
+ return await Promise.all(handlers.map((fn) => fn(req, params, this)));
1536
1557
  });
1537
1558
  let is404 = false;
1538
1559
  for (const res of result) {
1539
- if (Object.values(res.data ?? {})[0]?.status === 404) {
1560
+ const [data] = Object.values(res.data ?? {});
1561
+ if (data?.status === 404) {
1540
1562
  is404 = true;
1541
1563
  break;
1542
1564
  }
@@ -1582,7 +1604,7 @@ class App {
1582
1604
  if (exec) {
1583
1605
  let result = {};
1584
1606
  try {
1585
- result = await exec(req, params);
1607
+ result = await exec(req, params, this);
1586
1608
  } catch (err) {
1587
1609
  if (err instanceof RequestBreakerError) {
1588
1610
  return {
@@ -1673,11 +1695,96 @@ class App {
1673
1695
  ETag: this.appId,
1674
1696
  ...cookieHeaders
1675
1697
  },
1676
- status: is404 ? 404 : 200,
1677
- buildId: this.appId
1698
+ status: is404 ? 404 : 200
1678
1699
  };
1679
1700
  }
1680
1701
  }
1702
+ async fetch(req, renderParams) {
1703
+ const result = await this.handleRequest(req);
1704
+ if (result.kind === "viewError") {
1705
+ const { kind, ...payload } = result;
1706
+ return new Response(null, {
1707
+ ...payload
1708
+ });
1709
+ }
1710
+ if (result.kind === "apiError") {
1711
+ const { kind, data, ...payload } = result;
1712
+ return new Response(JSON.stringify(data), {
1713
+ ...payload
1714
+ });
1715
+ }
1716
+ if (!result) {
1717
+ return new Response("Not found", { status: 404 });
1718
+ }
1719
+ if (result.kind === "viewData") {
1720
+ const { data, headers, head } = result;
1721
+ return new Response(JSON.stringify({
1722
+ data,
1723
+ head
1724
+ }), {
1725
+ headers: {
1726
+ ...headers,
1727
+ "Content-Type": "application/json"
1728
+ }
1729
+ });
1730
+ }
1731
+ if (result.kind === "view") {
1732
+ const { data, headers, head, status } = result;
1733
+ const { styles, views, manifest, serverManifest, ...renderOptions } = renderParams;
1734
+ const viewImportMap = {};
1735
+ let appDir = null;
1736
+ const template = (viewName, path) => `"${viewName}": () => import("${path}")`;
1737
+ const templates = [];
1738
+ for (const fileName of flattenComponentTree(this.componentTree)) {
1739
+ if (!manifest) {
1740
+ appDir = `${process.env.APP_DIR}`;
1741
+ const mod = await import(`${appDir}/views/${fileName}.tsx`);
1742
+ viewImportMap[fileName] = mod.default;
1743
+ templates.push(template(fileName, `${appDir}/views/${fileName}.tsx`));
1744
+ } else {
1745
+ const { file } = serverManifest[`app/views/${fileName}.tsx`];
1746
+ const mod = await import(`${process.env.DIST_DIR}/server/${file}`);
1747
+ viewImportMap[fileName] = mod.default;
1748
+ const clientFile = manifest[`app/views/${fileName}.tsx`];
1749
+ if (clientFile) {
1750
+ templates.push(template(fileName, `/${clientFile.file}`));
1751
+ }
1752
+ }
1753
+ }
1754
+ const loaders = `{${templates.join(",")}}`;
1755
+ const stream = await renderToReadableStream(createElement(Fragment, {
1756
+ children: [
1757
+ styles,
1758
+ createElement(this.Root, {
1759
+ head,
1760
+ data,
1761
+ viewImportMap
1762
+ })
1763
+ ]
1764
+ }), {
1765
+ bootstrapScriptContent: `window.__GEMI_DATA__ = ${JSON.stringify(data)}; window.loaders=${loaders}`,
1766
+ ...renderOptions
1767
+ });
1768
+ return new Response(stream, {
1769
+ status,
1770
+ headers: {
1771
+ "Content-Type": "text/html",
1772
+ ...headers
1773
+ }
1774
+ });
1775
+ }
1776
+ if (result.kind === "api") {
1777
+ const { data, headers, status } = result;
1778
+ return new Response(JSON.stringify(data), {
1779
+ status,
1780
+ headers: {
1781
+ "Content-Type": "application/json",
1782
+ ...headers
1783
+ }
1784
+ });
1785
+ }
1786
+ return new Response("Not found", { status: 404 });
1787
+ }
1681
1788
  handleWebSocketMessage = (ws, message) => {
1682
1789
  };
1683
1790
  handleWebSocketOpen = (ws) => {
package/dist/bin/gemi CHANGED
Binary file
@@ -1,4 +1,6 @@
1
+ import { type ComponentType } from "react";
1
2
  export declare const ClientRouter: (props: {
2
- components: any;
3
+ viewImportMap?: Record<string, any>;
4
+ RootLayout: ComponentType<any>;
3
5
  }) => import("react/jsx-runtime").JSX.Element;
4
6
  //# 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":"AAAA,OAAO,EASL,KAAK,aAAa,EACnB,MAAM,OAAO,CAAC;AAkHf,eAAO,MAAM,YAAY,UAAW;IAClC,aAAa,CAAC,EAAE,OAAO,MAAM,EAAE,GAAG,CAAC,CAAC;IACpC,UAAU,EAAE,cAAc,GAAG,CAAC,CAAC;CAChC,4CA2BA,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,6CAQnB"}
@@ -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"}