@ereo/server 0.2.4 → 0.2.7

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 +1 @@
1
- {"version":3,"file":"bun-server.d.ts","sourceRoot":"","sources":["../src/bun-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bun-server.d.ts","sourceRoot":"","sources":["../src/bun-server.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -11,6 +11,6 @@ export type { MiddlewareHandler, NextFunction, Middleware, AppContext, } from '@
11
11
  export { enforceAuthConfig, resolveAuthDenial, resolveCheckResult, } from './auth-enforcement';
12
12
  export { serveStatic, staticMiddleware, getMimeType, } from './static';
13
13
  export type { StaticOptions } from './static';
14
- export { createShell, renderToStream, renderToString, createResponse, createSuspenseStream, } from './streaming';
14
+ export { createShell, renderToStream, renderToString, createResponse, } from './streaming';
15
15
  export type { RenderOptions, ShellTemplate, RenderResult, } from './streaming';
16
16
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,SAAS,EACT,YAAY,EACZ,KAAK,GACN,MAAM,cAAc,CAAC;AAEtB,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGpE,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,MAAM,EACN,IAAI,EACJ,eAAe,EACf,QAAQ,EACR,SAAS,GACV,MAAM,cAAc,CAAC;AAEtB,YAAY,EACV,oBAAoB,EACpB,WAAW,EACX,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAItB,YAAY,EACV,iBAAiB,EACjB,YAAY,EACZ,UAAU,EACV,UAAU,GACX,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,WAAW,GACZ,MAAM,UAAU,CAAC;AAElB,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG9C,OAAO,EACL,WAAW,EACX,cAAc,EACd,cAAc,EACd,cAAc,EACd,oBAAoB,GACrB,MAAM,aAAa,CAAC;AAErB,YAAY,EACV,aAAa,EACb,aAAa,EACb,YAAY,GACb,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,SAAS,EACT,YAAY,EACZ,KAAK,GACN,MAAM,cAAc,CAAC;AAEtB,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGpE,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,MAAM,EACN,IAAI,EACJ,eAAe,EACf,QAAQ,EACR,SAAS,GACV,MAAM,cAAc,CAAC;AAEtB,YAAY,EACV,oBAAoB,EACpB,WAAW,EACX,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,cAAc,CAAC;AAItB,YAAY,EACV,iBAAiB,EACjB,YAAY,EACZ,UAAU,EACV,UAAU,GACX,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,WAAW,GACZ,MAAM,UAAU,CAAC;AAElB,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAG9C,OAAO,EACL,WAAW,EACX,cAAc,EACd,cAAc,EACd,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,YAAY,EACV,aAAa,EACb,aAAa,EACb,YAAY,GACb,MAAM,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -484,40 +484,85 @@ async function renderToStream(element, options) {
484
484
  context: options.context
485
485
  });
486
486
  }
487
- if (hasDeferredData(loaderData)) {
488
- loaderData = await resolveAllDeferred(loaderData);
489
- }
490
- const { head, tail } = createShell({ shell, scripts, styles, loaderData });
487
+ const hasDeferred = hasDeferredData(loaderData);
488
+ const { head, tail } = createShell({
489
+ shell,
490
+ scripts: [],
491
+ styles,
492
+ loaderData: hasDeferred ? null : loaderData
493
+ });
491
494
  return new Promise((resolve2, reject) => {
492
495
  const { PassThrough } = __require("stream");
496
+ const DEFERRED_TIMEOUT_MS = 1e4;
497
+ const RENDER_TIMEOUT_MS = 1e4;
498
+ const timeoutId = setTimeout(() => {
499
+ abort();
500
+ }, RENDER_TIMEOUT_MS);
493
501
  const { pipe, abort } = renderToPipeableStream(element, {
494
- bootstrapScripts: scripts,
502
+ bootstrapModules: scripts,
495
503
  onShellReady() {
496
504
  const passThrough = new PassThrough;
497
- const chunks = [];
498
- chunks.push(Buffer.from(head));
499
- passThrough.on("data", (chunk) => {
500
- chunks.push(chunk);
501
- });
502
- passThrough.on("end", () => {
503
- chunks.push(Buffer.from(tail));
504
- const fullHtml = Buffer.concat(chunks).toString("utf-8");
505
- resolve2({
506
- body: fullHtml,
507
- headers: new Headers({
508
- "Content-Type": "text/html; charset=utf-8",
509
- "Content-Length": Buffer.byteLength(fullHtml).toString()
510
- }),
511
- status: 200
512
- });
505
+ const encoder = new TextEncoder;
506
+ const stream = new ReadableStream({
507
+ start(controller) {
508
+ controller.enqueue(encoder.encode(head));
509
+ passThrough.on("data", (chunk) => {
510
+ controller.enqueue(new Uint8Array(chunk));
511
+ });
512
+ passThrough.on("end", () => {
513
+ (async () => {
514
+ if (hasDeferred) {
515
+ let resolvedData;
516
+ try {
517
+ resolvedData = await Promise.race([
518
+ resolveAllDeferred(loaderData),
519
+ new Promise((_, rejectTimeout) => setTimeout(() => rejectTimeout(new Error("Deferred data resolution timed out")), DEFERRED_TIMEOUT_MS))
520
+ ]);
521
+ } catch (error) {
522
+ console.error("Deferred data resolution failed:", error);
523
+ resolvedData = null;
524
+ }
525
+ const loaderScript = `<script>window.__EREO_DATA__=${serializeLoaderData(resolvedData)}</script>`;
526
+ const resolvedTail = `</div>
527
+ ${loaderScript}
528
+ </body>
529
+ </html>`;
530
+ controller.enqueue(encoder.encode(resolvedTail));
531
+ } else {
532
+ controller.enqueue(encoder.encode(tail));
533
+ }
534
+ controller.close();
535
+ })().catch((error) => {
536
+ console.error("Stream finalization error:", error);
537
+ try {
538
+ controller.error(error);
539
+ } catch {}
540
+ }).finally(() => {
541
+ clearTimeout(timeoutId);
542
+ });
543
+ });
544
+ passThrough.on("error", (error) => {
545
+ clearTimeout(timeoutId);
546
+ console.error("Stream error:", error);
547
+ controller.error(error);
548
+ });
549
+ },
550
+ cancel() {
551
+ clearTimeout(timeoutId);
552
+ passThrough.destroy();
553
+ }
513
554
  });
514
- passThrough.on("error", (error) => {
515
- console.error("Stream error:", error);
516
- reject(error);
555
+ resolve2({
556
+ body: stream,
557
+ headers: new Headers({
558
+ "Content-Type": "text/html; charset=utf-8"
559
+ }),
560
+ status: 200
517
561
  });
518
562
  pipe(passThrough);
519
563
  },
520
564
  onShellError(error) {
565
+ clearTimeout(timeoutId);
521
566
  console.error("Shell render error:", error);
522
567
  reject(error);
523
568
  },
@@ -525,9 +570,6 @@ async function renderToStream(element, options) {
525
570
  console.error("Render error:", error);
526
571
  }
527
572
  });
528
- setTimeout(() => {
529
- abort();
530
- }, 1e4);
531
573
  });
532
574
  }
533
575
  async function renderToString(element, options) {
@@ -562,24 +604,6 @@ function createResponse(result) {
562
604
  headers: result.headers
563
605
  });
564
606
  }
565
- function createSuspenseStream() {
566
- const encoder = new TextEncoder;
567
- let controller;
568
- const stream = new ReadableStream({
569
- start(c) {
570
- controller = c;
571
- }
572
- });
573
- return {
574
- stream,
575
- push: (chunk) => {
576
- controller.enqueue(encoder.encode(chunk));
577
- },
578
- close: () => {
579
- controller.close();
580
- }
581
- };
582
- }
583
607
 
584
608
  // src/bun-server.ts
585
609
  import { serializeLoaderData as serializeLoaderData2, hasDeferredData as hasDeferredData2, resolveAllDeferred as resolveAllDeferred2 } from "@ereo/data";
@@ -1000,27 +1024,31 @@ class BunServer {
1000
1024
  }
1001
1025
  }
1002
1026
  async renderStreamingPage(element, shell, loaderData) {
1027
+ let timeoutId;
1003
1028
  try {
1004
1029
  const { renderToReadableStream } = await getStreamingRenderer();
1005
1030
  if (!renderToReadableStream) {
1006
1031
  return this.renderStringPage(element, shell, loaderData);
1007
1032
  }
1008
1033
  const hasDeferred = hasDeferredData2(loaderData);
1009
- const scripts = [this.options.clientEntry];
1034
+ const clientEntry = this.options.clientEntry;
1010
1035
  const { head, tail } = createShell({
1011
1036
  shell,
1012
- scripts,
1037
+ scripts: [],
1013
1038
  loaderData: hasDeferred ? null : loaderData
1014
1039
  });
1015
1040
  const encoder = new TextEncoder;
1016
1041
  const headBytes = encoder.encode(head);
1017
1042
  const tailBytes = hasDeferred ? null : encoder.encode(tail);
1043
+ const abortController = new AbortController;
1044
+ timeoutId = setTimeout(() => abortController.abort(), 1e4);
1018
1045
  const reactStream = await renderToReadableStream(element, {
1046
+ bootstrapModules: [clientEntry],
1047
+ signal: abortController.signal,
1019
1048
  onError(error) {
1020
1049
  console.error("Streaming render error:", error);
1021
1050
  }
1022
1051
  });
1023
- const clientEntry = this.options.clientEntry;
1024
1052
  const reader = reactStream.getReader();
1025
1053
  let phase = "head";
1026
1054
  const stream = new ReadableStream({
@@ -1034,18 +1062,26 @@ class BunServer {
1034
1062
  const { done, value } = await reader.read();
1035
1063
  if (done) {
1036
1064
  if (hasDeferred) {
1037
- const resolved = await resolveAllDeferred2(loaderData);
1038
- const loaderScript = `<script>window.__EREO_DATA__=${serializeLoaderData2(resolved)}</script>`;
1039
- const scriptTag = `<script type="module" src="${clientEntry}"></script>`;
1065
+ let resolvedData;
1066
+ try {
1067
+ resolvedData = await Promise.race([
1068
+ resolveAllDeferred2(loaderData),
1069
+ new Promise((_, reject) => setTimeout(() => reject(new Error("Deferred data resolution timed out")), 1e4))
1070
+ ]);
1071
+ } catch (error) {
1072
+ console.error("Deferred data resolution failed:", error);
1073
+ resolvedData = null;
1074
+ }
1075
+ const loaderScript = `<script>window.__EREO_DATA__=${serializeLoaderData2(resolvedData)}</script>`;
1040
1076
  const resolvedTail = `</div>
1041
1077
  ${loaderScript}
1042
- ${scriptTag}
1043
1078
  </body>
1044
1079
  </html>`;
1045
1080
  controller.enqueue(encoder.encode(resolvedTail));
1046
1081
  } else {
1047
1082
  controller.enqueue(tailBytes);
1048
1083
  }
1084
+ clearTimeout(timeoutId);
1049
1085
  controller.close();
1050
1086
  phase = "done";
1051
1087
  } else {
@@ -1057,6 +1093,7 @@ class BunServer {
1057
1093
  },
1058
1094
  cancel() {
1059
1095
  reader.cancel();
1096
+ clearTimeout(timeoutId);
1060
1097
  }
1061
1098
  });
1062
1099
  return new Response(stream, {
@@ -1066,6 +1103,7 @@ class BunServer {
1066
1103
  }
1067
1104
  });
1068
1105
  } catch (error) {
1106
+ clearTimeout(timeoutId);
1069
1107
  console.error("Streaming render failed:", error);
1070
1108
  return this.renderStringPage(element, shell, loaderData);
1071
1109
  }
@@ -1093,20 +1131,25 @@ class BunServer {
1093
1131
  }
1094
1132
  }
1095
1133
  async renderStreamingPageDirect(element, loaderData) {
1134
+ let timeoutId;
1096
1135
  try {
1097
1136
  const { renderToReadableStream } = await getStreamingRenderer();
1098
1137
  if (!renderToReadableStream) {
1099
1138
  return this.renderStringPageDirect(element, loaderData);
1100
1139
  }
1140
+ const hasDeferred = hasDeferredData2(loaderData);
1141
+ const clientEntry = this.options.clientEntry;
1142
+ const encoder = new TextEncoder;
1143
+ const abortController = new AbortController;
1144
+ timeoutId = setTimeout(() => abortController.abort(), 1e4);
1101
1145
  const reactStream = await renderToReadableStream(element, {
1146
+ bootstrapModules: [clientEntry],
1147
+ signal: abortController.signal,
1102
1148
  onError(error) {
1103
1149
  console.error("Streaming render error:", error);
1104
1150
  }
1105
1151
  });
1106
- const encoder = new TextEncoder;
1107
- const hasDeferred = hasDeferredData2(loaderData);
1108
- const clientEntry = this.options.clientEntry;
1109
- const injectedScripts = hasDeferred ? null : encoder.encode((loaderData ? `<script>window.__EREO_DATA__=${serializeLoaderData2(loaderData)}</script>` : "") + `<script type="module" src="${clientEntry}"></script>`);
1152
+ const loaderScript = !hasDeferred && loaderData ? encoder.encode(`<script>window.__EREO_DATA__=${serializeLoaderData2(loaderData)}</script>`) : null;
1110
1153
  const reader = reactStream.getReader();
1111
1154
  let done = false;
1112
1155
  const stream = new ReadableStream({
@@ -1116,13 +1159,21 @@ class BunServer {
1116
1159
  const result = await reader.read();
1117
1160
  if (result.done) {
1118
1161
  if (hasDeferred) {
1119
- const resolved = await resolveAllDeferred2(loaderData);
1120
- const loaderScript = resolved ? `<script>window.__EREO_DATA__=${serializeLoaderData2(resolved)}</script>` : "";
1121
- const clientScript = `<script type="module" src="${clientEntry}"></script>`;
1122
- controller.enqueue(encoder.encode(loaderScript + clientScript));
1123
- } else {
1124
- controller.enqueue(injectedScripts);
1162
+ let resolvedData;
1163
+ try {
1164
+ resolvedData = await Promise.race([
1165
+ resolveAllDeferred2(loaderData),
1166
+ new Promise((_, reject) => setTimeout(() => reject(new Error("Deferred data resolution timed out")), 1e4))
1167
+ ]);
1168
+ } catch (error) {
1169
+ console.error("Deferred data resolution failed:", error);
1170
+ resolvedData = null;
1171
+ }
1172
+ controller.enqueue(encoder.encode(`<script>window.__EREO_DATA__=${serializeLoaderData2(resolvedData)}</script>`));
1173
+ } else if (loaderScript) {
1174
+ controller.enqueue(loaderScript);
1125
1175
  }
1176
+ clearTimeout(timeoutId);
1126
1177
  controller.close();
1127
1178
  done = true;
1128
1179
  } else {
@@ -1131,6 +1182,7 @@ class BunServer {
1131
1182
  },
1132
1183
  cancel() {
1133
1184
  reader.cancel();
1185
+ clearTimeout(timeoutId);
1134
1186
  }
1135
1187
  });
1136
1188
  return new Response(stream, {
@@ -1140,6 +1192,7 @@ class BunServer {
1140
1192
  }
1141
1193
  });
1142
1194
  } catch (error) {
1195
+ clearTimeout(timeoutId);
1143
1196
  console.error("Streaming render failed:", error);
1144
1197
  return this.renderStringPageDirect(element, loaderData);
1145
1198
  }
@@ -1443,7 +1496,6 @@ export {
1443
1496
  logger,
1444
1497
  getMimeType,
1445
1498
  enforceAuthConfig,
1446
- createSuspenseStream,
1447
1499
  createShell,
1448
1500
  createServer,
1449
1501
  createResponse,
@@ -69,6 +69,13 @@ export declare function createShell(options: {
69
69
  /**
70
70
  * Render a route to a streaming response.
71
71
  * Uses renderToPipeableStream for Node.js/Bun environments.
72
+ *
73
+ * Returns a ReadableStream body that progressively sends:
74
+ * shell head → React content (with $RC scripts for Suspense) → tail
75
+ *
76
+ * Deferred data is NOT resolved upfront — React streams Suspense fallbacks
77
+ * and resolves them out-of-order via inline $RC scripts. Loader data is
78
+ * serialized into the tail only after all Suspense boundaries resolve.
72
79
  */
73
80
  export declare function renderToStream(element: ReactElement, options: RenderOptions): Promise<RenderResult>;
74
81
  /**
@@ -79,12 +86,4 @@ export declare function renderToString(element: ReactElement, options: RenderOpt
79
86
  * Create a Response from render result.
80
87
  */
81
88
  export declare function createResponse(result: RenderResult): Response;
82
- /**
83
- * Stream helper for sending chunks with delays (Suspense boundaries).
84
- */
85
- export declare function createSuspenseStream(): {
86
- stream: ReadableStream<Uint8Array>;
87
- push: (chunk: string) => void;
88
- close: () => void;
89
- };
90
89
  //# sourceMappingURL=streaming.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"streaming.d.ts","sourceRoot":"","sources":["../src/streaming.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,KAAK,EAAS,UAAU,EAAE,UAAU,EAAkB,cAAc,EAAE,MAAM,YAAY,CAAC;AAGhG;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,kBAAkB;IAClB,KAAK,EAAE,UAAU,CAAC;IAClB,sBAAsB;IACtB,OAAO,EAAE,UAAU,CAAC;IACpB,qBAAqB;IACrB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,uBAAuB;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wBAAwB;IACxB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,kBAAkB;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,qBAAqB;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB;IAChB,IAAI,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpE,uDAAuD;IACvD,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;IACzB,mBAAmB;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sBAAsB;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,sBAAsB;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,6BAA6B;IAC7B,IAAI,EAAE,MAAM,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;IAC1C,uBAAuB;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,kBAAkB;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE;IACnC,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CA8DjC;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,YAAY,CAAC,CAwEvB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,YAAY,CAAC,CAgCvB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,QAAQ,CAK7D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI;IACtC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;IACnC,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,CAmBA"}
1
+ {"version":3,"file":"streaming.d.ts","sourceRoot":"","sources":["../src/streaming.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,KAAK,EAAS,UAAU,EAAE,UAAU,EAAkB,cAAc,EAAE,MAAM,YAAY,CAAC;AAGhG;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,kBAAkB;IAClB,KAAK,EAAE,UAAU,CAAC;IAClB,sBAAsB;IACtB,OAAO,EAAE,UAAU,CAAC;IACpB,qBAAqB;IACrB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,uBAAuB;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wBAAwB;IACxB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,kBAAkB;IAClB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,qBAAqB;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB;IAChB,IAAI,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpE,uDAAuD;IACvD,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;IACzB,mBAAmB;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sBAAsB;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,sBAAsB;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,6BAA6B;IAC7B,IAAI,EAAE,MAAM,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;IAC1C,uBAAuB;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,kBAAkB;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE;IACnC,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CA8DjC;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,YAAY,CAAC,CAuHvB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,YAAY,EACrB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,YAAY,CAAC,CAgCvB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,YAAY,GAAG,QAAQ,CAK7D"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ereo/server",
3
- "version": "0.2.4",
3
+ "version": "0.2.7",
4
4
  "license": "MIT",
5
5
  "author": "Ereo Team",
6
6
  "homepage": "https://ereojs.github.io/ereoJS",
@@ -32,10 +32,10 @@
32
32
  "typecheck": "tsc --noEmit"
33
33
  },
34
34
  "dependencies": {
35
- "@ereo/core": "^0.2.4",
36
- "@ereo/client": "^0.2.4",
37
- "@ereo/router": "^0.2.4",
38
- "@ereo/data": "^0.2.4"
35
+ "@ereo/core": "^0.2.7",
36
+ "@ereo/client": "^0.2.7",
37
+ "@ereo/router": "^0.2.7",
38
+ "@ereo/data": "^0.2.7"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@types/bun": "^1.1.0",