hadars 1.0.2 → 1.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/README.md +13 -13
- package/dist/{chunk-LDVJ26Q3.js → chunk-PQ5N5GOY.js} +32 -11
- package/dist/cli.js +45 -15
- package/dist/cloudflare.cjs +32 -11
- package/dist/cloudflare.js +1 -1
- package/dist/lambda.cjs +32 -11
- package/dist/lambda.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,30 +21,30 @@ Bring your own router (or none), keep your components as plain React, and get SS
|
|
|
21
21
|
## Benchmarks
|
|
22
22
|
|
|
23
23
|
<!-- BENCHMARK_START -->
|
|
24
|
-
> Last run: 2026-04-
|
|
24
|
+
> Last run: 2026-04-19 · 120s · 100 connections · Bun runtime
|
|
25
25
|
> hadars is **9.5x faster** in requests/sec
|
|
26
26
|
|
|
27
27
|
**Throughput** (autocannon, 120s)
|
|
28
28
|
|
|
29
29
|
| Metric | hadars | Next.js |
|
|
30
30
|
|---|---:|---:|
|
|
31
|
-
| Requests/sec | **
|
|
32
|
-
| Latency median | **
|
|
33
|
-
| Latency p99 | **
|
|
34
|
-
| Throughput | **
|
|
35
|
-
| Peak RSS | 1032.
|
|
36
|
-
| Avg RSS |
|
|
37
|
-
| Build time |
|
|
31
|
+
| Requests/sec | **162** | 17 |
|
|
32
|
+
| Latency median | **607 ms** | 2754 ms |
|
|
33
|
+
| Latency p99 | **952 ms** | 4084 ms |
|
|
34
|
+
| Throughput | **46.04** MB/s | 9.49 MB/s |
|
|
35
|
+
| Peak RSS | 1032.4 MB | **482.3 MB** |
|
|
36
|
+
| Avg RSS | 797.0 MB | **427.0 MB** |
|
|
37
|
+
| Build time | 0.6 s | 6.0 s |
|
|
38
38
|
|
|
39
39
|
**Page load** (Playwright · Chromium headless · median)
|
|
40
40
|
|
|
41
41
|
| Metric | hadars | Next.js |
|
|
42
42
|
|---|---:|---:|
|
|
43
|
-
| TTFB | **
|
|
44
|
-
| FCP | **
|
|
45
|
-
| DOMContentLoaded | **
|
|
46
|
-
| Load | **
|
|
47
|
-
| Peak RSS |
|
|
43
|
+
| TTFB | **18 ms** | 47 ms |
|
|
44
|
+
| FCP | **96 ms** | 140 ms |
|
|
45
|
+
| DOMContentLoaded | **39 ms** | 128 ms |
|
|
46
|
+
| Load | **120 ms** | 174 ms |
|
|
47
|
+
| Peak RSS | 443.5 MB | **309.9 MB** |
|
|
48
48
|
<!-- BENCHMARK_END -->
|
|
49
49
|
|
|
50
50
|
## Quick start
|
|
@@ -179,14 +179,27 @@ var getReactResponse = async (req, opts) => {
|
|
|
179
179
|
globalThis.__hadarsUnsuspend = unsuspend;
|
|
180
180
|
globalThis.__hadarsContext = context;
|
|
181
181
|
const element = createElement(App, props);
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
globalThis.
|
|
186
|
-
|
|
182
|
+
let bodyHtml = null;
|
|
183
|
+
if (opts.singlePass) {
|
|
184
|
+
globalThis.__hadarsUnsuspend = unsuspend;
|
|
185
|
+
globalThis.__hadarsContext = context;
|
|
186
|
+
try {
|
|
187
|
+
bodyHtml = await renderToString(element);
|
|
188
|
+
} finally {
|
|
189
|
+
globalThis.__hadarsUnsuspend = null;
|
|
190
|
+
globalThis.__hadarsContext = null;
|
|
191
|
+
}
|
|
192
|
+
} else {
|
|
193
|
+
try {
|
|
194
|
+
await renderPreflight(element);
|
|
195
|
+
} finally {
|
|
196
|
+
globalThis.__hadarsUnsuspend = null;
|
|
197
|
+
globalThis.__hadarsContext = null;
|
|
198
|
+
}
|
|
187
199
|
}
|
|
188
200
|
const status = context.head.status;
|
|
189
201
|
const getAppBody = async () => {
|
|
202
|
+
if (bodyHtml !== null) return bodyHtml;
|
|
190
203
|
globalThis.__hadarsUnsuspend = unsuspend;
|
|
191
204
|
globalThis.__hadarsContext = context;
|
|
192
205
|
try {
|
|
@@ -264,15 +277,23 @@ async function transformStream(data, stream) {
|
|
|
264
277
|
}
|
|
265
278
|
return out;
|
|
266
279
|
}
|
|
280
|
+
var _zlibGzip = null;
|
|
281
|
+
var _zlibGunzip = null;
|
|
267
282
|
async function zlibGzip(d) {
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
283
|
+
if (!_zlibGzip) {
|
|
284
|
+
const zlib = await import("zlib");
|
|
285
|
+
const { promisify } = await import("util");
|
|
286
|
+
_zlibGzip = promisify(zlib.gzip);
|
|
287
|
+
}
|
|
288
|
+
return _zlibGzip(d);
|
|
271
289
|
}
|
|
272
290
|
async function zlibGunzip(d) {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
291
|
+
if (!_zlibGunzip) {
|
|
292
|
+
const zlib = await import("zlib");
|
|
293
|
+
const { promisify } = await import("util");
|
|
294
|
+
_zlibGunzip = promisify(zlib.gunzip);
|
|
295
|
+
}
|
|
296
|
+
return _zlibGunzip(d);
|
|
276
297
|
}
|
|
277
298
|
var gzipCompress = (d) => globalThis.CompressionStream ? transformStream(d, new globalThis.CompressionStream("gzip")) : zlibGzip(d);
|
|
278
299
|
var gzipDecompress = (d) => globalThis.DecompressionStream ? transformStream(d, new globalThis.DecompressionStream("gzip")) : zlibGunzip(d);
|
package/dist/cli.js
CHANGED
|
@@ -1220,14 +1220,28 @@ var getReactResponse = async (req, opts) => {
|
|
|
1220
1220
|
globalThis.__hadarsUnsuspend = unsuspend;
|
|
1221
1221
|
globalThis.__hadarsContext = context;
|
|
1222
1222
|
const element = createElement(App, props);
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
globalThis.
|
|
1227
|
-
|
|
1223
|
+
let bodyHtml = null;
|
|
1224
|
+
if (opts.singlePass) {
|
|
1225
|
+
globalThis.__hadarsUnsuspend = unsuspend;
|
|
1226
|
+
globalThis.__hadarsContext = context;
|
|
1227
|
+
try {
|
|
1228
|
+
bodyHtml = await renderToString(element);
|
|
1229
|
+
} finally {
|
|
1230
|
+
globalThis.__hadarsUnsuspend = null;
|
|
1231
|
+
globalThis.__hadarsContext = null;
|
|
1232
|
+
}
|
|
1233
|
+
} else {
|
|
1234
|
+
try {
|
|
1235
|
+
await renderPreflight(element);
|
|
1236
|
+
} finally {
|
|
1237
|
+
globalThis.__hadarsUnsuspend = null;
|
|
1238
|
+
globalThis.__hadarsContext = null;
|
|
1239
|
+
}
|
|
1228
1240
|
}
|
|
1229
1241
|
const status = context.head.status;
|
|
1230
1242
|
const getAppBody = async () => {
|
|
1243
|
+
if (bodyHtml !== null)
|
|
1244
|
+
return bodyHtml;
|
|
1231
1245
|
globalThis.__hadarsUnsuspend = unsuspend;
|
|
1232
1246
|
globalThis.__hadarsContext = context;
|
|
1233
1247
|
try {
|
|
@@ -1823,15 +1837,23 @@ async function transformStream(data, stream) {
|
|
|
1823
1837
|
}
|
|
1824
1838
|
return out;
|
|
1825
1839
|
}
|
|
1840
|
+
var _zlibGzip = null;
|
|
1841
|
+
var _zlibGunzip = null;
|
|
1826
1842
|
async function zlibGzip(d) {
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1843
|
+
if (!_zlibGzip) {
|
|
1844
|
+
const zlib = await import("node:zlib");
|
|
1845
|
+
const { promisify } = await import("node:util");
|
|
1846
|
+
_zlibGzip = promisify(zlib.gzip);
|
|
1847
|
+
}
|
|
1848
|
+
return _zlibGzip(d);
|
|
1830
1849
|
}
|
|
1831
1850
|
async function zlibGunzip(d) {
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1851
|
+
if (!_zlibGunzip) {
|
|
1852
|
+
const zlib = await import("node:zlib");
|
|
1853
|
+
const { promisify } = await import("node:util");
|
|
1854
|
+
_zlibGunzip = promisify(zlib.gunzip);
|
|
1855
|
+
}
|
|
1856
|
+
return _zlibGunzip(d);
|
|
1835
1857
|
}
|
|
1836
1858
|
var gzipCompress = (d) => globalThis.CompressionStream ? transformStream(d, new globalThis.CompressionStream("gzip")) : zlibGzip(d);
|
|
1837
1859
|
var gzipDecompress = (d) => globalThis.DecompressionStream ? transformStream(d, new globalThis.DecompressionStream("gzip")) : zlibGunzip(d);
|
|
@@ -2565,6 +2587,8 @@ var dev = async (options) => {
|
|
|
2565
2587
|
const tmpFilePath = pathMod2.join(HADARS_TMP_DIR, `client-${Date.now()}.tsx`);
|
|
2566
2588
|
await fs.writeFile(tmpFilePath, clientScript);
|
|
2567
2589
|
let ssrBuildId = crypto.randomBytes(4).toString("hex");
|
|
2590
|
+
let cachedSsrModule = null;
|
|
2591
|
+
let cachedSsrBuildId = "";
|
|
2568
2592
|
const resolvedHtmlTemplate = options.htmlTemplate ? await processHtmlTemplate(pathMod2.resolve(__dirname3, options.htmlTemplate)) : undefined;
|
|
2569
2593
|
const clientCompiler = createClientCompiler(tmpFilePath, {
|
|
2570
2594
|
target: "web",
|
|
@@ -2739,13 +2763,17 @@ var dev = async (options) => {
|
|
|
2739
2763
|
if (projectRes)
|
|
2740
2764
|
return projectRes;
|
|
2741
2765
|
const ssrComponentPath = pathMod2.join(__dirname3, HadarsFolder, SSR_FILENAME);
|
|
2742
|
-
const importPath = pathToFileURL(ssrComponentPath).href + `?t=${ssrBuildId}`;
|
|
2743
2766
|
try {
|
|
2767
|
+
if (ssrBuildId !== cachedSsrBuildId) {
|
|
2768
|
+
const importPath = pathToFileURL(ssrComponentPath).href + `?t=${ssrBuildId}`;
|
|
2769
|
+
cachedSsrModule = await import(importPath);
|
|
2770
|
+
cachedSsrBuildId = ssrBuildId;
|
|
2771
|
+
}
|
|
2744
2772
|
const {
|
|
2745
2773
|
default: Component,
|
|
2746
2774
|
getInitProps,
|
|
2747
2775
|
getFinalProps
|
|
2748
|
-
} =
|
|
2776
|
+
} = cachedSsrModule;
|
|
2749
2777
|
globalThis.__hadarsGraphQL = devStaticCtx?.graphql;
|
|
2750
2778
|
const { head, status, getAppBody, finalize } = await getReactResponse(request, {
|
|
2751
2779
|
document: {
|
|
@@ -2754,7 +2782,8 @@ var dev = async (options) => {
|
|
|
2754
2782
|
getInitProps,
|
|
2755
2783
|
getFinalProps
|
|
2756
2784
|
},
|
|
2757
|
-
staticCtx: devStaticCtx
|
|
2785
|
+
staticCtx: devStaticCtx,
|
|
2786
|
+
singlePass: true
|
|
2758
2787
|
});
|
|
2759
2788
|
if (request.headers.get("Accept") === "application/json") {
|
|
2760
2789
|
const { clientProps } = await finalize();
|
|
@@ -2913,7 +2942,8 @@ var run = async (options) => {
|
|
|
2913
2942
|
lang: "en",
|
|
2914
2943
|
getInitProps,
|
|
2915
2944
|
getFinalProps
|
|
2916
|
-
}
|
|
2945
|
+
},
|
|
2946
|
+
singlePass: true
|
|
2917
2947
|
});
|
|
2918
2948
|
if (request.headers.get("Accept") === "application/json") {
|
|
2919
2949
|
const { clientProps } = await finalize();
|
package/dist/cloudflare.cjs
CHANGED
|
@@ -1220,14 +1220,27 @@ var getReactResponse = async (req, opts) => {
|
|
|
1220
1220
|
globalThis.__hadarsUnsuspend = unsuspend;
|
|
1221
1221
|
globalThis.__hadarsContext = context;
|
|
1222
1222
|
const element = createElement(App, props);
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
globalThis.
|
|
1227
|
-
|
|
1223
|
+
let bodyHtml = null;
|
|
1224
|
+
if (opts.singlePass) {
|
|
1225
|
+
globalThis.__hadarsUnsuspend = unsuspend;
|
|
1226
|
+
globalThis.__hadarsContext = context;
|
|
1227
|
+
try {
|
|
1228
|
+
bodyHtml = await renderToString(element);
|
|
1229
|
+
} finally {
|
|
1230
|
+
globalThis.__hadarsUnsuspend = null;
|
|
1231
|
+
globalThis.__hadarsContext = null;
|
|
1232
|
+
}
|
|
1233
|
+
} else {
|
|
1234
|
+
try {
|
|
1235
|
+
await renderPreflight(element);
|
|
1236
|
+
} finally {
|
|
1237
|
+
globalThis.__hadarsUnsuspend = null;
|
|
1238
|
+
globalThis.__hadarsContext = null;
|
|
1239
|
+
}
|
|
1228
1240
|
}
|
|
1229
1241
|
const status = context.head.status;
|
|
1230
1242
|
const getAppBody = async () => {
|
|
1243
|
+
if (bodyHtml !== null) return bodyHtml;
|
|
1231
1244
|
globalThis.__hadarsUnsuspend = unsuspend;
|
|
1232
1245
|
globalThis.__hadarsContext = context;
|
|
1233
1246
|
try {
|
|
@@ -1305,15 +1318,23 @@ async function transformStream(data, stream) {
|
|
|
1305
1318
|
}
|
|
1306
1319
|
return out;
|
|
1307
1320
|
}
|
|
1321
|
+
var _zlibGzip = null;
|
|
1322
|
+
var _zlibGunzip = null;
|
|
1308
1323
|
async function zlibGzip(d) {
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1324
|
+
if (!_zlibGzip) {
|
|
1325
|
+
const zlib = await import("zlib");
|
|
1326
|
+
const { promisify } = await import("util");
|
|
1327
|
+
_zlibGzip = promisify(zlib.gzip);
|
|
1328
|
+
}
|
|
1329
|
+
return _zlibGzip(d);
|
|
1312
1330
|
}
|
|
1313
1331
|
async function zlibGunzip(d) {
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1332
|
+
if (!_zlibGunzip) {
|
|
1333
|
+
const zlib = await import("zlib");
|
|
1334
|
+
const { promisify } = await import("util");
|
|
1335
|
+
_zlibGunzip = promisify(zlib.gunzip);
|
|
1336
|
+
}
|
|
1337
|
+
return _zlibGunzip(d);
|
|
1317
1338
|
}
|
|
1318
1339
|
var gzipCompress = (d) => globalThis.CompressionStream ? transformStream(d, new globalThis.CompressionStream("gzip")) : zlibGzip(d);
|
|
1319
1340
|
var gzipDecompress = (d) => globalThis.DecompressionStream ? transformStream(d, new globalThis.DecompressionStream("gzip")) : zlibGunzip(d);
|
package/dist/cloudflare.js
CHANGED
package/dist/lambda.cjs
CHANGED
|
@@ -1260,14 +1260,27 @@ var getReactResponse = async (req, opts) => {
|
|
|
1260
1260
|
globalThis.__hadarsUnsuspend = unsuspend;
|
|
1261
1261
|
globalThis.__hadarsContext = context;
|
|
1262
1262
|
const element = createElement(App, props);
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
globalThis.
|
|
1267
|
-
|
|
1263
|
+
let bodyHtml = null;
|
|
1264
|
+
if (opts.singlePass) {
|
|
1265
|
+
globalThis.__hadarsUnsuspend = unsuspend;
|
|
1266
|
+
globalThis.__hadarsContext = context;
|
|
1267
|
+
try {
|
|
1268
|
+
bodyHtml = await renderToString(element);
|
|
1269
|
+
} finally {
|
|
1270
|
+
globalThis.__hadarsUnsuspend = null;
|
|
1271
|
+
globalThis.__hadarsContext = null;
|
|
1272
|
+
}
|
|
1273
|
+
} else {
|
|
1274
|
+
try {
|
|
1275
|
+
await renderPreflight(element);
|
|
1276
|
+
} finally {
|
|
1277
|
+
globalThis.__hadarsUnsuspend = null;
|
|
1278
|
+
globalThis.__hadarsContext = null;
|
|
1279
|
+
}
|
|
1268
1280
|
}
|
|
1269
1281
|
const status = context.head.status;
|
|
1270
1282
|
const getAppBody = async () => {
|
|
1283
|
+
if (bodyHtml !== null) return bodyHtml;
|
|
1271
1284
|
globalThis.__hadarsUnsuspend = unsuspend;
|
|
1272
1285
|
globalThis.__hadarsContext = context;
|
|
1273
1286
|
try {
|
|
@@ -1345,15 +1358,23 @@ async function transformStream(data, stream) {
|
|
|
1345
1358
|
}
|
|
1346
1359
|
return out;
|
|
1347
1360
|
}
|
|
1361
|
+
var _zlibGzip = null;
|
|
1362
|
+
var _zlibGunzip = null;
|
|
1348
1363
|
async function zlibGzip(d) {
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1364
|
+
if (!_zlibGzip) {
|
|
1365
|
+
const zlib = await import("zlib");
|
|
1366
|
+
const { promisify } = await import("util");
|
|
1367
|
+
_zlibGzip = promisify(zlib.gzip);
|
|
1368
|
+
}
|
|
1369
|
+
return _zlibGzip(d);
|
|
1352
1370
|
}
|
|
1353
1371
|
async function zlibGunzip(d) {
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1372
|
+
if (!_zlibGunzip) {
|
|
1373
|
+
const zlib = await import("zlib");
|
|
1374
|
+
const { promisify } = await import("util");
|
|
1375
|
+
_zlibGunzip = promisify(zlib.gunzip);
|
|
1376
|
+
}
|
|
1377
|
+
return _zlibGunzip(d);
|
|
1357
1378
|
}
|
|
1358
1379
|
var gzipCompress = (d) => globalThis.CompressionStream ? transformStream(d, new globalThis.CompressionStream("gzip")) : zlibGzip(d);
|
|
1359
1380
|
var gzipDecompress = (d) => globalThis.DecompressionStream ? transformStream(d, new globalThis.DecompressionStream("gzip")) : zlibGunzip(d);
|
package/dist/lambda.js
CHANGED