@ultimat3/render 27.16.0 → 28.0.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ultimat3/render",
3
- "version": "27.16.0",
3
+ "version": "28.0.0",
4
4
  "description": "The route primitive and the five render modes: static, isr, ssr, stream, spa.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -33,18 +33,18 @@
33
33
  "LICENSE"
34
34
  ],
35
35
  "engines": {
36
- "bun": ">=1.4.2"
36
+ "bun": ">=1.4.3"
37
37
  },
38
38
  "scripts": {
39
39
  "typecheck": "tsc --noEmit -p tsconfig.json",
40
40
  "test": "bun test"
41
41
  },
42
42
  "dependencies": {
43
- "@ultimat3/cache": "27.16.0",
44
- "@ultimat3/core": "27.16.0",
45
- "@ultimat3/http": "27.16.0",
46
- "@ultimat3/i18n": "27.16.0",
47
- "@ultimat3/seo": "27.16.0",
43
+ "@ultimat3/cache": "28.0.0",
44
+ "@ultimat3/core": "28.0.0",
45
+ "@ultimat3/http": "28.0.0",
46
+ "@ultimat3/i18n": "28.0.0",
47
+ "@ultimat3/seo": "28.0.0",
48
48
  "sass": "1.105.1"
49
49
  }
50
50
  }
@@ -12,11 +12,15 @@ import type { Surface } from './surfaces';
12
12
  import { surfaceUnder } from './surfaces';
13
13
 
14
14
  /**
15
- * Why a transform at all: `tsconfig.json` says `jsx: 'preserve'`, which makes Bun fall back to the
16
- * CLASSIC React factory and ignore `jsxImportSource` entirely — every `.tsx` in an Ultimate app
17
- * compiles to `React.createElement` against a global that does not exist. `jsxImportSource` stays
18
- * pointed at `solid-js` because that is where the JSX *type* namespace lives (`class`, not
19
- * `className`); the *runtime* factory is the framework's, and an app never configures one.
15
+ * Why a transform at all: Bun's own compile of a `.tsx` under the app's `tsconfig.json` (`jsx:
16
+ * 'preserve'`, `jsxImportSource: 'solid-js'`) is wrong on every Bun. Through 1.4.2 it fell back to
17
+ * the CLASSIC React factory — `React.createElement` against a global that does not exist. From
18
+ * 1.4.3 it honours `jsxImportSource` and imports `jsxDEV` from `solid-js/jsx-dev-runtime`, which
19
+ * solid-js maps to a module exporting no such name: a link-time `SyntaxError` (issue #883,
20
+ * measured on 1.3.14 and 1.4.3). Solid ships no runtime factory because its JSX is a COMPILE-time
21
+ * contract. `jsxImportSource` stays pointed at `solid-js` because that is where the JSX *type*
22
+ * namespace lives (`class`, not `className`); the *runtime* factory is the framework's, every graph
23
+ * that loads a `.tsx` installs this transform or the island one, and an app never configures one.
20
24
  */
21
25
  const JSX_FACTORY = '__xh';
22
26
  const JSX_FRAGMENT = '__xFragment';
@@ -57,7 +61,8 @@ export const JSX_FACTORY_SPECIFIER = ((): string => {
57
61
  })();
58
62
 
59
63
  /** No newline: the prelude shares line 1 with the file's own first line, so stack traces still point at it. */
60
- const JSX_PRELUDE = `import { h as ${JSX_FACTORY}, Fragment as ${JSX_FRAGMENT} } from ${JSON.stringify(JSX_FACTORY_SPECIFIER)};`;
64
+ const jsxPrelude = (factory: string): string =>
65
+ `import { h as ${JSX_FACTORY}, Fragment as ${JSX_FRAGMENT} } from ${JSON.stringify(factory)};`;
61
66
 
62
67
  const transpiler = new Bun.Transpiler({
63
68
  loader: 'tsx',
@@ -244,11 +249,14 @@ export function stylesheetOrder(a: Stylesheet, b: Stylesheet): number {
244
249
  /**
245
250
  * `.tsx` source → JS calling the server factory. Exported so the transform is testable as a pure
246
251
  * function: the plugin below is the six lines of glue that hand it a file.
252
+ *
253
+ * `factory` is the specifier the prelude imports `h` from: the runtime loader's resolved URL by
254
+ * default, and the PATH that URL names for a bundler (`tsx-build-plugin.ts` says why).
247
255
  */
248
- export function transformTsx(source: string): string {
256
+ export function transformTsx(source: string, factory: string = JSX_FACTORY_SPECIFIER): string {
249
257
  // No newline between: the prelude shares line 1 with the file's own first line, so every stack
250
258
  // trace and every reported error still points at the line the author wrote.
251
- return JSX_PRELUDE + transpiler.transformSync(source);
259
+ return jsxPrelude(factory) + transpiler.transformSync(source);
252
260
  }
253
261
 
254
262
  /**
package/src/server.ts CHANGED
@@ -89,3 +89,4 @@ export {
89
89
  } from './render-stream';
90
90
  // ---- the Sass compile cache: where it lives, and how often this process ran Sass instead --------
91
91
  export { sassCompilations, setSassCacheDir } from './sass-cache';
92
+ export { serverTsxBuildPlugin } from './tsx-build-plugin';
@@ -0,0 +1,34 @@
1
+ /**
2
+ * The server `.tsx` transform as a `Bun.build` plugin: what a bundle that carries server code —
3
+ * the compiled `x` executable, a module-graph measurement — hands the bundler so a `.tsx` it
4
+ * reaches compiles to the server factory, the same output the runtime loader gives that file.
5
+ */
6
+
7
+ import type { BunPlugin } from 'bun';
8
+ import { JSX_FACTORY_SPECIFIER, transformTsx } from './module-loader';
9
+
10
+ /**
11
+ * The PATH the loader's resolved URL names. `Bun.build` does not resolve a `file:` specifier —
12
+ * measured on 1.4.3, `Could not resolve: "file:///…/packages/render/src/index.ts"` — and resolves an
13
+ * absolute path. The bare-name fallback (inside a compiled binary) passes through unchanged.
14
+ */
15
+ const BUILD_FACTORY_SPECIFIER = JSX_FACTORY_SPECIFIER.startsWith('file:')
16
+ ? Bun.fileURLToPath(JSX_FACTORY_SPECIFIER)
17
+ : JSX_FACTORY_SPECIFIER;
18
+
19
+ /**
20
+ * Without it a bundle compiles each `.tsx` with Bun's own transform, which no Bun gets right
21
+ * (`module-loader.ts`): 1.4.3 refuses the build outright with `No matching export in
22
+ * "solid-js/dist/solid.js" for import "jsxDEV"` (issue #883), and earlier Bun shipped a
23
+ * `React.createElement` nobody defines. Islands do not use this: their graph is a browser's, and
24
+ * `@ultimat3/cli`'s `solidJsxPlugin` compiles it with Solid.
25
+ */
26
+ export const serverTsxBuildPlugin: BunPlugin = {
27
+ name: 'ultimate-render-tsx',
28
+ setup(build): void {
29
+ build.onLoad({ filter: /\.tsx$/ }, async ({ path }) => ({
30
+ contents: transformTsx(await Bun.file(path).text(), BUILD_FACTORY_SPECIFIER),
31
+ loader: 'js',
32
+ }));
33
+ },
34
+ };