hadars 0.4.1 → 0.4.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 (58) hide show
  1. package/dist/{chunk-TV37IMRB.js → chunk-2TMQUXFL.js} +10 -10
  2. package/dist/{chunk-2J2L2H3H.js → chunk-NYLXE7T7.js} +6 -6
  3. package/dist/{chunk-OS3V4CPN.js → chunk-OZUZS2PD.js} +4 -4
  4. package/dist/cli.js +462 -496
  5. package/dist/cloudflare.cjs +11 -11
  6. package/dist/cloudflare.js +3 -3
  7. package/dist/index.d.cts +8 -4
  8. package/dist/index.d.ts +8 -4
  9. package/dist/lambda.cjs +11 -11
  10. package/dist/lambda.js +7 -7
  11. package/dist/loader.cjs +90 -54
  12. package/dist/slim-react/index.cjs +13 -13
  13. package/dist/slim-react/index.js +2 -2
  14. package/dist/slim-react/jsx-runtime.cjs +2 -4
  15. package/dist/slim-react/jsx-runtime.js +1 -1
  16. package/dist/ssr-render-worker.js +174 -161
  17. package/dist/ssr-watch.js +40 -74
  18. package/package.json +8 -10
  19. package/cli-lib.ts +0 -676
  20. package/cli.ts +0 -36
  21. package/index.ts +0 -17
  22. package/src/build.ts +0 -805
  23. package/src/cloudflare.ts +0 -140
  24. package/src/index.tsx +0 -41
  25. package/src/lambda.ts +0 -287
  26. package/src/slim-react/context.ts +0 -55
  27. package/src/slim-react/dispatcher.ts +0 -87
  28. package/src/slim-react/hooks.ts +0 -137
  29. package/src/slim-react/index.ts +0 -232
  30. package/src/slim-react/jsx-runtime.ts +0 -7
  31. package/src/slim-react/jsx.ts +0 -53
  32. package/src/slim-react/render.ts +0 -1101
  33. package/src/slim-react/renderContext.ts +0 -294
  34. package/src/slim-react/types.ts +0 -33
  35. package/src/source/context.ts +0 -113
  36. package/src/source/graphiql.ts +0 -101
  37. package/src/source/inference.ts +0 -260
  38. package/src/source/runner.ts +0 -138
  39. package/src/source/store.ts +0 -50
  40. package/src/ssr-render-worker.ts +0 -116
  41. package/src/ssr-watch.ts +0 -62
  42. package/src/static.ts +0 -109
  43. package/src/types/global.d.ts +0 -5
  44. package/src/types/hadars.ts +0 -350
  45. package/src/utils/Head.tsx +0 -462
  46. package/src/utils/clientScript.tsx +0 -71
  47. package/src/utils/cookies.ts +0 -16
  48. package/src/utils/loader.ts +0 -335
  49. package/src/utils/proxyHandler.tsx +0 -104
  50. package/src/utils/request.tsx +0 -9
  51. package/src/utils/response.tsx +0 -141
  52. package/src/utils/rspack.ts +0 -467
  53. package/src/utils/runtime.ts +0 -19
  54. package/src/utils/serve.ts +0 -155
  55. package/src/utils/ssrHandler.ts +0 -239
  56. package/src/utils/staticFile.ts +0 -43
  57. package/src/utils/template.html +0 -11
  58. package/src/utils/upgradeRequest.tsx +0 -19
package/dist/ssr-watch.js CHANGED
@@ -8,7 +8,7 @@ import path from "node:path";
8
8
  import { fileURLToPath } from "node:url";
9
9
  import pathMod from "node:path";
10
10
  import { existsSync } from "node:fs";
11
- var __dirname = process.cwd();
11
+ var __dirname2 = process.cwd();
12
12
  var packageDir = pathMod.dirname(fileURLToPath(import.meta.url));
13
13
  var clientScriptPath = pathMod.resolve(packageDir, "template.html");
14
14
  var loaderPath = existsSync(pathMod.resolve(packageDir, "loader.cjs")) ? pathMod.resolve(packageDir, "loader.cjs") : pathMod.resolve(packageDir, "loader.ts");
@@ -21,13 +21,10 @@ var getConfigBase = (mode, isServerBuild = false) => {
21
21
  },
