xcode-graph 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +364 -41
- package/custom-elements.json +1418 -537
- package/dist/elk-worker.js +104592 -0
- package/dist/elk.bundled.js +5907 -5981
- package/dist/{assets/micro-layout.worker-CSeqAKhL.js → micro-layout.worker.js} +58 -364
- package/dist/xcode-graph.js +28509 -0
- package/dist/xcode-graph.service.js +4917 -0
- package/dist/xcodegraph.js +1 -22164
- package/package.json +49 -45
- package/vscode.css-custom-data.json +0 -5
- package/vscode.html-custom-data.json +358 -78
- package/web-types.json +918 -202
- package/dist/flow.js +0 -883
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
*/
|
|
9
9
|
/**
|
|
10
10
|
* Node role enum - determines positioning strategy within a cluster
|
|
11
|
+
*
|
|
12
|
+
* @public
|
|
11
13
|
*/
|
|
12
14
|
var NodeRole;
|
|
13
15
|
(function (NodeRole) {
|
|
@@ -20,6 +22,8 @@ var NodeRole;
|
|
|
20
22
|
})(NodeRole || (NodeRole = {}));
|
|
21
23
|
/**
|
|
22
24
|
* Cluster type enum - distinguishes local projects from packages
|
|
25
|
+
*
|
|
26
|
+
* @public
|
|
23
27
|
*/
|
|
24
28
|
var ClusterType;
|
|
25
29
|
(function (ClusterType) {
|
|
@@ -28,6 +32,8 @@ var ClusterType;
|
|
|
28
32
|
})(ClusterType || (ClusterType = {}));
|
|
29
33
|
/**
|
|
30
34
|
* ELK Hierarchy Handling strategy
|
|
35
|
+
*
|
|
36
|
+
* @public
|
|
31
37
|
*/
|
|
32
38
|
var ElkHierarchyHandling;
|
|
33
39
|
(function (ElkHierarchyHandling) {
|
|
@@ -35,12 +41,20 @@ var ElkHierarchyHandling;
|
|
|
35
41
|
ElkHierarchyHandling["IncludeChildren"] = "INCLUDE_CHILDREN";
|
|
36
42
|
ElkHierarchyHandling["SeparateChildren"] = "SEPARATE_CHILDREN";
|
|
37
43
|
})(ElkHierarchyHandling || (ElkHierarchyHandling = {}));
|
|
38
|
-
/**
|
|
44
|
+
/**
|
|
45
|
+
* All node role values for iteration
|
|
46
|
+
*
|
|
47
|
+
* @public
|
|
48
|
+
*/
|
|
39
49
|
Object.values(NodeRole);
|
|
40
|
-
/**
|
|
50
|
+
/**
|
|
51
|
+
* All cluster type values for iteration
|
|
52
|
+
*
|
|
53
|
+
* @public
|
|
54
|
+
*/
|
|
41
55
|
Object.values(ClusterType);
|
|
42
56
|
|
|
43
|
-
function
|
|
57
|
+
function forceCenter(x, y) {
|
|
44
58
|
var nodes, strength = 1;
|
|
45
59
|
|
|
46
60
|
if (x == null) x = 0;
|
|
@@ -1144,6 +1158,12 @@ function forceY(y) {
|
|
|
1144
1158
|
return force;
|
|
1145
1159
|
}
|
|
1146
1160
|
|
|
1161
|
+
/** Node count above which extra congestion padding is applied */
|
|
1162
|
+
const CONGESTION_THRESHOLD = 15;
|
|
1163
|
+
/** Per-node padding multiplier for clusters exceeding CONGESTION_THRESHOLD */
|
|
1164
|
+
const CONGESTION_FACTOR = 2.0;
|
|
1165
|
+
/** Base padding added to every cluster radius (pixels) */
|
|
1166
|
+
const BASE_MICRO_PADDING = 50;
|
|
1147
1167
|
/**
|
|
1148
1168
|
* Role order for dynamic band calculation (center to outside)
|
|
1149
1169
|
*/
|
|
@@ -1156,7 +1176,13 @@ const ROLE_ORDER = [
|
|
|
1156
1176
|
NodeRole.Tool,
|
|
1157
1177
|
];
|
|
1158
1178
|
/**
|
|
1159
|
-
* Compute micro-layout for a single cluster using "Solar System" physics
|
|
1179
|
+
* Compute micro-layout for a single cluster using "Solar System" physics.
|
|
1180
|
+
* Nodes are placed in concentric bands based on their role, with anchors at the center.
|
|
1181
|
+
* Uses D3 force simulation with orbit, collision, center gravity, and charge forces.
|
|
1182
|
+
*
|
|
1183
|
+
* @param cluster - The cluster to compute interior layout for
|
|
1184
|
+
* @param config - Layout configuration with force parameters
|
|
1185
|
+
* @returns Micro layout result with cluster dimensions and relative node positions
|
|
1160
1186
|
*/
|
|
1161
1187
|
function computeClusterInterior(cluster, config) {
|
|
1162
1188
|
const nodes = cluster.nodes;
|
|
@@ -1199,8 +1225,8 @@ function computeClusterInterior(cluster, config) {
|
|
|
1199
1225
|
const nodeSpace = config.nodeRadius * 2 + config.clusterNodeSpacing;
|
|
1200
1226
|
const baseR = n ** 0.6 * nodeSpace * spacingFactor;
|
|
1201
1227
|
// Add extra padding for large clusters
|
|
1202
|
-
const congestionPadding = Math.max(0, n -
|
|
1203
|
-
const padding =
|
|
1228
|
+
const congestionPadding = Math.max(0, n - CONGESTION_THRESHOLD) * CONGESTION_FACTOR;
|
|
1229
|
+
const padding = BASE_MICRO_PADDING + congestionPadding;
|
|
1204
1230
|
const radius = Math.max(config.minClusterSize / 2, baseR + padding);
|
|
1205
1231
|
const size = radius * 2;
|
|
1206
1232
|
// 3. Initialize Simulation Nodes
|
|
@@ -1247,7 +1273,7 @@ function computeClusterInterior(cluster, config) {
|
|
|
1247
1273
|
}
|
|
1248
1274
|
})
|
|
1249
1275
|
// C. Center Gravity (keep things coherent but loose)
|
|
1250
|
-
.force('center',
|
|
1276
|
+
.force('center', forceCenter(0, 0).strength(0.02))
|
|
1251
1277
|
// D. Many Body (stronger repulsion to use available space)
|
|
1252
1278
|
.force('charge', forceManyBody().strength(config.nodeCharge));
|
|
1253
1279
|
// 5. Run Simulation
|
|
@@ -1283,8 +1309,12 @@ function computeClusterInterior(cluster, config) {
|
|
|
1283
1309
|
|
|
1284
1310
|
/**
|
|
1285
1311
|
* Apply a gentle force-directed "massage" to nodes within a cluster.
|
|
1286
|
-
*
|
|
1287
|
-
*
|
|
1312
|
+
* Runs after the main "Solar System" layout to improve spacing and resolve
|
|
1313
|
+
* local congestions while preserving the overall band structure.
|
|
1314
|
+
*
|
|
1315
|
+
* @param micro - Micro layout result from `computeClusterInterior`
|
|
1316
|
+
* @param config - Layout configuration with collision and charge parameters
|
|
1317
|
+
* @returns Updated micro layout with refined node positions and possibly expanded dimensions
|
|
1288
1318
|
*/
|
|
1289
1319
|
function applyNodeMassage(micro, config) {
|
|
1290
1320
|
const nodes = Array.from(micro.relativePositions.values()).map((pos) => ({
|
|
@@ -1319,11 +1349,14 @@ function applyNodeMassage(micro, config) {
|
|
|
1319
1349
|
let minX = Infinity, maxX = -Infinity;
|
|
1320
1350
|
let minY = Infinity, maxY = -Infinity;
|
|
1321
1351
|
for (const node of nodes) {
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1352
|
+
const existingPos = micro.relativePositions.get(node.id);
|
|
1353
|
+
if (existingPos) {
|
|
1354
|
+
newPositions.set(node.id, {
|
|
1355
|
+
...existingPos,
|
|
1356
|
+
x: node.x,
|
|
1357
|
+
y: node.y,
|
|
1358
|
+
});
|
|
1359
|
+
}
|
|
1327
1360
|
if (node.x < minX)
|
|
1328
1361
|
minX = node.x;
|
|
1329
1362
|
if (node.x > maxX)
|
|
@@ -1348,355 +1381,6 @@ function applyNodeMassage(micro, config) {
|
|
|
1348
1381
|
};
|
|
1349
1382
|
}
|
|
1350
1383
|
|
|
1351
|
-
/**
|
|
1352
|
-
* @license
|
|
1353
|
-
* Copyright 2019 Google LLC
|
|
1354
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
1355
|
-
*/
|
|
1356
|
-
const proxyMarker = Symbol("Comlink.proxy");
|
|
1357
|
-
const createEndpoint = Symbol("Comlink.endpoint");
|
|
1358
|
-
const releaseProxy = Symbol("Comlink.releaseProxy");
|
|
1359
|
-
const finalizer = Symbol("Comlink.finalizer");
|
|
1360
|
-
const throwMarker = Symbol("Comlink.thrown");
|
|
1361
|
-
const isObject = (val) => (typeof val === "object" && val !== null) || typeof val === "function";
|
|
1362
|
-
/**
|
|
1363
|
-
* Internal transfer handle to handle objects marked to proxy.
|
|
1364
|
-
*/
|
|
1365
|
-
const proxyTransferHandler = {
|
|
1366
|
-
canHandle: (val) => isObject(val) && val[proxyMarker],
|
|
1367
|
-
serialize(obj) {
|
|
1368
|
-
const { port1, port2 } = new MessageChannel();
|
|
1369
|
-
expose(obj, port1);
|
|
1370
|
-
return [port2, [port2]];
|
|
1371
|
-
},
|
|
1372
|
-
deserialize(port) {
|
|
1373
|
-
port.start();
|
|
1374
|
-
return wrap(port);
|
|
1375
|
-
},
|
|
1376
|
-
};
|
|
1377
|
-
/**
|
|
1378
|
-
* Internal transfer handler to handle thrown exceptions.
|
|
1379
|
-
*/
|
|
1380
|
-
const throwTransferHandler = {
|
|
1381
|
-
canHandle: (value) => isObject(value) && throwMarker in value,
|
|
1382
|
-
serialize({ value }) {
|
|
1383
|
-
let serialized;
|
|
1384
|
-
if (value instanceof Error) {
|
|
1385
|
-
serialized = {
|
|
1386
|
-
isError: true,
|
|
1387
|
-
value: {
|
|
1388
|
-
message: value.message,
|
|
1389
|
-
name: value.name,
|
|
1390
|
-
stack: value.stack,
|
|
1391
|
-
},
|
|
1392
|
-
};
|
|
1393
|
-
}
|
|
1394
|
-
else {
|
|
1395
|
-
serialized = { isError: false, value };
|
|
1396
|
-
}
|
|
1397
|
-
return [serialized, []];
|
|
1398
|
-
},
|
|
1399
|
-
deserialize(serialized) {
|
|
1400
|
-
if (serialized.isError) {
|
|
1401
|
-
throw Object.assign(new Error(serialized.value.message), serialized.value);
|
|
1402
|
-
}
|
|
1403
|
-
throw serialized.value;
|
|
1404
|
-
},
|
|
1405
|
-
};
|
|
1406
|
-
/**
|
|
1407
|
-
* Allows customizing the serialization of certain values.
|
|
1408
|
-
*/
|
|
1409
|
-
const transferHandlers = new Map([
|
|
1410
|
-
["proxy", proxyTransferHandler],
|
|
1411
|
-
["throw", throwTransferHandler],
|
|
1412
|
-
]);
|
|
1413
|
-
function isAllowedOrigin(allowedOrigins, origin) {
|
|
1414
|
-
for (const allowedOrigin of allowedOrigins) {
|
|
1415
|
-
if (origin === allowedOrigin || allowedOrigin === "*") {
|
|
1416
|
-
return true;
|
|
1417
|
-
}
|
|
1418
|
-
if (allowedOrigin instanceof RegExp && allowedOrigin.test(origin)) {
|
|
1419
|
-
return true;
|
|
1420
|
-
}
|
|
1421
|
-
}
|
|
1422
|
-
return false;
|
|
1423
|
-
}
|
|
1424
|
-
function expose(obj, ep = globalThis, allowedOrigins = ["*"]) {
|
|
1425
|
-
ep.addEventListener("message", function callback(ev) {
|
|
1426
|
-
if (!ev || !ev.data) {
|
|
1427
|
-
return;
|
|
1428
|
-
}
|
|
1429
|
-
if (!isAllowedOrigin(allowedOrigins, ev.origin)) {
|
|
1430
|
-
console.warn(`Invalid origin '${ev.origin}' for comlink proxy`);
|
|
1431
|
-
return;
|
|
1432
|
-
}
|
|
1433
|
-
const { id, type, path } = Object.assign({ path: [] }, ev.data);
|
|
1434
|
-
const argumentList = (ev.data.argumentList || []).map(fromWireValue);
|
|
1435
|
-
let returnValue;
|
|
1436
|
-
try {
|
|
1437
|
-
const parent = path.slice(0, -1).reduce((obj, prop) => obj[prop], obj);
|
|
1438
|
-
const rawValue = path.reduce((obj, prop) => obj[prop], obj);
|
|
1439
|
-
switch (type) {
|
|
1440
|
-
case "GET" /* MessageType.GET */:
|
|
1441
|
-
{
|
|
1442
|
-
returnValue = rawValue;
|
|
1443
|
-
}
|
|
1444
|
-
break;
|
|
1445
|
-
case "SET" /* MessageType.SET */:
|
|
1446
|
-
{
|
|
1447
|
-
parent[path.slice(-1)[0]] = fromWireValue(ev.data.value);
|
|
1448
|
-
returnValue = true;
|
|
1449
|
-
}
|
|
1450
|
-
break;
|
|
1451
|
-
case "APPLY" /* MessageType.APPLY */:
|
|
1452
|
-
{
|
|
1453
|
-
returnValue = rawValue.apply(parent, argumentList);
|
|
1454
|
-
}
|
|
1455
|
-
break;
|
|
1456
|
-
case "CONSTRUCT" /* MessageType.CONSTRUCT */:
|
|
1457
|
-
{
|
|
1458
|
-
const value = new rawValue(...argumentList);
|
|
1459
|
-
returnValue = proxy(value);
|
|
1460
|
-
}
|
|
1461
|
-
break;
|
|
1462
|
-
case "ENDPOINT" /* MessageType.ENDPOINT */:
|
|
1463
|
-
{
|
|
1464
|
-
const { port1, port2 } = new MessageChannel();
|
|
1465
|
-
expose(obj, port2);
|
|
1466
|
-
returnValue = transfer(port1, [port1]);
|
|
1467
|
-
}
|
|
1468
|
-
break;
|
|
1469
|
-
case "RELEASE" /* MessageType.RELEASE */:
|
|
1470
|
-
{
|
|
1471
|
-
returnValue = undefined;
|
|
1472
|
-
}
|
|
1473
|
-
break;
|
|
1474
|
-
default:
|
|
1475
|
-
return;
|
|
1476
|
-
}
|
|
1477
|
-
}
|
|
1478
|
-
catch (value) {
|
|
1479
|
-
returnValue = { value, [throwMarker]: 0 };
|
|
1480
|
-
}
|
|
1481
|
-
Promise.resolve(returnValue)
|
|
1482
|
-
.catch((value) => {
|
|
1483
|
-
return { value, [throwMarker]: 0 };
|
|
1484
|
-
})
|
|
1485
|
-
.then((returnValue) => {
|
|
1486
|
-
const [wireValue, transferables] = toWireValue(returnValue);
|
|
1487
|
-
ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);
|
|
1488
|
-
if (type === "RELEASE" /* MessageType.RELEASE */) {
|
|
1489
|
-
// detach and deactive after sending release response above.
|
|
1490
|
-
ep.removeEventListener("message", callback);
|
|
1491
|
-
closeEndPoint(ep);
|
|
1492
|
-
if (finalizer in obj && typeof obj[finalizer] === "function") {
|
|
1493
|
-
obj[finalizer]();
|
|
1494
|
-
}
|
|
1495
|
-
}
|
|
1496
|
-
})
|
|
1497
|
-
.catch((error) => {
|
|
1498
|
-
// Send Serialization Error To Caller
|
|
1499
|
-
const [wireValue, transferables] = toWireValue({
|
|
1500
|
-
value: new TypeError("Unserializable return value"),
|
|
1501
|
-
[throwMarker]: 0,
|
|
1502
|
-
});
|
|
1503
|
-
ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);
|
|
1504
|
-
});
|
|
1505
|
-
});
|
|
1506
|
-
if (ep.start) {
|
|
1507
|
-
ep.start();
|
|
1508
|
-
}
|
|
1509
|
-
}
|
|
1510
|
-
function isMessagePort(endpoint) {
|
|
1511
|
-
return endpoint.constructor.name === "MessagePort";
|
|
1512
|
-
}
|
|
1513
|
-
function closeEndPoint(endpoint) {
|
|
1514
|
-
if (isMessagePort(endpoint))
|
|
1515
|
-
endpoint.close();
|
|
1516
|
-
}
|
|
1517
|
-
function wrap(ep, target) {
|
|
1518
|
-
const pendingListeners = new Map();
|
|
1519
|
-
ep.addEventListener("message", function handleMessage(ev) {
|
|
1520
|
-
const { data } = ev;
|
|
1521
|
-
if (!data || !data.id) {
|
|
1522
|
-
return;
|
|
1523
|
-
}
|
|
1524
|
-
const resolver = pendingListeners.get(data.id);
|
|
1525
|
-
if (!resolver) {
|
|
1526
|
-
return;
|
|
1527
|
-
}
|
|
1528
|
-
try {
|
|
1529
|
-
resolver(data);
|
|
1530
|
-
}
|
|
1531
|
-
finally {
|
|
1532
|
-
pendingListeners.delete(data.id);
|
|
1533
|
-
}
|
|
1534
|
-
});
|
|
1535
|
-
return createProxy(ep, pendingListeners, [], target);
|
|
1536
|
-
}
|
|
1537
|
-
function throwIfProxyReleased(isReleased) {
|
|
1538
|
-
if (isReleased) {
|
|
1539
|
-
throw new Error("Proxy has been released and is not useable");
|
|
1540
|
-
}
|
|
1541
|
-
}
|
|
1542
|
-
function releaseEndpoint(ep) {
|
|
1543
|
-
return requestResponseMessage(ep, new Map(), {
|
|
1544
|
-
type: "RELEASE" /* MessageType.RELEASE */,
|
|
1545
|
-
}).then(() => {
|
|
1546
|
-
closeEndPoint(ep);
|
|
1547
|
-
});
|
|
1548
|
-
}
|
|
1549
|
-
const proxyCounter = new WeakMap();
|
|
1550
|
-
const proxyFinalizers = "FinalizationRegistry" in globalThis &&
|
|
1551
|
-
new FinalizationRegistry((ep) => {
|
|
1552
|
-
const newCount = (proxyCounter.get(ep) || 0) - 1;
|
|
1553
|
-
proxyCounter.set(ep, newCount);
|
|
1554
|
-
if (newCount === 0) {
|
|
1555
|
-
releaseEndpoint(ep);
|
|
1556
|
-
}
|
|
1557
|
-
});
|
|
1558
|
-
function registerProxy(proxy, ep) {
|
|
1559
|
-
const newCount = (proxyCounter.get(ep) || 0) + 1;
|
|
1560
|
-
proxyCounter.set(ep, newCount);
|
|
1561
|
-
if (proxyFinalizers) {
|
|
1562
|
-
proxyFinalizers.register(proxy, ep, proxy);
|
|
1563
|
-
}
|
|
1564
|
-
}
|
|
1565
|
-
function unregisterProxy(proxy) {
|
|
1566
|
-
if (proxyFinalizers) {
|
|
1567
|
-
proxyFinalizers.unregister(proxy);
|
|
1568
|
-
}
|
|
1569
|
-
}
|
|
1570
|
-
function createProxy(ep, pendingListeners, path = [], target = function () { }) {
|
|
1571
|
-
let isProxyReleased = false;
|
|
1572
|
-
const proxy = new Proxy(target, {
|
|
1573
|
-
get(_target, prop) {
|
|
1574
|
-
throwIfProxyReleased(isProxyReleased);
|
|
1575
|
-
if (prop === releaseProxy) {
|
|
1576
|
-
return () => {
|
|
1577
|
-
unregisterProxy(proxy);
|
|
1578
|
-
releaseEndpoint(ep);
|
|
1579
|
-
pendingListeners.clear();
|
|
1580
|
-
isProxyReleased = true;
|
|
1581
|
-
};
|
|
1582
|
-
}
|
|
1583
|
-
if (prop === "then") {
|
|
1584
|
-
if (path.length === 0) {
|
|
1585
|
-
return { then: () => proxy };
|
|
1586
|
-
}
|
|
1587
|
-
const r = requestResponseMessage(ep, pendingListeners, {
|
|
1588
|
-
type: "GET" /* MessageType.GET */,
|
|
1589
|
-
path: path.map((p) => p.toString()),
|
|
1590
|
-
}).then(fromWireValue);
|
|
1591
|
-
return r.then.bind(r);
|
|
1592
|
-
}
|
|
1593
|
-
return createProxy(ep, pendingListeners, [...path, prop]);
|
|
1594
|
-
},
|
|
1595
|
-
set(_target, prop, rawValue) {
|
|
1596
|
-
throwIfProxyReleased(isProxyReleased);
|
|
1597
|
-
// FIXME: ES6 Proxy Handler `set` methods are supposed to return a
|
|
1598
|
-
// boolean. To show good will, we return true asynchronously ¯\_(ツ)_/¯
|
|
1599
|
-
const [value, transferables] = toWireValue(rawValue);
|
|
1600
|
-
return requestResponseMessage(ep, pendingListeners, {
|
|
1601
|
-
type: "SET" /* MessageType.SET */,
|
|
1602
|
-
path: [...path, prop].map((p) => p.toString()),
|
|
1603
|
-
value,
|
|
1604
|
-
}, transferables).then(fromWireValue);
|
|
1605
|
-
},
|
|
1606
|
-
apply(_target, _thisArg, rawArgumentList) {
|
|
1607
|
-
throwIfProxyReleased(isProxyReleased);
|
|
1608
|
-
const last = path[path.length - 1];
|
|
1609
|
-
if (last === createEndpoint) {
|
|
1610
|
-
return requestResponseMessage(ep, pendingListeners, {
|
|
1611
|
-
type: "ENDPOINT" /* MessageType.ENDPOINT */,
|
|
1612
|
-
}).then(fromWireValue);
|
|
1613
|
-
}
|
|
1614
|
-
// We just pretend that `bind()` didn’t happen.
|
|
1615
|
-
if (last === "bind") {
|
|
1616
|
-
return createProxy(ep, pendingListeners, path.slice(0, -1));
|
|
1617
|
-
}
|
|
1618
|
-
const [argumentList, transferables] = processArguments(rawArgumentList);
|
|
1619
|
-
return requestResponseMessage(ep, pendingListeners, {
|
|
1620
|
-
type: "APPLY" /* MessageType.APPLY */,
|
|
1621
|
-
path: path.map((p) => p.toString()),
|
|
1622
|
-
argumentList,
|
|
1623
|
-
}, transferables).then(fromWireValue);
|
|
1624
|
-
},
|
|
1625
|
-
construct(_target, rawArgumentList) {
|
|
1626
|
-
throwIfProxyReleased(isProxyReleased);
|
|
1627
|
-
const [argumentList, transferables] = processArguments(rawArgumentList);
|
|
1628
|
-
return requestResponseMessage(ep, pendingListeners, {
|
|
1629
|
-
type: "CONSTRUCT" /* MessageType.CONSTRUCT */,
|
|
1630
|
-
path: path.map((p) => p.toString()),
|
|
1631
|
-
argumentList,
|
|
1632
|
-
}, transferables).then(fromWireValue);
|
|
1633
|
-
},
|
|
1634
|
-
});
|
|
1635
|
-
registerProxy(proxy, ep);
|
|
1636
|
-
return proxy;
|
|
1637
|
-
}
|
|
1638
|
-
function myFlat(arr) {
|
|
1639
|
-
return Array.prototype.concat.apply([], arr);
|
|
1640
|
-
}
|
|
1641
|
-
function processArguments(argumentList) {
|
|
1642
|
-
const processed = argumentList.map(toWireValue);
|
|
1643
|
-
return [processed.map((v) => v[0]), myFlat(processed.map((v) => v[1]))];
|
|
1644
|
-
}
|
|
1645
|
-
const transferCache = new WeakMap();
|
|
1646
|
-
function transfer(obj, transfers) {
|
|
1647
|
-
transferCache.set(obj, transfers);
|
|
1648
|
-
return obj;
|
|
1649
|
-
}
|
|
1650
|
-
function proxy(obj) {
|
|
1651
|
-
return Object.assign(obj, { [proxyMarker]: true });
|
|
1652
|
-
}
|
|
1653
|
-
function toWireValue(value) {
|
|
1654
|
-
for (const [name, handler] of transferHandlers) {
|
|
1655
|
-
if (handler.canHandle(value)) {
|
|
1656
|
-
const [serializedValue, transferables] = handler.serialize(value);
|
|
1657
|
-
return [
|
|
1658
|
-
{
|
|
1659
|
-
type: "HANDLER" /* WireValueType.HANDLER */,
|
|
1660
|
-
name,
|
|
1661
|
-
value: serializedValue,
|
|
1662
|
-
},
|
|
1663
|
-
transferables,
|
|
1664
|
-
];
|
|
1665
|
-
}
|
|
1666
|
-
}
|
|
1667
|
-
return [
|
|
1668
|
-
{
|
|
1669
|
-
type: "RAW" /* WireValueType.RAW */,
|
|
1670
|
-
value,
|
|
1671
|
-
},
|
|
1672
|
-
transferCache.get(value) || [],
|
|
1673
|
-
];
|
|
1674
|
-
}
|
|
1675
|
-
function fromWireValue(value) {
|
|
1676
|
-
switch (value.type) {
|
|
1677
|
-
case "HANDLER" /* WireValueType.HANDLER */:
|
|
1678
|
-
return transferHandlers.get(value.name).deserialize(value.value);
|
|
1679
|
-
case "RAW" /* WireValueType.RAW */:
|
|
1680
|
-
return value.value;
|
|
1681
|
-
}
|
|
1682
|
-
}
|
|
1683
|
-
function requestResponseMessage(ep, pendingListeners, msg, transfers) {
|
|
1684
|
-
return new Promise((resolve) => {
|
|
1685
|
-
const id = generateUUID();
|
|
1686
|
-
pendingListeners.set(id, resolve);
|
|
1687
|
-
if (ep.start) {
|
|
1688
|
-
ep.start();
|
|
1689
|
-
}
|
|
1690
|
-
ep.postMessage(Object.assign({ id }, msg), transfers);
|
|
1691
|
-
});
|
|
1692
|
-
}
|
|
1693
|
-
function generateUUID() {
|
|
1694
|
-
return new Array(4)
|
|
1695
|
-
.fill(0)
|
|
1696
|
-
.map(() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16))
|
|
1697
|
-
.join("-");
|
|
1698
|
-
}
|
|
1699
|
-
|
|
1700
1384
|
/**
|
|
1701
1385
|
* Micro-Layout Web Worker
|
|
1702
1386
|
*
|
|
@@ -1704,6 +1388,11 @@ function generateUUID() {
|
|
|
1704
1388
|
* off the main thread. Used by parallel-micro.ts to parallelize
|
|
1705
1389
|
* micro-layout computation across multiple workers.
|
|
1706
1390
|
*/
|
|
1391
|
+
/**
|
|
1392
|
+
* Converts a serialized cluster (with arrays) back to the internal Cluster type (with Maps).
|
|
1393
|
+
* @param sc - Serialized cluster received from the main thread
|
|
1394
|
+
* @returns Deserialized Cluster instance
|
|
1395
|
+
*/
|
|
1707
1396
|
function deserializeCluster(sc) {
|
|
1708
1397
|
return {
|
|
1709
1398
|
...sc,
|
|
@@ -1723,4 +1412,9 @@ const workerApi = {
|
|
|
1723
1412
|
};
|
|
1724
1413
|
},
|
|
1725
1414
|
};
|
|
1726
|
-
|
|
1415
|
+
/* v8 ignore start */
|
|
1416
|
+
self.onmessage = (e) => {
|
|
1417
|
+
const result = workerApi.computeMicro(e.data.cluster, e.data.config);
|
|
1418
|
+
self.postMessage(result);
|
|
1419
|
+
};
|
|
1420
|
+
/* v8 ignore stop */
|