@getlimelight/sdk 0.4.5 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +13 -1
- package/dist/index.d.ts +13 -1
- package/dist/index.js +177 -15
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +177 -15
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -231,7 +231,7 @@ var SENSITIVE_HEADERS = [
|
|
|
231
231
|
var LIMELIGHT_WEB_WSS_URL = "wss://api.getlimelight.io";
|
|
232
232
|
var LIMELIGHT_DESKTOP_WSS_URL = "ws://localhost:8484";
|
|
233
233
|
var WS_PATH = "/limelight";
|
|
234
|
-
var SDK_VERSION = true ? "0.
|
|
234
|
+
var SDK_VERSION = true ? "0.5.1" : "test-version";
|
|
235
235
|
var RENDER_THRESHOLDS = {
|
|
236
236
|
HOT_VELOCITY: 5,
|
|
237
237
|
HIGH_RENDER_COUNT: 50,
|
|
@@ -1126,12 +1126,10 @@ var RenderInterceptor = class {
|
|
|
1126
1126
|
}, RENDER_THRESHOLDS.SNAPSHOT_INTERVAL_MS);
|
|
1127
1127
|
this.isSetup = true;
|
|
1128
1128
|
}
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
this.componentIdCounter = 0;
|
|
1134
|
-
}
|
|
1129
|
+
/**
|
|
1130
|
+
* Installs or wraps the React DevTools global hook.
|
|
1131
|
+
* Returns true if successful, false otherwise.
|
|
1132
|
+
*/
|
|
1135
1133
|
installHook() {
|
|
1136
1134
|
const globalObj = typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : null;
|
|
1137
1135
|
if (!globalObj) return false;
|
|
@@ -1144,6 +1142,11 @@ var RenderInterceptor = class {
|
|
|
1144
1142
|
}
|
|
1145
1143
|
return true;
|
|
1146
1144
|
}
|
|
1145
|
+
/**
|
|
1146
|
+
* Wraps an existing React DevTools hook to intercept render events.
|
|
1147
|
+
* Preserves original functionality.
|
|
1148
|
+
* @param hook - The existing React DevTools hook
|
|
1149
|
+
*/
|
|
1147
1150
|
wrapExistingHook(hook) {
|
|
1148
1151
|
this.originalHook = hook;
|
|
1149
1152
|
this.originalOnCommitFiberRoot = hook.onCommitFiberRoot?.bind(hook);
|
|
@@ -1157,6 +1160,11 @@ var RenderInterceptor = class {
|
|
|
1157
1160
|
this.handleCommitFiberUnmount(rendererID, fiber);
|
|
1158
1161
|
};
|
|
1159
1162
|
}
|
|
1163
|
+
/**
|
|
1164
|
+
* Creates a new React DevTools hook to intercept render events.
|
|
1165
|
+
* @param globalObj - The global object (window or global)
|
|
1166
|
+
* @param hookKey - The key for the React DevTools hook
|
|
1167
|
+
*/
|
|
1160
1168
|
createHook(globalObj, hookKey) {
|
|
1161
1169
|
const renderers = /* @__PURE__ */ new Map();
|
|
1162
1170
|
let rendererIdCounter = 0;
|
|
@@ -1179,6 +1187,8 @@ var RenderInterceptor = class {
|
|
|
1179
1187
|
/**
|
|
1180
1188
|
* Handles a fiber root commit - walks tree and ACCUMULATES into profiles.
|
|
1181
1189
|
* Two-pass: first count components, then accumulate with distributed cost.
|
|
1190
|
+
* @param rendererID - The renderer ID
|
|
1191
|
+
* @param root - The fiber root
|
|
1182
1192
|
*/
|
|
1183
1193
|
handleCommitFiberRoot(_rendererID, root) {
|
|
1184
1194
|
this.currentCommitComponents.clear();
|
|
@@ -1194,6 +1204,7 @@ var RenderInterceptor = class {
|
|
|
1194
1204
|
}
|
|
1195
1205
|
/**
|
|
1196
1206
|
* First pass: count rendered components for cost distribution.
|
|
1207
|
+
* @param fiber - The current fiber node
|
|
1197
1208
|
*/
|
|
1198
1209
|
countRenderedComponents(fiber) {
|
|
1199
1210
|
if (!fiber) return;
|
|
@@ -1203,6 +1214,11 @@ var RenderInterceptor = class {
|
|
|
1203
1214
|
this.countRenderedComponents(fiber.child);
|
|
1204
1215
|
this.countRenderedComponents(fiber.sibling);
|
|
1205
1216
|
}
|
|
1217
|
+
/**
|
|
1218
|
+
* Handles a fiber unmount - marks component as unmounted.
|
|
1219
|
+
* @param rendererID - The renderer ID
|
|
1220
|
+
* @param fiber - The fiber being unmounted
|
|
1221
|
+
*/
|
|
1206
1222
|
handleCommitFiberUnmount(_rendererID, fiber) {
|
|
1207
1223
|
if (!this.isUserComponent(fiber)) return;
|
|
1208
1224
|
const componentId = this.fiberToComponentId.get(fiber);
|
|
@@ -1216,6 +1232,9 @@ var RenderInterceptor = class {
|
|
|
1216
1232
|
}
|
|
1217
1233
|
/**
|
|
1218
1234
|
* Walks fiber tree and accumulates render stats into profiles.
|
|
1235
|
+
* @param fiber - The current fiber node
|
|
1236
|
+
* @param parentComponentId - The parent component ID
|
|
1237
|
+
* @param depth - The current depth in the tree
|
|
1219
1238
|
*/
|
|
1220
1239
|
walkFiberTree(fiber, parentComponentId, depth) {
|
|
1221
1240
|
if (!fiber) return;
|
|
@@ -1230,6 +1249,10 @@ var RenderInterceptor = class {
|
|
|
1230
1249
|
}
|
|
1231
1250
|
/**
|
|
1232
1251
|
* Core accumulation logic - this is where we build up the profile.
|
|
1252
|
+
* @param fiber - The current fiber node
|
|
1253
|
+
* @param componentId - The component ID
|
|
1254
|
+
* @param parentComponentId - The parent component ID
|
|
1255
|
+
* @param depth - The current depth in the tree
|
|
1233
1256
|
*/
|
|
1234
1257
|
accumulateRender(fiber, componentId, parentComponentId, depth) {
|
|
1235
1258
|
const now = Date.now();
|
|
@@ -1290,7 +1313,9 @@ var RenderInterceptor = class {
|
|
|
1290
1313
|
this.updateSuspiciousFlag(profile);
|
|
1291
1314
|
}
|
|
1292
1315
|
/**
|
|
1293
|
-
*
|
|
1316
|
+
* Accumulate prop change details into the profile.
|
|
1317
|
+
* @param profile - The component profile
|
|
1318
|
+
* @param changes - The list of prop change details
|
|
1294
1319
|
*/
|
|
1295
1320
|
accumulatePropChanges(profile, changes) {
|
|
1296
1321
|
const stats = profile.propChangeStats;
|
|
@@ -1319,7 +1344,9 @@ var RenderInterceptor = class {
|
|
|
1319
1344
|
}
|
|
1320
1345
|
}
|
|
1321
1346
|
/**
|
|
1322
|
-
*
|
|
1347
|
+
* Build prop change snapshot for emission.
|
|
1348
|
+
* @param profile - The component profile
|
|
1349
|
+
* @returns The prop change snapshot or undefined
|
|
1323
1350
|
*/
|
|
1324
1351
|
buildPropChangeSnapshot(profile) {
|
|
1325
1352
|
const stats = profile.propChangeStats;
|
|
@@ -1337,6 +1364,10 @@ var RenderInterceptor = class {
|
|
|
1337
1364
|
});
|
|
1338
1365
|
return { topChangedProps };
|
|
1339
1366
|
}
|
|
1367
|
+
/**
|
|
1368
|
+
* Updates the suspicious flag based on render velocity and count.
|
|
1369
|
+
* @param profile - The component profile
|
|
1370
|
+
*/
|
|
1340
1371
|
updateSuspiciousFlag(profile) {
|
|
1341
1372
|
const velocity = this.calculateVelocity(profile);
|
|
1342
1373
|
if (velocity > RENDER_THRESHOLDS.HOT_VELOCITY) {
|
|
@@ -1355,6 +1386,8 @@ var RenderInterceptor = class {
|
|
|
1355
1386
|
/**
|
|
1356
1387
|
* Calculates renders per second from velocity window.
|
|
1357
1388
|
* Cheap: just count / window duration, no array operations.
|
|
1389
|
+
* @param profile - The component profile
|
|
1390
|
+
* @returns The calculated velocity
|
|
1358
1391
|
*/
|
|
1359
1392
|
calculateVelocity(profile) {
|
|
1360
1393
|
const now = Date.now();
|
|
@@ -1367,6 +1400,8 @@ var RenderInterceptor = class {
|
|
|
1367
1400
|
}
|
|
1368
1401
|
/**
|
|
1369
1402
|
* Emits a snapshot of all profiles with deltas.
|
|
1403
|
+
* Only emits profiles that have significant changes since last emit.
|
|
1404
|
+
* Also emits unmounts.
|
|
1370
1405
|
*/
|
|
1371
1406
|
emitSnapshot() {
|
|
1372
1407
|
const now = Date.now();
|
|
@@ -1450,7 +1485,11 @@ var RenderInterceptor = class {
|
|
|
1450
1485
|
this.sendMessage(message);
|
|
1451
1486
|
}
|
|
1452
1487
|
/**
|
|
1453
|
-
*
|
|
1488
|
+
* Now returns prop change details when applicable.
|
|
1489
|
+
* Infers the cause of the render by comparing current and previous fiber states.
|
|
1490
|
+
* @param fiber - The current fiber node
|
|
1491
|
+
* @param parentComponentId - The parent component ID
|
|
1492
|
+
* @returns The inferred render cause
|
|
1454
1493
|
*/
|
|
1455
1494
|
inferRenderCause(fiber, parentComponentId) {
|
|
1456
1495
|
const alternate = fiber.alternate;
|
|
@@ -1499,6 +1538,9 @@ var RenderInterceptor = class {
|
|
|
1499
1538
|
/**
|
|
1500
1539
|
* Diff props to find which keys changed and whether it's reference-only.
|
|
1501
1540
|
* This is the key insight generator.
|
|
1541
|
+
* @param prevProps - The previous props
|
|
1542
|
+
* @param nextProps - The next props
|
|
1543
|
+
* @returns List of prop change details
|
|
1502
1544
|
*/
|
|
1503
1545
|
diffProps(prevProps, nextProps) {
|
|
1504
1546
|
if (!prevProps || !nextProps) {
|
|
@@ -1526,8 +1568,11 @@ var RenderInterceptor = class {
|
|
|
1526
1568
|
return changes;
|
|
1527
1569
|
}
|
|
1528
1570
|
/**
|
|
1529
|
-
*
|
|
1571
|
+
* Shallow equality check to determine if a prop is reference-only change.
|
|
1530
1572
|
* We only go one level deep to keep it fast.
|
|
1573
|
+
* @param a - The first value
|
|
1574
|
+
* @param b - The second value
|
|
1575
|
+
* @returns True if shallow equal, false otherwise
|
|
1531
1576
|
*/
|
|
1532
1577
|
isShallowEqual(a, b) {
|
|
1533
1578
|
if (a === b) return true;
|
|
@@ -1554,13 +1599,28 @@ var RenderInterceptor = class {
|
|
|
1554
1599
|
}
|
|
1555
1600
|
return a === b;
|
|
1556
1601
|
}
|
|
1602
|
+
/**
|
|
1603
|
+
* Determines if a fiber represents a user-defined component.
|
|
1604
|
+
* @param fiber - The fiber node
|
|
1605
|
+
* @returns True if user component, false otherwise
|
|
1606
|
+
*/
|
|
1557
1607
|
isUserComponent(fiber) {
|
|
1558
1608
|
const tag = fiber.tag;
|
|
1559
1609
|
return tag === 0 /* FunctionComponent */ || tag === 1 /* ClassComponent */ || tag === 11 /* ForwardRef */ || tag === 14 /* MemoComponent */ || tag === 15 /* SimpleMemoComponent */;
|
|
1560
1610
|
}
|
|
1611
|
+
/**
|
|
1612
|
+
* Determines if a fiber performed work during the commit.
|
|
1613
|
+
* @param fiber - The fiber node
|
|
1614
|
+
* @returns True if performed work, false otherwise
|
|
1615
|
+
*/
|
|
1561
1616
|
didFiberRender(fiber) {
|
|
1562
1617
|
return (fiber.flags & 1 /* PerformedWork */) !== 0;
|
|
1563
1618
|
}
|
|
1619
|
+
/**
|
|
1620
|
+
* Gets or creates a unique component ID for a fiber.
|
|
1621
|
+
* @param fiber - The fiber node
|
|
1622
|
+
* @returns The unique component ID
|
|
1623
|
+
*/
|
|
1564
1624
|
getOrCreateComponentId(fiber) {
|
|
1565
1625
|
let id = this.fiberToComponentId.get(fiber);
|
|
1566
1626
|
if (id) return id;
|
|
@@ -1575,6 +1635,11 @@ var RenderInterceptor = class {
|
|
|
1575
1635
|
this.fiberToComponentId.set(fiber, id);
|
|
1576
1636
|
return id;
|
|
1577
1637
|
}
|
|
1638
|
+
/**
|
|
1639
|
+
* Gets the display name of a component from a fiber.
|
|
1640
|
+
* @param fiber - The fiber node
|
|
1641
|
+
* @returns The component name
|
|
1642
|
+
*/
|
|
1578
1643
|
getComponentName(fiber) {
|
|
1579
1644
|
const type = fiber.type;
|
|
1580
1645
|
if (!type) return "Unknown";
|
|
@@ -1592,6 +1657,11 @@ var RenderInterceptor = class {
|
|
|
1592
1657
|
}
|
|
1593
1658
|
return "Unknown";
|
|
1594
1659
|
}
|
|
1660
|
+
/**
|
|
1661
|
+
* Gets the component type from a fiber.
|
|
1662
|
+
* @param fiber - The fiber node
|
|
1663
|
+
* @returns The component type
|
|
1664
|
+
*/
|
|
1595
1665
|
getComponentType(fiber) {
|
|
1596
1666
|
switch (fiber.tag) {
|
|
1597
1667
|
case 0 /* FunctionComponent */:
|
|
@@ -1625,6 +1695,9 @@ var RenderInterceptor = class {
|
|
|
1625
1695
|
getSuspiciousComponents() {
|
|
1626
1696
|
return Array.from(this.profiles.values()).filter((p) => p.isSuspicious);
|
|
1627
1697
|
}
|
|
1698
|
+
/**
|
|
1699
|
+
* Cleans up and restores original hook behavior.
|
|
1700
|
+
*/
|
|
1628
1701
|
cleanup() {
|
|
1629
1702
|
if (!this.isSetup) return;
|
|
1630
1703
|
this.emitSnapshot();
|
|
@@ -1650,6 +1723,16 @@ var RenderInterceptor = class {
|
|
|
1650
1723
|
this.config = null;
|
|
1651
1724
|
this.isSetup = false;
|
|
1652
1725
|
}
|
|
1726
|
+
/**
|
|
1727
|
+
* Resets all collected profiles
|
|
1728
|
+
*/
|
|
1729
|
+
resetProfiles() {
|
|
1730
|
+
this.profiles.clear();
|
|
1731
|
+
this.fiberToComponentId = /* @__PURE__ */ new WeakMap();
|
|
1732
|
+
this.pendingUnmounts = [];
|
|
1733
|
+
this.currentCommitComponents.clear();
|
|
1734
|
+
this.componentIdCounter = 0;
|
|
1735
|
+
}
|
|
1653
1736
|
};
|
|
1654
1737
|
|
|
1655
1738
|
// src/limelight/interceptors/StateInterceptor.ts
|
|
@@ -1676,7 +1759,9 @@ var StateInterceptor = class {
|
|
|
1676
1759
|
*/
|
|
1677
1760
|
registerStore(name, store) {
|
|
1678
1761
|
if (this.stores.has(name)) {
|
|
1679
|
-
|
|
1762
|
+
if (this.config?.enableInternalLogging) {
|
|
1763
|
+
console.warn(`[Limelight] Store "${name}" already registered`);
|
|
1764
|
+
}
|
|
1680
1765
|
return;
|
|
1681
1766
|
}
|
|
1682
1767
|
const library = this.detectLibrary(store);
|
|
@@ -1686,7 +1771,7 @@ var StateInterceptor = class {
|
|
|
1686
1771
|
);
|
|
1687
1772
|
return;
|
|
1688
1773
|
}
|
|
1689
|
-
const state = this.getState(store
|
|
1774
|
+
const state = this.getState(store);
|
|
1690
1775
|
const initEvent = {
|
|
1691
1776
|
phase: "STATE:INIT" /* INIT */,
|
|
1692
1777
|
sessionId: this.getSessionId(),
|
|
@@ -1703,6 +1788,8 @@ var StateInterceptor = class {
|
|
|
1703
1788
|
}
|
|
1704
1789
|
/**
|
|
1705
1790
|
* Unregister a store and stop listening to changes.
|
|
1791
|
+
* Can be called manually via Limelight.removeStore().
|
|
1792
|
+
* @param name The name of the store to unregister
|
|
1706
1793
|
*/
|
|
1707
1794
|
unregisterStore(name) {
|
|
1708
1795
|
const store = this.stores.get(name);
|
|
@@ -1713,6 +1800,7 @@ var StateInterceptor = class {
|
|
|
1713
1800
|
}
|
|
1714
1801
|
/**
|
|
1715
1802
|
* Emit an event, applying beforeSend hook if configured
|
|
1803
|
+
* @param event The event to emit
|
|
1716
1804
|
*/
|
|
1717
1805
|
emitEvent(event) {
|
|
1718
1806
|
if (this.config?.beforeSend) {
|
|
@@ -1731,6 +1819,8 @@ var StateInterceptor = class {
|
|
|
1731
1819
|
}
|
|
1732
1820
|
/**
|
|
1733
1821
|
* Detect whether a store is Zustand or Redux
|
|
1822
|
+
* @param store The store to inspect
|
|
1823
|
+
* @return StateLibrary or null if unknown
|
|
1734
1824
|
*/
|
|
1735
1825
|
detectLibrary(store) {
|
|
1736
1826
|
if (!store || typeof store !== "function" && typeof store !== "object") {
|
|
@@ -1749,13 +1839,19 @@ var StateInterceptor = class {
|
|
|
1749
1839
|
}
|
|
1750
1840
|
/**
|
|
1751
1841
|
* Get current state from a store
|
|
1842
|
+
* @param store The store to get state from
|
|
1843
|
+
* @return The current state
|
|
1752
1844
|
*/
|
|
1753
|
-
getState(store
|
|
1845
|
+
getState(store) {
|
|
1754
1846
|
const storeAny = store;
|
|
1755
1847
|
return storeAny.getState();
|
|
1756
1848
|
}
|
|
1757
1849
|
/**
|
|
1758
1850
|
* Subscribe to store changes
|
|
1851
|
+
* @param store The store to subscribe to
|
|
1852
|
+
* @param library The detected state library
|
|
1853
|
+
* @param storeName The name of the store
|
|
1854
|
+
* @return Unsubscribe function
|
|
1759
1855
|
*/
|
|
1760
1856
|
subscribe(store, library, storeName) {
|
|
1761
1857
|
const storeAny = store;
|
|
@@ -1767,6 +1863,9 @@ var StateInterceptor = class {
|
|
|
1767
1863
|
}
|
|
1768
1864
|
/**
|
|
1769
1865
|
* Subscribe to Zustand store changes
|
|
1866
|
+
* @param store The Zustand store
|
|
1867
|
+
* @param storeName The name of the store
|
|
1868
|
+
* @return Unsubscribe function
|
|
1770
1869
|
*/
|
|
1771
1870
|
subscribeZustand(store, storeName) {
|
|
1772
1871
|
return store.subscribe((state, prevState) => {
|
|
@@ -1789,6 +1888,9 @@ var StateInterceptor = class {
|
|
|
1789
1888
|
}
|
|
1790
1889
|
/**
|
|
1791
1890
|
* Subscribe to Redux store changes
|
|
1891
|
+
* @param store The Redux store
|
|
1892
|
+
* @param storeName The name of the store
|
|
1893
|
+
* @return Unsubscribe function
|
|
1792
1894
|
*/
|
|
1793
1895
|
subscribeRedux(store, storeName) {
|
|
1794
1896
|
let lastAction = { type: "@@INIT" };
|
|
@@ -1824,6 +1926,9 @@ var StateInterceptor = class {
|
|
|
1824
1926
|
}
|
|
1825
1927
|
/**
|
|
1826
1928
|
* Infer action name from stack trace for Zustand
|
|
1929
|
+
* @param state The new state
|
|
1930
|
+
* @param prevState The previous state
|
|
1931
|
+
* @return Inferred StateAction
|
|
1827
1932
|
*/
|
|
1828
1933
|
inferZustandAction(state, prevState) {
|
|
1829
1934
|
const actionType = this.parseActionFromStack(this.captureStackTrace());
|
|
@@ -1835,6 +1940,8 @@ var StateInterceptor = class {
|
|
|
1835
1940
|
}
|
|
1836
1941
|
/**
|
|
1837
1942
|
* Parse function name from stack trace
|
|
1943
|
+
* @param stack The stack trace string
|
|
1944
|
+
* @return The inferred action name
|
|
1838
1945
|
*/
|
|
1839
1946
|
parseActionFromStack(stack) {
|
|
1840
1947
|
if (!stack) return "set";
|
|
@@ -1865,6 +1972,9 @@ var StateInterceptor = class {
|
|
|
1865
1972
|
}
|
|
1866
1973
|
/**
|
|
1867
1974
|
* Compute what keys changed between states (shallow)
|
|
1975
|
+
* @param state The new state
|
|
1976
|
+
* @param prevState The previous state
|
|
1977
|
+
* @return Partial state with only changed keys
|
|
1868
1978
|
*/
|
|
1869
1979
|
computePartialState(state, prevState) {
|
|
1870
1980
|
if (typeof state !== "object" || state === null || typeof prevState !== "object" || prevState === null) {
|
|
@@ -1905,7 +2015,7 @@ var StateInterceptor = class {
|
|
|
1905
2015
|
}
|
|
1906
2016
|
};
|
|
1907
2017
|
|
|
1908
|
-
// src/limelight/
|
|
2018
|
+
// src/limelight/bridges/RequestBridge.ts
|
|
1909
2019
|
var RequestBridge = class {
|
|
1910
2020
|
constructor(sendMessage, getSessionId) {
|
|
1911
2021
|
this.sendMessage = sendMessage;
|
|
@@ -2072,6 +2182,42 @@ var RequestBridge = class {
|
|
|
2072
2182
|
}
|
|
2073
2183
|
};
|
|
2074
2184
|
|
|
2185
|
+
// src/limelight/handlers/CommandHandler.ts
|
|
2186
|
+
var CommandHandler = class {
|
|
2187
|
+
constructor(interceptors, sendMessage, getConfig) {
|
|
2188
|
+
this.interceptors = interceptors;
|
|
2189
|
+
this.sendMessage = sendMessage;
|
|
2190
|
+
this.getConfig = getConfig;
|
|
2191
|
+
}
|
|
2192
|
+
/**
|
|
2193
|
+
* Handles an incoming command.
|
|
2194
|
+
* @param command - The command to handle
|
|
2195
|
+
*/
|
|
2196
|
+
handle(command) {
|
|
2197
|
+
const config = this.getConfig();
|
|
2198
|
+
if (config?.enableInternalLogging) {
|
|
2199
|
+
console.log("[Limelight] Received command:", command.type);
|
|
2200
|
+
}
|
|
2201
|
+
switch (command.type) {
|
|
2202
|
+
case "CLEAR_RENDERS" /* CLEAR_RENDERS */:
|
|
2203
|
+
this.interceptors.render.resetProfiles();
|
|
2204
|
+
break;
|
|
2205
|
+
default:
|
|
2206
|
+
if (config?.enableInternalLogging) {
|
|
2207
|
+
console.warn("[Limelight] Unknown command:", command.type);
|
|
2208
|
+
}
|
|
2209
|
+
}
|
|
2210
|
+
if (command.id) {
|
|
2211
|
+
this.sendMessage({
|
|
2212
|
+
phase: "ACK" /* ACK */,
|
|
2213
|
+
commandId: command.id,
|
|
2214
|
+
type: command.type,
|
|
2215
|
+
success: true
|
|
2216
|
+
});
|
|
2217
|
+
}
|
|
2218
|
+
}
|
|
2219
|
+
};
|
|
2220
|
+
|
|
2075
2221
|
// src/limelight/LimelightClient.ts
|
|
2076
2222
|
var LimelightClient = class {
|
|
2077
2223
|
ws = null;
|
|
@@ -2089,6 +2235,7 @@ var LimelightClient = class {
|
|
|
2089
2235
|
renderInterceptor;
|
|
2090
2236
|
stateInterceptor;
|
|
2091
2237
|
requestBridge;
|
|
2238
|
+
commandHandler = null;
|
|
2092
2239
|
constructor() {
|
|
2093
2240
|
this.networkInterceptor = new NetworkInterceptor(
|
|
2094
2241
|
this.sendMessage.bind(this),
|
|
@@ -2114,6 +2261,11 @@ var LimelightClient = class {
|
|
|
2114
2261
|
this.sendMessage.bind(this),
|
|
2115
2262
|
() => this.sessionId
|
|
2116
2263
|
);
|
|
2264
|
+
this.commandHandler = new CommandHandler(
|
|
2265
|
+
{ render: this.renderInterceptor },
|
|
2266
|
+
this.sendMessage.bind(this),
|
|
2267
|
+
() => this.config
|
|
2268
|
+
);
|
|
2117
2269
|
}
|
|
2118
2270
|
/**
|
|
2119
2271
|
* Configures the Limelight client with the provided settings.
|
|
@@ -2220,6 +2372,16 @@ var LimelightClient = class {
|
|
|
2220
2372
|
this.flushMessageQueue();
|
|
2221
2373
|
this.sendMessage(message);
|
|
2222
2374
|
};
|
|
2375
|
+
this.ws.onmessage = (event) => {
|
|
2376
|
+
try {
|
|
2377
|
+
const command = JSON.parse(event.data);
|
|
2378
|
+
this.commandHandler?.handle(command);
|
|
2379
|
+
} catch (error) {
|
|
2380
|
+
if (this.config?.enableInternalLogging) {
|
|
2381
|
+
console.error("[Limelight] Failed to parse command:", error);
|
|
2382
|
+
}
|
|
2383
|
+
}
|
|
2384
|
+
};
|
|
2223
2385
|
this.ws.onerror = (error) => {
|
|
2224
2386
|
if (this.config?.enableInternalLogging) {
|
|
2225
2387
|
console.error("[Limelight] WebSocket error:", error);
|