22
22
  resolve: {
23
23
  modules: [
24
- path.resolve(__dirname, "node_modules"),
25
- // 'node_modules' (relative) enables the standard upward-traversal
26
- // resolution so rspack can find transitive deps (e.g. webpack-dev-server)
27
- // that live in a parent node_modules when running from a sub-project.
24
+ path.resolve(__dirname2, "node_modules"),
28
25
  "node_modules"
29
26
  ],
30
- tsConfig: path.resolve(__dirname, "tsconfig.json"),
27
+ tsConfig: path.resolve(__dirname2, "tsconfig.json"),
31
28
  extensions: [".tsx", ".ts", ".js", ".jsx"]
32
29
  },
33
30
  module: {
@@ -49,8 +46,6 @@ var getConfigBase = (mode, isServerBuild = false) => {
49
46
  },
50
47
  exclude: [loaderPath],
51
48
  use: [
52
- // Transforms loadModule('./path') based on build target.
53
- // Runs before swc-loader (loaders execute right-to-left).
54
49
  {
55
50
  loader: loaderPath,
56
51
  options: { server: isServerBuild }
@@ -112,12 +107,10 @@ var getConfigBase = (mode, isServerBuild = false) => {
112
107
  }
113
108
  };
114
109
  };
115
- var buildCompilerConfig = (entry2, opts, includeHotPlugin) => {
116
- const { base: base2 } = opts;
110
+ var buildCompilerConfig = (entry, opts, includeHotPlugin) => {
111
+ const { base } = opts;
117
112
  const isDev = opts.mode === "development";
118
- const isServerBuild = Boolean(
119
- opts.output && typeof opts.output === "object" && (opts.output.library || String(opts.output.filename || "").includes("ssr"))
120
- );
113
+ const isServerBuild = Boolean(opts.output && typeof opts.output === "object" && (opts.output.library || String(opts.output.filename || "").includes("ssr")));
121
114
  const Config = getConfigBase(opts.mode, isServerBuild);
122
115
  const localConfig = {
123
116
  ...Config,
@@ -138,8 +131,8 @@ var buildCompilerConfig = (entry2, opts, includeHotPlugin) => {
138
131
  for (const rule of rules) {
139
132
  const ruleUse = rule;
140
133
  if (ruleUse.use && Array.isArray(ruleUse.use)) {
141
- for (const entry3 of ruleUse.use) {
142
- const useEntry = entry3;
134
+ for (const entry2 of ruleUse.use) {
135
+ const useEntry = entry2;
143
136
  if (useEntry && useEntry.loader && typeof useEntry.loader === "string" && useEntry.loader.includes("swc-loader")) {
144
137
  const options = useEntry.options || {};
145
138
  useEntry.options = options;
@@ -148,7 +141,7 @@ var buildCompilerConfig = (entry2, opts, includeHotPlugin) => {
148
141
  useEntry.options.jsc.experimental.runPluginFirst = true;
149
142
  const existingPlugins = Array.isArray(useEntry.options.jsc.experimental.plugins) ? useEntry.options.jsc.experimental.plugins : [];
150
143
  const incomingPlugins = Array.isArray(opts.swcPlugins) ? opts.swcPlugins : [];
151
- const seen = /* @__PURE__ */ new Set();
144
+ const seen = new Set;
152
145
  const merged = [];
153
146
  for (const p of existingPlugins.concat(incomingPlugins)) {
154
147
  const name = Array.isArray(p) && p.length > 0 ? String(p[0]) : String(p);
@@ -182,46 +175,39 @@ var buildCompilerConfig = (entry2, opts, includeHotPlugin) => {
182
175
  const slimReactIndex = pathMod.resolve(packageDir, "slim-react", "index.js");
183
176
  const slimReactJsx = pathMod.resolve(packageDir, "slim-react", "jsx-runtime.js");
184
177
  const resolveAliases = isServerBuild ? {
185
- // Route all React imports to slim-react for SSR.
186
178
  react: slimReactIndex,
187
179
  "react/jsx-runtime": slimReactJsx,
188
180
  "react/jsx-dev-runtime": slimReactJsx
189
- // @emotion/* is bundled (not external) so that its `react` imports are
190
- // resolved through the alias above to slim-react. If left external,
191
- // emotion loads real React from node_modules and calls
192
- // ReactSharedInternals.H.useContext which requires React's dispatcher.
193
- } : void 0;
181
+ } : undefined;
194
182
  const externals = isServerBuild ? [
195
- // Node.js built-ins — must not be bundled; resolved by the runtime.
196
183
  "node:fs",
197
184
  "node:path",
198
185
  "node:os",
199
186
  "node:stream",
200
187
  "node:util",
201
- // @emotion/server is only used outside component rendering (CSS extraction)
202
- // and does not call React hooks, so it is safe to leave as external.
203
188
  "@emotion/server"
204
- ] : void 0;
189
+ ] : undefined;
205
190
  const effectiveReactDev = isServerBuild ? false : opts.reactMode === "development" ? true : opts.reactMode === "production" ? false : isDev;
206
- if (!isServerBuild && opts.reactMode !== void 0) {
191
+ if (!isServerBuild && opts.reactMode !== undefined) {
207
192
  const rules = localConfig.module?.rules ?? [];
208
193
  for (const rule of rules) {
209
- if (!rule?.use || !Array.isArray(rule.use)) continue;
210
- for (const entry3 of rule.use) {
211
- if (entry3?.loader?.includes("swc-loader")) {
212
- entry3.options = entry3.options ?? {};
213
- entry3.options.jsc = entry3.options.jsc ?? {};
214
- entry3.options.jsc.transform = entry3.options.jsc.transform ?? {};
215
- entry3.options.jsc.transform.react = entry3.options.jsc.transform.react ?? {};
216
- entry3.options.jsc.transform.react.development = effectiveReactDev;
217
- entry3.options.jsc.transform.react.refresh = effectiveReactDev && isDev;
194
+ if (!rule?.use || !Array.isArray(rule.use))
195
+ continue;
196
+ for (const entry2 of rule.use) {
197
+ if (entry2?.loader?.includes("swc-loader")) {
198
+ entry2.options = entry2.options ?? {};
199
+ entry2.options.jsc = entry2.options.jsc ?? {};
200
+ entry2.options.jsc.transform = entry2.options.jsc.transform ?? {};
201
+ entry2.options.jsc.transform.react = entry2.options.jsc.transform.react ?? {};
202
+ entry2.options.jsc.transform.react.development = effectiveReactDev;
203
+ entry2.options.jsc.transform.react.refresh = effectiveReactDev && isDev;
218
204
  }
219
205
  }
220
206
  }
221
207
  }
222
208
  const extraPlugins = [];
223
209
  const defineValues = { ...opts.define ?? {} };
224
- if (!isServerBuild && opts.reactMode !== void 0) {
210
+ if (!isServerBuild && opts.reactMode !== undefined) {
225
211
  defineValues["process.env.NODE_ENV"] = JSON.stringify(opts.reactMode);
226
212
  }
227
213
  if (Object.keys(defineValues).length > 0) {
@@ -233,10 +219,7 @@ var buildCompilerConfig = (entry2, opts, includeHotPlugin) => {
233
219
  const resolveConfig = {
234
220
  extensions: [".tsx", ".ts", ".js", ".jsx"],
235
221
  alias: resolveAliases,
236
- // for server builds prefer the package "main"/"module" fields and avoid "browser" so we don't pick browser-specific entrypoints
237
222
  mainFields: isServerBuild ? ["main", "module"] : ["browser", "module", "main"],
238
- // for server builds exclude the "browser" condition so packages with package.json
239
- // "exports" conditions (e.g. @emotion/*) resolve their Node/CJS entry, not the browser build
240
223
  ...isServerBuild ? { conditionNames: ["node", "require", "default"] } : {}
241
224
  };
242
225
  const optimization = !isServerBuild && !isDev ? {
@@ -253,28 +236,21 @@ var buildCompilerConfig = (entry2, opts, includeHotPlugin) => {
253
236
  }
254
237
  },
255
238
  ...opts.optimization ?? {}
256
- } : opts.optimization ? { ...opts.optimization } : void 0;
239
+ } : opts.optimization ? { ...opts.optimization } : undefined;
257
240
  return {
258
- entry: entry2,
241
+ entry,
259
242
  output: {
260
243
  ...opts.output,
261
244
  clean: false
262
245
  },
263
246
  mode: opts.mode,
264
- // Persist transformed modules to disk — subsequent starts only recompile
265
- // changed files, making repeat dev starts significantly faster.
266
247
  cache: true,
267
248
  externals,
268
- // externalsPresets.node externalises ALL Node.js built-ins (bare names
269
- // and the node: prefix) for both static and dynamic imports. This
270
- // complements the explicit `externals` array: the preset handles the
271
- // node: URI scheme that rspack cannot resolve as a file, while the
272
- // array keeps '@emotion/server' as an explicit external.
273
249
  ...isServerBuild ? { externalsPresets: { node: true } } : {},
274
- ...optimization !== void 0 ? { optimization } : {},
250
+ ...optimization !== undefined ? { optimization } : {},
275
251
  plugins: [
276
252
  !isServerBuild && new rspack.HtmlRspackPlugin({
277
- publicPath: base2 || "/",
253
+ publicPath: base || "/",
278
254
  template: opts.htmlTemplate ? pathMod.resolve(process.cwd(), opts.htmlTemplate) : clientScriptPath,
279
255
  scriptLoading: "module",
280
256
  filename: "out.html",
@@ -287,10 +263,7 @@ var buildCompilerConfig = (entry2, opts, includeHotPlugin) => {
287
263
  const asset = compilation.assets["out.html"];
288
264
  if (asset) {
289
265
  const html = asset.source();
290
- const updated = html.replace(
291
- /(<script\b[^>]*\btype="module"[^>]*)(>)/g,
292
- (match, before, end) => before.includes("async") ? match : `${before} async${end}`
293
- );
266
+ const updated = html.replace(/(<script\b[^>]*\btype="module"[^>]*)(>)/g, (match, before, end) => before.includes("async") ? match : `${before} async${end}`);
294
267
  compilation.assets["out.html"] = {
295
268
  source: () => updated,
296
269
  size: () => Buffer.byteLength(updated)
@@ -300,35 +273,27 @@ var buildCompilerConfig = (entry2, opts, includeHotPlugin) => {
300
273
  });
301
274
  }
302
275
  },
303
- isDev && !isServerBuild && new ReactRefreshPlugin(),
304
- includeHotPlugin && isDev && !isServerBuild && new rspack.HotModuleReplacementPlugin(),
276
+ isDev && !isServerBuild && new ReactRefreshPlugin,
277
+ includeHotPlugin && isDev && !isServerBuild && new rspack.HotModuleReplacementPlugin,
305
278
  ...extraPlugins,
306
279
  ...opts.plugins ?? []
307
280
  ],
308
281
  ...localConfig,
309
- // Merge base resolve (modules, tsConfig, extensions) with per-build resolve
310
- // (alias, mainFields). The spread order matters: resolveConfig wins for keys
311
- // it defines, localConfig.resolve wins for keys it defines exclusively.
312
282
  resolve: {
313
283
  ...localConfig.resolve,
314
284
  ...resolveConfig
315
285
  },
316
- // HMR is not implemented for module chunk format, so disable outputModule
317
- // for client builds. SSR builds still need it for dynamic import() of exports.
318
286
  experiments: {
319
287
  ...localConfig.experiments || {},
320
288
  outputModule: isServerBuild
321
289
  },
322
- // Prevent rspack from watching its own build output — without this the
323
- // SSR watcher writing .hadars/index.ssr.js triggers the client compiler
324
- // and vice versa, causing an infinite rebuild loop.
325
290
  watchOptions: {
326
291
  ignored: ["**/node_modules/**", "**/.hadars/**", "/tmp/**"]
327
292
  }
328
293
  };
329
294
  };
330
- var compileEntry = async (entry2, opts) => {
331
- const compiler = rspack(buildCompilerConfig(entry2, opts, true));
295
+ var compileEntry = async (entry, opts) => {
296
+ const compiler = rspack(buildCompilerConfig(entry, opts, true));
332
297
  if (opts.watch) {
333
298
  await new Promise((resolve, reject) => {
334
299
  let first = true;
@@ -376,9 +341,11 @@ var compileEntry = async (entry2, opts) => {
376
341
  var args = process.argv.slice(2);
377
342
  var argv = {};
378
343
  for (const a of args) {
379
- if (!a.startsWith("--")) continue;
344
+ if (!a.startsWith("--"))
345
+ continue;
380
346
  const idx = a.indexOf("=");
381
- if (idx === -1) continue;
347
+ if (idx === -1)
348
+ continue;
382
349
  const key = a.slice(2, idx);
383
350
  const val = a.slice(idx + 1);
384
351
  argv[key] = val;
@@ -387,9 +354,9 @@ var entry = argv["entry"];
387
354
  var outDir = argv["outDir"] || ".hadars";
388
355
  var outFile = argv["outFile"] || "index.ssr.js";
389
356
  var base = argv["base"] || "";
390
- var swcPlugins = argv["swcPlugins"] ? JSON.parse(argv["swcPlugins"]) : void 0;
391
- var define = argv["define"] ? JSON.parse(argv["define"]) : void 0;
392
- var moduleRules = argv["moduleRules"] ? JSON.parse(argv["moduleRules"], (_k, v) => v && typeof v === "object" && "__re" in v ? new RegExp(v.__re, v.__flags) : v) : void 0;
357
+ var swcPlugins = argv["swcPlugins"] ? JSON.parse(argv["swcPlugins"]) : undefined;
358
+ var define = argv["define"] ? JSON.parse(argv["define"]) : undefined;
359
+ var moduleRules = argv["moduleRules"] ? JSON.parse(argv["moduleRules"], (_k, v) => v && typeof v === "object" && ("__re" in v) ? new RegExp(v.__re, v.__flags) : v) : undefined;
393
360
  if (!entry) {
394
361
  console.error("ssr-watch: missing --entry argument");
395
362
  process.exit(1);
@@ -417,8 +384,7 @@ if (!entry) {
417
384
  }
418
385
  });
419
386
  console.log("ssr-watch: initial-build-complete");
420
- await new Promise(() => {
421
- });
387
+ await new Promise(() => {});
422
388
  } catch (err) {
423
389
  console.error("ssr-watch: error", err);
424
390
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hadars",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "Minimal SSR framework for React — rspack, HMR, TypeScript, Bun/Node/Deno",
5
5
  "module": "./dist/index.js",
6
6
  "type": "module",
@@ -11,10 +11,6 @@
11
11
  "types": "dist/index.d.ts",
12
12
  "files": [
13
13
  "dist",
14
- "src",
15
- "cli-lib.ts",
16
- "cli.ts",
17
- "index.ts",
18
14
  "LICENSE"
19
15
  ],
20
16
  "exports": {
@@ -40,7 +36,7 @@
40
36
  },
41
37
  "scripts": {
42
38
  "build:lib": "tsup src/index.tsx src/lambda.ts src/cloudflare.ts src/slim-react/index.ts src/slim-react/jsx-runtime.ts --format esm,cjs --dts --out-dir dist --clean --external '@rspack/*' --external '@rspack/binding'",
43
- "build:cli": "node build-scripts/build-cli.mjs",
39
+ "build:cli": "bun build-scripts/build-cli.mjs",
44
40
  "build:all": "node build-scripts/build-all.mjs",
45
41
  "test": "bun test test/render-compare.test.tsx && bun test test/ssr.test.ts",
46
42
  "prepare": "npm run build:all",
@@ -75,7 +71,8 @@
75
71
  "@rspack/core": "1.6.8",
76
72
  "@rspack/dev-server": "^1.2.1",
77
73
  "@rspack/plugin-react-refresh": "^1.6.1",
78
- "@swc/core": "^1.15.18",
74
+ "@svgr/webpack": "^8.1.0",
75
+ "@swc/core": "^1.15.24",
79
76
  "@types/bun": "latest",
80
77
  "react-refresh": "^0.17.0"
81
78
  },
@@ -84,16 +81,17 @@
84
81
  "@types/react-dom": "^19.2.3",
85
82
  "react": "^19.2.4",
86
83
  "react-dom": "^19.2.4",
87
- "tsup": "^8.3.5",
84
+ "tsup": "^8.5.1",
88
85
  "typescript": "^5.9.3"
89
86
  },
90
87
  "dependencies": {
91
- "@svgr/webpack": "^8.1.0",
92
- "esbuild": "^0.27.4",
93
88
  "postcss": "^8.5.8",
94
89
  "postcss-load-config": "^6.0.1",
95
90
  "postcss-loader": "^8.2.1"
96
91
  },
92
+ "overrides": {
93
+ "js-yaml": "^4.1.1"
94
+ },
97
95
  "license": "MIT",
98
96
  "repository": {
99
97
  "type": "git",