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/index.js
CHANGED
|
@@ -24,7 +24,6 @@ import { createDevMiddleware } from "@react-native/dev-middleware";
|
|
|
24
24
|
import Fastify from "fastify";
|
|
25
25
|
import mitt from "mitt";
|
|
26
26
|
import http from "node:http";
|
|
27
|
-
import EventEmitter from "node:events";
|
|
28
27
|
import stripAnsi from "strip-ansi";
|
|
29
28
|
import { SourceMapConsumer } from "source-map";
|
|
30
29
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -36,6 +35,7 @@ import { asConst } from "json-schema-to-ts";
|
|
|
36
35
|
import mime from "mime";
|
|
37
36
|
import Ajv from "ajv";
|
|
38
37
|
import { codeFrameColumns } from "@babel/code-frame";
|
|
38
|
+
import EventEmitter from "node:events";
|
|
39
39
|
import * as ws from "ws";
|
|
40
40
|
import * as babel from "@babel/core";
|
|
41
41
|
import * as swc from "@swc/core";
|
|
@@ -105,7 +105,7 @@ var constants_exports = /* @__PURE__ */ __exportAll({
|
|
|
105
105
|
IMAGE_EXTENSIONS: () => IMAGE_EXTENSIONS,
|
|
106
106
|
ROLLIPOP_VERSION: () => ROLLIPOP_VERSION
|
|
107
107
|
});
|
|
108
|
-
const ROLLIPOP_VERSION = "1.0.0-alpha.
|
|
108
|
+
const ROLLIPOP_VERSION = "1.0.0-alpha.22";
|
|
109
109
|
const GLOBAL_IDENTIFIER = "global";
|
|
110
110
|
/**
|
|
111
111
|
* @see {@link https://github.com/facebook/metro/blob/0.81.x/docs/Configuration.md#resolvermainfields}
|
|
@@ -639,6 +639,8 @@ var ProgressBarStatusReporter = class {
|
|
|
639
639
|
update(event) {
|
|
640
640
|
switch (event.type) {
|
|
641
641
|
case "bundle_build_started":
|
|
642
|
+
this.progressBar.setCurrent(0);
|
|
643
|
+
if (this.flags & ProgressFlags.FILE_CHANGED) this.progressBar.setTotal(0);
|
|
642
644
|
this.flags |= ProgressFlags.BUILD_IN_PROGRESS;
|
|
643
645
|
this.progressBar.start();
|
|
644
646
|
this.renderManager.start();
|
|
@@ -655,10 +657,6 @@ var ProgressBarStatusReporter = class {
|
|
|
655
657
|
break;
|
|
656
658
|
case "transform":
|
|
657
659
|
const { id, totalModules, transformedModules } = event;
|
|
658
|
-
if (this.flags & ProgressFlags.FILE_CHANGED) {
|
|
659
|
-
logger$2.debug("Transformed changed file", { id });
|
|
660
|
-
return;
|
|
661
|
-
}
|
|
662
660
|
this.renderProgress(id, totalModules, transformedModules);
|
|
663
661
|
break;
|
|
664
662
|
case "watch_change":
|
|
@@ -809,6 +807,7 @@ function mergeConfig(baseConfig, ...overrideConfigs) {
|
|
|
809
807
|
//#endregion
|
|
810
808
|
//#region src/config/load-config.ts
|
|
811
809
|
const CONFIG_FILE_NAME = "rollipop";
|
|
810
|
+
const INTERNAL_PLUGIN_HOOKS = ["transformCacheHit"];
|
|
812
811
|
async function loadConfig(options = {}) {
|
|
813
812
|
const { cwd = process.cwd(), configFile, mode, context = {} } = options;
|
|
814
813
|
const defaultConfig = await getDefaultConfig(cwd, mode);
|
|
@@ -843,7 +842,12 @@ async function flattenPluginOption(pluginOption) {
|
|
|
843
842
|
const awaitedPluginOption = await pluginOption;
|
|
844
843
|
if (Array.isArray(awaitedPluginOption)) return (await Promise.all(awaitedPluginOption.map(flattenPluginOption))).flat();
|
|
845
844
|
if (awaitedPluginOption == null || awaitedPluginOption === false) return [];
|
|
846
|
-
return [awaitedPluginOption];
|
|
845
|
+
return [stripInternalPluginHooks(awaitedPluginOption)];
|
|
846
|
+
}
|
|
847
|
+
function stripInternalPluginHooks(plugin) {
|
|
848
|
+
const maybeInternalPlugin = plugin;
|
|
849
|
+
if (!INTERNAL_PLUGIN_HOOKS.some((hook) => hook in maybeInternalPlugin)) return plugin;
|
|
850
|
+
return omit(maybeInternalPlugin, INTERNAL_PLUGIN_HOOKS);
|
|
847
851
|
}
|
|
848
852
|
async function resolvePluginConfig(baseConfig, plugins) {
|
|
849
853
|
let mergedConfig = omit(baseConfig, ["plugins"]);
|
|
@@ -1043,30 +1047,14 @@ function iife(body, path = "<unknown>") {
|
|
|
1043
1047
|
}
|
|
1044
1048
|
//#endregion
|
|
1045
1049
|
//#region src/utils/config.ts
|
|
1046
|
-
function bindReporter(config,
|
|
1047
|
-
const
|
|
1048
|
-
config.reporter = { update(event) {
|
|
1049
|
-
switch (event.type) {
|
|
1050
|
-
case "bundle_build_started":
|
|
1051
|
-
eventSource.emit("buildStart");
|
|
1052
|
-
break;
|
|
1053
|
-
case "bundle_build_done":
|
|
1054
|
-
eventSource.emit("buildDone");
|
|
1055
|
-
break;
|
|
1056
|
-
case "bundle_build_failed":
|
|
1057
|
-
eventSource.emit("buildFailed", event.error);
|
|
1058
|
-
break;
|
|
1059
|
-
case "transform":
|
|
1060
|
-
eventSource.emit("transform", event.id, event.totalModules, event.transformedModules);
|
|
1061
|
-
break;
|
|
1062
|
-
case "watch_change":
|
|
1063
|
-
eventSource.emit("watchChange", event.id);
|
|
1064
|
-
break;
|
|
1065
|
-
}
|
|
1066
|
-
originalReporter?.update(event);
|
|
1050
|
+
function bindReporter(config, onEvent) {
|
|
1051
|
+
const reporter = { update(event) {
|
|
1067
1052
|
onEvent?.(event);
|
|
1068
1053
|
} };
|
|
1069
|
-
return
|
|
1054
|
+
return {
|
|
1055
|
+
...config,
|
|
1056
|
+
reporter
|
|
1057
|
+
};
|
|
1070
1058
|
}
|
|
1071
1059
|
function resolveHmrConfig(config) {
|
|
1072
1060
|
if (config.mode !== "development") return null;
|
|
@@ -1298,7 +1286,7 @@ var FileSystemBundleStore = class {
|
|
|
1298
1286
|
};
|
|
1299
1287
|
//#endregion
|
|
1300
1288
|
//#region src/server/bundler-pool.ts
|
|
1301
|
-
var BundlerDevEngine = class
|
|
1289
|
+
var BundlerDevEngine = class {
|
|
1302
1290
|
initializeHandle;
|
|
1303
1291
|
isHmrEnabled;
|
|
1304
1292
|
_id;
|
|
@@ -1307,24 +1295,14 @@ var BundlerDevEngine = class extends EventEmitter {
|
|
|
1307
1295
|
_devEngine = null;
|
|
1308
1296
|
_state = "idle";
|
|
1309
1297
|
_status = "idle";
|
|
1310
|
-
constructor(options, config, buildOptions,
|
|
1311
|
-
super();
|
|
1298
|
+
constructor(options, config, buildOptions, eventBus) {
|
|
1312
1299
|
this.options = options;
|
|
1313
1300
|
this.config = config;
|
|
1314
1301
|
this.buildOptions = buildOptions;
|
|
1315
|
-
this.
|
|
1302
|
+
this.eventBus = eventBus;
|
|
1316
1303
|
this._id = Bundler.createId(config, buildOptions);
|
|
1317
1304
|
this.initializeHandle = taskHandler();
|
|
1318
1305
|
this.isHmrEnabled = Boolean(buildOptions.dev && config.devMode.hmr);
|
|
1319
|
-
this.on("buildStart", () => {
|
|
1320
|
-
this._status = "building";
|
|
1321
|
-
});
|
|
1322
|
-
this.on("buildDone", () => {
|
|
1323
|
-
this._status = "build-done";
|
|
1324
|
-
});
|
|
1325
|
-
this.on("buildFailed", () => {
|
|
1326
|
-
this._status = "build-failed";
|
|
1327
|
-
});
|
|
1328
1306
|
this.initialize();
|
|
1329
1307
|
}
|
|
1330
1308
|
get id() {
|
|
@@ -1344,8 +1322,24 @@ var BundlerDevEngine = class extends EventEmitter {
|
|
|
1344
1322
|
async initialize() {
|
|
1345
1323
|
if (this._state !== "idle" || this._devEngine != null) return this;
|
|
1346
1324
|
this._state = "initializing";
|
|
1347
|
-
const
|
|
1348
|
-
|
|
1325
|
+
const config = bindReporter(this.config, (event) => {
|
|
1326
|
+
switch (event.type) {
|
|
1327
|
+
case "bundle_build_started":
|
|
1328
|
+
this._status = "building";
|
|
1329
|
+
break;
|
|
1330
|
+
case "bundle_build_done":
|
|
1331
|
+
this._status = "build-done";
|
|
1332
|
+
break;
|
|
1333
|
+
case "bundle_build_failed":
|
|
1334
|
+
this._status = "build-failed";
|
|
1335
|
+
break;
|
|
1336
|
+
}
|
|
1337
|
+
this.eventBus.emit({
|
|
1338
|
+
...event,
|
|
1339
|
+
bundlerId: this.id
|
|
1340
|
+
});
|
|
1341
|
+
});
|
|
1342
|
+
const devEngine = await Bundler.devEngine(config, this.buildOptions, {
|
|
1349
1343
|
host: this.options.server.host,
|
|
1350
1344
|
port: this.options.server.port,
|
|
1351
1345
|
onHmrUpdates: (errorOrResult) => {
|
|
@@ -1355,17 +1349,25 @@ var BundlerDevEngine = class extends EventEmitter {
|
|
|
1355
1349
|
bundlerId: this.id,
|
|
1356
1350
|
error: errorOrResult
|
|
1357
1351
|
});
|
|
1358
|
-
const
|
|
1359
|
-
this.config.reporter?.update({
|
|
1352
|
+
const event = {
|
|
1360
1353
|
type: "bundle_build_failed",
|
|
1361
|
-
error:
|
|
1354
|
+
error: normalizeRolldownError(errorOrResult)
|
|
1355
|
+
};
|
|
1356
|
+
this._status = "build-failed";
|
|
1357
|
+
this.eventBus.emit({
|
|
1358
|
+
...event,
|
|
1359
|
+
bundlerId: this.id
|
|
1362
1360
|
});
|
|
1363
1361
|
} else {
|
|
1364
1362
|
logger$1.trace("Detected changed files", {
|
|
1365
1363
|
bundlerId: this.id,
|
|
1366
1364
|
changedFiles: errorOrResult.changedFiles
|
|
1367
1365
|
});
|
|
1368
|
-
this.emit(
|
|
1366
|
+
this.eventBus.emit({
|
|
1367
|
+
bundlerId: this.id,
|
|
1368
|
+
type: "hmr_updates",
|
|
1369
|
+
updates: errorOrResult.updates
|
|
1370
|
+
});
|
|
1369
1371
|
}
|
|
1370
1372
|
},
|
|
1371
1373
|
onOutput: (errorOrResult) => {
|
|
@@ -1374,7 +1376,15 @@ var BundlerDevEngine = class extends EventEmitter {
|
|
|
1374
1376
|
logger$1.trace("onOutput", { bundlerId: this.id });
|
|
1375
1377
|
logger$1.error(errorOrResult.message);
|
|
1376
1378
|
this.buildFailedError = normalizedError;
|
|
1377
|
-
|
|
1379
|
+
const event = {
|
|
1380
|
+
type: "bundle_build_failed",
|
|
1381
|
+
error: normalizedError
|
|
1382
|
+
};
|
|
1383
|
+
this._status = "build-failed";
|
|
1384
|
+
this.eventBus.emit({
|
|
1385
|
+
...event,
|
|
1386
|
+
bundlerId: this.id
|
|
1387
|
+
});
|
|
1378
1388
|
} else {
|
|
1379
1389
|
const output = errorOrResult.output[0];
|
|
1380
1390
|
this.updateBundleStore(output);
|
|
@@ -1410,16 +1420,13 @@ var BundlerDevEngine = class extends EventEmitter {
|
|
|
1410
1420
|
};
|
|
1411
1421
|
var BundlerPool = class BundlerPool {
|
|
1412
1422
|
static instances = /* @__PURE__ */ new Map();
|
|
1413
|
-
constructor(config, resolvedServerOptions,
|
|
1423
|
+
constructor(config, resolvedServerOptions, eventBus) {
|
|
1414
1424
|
this.config = config;
|
|
1415
1425
|
this.resolvedServerOptions = resolvedServerOptions;
|
|
1416
|
-
this.
|
|
1417
|
-
}
|
|
1418
|
-
instanceKey(bundleName, buildOptions) {
|
|
1419
|
-
return `${bundleName}-${Bundler.createId(this.config, buildOptions)}`;
|
|
1426
|
+
this.eventBus = eventBus;
|
|
1420
1427
|
}
|
|
1421
1428
|
get(bundleName, buildOptions) {
|
|
1422
|
-
const key =
|
|
1429
|
+
const key = `${getBaseBundleName(bundleName)}-${Bundler.createId(this.config, buildOptions)}`;
|
|
1423
1430
|
const instance = BundlerPool.instances.get(key);
|
|
1424
1431
|
if (instance) return instance;
|
|
1425
1432
|
else {
|
|
@@ -1427,16 +1434,14 @@ var BundlerPool = class BundlerPool {
|
|
|
1427
1434
|
bundleName,
|
|
1428
1435
|
key
|
|
1429
1436
|
});
|
|
1430
|
-
const instance = new BundlerDevEngine({ server: this.resolvedServerOptions }, this.config, buildOptions, this.
|
|
1437
|
+
const instance = new BundlerDevEngine({ server: this.resolvedServerOptions }, this.config, buildOptions, this.eventBus);
|
|
1431
1438
|
logger$1.debug("Setting new bundler instance", { key });
|
|
1432
1439
|
BundlerPool.instances.set(key, instance);
|
|
1433
1440
|
return instance;
|
|
1434
1441
|
}
|
|
1435
1442
|
}
|
|
1436
1443
|
/**
|
|
1437
|
-
* Look up a cached bundler by
|
|
1438
|
-
* in SSE events such as `bundle_build_done`). Returns `undefined` when no
|
|
1439
|
-
* instance with that id has been created yet.
|
|
1444
|
+
* 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.
|
|
1440
1445
|
*/
|
|
1441
1446
|
getInstanceById(id) {
|
|
1442
1447
|
for (const instance of BundlerPool.instances.values()) if (instance.id === id) return instance;
|
|
@@ -1455,6 +1460,82 @@ function errorHandler(error, request, reply) {
|
|
|
1455
1460
|
reply.status(500).send("Internal Server Error");
|
|
1456
1461
|
}
|
|
1457
1462
|
//#endregion
|
|
1463
|
+
//#region src/server/events/event-bus.ts
|
|
1464
|
+
var EventBus = class {
|
|
1465
|
+
listeners = /* @__PURE__ */ new Set();
|
|
1466
|
+
emit(event) {
|
|
1467
|
+
for (const listener of this.listeners) listener(event);
|
|
1468
|
+
}
|
|
1469
|
+
subscribe(listener) {
|
|
1470
|
+
this.listeners.add(listener);
|
|
1471
|
+
return () => {
|
|
1472
|
+
this.listeners.delete(listener);
|
|
1473
|
+
};
|
|
1474
|
+
}
|
|
1475
|
+
};
|
|
1476
|
+
var ServerEventBus = class extends EventBus {};
|
|
1477
|
+
//#endregion
|
|
1478
|
+
//#region src/server/sse/adapter.ts
|
|
1479
|
+
function toSSEEvent(event) {
|
|
1480
|
+
switch (event.type) {
|
|
1481
|
+
case "client_log": return {
|
|
1482
|
+
type: "client_log",
|
|
1483
|
+
...event.bundlerId != null ? { bundlerId: event.bundlerId } : {},
|
|
1484
|
+
data: event.data
|
|
1485
|
+
};
|
|
1486
|
+
case "device_connected": return {
|
|
1487
|
+
type: "device_connected",
|
|
1488
|
+
clientId: event.client.id
|
|
1489
|
+
};
|
|
1490
|
+
case "device_disconnected": return {
|
|
1491
|
+
type: "device_disconnected",
|
|
1492
|
+
clientId: event.client.id
|
|
1493
|
+
};
|
|
1494
|
+
case "server_ready":
|
|
1495
|
+
case "cache_reset": return event;
|
|
1496
|
+
case "bundle_build_started":
|
|
1497
|
+
case "bundle_build_done":
|
|
1498
|
+
case "bundle_build_failed":
|
|
1499
|
+
case "watch_change": return reporterEventToSSEEvent(event);
|
|
1500
|
+
case "hmr_updates":
|
|
1501
|
+
case "device_message":
|
|
1502
|
+
case "device_error":
|
|
1503
|
+
case "transform": return null;
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
function reporterEventToSSEEvent(event) {
|
|
1507
|
+
switch (event.type) {
|
|
1508
|
+
case "bundle_build_started": return {
|
|
1509
|
+
type: "bundle_build_started",
|
|
1510
|
+
bundlerId: event.bundlerId
|
|
1511
|
+
};
|
|
1512
|
+
case "bundle_build_done": return {
|
|
1513
|
+
type: "bundle_build_done",
|
|
1514
|
+
bundlerId: event.bundlerId,
|
|
1515
|
+
totalModules: event.totalModules,
|
|
1516
|
+
transformedModules: event.transformedModules,
|
|
1517
|
+
cacheHitModules: event.cacheHitModules,
|
|
1518
|
+
duration: event.duration
|
|
1519
|
+
};
|
|
1520
|
+
case "bundle_build_failed": return {
|
|
1521
|
+
type: "bundle_build_failed",
|
|
1522
|
+
bundlerId: event.bundlerId,
|
|
1523
|
+
error: stripAnsi(event.error.message)
|
|
1524
|
+
};
|
|
1525
|
+
case "watch_change": return {
|
|
1526
|
+
type: "watch_change",
|
|
1527
|
+
bundlerId: event.bundlerId,
|
|
1528
|
+
file: event.id
|
|
1529
|
+
};
|
|
1530
|
+
case "client_log": return {
|
|
1531
|
+
type: "client_log",
|
|
1532
|
+
bundlerId: event.bundlerId,
|
|
1533
|
+
data: event.data
|
|
1534
|
+
};
|
|
1535
|
+
case "transform": return null;
|
|
1536
|
+
}
|
|
1537
|
+
}
|
|
1538
|
+
//#endregion
|
|
1458
1539
|
//#region src/server/mcp/server.ts
|
|
1459
1540
|
function createMcpServer(options) {
|
|
1460
1541
|
const { projectRoot, eventBus } = options;
|
|
@@ -1475,11 +1556,14 @@ function createMcpServer(options) {
|
|
|
1475
1556
|
});
|
|
1476
1557
|
server.registerTool("get_build_events", {
|
|
1477
1558
|
title: "Get Build Events",
|
|
1478
|
-
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.",
|
|
1559
|
+
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.",
|
|
1479
1560
|
inputSchema: { duration: z.number().min(1e3).max(6e4).default(1e4).describe("How long to listen for events in milliseconds (1000-60000, default 10000)") }
|
|
1480
1561
|
}, async ({ duration }) => {
|
|
1481
1562
|
const events = [];
|
|
1482
|
-
const unsubscribe = eventBus.
|
|
1563
|
+
const unsubscribe = eventBus.subscribe((event) => {
|
|
1564
|
+
const sseEvent = toSSEEvent(event);
|
|
1565
|
+
if (sseEvent != null) events.push(sseEvent);
|
|
1566
|
+
});
|
|
1483
1567
|
await new Promise((resolve) => setTimeout(resolve, duration));
|
|
1484
1568
|
unsubscribe();
|
|
1485
1569
|
if (events.length === 0) return { content: [{
|
|
@@ -1736,6 +1820,11 @@ const bundleRequestSchema = asConst({
|
|
|
1736
1820
|
});
|
|
1737
1821
|
new Ajv().compile(bundleRequestSchema);
|
|
1738
1822
|
//#endregion
|
|
1823
|
+
//#region src/server/events/types.ts
|
|
1824
|
+
function isBundlerEventForId(event, bundlerId) {
|
|
1825
|
+
return "bundlerId" in event && event.bundlerId === bundlerId;
|
|
1826
|
+
}
|
|
1827
|
+
//#endregion
|
|
1739
1828
|
//#region src/server/middlewares/serve-bundle.ts
|
|
1740
1829
|
const routeParamSchema = asConst({
|
|
1741
1830
|
type: "object",
|
|
@@ -1747,7 +1836,7 @@ function withGetBundleErrorHandler(reply, task) {
|
|
|
1747
1836
|
});
|
|
1748
1837
|
}
|
|
1749
1838
|
const plugin$2 = fp((fastify, options) => {
|
|
1750
|
-
const { getBundler } = options;
|
|
1839
|
+
const { eventBus, getBundler } = options;
|
|
1751
1840
|
const getBundleOptions = (buildOptions) => {
|
|
1752
1841
|
return {
|
|
1753
1842
|
platform: buildOptions.platform,
|
|
@@ -1771,11 +1860,10 @@ const plugin$2 = fp((fastify, options) => {
|
|
|
1771
1860
|
const bundler = getBundler(params.name, buildOptions);
|
|
1772
1861
|
if (accept?.includes("multipart/mixed") ?? false) {
|
|
1773
1862
|
const bundleResponse = new BundleResponse(reply);
|
|
1774
|
-
const
|
|
1775
|
-
bundleResponse.writeBundleState(transformedModules, totalModules);
|
|
1776
|
-
};
|
|
1777
|
-
bundler.
|
|
1778
|
-
await bundler.getBundle().then((bundle) => bundleResponse.endWithBundle(bundle.code)).catch((error) => bundleResponse.endWithError(error)).finally(() => bundler.off("transform", transformHandler));
|
|
1863
|
+
const unsubscribe = eventBus.subscribe((event) => {
|
|
1864
|
+
if (isBundlerEventForId(event, bundler.id) && event.type === "transform") bundleResponse.writeBundleState(event.transformedModules, event.totalModules ?? 0);
|
|
1865
|
+
});
|
|
1866
|
+
await bundler.getBundle().then((bundle) => bundleResponse.endWithBundle(bundle.code)).catch((error) => bundleResponse.endWithError(error)).finally(unsubscribe);
|
|
1779
1867
|
} else {
|
|
1780
1868
|
this.log.debug(`client is not support multipart/mixed content: ${accept ?? "<empty>"}`);
|
|
1781
1869
|
const code = (await withGetBundleErrorHandler(reply, bundler.getBundle())).code;
|
|
@@ -1803,7 +1891,7 @@ const plugin$2 = fp((fastify, options) => {
|
|
|
1803
1891
|
}, { name: "serve-bundle" });
|
|
1804
1892
|
//#endregion
|
|
1805
1893
|
//#region src/server/middlewares/sse.ts
|
|
1806
|
-
const plugin$1 = fp((fastify, {
|
|
1894
|
+
const plugin$1 = fp((fastify, { publisher }) => {
|
|
1807
1895
|
fastify.get("/sse/events", (request, reply) => {
|
|
1808
1896
|
const res = reply.raw;
|
|
1809
1897
|
res.writeHead(200, {
|
|
@@ -1814,8 +1902,8 @@ const plugin$1 = fp((fastify, { eventBus }) => {
|
|
|
1814
1902
|
});
|
|
1815
1903
|
request.raw.socket.setNoDelay(true);
|
|
1816
1904
|
res.write(":ok\n\n");
|
|
1817
|
-
|
|
1818
|
-
request.raw.on("close", () =>
|
|
1905
|
+
publisher.addClient(res);
|
|
1906
|
+
request.raw.on("close", () => publisher.removeClient(res));
|
|
1819
1907
|
});
|
|
1820
1908
|
}, { name: "sse" });
|
|
1821
1909
|
//#endregion
|
|
@@ -1991,14 +2079,12 @@ function printSymbolicateResult(rawStackFrame, symbolicateResult) {
|
|
|
1991
2079
|
}
|
|
1992
2080
|
//#endregion
|
|
1993
2081
|
//#region src/server/sse/event-bus.ts
|
|
1994
|
-
var
|
|
2082
|
+
var SSEEventPublisher = class {
|
|
1995
2083
|
clients = /* @__PURE__ */ new Set();
|
|
1996
|
-
|
|
1997
|
-
emit(event) {
|
|
2084
|
+
publish(event) {
|
|
1998
2085
|
const data = JSON.stringify(event);
|
|
1999
2086
|
const message = `event: ${event.type}\ndata: ${data}\n\n`;
|
|
2000
2087
|
for (const client of this.clients) if (!client.closed) client.write(message);
|
|
2001
|
-
for (const listener of this.listeners) listener(event);
|
|
2002
2088
|
}
|
|
2003
2089
|
/**
|
|
2004
2090
|
* Subscribe an SSE HTTP response client.
|
|
@@ -2012,51 +2098,11 @@ var SSEEventBus = class {
|
|
|
2012
2098
|
removeClient(res) {
|
|
2013
2099
|
this.clients.delete(res);
|
|
2014
2100
|
}
|
|
2015
|
-
/**
|
|
2016
|
-
* Subscribe a listener that collects events into the given array.
|
|
2017
|
-
* Returns an unsubscribe function.
|
|
2018
|
-
*/
|
|
2019
|
-
collect(collector) {
|
|
2020
|
-
const listener = (event) => collector.push(event);
|
|
2021
|
-
this.listeners.add(listener);
|
|
2022
|
-
return () => this.listeners.delete(listener);
|
|
2023
|
-
}
|
|
2024
2101
|
get clientCount() {
|
|
2025
2102
|
return this.clients.size;
|
|
2026
2103
|
}
|
|
2027
2104
|
};
|
|
2028
2105
|
//#endregion
|
|
2029
|
-
//#region src/server/sse/reporter.ts
|
|
2030
|
-
function toSSEEvent(id, event) {
|
|
2031
|
-
switch (event.type) {
|
|
2032
|
-
case "bundle_build_started": return {
|
|
2033
|
-
type: "bundle_build_started",
|
|
2034
|
-
id
|
|
2035
|
-
};
|
|
2036
|
-
case "bundle_build_done": return {
|
|
2037
|
-
type: "bundle_build_done",
|
|
2038
|
-
id,
|
|
2039
|
-
totalModules: event.totalModules,
|
|
2040
|
-
duration: event.duration
|
|
2041
|
-
};
|
|
2042
|
-
case "bundle_build_failed": return {
|
|
2043
|
-
type: "bundle_build_failed",
|
|
2044
|
-
id,
|
|
2045
|
-
error: stripAnsi(event.error.message)
|
|
2046
|
-
};
|
|
2047
|
-
case "watch_change": return {
|
|
2048
|
-
type: "watch_change",
|
|
2049
|
-
id,
|
|
2050
|
-
file: event.id
|
|
2051
|
-
};
|
|
2052
|
-
case "client_log": return {
|
|
2053
|
-
type: "client_log",
|
|
2054
|
-
data: event.data
|
|
2055
|
-
};
|
|
2056
|
-
case "transform": return null;
|
|
2057
|
-
}
|
|
2058
|
-
}
|
|
2059
|
-
//#endregion
|
|
2060
2106
|
//#region src/server/wss/server.ts
|
|
2061
2107
|
var WebSocketServer = class extends EventEmitter {
|
|
2062
2108
|
clientId = 0;
|
|
@@ -2125,13 +2171,13 @@ function getWebSocketUpgradeHandler(websocketEndpoints) {
|
|
|
2125
2171
|
//#region src/server/wss/hmr-server.ts
|
|
2126
2172
|
var HMRServer = class extends WebSocketServer {
|
|
2127
2173
|
bundlerPool;
|
|
2128
|
-
|
|
2174
|
+
eventBus;
|
|
2129
2175
|
instances = /* @__PURE__ */ new Map();
|
|
2130
2176
|
bindings = /* @__PURE__ */ new Map();
|
|
2131
|
-
constructor({ bundlerPool,
|
|
2177
|
+
constructor({ bundlerPool, eventBus }) {
|
|
2132
2178
|
super("hmr", { noServer: true });
|
|
2133
2179
|
this.bundlerPool = bundlerPool;
|
|
2134
|
-
this.
|
|
2180
|
+
this.eventBus = eventBus;
|
|
2135
2181
|
}
|
|
2136
2182
|
parseClientMessage(data) {
|
|
2137
2183
|
const parsedData = JSON.parse(this.rawDataToString(data));
|
|
@@ -2158,33 +2204,34 @@ var HMRServer = class extends WebSocketServer {
|
|
|
2158
2204
|
}
|
|
2159
2205
|
bindEvents(client, instance) {
|
|
2160
2206
|
if (this.bindings.get(client.id) == null) {
|
|
2161
|
-
const
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
}
|
|
2175
|
-
}));
|
|
2176
|
-
};
|
|
2177
|
-
instance.addListener("hmrUpdates", handleHmrUpdates);
|
|
2178
|
-
instance.addListener("watchChange", handleWatchChange);
|
|
2179
|
-
instance.addListener("buildFailed", handleBuildFailed);
|
|
2180
|
-
this.bindings.set(client.id, {
|
|
2181
|
-
hmrUpdates: handleHmrUpdates,
|
|
2182
|
-
watchChange: handleWatchChange,
|
|
2183
|
-
buildFailed: handleBuildFailed
|
|
2207
|
+
const unsubscribe = this.eventBus.subscribe((event) => {
|
|
2208
|
+
if (!isBundlerEventForId(event, instance.id)) return;
|
|
2209
|
+
switch (event.type) {
|
|
2210
|
+
case "hmr_updates":
|
|
2211
|
+
this.handleUpdates(client, event.updates);
|
|
2212
|
+
break;
|
|
2213
|
+
case "watch_change":
|
|
2214
|
+
this.send(client, JSON.stringify({ type: "hmr:update-start" }));
|
|
2215
|
+
break;
|
|
2216
|
+
case "bundle_build_failed":
|
|
2217
|
+
this.sendBuildFailed(client, event.error);
|
|
2218
|
+
break;
|
|
2219
|
+
}
|
|
2184
2220
|
});
|
|
2221
|
+
this.bindings.set(client.id, { unsubscribe });
|
|
2185
2222
|
this.logger.trace(`HMR event binding established (clientId: ${client.id})`);
|
|
2186
2223
|
}
|
|
2187
2224
|
}
|
|
2225
|
+
sendBuildFailed(client, error) {
|
|
2226
|
+
this.send(client, JSON.stringify({
|
|
2227
|
+
type: "hmr:error",
|
|
2228
|
+
payload: {
|
|
2229
|
+
type: "BuildError",
|
|
2230
|
+
errors: [{ description: error.message }],
|
|
2231
|
+
message: error.message
|
|
2232
|
+
}
|
|
2233
|
+
}));
|
|
2234
|
+
}
|
|
2188
2235
|
async handleModuleRegistered(client, modules) {
|
|
2189
2236
|
try {
|
|
2190
2237
|
const instance = this.instances.get(client.id);
|
|
@@ -2251,11 +2298,7 @@ var HMRServer = class extends WebSocketServer {
|
|
|
2251
2298
|
this.logger.trace(`HMR client cleanup (clientId: ${client.id})`);
|
|
2252
2299
|
const binding = this.bindings.get(client.id);
|
|
2253
2300
|
const instance = this.instances.get(client.id);
|
|
2254
|
-
if (binding != null
|
|
2255
|
-
instance.removeListener("hmrUpdates", binding.hmrUpdates);
|
|
2256
|
-
instance.removeListener("watchChange", binding.watchChange);
|
|
2257
|
-
instance.removeListener("buildFailed", binding.buildFailed);
|
|
2258
|
-
}
|
|
2301
|
+
if (binding != null) binding.unsubscribe();
|
|
2259
2302
|
if (instance != null) try {
|
|
2260
2303
|
instance.devEngine.removeClient(String(client.id));
|
|
2261
2304
|
} catch (error) {
|
|
@@ -2302,13 +2345,16 @@ var HMRServer = class extends WebSocketServer {
|
|
|
2302
2345
|
case "hmr:invalidate":
|
|
2303
2346
|
this.handleInvalidate(client, message.moduleId);
|
|
2304
2347
|
break;
|
|
2305
|
-
case "hmr:log":
|
|
2306
|
-
this.
|
|
2348
|
+
case "hmr:log": {
|
|
2349
|
+
const instance = this.instances.get(client.id);
|
|
2350
|
+
this.eventBus.emit({
|
|
2307
2351
|
type: "client_log",
|
|
2352
|
+
...instance != null ? { bundlerId: instance.id } : {},
|
|
2308
2353
|
level: message.level,
|
|
2309
2354
|
data: message.data
|
|
2310
2355
|
});
|
|
2311
2356
|
break;
|
|
2357
|
+
}
|
|
2312
2358
|
}
|
|
2313
2359
|
}
|
|
2314
2360
|
onConnection(client) {
|
|
@@ -2349,22 +2395,58 @@ async function createDevServer(config, options) {
|
|
|
2349
2395
|
loggerInstance: new DevServerLogger(),
|
|
2350
2396
|
disableRequestLogging: true
|
|
2351
2397
|
});
|
|
2352
|
-
const
|
|
2353
|
-
const
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
if (sseEvent) sseEventBus.emit(sseEvent);
|
|
2398
|
+
const eventBus = new ServerEventBus();
|
|
2399
|
+
const ssePublisher = new SSEEventPublisher();
|
|
2400
|
+
const reporter = config.reporter;
|
|
2401
|
+
eventBus.subscribe((event) => {
|
|
2402
|
+
const sseEvent = toSSEEvent(event);
|
|
2403
|
+
if (sseEvent != null) ssePublisher.publish(sseEvent);
|
|
2359
2404
|
});
|
|
2360
|
-
const getBundler = (bundleName, buildOptions) => {
|
|
2361
|
-
return bundlerPool.get(bundleName, merge(options?.buildOptions ?? {}, buildOptions));
|
|
2362
|
-
};
|
|
2363
2405
|
const { middleware: communityMiddleware, websocketEndpoints: communityWebsocketEndpoints, messageSocketEndpoint: { server: messageServer, broadcast }, eventsSocketEndpoint: { server: eventsServer, reportEvent } } = createDevServerMiddleware({
|
|
2364
2406
|
port,
|
|
2365
2407
|
host,
|
|
2366
2408
|
watchFolders: []
|
|
2367
2409
|
});
|
|
2410
|
+
eventBus.subscribe((event) => {
|
|
2411
|
+
switch (event.type) {
|
|
2412
|
+
case "bundle_build_started":
|
|
2413
|
+
case "bundle_build_done":
|
|
2414
|
+
case "bundle_build_failed":
|
|
2415
|
+
case "transform":
|
|
2416
|
+
case "watch_change":
|
|
2417
|
+
reporter?.update(event);
|
|
2418
|
+
break;
|
|
2419
|
+
case "client_log":
|
|
2420
|
+
reportEvent?.(event);
|
|
2421
|
+
reporter?.update(event);
|
|
2422
|
+
break;
|
|
2423
|
+
case "device_connected":
|
|
2424
|
+
emitter.emit("device.connected", { client: event.client });
|
|
2425
|
+
break;
|
|
2426
|
+
case "device_message":
|
|
2427
|
+
emitter.emit("device.message", {
|
|
2428
|
+
client: event.client,
|
|
2429
|
+
data: event.data
|
|
2430
|
+
});
|
|
2431
|
+
break;
|
|
2432
|
+
case "device_error":
|
|
2433
|
+
emitter.emit("device.error", {
|
|
2434
|
+
client: event.client,
|
|
2435
|
+
error: event.error
|
|
2436
|
+
});
|
|
2437
|
+
break;
|
|
2438
|
+
case "device_disconnected":
|
|
2439
|
+
emitter.emit("device.disconnected", { client: event.client });
|
|
2440
|
+
break;
|
|
2441
|
+
}
|
|
2442
|
+
});
|
|
2443
|
+
const bundlerPool = new BundlerPool(config, {
|
|
2444
|
+
host,
|
|
2445
|
+
port
|
|
2446
|
+
}, eventBus);
|
|
2447
|
+
const getBundler = (bundleName, buildOptions) => {
|
|
2448
|
+
return bundlerPool.get(bundleName, merge(options?.buildOptions ?? {}, buildOptions));
|
|
2449
|
+
};
|
|
2368
2450
|
const { middleware: devMiddleware, websocketEndpoints } = createDevMiddleware({
|
|
2369
2451
|
serverBaseUrl,
|
|
2370
2452
|
logger: {
|
|
@@ -2382,29 +2464,22 @@ async function createDevServer(config, options) {
|
|
|
2382
2464
|
});
|
|
2383
2465
|
const hmrServer = new HMRServer({
|
|
2384
2466
|
bundlerPool,
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
}).on("
|
|
2390
|
-
|
|
2391
|
-
sseEventBus.emit({
|
|
2392
|
-
type: "device_connected",
|
|
2393
|
-
clientId: client.id
|
|
2394
|
-
});
|
|
2395
|
-
}).on("message", (client, data) => emitter.emit("device.message", {
|
|
2467
|
+
eventBus
|
|
2468
|
+
}).on("connection", (client) => eventBus.emit({
|
|
2469
|
+
type: "device_connected",
|
|
2470
|
+
client
|
|
2471
|
+
})).on("message", (client, data) => eventBus.emit({
|
|
2472
|
+
type: "device_message",
|
|
2396
2473
|
client,
|
|
2397
2474
|
data
|
|
2398
|
-
})).on("error", (client, error) =>
|
|
2475
|
+
})).on("error", (client, error) => eventBus.emit({
|
|
2476
|
+
type: "device_error",
|
|
2399
2477
|
client,
|
|
2400
2478
|
error
|
|
2401
|
-
})).on("close", (client) => {
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
clientId: client.id
|
|
2406
|
-
});
|
|
2407
|
-
});
|
|
2479
|
+
})).on("close", (client) => eventBus.emit({
|
|
2480
|
+
type: "device_disconnected",
|
|
2481
|
+
client
|
|
2482
|
+
}));
|
|
2408
2483
|
await fastify.register(import("@fastify/middie"));
|
|
2409
2484
|
const devServer = {
|
|
2410
2485
|
...emitter,
|
|
@@ -2429,13 +2504,16 @@ async function createDevServer(config, options) {
|
|
|
2429
2504
|
})
|
|
2430
2505
|
};
|
|
2431
2506
|
const { invokePostConfigureServer } = await invokeConfigureServer(devServer, config.plugins ?? []);
|
|
2432
|
-
fastify.use(requestLogger).use(communityMiddleware).use(devMiddleware).register(plugin$1, {
|
|
2507
|
+
fastify.use(requestLogger).use(communityMiddleware).use(devMiddleware).register(plugin$1, { publisher: ssePublisher }).register(plugin$4, {
|
|
2433
2508
|
projectRoot,
|
|
2434
|
-
eventBus
|
|
2509
|
+
eventBus
|
|
2435
2510
|
}).register(plugin$5, { bundlerPool }).register(plugin$6, {
|
|
2436
2511
|
projectRoot,
|
|
2437
|
-
eventBus
|
|
2438
|
-
}).register(plugin, { getBundler }).register(plugin$2, {
|
|
2512
|
+
eventBus
|
|
2513
|
+
}).register(plugin, { getBundler }).register(plugin$2, {
|
|
2514
|
+
eventBus,
|
|
2515
|
+
getBundler
|
|
2516
|
+
}).register(plugin$3, {
|
|
2439
2517
|
projectRoot,
|
|
2440
2518
|
host,
|
|
2441
2519
|
port,
|
|
@@ -2448,7 +2526,7 @@ async function createDevServer(config, options) {
|
|
|
2448
2526
|
"/hot": hmrServer.server
|
|
2449
2527
|
}));
|
|
2450
2528
|
await invokePostConfigureServer();
|
|
2451
|
-
|
|
2529
|
+
eventBus.emit({
|
|
2452
2530
|
type: "server_ready",
|
|
2453
2531
|
host,
|
|
2454
2532
|
port
|
|
@@ -3077,21 +3155,45 @@ function reporterPlugin(options) {
|
|
|
3077
3155
|
let totalModules = initialTotalModules;
|
|
3078
3156
|
let startedAt = 0;
|
|
3079
3157
|
let transformedModules = 0;
|
|
3158
|
+
let cacheHitModules = 0;
|
|
3080
3159
|
let unknownTotalModules = totalModules === 0;
|
|
3160
|
+
let rebuildPending = false;
|
|
3161
|
+
function getProcessedModules() {
|
|
3162
|
+
return transformedModules + cacheHitModules;
|
|
3163
|
+
}
|
|
3164
|
+
function reportProgress(id) {
|
|
3165
|
+
const processedModules = getProcessedModules();
|
|
3166
|
+
if (!unknownTotalModules && totalModules < processedModules) totalModules = processedModules;
|
|
3167
|
+
reporter?.update({
|
|
3168
|
+
type: "transform",
|
|
3169
|
+
id,
|
|
3170
|
+
totalModules: unknownTotalModules ? void 0 : totalModules,
|
|
3171
|
+
transformedModules: processedModules
|
|
3172
|
+
});
|
|
3173
|
+
}
|
|
3081
3174
|
return {
|
|
3082
3175
|
name: "rollipop:status",
|
|
3083
3176
|
buildStart() {
|
|
3084
3177
|
startedAt = performance.now();
|
|
3085
3178
|
transformedModules = 0;
|
|
3179
|
+
cacheHitModules = 0;
|
|
3180
|
+
if (rebuildPending) {
|
|
3181
|
+
totalModules = 0;
|
|
3182
|
+
unknownTotalModules = false;
|
|
3183
|
+
rebuildPending = false;
|
|
3184
|
+
}
|
|
3086
3185
|
reporter?.update({ type: "bundle_build_started" });
|
|
3087
3186
|
},
|
|
3088
3187
|
buildEnd(error) {
|
|
3089
3188
|
const endedAt = performance.now();
|
|
3090
|
-
|
|
3189
|
+
const processedModules = getProcessedModules();
|
|
3190
|
+
if (processedModules !== 0) totalModules = processedModules;
|
|
3091
3191
|
unknownTotalModules = false;
|
|
3092
3192
|
reporter?.update(error == null ? {
|
|
3093
3193
|
type: "bundle_build_done",
|
|
3094
3194
|
totalModules,
|
|
3195
|
+
transformedModules,
|
|
3196
|
+
cacheHitModules,
|
|
3095
3197
|
duration: endedAt - startedAt
|
|
3096
3198
|
} : {
|
|
3097
3199
|
type: "bundle_build_failed",
|
|
@@ -3102,16 +3204,15 @@ function reporterPlugin(options) {
|
|
|
3102
3204
|
order: "post",
|
|
3103
3205
|
handler(_code, id) {
|
|
3104
3206
|
++transformedModules;
|
|
3105
|
-
|
|
3106
|
-
reporter?.update({
|
|
3107
|
-
type: "transform",
|
|
3108
|
-
id,
|
|
3109
|
-
totalModules: unknownTotalModules ? void 0 : totalModules,
|
|
3110
|
-
transformedModules
|
|
3111
|
-
});
|
|
3207
|
+
reportProgress(id);
|
|
3112
3208
|
}
|
|
3113
3209
|
},
|
|
3210
|
+
transformCacheHit(id) {
|
|
3211
|
+
++cacheHitModules;
|
|
3212
|
+
reportProgress(id);
|
|
3213
|
+
},
|
|
3114
3214
|
watchChange(id) {
|
|
3215
|
+
rebuildPending = true;
|
|
3115
3216
|
reporter?.update({
|
|
3116
3217
|
type: "watch_change",
|
|
3117
3218
|
id
|
|
@@ -3480,7 +3581,7 @@ async function runServer(config, options) {
|
|
|
3480
3581
|
}
|
|
3481
3582
|
//#endregion
|
|
3482
3583
|
//#region package.json
|
|
3483
|
-
var version = "1.0.0-alpha.
|
|
3584
|
+
var version = "1.0.0-alpha.22";
|
|
3484
3585
|
//#endregion
|
|
3485
3586
|
//#region src/node/logger.ts
|
|
3486
3587
|
const logger = new Logger("cli");
|
|
@@ -3742,6 +3843,7 @@ function getAgentGuide(baseUrl = defaultBaseUrl) {
|
|
|
3742
3843
|
" Event format:",
|
|
3743
3844
|
" event: <event_type>",
|
|
3744
3845
|
" data: <json_payload>",
|
|
3846
|
+
" bundler-scoped events include bundlerId",
|
|
3745
3847
|
"",
|
|
3746
3848
|
" Useful event types:",
|
|
3747
3849
|
" bundle_build_started, bundle_build_done, bundle_build_failed",
|
|
@@ -3809,6 +3911,7 @@ const action$1 = async function(options) {
|
|
|
3809
3911
|
dev: options.dev,
|
|
3810
3912
|
minify: options.minify,
|
|
3811
3913
|
cache: options.cache,
|
|
3914
|
+
...options.sourcemapOutput ? { sourcemap: true } : {},
|
|
3812
3915
|
outfile: options.bundleOutput,
|
|
3813
3916
|
sourcemapOutfile: options.sourcemapOutput,
|
|
3814
3917
|
assetsDir: options.assetsDest
|