rollipop 1.0.0-alpha.21 → 1.0.0-alpha.22
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/CHANGELOG.md +11 -0
- package/dist/commands.cjs +292 -189
- package/dist/commands.js +291 -188
- package/dist/index.d.ts +15 -8
- package/dist/index.js +293 -190
- package/package.json +3 -3
package/dist/commands.cjs
CHANGED
|
@@ -46,8 +46,6 @@ let mitt = require("mitt");
|
|
|
46
46
|
mitt = __toESM(mitt);
|
|
47
47
|
let node_http = require("node:http");
|
|
48
48
|
node_http = __toESM(node_http);
|
|
49
|
-
let node_events = require("node:events");
|
|
50
|
-
node_events = __toESM(node_events);
|
|
51
49
|
let _rollipop_rolldown = require("@rollipop/rolldown");
|
|
52
50
|
_rollipop_rolldown = __toESM(_rollipop_rolldown);
|
|
53
51
|
let _rollipop_rolldown_experimental = require("@rollipop/rolldown/experimental");
|
|
@@ -86,6 +84,8 @@ mime = __toESM(mime);
|
|
|
86
84
|
let ajv = require("ajv");
|
|
87
85
|
ajv = __toESM(ajv);
|
|
88
86
|
let _babel_code_frame = require("@babel/code-frame");
|
|
87
|
+
let node_events = require("node:events");
|
|
88
|
+
node_events = __toESM(node_events);
|
|
89
89
|
let ws = require("ws");
|
|
90
90
|
ws = __toESM(ws);
|
|
91
91
|
let c12 = require("c12");
|
|
@@ -831,30 +831,14 @@ function getGlobalVariables(dev, buildType) {
|
|
|
831
831
|
}
|
|
832
832
|
//#endregion
|
|
833
833
|
//#region src/utils/config.ts
|
|
834
|
-
function bindReporter(config,
|
|
835
|
-
const
|
|
836
|
-
config.reporter = { update(event) {
|
|
837
|
-
switch (event.type) {
|
|
838
|
-
case "bundle_build_started":
|
|
839
|
-
eventSource.emit("buildStart");
|
|
840
|
-
break;
|
|
841
|
-
case "bundle_build_done":
|
|
842
|
-
eventSource.emit("buildDone");
|
|
843
|
-
break;
|
|
844
|
-
case "bundle_build_failed":
|
|
845
|
-
eventSource.emit("buildFailed", event.error);
|
|
846
|
-
break;
|
|
847
|
-
case "transform":
|
|
848
|
-
eventSource.emit("transform", event.id, event.totalModules, event.transformedModules);
|
|
849
|
-
break;
|
|
850
|
-
case "watch_change":
|
|
851
|
-
eventSource.emit("watchChange", event.id);
|
|
852
|
-
break;
|
|
853
|
-
}
|
|
854
|
-
originalReporter?.update(event);
|
|
834
|
+
function bindReporter(config, onEvent) {
|
|
835
|
+
const reporter = { update(event) {
|
|
855
836
|
onEvent?.(event);
|
|
856
837
|
} };
|
|
857
|
-
return
|
|
838
|
+
return {
|
|
839
|
+
...config,
|
|
840
|
+
reporter
|
|
841
|
+
};
|
|
858
842
|
}
|
|
859
843
|
function resolveHmrConfig(config) {
|
|
860
844
|
if (config.mode !== "development") return null;
|
|
@@ -1193,6 +1177,8 @@ var ProgressBarStatusReporter = class {
|
|
|
1193
1177
|
update(event) {
|
|
1194
1178
|
switch (event.type) {
|
|
1195
1179
|
case "bundle_build_started":
|
|
1180
|
+
this.progressBar.setCurrent(0);
|
|
1181
|
+
if (this.flags & ProgressFlags.FILE_CHANGED) this.progressBar.setTotal(0);
|
|
1196
1182
|
this.flags |= ProgressFlags.BUILD_IN_PROGRESS;
|
|
1197
1183
|
this.progressBar.start();
|
|
1198
1184
|
this.renderManager.start();
|
|
@@ -1209,10 +1195,6 @@ var ProgressBarStatusReporter = class {
|
|
|
1209
1195
|
break;
|
|
1210
1196
|
case "transform":
|
|
1211
1197
|
const { id, totalModules, transformedModules } = event;
|
|
1212
|
-
if (this.flags & ProgressFlags.FILE_CHANGED) {
|
|
1213
|
-
logger.debug("Transformed changed file", { id });
|
|
1214
|
-
return;
|
|
1215
|
-
}
|
|
1216
1198
|
this.renderProgress(id, totalModules, transformedModules);
|
|
1217
1199
|
break;
|
|
1218
1200
|
case "watch_change":
|
|
@@ -1898,21 +1880,45 @@ function reporterPlugin(options) {
|
|
|
1898
1880
|
let totalModules = initialTotalModules;
|
|
1899
1881
|
let startedAt = 0;
|
|
1900
1882
|
let transformedModules = 0;
|
|
1883
|
+
let cacheHitModules = 0;
|
|
1901
1884
|
let unknownTotalModules = totalModules === 0;
|
|
1885
|
+
let rebuildPending = false;
|
|
1886
|
+
function getProcessedModules() {
|
|
1887
|
+
return transformedModules + cacheHitModules;
|
|
1888
|
+
}
|
|
1889
|
+
function reportProgress(id) {
|
|
1890
|
+
const processedModules = getProcessedModules();
|
|
1891
|
+
if (!unknownTotalModules && totalModules < processedModules) totalModules = processedModules;
|
|
1892
|
+
reporter?.update({
|
|
1893
|
+
type: "transform",
|
|
1894
|
+
id,
|
|
1895
|
+
totalModules: unknownTotalModules ? void 0 : totalModules,
|
|
1896
|
+
transformedModules: processedModules
|
|
1897
|
+
});
|
|
1898
|
+
}
|
|
1902
1899
|
return {
|
|
1903
1900
|
name: "rollipop:status",
|
|
1904
1901
|
buildStart() {
|
|
1905
1902
|
startedAt = performance.now();
|
|
1906
1903
|
transformedModules = 0;
|
|
1904
|
+
cacheHitModules = 0;
|
|
1905
|
+
if (rebuildPending) {
|
|
1906
|
+
totalModules = 0;
|
|
1907
|
+
unknownTotalModules = false;
|
|
1908
|
+
rebuildPending = false;
|
|
1909
|
+
}
|
|
1907
1910
|
reporter?.update({ type: "bundle_build_started" });
|
|
1908
1911
|
},
|
|
1909
1912
|
buildEnd(error) {
|
|
1910
1913
|
const endedAt = performance.now();
|
|
1911
|
-
|
|
1914
|
+
const processedModules = getProcessedModules();
|
|
1915
|
+
if (processedModules !== 0) totalModules = processedModules;
|
|
1912
1916
|
unknownTotalModules = false;
|
|
1913
1917
|
reporter?.update(error == null ? {
|
|
1914
1918
|
type: "bundle_build_done",
|
|
1915
1919
|
totalModules,
|
|
1920
|
+
transformedModules,
|
|
1921
|
+
cacheHitModules,
|
|
1916
1922
|
duration: endedAt - startedAt
|
|
1917
1923
|
} : {
|
|
1918
1924
|
type: "bundle_build_failed",
|
|
@@ -1923,16 +1929,15 @@ function reporterPlugin(options) {
|
|
|
1923
1929
|
order: "post",
|
|
1924
1930
|
handler(_code, id) {
|
|
1925
1931
|
++transformedModules;
|
|
1926
|
-
|
|
1927
|
-
reporter?.update({
|
|
1928
|
-
type: "transform",
|
|
1929
|
-
id,
|
|
1930
|
-
totalModules: unknownTotalModules ? void 0 : totalModules,
|
|
1931
|
-
transformedModules
|
|
1932
|
-
});
|
|
1932
|
+
reportProgress(id);
|
|
1933
1933
|
}
|
|
1934
1934
|
},
|
|
1935
|
+
transformCacheHit(id) {
|
|
1936
|
+
++cacheHitModules;
|
|
1937
|
+
reportProgress(id);
|
|
1938
|
+
},
|
|
1935
1939
|
watchChange(id) {
|
|
1940
|
+
rebuildPending = true;
|
|
1936
1941
|
reporter?.update({
|
|
1937
1942
|
type: "watch_change",
|
|
1938
1943
|
id
|
|
@@ -2347,7 +2352,7 @@ var FileSystemBundleStore = class {
|
|
|
2347
2352
|
};
|
|
2348
2353
|
//#endregion
|
|
2349
2354
|
//#region src/server/bundler-pool.ts
|
|
2350
|
-
var BundlerDevEngine = class
|
|
2355
|
+
var BundlerDevEngine = class {
|
|
2351
2356
|
initializeHandle;
|
|
2352
2357
|
isHmrEnabled;
|
|
2353
2358
|
_id;
|
|
@@ -2356,24 +2361,14 @@ var BundlerDevEngine = class extends node_events.default {
|
|
|
2356
2361
|
_devEngine = null;
|
|
2357
2362
|
_state = "idle";
|
|
2358
2363
|
_status = "idle";
|
|
2359
|
-
constructor(options, config, buildOptions,
|
|
2360
|
-
super();
|
|
2364
|
+
constructor(options, config, buildOptions, eventBus) {
|
|
2361
2365
|
this.options = options;
|
|
2362
2366
|
this.config = config;
|
|
2363
2367
|
this.buildOptions = buildOptions;
|
|
2364
|
-
this.
|
|
2368
|
+
this.eventBus = eventBus;
|
|
2365
2369
|
this._id = Bundler.createId(config, buildOptions);
|
|
2366
2370
|
this.initializeHandle = taskHandler();
|
|
2367
2371
|
this.isHmrEnabled = Boolean(buildOptions.dev && config.devMode.hmr);
|
|
2368
|
-
this.on("buildStart", () => {
|
|
2369
|
-
this._status = "building";
|
|
2370
|
-
});
|
|
2371
|
-
this.on("buildDone", () => {
|
|
2372
|
-
this._status = "build-done";
|
|
2373
|
-
});
|
|
2374
|
-
this.on("buildFailed", () => {
|
|
2375
|
-
this._status = "build-failed";
|
|
2376
|
-
});
|
|
2377
2372
|
this.initialize();
|
|
2378
2373
|
}
|
|
2379
2374
|
get id() {
|
|
@@ -2393,8 +2388,24 @@ var BundlerDevEngine = class extends node_events.default {
|
|
|
2393
2388
|
async initialize() {
|
|
2394
2389
|
if (this._state !== "idle" || this._devEngine != null) return this;
|
|
2395
2390
|
this._state = "initializing";
|
|
2396
|
-
const
|
|
2397
|
-
|
|
2391
|
+
const config = bindReporter(this.config, (event) => {
|
|
2392
|
+
switch (event.type) {
|
|
2393
|
+
case "bundle_build_started":
|
|
2394
|
+
this._status = "building";
|
|
2395
|
+
break;
|
|
2396
|
+
case "bundle_build_done":
|
|
2397
|
+
this._status = "build-done";
|
|
2398
|
+
break;
|
|
2399
|
+
case "bundle_build_failed":
|
|
2400
|
+
this._status = "build-failed";
|
|
2401
|
+
break;
|
|
2402
|
+
}
|
|
2403
|
+
this.eventBus.emit({
|
|
2404
|
+
...event,
|
|
2405
|
+
bundlerId: this.id
|
|
2406
|
+
});
|
|
2407
|
+
});
|
|
2408
|
+
const devEngine = await Bundler.devEngine(config, this.buildOptions, {
|
|
2398
2409
|
host: this.options.server.host,
|
|
2399
2410
|
port: this.options.server.port,
|
|
2400
2411
|
onHmrUpdates: (errorOrResult) => {
|
|
@@ -2404,17 +2415,25 @@ var BundlerDevEngine = class extends node_events.default {
|
|
|
2404
2415
|
bundlerId: this.id,
|
|
2405
2416
|
error: errorOrResult
|
|
2406
2417
|
});
|
|
2407
|
-
const
|
|
2408
|
-
this.config.reporter?.update({
|
|
2418
|
+
const event = {
|
|
2409
2419
|
type: "bundle_build_failed",
|
|
2410
|
-
error:
|
|
2420
|
+
error: normalizeRolldownError(errorOrResult)
|
|
2421
|
+
};
|
|
2422
|
+
this._status = "build-failed";
|
|
2423
|
+
this.eventBus.emit({
|
|
2424
|
+
...event,
|
|
2425
|
+
bundlerId: this.id
|
|
2411
2426
|
});
|
|
2412
2427
|
} else {
|
|
2413
2428
|
logger$1.trace("Detected changed files", {
|
|
2414
2429
|
bundlerId: this.id,
|
|
2415
2430
|
changedFiles: errorOrResult.changedFiles
|
|
2416
2431
|
});
|
|
2417
|
-
this.emit(
|
|
2432
|
+
this.eventBus.emit({
|
|
2433
|
+
bundlerId: this.id,
|
|
2434
|
+
type: "hmr_updates",
|
|
2435
|
+
updates: errorOrResult.updates
|
|
2436
|
+
});
|
|
2418
2437
|
}
|
|
2419
2438
|
},
|
|
2420
2439
|
onOutput: (errorOrResult) => {
|
|
@@ -2423,7 +2442,15 @@ var BundlerDevEngine = class extends node_events.default {
|
|
|
2423
2442
|
logger$1.trace("onOutput", { bundlerId: this.id });
|
|
2424
2443
|
logger$1.error(errorOrResult.message);
|
|
2425
2444
|
this.buildFailedError = normalizedError;
|
|
2426
|
-
|
|
2445
|
+
const event = {
|
|
2446
|
+
type: "bundle_build_failed",
|
|
2447
|
+
error: normalizedError
|
|
2448
|
+
};
|
|
2449
|
+
this._status = "build-failed";
|
|
2450
|
+
this.eventBus.emit({
|
|
2451
|
+
...event,
|
|
2452
|
+
bundlerId: this.id
|
|
2453
|
+
});
|
|
2427
2454
|
} else {
|
|
2428
2455
|
const output = errorOrResult.output[0];
|
|
2429
2456
|
this.updateBundleStore(output);
|
|
@@ -2459,16 +2486,13 @@ var BundlerDevEngine = class extends node_events.default {
|
|
|
2459
2486
|
};
|
|
2460
2487
|
var BundlerPool = class BundlerPool {
|
|
2461
2488
|
static instances = /* @__PURE__ */ new Map();
|
|
2462
|
-
constructor(config, resolvedServerOptions,
|
|
2489
|
+
constructor(config, resolvedServerOptions, eventBus) {
|
|
2463
2490
|
this.config = config;
|
|
2464
2491
|
this.resolvedServerOptions = resolvedServerOptions;
|
|
2465
|
-
this.
|
|
2466
|
-
}
|
|
2467
|
-
instanceKey(bundleName, buildOptions) {
|
|
2468
|
-
return `${bundleName}-${Bundler.createId(this.config, buildOptions)}`;
|
|
2492
|
+
this.eventBus = eventBus;
|
|
2469
2493
|
}
|
|
2470
2494
|
get(bundleName, buildOptions) {
|
|
2471
|
-
const key =
|
|
2495
|
+
const key = `${getBaseBundleName(bundleName)}-${Bundler.createId(this.config, buildOptions)}`;
|
|
2472
2496
|
const instance = BundlerPool.instances.get(key);
|
|
2473
2497
|
if (instance) return instance;
|
|
2474
2498
|
else {
|
|
@@ -2476,16 +2500,14 @@ var BundlerPool = class BundlerPool {
|
|
|
2476
2500
|
bundleName,
|
|
2477
2501
|
key
|
|
2478
2502
|
});
|
|
2479
|
-
const instance = new BundlerDevEngine({ server: this.resolvedServerOptions }, this.config, buildOptions, this.
|
|
2503
|
+
const instance = new BundlerDevEngine({ server: this.resolvedServerOptions }, this.config, buildOptions, this.eventBus);
|
|
2480
2504
|
logger$1.debug("Setting new bundler instance", { key });
|
|
2481
2505
|
BundlerPool.instances.set(key, instance);
|
|
2482
2506
|
return instance;
|
|
2483
2507
|
}
|
|
2484
2508
|
}
|
|
2485
2509
|
/**
|
|
2486
|
-
* Look up a cached bundler by
|
|
2487
|
-
* in SSE events such as `bundle_build_done`). Returns `undefined` when no
|
|
2488
|
-
* instance with that id has been created yet.
|
|
2510
|
+
* Look up a cached bundler by the id carried as `bundlerId` in events such as `bundle_build_done`. Returns `undefined` when no instance with that id has been created yet.
|
|
2489
2511
|
*/
|
|
2490
2512
|
getInstanceById(id) {
|
|
2491
2513
|
for (const instance of BundlerPool.instances.values()) if (instance.id === id) return instance;
|
|
@@ -2504,6 +2526,21 @@ function errorHandler(error, request, reply) {
|
|
|
2504
2526
|
reply.status(500).send("Internal Server Error");
|
|
2505
2527
|
}
|
|
2506
2528
|
//#endregion
|
|
2529
|
+
//#region src/server/events/event-bus.ts
|
|
2530
|
+
var EventBus = class {
|
|
2531
|
+
listeners = /* @__PURE__ */ new Set();
|
|
2532
|
+
emit(event) {
|
|
2533
|
+
for (const listener of this.listeners) listener(event);
|
|
2534
|
+
}
|
|
2535
|
+
subscribe(listener) {
|
|
2536
|
+
this.listeners.add(listener);
|
|
2537
|
+
return () => {
|
|
2538
|
+
this.listeners.delete(listener);
|
|
2539
|
+
};
|
|
2540
|
+
}
|
|
2541
|
+
};
|
|
2542
|
+
var ServerEventBus = class extends EventBus {};
|
|
2543
|
+
//#endregion
|
|
2507
2544
|
//#region src/utils/reset-cache.ts
|
|
2508
2545
|
/**
|
|
2509
2546
|
* Resolve the build cache directory for the given project root. The cache
|
|
@@ -2526,6 +2563,67 @@ function resetCache(projectRoot) {
|
|
|
2526
2563
|
});
|
|
2527
2564
|
}
|
|
2528
2565
|
//#endregion
|
|
2566
|
+
//#region src/server/sse/adapter.ts
|
|
2567
|
+
function toSSEEvent(event) {
|
|
2568
|
+
switch (event.type) {
|
|
2569
|
+
case "client_log": return {
|
|
2570
|
+
type: "client_log",
|
|
2571
|
+
...event.bundlerId != null ? { bundlerId: event.bundlerId } : {},
|
|
2572
|
+
data: event.data
|
|
2573
|
+
};
|
|
2574
|
+
case "device_connected": return {
|
|
2575
|
+
type: "device_connected",
|
|
2576
|
+
clientId: event.client.id
|
|
2577
|
+
};
|
|
2578
|
+
case "device_disconnected": return {
|
|
2579
|
+
type: "device_disconnected",
|
|
2580
|
+
clientId: event.client.id
|
|
2581
|
+
};
|
|
2582
|
+
case "server_ready":
|
|
2583
|
+
case "cache_reset": return event;
|
|
2584
|
+
case "bundle_build_started":
|
|
2585
|
+
case "bundle_build_done":
|
|
2586
|
+
case "bundle_build_failed":
|
|
2587
|
+
case "watch_change": return reporterEventToSSEEvent(event);
|
|
2588
|
+
case "hmr_updates":
|
|
2589
|
+
case "device_message":
|
|
2590
|
+
case "device_error":
|
|
2591
|
+
case "transform": return null;
|
|
2592
|
+
}
|
|
2593
|
+
}
|
|
2594
|
+
function reporterEventToSSEEvent(event) {
|
|
2595
|
+
switch (event.type) {
|
|
2596
|
+
case "bundle_build_started": return {
|
|
2597
|
+
type: "bundle_build_started",
|
|
2598
|
+
bundlerId: event.bundlerId
|
|
2599
|
+
};
|
|
2600
|
+
case "bundle_build_done": return {
|
|
2601
|
+
type: "bundle_build_done",
|
|
2602
|
+
bundlerId: event.bundlerId,
|
|
2603
|
+
totalModules: event.totalModules,
|
|
2604
|
+
transformedModules: event.transformedModules,
|
|
2605
|
+
cacheHitModules: event.cacheHitModules,
|
|
2606
|
+
duration: event.duration
|
|
2607
|
+
};
|
|
2608
|
+
case "bundle_build_failed": return {
|
|
2609
|
+
type: "bundle_build_failed",
|
|
2610
|
+
bundlerId: event.bundlerId,
|
|
2611
|
+
error: (0, strip_ansi.default)(event.error.message)
|
|
2612
|
+
};
|
|
2613
|
+
case "watch_change": return {
|
|
2614
|
+
type: "watch_change",
|
|
2615
|
+
bundlerId: event.bundlerId,
|
|
2616
|
+
file: event.id
|
|
2617
|
+
};
|
|
2618
|
+
case "client_log": return {
|
|
2619
|
+
type: "client_log",
|
|
2620
|
+
bundlerId: event.bundlerId,
|
|
2621
|
+
data: event.data
|
|
2622
|
+
};
|
|
2623
|
+
case "transform": return null;
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
//#endregion
|
|
2529
2627
|
//#region src/server/mcp/server.ts
|
|
2530
2628
|
function createMcpServer(options) {
|
|
2531
2629
|
const { projectRoot, eventBus } = options;
|
|
@@ -2546,11 +2644,14 @@ function createMcpServer(options) {
|
|
|
2546
2644
|
});
|
|
2547
2645
|
server.registerTool("get_build_events", {
|
|
2548
2646
|
title: "Get Build Events",
|
|
2549
|
-
description: "Subscribe to bundler events for a duration. Returns all events (build start/done/fail, watch changes, client logs, device connections) collected during the wait period.",
|
|
2647
|
+
description: "Subscribe to bundler events for a duration. Returns all events (build start/done/fail, watch changes, client logs, device connections) collected during the wait period. Bundler-scoped events include bundlerId.",
|
|
2550
2648
|
inputSchema: { duration: zod.z.number().min(1e3).max(6e4).default(1e4).describe("How long to listen for events in milliseconds (1000-60000, default 10000)") }
|
|
2551
2649
|
}, async ({ duration }) => {
|
|
2552
2650
|
const events = [];
|
|
2553
|
-
const unsubscribe = eventBus.
|
|
2651
|
+
const unsubscribe = eventBus.subscribe((event) => {
|
|
2652
|
+
const sseEvent = toSSEEvent(event);
|
|
2653
|
+
if (sseEvent != null) events.push(sseEvent);
|
|
2654
|
+
});
|
|
2554
2655
|
await new Promise((resolve) => setTimeout(resolve, duration));
|
|
2555
2656
|
unsubscribe();
|
|
2556
2657
|
if (events.length === 0) return { content: [{
|
|
@@ -2807,6 +2908,11 @@ const bundleRequestSchema = (0, json_schema_to_ts.asConst)({
|
|
|
2807
2908
|
});
|
|
2808
2909
|
new ajv.default().compile(bundleRequestSchema);
|
|
2809
2910
|
//#endregion
|
|
2911
|
+
//#region src/server/events/types.ts
|
|
2912
|
+
function isBundlerEventForId(event, bundlerId) {
|
|
2913
|
+
return "bundlerId" in event && event.bundlerId === bundlerId;
|
|
2914
|
+
}
|
|
2915
|
+
//#endregion
|
|
2810
2916
|
//#region src/server/middlewares/serve-bundle.ts
|
|
2811
2917
|
const routeParamSchema = (0, json_schema_to_ts.asConst)({
|
|
2812
2918
|
type: "object",
|
|
@@ -2818,7 +2924,7 @@ function withGetBundleErrorHandler(reply, task) {
|
|
|
2818
2924
|
});
|
|
2819
2925
|
}
|
|
2820
2926
|
const plugin$2 = (0, fastify_plugin.default)((fastify, options) => {
|
|
2821
|
-
const { getBundler } = options;
|
|
2927
|
+
const { eventBus, getBundler } = options;
|
|
2822
2928
|
const getBundleOptions = (buildOptions) => {
|
|
2823
2929
|
return {
|
|
2824
2930
|
platform: buildOptions.platform,
|
|
@@ -2842,11 +2948,10 @@ const plugin$2 = (0, fastify_plugin.default)((fastify, options) => {
|
|
|
2842
2948
|
const bundler = getBundler(params.name, buildOptions);
|
|
2843
2949
|
if (accept?.includes("multipart/mixed") ?? false) {
|
|
2844
2950
|
const bundleResponse = new BundleResponse(reply);
|
|
2845
|
-
const
|
|
2846
|
-
bundleResponse.writeBundleState(transformedModules, totalModules);
|
|
2847
|
-
};
|
|
2848
|
-
bundler.
|
|
2849
|
-
await bundler.getBundle().then((bundle) => bundleResponse.endWithBundle(bundle.code)).catch((error) => bundleResponse.endWithError(error)).finally(() => bundler.off("transform", transformHandler));
|
|
2951
|
+
const unsubscribe = eventBus.subscribe((event) => {
|
|
2952
|
+
if (isBundlerEventForId(event, bundler.id) && event.type === "transform") bundleResponse.writeBundleState(event.transformedModules, event.totalModules ?? 0);
|
|
2953
|
+
});
|
|
2954
|
+
await bundler.getBundle().then((bundle) => bundleResponse.endWithBundle(bundle.code)).catch((error) => bundleResponse.endWithError(error)).finally(unsubscribe);
|
|
2850
2955
|
} else {
|
|
2851
2956
|
this.log.debug(`client is not support multipart/mixed content: ${accept ?? "<empty>"}`);
|
|
2852
2957
|
const code = (await withGetBundleErrorHandler(reply, bundler.getBundle())).code;
|
|
@@ -2874,7 +2979,7 @@ const plugin$2 = (0, fastify_plugin.default)((fastify, options) => {
|
|
|
2874
2979
|
}, { name: "serve-bundle" });
|
|
2875
2980
|
//#endregion
|
|
2876
2981
|
//#region src/server/middlewares/sse.ts
|
|
2877
|
-
const plugin$1 = (0, fastify_plugin.default)((fastify, {
|
|
2982
|
+
const plugin$1 = (0, fastify_plugin.default)((fastify, { publisher }) => {
|
|
2878
2983
|
fastify.get("/sse/events", (request, reply) => {
|
|
2879
2984
|
const res = reply.raw;
|
|
2880
2985
|
res.writeHead(200, {
|
|
@@ -2885,8 +2990,8 @@ const plugin$1 = (0, fastify_plugin.default)((fastify, { eventBus }) => {
|
|
|
2885
2990
|
});
|
|
2886
2991
|
request.raw.socket.setNoDelay(true);
|
|
2887
2992
|
res.write(":ok\n\n");
|
|
2888
|
-
|
|
2889
|
-
request.raw.on("close", () =>
|
|
2993
|
+
publisher.addClient(res);
|
|
2994
|
+
request.raw.on("close", () => publisher.removeClient(res));
|
|
2890
2995
|
});
|
|
2891
2996
|
}, { name: "sse" });
|
|
2892
2997
|
//#endregion
|
|
@@ -3062,14 +3167,12 @@ function printSymbolicateResult(rawStackFrame, symbolicateResult) {
|
|
|
3062
3167
|
}
|
|
3063
3168
|
//#endregion
|
|
3064
3169
|
//#region src/server/sse/event-bus.ts
|
|
3065
|
-
var
|
|
3170
|
+
var SSEEventPublisher = class {
|
|
3066
3171
|
clients = /* @__PURE__ */ new Set();
|
|
3067
|
-
|
|
3068
|
-
emit(event) {
|
|
3172
|
+
publish(event) {
|
|
3069
3173
|
const data = JSON.stringify(event);
|
|
3070
3174
|
const message = `event: ${event.type}\ndata: ${data}\n\n`;
|
|
3071
3175
|
for (const client of this.clients) if (!client.closed) client.write(message);
|
|
3072
|
-
for (const listener of this.listeners) listener(event);
|
|
3073
3176
|
}
|
|
3074
3177
|
/**
|
|
3075
3178
|
* Subscribe an SSE HTTP response client.
|
|
@@ -3083,51 +3186,11 @@ var SSEEventBus = class {
|
|
|
3083
3186
|
removeClient(res) {
|
|
3084
3187
|
this.clients.delete(res);
|
|
3085
3188
|
}
|
|
3086
|
-
/**
|
|
3087
|
-
* Subscribe a listener that collects events into the given array.
|
|
3088
|
-
* Returns an unsubscribe function.
|
|
3089
|
-
*/
|
|
3090
|
-
collect(collector) {
|
|
3091
|
-
const listener = (event) => collector.push(event);
|
|
3092
|
-
this.listeners.add(listener);
|
|
3093
|
-
return () => this.listeners.delete(listener);
|
|
3094
|
-
}
|
|
3095
3189
|
get clientCount() {
|
|
3096
3190
|
return this.clients.size;
|
|
3097
3191
|
}
|
|
3098
3192
|
};
|
|
3099
3193
|
//#endregion
|
|
3100
|
-
//#region src/server/sse/reporter.ts
|
|
3101
|
-
function toSSEEvent(id, event) {
|
|
3102
|
-
switch (event.type) {
|
|
3103
|
-
case "bundle_build_started": return {
|
|
3104
|
-
type: "bundle_build_started",
|
|
3105
|
-
id
|
|
3106
|
-
};
|
|
3107
|
-
case "bundle_build_done": return {
|
|
3108
|
-
type: "bundle_build_done",
|
|
3109
|
-
id,
|
|
3110
|
-
totalModules: event.totalModules,
|
|
3111
|
-
duration: event.duration
|
|
3112
|
-
};
|
|
3113
|
-
case "bundle_build_failed": return {
|
|
3114
|
-
type: "bundle_build_failed",
|
|
3115
|
-
id,
|
|
3116
|
-
error: (0, strip_ansi.default)(event.error.message)
|
|
3117
|
-
};
|
|
3118
|
-
case "watch_change": return {
|
|
3119
|
-
type: "watch_change",
|
|
3120
|
-
id,
|
|
3121
|
-
file: event.id
|
|
3122
|
-
};
|
|
3123
|
-
case "client_log": return {
|
|
3124
|
-
type: "client_log",
|
|
3125
|
-
data: event.data
|
|
3126
|
-
};
|
|
3127
|
-
case "transform": return null;
|
|
3128
|
-
}
|
|
3129
|
-
}
|
|
3130
|
-
//#endregion
|
|
3131
3194
|
//#region src/server/wss/server.ts
|
|
3132
3195
|
var WebSocketServer = class extends node_events.default {
|
|
3133
3196
|
clientId = 0;
|
|
@@ -3196,13 +3259,13 @@ function getWebSocketUpgradeHandler(websocketEndpoints) {
|
|
|
3196
3259
|
//#region src/server/wss/hmr-server.ts
|
|
3197
3260
|
var HMRServer = class extends WebSocketServer {
|
|
3198
3261
|
bundlerPool;
|
|
3199
|
-
|
|
3262
|
+
eventBus;
|
|
3200
3263
|
instances = /* @__PURE__ */ new Map();
|
|
3201
3264
|
bindings = /* @__PURE__ */ new Map();
|
|
3202
|
-
constructor({ bundlerPool,
|
|
3265
|
+
constructor({ bundlerPool, eventBus }) {
|
|
3203
3266
|
super("hmr", { noServer: true });
|
|
3204
3267
|
this.bundlerPool = bundlerPool;
|
|
3205
|
-
this.
|
|
3268
|
+
this.eventBus = eventBus;
|
|
3206
3269
|
}
|
|
3207
3270
|
parseClientMessage(data) {
|
|
3208
3271
|
const parsedData = JSON.parse(this.rawDataToString(data));
|
|
@@ -3229,33 +3292,34 @@ var HMRServer = class extends WebSocketServer {
|
|
|
3229
3292
|
}
|
|
3230
3293
|
bindEvents(client, instance) {
|
|
3231
3294
|
if (this.bindings.get(client.id) == null) {
|
|
3232
|
-
const
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
}
|
|
3246
|
-
}));
|
|
3247
|
-
};
|
|
3248
|
-
instance.addListener("hmrUpdates", handleHmrUpdates);
|
|
3249
|
-
instance.addListener("watchChange", handleWatchChange);
|
|
3250
|
-
instance.addListener("buildFailed", handleBuildFailed);
|
|
3251
|
-
this.bindings.set(client.id, {
|
|
3252
|
-
hmrUpdates: handleHmrUpdates,
|
|
3253
|
-
watchChange: handleWatchChange,
|
|
3254
|
-
buildFailed: handleBuildFailed
|
|
3295
|
+
const unsubscribe = this.eventBus.subscribe((event) => {
|
|
3296
|
+
if (!isBundlerEventForId(event, instance.id)) return;
|
|
3297
|
+
switch (event.type) {
|
|
3298
|
+
case "hmr_updates":
|
|
3299
|
+
this.handleUpdates(client, event.updates);
|
|
3300
|
+
break;
|
|
3301
|
+
case "watch_change":
|
|
3302
|
+
this.send(client, JSON.stringify({ type: "hmr:update-start" }));
|
|
3303
|
+
break;
|
|
3304
|
+
case "bundle_build_failed":
|
|
3305
|
+
this.sendBuildFailed(client, event.error);
|
|
3306
|
+
break;
|
|
3307
|
+
}
|
|
3255
3308
|
});
|
|
3309
|
+
this.bindings.set(client.id, { unsubscribe });
|
|
3256
3310
|
this.logger.trace(`HMR event binding established (clientId: ${client.id})`);
|
|
3257
3311
|
}
|
|
3258
3312
|
}
|
|
3313
|
+
sendBuildFailed(client, error) {
|
|
3314
|
+
this.send(client, JSON.stringify({
|
|
3315
|
+
type: "hmr:error",
|
|
3316
|
+
payload: {
|
|
3317
|
+
type: "BuildError",
|
|
3318
|
+
errors: [{ description: error.message }],
|
|
3319
|
+
message: error.message
|
|
3320
|
+
}
|
|
3321
|
+
}));
|
|
3322
|
+
}
|
|
3259
3323
|
async handleModuleRegistered(client, modules) {
|
|
3260
3324
|
try {
|
|
3261
3325
|
const instance = this.instances.get(client.id);
|
|
@@ -3322,11 +3386,7 @@ var HMRServer = class extends WebSocketServer {
|
|
|
3322
3386
|
this.logger.trace(`HMR client cleanup (clientId: ${client.id})`);
|
|
3323
3387
|
const binding = this.bindings.get(client.id);
|
|
3324
3388
|
const instance = this.instances.get(client.id);
|
|
3325
|
-
if (binding != null
|
|
3326
|
-
instance.removeListener("hmrUpdates", binding.hmrUpdates);
|
|
3327
|
-
instance.removeListener("watchChange", binding.watchChange);
|
|
3328
|
-
instance.removeListener("buildFailed", binding.buildFailed);
|
|
3329
|
-
}
|
|
3389
|
+
if (binding != null) binding.unsubscribe();
|
|
3330
3390
|
if (instance != null) try {
|
|
3331
3391
|
instance.devEngine.removeClient(String(client.id));
|
|
3332
3392
|
} catch (error) {
|
|
@@ -3373,13 +3433,16 @@ var HMRServer = class extends WebSocketServer {
|
|
|
3373
3433
|
case "hmr:invalidate":
|
|
3374
3434
|
this.handleInvalidate(client, message.moduleId);
|
|
3375
3435
|
break;
|
|
3376
|
-
case "hmr:log":
|
|
3377
|
-
this.
|
|
3436
|
+
case "hmr:log": {
|
|
3437
|
+
const instance = this.instances.get(client.id);
|
|
3438
|
+
this.eventBus.emit({
|
|
3378
3439
|
type: "client_log",
|
|
3440
|
+
...instance != null ? { bundlerId: instance.id } : {},
|
|
3379
3441
|
level: message.level,
|
|
3380
3442
|
data: message.data
|
|
3381
3443
|
});
|
|
3382
3444
|
break;
|
|
3445
|
+
}
|
|
3383
3446
|
}
|
|
3384
3447
|
}
|
|
3385
3448
|
onConnection(client) {
|
|
@@ -3420,22 +3483,58 @@ async function createDevServer(config, options) {
|
|
|
3420
3483
|
loggerInstance: new DevServerLogger(),
|
|
3421
3484
|
disableRequestLogging: true
|
|
3422
3485
|
});
|
|
3423
|
-
const
|
|
3424
|
-
const
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
if (sseEvent) sseEventBus.emit(sseEvent);
|
|
3486
|
+
const eventBus = new ServerEventBus();
|
|
3487
|
+
const ssePublisher = new SSEEventPublisher();
|
|
3488
|
+
const reporter = config.reporter;
|
|
3489
|
+
eventBus.subscribe((event) => {
|
|
3490
|
+
const sseEvent = toSSEEvent(event);
|
|
3491
|
+
if (sseEvent != null) ssePublisher.publish(sseEvent);
|
|
3430
3492
|
});
|
|
3431
|
-
const getBundler = (bundleName, buildOptions) => {
|
|
3432
|
-
return bundlerPool.get(bundleName, (0, es_toolkit.merge)(options?.buildOptions ?? {}, buildOptions));
|
|
3433
|
-
};
|
|
3434
3493
|
const { middleware: communityMiddleware, websocketEndpoints: communityWebsocketEndpoints, messageSocketEndpoint: { server: messageServer, broadcast }, eventsSocketEndpoint: { server: eventsServer, reportEvent } } = (0, _react_native_community_cli_server_api.createDevServerMiddleware)({
|
|
3435
3494
|
port,
|
|
3436
3495
|
host,
|
|
3437
3496
|
watchFolders: []
|
|
3438
3497
|
});
|
|
3498
|
+
eventBus.subscribe((event) => {
|
|
3499
|
+
switch (event.type) {
|
|
3500
|
+
case "bundle_build_started":
|
|
3501
|
+
case "bundle_build_done":
|
|
3502
|
+
case "bundle_build_failed":
|
|
3503
|
+
case "transform":
|
|
3504
|
+
case "watch_change":
|
|
3505
|
+
reporter?.update(event);
|
|
3506
|
+
break;
|
|
3507
|
+
case "client_log":
|
|
3508
|
+
reportEvent?.(event);
|
|
3509
|
+
reporter?.update(event);
|
|
3510
|
+
break;
|
|
3511
|
+
case "device_connected":
|
|
3512
|
+
emitter.emit("device.connected", { client: event.client });
|
|
3513
|
+
break;
|
|
3514
|
+
case "device_message":
|
|
3515
|
+
emitter.emit("device.message", {
|
|
3516
|
+
client: event.client,
|
|
3517
|
+
data: event.data
|
|
3518
|
+
});
|
|
3519
|
+
break;
|
|
3520
|
+
case "device_error":
|
|
3521
|
+
emitter.emit("device.error", {
|
|
3522
|
+
client: event.client,
|
|
3523
|
+
error: event.error
|
|
3524
|
+
});
|
|
3525
|
+
break;
|
|
3526
|
+
case "device_disconnected":
|
|
3527
|
+
emitter.emit("device.disconnected", { client: event.client });
|
|
3528
|
+
break;
|
|
3529
|
+
}
|
|
3530
|
+
});
|
|
3531
|
+
const bundlerPool = new BundlerPool(config, {
|
|
3532
|
+
host,
|
|
3533
|
+
port
|
|
3534
|
+
}, eventBus);
|
|
3535
|
+
const getBundler = (bundleName, buildOptions) => {
|
|
3536
|
+
return bundlerPool.get(bundleName, (0, es_toolkit.merge)(options?.buildOptions ?? {}, buildOptions));
|
|
3537
|
+
};
|
|
3439
3538
|
const { middleware: devMiddleware, websocketEndpoints } = (0, _react_native_dev_middleware.createDevMiddleware)({
|
|
3440
3539
|
serverBaseUrl,
|
|
3441
3540
|
logger: {
|
|
@@ -3453,29 +3552,22 @@ async function createDevServer(config, options) {
|
|
|
3453
3552
|
});
|
|
3454
3553
|
const hmrServer = new HMRServer({
|
|
3455
3554
|
bundlerPool,
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
}).on("
|
|
3461
|
-
|
|
3462
|
-
sseEventBus.emit({
|
|
3463
|
-
type: "device_connected",
|
|
3464
|
-
clientId: client.id
|
|
3465
|
-
});
|
|
3466
|
-
}).on("message", (client, data) => emitter.emit("device.message", {
|
|
3555
|
+
eventBus
|
|
3556
|
+
}).on("connection", (client) => eventBus.emit({
|
|
3557
|
+
type: "device_connected",
|
|
3558
|
+
client
|
|
3559
|
+
})).on("message", (client, data) => eventBus.emit({
|
|
3560
|
+
type: "device_message",
|
|
3467
3561
|
client,
|
|
3468
3562
|
data
|
|
3469
|
-
})).on("error", (client, error) =>
|
|
3563
|
+
})).on("error", (client, error) => eventBus.emit({
|
|
3564
|
+
type: "device_error",
|
|
3470
3565
|
client,
|
|
3471
3566
|
error
|
|
3472
|
-
})).on("close", (client) => {
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
clientId: client.id
|
|
3477
|
-
});
|
|
3478
|
-
});
|
|
3567
|
+
})).on("close", (client) => eventBus.emit({
|
|
3568
|
+
type: "device_disconnected",
|
|
3569
|
+
client
|
|
3570
|
+
}));
|
|
3479
3571
|
await fastify$1.register(import("@fastify/middie"));
|
|
3480
3572
|
const devServer = {
|
|
3481
3573
|
...emitter,
|
|
@@ -3500,13 +3592,16 @@ async function createDevServer(config, options) {
|
|
|
3500
3592
|
})
|
|
3501
3593
|
};
|
|
3502
3594
|
const { invokePostConfigureServer } = await invokeConfigureServer(devServer, config.plugins ?? []);
|
|
3503
|
-
fastify$1.use(requestLogger).use(communityMiddleware).use(devMiddleware).register(plugin$1, {
|
|
3595
|
+
fastify$1.use(requestLogger).use(communityMiddleware).use(devMiddleware).register(plugin$1, { publisher: ssePublisher }).register(plugin$4, {
|
|
3504
3596
|
projectRoot,
|
|
3505
|
-
eventBus
|
|
3597
|
+
eventBus
|
|
3506
3598
|
}).register(plugin$5, { bundlerPool }).register(plugin$6, {
|
|
3507
3599
|
projectRoot,
|
|
3508
|
-
eventBus
|
|
3509
|
-
}).register(plugin, { getBundler }).register(plugin$2, {
|
|
3600
|
+
eventBus
|
|
3601
|
+
}).register(plugin, { getBundler }).register(plugin$2, {
|
|
3602
|
+
eventBus,
|
|
3603
|
+
getBundler
|
|
3604
|
+
}).register(plugin$3, {
|
|
3510
3605
|
projectRoot,
|
|
3511
3606
|
host,
|
|
3512
3607
|
port,
|
|
@@ -3519,7 +3614,7 @@ async function createDevServer(config, options) {
|
|
|
3519
3614
|
"/hot": hmrServer.server
|
|
3520
3615
|
}));
|
|
3521
3616
|
await invokePostConfigureServer();
|
|
3522
|
-
|
|
3617
|
+
eventBus.emit({
|
|
3523
3618
|
type: "server_ready",
|
|
3524
3619
|
host,
|
|
3525
3620
|
port
|
|
@@ -3568,6 +3663,7 @@ function getAgentGuide(baseUrl = defaultBaseUrl) {
|
|
|
3568
3663
|
" Event format:",
|
|
3569
3664
|
" event: <event_type>",
|
|
3570
3665
|
" data: <json_payload>",
|
|
3666
|
+
" bundler-scoped events include bundlerId",
|
|
3571
3667
|
"",
|
|
3572
3668
|
" Useful event types:",
|
|
3573
3669
|
" bundle_build_started, bundle_build_done, bundle_build_failed",
|
|
@@ -3696,6 +3792,7 @@ function mergeConfig(baseConfig, ...overrideConfigs) {
|
|
|
3696
3792
|
//#endregion
|
|
3697
3793
|
//#region src/config/load-config.ts
|
|
3698
3794
|
const CONFIG_FILE_NAME = "rollipop";
|
|
3795
|
+
const INTERNAL_PLUGIN_HOOKS = ["transformCacheHit"];
|
|
3699
3796
|
async function loadConfig(options = {}) {
|
|
3700
3797
|
const { cwd = process.cwd(), configFile, mode, context = {} } = options;
|
|
3701
3798
|
const defaultConfig = await getDefaultConfig(cwd, mode);
|
|
@@ -3730,7 +3827,12 @@ async function flattenPluginOption(pluginOption) {
|
|
|
3730
3827
|
const awaitedPluginOption = await pluginOption;
|
|
3731
3828
|
if (Array.isArray(awaitedPluginOption)) return (await Promise.all(awaitedPluginOption.map(flattenPluginOption))).flat();
|
|
3732
3829
|
if (awaitedPluginOption == null || awaitedPluginOption === false) return [];
|
|
3733
|
-
return [awaitedPluginOption];
|
|
3830
|
+
return [stripInternalPluginHooks(awaitedPluginOption)];
|
|
3831
|
+
}
|
|
3832
|
+
function stripInternalPluginHooks(plugin) {
|
|
3833
|
+
const maybeInternalPlugin = plugin;
|
|
3834
|
+
if (!INTERNAL_PLUGIN_HOOKS.some((hook) => hook in maybeInternalPlugin)) return plugin;
|
|
3835
|
+
return (0, es_toolkit.omit)(maybeInternalPlugin, INTERNAL_PLUGIN_HOOKS);
|
|
3734
3836
|
}
|
|
3735
3837
|
async function resolvePluginConfig(baseConfig, plugins) {
|
|
3736
3838
|
let mergedConfig = (0, es_toolkit.omit)(baseConfig, ["plugins"]);
|
|
@@ -3900,6 +4002,7 @@ const action = async function(options) {
|
|
|
3900
4002
|
dev: options.dev,
|
|
3901
4003
|
minify: options.minify,
|
|
3902
4004
|
cache: options.cache,
|
|
4005
|
+
...options.sourcemapOutput ? { sourcemap: true } : {},
|
|
3903
4006
|
outfile: options.bundleOutput,
|
|
3904
4007
|
sourcemapOutfile: options.sourcemapOutput,
|
|
3905
4008
|
assetsDir: options.assetsDest
|