@timber-js/app 0.1.2 → 0.1.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.
@@ -1 +1 @@
1
- {"version":3,"file":"dev-server.d.ts","sourceRoot":"","sources":["../../src/plugins/dev-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAC;AAIlD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAiChD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAmD1D"}
1
+ {"version":3,"file":"dev-server.d.ts","sourceRoot":"","sources":["../../src/plugins/dev-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAiC,MAAM,MAAM,CAAC;AAGlE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAiChD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAmD1D"}
@@ -1 +1 @@
1
- {"version":3,"file":"entries.d.ts","sourceRoot":"","sources":["../../src/plugins/entries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAGnC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AA8FhD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CA2FxD"}
1
+ {"version":3,"file":"entries.d.ts","sourceRoot":"","sources":["../../src/plugins/entries.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAInC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAoGhD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CA2FxD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timber-js/app",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Vite-native React framework for Cloudflare Workers — correct HTTP semantics, real status codes, pages that work without JavaScript",
5
5
  "type": "module",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -90,15 +90,15 @@
90
90
  "dependencies": {
91
91
  "@opentelemetry/api": "^1.9.0",
92
92
  "@opentelemetry/context-async-hooks": "^2.6.0",
93
- "@opentelemetry/sdk-trace-base": "^2.6.0",
94
- "@vitejs/plugin-react": "^6.0.0",
95
- "@vitejs/plugin-rsc": "~0.5.21"
93
+ "@opentelemetry/sdk-trace-base": "^2.6.0"
96
94
  },
97
95
  "peerDependencies": {
98
96
  "@content-collections/core": "^0.14.0",
99
97
  "@content-collections/mdx": "^0.2.0",
100
98
  "@content-collections/vite": "^0.2.0",
101
99
  "@mdx-js/rollup": "^3.0.0",
100
+ "@vitejs/plugin-react": "^6.0.0",
101
+ "@vitejs/plugin-rsc": ">=0.5.21",
102
102
  "nuqs": "^2.0.0",
103
103
  "react": "^19.2.4",
104
104
  "react-dom": "^19.2.4",
package/src/index.ts CHANGED
@@ -2,6 +2,7 @@ import type { Plugin, PluginOption } from 'vite';
2
2
  import { existsSync } from 'node:fs';
3
3
  import { join } from 'node:path';
4
4
  import { pathToFileURL } from 'node:url';
5
+ import { createRequire } from 'node:module';
5
6
  import react from '@vitejs/plugin-react';
6
7
  import { cacheTransformPlugin } from './plugins/cache-transform';
7
8
  import { timberContent } from './plugins/content';
@@ -353,8 +354,14 @@ export function timber(config?: TimberUserConfig): PluginOption[] {
353
354
  // We do NOT set customBuildApp — the RSC plugin's orchestration is correct
354
355
  // and handles bundle ordering, asset manifest generation, and environment
355
356
  // imports manifest. See @vitejs/plugin-rsc's buildApp implementation.
357
+ // Resolve @vitejs/plugin-rsc from the consumer's project (process.cwd()),
358
+ // not from timber's own node_modules. This is critical for pnpm link:
359
+ // when linked, timber's node_modules has a separate vite instance, and
360
+ // the RSC plugin must use the same vite instance as the dev server.
361
+ const consumerRequire = createRequire(join(process.cwd(), 'package.json'));
362
+ const rscPluginPath = consumerRequire.resolve('@vitejs/plugin-rsc');
356
363
  ctx.timer.start('rsc-plugin-import');
357
- const rscPluginsPromise = import('@vitejs/plugin-rsc').then(({ default: vitePluginRsc }) => {
364
+ const rscPluginsPromise = import(pathToFileURL(rscPluginPath).href).then(({ default: vitePluginRsc }) => {
358
365
  ctx.timer.end('rsc-plugin-import');
359
366
  return vitePluginRsc({
360
367
  serverHandler: false,
@@ -12,8 +12,7 @@
12
12
  * Design docs: 18-build-system.md §"Dev Server", 02-rendering-pipeline.md
13
13
  */
14
14
 
15
- import type { Plugin, ViteDevServer } from 'vite';
16
- import { isRunnableDevEnvironment } from 'vite';
15
+ import type { Plugin, ViteDevServer, DevEnvironment } from 'vite';
17
16
  import type { IncomingMessage, ServerResponse } from 'node:http';
18
17
  import { join } from 'node:path';
19
18
  import type { PluginContext } from '#/index.js';
@@ -147,8 +146,11 @@ function createTimberMiddleware(server: ViteDevServer, projectRoot: string) {
147
146
  // environment's module runner for HMR-aware loading.
148
147
  let handler: (req: Request) => Promise<Response>;
149
148
  try {
150
- const rscEnv = server.environments.rsc;
151
- if (!isRunnableDevEnvironment(rscEnv)) {
149
+ const rscEnv = server.environments.rsc as DevEnvironment & { runner?: { import: (id: string) => Promise<any> } };
150
+ // Duck-type check instead of isRunnableDevEnvironment() — the vite
151
+ // import-based check fails across pnpm link boundaries where the
152
+ // linked package resolves a different vite module instance.
153
+ if (!rscEnv?.runner?.import) {
152
154
  throw new Error('[timber] RSC environment is not runnable');
153
155
  }
154
156
  const rscModule = await rscEnv.runner.import(RSC_ENTRY_ID);
@@ -14,10 +14,17 @@
14
14
  import type { Plugin } from 'vite';
15
15
  import { resolve, dirname } from 'node:path';
16
16
  import { fileURLToPath } from 'node:url';
17
+ import { existsSync } from 'node:fs';
17
18
  import type { PluginContext } from '#/index.js';
18
19
 
19
20
  const __dirname = dirname(fileURLToPath(import.meta.url));
20
- const SRC_DIR = resolve(__dirname, '..');
21
+
22
+ // In workspace dev, __dirname is src/plugins/ and src/ is the parent.
23
+ // In published package, entries.ts is bundled into dist/index.js so
24
+ // __dirname is dist/ and src/ is a sibling directory.
25
+ const SRC_DIR = existsSync(resolve(__dirname, '..', 'server', 'rsc-entry', 'index.ts'))
26
+ ? resolve(__dirname, '..')
27
+ : resolve(__dirname, '..', 'src');
21
28
 
22
29
  // ─── Virtual Module IDs ──────────────────────────────────────────────────
23
30