@nexus_js/compiler 0.6.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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +17 -0
  3. package/dist/codegen.d.ts +4 -0
  4. package/dist/codegen.d.ts.map +1 -0
  5. package/dist/codegen.js +308 -0
  6. package/dist/codegen.js.map +1 -0
  7. package/dist/css-scope.d.ts +76 -0
  8. package/dist/css-scope.d.ts.map +1 -0
  9. package/dist/css-scope.js +327 -0
  10. package/dist/css-scope.js.map +1 -0
  11. package/dist/guard.d.ts +59 -0
  12. package/dist/guard.d.ts.map +1 -0
  13. package/dist/guard.js +212 -0
  14. package/dist/guard.js.map +1 -0
  15. package/dist/index.d.ts +8 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +19 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/island-ssr-stubs.d.ts +25 -0
  20. package/dist/island-ssr-stubs.d.ts.map +1 -0
  21. package/dist/island-ssr-stubs.js +107 -0
  22. package/dist/island-ssr-stubs.js.map +1 -0
  23. package/dist/island-wrap.d.ts +19 -0
  24. package/dist/island-wrap.d.ts.map +1 -0
  25. package/dist/island-wrap.js +108 -0
  26. package/dist/island-wrap.js.map +1 -0
  27. package/dist/parser.d.ts +28 -0
  28. package/dist/parser.d.ts.map +1 -0
  29. package/dist/parser.js +128 -0
  30. package/dist/parser.js.map +1 -0
  31. package/dist/preload-scanner.d.ts +60 -0
  32. package/dist/preload-scanner.d.ts.map +1 -0
  33. package/dist/preload-scanner.js +156 -0
  34. package/dist/preload-scanner.js.map +1 -0
  35. package/dist/server-actions-extract.d.ts +9 -0
  36. package/dist/server-actions-extract.d.ts.map +1 -0
  37. package/dist/server-actions-extract.js +89 -0
  38. package/dist/server-actions-extract.js.map +1 -0
  39. package/dist/types.d.ts +98 -0
  40. package/dist/types.d.ts.map +1 -0
  41. package/dist/types.js +2 -0
  42. package/dist/types.js.map +1 -0
  43. package/package.json +56 -0
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Nexus Preload Scanner — Eliminates island waterfall loading.
3
+ *
4
+ * The waterfall problem:
5
+ * <Page> → loads Island A JS
6
+ * <IslandA> → renders, then discovers Island B
7
+ * <IslandB> → ONLY NOW starts loading Island B JS ← waterfall!
8
+ *
9
+ * The fix:
10
+ * At SSR time, the scanner walks the entire component tree and collects
11
+ * ALL island component paths (including deeply nested ones).
12
+ * It then emits <link rel="modulepreload"> for each, so the browser
13
+ * fetches them in parallel while parsing the initial HTML.
14
+ *
15
+ * Result: Island A and Island B both start loading immediately,
16
+ * even if B is nested inside A.
17
+ *
18
+ * Algorithm:
19
+ * 1. Parse the template for component references (<ComponentName ...>)
20
+ * 2. For each component that resolves to a .nx file, compile it
21
+ * 3. If it has islands, record their client bundle paths
22
+ * 4. Recurse into imported components
23
+ * 5. Deduplicate and emit modulepreload links
24
+ */
25
+ import { readFile } from 'node:fs/promises';
26
+ import { join, resolve, dirname, relative } from 'node:path';
27
+ import { parse } from './parser.js';
28
+ // Priority order for fetch (load > idle > visible > media)
29
+ const STRATEGY_PRIORITY = {
30
+ 'client:load': 0,
31
+ 'client:idle': 1,
32
+ 'client:visible': 2,
33
+ 'client:media': 3,
34
+ 'server:only': 99,
35
+ };
36
+ /**
37
+ * Scans a route file and all its imported components recursively.
38
+ * Returns modulepreload entries for every island in the tree.
39
+ */
40
+ export async function scanPreloads(filepath, opts) {
41
+ const publicBase = opts.publicBase ?? '/_nexus/islands';
42
+ const maxDepth = opts.maxDepth ?? 8;
43
+ const visited = new Set();
44
+ const entries = [];
45
+ await walkComponent(filepath, opts.root, publicBase, maxDepth, 0, visited, entries);
46
+ // Sort by hydration strategy priority
47
+ entries.sort((a, b) => (STRATEGY_PRIORITY[a.strategy] ?? 99) - (STRATEGY_PRIORITY[b.strategy] ?? 99));
48
+ const linkTags = entries.map((e) => buildPreloadTag(e)).join('\n ');
49
+ return { entries, linkTags, islandCount: entries.length };
50
+ }
51
+ async function walkComponent(filepath, root, publicBase, maxDepth, depth, visited, entries) {
52
+ if (depth > maxDepth)
53
+ return;
54
+ if (visited.has(filepath))
55
+ return;
56
+ visited.add(filepath);
57
+ let source;
58
+ try {
59
+ source = await readFile(filepath, 'utf-8');
60
+ }
61
+ catch {
62
+ return; // File not found — skip
63
+ }
64
+ const parsed = parse(source, filepath);
65
+ // Collect islands from this component
66
+ for (const directive of parsed.islandDirectives) {
67
+ if (directive.directive === 'server:only')
68
+ continue;
69
+ const relPath = relative(root, filepath);
70
+ const href = `${publicBase}/${relPath.replace(/\.nx$/, '.client.js')}`;
71
+ entries.push({
72
+ modulePath: filepath,
73
+ href,
74
+ strategy: directive.directive,
75
+ component: directive.componentName,
76
+ });
77
+ }
78
+ // Find and recurse into imported components
79
+ const importedPaths = extractComponentImports(source, filepath, root);
80
+ for (const importedPath of importedPaths) {
81
+ await walkComponent(importedPath, root, publicBase, maxDepth, depth + 1, visited, entries);
82
+ }
83
+ }
84
+ /**
85
+ * Extracts .nx component imports from a file's frontmatter and script block.
86
+ * Resolves them relative to the current file.
87
+ */
88
+ function extractComponentImports(source, filepath, root) {
89
+ const dir = dirname(filepath);
90
+ const resolved = [];
91
+ // Match: import X from './Foo.nx' or import './Foo.nx'
92
+ const importRe = /import\s+(?:\w+\s+from\s+)?['"]([^'"]+\.nx)['"]/g;
93
+ let m;
94
+ while ((m = importRe.exec(source)) !== null) {
95
+ const spec = m[1];
96
+ if (!spec)
97
+ continue;
98
+ let absPath;
99
+ if (spec.startsWith('.')) {
100
+ absPath = resolve(dir, spec);
101
+ }
102
+ else if (spec.startsWith('$')) {
103
+ // $lib/* alias
104
+ absPath = resolve(root, 'src', spec.slice(1), '.nx');
105
+ }
106
+ else {
107
+ continue; // External package — skip
108
+ }
109
+ if (!absPath.endsWith('.nx'))
110
+ absPath += '.nx';
111
+ resolved.push(absPath);
112
+ }
113
+ // Also scan template for <ComponentName /> patterns
114
+ // These may map to co-located .nx files
115
+ const componentRe = /<([A-Z][a-zA-Z0-9]*)\s/g;
116
+ while ((m = componentRe.exec(source)) !== null) {
117
+ const name = m[1];
118
+ if (!name)
119
+ continue;
120
+ // Try conventional co-location paths
121
+ const candidates = [
122
+ join(dir, `${name}.nx`),
123
+ join(dir, 'components', `${name}.nx`),
124
+ join(root, 'src', 'components', `${name}.nx`),
125
+ ];
126
+ for (const candidate of candidates) {
127
+ resolved.push(candidate); // walkComponent will skip non-existent files
128
+ }
129
+ }
130
+ return [...new Set(resolved)];
131
+ }
132
+ /**
133
+ * Builds a <link rel="modulepreload"> tag with correct fetch priority.
134
+ */
135
+ function buildPreloadTag(entry) {
136
+ const priority = entry.strategy === 'client:load' ? ' fetchpriority="high"' : '';
137
+ const asAttr = ' as="script"';
138
+ return `<link rel="modulepreload" href="${entry.href}"${asAttr}${priority}>`;
139
+ }
140
+ /**
141
+ * Quick synchronous scan — for use inside the compiler during codegen.
142
+ * Returns preload hrefs from already-parsed island directives.
143
+ */
144
+ export function buildPreloadTagsFromManifest(islands, root, publicBase = '/_nexus/islands') {
145
+ const tags = islands
146
+ .filter((i) => i.directive !== 'server:only')
147
+ .sort((a, b) => (STRATEGY_PRIORITY[a.directive] ?? 99) - (STRATEGY_PRIORITY[b.directive] ?? 99))
148
+ .map((island) => {
149
+ const relPath = relative(root, island.componentPath);
150
+ const href = `${publicBase}/${relPath.replace(/\.nx$/, '.client.js')}`;
151
+ const priority = island.directive === 'client:load' ? ' fetchpriority="high"' : '';
152
+ return `<link rel="modulepreload" href="${href}" as="script"${priority}>`;
153
+ });
154
+ return tags.join('\n ');
155
+ }
156
+ //# sourceMappingURL=preload-scanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preload-scanner.js","sourceRoot":"","sources":["../src/preload-scanner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Server Action extraction via TypeScript AST (handles nested braces, return objects, etc.).
3
+ */
4
+ import type { ServerAction } from './types.js';
5
+ /**
6
+ * Extracts server actions from script + frontmatter (TypeScript / JS).
7
+ */
8
+ export declare function extractServerActionsFromSource(code: string): ServerAction[];
9
+ //# sourceMappingURL=server-actions-extract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-actions-extract.d.ts","sourceRoot":"","sources":["../src/server-actions-extract.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAiE/C;;GAEG;AACH,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,EAAE,CAuC3E"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Server Action extraction via TypeScript AST (handles nested braces, return objects, etc.).
3
+ */
4
+ import ts from 'typescript';
5
+ function hasUseServerDirective(body) {
6
+ if (body.statements.length === 0)
7
+ return false;
8
+ const first = body.statements[0];
9
+ if (!ts.isExpressionStatement(first))
10
+ return false;
11
+ const ex = first.expression;
12
+ if (ts.isStringLiteral(ex))
13
+ return ex.text === 'use server';
14
+ if (ts.isNoSubstitutionTemplateLiteral(ex))
15
+ return ex.text === 'use server';
16
+ return false;
17
+ }
18
+ /** Body text for registerAction: statements after the leading "use server" directive. */
19
+ function extractActionBody(sourceFile, body) {
20
+ return body.statements.slice(1).map((s) => s.getText(sourceFile)).join('\n');
21
+ }
22
+ function paramTexts(sourceFile, params) {
23
+ return params.map((p) => p.getText(sourceFile));
24
+ }
25
+ function tryPushAction(name, sourceFile, params, body, seen, out) {
26
+ if (!body || !hasUseServerDirective(body))
27
+ return;
28
+ if (seen.has(name))
29
+ return;
30
+ seen.add(name);
31
+ const bodyText = extractActionBody(sourceFile, body);
32
+ out.push({
33
+ name,
34
+ params: paramTexts(sourceFile, params),
35
+ body: bodyText,
36
+ returnType: 'Promise<unknown>',
37
+ });
38
+ }
39
+ function isCreateActionCallee(expr) {
40
+ return ts.isIdentifier(expr) && expr.text === 'createAction';
41
+ }
42
+ /** `const save = createAction({ handler: ... })` or `createAction(async (fd, ctx) => {})` */
43
+ function tryPushCreateAction(name, sourceFile, call, seen, out) {
44
+ if (seen.has(name))
45
+ return;
46
+ seen.add(name);
47
+ const createActionSource = call.getText(sourceFile);
48
+ out.push({
49
+ name,
50
+ params: [],
51
+ body: '',
52
+ returnType: 'Promise<unknown>',
53
+ createActionSource,
54
+ });
55
+ }
56
+ /**
57
+ * Extracts server actions from script + frontmatter (TypeScript / JS).
58
+ */
59
+ export function extractServerActionsFromSource(code) {
60
+ const out = [];
61
+ const seen = new Set();
62
+ const sourceFile = ts.createSourceFile('actions.ts', code, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
63
+ function visit(node) {
64
+ if (ts.isFunctionDeclaration(node) && node.name && node.body) {
65
+ tryPushAction(node.name.text, sourceFile, node.parameters, node.body, seen, out);
66
+ }
67
+ if (ts.isVariableStatement(node)) {
68
+ for (const decl of node.declarationList.declarations) {
69
+ if (!ts.isIdentifier(decl.name) || !decl.initializer)
70
+ continue;
71
+ const name = decl.name.text;
72
+ const init = decl.initializer;
73
+ if (ts.isCallExpression(init) && isCreateActionCallee(init.expression)) {
74
+ tryPushCreateAction(name, sourceFile, init, seen, out);
75
+ continue;
76
+ }
77
+ if (ts.isArrowFunction(init) || ts.isFunctionExpression(init)) {
78
+ if (init.body && ts.isBlock(init.body)) {
79
+ tryPushAction(name, sourceFile, init.parameters, init.body, seen, out);
80
+ }
81
+ }
82
+ }
83
+ }
84
+ ts.forEachChild(node, visit);
85
+ }
86
+ visit(sourceFile);
87
+ return out;
88
+ }
89
+ //# sourceMappingURL=server-actions-extract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-actions-extract.js","sourceRoot":"","sources":["../src/server-actions-extract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ /** A parsed block extracted from a .nx file */
2
+ export interface NexusBlock {
3
+ type: 'server' | 'script' | 'template' | 'style';
4
+ content: string;
5
+ start: number;
6
+ end: number;
7
+ }
8
+ /** Parsed representation of a .nx component file */
9
+ export interface ParsedComponent {
10
+ /** Raw source code */
11
+ source: string;
12
+ /** Path of the file */
13
+ filepath: string;
14
+ /** Frontmatter block (server-only, runs at request time) */
15
+ frontmatter: NexusBlock | null;
16
+ /** Reactive script block (client island code using Runes) */
17
+ script: NexusBlock | null;
18
+ /** HTML template block */
19
+ template: NexusBlock | null;
20
+ /** Style block */
21
+ style: NexusBlock | null;
22
+ /** Detected island directives e.g. client:visible, client:idle */
23
+ islandDirectives: IslandDirective[];
24
+ /** Detected server actions ("use server" functions) */
25
+ serverActions: ServerAction[];
26
+ }
27
+ export type IslandHydration = 'client:load' | 'client:idle' | 'client:visible' | 'client:media' | 'server:only';
28
+ export interface IslandDirective {
29
+ directive: IslandHydration;
30
+ componentName: string;
31
+ /** For client:media — the query string */
32
+ mediaQuery?: string;
33
+ }
34
+ export interface ServerAction {
35
+ name: string;
36
+ params: string[];
37
+ body: string;
38
+ /** Inferred TypeScript return type */
39
+ returnType: string;
40
+ /**
41
+ * If set, emitted as `registerAction(name, createAction(...), { csrf: false })` instead of a raw
42
+ * async handler (from `const x = createAction(...)` in the .nx script).
43
+ */
44
+ createActionSource?: string;
45
+ }
46
+ export interface CompileOptions {
47
+ mode: 'server' | 'client' | 'static';
48
+ dev: boolean;
49
+ ssr: boolean;
50
+ /** Whether to emit island manifests for the runtime */
51
+ emitIslandManifest: boolean;
52
+ target: 'node' | 'edge' | 'browser';
53
+ /** App root — used for stable /_nexus/islands/client.mjs?path=… query strings */
54
+ appRoot?: string;
55
+ }
56
+ export interface CompileResult {
57
+ /** Server-side module code (runs on every request) */
58
+ serverCode: string;
59
+ /** Client-side island code (only sent to browser when needed) */
60
+ clientCode: string | null;
61
+ /** CSS output */
62
+ css: string | null;
63
+ /** Island manifest for runtime hydration */
64
+ islandManifest: IslandManifest | null;
65
+ /** Server Actions extracted to separate module */
66
+ actionsModule: string | null;
67
+ /** Source maps */
68
+ map: string | null;
69
+ warnings: CompileWarning[];
70
+ }
71
+ export interface IslandManifest {
72
+ islands: IslandEntry[];
73
+ }
74
+ export interface IslandEntry {
75
+ id: string;
76
+ componentPath: string;
77
+ directive: IslandHydration;
78
+ props: string[];
79
+ mediaQuery?: string;
80
+ }
81
+ export interface CompileWarning {
82
+ message: string;
83
+ start?: number;
84
+ end?: number;
85
+ }
86
+ export interface RouteManifest {
87
+ routes: RouteEntry[];
88
+ }
89
+ export interface RouteEntry {
90
+ pattern: string;
91
+ filepath: string;
92
+ params: string[];
93
+ isDynamic: boolean;
94
+ isLayout: boolean;
95
+ parentLayout?: string;
96
+ serverActions: string[];
97
+ }
98
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,oDAAoD;AACpD,MAAM,WAAW,eAAe;IAC9B,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,uBAAuB;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,4DAA4D;IAC5D,WAAW,EAAE,UAAU,GAAG,IAAI,CAAC;IAC/B,6DAA6D;IAC7D,MAAM,EAAE,UAAU,GAAG,IAAI,CAAC;IAC1B,0BAA0B;IAC1B,QAAQ,EAAE,UAAU,GAAG,IAAI,CAAC;IAC5B,kBAAkB;IAClB,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB,kEAAkE;IAClE,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC,uDAAuD;IACvD,aAAa,EAAE,YAAY,EAAE,CAAC;CAC/B;AAED,MAAM,MAAM,eAAe,GACvB,aAAa,GACb,aAAa,GACb,gBAAgB,GAChB,cAAc,GACd,aAAa,CAAC;AAElB,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,eAAe,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACrC,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,uDAAuD;IACvD,kBAAkB,EAAE,OAAO,CAAC;IAC5B,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACpC,iFAAiF;IACjF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,sDAAsD;IACtD,UAAU,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,iBAAiB;IACjB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,4CAA4C;IAC5C,cAAc,EAAE,cAAc,GAAG,IAAI,CAAC;IACtC,kDAAkD;IAClD,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,kBAAkB;IAClB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,QAAQ,EAAE,cAAc,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,eAAe,CAAC;IAC3B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,56 @@
1
+ {
2
+ "name": "@nexus_js/compiler",
3
+ "version": "0.6.0",
4
+ "description": "Nexus compiler — transforms .nx files into optimized server/client bundles",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "dependencies": {
15
+ "magic-string": "^0.30.0",
16
+ "typescript": "^5.5.0"
17
+ },
18
+ "devDependencies": {
19
+ "typescript": "^5.5.0",
20
+ "vitest": "^2.0.0"
21
+ },
22
+ "license": "MIT",
23
+ "homepage": "https://nexusjs.dev",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "https://github.com/bierfor/nexus.git",
27
+ "directory": "packages/compiler"
28
+ },
29
+ "bugs": {
30
+ "url": "https://github.com/bierfor/nexus/issues"
31
+ },
32
+ "keywords": [
33
+ "nexus",
34
+ "framework",
35
+ "full-stack",
36
+ "svelte",
37
+ "islands",
38
+ "ssr",
39
+ "vite",
40
+ "server-actions"
41
+ ],
42
+ "files": [
43
+ "dist",
44
+ "README.md"
45
+ ],
46
+ "publishConfig": {
47
+ "access": "public",
48
+ "registry": "https://registry.npmjs.org/"
49
+ },
50
+ "scripts": {
51
+ "build": "tsc -p tsconfig.json",
52
+ "dev": "tsc -p tsconfig.json --watch",
53
+ "test": "vitest run --passWithNoTests",
54
+ "clean": "rm -rf dist"
55
+ }
56
+ }