@flight-framework/bundler-flightpack 0.1.2 → 0.1.4

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/dist/index.js CHANGED
@@ -1,10 +1,3 @@
1
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
- }) : x)(function(x) {
4
- if (typeof require !== "undefined") return require.apply(this, arguments);
5
- throw Error('Dynamic require of "' + x + '" is not supported');
6
- });
7
-
8
1
  // src/index.ts
9
2
  import {
10
3
  registerAdapter,
@@ -49,7 +42,7 @@ function flightpack(options = {}) {
49
42
  port,
50
43
  publicDir: resolvePath(config.root, "public"),
51
44
  outDir: resolvePath(config.root, config.build.outDir),
52
- hmr: options.hmr ?? true,
45
+ hmr: typeof options.hmr === "boolean" ? options.hmr : options.hmr !== void 0 ? true : true,
53
46
  root: config.root
54
47
  });
55
48
  logDevServerStarted(result.url, "FlightPack");
@@ -117,28 +110,265 @@ function flightpack(options = {}) {
117
110
  async build(config) {
118
111
  const native = await loadNativeBinding();
119
112
  const timer = createTimer();
113
+ const { existsSync } = await import("fs");
114
+ const { mkdir, copyFile, writeFile, readFile } = await import("fs/promises");
115
+ const { join, basename, relative } = await import("path");
116
+ const resolvedOptions = {
117
+ minify: typeof options.minify === "boolean" ? options.minify : config.build.minify !== false && config.build.minify !== void 0,
118
+ sourcemap: typeof options.sourcemap === "boolean" ? options.sourcemap : config.build.sourcemap !== false && config.build.sourcemap !== void 0,
119
+ treeshake: typeof options.treeshake === "boolean" ? options.treeshake : typeof options.treeshake === "object" ? options.treeshake.enabled : true,
120
+ splitting: typeof options.splitting === "boolean" ? options.splitting : typeof options.splitting === "object" ? options.splitting.enabled : true,
121
+ cache: typeof options.cache === "boolean" ? options.cache : typeof options.cache === "object" ? options.cache.enabled : true,
122
+ cacheDir: options.cacheDir ?? (typeof options.cache === "object" ? options.cache.directory : void 0) ?? ".flightpack_cache",
123
+ rsc: options.rsc ?? true,
124
+ target: options.target ?? "es2022",
125
+ external: options.external ?? [],
126
+ noExternal: options.noExternal ?? []
127
+ };
128
+ const baseOutDir = resolvePath(config.root, config.build.outDir);
129
+ const cacheDir = resolvePath(config.root, resolvedOptions.cacheDir);
130
+ const allFiles = [];
131
+ let totalSize = 0;
132
+ let cacheHits = 0;
133
+ let cacheMisses = 0;
120
134
  try {
121
- const minifyOption = typeof options.minify === "boolean" ? options.minify : typeof config.build.minify === "boolean" ? config.build.minify : true;
122
- const flightpackOptions = {
123
- entry: getEntryPoints(config),
124
- outDir: resolvePath(config.root, config.build.outDir),
135
+ await cleanDirectory(baseOutDir);
136
+ console.log("\n\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510");
137
+ console.log("\u2502 \u26A1 FlightPack Production Build \u2502");
138
+ console.log("\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524");
139
+ console.log(`\u2502 Tree Shaking: ${resolvedOptions.treeshake ? "\u2713 InnerGraph (statement-level)" : "\u2717 disabled"} `);
140
+ console.log(`\u2502 Code Splitting: ${resolvedOptions.splitting ? "\u2713 ChunkSplitter" : "\u2717 disabled"} `);
141
+ console.log(`\u2502 Caching: ${resolvedOptions.cache ? "\u2713 TurboCache + ArtifactStore" : "\u2717 disabled"} `);
142
+ console.log(`\u2502 Target: ${resolvedOptions.target} `);
143
+ console.log("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n");
144
+ console.log("\u26A1 Phase 1/6: Building client bundle...");
145
+ const clientEntries = await getEntryPoints(config, "client");
146
+ const clientOutDir = join(baseOutDir, "client", "assets");
147
+ await mkdir(clientOutDir, { recursive: true });
148
+ const browserConditions = native.getPlatformConditions("browser");
149
+ const clientOptions = {
150
+ entry: clientEntries,
151
+ outDir: clientOutDir,
125
152
  root: config.root,
126
- minify: minifyOption,
127
- sourcemap: typeof options.sourcemap === "boolean" ? options.sourcemap : typeof config.build.sourcemap === "boolean" ? config.build.sourcemap : true,
128
- rsc: options.rsc ?? true
153
+ minify: resolvedOptions.minify,
154
+ sourcemap: resolvedOptions.sourcemap,
155
+ rsc: resolvedOptions.rsc,
156
+ // Full capabilities
157
+ treeshake: resolvedOptions.treeshake,
158
+ splitting: resolvedOptions.splitting,
159
+ cache: resolvedOptions.cache,
160
+ cacheDir,
161
+ platform: "browser",
162
+ external: [],
163
+ // Browser bundles include everything
164
+ target: resolvedOptions.target
129
165
  };
130
- const result = await native.build(flightpackOptions);
131
- const files = result.chunks.map((chunk) => ({
132
- path: chunk.fileName,
133
- size: chunk.size,
134
- type: chunk.chunkType,
135
- isDynamicEntry: false
136
- }));
166
+ const clientResult = await native.build(clientOptions);
167
+ for (const chunk of clientResult.chunks) {
168
+ allFiles.push({
169
+ path: `client/assets/${chunk.fileName}`,
170
+ size: chunk.size,
171
+ type: chunk.chunkType,
172
+ isDynamicEntry: false
173
+ });
174
+ totalSize += chunk.size;
175
+ }
176
+ console.log(` \u2713 Client: ${clientResult.chunks.length} chunks (${formatBytes(clientResult.totalSize)})`);
177
+ const isSSR = config.rendering?.default !== "csr";
178
+ if (isSSR) {
179
+ console.log("\u26A1 Phase 2/6: Building server bundle (SSR)...");
180
+ const serverEntries = await getEntryPoints(config, "server");
181
+ const serverOutDir = join(baseOutDir, "server");
182
+ await mkdir(serverOutDir, { recursive: true });
183
+ const nodeBuiltins = native.getNodeBuiltins();
184
+ const serverExternals = [
185
+ ...nodeBuiltins,
186
+ ...resolvedOptions.external
187
+ ].filter((ext) => !resolvedOptions.noExternal.includes(ext));
188
+ const serverOptions = {
189
+ entry: serverEntries,
190
+ outDir: serverOutDir,
191
+ root: config.root,
192
+ minify: false,
193
+ // Server bundles: keep readable for debugging
194
+ sourcemap: resolvedOptions.sourcemap,
195
+ rsc: resolvedOptions.rsc,
196
+ treeshake: resolvedOptions.treeshake,
197
+ splitting: false,
198
+ // Single SSR bundle recommended
199
+ cache: resolvedOptions.cache,
200
+ cacheDir,
201
+ platform: "node",
202
+ external: serverExternals,
203
+ target: "es2022"
204
+ // Node 18+ supports ES2022
205
+ };
206
+ const serverResult = await native.build(serverOptions);
207
+ for (const chunk of serverResult.chunks) {
208
+ allFiles.push({
209
+ path: `server/${chunk.fileName}`,
210
+ size: chunk.size,
211
+ type: chunk.chunkType,
212
+ isDynamicEntry: false
213
+ });
214
+ totalSize += chunk.size;
215
+ }
216
+ console.log(` \u2713 Server: ${serverResult.chunks.length} chunks (${formatBytes(serverResult.totalSize)})`);
217
+ } else {
218
+ console.log("\u26A1 Phase 2/6: Skipped (CSR mode)");
219
+ }
220
+ const hasEdgeConfig = options.environments?.edge;
221
+ if (hasEdgeConfig) {
222
+ console.log("\u26A1 Phase 3/6: Building edge bundle...");
223
+ const edgeOutDir = join(baseOutDir, "edge");
224
+ await mkdir(edgeOutDir, { recursive: true });
225
+ const edgeIncompatible = native.getEdgeIncompatibleModules();
226
+ const edgeOptions = {
227
+ entry: hasEdgeConfig.entry ?? await getEntryPoints(config, "server"),
228
+ outDir: edgeOutDir,
229
+ root: config.root,
230
+ minify: true,
231
+ sourcemap: resolvedOptions.sourcemap,
232
+ rsc: resolvedOptions.rsc,
233
+ treeshake: true,
234
+ // Always tree shake edge bundles
235
+ splitting: false,
236
+ cache: resolvedOptions.cache,
237
+ cacheDir,
238
+ platform: "edge",
239
+ external: edgeIncompatible,
240
+ target: "es2022"
241
+ };
242
+ const edgeResult = await native.build(edgeOptions);
243
+ for (const chunk of edgeResult.chunks) {
244
+ allFiles.push({
245
+ path: `edge/${chunk.fileName}`,
246
+ size: chunk.size,
247
+ type: chunk.chunkType,
248
+ isDynamicEntry: false
249
+ });
250
+ totalSize += chunk.size;
251
+ }
252
+ console.log(` \u2713 Edge: ${edgeResult.chunks.length} chunks (${formatBytes(edgeResult.totalSize)})`);
253
+ } else {
254
+ console.log("\u26A1 Phase 3/6: Skipped (no edge config)");
255
+ }
256
+ console.log("\u26A1 Phase 4/6: Processing CSS...");
257
+ const cssFiles = await findCssFiles(config.root);
258
+ let cssProcessed = 0;
259
+ if (cssFiles.length > 0) {
260
+ const cssOutDir = join(baseOutDir, "client", "assets");
261
+ await mkdir(cssOutDir, { recursive: true });
262
+ const cssOptions = typeof options.css === "object" ? options.css : {};
263
+ const cssTargets = "targets" in cssOptions ? cssOptions.targets : void 0;
264
+ for (const cssFile of cssFiles) {
265
+ try {
266
+ const cssContent = await readFile(cssFile, "utf-8");
267
+ const isCssModule = cssFile.includes(".module.");
268
+ let processedCss;
269
+ let classMap = [];
270
+ if (isCssModule) {
271
+ const result = native.transformCssModule(cssContent, cssFile);
272
+ processedCss = result.code;
273
+ classMap = result.classMap;
274
+ } else {
275
+ const result = native.transformCss(cssContent, cssFile, {
276
+ minify: resolvedOptions.minify,
277
+ cssModules: false,
278
+ sourcemap: resolvedOptions.sourcemap,
279
+ browserTargets: cssTargets
280
+ });
281
+ processedCss = result.code;
282
+ }
283
+ const outFileName = basename(cssFile);
284
+ const outPath = join(cssOutDir, outFileName);
285
+ await writeFile(outPath, processedCss);
286
+ if (resolvedOptions.sourcemap) {
287
+ }
288
+ allFiles.push({
289
+ path: `client/assets/${outFileName}`,
290
+ size: processedCss.length,
291
+ type: "asset",
292
+ isDynamicEntry: false
293
+ });
294
+ totalSize += processedCss.length;
295
+ cssProcessed++;
296
+ } catch (e) {
297
+ console.warn(` \u26A0 Warning: CSS processing failed for ${basename(cssFile)}`);
298
+ }
299
+ }
300
+ }
301
+ console.log(` \u2713 CSS: ${cssProcessed} files processed`);
302
+ console.log("\u26A1 Phase 5/6: Copying static assets...");
303
+ let assetsCount = 0;
304
+ const htmlSource = join(config.root, "index.html");
305
+ const htmlDest = join(baseOutDir, "client", "index.html");
306
+ if (existsSync(htmlSource)) {
307
+ await mkdir(join(baseOutDir, "client"), { recursive: true });
308
+ let htmlContent = await readFile(htmlSource, "utf-8");
309
+ const clientEntry = clientResult.chunks.find((c) => c.chunkType === "entry");
310
+ if (clientEntry) {
311
+ htmlContent = htmlContent.replace(
312
+ "</body>",
313
+ ` <script type="module" src="/assets/${clientEntry.fileName}"></script>
314
+ </body>`
315
+ );
316
+ }
317
+ await writeFile(htmlDest, htmlContent);
318
+ allFiles.push({
319
+ path: "client/index.html",
320
+ size: htmlContent.length,
321
+ type: "asset",
322
+ isDynamicEntry: false
323
+ });
324
+ assetsCount++;
325
+ }
326
+ const publicDir = join(config.root, "public");
327
+ if (existsSync(publicDir)) {
328
+ const copied = await copyDirectoryRecursive(publicDir, join(baseOutDir, "client"));
329
+ assetsCount += copied;
330
+ }
331
+ console.log(` \u2713 Assets: ${assetsCount} files copied`);
332
+ if (resolvedOptions.rsc && isSSR) {
333
+ console.log("\u26A1 Phase 6/6: Generating RSC manifests...");
334
+ const clientManifest = {
335
+ ssrModuleMapping: {},
336
+ edgeSSRModuleMapping: {},
337
+ clientModules: {},
338
+ entryCSSFiles: {}
339
+ };
340
+ const serverManifest = {
341
+ node: {},
342
+ edge: {}
343
+ };
344
+ await writeFile(
345
+ join(baseOutDir, "client", "react-client-manifest.json"),
346
+ JSON.stringify(clientManifest, null, 2)
347
+ );
348
+ await writeFile(
349
+ join(baseOutDir, "server", "react-server-manifest.json"),
350
+ JSON.stringify(serverManifest, null, 2)
351
+ );
352
+ console.log(" \u2713 RSC manifests generated");
353
+ } else {
354
+ console.log("\u26A1 Phase 6/6: Skipped (RSC disabled or CSR mode)");
355
+ }
356
+ const duration = timer.stop();
357
+ console.log("\n\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510");
358
+ console.log("\u2502 Build Summary \u2502");
359
+ console.log("\u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524");
360
+ console.log(`\u2502 Duration: ${duration}ms `);
361
+ console.log(`\u2502 Total Size: ${formatBytes(totalSize)} `);
362
+ console.log(`\u2502 Files: ${allFiles.length} `);
363
+ if (resolvedOptions.cache) {
364
+ console.log(`\u2502 Cache: ${cacheDir} `);
365
+ }
366
+ console.log("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n");
137
367
  const buildResult = {
138
- outDir: result.outputDir,
139
- duration: timer.stop(),
140
- files,
141
- totalSize: result.totalSize,
368
+ outDir: baseOutDir,
369
+ duration,
370
+ files: allFiles,
371
+ totalSize,
142
372
  errors: [],
143
373
  warnings: [],
144
374
  success: true
@@ -147,7 +377,7 @@ function flightpack(options = {}) {
147
377
  return buildResult;
148
378
  } catch (error) {
149
379
  const buildResult = {
150
- outDir: resolvePath(config.root, config.build.outDir),
380
+ outDir: baseOutDir,
151
381
  duration: timer.stop(),
152
382
  files: [],
153
383
  totalSize: 0,
@@ -275,40 +505,104 @@ function flightpack(options = {}) {
275
505
  }
276
506
  return adapter;
277
507
  }
278
- function getEntryPoints(config) {
508
+ async function getEntryPoints(config, type = "client") {
279
509
  const entries = [];
280
- const { existsSync } = __require("fs");
281
- const { join } = __require("path");
282
- const possibleEntries = [
283
- // Standard Flight entries
284
- "src/entry-client.tsx",
285
- "src/entry-client.ts",
286
- // Vite-style entries
287
- "src/main.tsx",
288
- "src/main.ts",
289
- // App-style entries
290
- "src/App.tsx",
291
- "src/App.ts",
292
- "src/app.tsx",
293
- "src/app.ts",
294
- // Index-style entries
295
- "src/index.tsx",
296
- "src/index.ts"
297
- ];
298
- for (const entry of possibleEntries) {
299
- const fullPath = join(config.root, entry);
300
- if (existsSync(fullPath)) {
301
- entries.push(entry);
302
- break;
510
+ const { existsSync } = await import("fs");
511
+ const { join } = await import("path");
512
+ if (type === "server") {
513
+ const serverEntries = [
514
+ "src/entry-server.tsx",
515
+ "src/entry-server.ts",
516
+ "src/server.tsx",
517
+ "src/server.ts"
518
+ ];
519
+ for (const entry of serverEntries) {
520
+ const fullPath = join(config.root, entry);
521
+ if (existsSync(fullPath)) {
522
+ entries.push(entry);
523
+ break;
524
+ }
525
+ }
526
+ if (entries.length === 0) {
527
+ entries.push("src/entry-server.tsx");
528
+ }
529
+ } else {
530
+ const clientEntries = [
531
+ "src/entry-client.tsx",
532
+ "src/entry-client.ts",
533
+ "src/main.tsx",
534
+ "src/main.ts",
535
+ "src/App.tsx",
536
+ "src/App.ts",
537
+ "src/app.tsx",
538
+ "src/app.ts",
539
+ "src/index.tsx",
540
+ "src/index.ts"
541
+ ];
542
+ for (const entry of clientEntries) {
543
+ const fullPath = join(config.root, entry);
544
+ if (existsSync(fullPath)) {
545
+ entries.push(entry);
546
+ break;
547
+ }
548
+ }
549
+ if (entries.length === 0) {
550
+ entries.push("src/index.tsx");
303
551
  }
304
- }
305
- if (entries.length === 0) {
306
- entries.push("src/index.tsx");
307
552
  }
308
553
  return entries;
309
554
  }
555
+ async function findCssFiles(root) {
556
+ const { readdir, stat } = await import("fs/promises");
557
+ const { join } = await import("path");
558
+ const cssFiles = [];
559
+ async function walkDir(dir) {
560
+ try {
561
+ const items = await readdir(dir);
562
+ for (const item of items) {
563
+ if (item === "node_modules" || item.startsWith(".")) continue;
564
+ const itemPath = join(dir, item);
565
+ const itemStat = await stat(itemPath);
566
+ if (itemStat.isDirectory()) {
567
+ await walkDir(itemPath);
568
+ } else if (item.endsWith(".css")) {
569
+ cssFiles.push(itemPath);
570
+ }
571
+ }
572
+ } catch {
573
+ }
574
+ }
575
+ await walkDir(join(root, "src"));
576
+ return cssFiles;
577
+ }
578
+ async function copyDirectoryRecursive(src, dest) {
579
+ const { mkdir, readdir, copyFile, stat } = await import("fs/promises");
580
+ const { join } = await import("path");
581
+ await mkdir(dest, { recursive: true });
582
+ let count = 0;
583
+ const items = await readdir(src);
584
+ for (const item of items) {
585
+ const srcPath = join(src, item);
586
+ const destPath = join(dest, item);
587
+ const itemStat = await stat(srcPath);
588
+ if (itemStat.isDirectory()) {
589
+ count += await copyDirectoryRecursive(srcPath, destPath);
590
+ } else {
591
+ await copyFile(srcPath, destPath);
592
+ count++;
593
+ }
594
+ }
595
+ return count;
596
+ }
597
+ function formatBytes(bytes) {
598
+ if (bytes === 0) return "0 B";
599
+ const k = 1024;
600
+ const sizes = ["B", "KB", "MB", "GB"];
601
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
602
+ return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
603
+ }
310
604
  var index_default = flightpack;
311
- var VERSION = "0.0.1";
605
+ var VERSION = "0.1.4";
312
606
  export {
313
607
  VERSION,
314
608
  flightpack as createFlightPackAdapter,