@memoized-dom/vite 0.0.6 → 0.0.7

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
@@ -1,43 +1,76 @@
1
- # @memoized-dom/vite
2
-
3
- Vite 8 adapter for compiler-linked memoized-dom applications.
4
-
5
- ```ts
6
- import { defineConfig } from 'vite';
7
- import memoizedDom from '@memoized-dom/vite';
8
-
9
- export default defineConfig({
10
- plugins: [
11
- memoizedDom({
12
- entries: 'src/entry.ts',
13
- }),
14
- ],
15
- });
16
- ```
17
-
18
- The entry is an ordinary TypeScript browser bootstrap containing one top-level
19
- `mount(target, Component)` call. The adapter resolves that imported component,
20
- derives its compiler entity identity, follows local static value imports with
21
- Vite's resolver, compiles the graph through `compileModulesDetailed()`, returns
22
- authored-module source maps from Vite transforms, and caches output per Vite
23
- environment.
24
-
25
- During an edit, the adapter recompiles before notifying the browser. Compiler
26
- failures therefore reach Vite's standard terminal and overlay feedback. It
27
- diffs the linked generated graph and invalidates only outputs that changed.
28
- Every generated module is a self-accepting HMR boundary. Ordinary live
29
- components are disposed and recreated at their existing DOM position while
30
- the browser document remains loaded. A root-component edit recreates that root
31
- and therefore resets its local closure state. Lightweight keyed-row factories
32
- currently remount their application root because retained rows do not own a
33
- schedulable entity boundary.
34
-
35
- Restart the Vite dev server after changing or rebuilding this server-side
36
- plugin. An active Vite process does not hot-replace plugin hooks.
37
-
38
- Run the package-owned integration tests and adapter benchmark with:
39
-
40
- ```bash
41
- bun run --cwd packages/vite test
42
- bun run --cwd packages/vite bench
43
- ```
1
+ # @memoized-dom/vite
2
+
3
+ Vite 8 adapter for compiler-linked memoized-dom applications.
4
+
5
+ ```ts
6
+ import { defineConfig } from 'vite';
7
+ import memoizedDom from '@memoized-dom/vite';
8
+
9
+ export default defineConfig({
10
+ plugins: [
11
+ memoizedDom({
12
+ entries: 'src/entry.ts',
13
+ }),
14
+ ],
15
+ });
16
+ ```
17
+
18
+ The entry is an ordinary TypeScript browser bootstrap containing one top-level
19
+ `mount(target, Component)` call. The adapter resolves that imported component,
20
+ derives its compiler entity identity, follows local static value imports with
21
+ Vite's resolver, compiles the graph through `compileModulesDetailed()`, returns
22
+ authored-module source maps from Vite transforms, and caches output per Vite
23
+ environment.
24
+
25
+ During an edit, the adapter recompiles before notifying the browser. Compiler
26
+ failures therefore reach Vite's standard terminal and overlay feedback. It
27
+ diffs the linked generated graph and invalidates only outputs that changed.
28
+ Every generated module is a self-accepting HMR boundary. Ordinary live
29
+ components are disposed and recreated at their existing DOM position while
30
+ the browser document remains loaded. A root-component edit recreates that root
31
+ and therefore resets its local closure state. Lightweight keyed-row factories
32
+ currently remount their application root because retained rows do not own a
33
+ schedulable entity boundary.
34
+
35
+ Restart the Vite dev server after changing or rebuilding this server-side
36
+ plugin. An active Vite process does not hot-replace plugin hooks.
37
+
38
+ ## Fullstack development
39
+
40
+ `memoizedDomFullstack()` installs a post-Vite server boundary. Vite continues
41
+ to own client modules, CSS, dependency optimization, and HMR. All remaining
42
+ requests are dispatched to a Web-standard server entry loaded through
43
+ `ssrLoadModule()`:
44
+
45
+ ```ts
46
+ import { defineConfig } from 'vite';
47
+ import memoizedDom, { memoizedDomFullstack } from '@memoized-dom/vite';
48
+
49
+ export default defineConfig({
50
+ appType: 'custom',
51
+ plugins: [
52
+ memoizedDom({ entries: 'src/entry.client.ts' }),
53
+ memoizedDomFullstack({ entry: 'src/entry.server.ts' }),
54
+ ],
55
+ });
56
+ ```
57
+
58
+ The server entry exports `fetch(request)` or a default Web handler:
59
+
60
+ ```ts
61
+ export function fetch(request: Request): Response {
62
+ return new Response(`Request URL: ${request.url}`);
63
+ }
64
+ ```
65
+
66
+ The dev adapter uses the published `@memoized-dom/adapters/node` bridge. It
67
+ does not emulate Node request/response objects or intercept Vite asset routes.
68
+ Production hosts can use the same Web handler directly on Bun/Workers, or the
69
+ Node adapter with an ordinary `node:http` server.
70
+
71
+ Run the package-owned integration tests and adapter benchmark with:
72
+
73
+ ```bash
74
+ bun run --cwd packages/vite test
75
+ bun run --cwd packages/vite bench
76
+ ```
@@ -0,0 +1,14 @@
1
+ import type { Plugin } from 'vite';
2
+ export interface MemoizedDomFullstackOptions {
3
+ /** Vite-root-relative server module exporting `fetch` or a default handler. */
4
+ readonly entry: string;
5
+ }
6
+ /**
7
+ * Install a post-Vite Web-handler boundary for fullstack development.
8
+ *
9
+ * Vite owns HMR and module/assets. Requests that remain are converted from
10
+ * Node HTTP to the Web Request/Response contract and dispatched through the
11
+ * application server entry loaded by `ssrLoadModule`.
12
+ */
13
+ export declare function memoizedDomFullstack(options: MemoizedDomFullstackOptions): Plugin;
14
+ //# sourceMappingURL=fullstack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fullstack.d.ts","sourceRoot":"","sources":["../src/fullstack.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAC;AAIlD,MAAM,WAAW,2BAA2B;IAC1C,+EAA+E;IAC/E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAuED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,2BAA2B,GACnC,MAAM,CAUR"}
@@ -1,14 +1,11 @@
1
1
  import { type CompilerSourceMap } from '@memoized-dom/compiler';
2
2
  import type { ResolvedAdapterOptions } from '../options';
3
- import { type ParsedProgram } from './imports';
3
+ import { type ServerFunctionBarrelEntry } from '../server-functions';
4
4
  export interface ResolvedImport {
5
5
  id: string;
6
6
  external?: boolean | 'absolute' | 'relative';
7
7
  }
