zylaris 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +558 -0
- package/Zylaris.js.png +0 -0
- package/examples/default/index.html +13 -0
- package/examples/default/package.json +23 -0
- package/examples/default/src/app/about/page.tsx +18 -0
- package/examples/default/src/app/counter/page.tsx +22 -0
- package/examples/default/src/app/global.css +225 -0
- package/examples/default/src/app/layout.tsx +33 -0
- package/examples/default/src/app/page.tsx +14 -0
- package/examples/default/src/entry-client.tsx +87 -0
- package/examples/default/src/entry-server.tsx +52 -0
- package/examples/default/src/router.ts +60 -0
- package/examples/default/tsconfig.json +28 -0
- package/examples/default/zylaris.config.ts +24 -0
- package/package.json +34 -0
- package/packages/adapter/package.json +59 -0
- package/packages/adapter/src/adapters/bun.ts +215 -0
- package/packages/adapter/src/adapters/cloudflare.ts +278 -0
- package/packages/adapter/src/adapters/deno.ts +219 -0
- package/packages/adapter/src/adapters/netlify.ts +274 -0
- package/packages/adapter/src/adapters/node.ts +155 -0
- package/packages/adapter/src/adapters/static.ts +134 -0
- package/packages/adapter/src/adapters/vercel.ts +239 -0
- package/packages/adapter/src/index.ts +115 -0
- package/packages/adapter/src/lib/builder.ts +361 -0
- package/packages/adapter/src/types.ts +191 -0
- package/packages/adapter/tsconfig.json +8 -0
- package/packages/cli/package.json +43 -0
- package/packages/cli/src/bin.ts +107 -0
- package/packages/cli/src/commands/build.ts +197 -0
- package/packages/cli/src/commands/create.ts +222 -0
- package/packages/cli/src/commands/deploy.ts +90 -0
- package/packages/cli/src/commands/dev.ts +108 -0
- package/packages/cli/src/index.ts +6 -0
- package/packages/cli/tsconfig.json +9 -0
- package/packages/compiler/package.json +39 -0
- package/packages/compiler/src/index.ts +210 -0
- package/packages/compiler/src/jit.ts +187 -0
- package/packages/compiler/tsconfig.json +9 -0
- package/packages/core/package.json +55 -0
- package/packages/core/src/components.test.ts +125 -0
- package/packages/core/src/components.ts +181 -0
- package/packages/core/src/config.ts +204 -0
- package/packages/core/src/hooks.ts +142 -0
- package/packages/core/src/index.ts +59 -0
- package/packages/core/src/jsx-runtime.ts +46 -0
- package/packages/core/tsconfig.json +16 -0
- package/packages/dev-server/package.json +51 -0
- package/packages/dev-server/src/index.ts +306 -0
- package/packages/dev-server/src/jit-middleware.ts +78 -0
- package/packages/dev-server/tsconfig.json +9 -0
- package/packages/plugins/package.json +44 -0
- package/packages/plugins/src/cdn/loader.ts +275 -0
- package/packages/plugins/src/index.ts +238 -0
- package/packages/plugins/src/loaders/auto-import.ts +219 -0
- package/packages/plugins/src/loaders/external.ts +332 -0
- package/packages/plugins/src/transforms/index.ts +407 -0
- package/packages/plugins/src/types.ts +296 -0
- package/packages/plugins/tsconfig.json +8 -0
- package/packages/reactivity/package.json +36 -0
- package/packages/reactivity/src/computed.d.ts +3 -0
- package/packages/reactivity/src/computed.d.ts.map +1 -0
- package/packages/reactivity/src/computed.js +64 -0
- package/packages/reactivity/src/computed.js.map +1 -0
- package/packages/reactivity/src/computed.test.ts +83 -0
- package/packages/reactivity/src/computed.ts +69 -0
- package/packages/reactivity/src/index.d.ts +6 -0
- package/packages/reactivity/src/index.d.ts.map +1 -0
- package/packages/reactivity/src/index.js +7 -0
- package/packages/reactivity/src/index.js.map +1 -0
- package/packages/reactivity/src/index.ts +18 -0
- package/packages/reactivity/src/resource.d.ts +6 -0
- package/packages/reactivity/src/resource.d.ts.map +1 -0
- package/packages/reactivity/src/resource.js +43 -0
- package/packages/reactivity/src/resource.js.map +1 -0
- package/packages/reactivity/src/resource.test.ts +70 -0
- package/packages/reactivity/src/resource.ts +59 -0
- package/packages/reactivity/src/signal.d.ts +7 -0
- package/packages/reactivity/src/signal.d.ts.map +1 -0
- package/packages/reactivity/src/signal.js +145 -0
- package/packages/reactivity/src/signal.js.map +1 -0
- package/packages/reactivity/src/signal.test.ts +130 -0
- package/packages/reactivity/src/signal.ts +207 -0
- package/packages/reactivity/src/store.d.ts +4 -0
- package/packages/reactivity/src/store.d.ts.map +1 -0
- package/packages/reactivity/src/store.js +62 -0
- package/packages/reactivity/src/store.js.map +1 -0
- package/packages/reactivity/src/store.test.ts +38 -0
- package/packages/reactivity/src/store.ts +111 -0
- package/packages/reactivity/src/types.d.ts +43 -0
- package/packages/reactivity/src/types.d.ts.map +1 -0
- package/packages/reactivity/src/types.js +3 -0
- package/packages/reactivity/src/types.js.map +1 -0
- package/packages/reactivity/src/types.ts +43 -0
- package/packages/reactivity/tsconfig.json +9 -0
- package/packages/router/package.json +44 -0
- package/packages/router/src/components.tsx +150 -0
- package/packages/router/src/fs-router.ts +163 -0
- package/packages/router/src/index.ts +22 -0
- package/packages/router/src/router.test.ts +111 -0
- package/packages/router/src/router.ts +112 -0
- package/packages/router/src/types.ts +69 -0
- package/packages/router/tsconfig.json +10 -0
- package/packages/server/package.json +41 -0
- package/packages/server/src/action.test.ts +102 -0
- package/packages/server/src/action.ts +201 -0
- package/packages/server/src/api.ts +143 -0
- package/packages/server/src/index.ts +18 -0
- package/packages/server/src/types.ts +72 -0
- package/packages/server/tsconfig.json +9 -0
- package/pnpm-workspace.yaml +4 -0
- package/scripts/publish.ps1 +138 -0
- package/scripts/publish.sh +142 -0
- package/tsconfig.json +28 -0
- package/turbo.json +24 -0
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External Dependencies Optimizer
|
|
3
|
+
* Smart handling of npm dependencies with pre-bundling
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { build } from 'esbuild';
|
|
7
|
+
import * as fs from 'fs/promises';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
import type { ExternalConfig, BundleAnalysis } from '../types.js';
|
|
10
|
+
import { generateCDNUrl } from '../cdn/loader.js';
|
|
11
|
+
|
|
12
|
+
/** Dependency metadata */
|
|
13
|
+
interface DepMetadata {
|
|
14
|
+
name: string;
|
|
15
|
+
version: string;
|
|
16
|
+
entry: string;
|
|
17
|
+
browserEntry?: string;
|
|
18
|
+
sideEffects: boolean | string[];
|
|
19
|
+
peerDependencies?: string[];
|
|
20
|
+
size: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Pre-bundle dependencies */
|
|
24
|
+
export async function prebundleDependencies(
|
|
25
|
+
deps: string[],
|
|
26
|
+
options: {
|
|
27
|
+
outDir?: string;
|
|
28
|
+
format?: 'esm' | 'cjs' | 'iife';
|
|
29
|
+
minify?: boolean;
|
|
30
|
+
sourcemap?: boolean;
|
|
31
|
+
} = {}
|
|
32
|
+
): Promise<BundleAnalysis[]> {
|
|
33
|
+
const {
|
|
34
|
+
outDir = 'node_modules/.zylaris/deps',
|
|
35
|
+
format = 'esm',
|
|
36
|
+
minify = true,
|
|
37
|
+
sourcemap = true,
|
|
38
|
+
} = options;
|
|
39
|
+
|
|
40
|
+
const results: BundleAnalysis[] = [];
|
|
41
|
+
|
|
42
|
+
await fs.mkdir(outDir, { recursive: true });
|
|
43
|
+
|
|
44
|
+
for (const dep of deps) {
|
|
45
|
+
const metadata = await getDependencyMetadata(dep);
|
|
46
|
+
if (!metadata) continue;
|
|
47
|
+
|
|
48
|
+
const outfile = path.join(outDir, `${dep.replace('/', '_')}.js`);
|
|
49
|
+
const metafile = path.join(outDir, `${dep.replace('/', '_')}.json`);
|
|
50
|
+
|
|
51
|
+
// Check if already bundled and up to date
|
|
52
|
+
if (await isUpToDate(metafile, metadata)) {
|
|
53
|
+
const cached = await loadCachedAnalysis(metafile);
|
|
54
|
+
if (cached) {
|
|
55
|
+
results.push(cached);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
const result = await build({
|
|
62
|
+
entryPoints: [metadata.entry],
|
|
63
|
+
bundle: true,
|
|
64
|
+
format,
|
|
65
|
+
outfile,
|
|
66
|
+
platform: 'browser',
|
|
67
|
+
target: 'es2022',
|
|
68
|
+
minify,
|
|
69
|
+
sourcemap,
|
|
70
|
+
metafile: true,
|
|
71
|
+
external: metadata.peerDependencies || [],
|
|
72
|
+
define: {
|
|
73
|
+
'process.env.NODE_ENV': '"production"',
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const analysis = analyzeMetafile(result.metafile!, metadata.name);
|
|
78
|
+
results.push(analysis);
|
|
79
|
+
|
|
80
|
+
// Cache metadata
|
|
81
|
+
await fs.writeFile(metafile, JSON.stringify({
|
|
82
|
+
metadata,
|
|
83
|
+
analysis,
|
|
84
|
+
timestamp: Date.now(),
|
|
85
|
+
}, null, 2));
|
|
86
|
+
|
|
87
|
+
} catch (error) {
|
|
88
|
+
console.warn(`Failed to pre-bundle ${dep}:`, error);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return results;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Get dependency metadata */
|
|
96
|
+
async function getDependencyMetadata(name: string): Promise<DepMetadata | null> {
|
|
97
|
+
try {
|
|
98
|
+
const pkgPath = require.resolve(`${name}/package.json`, { paths: [process.cwd()] });
|
|
99
|
+
const pkg = JSON.parse(await fs.readFile(pkgPath, 'utf-8'));
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
name: pkg.name,
|
|
103
|
+
version: pkg.version,
|
|
104
|
+
entry: pkg.module || pkg.main || 'index.js',
|
|
105
|
+
browserEntry: pkg.browser,
|
|
106
|
+
sideEffects: pkg.sideEffects ?? true,
|
|
107
|
+
peerDependencies: pkg.peerDependencies ? Object.keys(pkg.peerDependencies) : undefined,
|
|
108
|
+
size: 0, // Will be calculated during bundling
|
|
109
|
+
};
|
|
110
|
+
} catch {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Check if cached bundle is up to date */
|
|
116
|
+
async function isUpToDate(metafile: string, metadata: DepMetadata): Promise<boolean> {
|
|
117
|
+
try {
|
|
118
|
+
const cached = JSON.parse(await fs.readFile(metafile, 'utf-8'));
|
|
119
|
+
return cached.metadata.version === metadata.version;
|
|
120
|
+
} catch {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** Load cached analysis */
|
|
126
|
+
async function loadCachedAnalysis(metafile: string): Promise<BundleAnalysis | null> {
|
|
127
|
+
try {
|
|
128
|
+
const cached = JSON.parse(await fs.readFile(metafile, 'utf-8'));
|
|
129
|
+
return cached.analysis;
|
|
130
|
+
} catch {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** Analyze esbuild metafile */
|
|
136
|
+
function analyzeMetafile(metafile: { outputs?: Record<string, { bytes: number; inputs?: Record<string, { bytesInOutput: number }> }> }, _name: string): BundleAnalysis {
|
|
137
|
+
const outputs = metafile.outputs as Record<string, { bytes: number; inputs?: Record<string, { bytesInOutput: number }> }>;
|
|
138
|
+
let bundled = 0;
|
|
139
|
+
const dependencies: string[] = [];
|
|
140
|
+
|
|
141
|
+
for (const [file, info] of Object.entries(outputs)) {
|
|
142
|
+
if (!file.endsWith('.map')) {
|
|
143
|
+
bundled += info.bytes;
|
|
144
|
+
|
|
145
|
+
// Extract dependencies from inputs
|
|
146
|
+
if (info.inputs) {
|
|
147
|
+
for (const input of Object.keys(info.inputs)) {
|
|
148
|
+
if (input.includes('node_modules')) {
|
|
149
|
+
const match = input.match(/node_modules\/([^/]+)/);
|
|
150
|
+
if (match && !dependencies.includes(match[1])) {
|
|
151
|
+
dependencies.push(match[1]);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return {
|
|
160
|
+
original: bundled, // Approximation
|
|
161
|
+
bundled,
|
|
162
|
+
gzip: 0, // Will be calculated separately
|
|
163
|
+
dependencies,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** Generate optimized import map */
|
|
168
|
+
export async function generateOptimizedImportMap(
|
|
169
|
+
deps: string[],
|
|
170
|
+
config: ExternalConfig
|
|
171
|
+
): Promise<Record<string, string>> {
|
|
172
|
+
const imports: Record<string, string> = {};
|
|
173
|
+
|
|
174
|
+
// Pre-bundled deps
|
|
175
|
+
if (config.prebundle) {
|
|
176
|
+
const bundled = await prebundleDependencies(config.prebundle);
|
|
177
|
+
for (const dep of bundled) {
|
|
178
|
+
imports[dep.dependencies[0]] = `/node_modules/.zylaris/deps/${dep.dependencies[0]}.js`;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// CDN deps
|
|
183
|
+
if (config.cdn) {
|
|
184
|
+
for (const dep of deps) {
|
|
185
|
+
if (!imports[dep]) {
|
|
186
|
+
imports[dep] = generateCDNUrl(dep, config.cdn);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return imports;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/** Smart external resolver */
|
|
195
|
+
export function createExternalResolver(
|
|
196
|
+
config: ExternalConfig = {}
|
|
197
|
+
): (id: string) => boolean {
|
|
198
|
+
const { external = [], forceInclude = [] } = config;
|
|
199
|
+
|
|
200
|
+
return (id: string): boolean => {
|
|
201
|
+
// Never externalize forced includes
|
|
202
|
+
if (forceInclude.includes(id)) {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Check explicit externals
|
|
207
|
+
for (const pattern of external) {
|
|
208
|
+
if (typeof pattern === 'string') {
|
|
209
|
+
if (id === pattern || id.startsWith(pattern + '/')) {
|
|
210
|
+
return true;
|
|
211
|
+
}
|
|
212
|
+
} else if (pattern instanceof RegExp) {
|
|
213
|
+
if (pattern.test(id)) {
|
|
214
|
+
return true;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Default: externalize node_modules
|
|
220
|
+
if (id.includes('node_modules')) {
|
|
221
|
+
return true;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
return false;
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/** Dependency graph analyzer */
|
|
229
|
+
export class DependencyGraph {
|
|
230
|
+
private graph = new Map<string, Set<string>>();
|
|
231
|
+
|
|
232
|
+
async add(modulePath: string): Promise<void> {
|
|
233
|
+
if (this.graph.has(modulePath)) return;
|
|
234
|
+
|
|
235
|
+
const deps = await this.extractImports(modulePath);
|
|
236
|
+
this.graph.set(modulePath, new Set(deps));
|
|
237
|
+
|
|
238
|
+
// Recursively add dependencies
|
|
239
|
+
for (const dep of deps) {
|
|
240
|
+
if (!this.isExternal(dep)) {
|
|
241
|
+
await this.add(dep);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
private async extractImports(modulePath: string): Promise<string[]> {
|
|
247
|
+
// Simple regex-based extraction (in production, use AST)
|
|
248
|
+
const content = await fs.readFile(modulePath, 'utf-8');
|
|
249
|
+
const imports: string[] = [];
|
|
250
|
+
|
|
251
|
+
const importRegex = /import\s+(?:.*?\s+from\s+)?['"]([^'"]+)['"];?/g;
|
|
252
|
+
let match;
|
|
253
|
+
|
|
254
|
+
while ((match = importRegex.exec(content)) !== null) {
|
|
255
|
+
const importPath = match[1];
|
|
256
|
+
if (!importPath.startsWith('.') && !importPath.startsWith('/')) {
|
|
257
|
+
imports.push(importPath);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return imports;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
private isExternal(id: string): boolean {
|
|
265
|
+
return !id.startsWith('.') && !id.startsWith('/');
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
getDependencies(modulePath: string): string[] {
|
|
269
|
+
const visited = new Set<string>();
|
|
270
|
+
const result: string[] = [];
|
|
271
|
+
|
|
272
|
+
const visit = (path: string) => {
|
|
273
|
+
if (visited.has(path)) return;
|
|
274
|
+
visited.add(path);
|
|
275
|
+
|
|
276
|
+
const deps = this.graph.get(path);
|
|
277
|
+
if (deps) {
|
|
278
|
+
for (const dep of deps) {
|
|
279
|
+
if (!result.includes(dep)) {
|
|
280
|
+
result.push(dep);
|
|
281
|
+
}
|
|
282
|
+
visit(dep);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
visit(modulePath);
|
|
288
|
+
return result;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
findDuplicates(): string[] {
|
|
292
|
+
const versionMap = new Map<string, string[]>();
|
|
293
|
+
|
|
294
|
+
for (const [module] of this.graph) {
|
|
295
|
+
const name = this.getPackageName(module);
|
|
296
|
+
if (!versionMap.has(name)) {
|
|
297
|
+
versionMap.set(name, []);
|
|
298
|
+
}
|
|
299
|
+
versionMap.get(name)!.push(module);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
return Array.from(versionMap.entries())
|
|
303
|
+
.filter(([_, versions]) => versions.length > 1)
|
|
304
|
+
.map(([name]) => name);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
private getPackageName(modulePath: string): string {
|
|
308
|
+
const match = modulePath.match(/node_modules\/([^/]+)/);
|
|
309
|
+
return match ? match[1] : modulePath;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/** Estimate bundle impact */
|
|
314
|
+
export async function estimateBundleImpact(
|
|
315
|
+
deps: string[]
|
|
316
|
+
): Promise<Array<{ name: string; size: number; gzip: number }>> {
|
|
317
|
+
const results = await prebundleDependencies(deps, { minify: true });
|
|
318
|
+
|
|
319
|
+
return results.map(r => ({
|
|
320
|
+
name: r.dependencies[0] || 'unknown',
|
|
321
|
+
size: r.bundled,
|
|
322
|
+
gzip: r.gzip,
|
|
323
|
+
}));
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
export default {
|
|
327
|
+
prebundleDependencies,
|
|
328
|
+
generateOptimizedImportMap,
|
|
329
|
+
createExternalResolver,
|
|
330
|
+
DependencyGraph,
|
|
331
|
+
estimateBundleImpact,
|
|
332
|
+
};
|