@reactra/vite-plugin 0.1.0-alpha.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/LICENSE +21 -0
- package/README.md +17 -0
- package/dist/esbuild-prescan.d.ts +31 -0
- package/dist/esbuild-prescan.d.ts.map +1 -0
- package/dist/esbuild-prescan.js +75 -0
- package/dist/esbuild-prescan.js.map +1 -0
- package/dist/extract.d.ts +128 -0
- package/dist/extract.d.ts.map +1 -0
- package/dist/extract.js +155 -0
- package/dist/extract.js.map +1 -0
- package/dist/fingerprint.d.ts +28 -0
- package/dist/fingerprint.d.ts.map +1 -0
- package/dist/fingerprint.js +68 -0
- package/dist/fingerprint.js.map +1 -0
- package/dist/graph-cache.d.ts +23 -0
- package/dist/graph-cache.d.ts.map +1 -0
- package/dist/graph-cache.js +52 -0
- package/dist/graph-cache.js.map +1 -0
- package/dist/index.d.ts +84 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +379 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest.d.ts +57 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +147 -0
- package/dist/manifest.js.map +1 -0
- package/dist/resource-names.d.ts +49 -0
- package/dist/resource-names.d.ts.map +1 -0
- package/dist/resource-names.js +128 -0
- package/dist/resource-names.js.map +1 -0
- package/dist/sidecar-writer.d.ts +60 -0
- package/dist/sidecar-writer.d.ts.map +1 -0
- package/dist/sidecar-writer.js +114 -0
- package/dist/sidecar-writer.js.map +1 -0
- package/dist/walker.d.ts +332 -0
- package/dist/walker.d.ts.map +1 -0
- package/dist/walker.js +1070 -0
- package/dist/walker.js.map +1 -0
- package/package.json +39 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graph-cache.js","sourceRoot":"","sources":["../src/graph-cache.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,EAAE;AACF,yEAAyE;AACzE,iFAAiF;AACjF,EAAE;AACF,0EAA0E;AAC1E,+EAA+E;AAC/E,+EAA+E;AAC/E,4EAA4E;AAC5E,6EAA6E;AAC7E,mCAAmC;AACnC,EAAE;AACF,kFAAkF;AAClF,8EAA8E;AAC9E,+EAA+E;AAC/E,2EAA2E;AAC3E,gDAAgD;AAChD,EAAE;AACF,+EAA+E;AAC/E,+EAA+E;AAC/E,iEAAiE;AAEjE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAEtC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAkBtD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAe,EAAE;IAC/C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAoC,CAAA;IAE1D,MAAM,aAAa,GAAG,CAAC,IAAY,EAA4B,EAAE;QAC/D,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAC/B,IAAI,MAAM;YAAE,OAAO,MAAM,CAAA;QACzB,IAAI,UAAoC,CAAA;QACxC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;YACzC,qEAAqE;YACrE,UAAU,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,UAAU,CAAA;QACtD,CAAC;QAAC,MAAM,CAAC;YACP,kEAAkE;YAClE,oEAAoE;YACpE,UAAU,GAAG,EAAE,CAAA;QACjB,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;QAC5B,OAAO,UAAU,CAAA;IACnB,CAAC,CAAA;IAED,OAAO,EAAE,aAAa,EAAE,CAAA;AAC1B,CAAC,CAAA"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { Plugin } from "vite";
|
|
2
|
+
import { type EsbuildPlugin } from "./esbuild-prescan.ts";
|
|
3
|
+
/**
|
|
4
|
+
* Options accepted by the Vite plugin factory. Reserved for Phase 2 —
|
|
5
|
+
* pagesDir / storesDir / servicesDir / emitSidecars / devtools per
|
|
6
|
+
* Compiler §7.1 land alongside items #7 and #5c.
|
|
7
|
+
*/
|
|
8
|
+
export interface ReactraVitePluginOptions {
|
|
9
|
+
/** Reserved — no options recognised in the Phase 1 MVP. */
|
|
10
|
+
readonly _reserved?: never;
|
|
11
|
+
}
|
|
12
|
+
interface ResolvedConfigLike {
|
|
13
|
+
readonly root: string;
|
|
14
|
+
}
|
|
15
|
+
interface FSWatcherLike {
|
|
16
|
+
on(event: "add" | "unlink" | "change", listener: (path: string) => void): unknown;
|
|
17
|
+
}
|
|
18
|
+
interface ViteDevServerLike {
|
|
19
|
+
readonly watcher: FSWatcherLike;
|
|
20
|
+
}
|
|
21
|
+
interface ViteSourceMap {
|
|
22
|
+
version: 3;
|
|
23
|
+
file: string;
|
|
24
|
+
sources: string[];
|
|
25
|
+
sourcesContent: string[];
|
|
26
|
+
names: string[];
|
|
27
|
+
mappings: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Vite plugin shape used by Reactra. Structurally a subset of Vite's
|
|
31
|
+
* `Plugin` interface — we don't import Vite types so the plugin source
|
|
32
|
+
* resolves under Bun without Vite installed (matches the test environment).
|
|
33
|
+
*/
|
|
34
|
+
export interface ReactraVitePlugin {
|
|
35
|
+
readonly name: string;
|
|
36
|
+
readonly enforce: "pre";
|
|
37
|
+
/**
|
|
38
|
+
* Day 24 / `#15`: contributes
|
|
39
|
+
* `optimizeDeps.esbuildOptions.plugins` so esbuild's dep-scan pass
|
|
40
|
+
* can preprocess Reactra DSL files before its parser sees them.
|
|
41
|
+
* Returns a partial UserConfig — Vite shallow-merges with the
|
|
42
|
+
* user's `vite.config.ts`.
|
|
43
|
+
*/
|
|
44
|
+
config(): {
|
|
45
|
+
optimizeDeps: {
|
|
46
|
+
esbuildOptions: {
|
|
47
|
+
plugins: EsbuildPlugin[];
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
configResolved(config: ResolvedConfigLike): void;
|
|
52
|
+
buildStart(): void;
|
|
53
|
+
configureServer(server: ViteDevServerLike): void;
|
|
54
|
+
transform(code: string, id: string): {
|
|
55
|
+
code: string;
|
|
56
|
+
map: ViteSourceMap | null;
|
|
57
|
+
} | null;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Vite plugin factory.
|
|
61
|
+
*
|
|
62
|
+
* ```ts
|
|
63
|
+
* // vite.config.ts
|
|
64
|
+
* import { defineConfig } from "vite"
|
|
65
|
+
* import reactra from "@reactra/vite-plugin"
|
|
66
|
+
* import react from "@vitejs/plugin-react"
|
|
67
|
+
*
|
|
68
|
+
* export default defineConfig({
|
|
69
|
+
* plugins: [reactra(), react()],
|
|
70
|
+
* })
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* Reactra MUST run before @vitejs/plugin-react. The enforce: "pre" hint
|
|
74
|
+
* pins us to the head of the pipeline; downstream plugins see standard
|
|
75
|
+
* React 19 TSX, never the DSL.
|
|
76
|
+
*/
|
|
77
|
+
export declare const reactraVitePlugin: (_options?: ReactraVitePluginOptions) => Plugin;
|
|
78
|
+
export default reactraVitePlugin;
|
|
79
|
+
export { chainsForRoutes, collectServiceInjectionDiagnostics, deriveRoutePath, emitRouteManifest, emitRouterMiddleware, scanMiddleware, scanPages, scanServices, scanStores, type DiscoveredMiddleware, type DiscoveredRoute, type DiscoveredService, type DiscoveredStore, type ServiceInjectionDiagnostic, } from "./walker.ts";
|
|
80
|
+
export { MANIFEST_RELATIVE_PATH, ROUTER_MIDDLEWARE_RELATIVE_PATH, regenerateRouteManifest, type RegenerateResult, } from "./manifest.ts";
|
|
81
|
+
export { RESOURCE_NAMES_RELATIVE_PATH, collectResourceNames, emitResourceNames, regenerateResourceNames, type ResourceNamesResult, } from "./resource-names.ts";
|
|
82
|
+
export { deleteSidecar, isEmptyForIndex, writeSidecar, type DeleteSidecarResult, type WriteSidecarResult, } from "./sidecar-writer.ts";
|
|
83
|
+
export { reactraEsbuildPlugin } from "./esbuild-prescan.ts";
|
|
84
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAkBlC,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAmC/E;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,2DAA2D;IAC3D,QAAQ,CAAC,SAAS,CAAC,EAAE,KAAK,CAAA;CAC3B;AAID,UAAU,kBAAkB;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAID,UAAU,aAAa;IACrB,EAAE,CAAC,KAAK,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,EAAE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAA;CAClF;AACD,UAAU,iBAAiB;IACzB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAA;CAChC;AAQD,UAAU,aAAa;IACrB,OAAO,EAAE,CAAC,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAA;IACvB;;;;;;OAMG;IACH,MAAM,IAAI;QACR,YAAY,EAAE;YACZ,cAAc,EAAE;gBAGd,OAAO,EAAE,aAAa,EAAE,CAAA;aACzB,CAAA;SACF,CAAA;KACF,CAAA;IACD,cAAc,CAAC,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAAA;IAChD,UAAU,IAAI,IAAI,CAAA;IAClB,eAAe,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAAA;IAChD,SAAS,CACP,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,GACT;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAA;CACtD;AAmDD;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,iBAAiB,GAC5B,WAAU,wBAA6B,KACtC,MA2OF,CAAA;AAED,eAAe,iBAAiB,CAAA;AAIhC,OAAO,EACL,eAAe,EACf,kCAAkC,EAClC,eAAe,EACf,iBAAiB,EACjB,oBAAoB,EACpB,cAAc,EACd,SAAS,EACT,YAAY,EACZ,UAAU,EACV,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,0BAA0B,GAChC,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,sBAAsB,EACtB,+BAA+B,EAC/B,uBAAuB,EACvB,KAAK,gBAAgB,GACtB,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,4BAA4B,EAC5B,oBAAoB,EACpB,iBAAiB,EACjB,uBAAuB,EACvB,KAAK,mBAAmB,GACzB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACL,aAAa,EACb,eAAe,EACf,YAAY,EACZ,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,GACxB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
// @reactra/vite-plugin — Vite integration for the Reactra compiler.
|
|
2
|
+
//
|
|
3
|
+
// Owner: reactra-compiler-spec.md §7.1
|
|
4
|
+
//
|
|
5
|
+
// Phase 1 surface — what ships today:
|
|
6
|
+
// - enforce: "pre" — Reactra's transform runs before @vitejs/plugin-react.
|
|
7
|
+
// - transform(code, id): calls @reactra/babel-plugin's compile() on any
|
|
8
|
+
// .tsx / .ts / .jsx / .js file whose source contains a Reactra container
|
|
9
|
+
// keyword. compile() short-circuits cheaply on non-DSL files via the
|
|
10
|
+
// containsReactraDsl gate.
|
|
11
|
+
// - configResolved(config): captures the project root for the walker.
|
|
12
|
+
// - buildStart: scan src/pages/ and emit routeManifest.generated.ts.
|
|
13
|
+
// Phase 1 #5b — file-based route discovery (Router §5.1).
|
|
14
|
+
// - configureServer({ watcher }): re-emit on src/pages/ add/unlink/change.
|
|
15
|
+
// - Source maps return null (Vite falls back to a 1-to-1 line map).
|
|
16
|
+
//
|
|
17
|
+
// Deferred (still tracked in phase-1.md):
|
|
18
|
+
// - Typed RouteId / RouteParams / RouteQuery / TypedNavigate exports
|
|
19
|
+
// in the manifest (item #5c — needs compiler to surface query schemas)
|
|
20
|
+
// - HMR boundary injection via import.meta.hot.accept(...) (item #11)
|
|
21
|
+
// - Source maps (item #10)
|
|
22
|
+
//
|
|
23
|
+
// Day 14b (#7 writer): every successful transform also drops a
|
|
24
|
+
// `.reactra.json` sidecar under node_modules/.reactra/sidecars/ per
|
|
25
|
+
// Compiler §6. Cross-file `use storeX` resolution (the consumer side)
|
|
26
|
+
// is a follow-up — this commit only emits.
|
|
27
|
+
import { buildSidecar, compile, containsReactraDsl, } from "@reactra/babel-plugin";
|
|
28
|
+
import { createGraphCache } from "./graph-cache.js";
|
|
29
|
+
import { fingerprintOf, fingerprintsEqual, isPagesFile, } from "./fingerprint.js";
|
|
30
|
+
import { regenerateRouteManifest } from "./manifest.js";
|
|
31
|
+
import { regenerateResourceNames } from "./resource-names.js";
|
|
32
|
+
import { reactraEsbuildPlugin } from "./esbuild-prescan.js";
|
|
33
|
+
import { deleteSidecar, isEmptyForIndex, writeSidecar } from "./sidecar-writer.js";
|
|
34
|
+
/** File-level opt-out for the co-located-store HMR advisory (improvements #5). */
|
|
35
|
+
const COLOCATION_OPT_OUT = "// reactra-allow-colocated-route-store";
|
|
36
|
+
const STORE_KINDS = new Set([
|
|
37
|
+
"route-store",
|
|
38
|
+
"session-store",
|
|
39
|
+
"export-store",
|
|
40
|
+
]);
|
|
41
|
+
/**
|
|
42
|
+
* improvements #5 — advise when a store is co-located with a component in one
|
|
43
|
+
* file. The emitted store binding is a non-component export, which makes the
|
|
44
|
+
* whole module ineligible for React Fast Refresh, so HMR full-reloads. A
|
|
45
|
+
* co-located `route store` loses its per-route state on every edit (the
|
|
46
|
+
* painful case); `session`/`export` stores are registry-preserved, so only
|
|
47
|
+
* in-progress Fast Refresh is disrupted. Advisory only — never fails the
|
|
48
|
+
* build (same-file stores are legal; Store v4.2 §2.5). Opt out per file with
|
|
49
|
+
* the {@link COLOCATION_OPT_OUT} comment.
|
|
50
|
+
*/
|
|
51
|
+
const warnIfColocatedStore = (graph, source) => {
|
|
52
|
+
if (source.includes(COLOCATION_OPT_OUT))
|
|
53
|
+
return;
|
|
54
|
+
const stores = graph.containers.filter((c) => STORE_KINDS.has(c.kind));
|
|
55
|
+
if (stores.length === 0 || !graph.containers.some((c) => c.kind === "component"))
|
|
56
|
+
return;
|
|
57
|
+
const names = stores.map((c) => `\`${c.name}\``).join(", ");
|
|
58
|
+
const note = stores.some((c) => c.kind === "route-store")
|
|
59
|
+
? " — per-route store state is lost on every edit"
|
|
60
|
+
: " (store state is registry-preserved; only in-progress Fast Refresh is disrupted)";
|
|
61
|
+
console.warn(`[@reactra/vite-plugin] Store(s) ${names} co-located with a component — HMR will full-reload${note}. ` +
|
|
62
|
+
`Extract to src/stores/ for fast HMR, or add \`${COLOCATION_OPT_OUT}\` to this file to silence. (Store §2.5)`);
|
|
63
|
+
};
|
|
64
|
+
const SUPPORTED_EXT_RE = /\.(?:tsx|ts|jsx|js)(?:\?.*)?$/;
|
|
65
|
+
const stripQuery = (id) => {
|
|
66
|
+
const q = id.indexOf("?");
|
|
67
|
+
return q === -1 ? id : id.slice(0, q);
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Relabel a compiled module's source map so DevTools doesn't list the DSL
|
|
71
|
+
* original under the same name as the served compiled module (devtools-debugging
|
|
72
|
+
* backlog issue A). The compiled module is served at its real http URL; the map's
|
|
73
|
+
* `sources[0]` (the DSL leaf the user authored) is moved under a distinct
|
|
74
|
+
* `reactra://` virtual URL so the two appear as clearly different Sources entries.
|
|
75
|
+
* `sourcesContent` is untouched — devtools still shows the DSL you wrote — and
|
|
76
|
+
* `file` keeps the real path, since it names the generated output. Only the first
|
|
77
|
+
* source (Reactra always emits exactly one) is relabelled.
|
|
78
|
+
*/
|
|
79
|
+
const labelDslSource = (map, sourcePath) => {
|
|
80
|
+
if (map.sources.length === 0)
|
|
81
|
+
return map;
|
|
82
|
+
// Drive letter + backslashes → a clean POSIX-ish path under the virtual host.
|
|
83
|
+
const rel = sourcePath
|
|
84
|
+
.replace(/^[A-Za-z]:/, "")
|
|
85
|
+
.replace(/\\/g, "/")
|
|
86
|
+
.replace(/^\/+/, "");
|
|
87
|
+
return { ...map, sources: [`reactra:///${rel}`, ...map.sources.slice(1)] };
|
|
88
|
+
};
|
|
89
|
+
// True when `path` (absolute or project-relative) refers to a file under
|
|
90
|
+
// `<projectRoot>/src/`. Day 20 / `#5c` widened from `src/pages/` only —
|
|
91
|
+
// store-file changes anywhere under `src/` need to regen the manifest
|
|
92
|
+
// so `STORES` picks up adds / removes. Filter still excludes the generated
|
|
93
|
+
// manifest itself to avoid feedback loops (Vite watcher fires `change`
|
|
94
|
+
// on its own write).
|
|
95
|
+
const isInsideSrc = (projectRoot, eventPath) => {
|
|
96
|
+
const root = projectRoot.replace(/\\/g, "/");
|
|
97
|
+
const target = eventPath.replace(/\\/g, "/");
|
|
98
|
+
const prefix = root.endsWith("/") ? root + "src/" : root + "/src/";
|
|
99
|
+
if (!target.startsWith(prefix))
|
|
100
|
+
return false;
|
|
101
|
+
// Skip the generated manifest's own writes (Day-20 added the loop
|
|
102
|
+
// risk because store-file detection now walks src/, and the manifest
|
|
103
|
+
// lives under src/).
|
|
104
|
+
if (target.endsWith("/routeManifest.generated.ts"))
|
|
105
|
+
return false;
|
|
106
|
+
// Same skip for the Wave-3 / Stage-2 middleware companion. Without it,
|
|
107
|
+
// regenerateRouteManifest's own write-out would re-fire this watcher
|
|
108
|
+
// and loop indefinitely.
|
|
109
|
+
if (target.endsWith("/router-middleware.generated.ts"))
|
|
110
|
+
return false;
|
|
111
|
+
return true;
|
|
112
|
+
};
|
|
113
|
+
/**
|
|
114
|
+
* Vite plugin factory.
|
|
115
|
+
*
|
|
116
|
+
* ```ts
|
|
117
|
+
* // vite.config.ts
|
|
118
|
+
* import { defineConfig } from "vite"
|
|
119
|
+
* import reactra from "@reactra/vite-plugin"
|
|
120
|
+
* import react from "@vitejs/plugin-react"
|
|
121
|
+
*
|
|
122
|
+
* export default defineConfig({
|
|
123
|
+
* plugins: [reactra(), react()],
|
|
124
|
+
* })
|
|
125
|
+
* ```
|
|
126
|
+
*
|
|
127
|
+
* Reactra MUST run before @vitejs/plugin-react. The enforce: "pre" hint
|
|
128
|
+
* pins us to the head of the pipeline; downstream plugins see standard
|
|
129
|
+
* React 19 TSX, never the DSL.
|
|
130
|
+
*/
|
|
131
|
+
export const reactraVitePlugin = (_options = {}) => {
|
|
132
|
+
// Captured in configResolved; consumed by buildStart + configureServer.
|
|
133
|
+
// Starts empty so the type stays narrow; the plugin never reads it
|
|
134
|
+
// before configResolved fires (Vite guarantees the call order).
|
|
135
|
+
let projectRoot = "";
|
|
136
|
+
// A3 increment 2 — the per-file declaration fingerprint map. The ONLY mutable
|
|
137
|
+
// watcher state (C1 exempts it). Scoped to this plugin instance (not a
|
|
138
|
+
// module-level global) so two projects building in one process don't share
|
|
139
|
+
// it. A `change` whose recomputed fingerprint matches the stored one means
|
|
140
|
+
// no store/service/resource decl was added/renamed/removed → the src/-wide
|
|
141
|
+
// rescan can be skipped (a non-pages/ change can skip the regen entirely).
|
|
142
|
+
// Entries are added/refreshed on every full regen and removed on `unlink`.
|
|
143
|
+
const fingerprints = new Map();
|
|
144
|
+
/**
|
|
145
|
+
* Run BOTH regens (manifest + resource-names) over one shared per-event
|
|
146
|
+
* cache, then refresh the fingerprint for `eventPath` from that same cache
|
|
147
|
+
* (no extra compile). `eventPath` is absolute; pass `null` for build-time
|
|
148
|
+
* regens that don't carry a single triggering file.
|
|
149
|
+
*/
|
|
150
|
+
const regenAll = (eventPath) => {
|
|
151
|
+
const cache = createGraphCache();
|
|
152
|
+
try {
|
|
153
|
+
regenerateRouteManifest(projectRoot, cache);
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
console.error("[@reactra/vite-plugin] manifest regen failed:", err);
|
|
157
|
+
}
|
|
158
|
+
try {
|
|
159
|
+
regenerateResourceNames(projectRoot, cache);
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
console.error("[@reactra/vite-plugin] resource-names regen failed:", err);
|
|
163
|
+
}
|
|
164
|
+
if (eventPath) {
|
|
165
|
+
fingerprints.set(eventPath, fingerprintOf(cache.containersFor(eventPath)));
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
const plugin = {
|
|
169
|
+
name: "@reactra/vite-plugin",
|
|
170
|
+
enforce: "pre",
|
|
171
|
+
config() {
|
|
172
|
+
// Day 24 / `#15`: hand esbuild a Reactra-aware onLoad so the
|
|
173
|
+
// dep-scan phase can preprocess DSL files before its parser
|
|
174
|
+
// sees them. Without this, esbuild prints "Unexpected
|
|
175
|
+
// component" / "Expected ';' but found 'store'" + the
|
|
176
|
+
// umbrella "Failed to run dependency scan" warning at first
|
|
177
|
+
// dev-server boot. On-demand serving still works because the
|
|
178
|
+
// transform() hook below catches each per-request compile.
|
|
179
|
+
return {
|
|
180
|
+
optimizeDeps: {
|
|
181
|
+
esbuildOptions: {
|
|
182
|
+
plugins: [reactraEsbuildPlugin],
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
},
|
|
187
|
+
configResolved(config) {
|
|
188
|
+
projectRoot = config.root;
|
|
189
|
+
},
|
|
190
|
+
buildStart() {
|
|
191
|
+
// First emission of the manifest. Walker tolerates a missing
|
|
192
|
+
// src/pages/ directory (returns [] and we write an empty manifest)
|
|
193
|
+
// so this is safe even on a fresh-clone with no pages yet.
|
|
194
|
+
if (projectRoot) {
|
|
195
|
+
// A3: one shared cache across both build-time regens (regenAll), so a
|
|
196
|
+
// file read by both compiles once. QW-5: this also emits
|
|
197
|
+
// `.reactra/resource-names.d.ts` so `useMutation`'s `invalidate` is
|
|
198
|
+
// typed against the project's resource set (degrades to `string` when
|
|
199
|
+
// no resource is declared). regenAll swallows generator failures so a
|
|
200
|
+
// bad file never fails the build.
|
|
201
|
+
regenAll(null);
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
configureServer(server) {
|
|
205
|
+
// Day 20 / `#5c`: watch all of src/ (was src/pages/ only). Page
|
|
206
|
+
// adds/removes still regen ROUTES; store file adds/removes regen
|
|
207
|
+
// STORES. The generated manifest itself is filtered out by
|
|
208
|
+
// `isInsideSrc` to avoid feedback loops.
|
|
209
|
+
// `add` / `unlink` ALWAYS full-regen + refresh fingerprints — the file-
|
|
210
|
+
// set membership changed, so ROUTES/STORES/SERVICES/resources may all
|
|
211
|
+
// shift (regenAll shares one per-event cache between both generators).
|
|
212
|
+
const onAdd = (path) => {
|
|
213
|
+
if (!projectRoot || !isInsideSrc(projectRoot, path))
|
|
214
|
+
return;
|
|
215
|
+
regenAll(path);
|
|
216
|
+
};
|
|
217
|
+
// A3 increment 2 — `change` is the hot path (every keystroke-save). Compile
|
|
218
|
+
// the changed file ONCE, diff its declaration fingerprint against the
|
|
219
|
+
// stored one:
|
|
220
|
+
// - decl set DIFFERENT (store/service renamed, added, removed, or a
|
|
221
|
+
// service modifier flipped) → full regen + refresh fingerprint.
|
|
222
|
+
// - decl set UNCHANGED (body-only edit) → the src/-wide store/service/
|
|
223
|
+
// resource scan can't change the output, so SKIP it. A pages/ change
|
|
224
|
+
// still needs scanPages (routes/queries/prefetch can change), so we
|
|
225
|
+
// regen there; a non-pages/ body-only change skips the regen entirely.
|
|
226
|
+
const onChange = (path) => {
|
|
227
|
+
if (!projectRoot || !isInsideSrc(projectRoot, path))
|
|
228
|
+
return;
|
|
229
|
+
const cache = createGraphCache();
|
|
230
|
+
const next = fingerprintOf(cache.containersFor(path));
|
|
231
|
+
const prev = fingerprints.get(path);
|
|
232
|
+
const declUnchanged = prev !== undefined && fingerprintsEqual(prev, next);
|
|
233
|
+
fingerprints.set(path, next);
|
|
234
|
+
if (declUnchanged && !isPagesFile(projectRoot, path)) {
|
|
235
|
+
// Body-only edit to a non-pages/ file — nothing the manifest or
|
|
236
|
+
// resource-names depend on changed. Skip the whole regen.
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
if (declUnchanged) {
|
|
240
|
+
// Body-only edit to a pages/ file: routes/queries/prefetch could
|
|
241
|
+
// still change, so regen the manifest (reusing the cache that already
|
|
242
|
+
// compiled this file). The src/-wide store/service walk still runs
|
|
243
|
+
// inside regenerateRouteManifest but reads cached compiles — cheap.
|
|
244
|
+
// resource-names also reuses the cache.
|
|
245
|
+
try {
|
|
246
|
+
regenerateRouteManifest(projectRoot, cache);
|
|
247
|
+
}
|
|
248
|
+
catch (err) {
|
|
249
|
+
console.error("[@reactra/vite-plugin] manifest regen failed:", err);
|
|
250
|
+
}
|
|
251
|
+
try {
|
|
252
|
+
regenerateResourceNames(projectRoot, cache);
|
|
253
|
+
}
|
|
254
|
+
catch (err) {
|
|
255
|
+
console.error("[@reactra/vite-plugin] resource-names regen failed:", err);
|
|
256
|
+
}
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
// Decl set changed (or first-ever sighting of this file) → full regen.
|
|
260
|
+
// Reuse the cache that already compiled the changed file.
|
|
261
|
+
try {
|
|
262
|
+
regenerateRouteManifest(projectRoot, cache);
|
|
263
|
+
}
|
|
264
|
+
catch (err) {
|
|
265
|
+
console.error("[@reactra/vite-plugin] manifest regen failed:", err);
|
|
266
|
+
}
|
|
267
|
+
try {
|
|
268
|
+
regenerateResourceNames(projectRoot, cache);
|
|
269
|
+
}
|
|
270
|
+
catch (err) {
|
|
271
|
+
console.error("[@reactra/vite-plugin] resource-names regen failed:", err);
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
// Day 25 / sidecar-on-unlink: when a Reactra source file is
|
|
275
|
+
// DELETED (not just edited), Vite never re-fires `transform()`
|
|
276
|
+
// for it — the file is gone — so `#7c`'s sidecar GC path inside
|
|
277
|
+
// transform() doesn't get a chance to run. Result: the deleted
|
|
278
|
+
// file's stale sidecar lingers under
|
|
279
|
+
// `node_modules/.reactra/sidecars/` and the next
|
|
280
|
+
// `loadSidecarIndex` call still sees its `stores[]` entries,
|
|
281
|
+
// potentially triggering duplicate-store-across-files against a
|
|
282
|
+
// new home file the user moved the store to. Fix: hook the
|
|
283
|
+
// watcher's unlink event directly to delete the sidecar by path.
|
|
284
|
+
// ENOENT-as-no-op in `deleteSidecar` means we don't need to gate
|
|
285
|
+
// by file extension — the call is harmless on non-Reactra files
|
|
286
|
+
// that never had a sidecar to begin with.
|
|
287
|
+
const onUnlink = (path) => {
|
|
288
|
+
if (!projectRoot || !isInsideSrc(projectRoot, path))
|
|
289
|
+
return;
|
|
290
|
+
// File removed → drop its fingerprint so a later re-create is treated
|
|
291
|
+
// as a fresh sighting (full regen), and full-regen now that the
|
|
292
|
+
// file-set membership changed.
|
|
293
|
+
fingerprints.delete(path);
|
|
294
|
+
regenAll(null);
|
|
295
|
+
try {
|
|
296
|
+
deleteSidecar(projectRoot, path);
|
|
297
|
+
}
|
|
298
|
+
catch (err) {
|
|
299
|
+
console.error("[@reactra/vite-plugin] sidecar unlink failed:", err);
|
|
300
|
+
}
|
|
301
|
+
};
|
|
302
|
+
server.watcher.on("add", onAdd);
|
|
303
|
+
server.watcher.on("unlink", onUnlink);
|
|
304
|
+
// `change` is needed too — renaming a [param] segment from
|
|
305
|
+
// [id] → [customerId] surfaces as change(rename source) on some
|
|
306
|
+
// platforms rather than add+unlink (the fingerprint differ in onChange
|
|
307
|
+
// still forces a regen because the file's queries/route change).
|
|
308
|
+
server.watcher.on("change", onChange);
|
|
309
|
+
},
|
|
310
|
+
transform(code, id) {
|
|
311
|
+
// Skip files Reactra doesn't own (node_modules, virtual modules).
|
|
312
|
+
if (id.includes("/node_modules/") || id.includes("\\node_modules\\")) {
|
|
313
|
+
return null;
|
|
314
|
+
}
|
|
315
|
+
if (id.startsWith("\0") || id.startsWith("virtual:"))
|
|
316
|
+
return null;
|
|
317
|
+
if (!SUPPORTED_EXT_RE.test(stripQuery(id)))
|
|
318
|
+
return null;
|
|
319
|
+
if (!containsReactraDsl(code))
|
|
320
|
+
return null;
|
|
321
|
+
const sourcePath = stripQuery(id);
|
|
322
|
+
// Backlog 1a: `inject store X` binds via `import type` / same-file decl,
|
|
323
|
+
// so Pass 9 no longer needs `projectRoot` to resolve store names — the
|
|
324
|
+
// sidecar reader is gone. We still pass `sourceFile: id` (Day 22 / `#10`)
|
|
325
|
+
// so the returned source map's `sources[0]` + `file` carry the Vite
|
|
326
|
+
// module id; devtools shows the original DSL in the Sources panel.
|
|
327
|
+
const { code: compiled, graph, map } = compile(code, {
|
|
328
|
+
sourceFile: sourcePath,
|
|
329
|
+
});
|
|
330
|
+
warnIfColocatedStore(graph, code);
|
|
331
|
+
if (projectRoot) {
|
|
332
|
+
// Best-effort write — failures log but never break the transform.
|
|
333
|
+
// Day 18 / `#7c`: if the recompile produced a sidecar with no
|
|
334
|
+
// stores+services (e.g. a route store was moved out to its own
|
|
335
|
+
// file and what's left in this source is a pure-component page),
|
|
336
|
+
// DELETE the prior sidecar instead of overwriting it with an
|
|
337
|
+
// empty one. Leaving the stale sidecar around would let
|
|
338
|
+
// loadSidecarIndex keep seeing the moved-away store name and
|
|
339
|
+
// throw duplicate-store-across-files against the new home file.
|
|
340
|
+
try {
|
|
341
|
+
const sidecar = buildSidecar(graph, sourcePath);
|
|
342
|
+
if (isEmptyForIndex(sidecar)) {
|
|
343
|
+
deleteSidecar(projectRoot, sourcePath);
|
|
344
|
+
}
|
|
345
|
+
else {
|
|
346
|
+
writeSidecar(projectRoot, sourcePath, sidecar);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
catch (err) {
|
|
350
|
+
console.error("[@reactra/vite-plugin] sidecar write failed:", err);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
// `#10-followup` (Compiler §8): the returned map is now the full composed
|
|
354
|
+
// source→compiled map — both hops mapped, one segment per user-code slice
|
|
355
|
+
// (state/derived/action/resource/view) — so a breakpoint on a DSL line
|
|
356
|
+
// binds to the matching compiled line. `sourcesContent` carries the DSL.
|
|
357
|
+
//
|
|
358
|
+
// devtools-debugging backlog issue A: relabel the DSL leaf so DevTools
|
|
359
|
+
// doesn't list it under the same name as the served compiled module.
|
|
360
|
+
// Cast the readonly RawSourceMap to the mutable boundary type — same
|
|
361
|
+
// object, only the array element types differ in readonly-ness.
|
|
362
|
+
return { code: compiled, map: (map && labelDslSource(map, sourcePath)) };
|
|
363
|
+
},
|
|
364
|
+
};
|
|
365
|
+
// `ReactraVitePlugin` is a hand-rolled structural subset of Vite's `Plugin`
|
|
366
|
+
// (we don't import Vite at runtime). Vite's richer esbuild/source-map hook
|
|
367
|
+
// types don't bidirectionally match our minimal ones, so cast at the public
|
|
368
|
+
// boundary — the object is still type-checked against ReactraVitePlugin above.
|
|
369
|
+
return plugin;
|
|
370
|
+
};
|
|
371
|
+
export default reactraVitePlugin;
|
|
372
|
+
// Re-exports so consumers (tests, integrations) can reach the walker and
|
|
373
|
+
// the manifest helpers without a second package boundary.
|
|
374
|
+
export { chainsForRoutes, collectServiceInjectionDiagnostics, deriveRoutePath, emitRouteManifest, emitRouterMiddleware, scanMiddleware, scanPages, scanServices, scanStores, } from "./walker.js";
|
|
375
|
+
export { MANIFEST_RELATIVE_PATH, ROUTER_MIDDLEWARE_RELATIVE_PATH, regenerateRouteManifest, } from "./manifest.js";
|
|
376
|
+
export { RESOURCE_NAMES_RELATIVE_PATH, collectResourceNames, emitResourceNames, regenerateResourceNames, } from "./resource-names.js";
|
|
377
|
+
export { deleteSidecar, isEmptyForIndex, writeSidecar, } from "./sidecar-writer.js";
|
|
378
|
+
export { reactraEsbuildPlugin } from "./esbuild-prescan.js";
|
|
379
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { type DiscoveredMiddleware, type DiscoveredRoute, type DiscoveredService, type DiscoveredStore } from "./walker.ts";
|
|
2
|
+
/**
|
|
3
|
+
* The on-disk location of the generated manifest, relative to the project
|
|
4
|
+
* root. Exported for tests + so the vite plugin can `import` from a stable
|
|
5
|
+
* path in the demo / app config.
|
|
6
|
+
*/
|
|
7
|
+
export declare const MANIFEST_RELATIVE_PATH = "src/routeManifest.generated.ts";
|
|
8
|
+
/**
|
|
9
|
+
* The on-disk location of the generated middleware chains module (Wave 3,
|
|
10
|
+
* Stage 2). Sits next to the route manifest in `src/` so importers can
|
|
11
|
+
* pull `import { middlewareChains } from "./router-middleware.generated.ts"`
|
|
12
|
+
* with the same relative-path convention. Spec §6.4 names this file.
|
|
13
|
+
*/
|
|
14
|
+
export declare const ROUTER_MIDDLEWARE_RELATIVE_PATH = "src/router-middleware.generated.ts";
|
|
15
|
+
/**
|
|
16
|
+
* Result of a regeneration attempt. `wrote: true` means the file changed
|
|
17
|
+
* and we wrote new bytes; `wrote: false` means the content was already
|
|
18
|
+
* up-to-date and we left the file alone.
|
|
19
|
+
*/
|
|
20
|
+
export interface RegenerateResult {
|
|
21
|
+
readonly wrote: boolean;
|
|
22
|
+
readonly routes: readonly DiscoveredRoute[];
|
|
23
|
+
/**
|
|
24
|
+
* Stores discovered via the sidecar index — surfaced in the result for
|
|
25
|
+
* tests + diagnostics. Day 20 / `#5c`.
|
|
26
|
+
*/
|
|
27
|
+
readonly stores: readonly DiscoveredStore[];
|
|
28
|
+
/**
|
|
29
|
+
* Services discovered via the `preprocess()`-based scan of `src/` —
|
|
30
|
+
* surfaced in the result for tests + diagnostics. Phase 3.
|
|
31
|
+
*/
|
|
32
|
+
readonly services: readonly DiscoveredService[];
|
|
33
|
+
readonly content: string;
|
|
34
|
+
readonly path: string;
|
|
35
|
+
/**
|
|
36
|
+
* Wave 3 / Stage 2 — middleware files discovered + the per-route chains
|
|
37
|
+
* resolved against them. Surfaced for tests + so the vite plugin can
|
|
38
|
+
* detect "no middleware exists anywhere" and skip the second write.
|
|
39
|
+
*/
|
|
40
|
+
readonly middleware: readonly DiscoveredMiddleware[];
|
|
41
|
+
/**
|
|
42
|
+
* Whether the middleware companion file `<projectRoot>/src/
|
|
43
|
+
* router-middleware.generated.ts` was rewritten this call. Same
|
|
44
|
+
* change-check semantics as `wrote` — true only when bytes differ.
|
|
45
|
+
*/
|
|
46
|
+
readonly wroteMiddleware: boolean;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Scan + emit + write-if-changed. Idempotent — calling twice with no
|
|
50
|
+
* page-tree change is a no-op for the filesystem.
|
|
51
|
+
*
|
|
52
|
+
* The walker tolerates a missing `src/pages/` directory (returns []); we
|
|
53
|
+
* still write the empty manifest so importers don't ImportError before
|
|
54
|
+
* any pages exist. Mirrors the placeholder a fresh-clone commits.
|
|
55
|
+
*/
|
|
56
|
+
export declare const regenerateRouteManifest: (projectRoot: string, cache?: import("./graph-cache.ts").GraphCache) => RegenerateResult;
|
|
57
|
+
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAkBA,OAAO,EASL,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACrB,MAAM,aAAa,CAAA;AAEpB;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,mCAAmC,CAAA;AAEtE;;;;;GAKG;AACH,eAAO,MAAM,+BAA+B,uCACN,CAAA;AAEtC;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAA;IAC3C;;;OAGG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAA;IAC3C;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS,iBAAiB,EAAE,CAAA;IAC/C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,SAAS,oBAAoB,EAAE,CAAA;IACpD;;;;OAIG;IACH,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAA;CAClC;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,GAClC,aAAa,MAAM,EACnB,6CAA0B,KACzB,gBA4GF,CAAA"}
|