8
8
  export interface GraphPluginContext {
9
- parse(source: string, options: {
10
- lang: 'js' | 'jsx' | 'ts' | 'tsx';
11
- }): ParsedProgram;
12
9
  resolve(specifier: string, importer: string, options: {
13
10
  skipSelf: true;
14
11
  }): Promise<ResolvedImport | null>;
@@ -26,6 +23,7 @@ export interface CompiledGraph {
26
23
  files: ReadonlySet<string>;
27
24
  output: ReadonlyMap<string, string>;
28
25
  maps: ReadonlyMap<string, CompilerSourceMap>;
26
+ css: ReadonlyMap<string, string>;
29
27
  }
30
- export declare function compileGraph(context: GraphPluginContext, root: string, entries: readonly string[], options: ResolvedAdapterOptions, overrides: ReadonlyMap<string, string>, hot: boolean): Promise<CompiledGraph>;
28
+ export declare function compileGraph(context: GraphPluginContext, root: string, entries: readonly string[], options: ResolvedAdapterOptions, overrides: ReadonlyMap<string, string>, hot: boolean, requireMount?: boolean, serverFunctionBarrelEntries?: readonly ServerFunctionBarrelEntry[]): Promise<CompiledGraph>;
31
29
  //# sourceMappingURL=collector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../../src/graph/collector.ts"],"names":[],"mappings":"AAIA,OAAO,EAKL,KAAK,iBAAiB,EACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAOzD,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,WAAW,CAAC;AAE7D,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,UAAU,CAAC;CAC9C;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,CACH,MAAM,EAAE,MAAM,EACd,OAAO,EAAE;QAAE,IAAI,EAAE,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,CAAA;KAAE,GAC7C,aAAa,CAAC;IACjB,OAAO,CACL,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE;QAAE,QAAQ,EAAE,IAAI,CAAA;KAAE,GAC1B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAClC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,KAAK,CAAC,KAAK,EAAE;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,GAAG,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;KACxC,GAAG,KAAK,CAAC;CACX;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3B,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CAC9C;AAMD,wBAAsB,YAAY,CAChC,OAAO,EAAE,kBAAkB,EAC3B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,OAAO,EAAE,sBAAsB,EAC/B,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EACtC,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,aAAa,CAAC,CAoGxB"}
1
+ {"version":3,"file":"collector.d.ts","sourceRoot":"","sources":["../../src/graph/collector.ts"],"names":[],"mappings":"AAMA,OAAO,EAOL,KAAK,iBAAiB,EACvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAOzD,OAAO,EAIL,KAAK,yBAAyB,EAC/B,MAAM,qBAAqB,CAAC;AAE7B,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,UAAU,CAAC;CAC9C;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,CACL,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE;QAAE,QAAQ,EAAE,IAAI,CAAA;KAAE,GAC1B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAClC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,KAAK,CAAC,KAAK,EAAE;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,GAAG,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;KACxC,GAAG,KAAK,CAAC;CACX;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3B,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC7C,GAAG,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAMD,wBAAsB,YAAY,CAChC,OAAO,EAAE,kBAAkB,EAC3B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,OAAO,EAAE,sBAAsB,EAC/B,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EACtC,GAAG,EAAE,OAAO,EACZ,YAAY,UAAO,EACnB,2BAA2B,GAAE,SAAS,yBAAyB,EAAO,GACrE,OAAO,CAAC,aAAa,CAAC,CA8KxB"}
@@ -1,7 +1,12 @@
1
1
  interface Program {
2
2
  body: readonly unknown[];
3
3
  }
4
- export declare function valueImports(program: Program): string[];
4
+ export interface ValueImport {
5
+ readonly specifier: string;
6
+ readonly line?: number;
7
+ readonly column?: number;
8
+ }
9
+ export declare function valueImports(program: Program): ValueImport[];
5
10
  export type ParsedProgram = Program;
6
11
  export {};
7
12
  //# sourceMappingURL=imports.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"imports.d.ts","sourceRoot":"","sources":["../../src/graph/imports.ts"],"names":[],"mappings":"AAcA,UAAU,OAAO;IACf,IAAI,EAAE,SAAS,OAAO,EAAE,CAAC;CAC1B;AAUD,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,EAAE,CAgBvD;AAED,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC"}
1
+ {"version":3,"file":"imports.d.ts","sourceRoot":"","sources":["../../src/graph/imports.ts"],"names":[],"mappings":"AAmBA,UAAU,OAAO;IACf,IAAI,EAAE,SAAS,OAAO,EAAE,CAAC;CAC1B;AAUD,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,WAAW,EAAE,CAsB5D;AAED,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC"}
package/dist/hmr.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"hmr.d.ts","sourceRoot":"","sources":["../src/hmr.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACtB,MAAM,MAAM,CAAC;AACd,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,cAAc,EAC3B,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,EAC1B,SAAS,EAAE,MAAM,GAChB,qBAAqB,EAAE,CAezB"}
1
+ {"version":3,"file":"hmr.d.ts","sourceRoot":"","sources":["../src/hmr.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACtB,MAAM,MAAM,CAAC;AACd,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,cAAc,EAC3B,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,EAC1B,SAAS,EAAE,MAAM,GAChB,qBAAqB,EAAE,CAiBzB"}
package/dist/index.d.ts CHANGED
@@ -3,5 +3,7 @@
3
3
  */
4
4
  export { memoizedDom } from './plugin';
5
5
  export { memoizedDom as default } from './plugin';
6
- export type { MemoizedDomViteOptions } from './options';
6
+ export type { MemoizedDomServerFunctionsOptions, MemoizedDomViteOptions, } from './options';
7
+ export { memoizedDomFullstack } from './fullstack';
8
+ export type { MemoizedDomFullstackOptions } from './fullstack';
7
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,WAAW,IAAI,OAAO,EAAE,MAAM,UAAU,CAAC;AAClD,YAAY,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,WAAW,IAAI,OAAO,EAAE,MAAM,UAAU,CAAC;AAClD,YAAY,EACV,iCAAiC,EACjC,sBAAsB,GACvB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,YAAY,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -1,8 +1,22 @@
1
- import{parseSync as Q}from"vite";import{readFile as L}from"node:fs/promises";import{compileModulesDetailed as q,toCompilerDiagnostic as B}from"@memoized-dom/compiler";import{extname as D,isAbsolute as P,relative as O,resolve as j,sep as G}from"node:path";var T=new Set([".ts",".tsx",".js",".jsx"]);function x(e){let t=e.search(/[?#]/);return y(t===-1?e:e.slice(0,t))}function y(e){return j(e).replaceAll("\\","/")}function b(e,t){return t.map(n=>{if(P(n))return y(n);let o=n.startsWith("/")?n.slice(1):n;return y(j(e,o))})}function R(e,t){let n=O(e,t).split(G).join("/");return n!==".."&&!n.startsWith("../")&&!P(n)?`./${n}`:y(t)}function z(e,t){return e===void 0?!1:(e instanceof RegExp?[e]:e).some(o=>(o.lastIndex=0,o.test(t)))}function E(e,t,n){let o=y(t);if(!T.has(D(o))||o.includes("/node_modules/")||z(n.exclude,o))return!1;if(z(n.include,o))return!0;let m=O(e,o);return m!==".."&&!m.startsWith(`..${G}`)&&!P(m)}function $(e){let t=D(e);return t===".tsx"?"tsx":t===".ts"?"ts":t===".jsx"?"jsx":"js"}function H(e){return typeof e=="object"&&e!==null&&e.type==="ImportDeclaration"}function A(e){let t=[];for(let n of e.body){if(!H(n)||n.importKind==="type")continue;let o=n.specifiers??[];o.length>0&&o.every(m=>m.importKind==="type")||typeof n.source.value=="string"&&t.push(n.source.value)}return t}function F(e,t){return`${e}\0${t}`}async function V(e,t,n,o,m,c){let f=new Map,u=new Map,h=new Map,M=new Set;async function i(l){let s=x(l);if(M.has(s))return;M.add(s),e.addWatchFile(s);let g=R(t,s),w=m.get(s)??await L(s,"utf8");f.set(g,w),u.set(s,g);let K=e.parse(w,{lang:$(s)});for(let I of A(K)){let S=await e.resolve(I,s,{skipSelf:!0});if(S===null||S.external)continue;let _=x(S.id);E(t,_,o)&&(h.set(F(g,I),R(t,_)),await i(_))}}for(let l of n){if(!E(t,l,o))throw new Error(`memoized-dom: Vite entry is not an accepted source file: ${l}`);await i(l)}let r={...o.runtimePath===void 0?{}:{runtimePath:o.runtimePath},...c?{hot:!0}:{},resolveImport(l,s){return h.get(F(s,l))}},a;try{a=q(Object.fromEntries(f),r)}catch(l){let s=B(l,[...f.keys()]),g=s.moduleId===void 0?void 0:[...u].find(([,w])=>w===s.moduleId)?.[0];e.error({message:s.message,...g===void 0?{}:{id:g},...s.line===void 0||s.column===void 0?{}:{loc:{line:s.line,column:s.column}}})}a.applicationRoot===void 0&&e.error({message:"memoized-dom: Vite entry graph must contain one top-level mount(target, Component) call"});let p=a.applicationRoot.rootId,d=new Map,v=new Map;for(let[l,s]of u){let g=a.output[s];d.set(l,c&&s!==a.applicationRoot.mountModuleId?U(g,a.metadata[s],s,o.runtimePath??"@memoized-dom/runtime",p):g),v.set(l,a.maps[s])}return{files:new Set(u.keys()),output:d,maps:v}}function U(e,t,n,o,m){let f=[...new Map(t.componentExports.map(u=>[u.local,u])).values()].map(u=>`[${u.local}, updatedModule[${JSON.stringify(u.exported)}], ${u.listLightweight}]`).join(", ");return`${e}
2
- import { applyHotUpdate as __memoized_dom_apply_hot_update__, disposeHotModule as __memoized_dom_dispose_hot_module__ } from ${JSON.stringify(o)};
3
- if (import.meta.hot) {
4
- import.meta.hot.dispose(() => __memoized_dom_dispose_hot_module__(${JSON.stringify(n)}, ${JSON.stringify(m)}));
5
- import.meta.hot.accept((updatedModule) => {
6
- if (updatedModule) __memoized_dom_apply_hot_update__([${f}], ${JSON.stringify(m)});
7
- });
8
- }`}function k(e,t,n){let o=new Set;for(let m of t){let c=e.moduleGraph.getModulesByFile(m);if(c!==void 0)for(let f of c)e.moduleGraph.invalidateModule(f,o,n,!0)}return[...o]}function W(e){let t=typeof e.entries=="string"?[e.entries]:e.entries;if(t.length===0)throw new Error("memoized-dom: Vite adapter requires at least one entry");return{...e,entries:[...t]}}var C=class{files=new Set;output=new Map;maps=new Map;compiling;replace(t){this.files.clear();for(let n of t.files)this.files.add(n);this.output.clear();for(let[n,o]of t.output)this.output.set(n,o);this.maps.clear();for(let[n,o]of t.maps)this.maps.set(n,o)}};var N=/\.[jt]sx?(?:$|[?#])/;function J(e){let t=W(e),n=new Map,o,m=[];function c(i){let r=n.get(i);return r===void 0&&(r=new C,n.set(i,r)),r}function f(i){return{parse:(r,a)=>i.parse(r,a),resolve:(r,a,p)=>i.resolve(r,a,p),addWatchFile:r=>i.addWatchFile(r),error:r=>i.error(r)}}function u(i,r){return{parse:(a,p)=>Q(`module.${p.lang}`,a,p).program,async resolve(a,p){let d=await i.pluginContainer.resolveId(a,p);return d===null?null:{id:d.id,external:d.external}},addWatchFile:a=>i.pluginContainer.watchFiles.add(a),error:a=>r.error(a)}}async function h(i,r,a=new Map){if(o===void 0)throw new Error("memoized-dom: Vite graph compilation started before config resolution");r.compiling===void 0&&(r.compiling=V(f(i),o.root,m,t,a,o.command==="serve"));let p=r.compiling;try{r.replace(await p)}finally{r.compiling===p&&(r.compiling=void 0)}}async function M(i,r,a){if(o===void 0||!N.test(a))return null;let p=x(a),d=c(i.environment);if(!(m.includes(p)||d.files.has(p))&&d.compiling===void 0)return null;let l=d.output.get(p);if(l!==void 0)return{code:l,map:d.maps.get(p)};d.compiling===void 0?await h(i,d,new Map([[p,r]])):await h(i,d);let s=d.output.get(p);if(s===void 0){if(!m.includes(p))return null;throw new Error(`memoized-dom: linked Vite graph omitted managed module ${p}`)}return{code:s,map:d.maps.get(p)}}return{name:"memoized-dom",enforce:"pre",perEnvironmentWatchChangeDuringDev:!0,perEnvironmentStartEndDuringDev:!0,applyToEnvironment(i){return i.name==="client"},configResolved(i){o=i,m=b(i.root,t.entries)},async buildStart(){await h(this,c(this.environment))},transform:{filter:{id:N},handler(i,r){return M(this,i,r)}},async hotUpdate(i){let r=n.get(this.environment),a=y(i.file);if(r===void 0||!r.files.has(a))return;let p=new Map(r.output),d=i.type==="delete"?new Map:new Map([[a,await i.read()]]);await h(u(this.environment,this),r,d);let v=new Set;for(let l of new Set([...p.keys(),...r.output.keys()]))p.get(l)!==r.output.get(l)&&v.add(l);return k(this.environment,v,i.timestamp)}}}export{J as default,J as memoizedDom};
1
+ import{basename as e,dirname as t,extname as n,isAbsolute as r,join as i,relative as a,resolve as o,sep as s}from"node:path";import{existsSync as c}from"node:fs";import{mkdir as l,readFile as u,readdir as d,writeFile as f}from"node:fs/promises";import{analyzeServerFunctionModule as p,compileModulesDetailed as m,generateServerFunctionClient as h,generateServerFunctionDeclarations as g,memoizedEstreeFrontend as _,parseWithEstreeFrontendOrThrow as v,toCompilerDiagnostic as y}from"@memoized-dom/compiler";import{sendNodeResponse as b,toWebRequest as x}from"@memoized-dom/adapters/node";const S=new Set([`.ts`,`.tsx`,`.tsrx`,`.js`,`.jsx`]);function C(e){let t=e.search(/[?#]/);return w(t===-1?e:e.slice(0,t))}function w(e){return o(e).replaceAll(`\\`,`/`)}function T(e,t){return t.map(t=>{if(r(t))return w(t);let n=t.startsWith(`/`)?t.slice(1):t;return w(o(e,n))})}function E(e,t){let n=a(e,t).split(s).join(`/`);return n!==`..`&&!n.startsWith(`../`)&&!r(n)?`./${n}`:w(t)}function D(e,t){return e!==void 0&&(e instanceof RegExp?[e]:e).some(e=>(e.lastIndex=0,e.test(t)))}function O(e,t,i){let o=w(t);if(!S.has(n(o))||o.includes(`/node_modules/`)||D(i.exclude,o))return!1;if(D(i.include,o))return!0;let c=a(e,o);return c!==`..`&&!c.startsWith(`..${s}`)&&!r(c)}function k(e){return typeof e==`object`&&!!e&&e.type===`ImportDeclaration`}function A(e){let t=[];for(let n of e.body){if(!k(n)||n.importKind===`type`)continue;let e=n.specifiers??[];if(!(e.length>0&&e.every(e=>e.importKind===`type`))&&typeof n.source.value==`string`){let e=n.source.loc?.start;t.push({specifier:n.source.value,...e===void 0?{}:{line:e.line,column:e.column}})}}return t}const j=`\0virtual:memoized-dom/server-functions`,M=`\0virtual:memoized-dom/server-functions-client`,N=new Set([`.ts`,`.tsx`,`.tsrx`,`.js`,`.jsx`]);function P(e,t){if(t.serverFunctions===!1)return null;let n=typeof t.serverFunctions==`string`?t.serverFunctions:t.serverFunctions?.directory??`server/functions`;return w(r(n)?n:o(e,n))}function F(e,t,i){let o=P(e,i);if(o===null)return!1;let s=w(t),c=a(o,s).replaceAll(`\\`,`/`);return N.has(n(s))&&!s.endsWith(`.d.ts`)&&c!==`..`&&!c.startsWith(`../`)&&!r(c)}function I(e){return e.includes(`?memo-server-function-implementation`)||e.includes(`&memo-server-function-implementation`)}async function L(e,t,n,r){let i=P(n,r);if(i===null)return e;let o=p(e,{moduleId:w(t),functionsRoot:a(n,i).replaceAll(`\\`,`/`),...r.frontend===void 0?{}:{frontend:r.frontend}});return h(o)}async function R(e){if(!c(e))return[];let t=[],r=async e=>{let i=await d(e,{withFileTypes:!0});for(let a of i){let i=o(e,a.name);a.isDirectory()?await r(i):a.isFile()&&N.has(n(a.name))&&!a.name.endsWith(`.d.ts`)&&t.push(w(i))}};return await r(e),t.sort()}function z(e,t){let n=a(e,t).replaceAll(`\\`,`/`),r=n.lastIndexOf(`/`);return r===-1?``:n.slice(0,r)}function B(e){if(e===``)return[``];let t=e.split(`/`);return[``,...t.map((e,n)=>t.slice(0,n+1).join(`/`))]}function V(e,t){return e.includes(`#server-functions`)?e.replace(/import\s*\{([^}]+)\}\s*from\s*(['"])#server-functions\2\s*;?/g,(e,n)=>{let r=new Map;for(let i of n.split(`,`)){let n=i.trim();if(n===``)continue;let a=n.split(/\s+as\s+/)[0].trim(),o=t.find(e=>e.exported===a);if(o===void 0)return e;let s=r.get(o.specifier)??[];s.push(n),r.set(o.specifier,s)}return r.size===0?e:[...r].map(([e,t])=>`import { ${t.join(`, `)} } from ${JSON.stringify(e)};`).join(`
2
+ `)}):e}async function H(e,t){let n=P(e,t);if(n===null)return{source:`export const serverFunctionManifest = [];
3
+ export const serverFunctionRoutes = [];
4
+ `,files:[],modules:[],clientBarrelSource:``,clientBarrelEntries:[]};let r=[];for(let i of await R(n)){let o=await u(i,`utf8`),s=p(o,{moduleId:i,functionsRoot:a(e,n).replaceAll(`\\`,`/`),...t.frontend===void 0?{}:{frontend:t.frontend}}),c=/(?:^|\/)\_middleware\.[^.]+$/.test(i);if(c&&!s.middlewareExport)throw Error(`memo-dom: server function middleware '${i}' must export a named 'middleware' array`);r.push({file:i,metadata:s,middlewareFile:c})}let i=[`import { createServerFunctionRoutes as __mmd_create_routes } from ${JSON.stringify(`@memoized-dom/server/router`)};`],o=new Map;r.forEach((e,t)=>{let n=`__mmd_server_${t}`;o.set(e.file,n),i.push(`import * as ${n} from ${JSON.stringify(`${e.file}?memo-server-function-implementation`)};`)});let s=new Map;for(let e of r)e.middlewareFile&&s.set(z(n,e.file),`${o.get(e.file)}.middleware`);let c=[],l=[];for(let e of r){if(e.middlewareFile)continue;let t=o.get(e.file),r=B(z(n,e.file)).map(e=>s.get(e)).filter(e=>e!==void 0);e.metadata.middlewareExport&&r.push(`${t}.middleware`);for(let n of e.metadata.functions){let i=`${e.metadata.moduleName}/${n.exported}`;c.push({id:i,method:n.method,path:n.path,parameters:n.parameters}),l.push(`{
5
+ id: ${JSON.stringify(i)},
6
+ method: ${JSON.stringify(n.method)},
7
+ path: ${JSON.stringify(n.path)},
8
+ parameters: ${JSON.stringify(n.parameters)},
9
+ middleware: [${r.map(e=>`...${e}`).join(`, `)}],
10
+ handler: ${t}[${JSON.stringify(n.exported)}]
11
+ }`)}}let d=[],f=[];for(let t of r){if(t.middlewareFile||t.metadata.functions.length===0)continue;let n=`/${a(e,t.file).replaceAll(`\\`,`/`)}`;for(let e of t.metadata.functions)f.push({exported:e.exported,specifier:n});d.push(`export { ${t.metadata.functions.map(e=>e.exported).join(`, `)} } from ${JSON.stringify(n)};`)}return{source:`${i.join(`
12
+ `)}
13
+ export const serverFunctionManifest = ${JSON.stringify(c)};
14
+ export const serverFunctionRoutes = __mmd_create_routes([
15
+ ${l.join(`,
16
+ `)}
17
+ ]);
18
+ `,files:r.map(e=>e.file),modules:r.map(e=>e.metadata),clientBarrelSource:`${d.join(`
19
+ `)}${d.length===0?``:`
20
+ `}`,clientBarrelEntries:f}}function U(e){return o(e,`.memoized`,`server-functions.d.ts`)}function W(e,n){let r=t(U(e)),i=w(n).replace(/(?:\.[cm]?[jt]sx?|\.tsrx)$/i,``),o=a(r,`${i}.js`).replaceAll(`\\`,`/`);return o.startsWith(`.`)?o:`./${o}`}async function G(e,n,r){if(P(e,r)===null)return;let i=U(e),a=g(n.map(e=>({...e,moduleId:w(e.moduleId)})),{resolveImplementation:t=>W(e,t)});await u(i,`utf8`).catch(()=>void 0)!==a&&(await l(t(i),{recursive:!0}),await f(i,a))}function K(e,t){return`${e}\0${t}`}async function q(t,n,r,i,a,o,s=!0,l=[]){let d=new Map,f=new Map,p=new Map,h=new Set;async function g(e){let r=C(e);if(h.has(r))return;h.add(r),t.addWatchFile(r);let o=E(n,r),s=a.get(r)??await u(r,`utf8`),c=v(i.frontend??_,s,{filename:o,sourceType:`module`}).program,m=new Map(A(c).map(e=>[e.specifier,e])),y=V(F(n,r,i)?await L(s,r,n,i):s,l);d.set(o,y),f.set(r,o);let b=v(i.frontend??_,y,{filename:o,sourceType:`module`}).program;for(let e of A(b)){let{specifier:a}=e,s=await t.resolve(a,r,{skipSelf:!0});if(s===null||s.external)continue;let c=C(s.id),l=m.get(a);l!==void 0&&!F(n,r,i)&&F(n,c,i)&&t.error({message:`memo-dom: [MMD-S003] UI modules cannot import '${a}' directly; import named server functions from '#server-functions' so server-only code cannot enter the client graph`,id:r,...l.line===void 0||l.column===void 0?{}:{loc:{line:l.line,column:l.column}}}),O(n,c,i)&&(p.set(K(o,a),E(n,c)),await g(c))}}let b=[];for(let e of r){if(!O(n,e,i))throw Error(`memoized-dom: Vite entry is not an accepted source file: ${e}`);c(e)&&b.push(e)}if(b.length===0)return{files:new Set,output:new Map,maps:new Map,css:new Map};for(let e of b)await g(e);let x={...i.frontend===void 0?{}:{frontend:i.frontend},...i.runtimePath===void 0?{}:{runtimePath:i.runtimePath},...o?{hot:!0}:{},...i.moduleStateCells===void 0?{}:{moduleStateCells:i.moduleStateCells},resolveImport(e,t){return p.get(K(t,e))}},S;try{S=m(Object.fromEntries(d),x)}catch(e){let n=y(e,[...d.keys()]),r=n.moduleId===void 0?void 0:[...f].find(([,e])=>e===n.moduleId)?.[0];t.error({message:n.message,...r===void 0?{}:{id:r},...n.line===void 0||n.column===void 0?{}:{loc:{line:n.line,column:n.column}}})}s&&S.applicationRoot===void 0&&t.error({message:`memoized-dom: Vite entry graph must contain one top-level mount(target, Component) call`});let w=S.applicationRoot?.rootId??`App`,T=S.applicationRoot?.mountModuleId,D=new Map,k=new Map,j=new Map;for(let[t,n]of f){let r=S.output[n];S.css?.[n]&&(j.set(t,S.css[n]),r=`import ${JSON.stringify(`./${e(t)}?memo-style.css`)};\n${r}`),D.set(t,o&&T!==void 0&&n!==T?J(r,S.metadata[n],n,i.hotRuntimePath??`${i.runtimePath??`@memoized-dom/runtime`}/hot`,w):r),k.set(t,S.maps[n])}return{files:new Set(f.keys()),output:D,maps:k,css:j}}function J(e,t,n,r,i){let a=[...new Map(t.componentExports.map(e=>[e.local,e])).values()].map(e=>`[${e.local}, updatedModule[${JSON.stringify(e.exported)}], ${e.listLightweight}]`).join(`, `);return`${e}\nimport { applyHotUpdate as __memoized_dom_apply_hot_update__, disposeHotModule as __memoized_dom_dispose_hot_module__ } from ${JSON.stringify(r)};\nif (import.meta.hot) {\n import.meta.hot.dispose(() => __memoized_dom_dispose_hot_module__(${JSON.stringify(n)}, ${JSON.stringify(i)}));\n import.meta.hot.accept((updatedModule) => {\n if (updatedModule) __memoized_dom_apply_hot_update__([${a}], ${JSON.stringify(i)});\n });\n}`}function Y(e,t,n){let r=new Set,i=new Set;for(let a of t){let t=e.moduleGraph.getModulesByFile(a);if(t!==void 0)for(let a of t)r.add(a),e.moduleGraph.invalidateModule(a,i,n,!0)}return[...r]}function X(e){let t=typeof e.entries==`string`?[e.entries]:e.entries;if(t.length===0)throw Error(`memoized-dom: Vite adapter requires at least one entry`);return{...e,entries:[...t]}}var Z=class{files=new Set;output=new Map;maps=new Map;css=new Map;entry;compiling;hotUpdateFailed=!1;replace(e){this.files.clear();for(let t of e.files)this.files.add(t);this.output.clear();for(let[t,n]of e.output)this.output.set(t,n);this.maps.clear();for(let[t,n]of e.maps)this.maps.set(t,n);this.css.clear();for(let[t,n]of e.css)this.css.set(t,n)}};const Q=/(?:\.[jt]sx?|\.tsrx)(?:$|[?#])/;function $(e){let n=X(e),r=new Map,a=new Map,o,s=[],c=`export const serverFunctionManifest = [];
21
+ export const serverFunctionRoutes = [];
22
+ `,l=``,u=[];async function d(){if(o===void 0)return[];let e=await H(o.root,n);return c=e.source,l=e.clientBarrelSource,u=e.clientBarrelEntries,await G(o.root,e.modules,n),e.files}function f(e){let t=r.get(e);return t===void 0&&(t=new Z,r.set(e,t)),t}function p(e){return{resolve:(t,n,r)=>e.resolve(t,n,r),addWatchFile:t=>e.addWatchFile(t),error:t=>e.error(t)}}function m(e,t){return{async resolve(t,n){let r=await e.pluginContainer.resolveId(t,n);return r===null?null:{id:r.id,external:r.external}},addWatchFile:t=>e.pluginContainer.watchFiles.add(t),error:e=>t.error(e)}}async function h(e,t,r=new Map){if(o===void 0)throw Error(`memoized-dom: Vite graph compilation started before config resolution`);t.compiling===void 0&&(t.compiling=q(p(e),o.root,s,n,r,o.command===`serve`,!0,u));let i=t.compiling;try{t.replace(await i)}finally{t.compiling===i&&(t.compiling=void 0)}}async function g(e,t,r,i=new Map){if(o===void 0)throw Error(`memoized-dom: Vite graph compilation started before config resolution`);let a=t.entry??r;t.compiling===void 0&&(t.compiling=q(p(e),o.root,[a],n,i,o.command===`serve`,!1,u));let s=t.compiling;try{t.replace(await s)}finally{t.compiling===s&&(t.compiling=void 0)}}function _(e,t){let n=a.get(e);if(n===void 0)return;let r=n.get(t);if(r!==void 0&&(r.files.has(t)||r.css.has(t)))return r;for(let e of n.values())if(e.files.has(t)||e.css.has(t))return e}function v(e,t){let n=r.get(e);return n!==void 0&&(n.files.has(t)||n.css.has(t))?n:_(e,t)}async function y(e){let t=e.compiling;if(t!==void 0)try{await t}catch{}finally{e.compiling===t&&(e.compiling=void 0)}}function b(e){let t=a.get(e);return t===void 0&&(t=new Map,a.set(e,t)),t}async function x(e,t,r){if(o===void 0||!Q.test(r)||r.includes(`?memo-style.css`)||I(r))return null;let i=C(r),a=f(e.environment),c=s.includes(i)||a.files.has(i),l=c?a.output.get(i):void 0;if(l!==void 0)return{code:l,map:a.maps.get(i)};if(c){a.compiling===void 0?await h(e,a,new Map([[i,t]])):await h(e,a);let n=a.output.get(i);if(n===void 0){if(!s.includes(i))return null;throw Error(`memoized-dom: linked Vite graph omitted managed module ${i}`)}return{code:n,map:a.maps.get(i)}}if(!O(o.root,i,n))return null;let d=b(e.environment),m=_(e.environment,i);m===void 0&&(m=new Z,m.entry=i,d.set(i,m));let g=m.output.get(i);if(g!==void 0)return{code:g,map:m.maps.get(i)};m.compiling===void 0&&(m.compiling=q(p(e),o.root,[i],n,new Map([[i,t]]),o.command===`serve`,!1,u));let v=m.compiling;try{m.replace(await v)}finally{m.compiling===v&&(m.compiling=void 0)}let y=m.output.get(i);return y===void 0?null:{code:y,map:m.maps.get(i)}}return{name:`memoized-dom`,enforce:`pre`,perEnvironmentWatchChangeDuringDev:!0,perEnvironmentStartEndDuringDev:!0,applyToEnvironment(e){return e.name===`client`||e.name===`ssr`},configResolved(e){o=e,s=T(e.root,n.entries)},async buildStart(){for(let e of await d())this.addWatchFile(e);await h(this,f(this.environment))},resolveId(e,n){if(e===`virtual:memoized-dom/server-functions`)return j;if(e===`#server-functions`)return M;if(I(e))return e;if(e.includes(`?memo-style.css`)){if(n){let r=e.indexOf(`?`),a=e.slice(0,r),o=e.slice(r),s=C(n),c=t(s);return`${w(i(c,a))}${o}`}let r=e.indexOf(`?`),a=r===-1?``:e.slice(r);return`${w(C(e))}${a}`}return null},load(e){if(e===`\0virtual:memoized-dom/server-functions`)return this.environment.name===`client`&&this.error(`memoized-dom: virtual:memoized-dom/server-functions is server-only and cannot be imported by the client graph`),{code:c,map:{mappings:``}};if(e===`\0virtual:memoized-dom/server-functions-client`)return{code:l,map:{mappings:``}};if(e.includes(`?memo-style.css`)){let t=w(C(e)),n=v(this.environment,t)?.css.get(t);if(n!==void 0)return{code:n,map:{mappings:``}}}return null},transform:{filter:{id:Q},handler(e,t){return x(this,e,t)}},async hotUpdate(e){let t=w(e.file),i=o!==void 0&&F(o.root,t,n),a=i?this.environment.moduleGraph.getModuleById(j):void 0,s=i?this.environment.moduleGraph.getModuleById(M):void 0;if(i){await d();for(let t of[a,s])t!==void 0&&this.environment.moduleGraph.invalidateModule(t,new Set,e.timestamp,!0)}let c=r.get(this.environment)?.files.has(t)===!0,l=v(this.environment,t);if(l===void 0)return a===void 0?void 0:[a];let u=new Map(l.output),f=new Map(l.css),p=e.type===`delete`?new Map:new Map([[t,await e.read()]]),_=m(this.environment,this);await y(l);try{c?await h(_,l,p):await g(_,l,t,p)}catch(e){throw l.hotUpdateFailed=!0,e}let b=new Set;for(let e of new Set([...u.keys(),...l.output.keys()]))u.get(e)!==l.output.get(e)&&b.add(e);for(let e of new Set([...f.keys(),...l.css.keys()]))f.get(e)!==l.css.get(e)&&b.add(e);l.hotUpdateFailed&&=(b.add(t),!1);let x=Y(this.environment,b,e.timestamp);return a!==void 0&&!x.includes(a)&&x.push(a),x}}}function ee(e,t){let n=e.fetch??e.default;if(typeof n!=`function`)throw TypeError(`memoized-dom: fullstack entry '${t}' must export a Web handler as 'fetch' or default`);return n}function te(e){return e.startsWith(`/`)?e:`/${e}`}async function ne(e,t,n,r){let i=ee(await e.ssrLoadModule(te(t)),t);if(i.installServerFunctions!==void 0){let t=await e.ssrLoadModule(`virtual:memoized-dom/server-functions`);if(!Array.isArray(t.serverFunctionRoutes))throw TypeError(`memoized-dom: generated server-function manifest did not export a route array`);i.installServerFunctions(t.serverFunctionRoutes)}await b(await i(x(n)),r)}function re(e,t){return async function(n,r,i){try{await ne(e,t,n,r)}catch(t){t instanceof Error&&e.ssrFixStacktrace(t),i(t)}}}function ie(e){return{name:`memoized-dom-fullstack`,apply:`serve`,configureServer(t){return()=>{t.middlewares.use(re(t,e.entry))}}}}export{$ as default,$ as memoizedDom,ie as memoizedDomFullstack};
package/dist/options.d.ts CHANGED
@@ -2,6 +2,10 @@
2
2
  * Public configuration for the Vite connected-graph adapter.
3
3
  */
4
4
  import type { CompileModulesOptions } from '@memoized-dom/compiler';
5
+ export interface MemoizedDomServerFunctionsOptions {
6
+ /** Vite-root-relative directory containing named HTTP functions. */
7
+ readonly directory?: string;
8
+ }
5
9
  export interface MemoizedDomViteOptions extends Omit<CompileModulesOptions, 'aliases' | 'resolveImport' | 'hot'> {
6
10
  /**
7
11
  * Ordinary TypeScript browser entries, relative to Vite's project root.
@@ -17,6 +21,11 @@ export interface MemoizedDomViteOptions extends Omit<CompileModulesOptions, 'ali
17
21
  * Source paths excluded from connected-graph compilation.
18
22
  */
19
23
  exclude?: RegExp | readonly RegExp[];
24
+ /**
25
+ * Named HTTP function discovery. Enabled at server/functions by default;
26
+ * use false to disable it or provide a different directory.
27
+ */
28
+ serverFunctions?: false | string | MemoizedDomServerFunctionsOptions;
20
29
  }
21
30
  export interface ResolvedAdapterOptions extends Omit<MemoizedDomViteOptions, 'entries'> {
22
31
  entries: readonly string[];
@@ -1 +1 @@
1
- {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAEpE,MAAM,WAAW,sBACf,SAAQ,IAAI,CAAC,qBAAqB,EAAE,SAAS,GAAG,eAAe,GAAG,KAAK,CAAC;IACxE;;;;OAIG;IACH,OAAO,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IACpC;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IACrC;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;CACtC;AAED,MAAM,WAAW,sBACf,SAAQ,IAAI,CAAC,sBAAsB,EAAE,SAAS,CAAC;IAC/C,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,sBAAsB,GAC9B,sBAAsB,CAOxB"}
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAEpE,MAAM,WAAW,iCAAiC;IAChD,oEAAoE;IACpE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,sBACf,SAAQ,IAAI,CAAC,qBAAqB,EAAE,SAAS,GAAG,eAAe,GAAG,KAAK,CAAC;IACxE;;;;OAIG;IACH,OAAO,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IACpC;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IACrC;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAAC;IACrC;;;OAGG;IACH,eAAe,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,iCAAiC,CAAC;CACtE;AAED,MAAM,WAAW,sBACf,SAAQ,IAAI,CAAC,sBAAsB,EAAE,SAAS,CAAC;IAC/C,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,sBAAsB,GAC9B,sBAAsB,CAOxB"}
package/dist/paths.d.ts CHANGED
@@ -4,5 +4,4 @@ export declare function normalizeFile(file: string): string;
4
4
  export declare function entryFiles(root: string, entries: readonly string[]): readonly string[];
5
5
  export declare function moduleId(root: string, file: string): string;
6
6
  export declare function acceptsSource(root: string, file: string, options: ResolvedAdapterOptions): boolean;
7
- export declare function parserLanguage(file: string): 'js' | 'jsx' | 'ts' | 'tsx';
8
7
  //# sourceMappingURL=paths.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAIxD,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAG9C;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,SAAS,MAAM,EAAE,GACzB,SAAS,MAAM,EAAE,CAMnB;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAU3D;AAWD,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAaT;AAED,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,GACX,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,CAM7B"}
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAIxD,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAG9C;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,SAAS,MAAM,EAAE,GACzB,SAAS,MAAM,EAAE,CAMnB;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAU3D;AAWD,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAaT"}
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAGV,MAAM,EAEP,MAAM,MAAM,CAAC;AAKd,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,WAAW,CAAC;AAUnB,wBAAgB,WAAW,CACzB,KAAK,EAAE,sBAAsB,GAC5B,MAAM,CAwKR"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAGV,MAAM,EAEP,MAAM,MAAM,CAAC;AAId,OAAO,EAEL,KAAK,sBAAsB,EAC5B,MAAM,WAAW,CAAC;AA0BnB,wBAAgB,WAAW,CACzB,KAAK,EAAE,sBAAsB,GAC5B,MAAM,CA0ZR"}
@@ -0,0 +1,39 @@
1
+ import { type ServerFunctionModule } from '@memoized-dom/compiler';
2
+ import type { ResolvedAdapterOptions } from './options';
3
+ export declare const serverFunctionsVirtualId = "virtual:memoized-dom/server-functions";
4
+ export declare const resolvedServerFunctionsVirtualId = "\0virtual:memoized-dom/server-functions";
5
+ export declare const serverFunctionsClientVirtualId = "#server-functions";
6
+ export declare const resolvedServerFunctionsClientVirtualId = "\0virtual:memoized-dom/server-functions-client";
7
+ export declare const serverFunctionImplementationQuery = "memo-server-function-implementation";
8
+ export declare function serverFunctionsRoot(root: string, options: ResolvedAdapterOptions): string | null;
9
+ export declare function isServerFunctionFile(root: string, file: string, options: ResolvedAdapterOptions): boolean;
10
+ export declare function isServerFunctionImplementation(id: string): boolean;
11
+ export declare function clientServerFunctionSource(source: string, file: string, root: string, options: ResolvedAdapterOptions): Promise<string>;
12
+ export interface GeneratedServerFunctionModules {
13
+ readonly source: string;
14
+ readonly files: readonly string[];
15
+ readonly modules: readonly ServerFunctionModule[];
16
+ /** Client `#server-functions` re-export barrel over facade modules. */
17
+ readonly clientBarrelSource: string;
18
+ /** Flat exported-name ownership used to rewrite barrel imports per module. */
19
+ readonly clientBarrelEntries: readonly ServerFunctionBarrelEntry[];
20
+ }
21
+ export interface ServerFunctionBarrelEntry {
22
+ readonly exported: string;
23
+ readonly specifier: string;
24
+ }
25
+ /**
26
+ * Rewrite `import { x } from '#server-functions'` into per-module facade
27
+ * imports so the compiler links colorless sources directly instead of through
28
+ * an opaque barrel. Unknown names keep the original clause; the runtime
29
+ * barrel virtual module still serves them.
30
+ */
31
+ export declare function rewriteServerFunctionBarrelImports(source: string, barrelEntries: readonly ServerFunctionBarrelEntry[]): string;
32
+ export declare function generateServerFunctionRoutesModule(root: string, options: ResolvedAdapterOptions): Promise<GeneratedServerFunctionModules>;
33
+ /** Generated declaration barrel location: `<root>/.memoized/server-functions.d.ts`. */
34
+ export declare function serverFunctionsDeclarationFile(root: string): string;
35
+ /** Type-only specifier from the generated declaration file to a real module. */
36
+ export declare function implementationSpecifier(root: string, moduleId: string): string;
37
+ /** Write the `.memoized/server-functions.d.ts` barrel; no-op when unchanged. */
38
+ export declare function writeServerFunctionDeclarations(root: string, modules: readonly ServerFunctionModule[], options: ResolvedAdapterOptions): Promise<void>;
39
+ //# sourceMappingURL=server-functions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-functions.d.ts","sourceRoot":"","sources":["../src/server-functions.ts"],"names":[],"mappings":"AAIA,OAAO,EAIL,KAAK,oBAAoB,EAC1B,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAGxD,eAAO,MAAM,wBAAwB,0CAA0C,CAAC;AAChF,eAAO,MAAM,gCAAgC,4CACF,CAAC;AAC5C,eAAO,MAAM,8BAA8B,sBAAsB,CAAC;AAClE,eAAO,MAAM,sCAAsC,mDACD,CAAC;AACnD,eAAO,MAAM,iCAAiC,wCACP,CAAC;AAIxC,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,sBAAsB,GAC9B,MAAM,GAAG,IAAI,CAQf;AAED,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAUT;AAED,wBAAgB,8BAA8B,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAGlE;AAED,wBAAsB,0BAA0B,CAC9C,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,MAAM,CAAC,CASjB;AA0CD,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,SAAS,oBAAoB,EAAE,CAAC;IAClD,uEAAuE;IACvE,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,8EAA8E;IAC9E,QAAQ,CAAC,mBAAmB,EAAE,SAAS,yBAAyB,EAAE,CAAC;CACpE;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAgB,kCAAkC,CAChD,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,SAAS,yBAAyB,EAAE,GAClD,MAAM,CAuBR;AAED,wBAAsB,kCAAkC,CACtD,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,8BAA8B,CAAC,CAwGzC;AAED,uFAAuF;AACvF,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED,gFAAgF;AAChF,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GACf,MAAM,CAOR;AAED,gFAAgF;AAChF,wBAAsB,+BAA+B,CACnD,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,SAAS,oBAAoB,EAAE,EACxC,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAcf"}
package/dist/state.d.ts CHANGED
@@ -7,7 +7,10 @@ export declare class AdapterState {
7
7
  readonly files: Set<string>;
8
8
  readonly output: Map<string, string>;
9
9
  readonly maps: Map<string, CompilerSourceMap>;
10
+ readonly css: Map<string, string>;
11
+ entry?: string;
10
12
  compiling: Promise<CompiledGraph> | undefined;
13
+ hotUpdateFailed: boolean;
11
14
  replace(graph: CompiledGraph): void;
12
15
  }
13
16
  //# sourceMappingURL=state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,qBAAa,YAAY;IACvB,QAAQ,CAAC,KAAK,cAAqB;IACnC,QAAQ,CAAC,MAAM,sBAA6B;IAC5C,QAAQ,CAAC,IAAI,iCAAwC;IACrD,SAAS,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,SAAS,CAAC;IAE9C,OAAO,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;CAQpC"}
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,qBAAa,YAAY;IACvB,QAAQ,CAAC,KAAK,cAAqB;IACnC,QAAQ,CAAC,MAAM,sBAA6B;IAC5C,QAAQ,CAAC,IAAI,iCAAwC;IACrD,QAAQ,CAAC,GAAG,sBAA6B;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,SAAS,CAAC;IAC9C,eAAe,UAAS;IACxB,OAAO,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CASlC;CACF"}
package/package.json CHANGED
@@ -1,35 +1,36 @@
1
- {
2
- "name": "@memoized-dom/vite",
3
- "version": "0.0.6",
4
- "description": "Vite 8 adapter for connected memoized-dom module graphs",
5
- "type": "module",
6
- "engines": {
7
- "node": ">=24.11.0"
8
- },
9
- "sideEffects": false,
10
- "files": [
11
- "dist"
12
- ],
13
- "exports": {
14
- ".": {
15
- "types": "./dist/index.d.ts",
16
- "import": "./dist/index.js",
17
- "default": "./dist/index.js"
18
- }
19
- },
20
- "scripts": {
21
- "build": "bun run ./scripts/clean.ts && esbuild ./src/index.ts --bundle --outfile=./dist/index.js --platform=node --format=esm --target=node24 --packages=external --minify && tsc -p tsconfig.build.json",
22
- "test": "vitest run --config vitest.config.ts",
23
- "bench": "bun run ./bench/run.ts"
24
- },
25
- "dependencies": {
26
- "@memoized-dom/compiler": "^0.0.5"
27
- },
28
- "peerDependencies": {
29
- "@memoized-dom/runtime": "^0.0.6",
30
- "vite": "^8.0.0"
31
- },
32
- "publishConfig": {
33
- "access": "public"
34
- }
35
- }
1
+ {
2
+ "name": "@memoized-dom/vite",
3
+ "version": "0.0.7",
4
+ "description": "Vite 8 adapter for connected memoized-dom module graphs",
5
+ "type": "module",
6
+ "engines": {
7
+ "node": ">=24.11.0"
8
+ },
9
+ "sideEffects": false,
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "exports": {
14
+ ".": {
15
+ "types": "./dist/index.d.ts",
16
+ "import": "./dist/index.js",
17
+ "default": "./dist/index.js"
18
+ }
19
+ },
20
+ "scripts": {
21
+ "build": "bun run ./scripts/clean.ts && rolldown -c rolldown.config.ts && tsc -p tsconfig.build.json",
22
+ "test": "vitest run --config vitest.config.ts",
23
+ "bench": "bun run ./bench/run.ts"
24
+ },
25
+ "dependencies": {
26
+ "@memoized-dom/adapters": "^0.0.1",
27
+ "@memoized-dom/compiler": "^0.0.6"
28
+ },
29
+ "peerDependencies": {
30
+ "@memoized-dom/runtime": "^0.0.6",
31
+ "vite": "^8.0.0"
32
+ },
33
+ "publishConfig": {
34
+ "access": "public"
35
+ }
36
+ }