@reactor-team/js-sdk 1.0.16 → 1.0.17

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 CHANGED
@@ -169,6 +169,12 @@ interface ReactorViewProps {
169
169
  }
170
170
  declare function ReactorView({ width, height, className, style, videoObjectFit, }: ReactorViewProps): react_jsx_runtime.JSX.Element;
171
171
 
172
+ interface ReactorControllerProps {
173
+ className?: string;
174
+ style?: React.CSSProperties;
175
+ }
176
+ declare function ReactorController({ className, style, }: ReactorControllerProps): react_jsx_runtime.JSX.Element;
177
+
172
178
  interface Props {
173
179
  className?: string;
174
180
  style?: React.CSSProperties;
@@ -192,4 +198,4 @@ declare function useReactor<T>(selector: (state: ReactorStore) => T): T;
192
198
  */
193
199
  declare function useReactorMessage(handler: (message: any) => void): void;
194
200
 
195
- export { type Options, Reactor, type ReactorError, type ReactorEvent, ReactorProvider, type ReactorSessionExpiration, type ReactorState$1 as ReactorState, type ReactorStatus, ReactorView, type ReactorViewProps, type ReactorWaitingInfo, WebcamStream, useReactor, useReactorMessage, useReactorStore };
201
+ export { type Options, Reactor, ReactorController, type ReactorControllerProps, type ReactorError, type ReactorEvent, ReactorProvider, type ReactorSessionExpiration, type ReactorState$1 as ReactorState, type ReactorStatus, ReactorView, type ReactorViewProps, type ReactorWaitingInfo, WebcamStream, useReactor, useReactorMessage, useReactorStore };
package/dist/index.d.ts CHANGED
@@ -169,6 +169,12 @@ interface ReactorViewProps {
169
169
  }
170
170
  declare function ReactorView({ width, height, className, style, videoObjectFit, }: ReactorViewProps): react_jsx_runtime.JSX.Element;
171
171
 
172
+ interface ReactorControllerProps {
173
+ className?: string;
174
+ style?: React.CSSProperties;
175
+ }
176
+ declare function ReactorController({ className, style, }: ReactorControllerProps): react_jsx_runtime.JSX.Element;
177
+
172
178
  interface Props {
173
179
  className?: string;
174
180
  style?: React.CSSProperties;
@@ -192,4 +198,4 @@ declare function useReactor<T>(selector: (state: ReactorStore) => T): T;
192
198
  */
193
199
  declare function useReactorMessage(handler: (message: any) => void): void;
194
200
 
195
- export { type Options, Reactor, type ReactorError, type ReactorEvent, ReactorProvider, type ReactorSessionExpiration, type ReactorState$1 as ReactorState, type ReactorStatus, ReactorView, type ReactorViewProps, type ReactorWaitingInfo, WebcamStream, useReactor, useReactorMessage, useReactorStore };
201
+ export { type Options, Reactor, ReactorController, type ReactorControllerProps, type ReactorError, type ReactorEvent, ReactorProvider, type ReactorSessionExpiration, type ReactorState$1 as ReactorState, type ReactorStatus, ReactorView, type ReactorViewProps, type ReactorWaitingInfo, WebcamStream, useReactor, useReactorMessage, useReactorStore };
package/dist/index.js CHANGED
@@ -1,10 +1,12 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __defProps = Object.defineProperties;
4
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
6
  var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
6
7
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
8
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
9
+ var __getProtoOf = Object.getPrototypeOf;
8
10
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
11
  var __propIsEnum = Object.prototype.propertyIsEnumerable;
10
12
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -44,6 +46,14 @@ var __copyProps = (to, from, except, desc) => {
44
46
  }
45
47
  return to;
46
48
  };
49
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
50
+ // If the importer is in node compatibility mode or this is not an ESM
51
+ // file that has been converted to a CommonJS file using a Babel-
52
+ // compatible transform (i.e. "__esModule" has not been set), then set
53
+ // "default" to the CommonJS "module.exports" for node compatibility.
54
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
55
+ mod
56
+ ));
47
57
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
48
58
  var __async = (__this, __arguments, generator) => {
49
59
  return new Promise((resolve, reject) => {
@@ -70,6 +80,7 @@ var __async = (__this, __arguments, generator) => {
70
80
  var index_exports = {};
71
81
  __export(index_exports, {
72
82
  Reactor: () => Reactor,
83
+ ReactorController: () => ReactorController,
73
84
  ReactorProvider: () => ReactorProvider,
74
85
  ReactorView: () => ReactorView,
75
86
  WebcamStream: () => WebcamStream,
@@ -1321,9 +1332,454 @@ function ReactorView({
1321
1332
  );
1322
1333
  }
1323
1334
 
1324
- // src/react/WebcamStream.tsx
1325
- var import_react6 = require("react");
1335
+ // src/react/ReactorController.tsx
1336
+ var import_react6 = __toESM(require("react"));
1326
1337
  var import_jsx_runtime3 = require("react/jsx-runtime");
1338
+ function ReactorController({
1339
+ className,
1340
+ style
1341
+ }) {
1342
+ const { sendMessage, status } = useReactor((state) => ({
1343
+ sendMessage: state.sendMessage,
1344
+ status: state.status
1345
+ }));
1346
+ const [commands, setCommands] = (0, import_react6.useState)({});
1347
+ const [formValues, setFormValues] = (0, import_react6.useState)({});
1348
+ const [expandedCommands, setExpandedCommands] = (0, import_react6.useState)({});
1349
+ import_react6.default.useEffect(() => {
1350
+ if (status === "disconnected") {
1351
+ setCommands({});
1352
+ setFormValues({});
1353
+ setExpandedCommands({});
1354
+ }
1355
+ }, [status]);
1356
+ import_react6.default.useEffect(() => {
1357
+ if (status === "ready") {
1358
+ sendMessage({
1359
+ type: "requestCapabilities",
1360
+ data: {}
1361
+ });
1362
+ }
1363
+ }, [status, sendMessage]);
1364
+ useReactorMessage((message) => {
1365
+ if (message && typeof message === "object" && "commands" in message) {
1366
+ const commandsMessage = message;
1367
+ setCommands(commandsMessage.commands);
1368
+ const initialValues = {};
1369
+ const initialExpanded = {};
1370
+ Object.entries(commandsMessage.commands).forEach(
1371
+ ([commandName, commandSchema]) => {
1372
+ initialValues[commandName] = {};
1373
+ initialExpanded[commandName] = false;
1374
+ Object.entries(commandSchema.schema).forEach(
1375
+ ([paramName, paramSchema]) => {
1376
+ var _a, _b;
1377
+ if (paramSchema.type === "number") {
1378
+ initialValues[commandName][paramName] = (_a = paramSchema.minimum) != null ? _a : 0;
1379
+ } else if (paramSchema.type === "string") {
1380
+ initialValues[commandName][paramName] = "";
1381
+ } else if (paramSchema.type === "boolean") {
1382
+ initialValues[commandName][paramName] = false;
1383
+ } else if (paramSchema.type === "integer") {
1384
+ initialValues[commandName][paramName] = (_b = paramSchema.minimum) != null ? _b : 0;
1385
+ }
1386
+ }
1387
+ );
1388
+ }
1389
+ );
1390
+ setFormValues(initialValues);
1391
+ setExpandedCommands(initialExpanded);
1392
+ }
1393
+ });
1394
+ const handleInputChange = (0, import_react6.useCallback)(
1395
+ (commandName, paramName, value) => {
1396
+ setFormValues((prev) => __spreadProps(__spreadValues({}, prev), {
1397
+ [commandName]: __spreadProps(__spreadValues({}, prev[commandName]), {
1398
+ [paramName]: value
1399
+ })
1400
+ }));
1401
+ },
1402
+ []
1403
+ );
1404
+ const toggleCommandExpanded = (0, import_react6.useCallback)((commandName) => {
1405
+ setExpandedCommands((prev) => __spreadProps(__spreadValues({}, prev), {
1406
+ [commandName]: !prev[commandName]
1407
+ }));
1408
+ }, []);
1409
+ const handleCommandSubmit = (0, import_react6.useCallback)(
1410
+ (commandName) => __async(null, null, function* () {
1411
+ const commandSchema = commands[commandName];
1412
+ const formData = formValues[commandName] || {};
1413
+ const data = {};
1414
+ Object.keys(commandSchema.schema).forEach((paramName) => {
1415
+ var _a, _b;
1416
+ const paramSchema = commandSchema.schema[paramName];
1417
+ let value = formData[paramName];
1418
+ if (paramSchema.type === "number" && typeof value === "string") {
1419
+ value = parseFloat(value) || 0;
1420
+ } else if (paramSchema.type === "integer" && typeof value === "string") {
1421
+ value = parseInt(value) || 0;
1422
+ } else if (paramSchema.type === "boolean" && typeof value !== "boolean") {
1423
+ value = Boolean(value);
1424
+ }
1425
+ if (value !== void 0 && value !== "" && value !== null) {
1426
+ data[paramName] = value;
1427
+ } else if (paramSchema.required) {
1428
+ if (paramSchema.type === "number") {
1429
+ data[paramName] = (_a = paramSchema.minimum) != null ? _a : 0;
1430
+ } else if (paramSchema.type === "integer") {
1431
+ data[paramName] = (_b = paramSchema.minimum) != null ? _b : 0;
1432
+ } else if (paramSchema.type === "string") {
1433
+ data[paramName] = "";
1434
+ } else if (paramSchema.type === "boolean") {
1435
+ data[paramName] = false;
1436
+ }
1437
+ }
1438
+ });
1439
+ console.log(`Executing command: ${commandName}`, data);
1440
+ yield sendMessage({
1441
+ type: commandName,
1442
+ data
1443
+ });
1444
+ }),
1445
+ [formValues, sendMessage, commands]
1446
+ );
1447
+ const renderInput = (commandName, paramName, paramSchema) => {
1448
+ var _a, _b;
1449
+ const value = (_b = (_a = formValues[commandName]) == null ? void 0 : _a[paramName]) != null ? _b : "";
1450
+ if (paramSchema.type === "number" || paramSchema.type === "integer") {
1451
+ const isInteger = paramSchema.type === "integer";
1452
+ const step = isInteger ? 1 : 0.1;
1453
+ const parseValue = isInteger ? parseInt : parseFloat;
1454
+ if (typeof paramSchema.minimum === "number" && typeof paramSchema.maximum === "number") {
1455
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { marginBottom: "8px" }, children: [
1456
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1457
+ "label",
1458
+ {
1459
+ style: { fontSize: "12px", color: "#666", display: "block" },
1460
+ children: [
1461
+ paramName,
1462
+ " (",
1463
+ paramSchema.minimum,
1464
+ " - ",
1465
+ paramSchema.maximum,
1466
+ ")",
1467
+ paramSchema.description && ` - ${paramSchema.description}`,
1468
+ paramSchema.required && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { color: "red" }, children: " *" })
1469
+ ]
1470
+ }
1471
+ ),
1472
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1473
+ "input",
1474
+ {
1475
+ type: "range",
1476
+ min: paramSchema.minimum,
1477
+ max: paramSchema.maximum,
1478
+ step,
1479
+ value,
1480
+ onChange: (e) => {
1481
+ const newValue = parseValue(e.target.value) || 0;
1482
+ handleInputChange(commandName, paramName, newValue);
1483
+ handleCommandSubmit(commandName);
1484
+ },
1485
+ style: { width: "100%", marginBottom: "4px" }
1486
+ }
1487
+ ),
1488
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { fontSize: "11px", color: "#888" }, children: [
1489
+ "Value: ",
1490
+ value
1491
+ ] })
1492
+ ] });
1493
+ } else {
1494
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { marginBottom: "8px" }, children: [
1495
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1496
+ "label",
1497
+ {
1498
+ style: { fontSize: "12px", color: "#666", display: "block" },
1499
+ children: [
1500
+ paramName,
1501
+ paramSchema.description && ` - ${paramSchema.description}`,
1502
+ paramSchema.required && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { color: "red" }, children: " *" })
1503
+ ]
1504
+ }
1505
+ ),
1506
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1507
+ "input",
1508
+ {
1509
+ type: "number",
1510
+ value,
1511
+ min: paramSchema.minimum,
1512
+ max: paramSchema.maximum,
1513
+ step,
1514
+ inputMode: "numeric",
1515
+ onChange: (e) => {
1516
+ const val = e.target.value;
1517
+ if (val === "" || val === "-") {
1518
+ handleInputChange(commandName, paramName, val);
1519
+ } else {
1520
+ const parsed = parseValue(val);
1521
+ if (!isNaN(parsed)) {
1522
+ handleInputChange(commandName, paramName, parsed);
1523
+ }
1524
+ }
1525
+ },
1526
+ onBlur: (e) => {
1527
+ const val = e.target.value;
1528
+ if (val === "" || val === "-") {
1529
+ handleInputChange(commandName, paramName, 0);
1530
+ }
1531
+ },
1532
+ style: {
1533
+ width: "100%",
1534
+ padding: "4px",
1535
+ fontSize: "12px",
1536
+ border: "1px solid #ccc",
1537
+ borderRadius: "2px"
1538
+ }
1539
+ }
1540
+ )
1541
+ ] });
1542
+ }
1543
+ } else if (paramSchema.type === "string") {
1544
+ if (paramSchema.enum) {
1545
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { marginBottom: "8px" }, children: [
1546
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1547
+ "label",
1548
+ {
1549
+ style: { fontSize: "12px", color: "#666", display: "block" },
1550
+ children: [
1551
+ paramName,
1552
+ paramSchema.description && ` - ${paramSchema.description}`,
1553
+ paramSchema.required && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { color: "red" }, children: " *" })
1554
+ ]
1555
+ }
1556
+ ),
1557
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1558
+ "select",
1559
+ {
1560
+ value,
1561
+ onChange: (e) => handleInputChange(commandName, paramName, e.target.value),
1562
+ style: {
1563
+ width: "100%",
1564
+ padding: "4px",
1565
+ fontSize: "12px",
1566
+ border: "1px solid #ccc",
1567
+ borderRadius: "2px"
1568
+ },
1569
+ children: [
1570
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "", children: "Select..." }),
1571
+ paramSchema.enum.map((option) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: option, children: option }, option))
1572
+ ]
1573
+ }
1574
+ )
1575
+ ] });
1576
+ } else {
1577
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { marginBottom: "8px" }, children: [
1578
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1579
+ "label",
1580
+ {
1581
+ style: { fontSize: "12px", color: "#666", display: "block" },
1582
+ children: [
1583
+ paramName,
1584
+ paramSchema.description && ` - ${paramSchema.description}`,
1585
+ paramSchema.required && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { color: "red" }, children: " *" })
1586
+ ]
1587
+ }
1588
+ ),
1589
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1590
+ "input",
1591
+ {
1592
+ type: "text",
1593
+ value,
1594
+ onChange: (e) => handleInputChange(commandName, paramName, e.target.value),
1595
+ style: {
1596
+ width: "100%",
1597
+ padding: "4px",
1598
+ fontSize: "12px",
1599
+ border: "1px solid #ccc",
1600
+ borderRadius: "2px"
1601
+ }
1602
+ }
1603
+ )
1604
+ ] });
1605
+ }
1606
+ } else if (paramSchema.type === "boolean") {
1607
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { marginBottom: "8px" }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1608
+ "label",
1609
+ {
1610
+ style: {
1611
+ fontSize: "12px",
1612
+ color: "#666",
1613
+ display: "flex",
1614
+ alignItems: "center"
1615
+ },
1616
+ children: [
1617
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1618
+ "input",
1619
+ {
1620
+ type: "checkbox",
1621
+ checked: value,
1622
+ onChange: (e) => handleInputChange(commandName, paramName, e.target.checked),
1623
+ style: { marginRight: "6px" }
1624
+ }
1625
+ ),
1626
+ paramName,
1627
+ paramSchema.description && ` - ${paramSchema.description}`,
1628
+ paramSchema.required && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { color: "red" }, children: " *" })
1629
+ ]
1630
+ }
1631
+ ) });
1632
+ }
1633
+ return null;
1634
+ };
1635
+ const renderCommand = (commandName, commandSchema) => {
1636
+ const hasParams = Object.keys(commandSchema.schema).length > 0;
1637
+ const isExpanded = expandedCommands[commandName];
1638
+ const hasSliderInputs = Object.values(commandSchema.schema).some(
1639
+ (paramSchema) => (paramSchema.type === "number" || paramSchema.type === "integer") && typeof paramSchema.minimum === "number" && typeof paramSchema.maximum === "number"
1640
+ );
1641
+ const showExecuteButton = !hasSliderInputs;
1642
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1643
+ "div",
1644
+ {
1645
+ style: {
1646
+ border: "1px solid #ddd",
1647
+ borderRadius: "4px",
1648
+ marginBottom: "8px",
1649
+ backgroundColor: "#fafafa"
1650
+ },
1651
+ children: [
1652
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1653
+ "div",
1654
+ {
1655
+ onClick: () => toggleCommandExpanded(commandName),
1656
+ style: {
1657
+ padding: "8px 12px",
1658
+ cursor: "pointer",
1659
+ borderBottom: isExpanded ? "1px solid #ddd" : "none",
1660
+ display: "flex",
1661
+ justifyContent: "space-between",
1662
+ alignItems: "center"
1663
+ },
1664
+ children: [
1665
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
1666
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1667
+ "h4",
1668
+ {
1669
+ style: {
1670
+ margin: "0",
1671
+ fontSize: "13px",
1672
+ fontWeight: "bold"
1673
+ },
1674
+ children: commandName
1675
+ }
1676
+ ),
1677
+ isExpanded && commandSchema.description && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1678
+ "p",
1679
+ {
1680
+ style: { margin: "4px 0 0 0", fontSize: "11px", color: "#666" },
1681
+ children: commandSchema.description
1682
+ }
1683
+ )
1684
+ ] }),
1685
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1686
+ "div",
1687
+ {
1688
+ style: {
1689
+ fontSize: "10px",
1690
+ color: "#999",
1691
+ transform: isExpanded ? "rotate(180deg)" : "rotate(0deg)",
1692
+ transition: "transform 0.2s"
1693
+ },
1694
+ children: "\u25BC"
1695
+ }
1696
+ )
1697
+ ]
1698
+ }
1699
+ ),
1700
+ isExpanded && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { padding: "12px", paddingTop: "0" }, children: [
1701
+ hasParams && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { marginBottom: showExecuteButton ? "12px" : "0" }, children: [
1702
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1703
+ "div",
1704
+ {
1705
+ style: {
1706
+ marginBottom: "8px",
1707
+ fontSize: "12px",
1708
+ fontWeight: "bold",
1709
+ color: "#555"
1710
+ },
1711
+ children: "Parameters:"
1712
+ }
1713
+ ),
1714
+ Object.entries(commandSchema.schema).map(
1715
+ ([paramName, paramSchema]) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1716
+ "div",
1717
+ {
1718
+ style: { marginLeft: "8px" },
1719
+ children: renderInput(commandName, paramName, paramSchema)
1720
+ },
1721
+ `${commandName}-${paramName}`
1722
+ )
1723
+ )
1724
+ ] }),
1725
+ !hasParams && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1726
+ "div",
1727
+ {
1728
+ style: {
1729
+ marginBottom: showExecuteButton ? "12px" : "0",
1730
+ marginTop: "2px",
1731
+ fontSize: "11px",
1732
+ color: "#666",
1733
+ fontStyle: "italic"
1734
+ },
1735
+ children: "No parameters required"
1736
+ }
1737
+ ),
1738
+ showExecuteButton && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1739
+ "button",
1740
+ {
1741
+ onClick: () => handleCommandSubmit(commandName),
1742
+ style: {
1743
+ padding: "8px 16px",
1744
+ fontSize: "12px",
1745
+ backgroundColor: "#007bff",
1746
+ color: "white",
1747
+ border: "none",
1748
+ borderRadius: "4px",
1749
+ cursor: "pointer",
1750
+ fontWeight: "bold"
1751
+ },
1752
+ children: [
1753
+ "Execute ",
1754
+ commandName
1755
+ ]
1756
+ }
1757
+ )
1758
+ ] })
1759
+ ]
1760
+ },
1761
+ commandName
1762
+ );
1763
+ };
1764
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className, style, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { fontFamily: "monospace", fontSize: "12px" }, children: Object.keys(commands).length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { padding: "12px", color: "#666", fontStyle: "italic" }, children: "Waiting for commands schema..." }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { children: [
1765
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1766
+ "h3",
1767
+ {
1768
+ style: {
1769
+ margin: "0 0 16px 0",
1770
+ fontSize: "16px",
1771
+ fontWeight: "bold"
1772
+ },
1773
+ children: "Reactor Commands"
1774
+ }
1775
+ ),
1776
+ Object.entries(commands).map(([commandName, commandSchema]) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { children: renderCommand(commandName, commandSchema) }, commandName))
1777
+ ] }) }) });
1778
+ }
1779
+
1780
+ // src/react/WebcamStream.tsx
1781
+ var import_react7 = require("react");
1782
+ var import_jsx_runtime4 = require("react/jsx-runtime");
1327
1783
  function WebcamStream({
1328
1784
  className,
1329
1785
  style,
@@ -1334,16 +1790,16 @@ function WebcamStream({
1334
1790
  showWebcam = true,
1335
1791
  videoObjectFit = "contain"
1336
1792
  }) {
1337
- const [stream, setStream] = (0, import_react6.useState)(null);
1338
- const [isPublishing, setIsPublishing] = (0, import_react6.useState)(false);
1339
- const [permissionDenied, setPermissionDenied] = (0, import_react6.useState)(false);
1793
+ const [stream, setStream] = (0, import_react7.useState)(null);
1794
+ const [isPublishing, setIsPublishing] = (0, import_react7.useState)(false);
1795
+ const [permissionDenied, setPermissionDenied] = (0, import_react7.useState)(false);
1340
1796
  const { status, publishVideoStream, unpublishVideoStream, reactor } = useReactor((state) => ({
1341
1797
  status: state.status,
1342
1798
  publishVideoStream: state.publishVideoStream,
1343
1799
  unpublishVideoStream: state.unpublishVideoStream,
1344
1800
  reactor: state.internal.reactor
1345
1801
  }));
1346
- const videoRef = (0, import_react6.useRef)(null);
1802
+ const videoRef = (0, import_react7.useRef)(null);
1347
1803
  const startWebcam = () => __async(null, null, function* () {
1348
1804
  console.debug("[WebcamPublisher] Starting webcam");
1349
1805
  try {
@@ -1378,7 +1834,7 @@ function WebcamStream({
1378
1834
  setStream(null);
1379
1835
  console.debug("[WebcamPublisher] Webcam stopped");
1380
1836
  });
1381
- (0, import_react6.useEffect)(() => {
1837
+ (0, import_react7.useEffect)(() => {
1382
1838
  console.debug("[WebcamPublisher] Stream effect triggered", {
1383
1839
  hasVideoElement: !!videoRef.current,
1384
1840
  hasStream: !!stream
@@ -1395,7 +1851,7 @@ function WebcamStream({
1395
1851
  videoRef.current.srcObject = null;
1396
1852
  }
1397
1853
  }, [stream]);
1398
- (0, import_react6.useEffect)(() => {
1854
+ (0, import_react7.useEffect)(() => {
1399
1855
  if (!stream) {
1400
1856
  return;
1401
1857
  }
@@ -1419,7 +1875,7 @@ function WebcamStream({
1419
1875
  });
1420
1876
  }
1421
1877
  }, [status, stream, isPublishing, publishVideoStream, unpublishVideoStream]);
1422
- (0, import_react6.useEffect)(() => {
1878
+ (0, import_react7.useEffect)(() => {
1423
1879
  const handleError = (error) => {
1424
1880
  console.debug("[WebcamPublisher] Received error event:", error);
1425
1881
  if (error.code === "VIDEO_PUBLISH_FAILED") {
@@ -1434,7 +1890,7 @@ function WebcamStream({
1434
1890
  reactor.off("error", handleError);
1435
1891
  };
1436
1892
  }, [reactor]);
1437
- (0, import_react6.useEffect)(() => {
1893
+ (0, import_react7.useEffect)(() => {
1438
1894
  if (status !== "ready") {
1439
1895
  console.debug(
1440
1896
  "[WebcamPublisher] Status changed to",
@@ -1444,7 +1900,7 @@ function WebcamStream({
1444
1900
  setIsPublishing(false);
1445
1901
  }
1446
1902
  }, [status, isPublishing]);
1447
- (0, import_react6.useEffect)(() => {
1903
+ (0, import_react7.useEffect)(() => {
1448
1904
  console.debug("[WebcamPublisher] Auto-starting webcam");
1449
1905
  startWebcam();
1450
1906
  return () => {
@@ -1453,7 +1909,7 @@ function WebcamStream({
1453
1909
  };
1454
1910
  }, []);
1455
1911
  const showPlaceholder = !stream;
1456
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1912
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1457
1913
  "div",
1458
1914
  {
1459
1915
  style: __spreadValues({
@@ -1463,7 +1919,7 @@ function WebcamStream({
1463
1919
  }, style),
1464
1920
  className,
1465
1921
  children: [
1466
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1922
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1467
1923
  "video",
1468
1924
  {
1469
1925
  ref: videoRef,
@@ -1478,7 +1934,7 @@ function WebcamStream({
1478
1934
  autoPlay: true
1479
1935
  }
1480
1936
  ),
1481
- showPlaceholder && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1937
+ showPlaceholder && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1482
1938
  "div",
1483
1939
  {
1484
1940
  style: {
@@ -1499,11 +1955,11 @@ function WebcamStream({
1499
1955
  flexDirection: "column",
1500
1956
  gap: "12px"
1501
1957
  },
1502
- children: permissionDenied ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { fontSize: "12px", fontFamily: "monospace" }, children: [
1958
+ children: permissionDenied ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { fontSize: "12px", fontFamily: "monospace" }, children: [
1503
1959
  "Camera access denied.",
1504
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("br", {}),
1960
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("br", {}),
1505
1961
  "Please allow access in your browser settings."
1506
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { fontSize: "12px", fontFamily: "monospace" }, children: "Starting camera..." })
1962
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { fontSize: "12px", fontFamily: "monospace" }, children: "Starting camera..." })
1507
1963
  }
1508
1964
  )
1509
1965
  ]
@@ -1513,6 +1969,7 @@ function WebcamStream({
1513
1969
  // Annotate the CommonJS export names for ESM import in node:
1514
1970
  0 && (module.exports = {
1515
1971
  Reactor,
1972
+ ReactorController,
1516
1973
  ReactorProvider,
1517
1974
  ReactorView,
1518
1975
  WebcamStream,