@pantoken/vite-workspace-orchestrator 0.1.0 → 0.1.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.
package/README.md CHANGED
@@ -14,7 +14,8 @@ Key behaviors:
14
14
  filtered out.
15
15
  - Debounces rapid changes per package before spawning a build.
16
16
  - Rebuilds dependents in topological order after a successful build.
17
- - Registers optional HMR paths with Vite's watcher, and mounts optional static file servers.
17
+ - Watches built-output paths with native `fs.watch` and emits `change` events into Vite — CSS files
18
+ already in the module graph get a targeted hot-update; anything else falls back to a full reload.
18
19
 
19
20
  ## Usage
20
21
 
@@ -34,7 +35,7 @@ export default {
34
35
  dependents: [],
35
36
  },
36
37
  ],
37
- hmrWatchPaths: [resolve(root, "formats/components/generated")],
38
+ outputWatchPaths: [resolve(root, "formats/components/generated")],
38
39
  debounceMs: 200,
39
40
  }),
40
41
  ],
package/dist/index.d.mts CHANGED
@@ -50,17 +50,14 @@ interface OrchestratorOptions {
50
50
  /** The upstream workspace dependency graph. */
51
51
  upstream: readonly UpstreamNode[];
52
52
  /**
53
- * Paths to add to Vite's `server.watcher` so HMR fires when built output is updated (e.g. a
54
- * package's `dist` or `generated` directory).
53
+ * Paths to watch with native `fs.watch` so Vite picks up built output after an upstream rebuild
54
+ * (e.g. a package's `dist` or `generated` directory). Uses native `fs.watch` rather than
55
+ * chokidar's `add()`, which doesn't reliably detect changes in pnpm-symlinked or out-of-root
56
+ * directories. On each change a synthetic `"change"` event is emitted on `server.watcher`: for
57
+ * CSS files already in the module graph Vite triggers a targeted hot-update; for anything else
58
+ * it falls back to a full page reload.
55
59
  */
56
- hmrWatchPaths?: readonly string[];
57
- /**
58
- * Paths to watch with native `fs.watch` for triggering module invalidation. Unlike
59
- * `hmrWatchPaths` (which relies on chokidar), these are monitored with Node's native `fs.watch` —
60
- * which reliably detects changes for pnpm-symlinked workspace `dist` directories. On a change, a
61
- * synthetic `"change"` event is emitted on `server.watcher` so the module graph is invalidated.
62
- */
63
- reloadWatchPaths?: readonly string[];
60
+ outputWatchPaths?: readonly string[];
64
61
  /** Debounce delay in milliseconds before triggering a rebuild (default: 200). */
65
62
  debounceMs?: number;
66
63
  /** Optional static file-serving middleware entries. */
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { readFileSync, watch } from "node:fs";
2
- import { matchesGlob, resolve } from "node:path";
2
+ import { isAbsolute, matchesGlob, relative, resolve } from "node:path";
3
3
  import { spawn } from "node:child_process";
4
4
  //#region src/file-server.ts
5
5
  /**
@@ -22,7 +22,13 @@ function mountFileServers(fileServers, middlewares) {
22
22
  return;
23
23
  }
24
24
  const resolved = entry.pathTransform ? entry.pathTransform(filePath) : filePath;
25
- const fullPath = resolve(entry.serveDir, resolved.slice(1));
25
+ const serveRoot = resolve(entry.serveDir);
26
+ const fullPath = resolve(serveRoot, resolved.slice(1));
27
+ const rel = relative(serveRoot, fullPath);
28
+ if (rel.startsWith("..") || isAbsolute(rel)) {
29
+ next();
30
+ return;
31
+ }
26
32
  try {
27
33
  const content = readFileSync(fullPath, "utf8");
28
34
  res.setHeader("Content-Type", entry.contentType);
@@ -125,7 +131,7 @@ function createScheduler(nodeMap, logger, debounceMs) {
125
131
  * dependents: [],
126
132
  * },
127
133
  * ],
128
- * hmrWatchPaths: [resolve(root, "formats/components/generated")],
134
+ * outputWatchPaths: [resolve(root, "formats/components/generated")],
129
135
  * });
130
136
  * ```
131
137
  *
@@ -166,7 +172,7 @@ function matchesFilters(filename, node) {
166
172
  * @returns A Vite plugin object (`apply: "serve"`).
167
173
  */
168
174
  const workspaceOrchestrator = (options) => {
169
- const { upstream, hmrWatchPaths = [], reloadWatchPaths = [], debounceMs = DEFAULT_DEBOUNCE_MS, fileServers = [] } = options;
175
+ const { upstream, outputWatchPaths = [], debounceMs = DEFAULT_DEBOUNCE_MS, fileServers = [] } = options;
170
176
  return {
171
177
  apply: "serve",
172
178
  name: "workspace-orchestrator",
@@ -181,13 +187,10 @@ const workspaceOrchestrator = (options) => {
181
187
  });
182
188
  fsWatchers.push(watcher);
183
189
  } catch {}
184
- for (const hmrPath of hmrWatchPaths) server.watcher.add(hmrPath);
185
- for (const reloadPath of reloadWatchPaths) try {
186
- const watcher = watch(reloadPath, { recursive: true }, (_event, filename) => {
190
+ for (const outputPath of outputWatchPaths) try {
191
+ const watcher = watch(outputPath, { recursive: true }, (_event, filename) => {
187
192
  if (filename === null) return;
188
- const fullPath = resolve(reloadPath, filename);
189
- logger.info(`[orchestrator] invalidating ${fullPath}`, { timestamp: true });
190
- server.watcher.emit("change", fullPath);
193
+ server.watcher.emit("change", resolve(outputPath, filename));
191
194
  });
192
195
  fsWatchers.push(watcher);
193
196
  } catch {}
package/package.json CHANGED
@@ -1,32 +1,43 @@
1
1
  {
2
2
  "name": "@pantoken/vite-workspace-orchestrator",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Vite dev-server plugin that watches upstream workspace packages and rebuilds them (and their dependents) when source changes.",
5
+ "homepage": "https://pantoken.iywahl.com",
6
+ "bugs": "https://github.com/thedannywahl/pantoken/issues",
5
7
  "license": "MIT",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/thedannywahl/pantoken.git",
11
+ "directory": "plugins/vite/workspace-orchestrator"
12
+ },
6
13
  "files": [
7
14
  "dist"
8
15
  ],
9
16
  "type": "module",
17
+ "sideEffects": false,
10
18
  "exports": {
11
19
  ".": "./dist/index.mjs",
12
20
  "./package.json": "./package.json"
13
21
  },
14
22
  "publishConfig": {
15
- "access": "public"
23
+ "access": "public",
24
+ "provenance": true
25
+ },
26
+ "scripts": {
27
+ "dev": "vp pack --watch",
28
+ "test": "vp test",
29
+ "check": "vp check"
16
30
  },
17
31
  "devDependencies": {
18
- "@types/node": "^24.13.3",
19
- "typescript": "^6.0.3",
20
- "vite": "npm:@voidzero-dev/vite-plus-core@0.2.4",
21
- "vite-plus": "0.2.4"
32
+ "@types/node": "catalog:",
33
+ "typescript": "catalog:",
34
+ "vite": "catalog:",
35
+ "vite-plus": "catalog:"
22
36
  },
23
37
  "peerDependencies": {
24
38
  "vite": ">=6"
25
39
  },
26
- "scripts": {
27
- "build": "vp pack",
28
- "dev": "vp pack --watch",
29
- "test": "vp test",
30
- "check": "vp check"
40
+ "engines": {
41
+ "node": ">=22.18.0"
31
42
  }
32
- }
43
+ }