hadars 1.0.1 → 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 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-17 · 120s · 100 connections · Bun runtime
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 | **218** | 23 |
32
- | Latency median | **446 ms** | 2421 ms |
33
- | Latency p99 | **838 ms** | 3244 ms |
34
- | Throughput | **62.07** MB/s | 12.6 MB/s |
35
- | Peak RSS | 1032.7 MB | **514.0 MB** |
36
- | Avg RSS | 842.2 MB | **462.8 MB** |
37
- | Build time | 1.1 s | 5.3 s |
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 | **15 ms** | 33 ms |
44
- | FCP | **76 ms** | 112 ms |
45
- | DOMContentLoaded | **31 ms** | 101 ms |
46
- | Load | **96 ms** | 139 ms |
47
- | Peak RSS | 508.0 MB | **299.5 MB** |
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
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  renderPreflight,
3
3
  renderToString
4
- } from "./chunk-HIKMDNRB.js";
4
+ } from "./chunk-QOTDCUE5.js";
5
5
  import {
6
6
  createElement
7
7
  } from "./chunk-OZUZS2PD.js";
@@ -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
- try {
183
- await renderPreflight(element);
184
- } finally {
185
- globalThis.__hadarsUnsuspend = null;
186
- globalThis.__hadarsContext = null;
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
- const zlib = await import("zlib");
269
- const { promisify } = await import("util");
270
- return promisify(zlib.gzip)(d);
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
- const zlib = await import("zlib");
274
- const { promisify } = await import("util");
275
- return promisify(zlib.gunzip)(d);
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);
@@ -6,12 +6,8 @@ import {
6
6
  SUSPENSE_TYPE,
7
7
  createElement
8
8
  } from "./chunk-OZUZS2PD.js";
9
- import {
10
- __require
11
- } from "./chunk-3RG5ZIWI.js";
12
9
 
13
10
  // src/slim-react/renderContext.ts
14
- import { createRequire as _nodeCreateRequire } from "module";
15
11
  var MAP_KEY = "__slimReactContextMap";
16
12
  var _g = globalThis;
17
13
  if (!("__slimReactContextMap" in _g)) _g[MAP_KEY] = null;
@@ -146,31 +142,12 @@ function getTreeId() {
146
142
  const stripped = (id & ~(1 << 31 - Math.clz32(id))).toString(32);
147
143
  return stripped + overflow;
148
144
  }
149
- var _detectReact = () => {
150
- if (typeof __HADARS_REACT_MAJOR__ !== "undefined") {
151
- const major = parseInt(String(__HADARS_REACT_MAJOR__), 10);
152
- return {
153
- major,
154
- // Exact patch version is unknown from the define alone; use a
155
- // representative fallback. Most libraries only check the major.
156
- version: major < 19 ? "18.3.1" : "19.1.1"
157
- };
158
- }
159
- const parse = (ver) => ({ major: parseInt(ver.split(".")[0], 10), version: ver });
160
- try {
161
- return parse(__require("react").version);
162
- } catch {
163
- }
164
- try {
165
- const req = _nodeCreateRequire(process.cwd() + "/__hadars__.js");
166
- return parse(req("react").version);
167
- } catch {
168
- }
169
- return { major: 19, version: "19.1.1" };
170
- };
171
- var _react = _detectReact();
172
- var REACT_MAJOR = _react.major;
173
- var REACT_VERSION = _react.version;
145
+ var REACT_MAJOR = typeof __HADARS_REACT_MAJOR__ !== "undefined" ? parseInt(String(__HADARS_REACT_MAJOR__), 10) : 19;
146
+ var REACT_VERSION = REACT_MAJOR < 19 ? "18.3.1" : "19.1.1";
147
+ function setReactVersion(major, version2) {
148
+ REACT_MAJOR = major;
149
+ REACT_VERSION = version2 ?? (major < 19 ? "18.3.1" : "19.1.1");
150
+ }
174
151
  function makeId() {
175
152
  const st = s();
176
153
  const treeId = getTreeId();
@@ -272,9 +249,22 @@ function createContext(defaultValue) {
272
249
 
273
250
  // src/slim-react/dispatcher.ts
274
251
  import * as ReactNS from "react";
275
- var _r19 = ReactNS["__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE"];
276
- var _r18Raw = !_r19 ? ReactNS["__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED"] : void 0;
277
- var _r18 = _r18Raw?.ReactCurrentDispatcher ? _r18Raw : void 0;
252
+ var _r19;
253
+ var _r18;
254
+ var _detected = false;
255
+ var _k19 = "__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE";
256
+ var _k18 = "__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED";
257
+ function _detect() {
258
+ if (_detected) return;
259
+ _detected = true;
260
+ const r19 = ReactNS[_k19];
261
+ if (r19) {
262
+ _r19 = r19;
263
+ return;
264
+ }
265
+ const raw = ReactNS[_k18];
266
+ if (raw?.ReactCurrentDispatcher) _r18 = raw;
267
+ }
278
268
  var slimDispatcher = {
279
269
  useId: makeId,
280
270
  readContext: (ctx) => getContextValue(ctx),
@@ -302,6 +292,7 @@ var slimDispatcher = {
302
292
  useHostTransitionStatus: () => false
303
293
  };
304
294
  function installDispatcher() {
295
+ _detect();
305
296
  if (_r19) {
306
297
  const prev = _r19.H;
307
298
  _r19.H = slimDispatcher;
@@ -315,6 +306,7 @@ function installDispatcher() {
315
306
  return null;
316
307
  }
317
308
  function restoreDispatcher(prev) {
309
+ _detect();
318
310
  if (_r19) _r19.H = prev;
319
311
  else if (_r18) _r18.ReactCurrentDispatcher.current = prev;
320
312
  }
@@ -1170,7 +1162,7 @@ var Component = class {
1170
1162
  var PureComponent = class extends Component {
1171
1163
  };
1172
1164
  var version = REACT_VERSION;
1173
- var __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED2 = {
1165
+ var __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = {
1174
1166
  ReactCurrentDispatcher: { current: null },
1175
1167
  ReactCurrentBatchConfig: { transition: null },
1176
1168
  ReactCurrentOwner: { current: null }
@@ -1220,11 +1212,12 @@ var React = {
1220
1212
  // Version
1221
1213
  version,
1222
1214
  // React 18 internals
1223
- __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED2
1215
+ __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED
1224
1216
  };
1225
1217
  var slim_react_default = React;
1226
1218
 
1227
1219
  export {
1220
+ setReactVersion,
1228
1221
  useState,
1229
1222
  useReducer,
1230
1223
  useEffect,
@@ -1259,6 +1252,6 @@ export {
1259
1252
  Component,
1260
1253
  PureComponent,
1261
1254
  version,
1262
- __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED2 as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
1255
+ __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,
1263
1256
  slim_react_default
1264
1257
  };