@noya-app/noya-multiplayer-react 0.1.50 → 0.1.52

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.js CHANGED
@@ -74,8 +74,8 @@ var require_sort = __commonJS({
74
74
  "../../node_modules/tree-visit/lib/sort.js"(exports2) {
75
75
  "use strict";
76
76
  Object.defineProperty(exports2, "__esModule", { value: true });
77
- exports2.sortIndexPaths = exports2.compareIndexPaths = void 0;
78
- function compareIndexPaths(a, b) {
77
+ exports2.sortPaths = exports2.comparePathsByComponent = void 0;
78
+ function comparePathsByComponent(a, b) {
79
79
  for (let i = 0; i < Math.min(a.length, b.length); i++) {
80
80
  if (a[i] < b[i])
81
81
  return -1;
@@ -84,11 +84,11 @@ var require_sort = __commonJS({
84
84
  }
85
85
  return a.length - b.length;
86
86
  }
87
- exports2.compareIndexPaths = compareIndexPaths;
88
- function sortIndexPaths(indexPaths) {
89
- return indexPaths.sort(compareIndexPaths);
87
+ exports2.comparePathsByComponent = comparePathsByComponent;
88
+ function sortPaths(indexPaths) {
89
+ return [...indexPaths].sort(comparePathsByComponent);
90
90
  }
91
- exports2.sortIndexPaths = sortIndexPaths;
91
+ exports2.sortPaths = sortPaths;
92
92
  }
93
93
  });
94
94
 
@@ -97,23 +97,25 @@ var require_ancestors = __commonJS({
97
97
  "../../node_modules/tree-visit/lib/ancestors.js"(exports2) {
98
98
  "use strict";
99
99
  Object.defineProperty(exports2, "__esModule", { value: true });
100
- exports2.ancestorIndexPaths = void 0;
100
+ exports2.ancestorPaths = void 0;
101
101
  var sort_1 = require_sort();
102
- function ancestorIndexPaths(indexPaths) {
103
- const paths = /* @__PURE__ */ new Map();
104
- const sortedIndexPaths = (0, sort_1.sortIndexPaths)(indexPaths);
102
+ function ancestorPaths(paths, options) {
103
+ var _a;
104
+ const result = /* @__PURE__ */ new Map();
105
+ const compare = (_a = options === null || options === void 0 ? void 0 : options.compare) !== null && _a !== void 0 ? _a : sort_1.comparePathsByComponent;
106
+ const sortedIndexPaths = paths.sort(compare);
105
107
  for (const indexPath of sortedIndexPaths) {
106
108
  const foundParent = indexPath.some((_, index) => {
107
109
  const parentKey = indexPath.slice(0, index).join();
108
- return paths.has(parentKey);
110
+ return result.has(parentKey);
109
111
  });
110
112
  if (foundParent)
111
113
  continue;
112
- paths.set(indexPath.join(), indexPath);
114
+ result.set(indexPath.join(), indexPath);
113
115
  }
114
- return Array.from(paths.values());
116
+ return Array.from(result.values());
115
117
  }
116
- exports2.ancestorIndexPaths = ancestorIndexPaths;
118
+ exports2.ancestorPaths = ancestorPaths;
117
119
  }
118
120
  });
119
121
 
@@ -619,7 +621,7 @@ var require_operation = __commonJS({
619
621
  exports2.getInsertionOperations = getInsertionOperations;
620
622
  function getRemovalOperations(indexPaths) {
621
623
  var _a, _b;
622
- const _ancestorIndexPaths = (0, ancestors_1.ancestorIndexPaths)(indexPaths);
624
+ const _ancestorIndexPaths = (0, ancestors_1.ancestorPaths)(indexPaths);
623
625
  const indexesToRemove = /* @__PURE__ */ new Map();
624
626
  for (const indexPath of _ancestorIndexPaths) {
625
627
  const parentKey = indexPath.slice(0, -1).join();
@@ -745,7 +747,7 @@ var require_move = __commonJS({
745
747
  if (options.to.length === 0) {
746
748
  throw new Error(`Can't move nodes to the root`);
747
749
  }
748
- const _ancestorIndexPaths = (0, ancestors_1.ancestorIndexPaths)(options.indexPaths);
750
+ const _ancestorIndexPaths = (0, ancestors_1.ancestorPaths)(options.indexPaths);
749
751
  const nodesToInsert = _ancestorIndexPaths.map((indexPath) => (0, access_1.access)(node, indexPath, options));
750
752
  const operations = (0, operation_1.getInsertionOperations)(options.to, nodesToInsert, (0, operation_1.getRemovalOperations)(_ancestorIndexPaths));
751
753
  return (0, operation_1.applyOperations)(node, operations, options);
@@ -915,6 +917,7 @@ var require_lib = __commonJS({
915
917
  var src_exports = {};
916
918
  __export(src_exports, {
917
919
  AnyEphemeralUserDataManagerContext: () => AnyEphemeralUserDataManagerContext,
920
+ AnyNoyaStateContext: () => AnyNoyaStateContext,
918
921
  ConnectedUsersContext: () => ConnectedUsersContext,
919
922
  FallbackUntilInitialized: () => FallbackUntilInitialized,
920
923
  StateInspector: () => StateInspector,
@@ -932,6 +935,7 @@ __export(src_exports, {
932
935
  useAsset: () => useAsset,
933
936
  useAssetManager: () => useAssetManager,
934
937
  useAssets: () => useAssets,
938
+ useCallableAITools: () => useCallableAITools,
935
939
  useColorScheme: () => useColorScheme,
936
940
  useConnectedUsersManager: () => useConnectedUsersManager,
937
941
  useCurrentUserId: () => useCurrentUserId,
@@ -944,1452 +948,146 @@ __export(src_exports, {
944
948
  useNoyaState: () => useNoyaState,
945
949
  useObservable: () => useObservable,
946
950
  useOutputTransforms: () => useOutputTransforms,
951
+ usePipelineManager: () => usePipelineManager,
952
+ useRegisterAITool: () => useRegisterAITool,
947
953
  useSecret: () => useSecret,
948
954
  useSecretManager: () => useSecretManager,
949
955
  useSecrets: () => useSecrets,
950
956
  useSyncStateManager: () => useSyncStateManager,
951
- useViewType: () => useViewType,
952
- useWorkflowManager: () => useWorkflowManager
957
+ useViewType: () => useViewType
953
958
  });
954
959
  module.exports = __toCommonJS(src_exports);
955
960
  __reExport(src_exports, require("@noya-app/state-manager"), module.exports);
956
961
 
957
- // src/components/UserPointersOverlay.tsx
958
- var import_react_utils = require("@noya-app/react-utils");
959
- var import_react2 = __toESM(require("react"));
962
+ // src/ai.ts
963
+ var import_react8 = require("react");
960
964
 
961
- // src/useObservable.ts
962
- var import_react = require("react");
963
- function useObservable(observable, pathOrSelector, options) {
964
- const { get, listen } = (0, import_react.useMemo)(() => {
965
- if (!observable) {
966
- return {
967
- get: () => void 0,
968
- listen: () => () => {
969
- }
970
- };
971
- }
972
- if (typeof pathOrSelector === "function") {
973
- const mappedObservable = observable.map(pathOrSelector, {
974
- isEqual: options?.isEqual
975
- });
976
- return {
977
- get: mappedObservable.get,
978
- listen: mappedObservable.subscribe
979
- };
980
- }
981
- const listen2 = pathOrSelector ? (callback) => observable.subscribe(pathOrSelector, callback) : observable.subscribe;
982
- const get2 = pathOrSelector ? () => observable.get(pathOrSelector) : observable.get;
983
- return { get: get2, listen: listen2 };
984
- }, [observable, pathOrSelector, options?.isEqual]);
985
- return (0, import_react.useSyncExternalStore)(listen, get, get);
986
- }
965
+ // src/NoyaStateContext.tsx
966
+ var import_observable = require("@noya-app/observable");
967
+ var import_react7 = __toESM(require("react"));
987
968
 
988
- // src/components/UserPointersOverlay.tsx
989
- function shouldShow(hideAfter, updatedAt) {
990
- return !!updatedAt && Date.now() - updatedAt < hideAfter;
991
- }
992
- var UserPointerInternal = (0, import_react_utils.memoGeneric)(function UserPointerInternal2({
993
- user,
994
- ephemeralUserDataManager,
995
- hideAfter = 5e3,
996
- renderUserPointer
997
- }) {
998
- const metadata = useObservable(ephemeralUserDataManager.metadata$, [
999
- user.id
1000
- ]);
1001
- const data = useObservable(ephemeralUserDataManager.data$, [
1002
- user.id
1003
- ]);
1004
- const [, setForceUpdate] = (0, import_react2.useState)(0);
1005
- const updatedAt = metadata?.updatedAt ?? 0;
1006
- const show = shouldShow(hideAfter, updatedAt);
1007
- (0, import_react2.useEffect)(() => {
1008
- if (!show) return;
1009
- const timeoutId = setTimeout(() => {
1010
- setForceUpdate((prev) => prev + 1);
1011
- }, hideAfter);
1012
- return () => clearTimeout(timeoutId);
1013
- }, [hideAfter, show, updatedAt]);
1014
- if (!data?.pointer) return null;
1015
- return renderUserPointer({
1016
- userId: user.id,
1017
- name: user.name,
1018
- point: data.pointer,
1019
- visible: show
1020
- });
1021
- });
1022
- var UserPointersOverlay = (0, import_react_utils.memoGeneric)(function UserPointers({
1023
- connectedUsersManager,
1024
- ephemeralUserDataManager,
1025
- renderUserPointer
1026
- }) {
1027
- const currentUserId = useObservable(ephemeralUserDataManager.currentUserId$);
1028
- const connectedUsers = useObservable(connectedUsersManager.connectedUsers$);
1029
- return /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, connectedUsers.map((user) => {
1030
- if (user.id === currentUserId) return null;
1031
- return /* @__PURE__ */ import_react2.default.createElement(
1032
- UserPointerInternal,
1033
- {
1034
- key: user.id,
1035
- user,
1036
- ephemeralUserDataManager,
1037
- renderUserPointer
1038
- }
1039
- );
1040
- }));
1041
- });
969
+ // ../../node_modules/@sinclair/typebox/build/esm/type/symbols/symbols.mjs
970
+ var TransformKind = Symbol.for("TypeBox.Transform");
971
+ var ReadonlyKind = Symbol.for("TypeBox.Readonly");
972
+ var OptionalKind = Symbol.for("TypeBox.Optional");
973
+ var Hint = Symbol.for("TypeBox.Hint");
974
+ var Kind = Symbol.for("TypeBox.Kind");
1042
975
 
1043
- // src/hooks.ts
1044
- var import_state_manager = require("@noya-app/state-manager");
1045
- var import_react6 = require("react");
1046
- var import_client2 = require("react-dom/client");
976
+ // ../../node_modules/@sinclair/typebox/build/esm/type/any/any.mjs
977
+ function Any(options = {}) {
978
+ return { ...options, [Kind]: "Any" };
979
+ }
1047
980
 
1048
- // src/components/ErrorOverlay.tsx
1049
- var React2 = __toESM(require("react"));
1050
- var ErrorOverlay = React2.memo(function ErrorOverlay2({
1051
- error
1052
- }) {
1053
- return /* @__PURE__ */ React2.createElement(
1054
- "div",
1055
- {
1056
- style: {
1057
- position: "fixed",
1058
- top: "20px",
1059
- left: "50%",
1060
- transform: "translateX(-50%)",
1061
- maxWidth: "80%",
1062
- width: "fit-content",
1063
- padding: "12px 20px",
1064
- background: "white",
1065
- color: "black",
1066
- zIndex: 1e4,
1067
- display: "flex",
1068
- flexDirection: "column",
1069
- justifyContent: "center",
1070
- borderRadius: "4px",
1071
- boxShadow: "0 4px 6px rgba(0, 0, 0, 0.1)",
1072
- fontFamily: "'__Inter_6b0edc', '__Inter_Fallback_6b0edc', -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Segoe UI', Roboto, Helvetica, Arial, sans-serif",
1073
- fontSize: "14px",
1074
- fontWeight: 400,
1075
- lineHeight: "19px"
1076
- }
1077
- },
1078
- error.reason === "schemaMigration" ? /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("p", null, "An updated version of Noya is available. Please reload the page to continue.")) : /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("p", null, "An error occurred:", " ", /* @__PURE__ */ React2.createElement(
1079
- "code",
1080
- {
1081
- style: {
1082
- background: "rgba(255, 0, 0, 0.1)",
1083
- color: "rgba(255, 0, 0, 0.5)",
1084
- padding: "2px 4px",
1085
- borderRadius: "4px"
1086
- }
1087
- },
1088
- error.reason
1089
- ), ". Please reload the page to continue.", /* @__PURE__ */ React2.createElement("br", null), /* @__PURE__ */ React2.createElement("br", null), "If this happens repeatedly, please get in touch and the Noya team can help.")),
1090
- /* @__PURE__ */ React2.createElement(
1091
- "div",
1092
- {
1093
- style: {
1094
- height: "1px",
1095
- background: "rgba(0, 0, 0, 0.1)",
1096
- margin: "12px -20px"
1097
- }
1098
- }
1099
- ),
1100
- /* @__PURE__ */ React2.createElement(
1101
- "button",
1102
- {
1103
- style: {
1104
- background: "black",
1105
- color: "white",
1106
- padding: "8px 16px",
1107
- borderRadius: "4px",
1108
- cursor: "pointer",
1109
- fontSize: "14px",
1110
- fontWeight: 700,
1111
- lineHeight: "19px"
1112
- },
1113
- onClick: () => {
1114
- window.location.reload();
1115
- }
1116
- },
1117
- "Reload"
1118
- )
1119
- );
981
+ // ../../node_modules/@sinclair/typebox/build/esm/type/guard/value.mjs
982
+ var value_exports = {};
983
+ __export(value_exports, {
984
+ IsArray: () => IsArray,
985
+ IsAsyncIterator: () => IsAsyncIterator,
986
+ IsBigInt: () => IsBigInt,
987
+ IsBoolean: () => IsBoolean,
988
+ IsDate: () => IsDate,
989
+ IsFunction: () => IsFunction,
990
+ IsIterator: () => IsIterator,
991
+ IsNull: () => IsNull,
992
+ IsNumber: () => IsNumber,
993
+ IsObject: () => IsObject,
994
+ IsRegExp: () => IsRegExp,
995
+ IsString: () => IsString,
996
+ IsSymbol: () => IsSymbol,
997
+ IsUint8Array: () => IsUint8Array,
998
+ IsUndefined: () => IsUndefined
1120
999
  });
1121
-
1122
- // src/inspector/useStateInspector.tsx
1123
- var import_react5 = __toESM(require("react"));
1124
- var import_client = require("react-dom/client");
1125
-
1126
- // src/inspector/StateInspector.tsx
1127
- var import_react_utils2 = require("@noya-app/react-utils");
1128
- var import_react4 = __toESM(require("react"));
1129
- var import_react_inspector = require("react-inspector");
1130
-
1131
- // src/inspector/useLocalStorageState.tsx
1132
- var import_react3 = __toESM(require("react"));
1133
- var localStorage = typeof window !== "undefined" ? window.localStorage : null;
1134
- function useLocalStorageState(key, defaultValue) {
1135
- const [state, setState] = import_react3.default.useState(() => {
1136
- const value = localStorage?.getItem(key);
1137
- let result = defaultValue;
1138
- if (value) {
1139
- try {
1140
- result = JSON.parse(value);
1141
- } catch (error) {
1142
- console.error("Error parsing localStorage value", error);
1143
- }
1144
- }
1145
- return result;
1146
- });
1147
- const setLocalStorageState = (value) => {
1148
- localStorage?.setItem(key, JSON.stringify(value));
1149
- setState(value);
1150
- };
1151
- return [state, setLocalStorageState];
1000
+ function IsAsyncIterator(value) {
1001
+ return IsObject(value) && !IsArray(value) && !IsUint8Array(value) && Symbol.asyncIterator in value;
1002
+ }
1003
+ function IsArray(value) {
1004
+ return Array.isArray(value);
1005
+ }
1006
+ function IsBigInt(value) {
1007
+ return typeof value === "bigint";
1008
+ }
1009
+ function IsBoolean(value) {
1010
+ return typeof value === "boolean";
1011
+ }
1012
+ function IsDate(value) {
1013
+ return value instanceof globalThis.Date;
1014
+ }
1015
+ function IsFunction(value) {
1016
+ return typeof value === "function";
1017
+ }
1018
+ function IsIterator(value) {
1019
+ return IsObject(value) && !IsArray(value) && !IsUint8Array(value) && Symbol.iterator in value;
1020
+ }
1021
+ function IsNull(value) {
1022
+ return value === null;
1023
+ }
1024
+ function IsNumber(value) {
1025
+ return typeof value === "number";
1026
+ }
1027
+ function IsObject(value) {
1028
+ return typeof value === "object" && value !== null;
1029
+ }
1030
+ function IsRegExp(value) {
1031
+ return value instanceof globalThis.RegExp;
1032
+ }
1033
+ function IsString(value) {
1034
+ return typeof value === "string";
1035
+ }
1036
+ function IsSymbol(value) {
1037
+ return typeof value === "symbol";
1038
+ }
1039
+ function IsUint8Array(value) {
1040
+ return value instanceof globalThis.Uint8Array;
1041
+ }
1042
+ function IsUndefined(value) {
1043
+ return value === void 0;
1152
1044
  }
1153
1045
 
1154
- // src/inspector/StateInspector.tsx
1155
- var lightTheme = {
1156
- ...import_react_inspector.chromeLight,
1157
- BASE_BACKGROUND_COLOR: "transparent",
1158
- OBJECT_NAME_COLOR: "rgba(0,0,0,0.7)"
1159
- };
1160
- var darkTheme = {
1161
- ...import_react_inspector.chromeDark,
1162
- BASE_BACKGROUND_COLOR: "transparent",
1163
- OBJECT_NAME_COLOR: "rgba(255,255,255,0.7)"
1164
- };
1165
- var styles = {
1166
- sectionInner: {
1167
- flex: "1 1 0",
1168
- overflowY: "auto",
1169
- overflowX: "hidden",
1170
- display: "flex",
1171
- flexDirection: "column"
1046
+ // ../../node_modules/@sinclair/typebox/build/esm/type/clone/value.mjs
1047
+ function ArrayType(value) {
1048
+ return value.map((value2) => Visit(value2));
1049
+ }
1050
+ function DateType(value) {
1051
+ return new Date(value.getTime());
1052
+ }
1053
+ function Uint8ArrayType(value) {
1054
+ return new Uint8Array(value);
1055
+ }
1056
+ function RegExpType(value) {
1057
+ return new RegExp(value.source, value.flags);
1058
+ }
1059
+ function ObjectType(value) {
1060
+ const result = {};
1061
+ for (const key of Object.getOwnPropertyNames(value)) {
1062
+ result[key] = Visit(value[key]);
1172
1063
  }
1173
- };
1174
- function ToggleButton({
1175
- showInspector,
1176
- setShowInspector,
1177
- theme,
1178
- anchor
1179
- }) {
1180
- return /* @__PURE__ */ import_react4.default.createElement(
1181
- "span",
1182
- {
1183
- role: "button",
1184
- style: {
1185
- flex: "0",
1186
- appearance: "none",
1187
- color: theme.BASE_COLOR,
1188
- border: "none",
1189
- fontSize: "12px",
1190
- whiteSpace: "nowrap",
1191
- display: "inline-flex",
1192
- alignItems: "center",
1193
- justifyContent: "center",
1194
- padding: "2px 0"
1195
- },
1196
- onClick: (event) => {
1197
- event.stopPropagation();
1198
- setShowInspector(!showInspector);
1199
- }
1200
- },
1201
- /* @__PURE__ */ import_react4.default.createElement("span", { style: { width: "12px", height: "12px" } }, showInspector === (anchor === "right") ? /* @__PURE__ */ import_react4.default.createElement(
1202
- "svg",
1203
- {
1204
- xmlns: "http://www.w3.org/2000/svg",
1205
- fill: "none",
1206
- viewBox: "0 0 24 24",
1207
- strokeWidth: 1.5,
1208
- stroke: "currentColor",
1209
- className: "size-6"
1210
- },
1211
- /* @__PURE__ */ import_react4.default.createElement(
1212
- "path",
1213
- {
1214
- strokeLinecap: "round",
1215
- strokeLinejoin: "round",
1216
- d: "m5.25 4.5 7.5 7.5-7.5 7.5m6-15 7.5 7.5-7.5 7.5"
1217
- }
1218
- )
1219
- ) : /* @__PURE__ */ import_react4.default.createElement(
1220
- "svg",
1221
- {
1222
- xmlns: "http://www.w3.org/2000/svg",
1223
- fill: "none",
1224
- viewBox: "0 0 24 24",
1225
- strokeWidth: 1.5,
1226
- stroke: "currentColor",
1227
- className: "size-6"
1228
- },
1229
- /* @__PURE__ */ import_react4.default.createElement(
1230
- "path",
1231
- {
1232
- strokeLinecap: "round",
1233
- strokeLinejoin: "round",
1234
- d: "m18.75 4.5-7.5 7.5 7.5 7.5m-6-15L5.25 12l7.5 7.5"
1235
- }
1236
- )
1237
- ))
1238
- );
1064
+ for (const key of Object.getOwnPropertySymbols(value)) {
1065
+ result[key] = Visit(value[key]);
1066
+ }
1067
+ return result;
1239
1068
  }
1240
- function DisclosureSection({
1241
- open,
1242
- setOpen,
1243
- title,
1244
- right,
1245
- children,
1246
- colorScheme,
1247
- isFirst,
1248
- style
1249
- }) {
1250
- const theme = colorScheme === "light" ? lightTheme : darkTheme;
1251
- const borderColor = colorScheme === "light" ? "rgba(0,0,0,0.1)" : "rgba(255,255,255,0.1)";
1252
- return /* @__PURE__ */ import_react4.default.createElement(
1253
- "div",
1254
- {
1255
- style: {
1256
- flex: open ? "1 1 0" : "0",
1257
- display: "flex",
1258
- flexDirection: "column",
1259
- ...style
1260
- }
1261
- },
1262
- /* @__PURE__ */ import_react4.default.createElement(
1263
- "div",
1264
- {
1265
- onClick: () => setOpen?.(!open),
1266
- style: {
1267
- cursor: "default",
1268
- fontSize: "12px",
1269
- padding: "4px 10px",
1270
- display: "flex",
1271
- alignItems: "center",
1272
- ...!isFirst && { borderTop: `1px solid ${borderColor}` },
1273
- ...open && { borderBottom: `1px solid ${borderColor}` }
1274
- }
1275
- },
1276
- setOpen && /* @__PURE__ */ import_react4.default.createElement(
1277
- Arrow,
1278
- {
1279
- expanded: open,
1280
- style: {
1281
- fontSize: theme.ARROW_FONT_SIZE,
1282
- marginRight: theme.ARROW_MARGIN_RIGHT + 1,
1283
- color: theme.ARROW_COLOR
1284
- }
1285
- }
1286
- ),
1287
- /* @__PURE__ */ import_react4.default.createElement("span", { style: { flex: "1 1 0", userSelect: "none" } }, title),
1288
- right
1289
- ),
1290
- open && children
1291
- );
1069
+ function Visit(value) {
1070
+ return IsArray(value) ? ArrayType(value) : IsDate(value) ? DateType(value) : IsUint8Array(value) ? Uint8ArrayType(value) : IsRegExp(value) ? RegExpType(value) : IsObject(value) ? ObjectType(value) : value;
1292
1071
  }
1293
- function InspectorRow({
1294
- children,
1295
- colorScheme,
1296
- selected,
1297
- style,
1298
- variant
1299
- }) {
1300
- const solidBorderColor = colorScheme === "light" ? "rgb(223 223 223)" : "rgb(29 29 29)";
1301
- return /* @__PURE__ */ import_react4.default.createElement(
1302
- "div",
1303
- {
1304
- style: {
1305
- borderBottom: `1px solid ${solidBorderColor}`,
1306
- fontSize: "12px",
1307
- fontFamily: "Menlo, monospace",
1308
- padding: "2px 12px 1px",
1309
- display: "flex",
1310
- alignItems: "center",
1311
- background: variant === "up" ? "rgba(0,255,0,0.1)" : variant === "down" ? "transparent" : selected ? "rgb(59 130 246 / 15%)" : void 0,
1312
- // background:
1313
- // colorScheme === "light"
1314
- // ? "rgba(0,0,0,0.05)"
1315
- // : "rgba(255,255,255,0.05)",
1316
- ...style
1317
- }
1318
- },
1319
- /* @__PURE__ */ import_react4.default.createElement(
1320
- "span",
1321
- {
1322
- style: {
1323
- fontFamily: "Menlo, monospace",
1324
- fontSize: "11px",
1325
- borderRadius: 4,
1326
- display: "inline-block"
1327
- }
1328
- },
1329
- children
1330
- )
1331
- );
1072
+ function Clone(value) {
1073
+ return Visit(value);
1332
1074
  }
1333
- var HISTORY_ELEMENT_PREFIX = "noya-multiplayer-history-";
1334
- var StateInspector = (0, import_react_utils2.memoGeneric)(function StateInspector2({
1335
- noyaManager,
1336
- colorScheme = "light",
1337
- anchor = "right",
1338
- unstyled = false,
1339
- ...props
1340
- }) {
1341
- const {
1342
- multiplayerStateManager,
1343
- assetManager,
1344
- connectedUsersManager,
1345
- secretManager,
1346
- ephemeralUserDataManager,
1347
- connectionEventManager,
1348
- taskManager,
1349
- ioManager
1350
- } = noyaManager;
1351
- const [didMount, setDidMount] = import_react4.default.useState(false);
1352
- const tasks = useObservable(taskManager.tasks$);
1353
- const inputs = useObservable(ioManager.inputs$);
1354
- const outputTransforms = useObservable(ioManager.outputTransforms$);
1355
- (0, import_react4.useLayoutEffect)(() => {
1356
- setDidMount(true);
1357
- }, []);
1358
- const eventsContainerRef = import_react4.default.useRef(null);
1359
- const historyContainerRef = import_react4.default.useRef(null);
1360
- const [showInspector, setShowInspector] = useLocalStorageState(
1361
- "noya-multiplayer-react-show-inspector",
1362
- true
1363
- );
1364
- const [showEvents, setShowEvents] = useLocalStorageState(
1365
- "noya-multiplayer-react-show-events",
1366
- false
1367
- );
1368
- const [showHistory, setShowHistory] = useLocalStorageState(
1369
- "noya-multiplayer-react-show-history",
1370
- false
1371
- );
1372
- const [showUsers, setShowUsers] = useLocalStorageState(
1373
- "noya-multiplayer-react-show-users",
1374
- true
1375
- );
1376
- const [showData, setShowData] = useLocalStorageState(
1377
- "noya-multiplayer-react-show-data",
1378
- true
1379
- );
1380
- const [showTasks, setShowTasks] = useLocalStorageState(
1381
- "noya-multiplayer-react-show-tasks",
1382
- false
1383
- );
1384
- const [showEphemeral, setShowEphemeral] = useLocalStorageState(
1385
- "noya-multiplayer-react-show-ephemeral",
1386
- false
1387
- );
1388
- const [showAssets, setShowAssets] = useLocalStorageState(
1389
- "noya-multiplayer-react-show-assets",
1390
- false
1391
- );
1392
- const [showSecrets, setShowSecrets] = useLocalStorageState(
1393
- "noya-multiplayer-react-show-secrets",
1394
- false
1395
- );
1396
- const [showInputs, setShowInputs] = useLocalStorageState(
1397
- "noya-multiplayer-react-show-inputs",
1398
- false
1399
- );
1400
- const [showOutputTransforms, setShowOutputTransforms] = useLocalStorageState(
1401
- "noya-multiplayer-react-show-output-transforms",
1402
- false
1403
- );
1404
- const connectionEvents = useObservable(connectionEventManager.events$);
1405
- (0, import_react4.useEffect)(() => {
1406
- if (eventsContainerRef.current) {
1407
- eventsContainerRef.current.scrollTop = eventsContainerRef.current.scrollHeight;
1408
- }
1409
- }, [connectionEvents]);
1410
- const multipeerStateInitialized = useObservable(
1411
- multiplayerStateManager.isInitialized$
1412
- );
1413
- const ephemeral = useObservable(ephemeralUserDataManager.data$);
1414
- const historySnapshot = useManagedHistory(multiplayerStateManager.sm);
1415
- const assets = useObservable(assetManager.assets$);
1416
- const assetsInitialized = useObservable(assetManager.isInitialized$);
1417
- const secrets = useObservable(secretManager.secrets$);
1418
- const secretsInitialized = useObservable(secretManager.isInitialized$);
1419
- const connectedUsers = useObservable(connectedUsersManager.connectedUsers$);
1420
- const userId = useObservable(connectedUsersManager.currentUserId$);
1421
- const state = useObservable(multiplayerStateManager.optimisticState$);
1422
- const inputsInitialized = useObservable(ioManager.inputsInitialized$);
1423
- const outputTransformsInitialized = useObservable(
1424
- ioManager.outputTransformsInitialized$
1425
- );
1426
- (0, import_react4.useEffect)(() => {
1427
- if (historyContainerRef.current) {
1428
- historyContainerRef.current.scrollTop = historyContainerRef.current.scrollHeight;
1429
- }
1430
- }, [historySnapshot]);
1431
- (0, import_react4.useEffect)(() => {
1432
- if (!historyContainerRef.current) return;
1433
- const historyEntry = historyContainerRef.current.querySelector(
1434
- `#${HISTORY_ELEMENT_PREFIX}${historySnapshot.historyIndex}`
1435
- );
1436
- if (historyEntry) {
1437
- historyEntry.scrollIntoView({
1438
- block: "nearest",
1439
- inline: "nearest"
1440
- });
1441
- }
1442
- }, [historySnapshot.historyIndex]);
1443
- const theme = colorScheme === "light" ? lightTheme : darkTheme;
1444
- const solidBorderColor = colorScheme === "light" ? "rgb(223 223 223)" : "rgb(29 29 29)";
1445
- const baseStyle = {
1446
- position: "fixed",
1447
- top: 12,
1448
- ...anchor.includes("right") ? { right: 12 } : { left: 12 },
1449
- bottom: 12,
1450
- width: 400,
1451
- background: colorScheme === "light" ? "rgba(255,255,255,0.95)" : "rgba(0,0,0,0.95)",
1452
- backdropFilter: "blur(48px)",
1453
- border: `1px solid ${solidBorderColor}`,
1454
- // outlineOffset: -1,
1455
- borderRadius: 4,
1456
- display: "flex",
1457
- flexDirection: "column",
1458
- // gap: 12,
1459
- color: theme.BASE_COLOR,
1460
- overflow: "hidden",
1461
- zIndex: 9999,
1462
- lineHeight: "13px"
1463
- };
1464
- if (!didMount) return null;
1465
- if (!showInspector) {
1466
- return /* @__PURE__ */ import_react4.default.createElement(
1467
- "div",
1468
- {
1469
- ...props,
1470
- style: {
1471
- ...baseStyle,
1472
- padding: "4px 10px",
1473
- width: void 0,
1474
- ...anchor.includes("bottom") ? { bottom: 12, top: void 0 } : { bottom: void 0 }
1475
- },
1476
- onClick: () => setShowInspector(true)
1477
- },
1478
- /* @__PURE__ */ import_react4.default.createElement(
1479
- ToggleButton,
1480
- {
1481
- showInspector,
1482
- setShowInspector,
1483
- theme,
1484
- anchor
1485
- }
1486
- )
1487
- );
1488
- }
1489
- return /* @__PURE__ */ import_react4.default.createElement(
1490
- "div",
1491
- {
1492
- ...props,
1493
- style: {
1494
- ...!unstyled && baseStyle,
1495
- ...props.style
1496
- }
1497
- },
1498
- /* @__PURE__ */ import_react4.default.createElement(
1499
- DisclosureSection,
1500
- {
1501
- isFirst: true,
1502
- open: showUsers,
1503
- setOpen: setShowUsers,
1504
- title: "Users",
1505
- colorScheme,
1506
- style: {
1507
- flex: "0 0 auto",
1508
- maxHeight: "200px"
1509
- },
1510
- right: /* @__PURE__ */ import_react4.default.createElement(
1511
- ToggleButton,
1512
- {
1513
- showInspector,
1514
- setShowInspector,
1515
- theme,
1516
- anchor
1517
- }
1518
- )
1519
- },
1520
- /* @__PURE__ */ import_react4.default.createElement("div", { style: { ...styles.sectionInner, flex: "0 0 auto" } }, connectedUsers?.map((user) => /* @__PURE__ */ import_react4.default.createElement(
1521
- InspectorRow,
1522
- {
1523
- key: user.id,
1524
- colorScheme,
1525
- variant: user.id === userId ? "up" : void 0
1526
- },
1527
- user.image && /* @__PURE__ */ import_react4.default.createElement(
1528
- "img",
1529
- {
1530
- src: user.image,
1531
- alt: user.name,
1532
- style: {
1533
- width: "13px",
1534
- height: "13px",
1535
- borderRadius: "50%",
1536
- marginRight: "4px",
1537
- display: "inline-block",
1538
- position: "relative",
1539
- background: solidBorderColor,
1540
- verticalAlign: "middle"
1541
- }
1542
- }
1543
- ),
1544
- user.name,
1545
- " (",
1546
- ellipsis(user.id.toString(), 8, "middle"),
1547
- ")"
1548
- )), !connectedUsers && /* @__PURE__ */ import_react4.default.createElement(
1549
- "div",
1550
- {
1551
- style: {
1552
- padding: "12px",
1553
- fontSize: "12px",
1554
- display: "flex",
1555
- flexDirection: "column",
1556
- gap: "4px"
1557
- }
1558
- },
1559
- /* @__PURE__ */ import_react4.default.createElement("span", null, "No connected users")
1560
- ))
1561
- ),
1562
- /* @__PURE__ */ import_react4.default.createElement(
1563
- DisclosureSection,
1564
- {
1565
- title: /* @__PURE__ */ import_react4.default.createElement(TitleLabel, null, "Data", /* @__PURE__ */ import_react4.default.createElement(
1566
- ColoredDot,
1567
- {
1568
- type: multipeerStateInitialized ? "success" : "error"
1569
- }
1570
- )),
1571
- colorScheme,
1572
- setOpen: setShowData,
1573
- open: showData,
1574
- right: /* @__PURE__ */ import_react4.default.createElement(
1575
- "span",
1576
- {
1577
- style: {
1578
- display: "flex",
1579
- gap: "4px"
1580
- }
1581
- },
1582
- /* @__PURE__ */ import_react4.default.createElement(
1583
- SmallButton,
1584
- {
1585
- theme,
1586
- onClick: () => {
1587
- noyaManager.forceInit();
1588
- }
1589
- },
1590
- "Reset"
1591
- )
1592
- )
1593
- },
1594
- /* @__PURE__ */ import_react4.default.createElement("div", { style: styles.sectionInner }, /* @__PURE__ */ import_react4.default.createElement(InspectorRow, { colorScheme }, /* @__PURE__ */ import_react4.default.createElement(
1595
- import_react_inspector.ObjectInspector,
1596
- {
1597
- name: multiplayerStateManager.schema ? "state" : void 0,
1598
- data: state,
1599
- theme
1600
- }
1601
- )), multiplayerStateManager.schema && /* @__PURE__ */ import_react4.default.createElement(InspectorRow, { colorScheme }, /* @__PURE__ */ import_react4.default.createElement(
1602
- import_react_inspector.ObjectInspector,
1603
- {
1604
- name: "schema",
1605
- data: multiplayerStateManager.schema,
1606
- theme
1607
- }
1608
- )))
1609
- ),
1610
- /* @__PURE__ */ import_react4.default.createElement(
1611
- DisclosureSection,
1612
- {
1613
- open: showHistory,
1614
- setOpen: setShowHistory,
1615
- title: "History",
1616
- colorScheme,
1617
- right: /* @__PURE__ */ import_react4.default.createElement(
1618
- "span",
1619
- {
1620
- style: {
1621
- display: "flex",
1622
- gap: "4px"
1623
- }
1624
- },
1625
- /* @__PURE__ */ import_react4.default.createElement(
1626
- SmallButton,
1627
- {
1628
- disabled: !historySnapshot.canUndo,
1629
- theme,
1630
- onClick: () => {
1631
- multiplayerStateManager.undo();
1632
- }
1633
- },
1634
- /* @__PURE__ */ import_react4.default.createElement("span", { style: { width: "12px", height: "12px" } }, /* @__PURE__ */ import_react4.default.createElement(
1635
- "svg",
1636
- {
1637
- xmlns: "http://www.w3.org/2000/svg",
1638
- width: "1em",
1639
- height: "1em",
1640
- viewBox: "0 0 20 20"
1641
- },
1642
- /* @__PURE__ */ import_react4.default.createElement(
1643
- "path",
1644
- {
1645
- fill: "currentColor",
1646
- d: "M12 5H7V2L1 6l6 4V7h5c2.2 0 4 1.8 4 4s-1.8 4-4 4H7v2h5c3.3 0 6-2.7 6-6s-2.7-6-6-6"
1647
- }
1648
- )
1649
- ))
1650
- ),
1651
- /* @__PURE__ */ import_react4.default.createElement(
1652
- SmallButton,
1653
- {
1654
- disabled: !historySnapshot.canRedo,
1655
- theme,
1656
- onClick: () => {
1657
- multiplayerStateManager.redo();
1658
- }
1659
- },
1660
- /* @__PURE__ */ import_react4.default.createElement("span", { style: { width: "12px", height: "12px" } }, /* @__PURE__ */ import_react4.default.createElement(
1661
- "svg",
1662
- {
1663
- xmlns: "http://www.w3.org/2000/svg",
1664
- width: "1em",
1665
- height: "1em",
1666
- viewBox: "0 0 20 20"
1667
- },
1668
- /* @__PURE__ */ import_react4.default.createElement(
1669
- "path",
1670
- {
1671
- fill: "currentColor",
1672
- d: "M8 5h5V2l6 4l-6 4V7H8c-2.2 0-4 1.8-4 4s1.8 4 4 4h5v2H8c-3.3 0-6-2.7-6-6s2.7-6 6-6"
1673
- }
1674
- )
1675
- ))
1676
- )
1677
- )
1678
- },
1679
- /* @__PURE__ */ import_react4.default.createElement("div", { ref: historyContainerRef, style: styles.sectionInner }, /* @__PURE__ */ import_react4.default.createElement(
1680
- "div",
1681
- {
1682
- id: `${HISTORY_ELEMENT_PREFIX}0`,
1683
- style: {
1684
- borderBottom: `1px solid ${solidBorderColor}`,
1685
- fontSize: "12px",
1686
- fontFamily: "Menlo, monospace",
1687
- padding: "2px 12px 1px",
1688
- display: "flex",
1689
- alignItems: "center",
1690
- background: historySnapshot.historyIndex === 0 ? "rgb(59 130 246 / 15%)" : void 0
1691
- }
1692
- },
1693
- /* @__PURE__ */ import_react4.default.createElement(
1694
- "span",
1695
- {
1696
- style: {
1697
- fontFamily: "Menlo, monospace",
1698
- fontSize: "11px",
1699
- borderRadius: 4,
1700
- display: "inline-block"
1701
- }
1702
- },
1703
- "Initial state"
1704
- )
1705
- ), historySnapshot.history.map((entry, index) => /* @__PURE__ */ import_react4.default.createElement(
1706
- "div",
1707
- {
1708
- id: `${HISTORY_ELEMENT_PREFIX}${index + 1}`,
1709
- key: index,
1710
- style: {
1711
- padding: "0px 12px 1px",
1712
- borderBottom: `1px solid ${solidBorderColor}`,
1713
- background: index + 1 === historySnapshot.historyIndex ? "rgb(59 130 246 / 15%)" : void 0
1714
- }
1715
- },
1716
- "name" in entry.metadata && typeof entry.metadata.name === "string" && /* @__PURE__ */ import_react4.default.createElement(
1717
- "pre",
1718
- {
1719
- style: {
1720
- fontSize: "11px",
1721
- display: "flex",
1722
- flexWrap: "wrap",
1723
- margin: 0
1724
- }
1725
- },
1726
- entry.metadata.name
1727
- ),
1728
- entry.redoPatches?.map((patch, j) => /* @__PURE__ */ import_react4.default.createElement(
1729
- "pre",
1730
- {
1731
- key: j,
1732
- style: {
1733
- fontSize: "11px",
1734
- display: "flex",
1735
- flexWrap: "wrap",
1736
- margin: 0
1737
- }
1738
- },
1739
- patch.op === "add" && /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, /* @__PURE__ */ import_react4.default.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path)), " = ", /* @__PURE__ */ import_react4.default.createElement(import_react_inspector.ObjectInspector, { data: patch.value, theme })),
1740
- patch.op === "replace" && /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, /* @__PURE__ */ import_react4.default.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path)), " = ", /* @__PURE__ */ import_react4.default.createElement(import_react_inspector.ObjectInspector, { data: patch.value, theme })),
1741
- patch.op === "remove" && /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, /* @__PURE__ */ import_react4.default.createElement("span", { style: { color: theme.OBJECT_VALUE_STRING_COLOR } }, "delete", " "), /* @__PURE__ */ import_react4.default.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path))),
1742
- patch.op === "move" && /* @__PURE__ */ import_react4.default.createElement(import_react4.default.Fragment, null, /* @__PURE__ */ import_react4.default.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.from)), " -> ", /* @__PURE__ */ import_react4.default.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path)))
1743
- ))
1744
- )))
1745
- ),
1746
- /* @__PURE__ */ import_react4.default.createElement(
1747
- DisclosureSection,
1748
- {
1749
- open: showAssets,
1750
- setOpen: setShowAssets,
1751
- title: /* @__PURE__ */ import_react4.default.createElement(TitleLabel, null, "Assets", /* @__PURE__ */ import_react4.default.createElement(ColoredDot, { type: assetsInitialized ? "success" : "error" })),
1752
- colorScheme,
1753
- right: /* @__PURE__ */ import_react4.default.createElement("span", { style: { display: "flex", gap: "10px" } }, /* @__PURE__ */ import_react4.default.createElement(
1754
- SmallButton,
1755
- {
1756
- theme,
1757
- onClick: () => {
1758
- console.info(
1759
- "[StateInspector] Reloading assets",
1760
- noyaManager.id
1761
- );
1762
- assetManager.fetch();
1763
- }
1764
- },
1765
- "Reload"
1766
- ), /* @__PURE__ */ import_react4.default.createElement(
1767
- SmallButton,
1768
- {
1769
- theme,
1770
- onClick: () => {
1771
- const input = document.createElement("input");
1772
- input.type = "file";
1773
- input.onchange = () => {
1774
- const file = input.files?.[0];
1775
- if (file) {
1776
- const reader = new FileReader();
1777
- reader.onload = () => {
1778
- const buffer = reader.result;
1779
- assetManager.create(new Uint8Array(buffer));
1780
- };
1781
- reader.readAsArrayBuffer(file);
1782
- }
1783
- };
1784
- input.click();
1785
- }
1786
- },
1787
- "Upload"
1788
- ))
1789
- },
1790
- /* @__PURE__ */ import_react4.default.createElement("div", { style: styles.sectionInner }, assets.map((asset) => /* @__PURE__ */ import_react4.default.createElement(InspectorRow, { key: asset.id, colorScheme }, /* @__PURE__ */ import_react4.default.createElement(import_react_inspector.ObjectInspector, { name: asset.id, data: asset, theme }), /* @__PURE__ */ import_react4.default.createElement(
1791
- SmallButton,
1792
- {
1793
- theme,
1794
- onClick: () => assetManager.delete(asset.id)
1795
- },
1796
- "Delete"
1797
- ))))
1798
- ),
1799
- /* @__PURE__ */ import_react4.default.createElement(
1800
- DisclosureSection,
1801
- {
1802
- title: /* @__PURE__ */ import_react4.default.createElement(TitleLabel, null, "Secrets", /* @__PURE__ */ import_react4.default.createElement(ColoredDot, { type: secretsInitialized ? "success" : "error" })),
1803
- colorScheme,
1804
- open: showSecrets,
1805
- setOpen: setShowSecrets,
1806
- right: /* @__PURE__ */ import_react4.default.createElement(
1807
- SmallButton,
1808
- {
1809
- theme,
1810
- onClick: () => {
1811
- const name = prompt("Enter secret name");
1812
- if (!name) return;
1813
- const value = prompt("Enter secret value");
1814
- if (!value) return;
1815
- secretManager.createSecret(name, value);
1816
- }
1817
- },
1818
- "Create"
1819
- )
1820
- },
1821
- /* @__PURE__ */ import_react4.default.createElement("div", { style: styles.sectionInner }, secrets.map((secret) => /* @__PURE__ */ import_react4.default.createElement(InspectorRow, { key: secret.id, colorScheme }, /* @__PURE__ */ import_react4.default.createElement(import_react_inspector.ObjectInspector, { data: secret, theme }), /* @__PURE__ */ import_react4.default.createElement(
1822
- SmallButton,
1823
- {
1824
- theme,
1825
- onClick: () => secretManager.deleteSecret(secret.name)
1826
- },
1827
- "Delete"
1828
- ))))
1829
- ),
1830
- " ",
1831
- /* @__PURE__ */ import_react4.default.createElement(
1832
- DisclosureSection,
1833
- {
1834
- open: showInputs,
1835
- setOpen: setShowInputs,
1836
- title: /* @__PURE__ */ import_react4.default.createElement(TitleLabel, null, "Inputs", /* @__PURE__ */ import_react4.default.createElement(ColoredDot, { type: inputsInitialized ? "success" : "error" })),
1837
- colorScheme
1838
- },
1839
- /* @__PURE__ */ import_react4.default.createElement("div", { style: styles.sectionInner }, inputs?.map((input) => /* @__PURE__ */ import_react4.default.createElement(InspectorRow, { key: input.id, colorScheme }, /* @__PURE__ */ import_react4.default.createElement(import_react_inspector.ObjectInspector, { data: input, theme }))), !inputs?.length && /* @__PURE__ */ import_react4.default.createElement(
1840
- "div",
1841
- {
1842
- style: {
1843
- padding: "12px",
1844
- fontSize: "12px",
1845
- display: "flex",
1846
- flexDirection: "column",
1847
- gap: "4px"
1848
- }
1849
- },
1850
- /* @__PURE__ */ import_react4.default.createElement("span", null, "No inputs")
1851
- ))
1852
- ),
1853
- /* @__PURE__ */ import_react4.default.createElement(
1854
- DisclosureSection,
1855
- {
1856
- open: showOutputTransforms,
1857
- setOpen: setShowOutputTransforms,
1858
- title: /* @__PURE__ */ import_react4.default.createElement(TitleLabel, null, "Output Transforms", /* @__PURE__ */ import_react4.default.createElement(
1859
- ColoredDot,
1860
- {
1861
- type: outputTransformsInitialized ? "success" : "error"
1862
- }
1863
- )),
1864
- colorScheme
1865
- },
1866
- /* @__PURE__ */ import_react4.default.createElement("div", { style: styles.sectionInner }, outputTransforms?.map((transform) => /* @__PURE__ */ import_react4.default.createElement(InspectorRow, { key: transform.id, colorScheme }, /* @__PURE__ */ import_react4.default.createElement(import_react_inspector.ObjectInspector, { data: transform, theme }))), !outputTransforms?.length && /* @__PURE__ */ import_react4.default.createElement(
1867
- "div",
1868
- {
1869
- style: {
1870
- padding: "12px",
1871
- fontSize: "12px",
1872
- display: "flex",
1873
- flexDirection: "column",
1874
- gap: "4px"
1875
- }
1876
- },
1877
- /* @__PURE__ */ import_react4.default.createElement("span", null, "No output transforms")
1878
- ))
1879
- ),
1880
- /* @__PURE__ */ import_react4.default.createElement(
1881
- DisclosureSection,
1882
- {
1883
- title: "Tasks",
1884
- colorScheme,
1885
- open: showTasks,
1886
- setOpen: setShowTasks
1887
- },
1888
- /* @__PURE__ */ import_react4.default.createElement("div", { style: styles.sectionInner }, tasks?.map((task) => /* @__PURE__ */ import_react4.default.createElement(
1889
- InspectorRow,
1890
- {
1891
- key: task.id,
1892
- colorScheme,
1893
- style: {
1894
- backgroundColor: task.status === "done" ? "rgba(0,255,0,0.2)" : task.status === "error" ? "rgba(255,0,0,0.2)" : void 0
1895
- }
1896
- },
1897
- /* @__PURE__ */ import_react4.default.createElement(
1898
- import_react_inspector.ObjectInspector,
1899
- {
1900
- name: task.name,
1901
- data: task.payload,
1902
- theme
1903
- }
1904
- )
1905
- )))
1906
- ),
1907
- /* @__PURE__ */ import_react4.default.createElement(
1908
- DisclosureSection,
1909
- {
1910
- open: showEphemeral,
1911
- setOpen: setShowEphemeral,
1912
- title: "Ephemeral User Data",
1913
- colorScheme
1914
- },
1915
- /* @__PURE__ */ import_react4.default.createElement("div", { style: styles.sectionInner }, Object.entries(ephemeral).map(([key, value]) => /* @__PURE__ */ import_react4.default.createElement(InspectorRow, { key, colorScheme }, /* @__PURE__ */ import_react4.default.createElement(
1916
- import_react_inspector.ObjectInspector,
1917
- {
1918
- name: key,
1919
- data: value,
1920
- theme,
1921
- expandLevel: 10
1922
- }
1923
- ))))
1924
- ),
1925
- /* @__PURE__ */ import_react4.default.createElement(
1926
- DisclosureSection,
1927
- {
1928
- open: showEvents,
1929
- setOpen: setShowEvents,
1930
- title: "Events",
1931
- colorScheme
1932
- },
1933
- /* @__PURE__ */ import_react4.default.createElement("div", { ref: eventsContainerRef, style: styles.sectionInner }, connectionEvents?.map(
1934
- (event, index) => event.type === "stateChange" ? /* @__PURE__ */ import_react4.default.createElement(InspectorRow, { key: index, colorScheme }, "connection:", " ", /* @__PURE__ */ import_react4.default.createElement("span", { style: { fontStyle: "italic" } }, event.state.toLowerCase())) : /* @__PURE__ */ import_react4.default.createElement(
1935
- InspectorRow,
1936
- {
1937
- key: index,
1938
- colorScheme,
1939
- variant: event.type === "send" ? "up" : "down",
1940
- style: {
1941
- padding: "0px 12px 1px"
1942
- }
1943
- },
1944
- /* @__PURE__ */ import_react4.default.createElement(
1945
- import_react_inspector.ObjectInspector,
1946
- {
1947
- data: event.type === "error" ? event.error : event.message,
1948
- theme,
1949
- nodeRenderer: ({
1950
- depth,
1951
- name,
1952
- data,
1953
- isNonenumerable
1954
- }) => {
1955
- const direction = event.type === "send" ? "up" : "down";
1956
- return depth === 0 ? /* @__PURE__ */ import_react4.default.createElement(ObjectRootLabel, { direction, data }) : /* @__PURE__ */ import_react4.default.createElement(
1957
- import_react_inspector.ObjectLabel,
1958
- {
1959
- direction,
1960
- name,
1961
- data,
1962
- isNonenumerable
1963
- }
1964
- );
1965
- }
1966
- }
1967
- )
1968
- )
1969
- ), !connectionEvents && /* @__PURE__ */ import_react4.default.createElement(
1970
- "div",
1971
- {
1972
- style: {
1973
- padding: "12px",
1974
- fontSize: "12px",
1975
- display: "flex",
1976
- flexDirection: "column",
1977
- gap: "4px"
1978
- }
1979
- },
1980
- /* @__PURE__ */ import_react4.default.createElement("span", null, "No recorded events")
1981
- ))
1982
- )
1983
- );
1984
- });
1985
- var ObjectRootLabel = ({ name, data, direction }) => {
1986
- if (typeof name === "string") {
1987
- return /* @__PURE__ */ import_react4.default.createElement("span", null, /* @__PURE__ */ import_react4.default.createElement(import_react_inspector.ObjectName, { name }), /* @__PURE__ */ import_react4.default.createElement("span", null, ": "), /* @__PURE__ */ import_react4.default.createElement(import_react_inspector.ObjectPreview, { data }));
1988
- }
1989
- if (direction === "up" || direction === "down") {
1990
- const arrow = direction === "up" ? "\u2191" : "\u2193";
1991
- return /* @__PURE__ */ import_react4.default.createElement("span", null, /* @__PURE__ */ import_react4.default.createElement(
1992
- "span",
1993
- {
1994
- style: {
1995
- background: direction === "up" ? "rgba(0,255,0,0.2)" : "rgba(255,0,0,0.2)",
1996
- // color: "white",
1997
- width: 12,
1998
- height: 12,
1999
- borderRadius: 2,
2000
- display: "inline-flex",
2001
- justifyContent: "center",
2002
- alignItems: "center",
2003
- marginRight: 4,
2004
- lineHeight: "12px"
2005
- }
2006
- },
2007
- arrow
2008
- ), /* @__PURE__ */ import_react4.default.createElement(import_react_inspector.ObjectPreview, { data }));
2009
- } else {
2010
- return /* @__PURE__ */ import_react4.default.createElement(import_react_inspector.ObjectPreview, { data });
2011
- }
2012
- };
2013
- function Arrow({
2014
- expanded,
2015
- onClick,
2016
- style
2017
- }) {
2018
- return /* @__PURE__ */ import_react4.default.createElement(
2019
- "span",
2020
- {
2021
- role: "button",
2022
- onClick,
2023
- style: {
2024
- display: "inline-block",
2025
- textAlign: "center",
2026
- transform: expanded ? "rotate(0deg)" : "rotate(-90deg)",
2027
- fontFamily: "Menlo, monospace",
2028
- ...style
2029
- }
2030
- },
2031
- "\u25BC"
2032
- );
2033
- }
2034
- function pathToString(extendedPath) {
2035
- return extendedPath.map(
2036
- (key) => typeof key === "object" ? `:${ellipsis(key.id.toString(), 8, "middle")}` : key
2037
- ).map(
2038
- (key, index) => index === 0 || typeof key === "string" && key.startsWith(":") ? key : `.${key}`
2039
- ).join("");
2040
- }
2041
- function ellipsis(str, maxLength, position = "end") {
2042
- if (str.length <= maxLength) return str;
2043
- switch (position) {
2044
- case "start":
2045
- return `\u2026${str.slice(str.length - maxLength)}`;
2046
- case "middle":
2047
- const halfLength = Math.floor(maxLength / 2);
2048
- return `${str.slice(0, halfLength)}\u2026${str.slice(str.length - halfLength)}`;
2049
- case "end":
2050
- return `${str.slice(0, maxLength)}\u2026`;
2051
- }
2052
- }
2053
- function SmallButton({
2054
- children,
2055
- onClick,
2056
- style,
2057
- theme,
2058
- disabled
2059
- }) {
2060
- return /* @__PURE__ */ import_react4.default.createElement(
2061
- "button",
2062
- {
2063
- type: "button",
2064
- disabled,
2065
- onClick: (event) => {
2066
- event.stopPropagation();
2067
- onClick();
2068
- },
2069
- style: {
2070
- flex: "0",
2071
- appearance: "none",
2072
- background: "none",
2073
- color: theme.BASE_COLOR,
2074
- opacity: disabled ? 0.25 : 1,
2075
- border: "none",
2076
- fontSize: "12px",
2077
- whiteSpace: "nowrap",
2078
- display: "inline-flex",
2079
- alignItems: "center",
2080
- justifyContent: "center",
2081
- padding: "0",
2082
- cursor: "pointer",
2083
- ...style
2084
- }
2085
- },
2086
- children
2087
- );
2088
- }
2089
- function ColoredDot({ type }) {
2090
- return /* @__PURE__ */ import_react4.default.createElement(
2091
- "span",
2092
- {
2093
- style: {
2094
- display: "inline-block",
2095
- width: 6,
2096
- height: 6,
2097
- background: type === "success" ? "rgba(0,200,0,0.8)" : "rgba(200,0,0,0.8)",
2098
- borderRadius: "50%",
2099
- verticalAlign: "middle"
2100
- }
2101
- }
2102
- );
2103
- }
2104
- function TitleLabel({ children }) {
2105
- return /* @__PURE__ */ import_react4.default.createElement("span", { style: { display: "flex", alignItems: "center", gap: "4px" } }, children);
2106
- }
2107
-
2108
- // src/inspector/useStateInspector.tsx
2109
- function createShadowRootElement() {
2110
- const host = document.createElement("div");
2111
- host.id = "noya-multiplayer-react-inspector-host";
2112
- const shadowRoot = host.attachShadow({ mode: "open" });
2113
- const container = document.createElement("div");
2114
- shadowRoot.appendChild(container);
2115
- return { host, container };
2116
- }
2117
- function useStateInspector({
2118
- noyaManager,
2119
- disabled = false,
2120
- colorScheme,
2121
- anchor
2122
- }) {
2123
- const [root, setRoot] = import_react5.default.useState(null);
2124
- (0, import_react5.useLayoutEffect)(() => {
2125
- if (disabled) return;
2126
- const { host, container } = createShadowRootElement();
2127
- const root2 = (0, import_client.createRoot)(container);
2128
- document.body.appendChild(host);
2129
- setRoot(root2);
2130
- return () => {
2131
- document.body.removeChild(host);
2132
- };
2133
- }, [disabled]);
2134
- (0, import_react5.useLayoutEffect)(() => {
2135
- if (!root) return;
2136
- root.render(
2137
- /* @__PURE__ */ import_react5.default.createElement(
2138
- StateInspector,
2139
- {
2140
- colorScheme,
2141
- anchor,
2142
- noyaManager
2143
- }
2144
- )
2145
- );
2146
- }, [noyaManager, anchor, colorScheme, root]);
2147
- }
2148
-
2149
- // src/hooks.ts
2150
- function useSyncStateManager(stateManager, path) {
2151
- const getSnapshot = (0, import_react6.useCallback)(
2152
- () => typeof path === "string" ? stateManager.getState(path) : stateManager.getState(),
2153
- [stateManager, path]
2154
- );
2155
- return (0, import_react6.useSyncExternalStore)(
2156
- stateManager.addListener,
2157
- getSnapshot,
2158
- getSnapshot
2159
- );
2160
- }
2161
- function useManagedState(createInitialState, options) {
2162
- const [stateManager] = (0, import_react6.useState)(
2163
- () => new import_state_manager.StateManager(createInitialState(), options)
2164
- );
2165
- const state = useSyncStateManager(stateManager);
2166
- const setState = (0, import_react6.useCallback)(
2167
- (...args) => {
2168
- const [metadata, action] = args.length === 1 ? [void 0, args[0]] : args;
2169
- if (metadata === void 0) {
2170
- const performActionNoMetadata = stateManager.performAction;
2171
- if (action instanceof Function) {
2172
- performActionNoMetadata({
2173
- run: action,
2174
- undo: () => state
2175
- });
2176
- } else {
2177
- performActionNoMetadata({
2178
- run: () => action,
2179
- undo: () => state
2180
- });
2181
- }
2182
- } else {
2183
- const performActionWithMetadata = stateManager.performAction;
2184
- if (action instanceof Function) {
2185
- performActionWithMetadata(metadata, {
2186
- run: action,
2187
- undo: () => state
2188
- });
2189
- } else {
2190
- performActionWithMetadata(metadata, {
2191
- run: () => action,
2192
- undo: () => state
2193
- });
2194
- }
2195
- }
2196
- },
2197
- [state, stateManager]
2198
- );
2199
- return [state, setState, stateManager];
2200
- }
2201
- function useManagedHistory(stateManager) {
2202
- return (0, import_react6.useSyncExternalStore)(
2203
- stateManager.historyEmittor.addListener,
2204
- stateManager.getHistorySnapshot,
2205
- stateManager.getHistorySnapshot
2206
- );
2207
- }
2208
- var defaultStubSync = (0, import_state_manager.stubSync)();
2209
- function useMultiplayerState(initialState, options) {
2210
- const {
2211
- sync = defaultStubSync,
2212
- inspector,
2213
- ...rest
2214
- } = options ?? {};
2215
- const [noyaManager] = (0, import_react6.useState)(
2216
- () => new import_state_manager.NoyaManager(initialState, rest)
2217
- );
2218
- const state = useObservable(
2219
- noyaManager.multiplayerStateManager.optimisticState$
2220
- );
2221
- const assets = useObservable(noyaManager.assetManager.assets$);
2222
- const extras = (0, import_react6.useMemo)(() => {
2223
- return {
2224
- noyaManager,
2225
- taskManager: noyaManager.taskManager,
2226
- connectionEventManager: noyaManager.connectionEventManager,
2227
- connectedUsersManager: noyaManager.connectedUsersManager,
2228
- ephemeralUserDataManager: noyaManager.ephemeralUserDataManager,
2229
- multiplayerStateManager: noyaManager.multiplayerStateManager,
2230
- assetManager: noyaManager.assetManager,
2231
- aiManager: noyaManager.aiManager,
2232
- rpcManager: noyaManager.rpcManager,
2233
- workflowManager: noyaManager.workflowManager,
2234
- secretManager: noyaManager.secretManager,
2235
- menuItemsManager: noyaManager.menuManager,
2236
- createAsset: noyaManager.assetManager.create,
2237
- deleteAsset: noyaManager.assetManager.delete,
2238
- assets
2239
- };
2240
- }, [noyaManager, assets]);
2241
- const syncRef = (0, import_react6.useRef)(sync);
2242
- (0, import_react6.useEffect)(() => {
2243
- if (syncRef.current) {
2244
- return syncRef.current({ noyaManager });
2245
- }
2246
- }, [noyaManager]);
2247
- useErrorOverlay(noyaManager);
2248
- useStateInspector({
2249
- noyaManager,
2250
- disabled: !inspector,
2251
- ...typeof inspector === "object" && inspector
2252
- });
2253
- return [state, noyaManager.multiplayerStateManager.setState, extras];
2254
- }
2255
- function useErrorOverlay(noyaManager) {
2256
- const unrecoverableError = useObservable(noyaManager.unrecoverableError);
2257
- (0, import_react6.useEffect)(() => {
2258
- if (!unrecoverableError) return;
2259
- const el = document.createElement("div");
2260
- el.id = "noya-multiplayer-react-error-overlay";
2261
- document.body.appendChild(el);
2262
- const root = (0, import_client2.createRoot)(el);
2263
- root.render((0, import_react6.createElement)(ErrorOverlay, { error: unrecoverableError }));
2264
- return () => {
2265
- root.unmount();
2266
- el.remove();
2267
- };
2268
- });
2269
- }
2270
-
2271
- // ../../node_modules/@sinclair/typebox/build/esm/type/symbols/symbols.mjs
2272
- var TransformKind = Symbol.for("TypeBox.Transform");
2273
- var ReadonlyKind = Symbol.for("TypeBox.Readonly");
2274
- var OptionalKind = Symbol.for("TypeBox.Optional");
2275
- var Hint = Symbol.for("TypeBox.Hint");
2276
- var Kind = Symbol.for("TypeBox.Kind");
2277
-
2278
- // ../../node_modules/@sinclair/typebox/build/esm/type/any/any.mjs
2279
- function Any(options = {}) {
2280
- return { ...options, [Kind]: "Any" };
2281
- }
2282
-
2283
- // ../../node_modules/@sinclair/typebox/build/esm/type/guard/value.mjs
2284
- var value_exports = {};
2285
- __export(value_exports, {
2286
- IsArray: () => IsArray,
2287
- IsAsyncIterator: () => IsAsyncIterator,
2288
- IsBigInt: () => IsBigInt,
2289
- IsBoolean: () => IsBoolean,
2290
- IsDate: () => IsDate,
2291
- IsFunction: () => IsFunction,
2292
- IsIterator: () => IsIterator,
2293
- IsNull: () => IsNull,
2294
- IsNumber: () => IsNumber,
2295
- IsObject: () => IsObject,
2296
- IsRegExp: () => IsRegExp,
2297
- IsString: () => IsString,
2298
- IsSymbol: () => IsSymbol,
2299
- IsUint8Array: () => IsUint8Array,
2300
- IsUndefined: () => IsUndefined
2301
- });
2302
- function IsAsyncIterator(value) {
2303
- return IsObject(value) && !IsArray(value) && !IsUint8Array(value) && Symbol.asyncIterator in value;
2304
- }
2305
- function IsArray(value) {
2306
- return Array.isArray(value);
2307
- }
2308
- function IsBigInt(value) {
2309
- return typeof value === "bigint";
2310
- }
2311
- function IsBoolean(value) {
2312
- return typeof value === "boolean";
2313
- }
2314
- function IsDate(value) {
2315
- return value instanceof globalThis.Date;
2316
- }
2317
- function IsFunction(value) {
2318
- return typeof value === "function";
2319
- }
2320
- function IsIterator(value) {
2321
- return IsObject(value) && !IsArray(value) && !IsUint8Array(value) && Symbol.iterator in value;
2322
- }
2323
- function IsNull(value) {
2324
- return value === null;
2325
- }
2326
- function IsNumber(value) {
2327
- return typeof value === "number";
2328
- }
2329
- function IsObject(value) {
2330
- return typeof value === "object" && value !== null;
2331
- }
2332
- function IsRegExp(value) {
2333
- return value instanceof globalThis.RegExp;
2334
- }
2335
- function IsString(value) {
2336
- return typeof value === "string";
2337
- }
2338
- function IsSymbol(value) {
2339
- return typeof value === "symbol";
2340
- }
2341
- function IsUint8Array(value) {
2342
- return value instanceof globalThis.Uint8Array;
2343
- }
2344
- function IsUndefined(value) {
2345
- return value === void 0;
2346
- }
2347
-
2348
- // ../../node_modules/@sinclair/typebox/build/esm/type/clone/value.mjs
2349
- function ArrayType(value) {
2350
- return value.map((value2) => Visit(value2));
2351
- }
2352
- function DateType(value) {
2353
- return new Date(value.getTime());
2354
- }
2355
- function Uint8ArrayType(value) {
2356
- return new Uint8Array(value);
2357
- }
2358
- function RegExpType(value) {
2359
- return new RegExp(value.source, value.flags);
2360
- }
2361
- function ObjectType(value) {
2362
- const result = {};
2363
- for (const key of Object.getOwnPropertyNames(value)) {
2364
- result[key] = Visit(value[key]);
2365
- }
2366
- for (const key of Object.getOwnPropertySymbols(value)) {
2367
- result[key] = Visit(value[key]);
2368
- }
2369
- return result;
2370
- }
2371
- function Visit(value) {
2372
- return IsArray(value) ? ArrayType(value) : IsDate(value) ? DateType(value) : IsUint8Array(value) ? Uint8ArrayType(value) : IsRegExp(value) ? RegExpType(value) : IsObject(value) ? ObjectType(value) : value;
2373
- }
2374
- function Clone(value) {
2375
- return Visit(value);
2376
- }
2377
-
2378
- // ../../node_modules/@sinclair/typebox/build/esm/type/clone/type.mjs
2379
- function CloneRest(schemas) {
2380
- return schemas.map((schema) => CloneType(schema));
2381
- }
2382
- function CloneType(schema, options = {}) {
2383
- return { ...Clone(schema), ...options };
2384
- }
2385
-
2386
- // ../../node_modules/@sinclair/typebox/build/esm/type/array/array.mjs
2387
- function Array2(schema, options = {}) {
2388
- return {
2389
- ...options,
2390
- [Kind]: "Array",
2391
- type: "array",
2392
- items: CloneType(schema)
1075
+
1076
+ // ../../node_modules/@sinclair/typebox/build/esm/type/clone/type.mjs
1077
+ function CloneRest(schemas) {
1078
+ return schemas.map((schema) => CloneType(schema));
1079
+ }
1080
+ function CloneType(schema, options = {}) {
1081
+ return { ...Clone(schema), ...options };
1082
+ }
1083
+
1084
+ // ../../node_modules/@sinclair/typebox/build/esm/type/array/array.mjs
1085
+ function Array2(schema, options = {}) {
1086
+ return {
1087
+ ...options,
1088
+ [Kind]: "Array",
1089
+ type: "array",
1090
+ items: CloneType(schema)
2393
1091
  };
2394
1092
  }
2395
1093
 
@@ -4556,452 +3254,1744 @@ function RequiredFromMappedResult(R, options) {
4556
3254
  function RestResolve(T) {
4557
3255
  return IsIntersect(T) ? CloneRest(T.allOf) : IsUnion(T) ? CloneRest(T.anyOf) : IsTuple(T) ? CloneRest(T.items ?? []) : [];
4558
3256
  }
4559
- function Rest(T) {
4560
- return CloneRest(RestResolve(T));
3257
+ function Rest(T) {
3258
+ return CloneRest(RestResolve(T));
3259
+ }
3260
+
3261
+ // ../../node_modules/@sinclair/typebox/build/esm/type/return-type/return-type.mjs
3262
+ function ReturnType(schema, options = {}) {
3263
+ return CloneType(schema.returns, options);
3264
+ }
3265
+
3266
+ // ../../node_modules/@sinclair/typebox/build/esm/type/strict/strict.mjs
3267
+ function Strict(schema) {
3268
+ return JSON.parse(JSON.stringify(schema));
3269
+ }
3270
+
3271
+ // ../../node_modules/@sinclair/typebox/build/esm/type/transform/transform.mjs
3272
+ var TransformDecodeBuilder = class {
3273
+ schema;
3274
+ constructor(schema) {
3275
+ this.schema = schema;
3276
+ }
3277
+ Decode(decode) {
3278
+ return new TransformEncodeBuilder(this.schema, decode);
3279
+ }
3280
+ };
3281
+ var TransformEncodeBuilder = class {
3282
+ schema;
3283
+ decode;
3284
+ constructor(schema, decode) {
3285
+ this.schema = schema;
3286
+ this.decode = decode;
3287
+ }
3288
+ EncodeTransform(encode, schema) {
3289
+ const Encode = (value) => schema[TransformKind].Encode(encode(value));
3290
+ const Decode = (value) => this.decode(schema[TransformKind].Decode(value));
3291
+ const Codec = { Encode, Decode };
3292
+ return { ...schema, [TransformKind]: Codec };
3293
+ }
3294
+ EncodeSchema(encode, schema) {
3295
+ const Codec = { Decode: this.decode, Encode: encode };
3296
+ return { ...schema, [TransformKind]: Codec };
3297
+ }
3298
+ Encode(encode) {
3299
+ const schema = CloneType(this.schema);
3300
+ return IsTransform(schema) ? this.EncodeTransform(encode, schema) : this.EncodeSchema(encode, schema);
3301
+ }
3302
+ };
3303
+ function Transform(schema) {
3304
+ return new TransformDecodeBuilder(schema);
3305
+ }
3306
+
3307
+ // ../../node_modules/@sinclair/typebox/build/esm/type/unsafe/unsafe.mjs
3308
+ function Unsafe(options = {}) {
3309
+ return {
3310
+ ...options,
3311
+ [Kind]: options[Kind] ?? "Unsafe"
3312
+ };
3313
+ }
3314
+
3315
+ // ../../node_modules/@sinclair/typebox/build/esm/type/type/type.mjs
3316
+ var type_exports3 = {};
3317
+ __export(type_exports3, {
3318
+ Any: () => Any,
3319
+ Array: () => Array2,
3320
+ AsyncIterator: () => AsyncIterator,
3321
+ Awaited: () => Awaited,
3322
+ BigInt: () => BigInt2,
3323
+ Boolean: () => Boolean,
3324
+ Capitalize: () => Capitalize,
3325
+ Composite: () => Composite,
3326
+ Const: () => Const,
3327
+ Constructor: () => Constructor,
3328
+ ConstructorParameters: () => ConstructorParameters,
3329
+ Date: () => Date2,
3330
+ Deref: () => Deref,
3331
+ Enum: () => Enum,
3332
+ Exclude: () => Exclude,
3333
+ Extends: () => Extends,
3334
+ Extract: () => Extract,
3335
+ Function: () => Function2,
3336
+ Index: () => Index,
3337
+ InstanceType: () => InstanceType,
3338
+ Integer: () => Integer,
3339
+ Intersect: () => Intersect,
3340
+ Iterator: () => Iterator,
3341
+ KeyOf: () => KeyOf,
3342
+ Literal: () => Literal,
3343
+ Lowercase: () => Lowercase,
3344
+ Mapped: () => Mapped,
3345
+ Never: () => Never,
3346
+ Not: () => Not,
3347
+ Null: () => Null,
3348
+ Number: () => Number2,
3349
+ Object: () => Object2,
3350
+ Omit: () => Omit,
3351
+ Optional: () => Optional,
3352
+ Parameters: () => Parameters,
3353
+ Partial: () => Partial,
3354
+ Pick: () => Pick,
3355
+ Promise: () => Promise2,
3356
+ Readonly: () => Readonly,
3357
+ ReadonlyOptional: () => ReadonlyOptional,
3358
+ Record: () => Record,
3359
+ Recursive: () => Recursive,
3360
+ Ref: () => Ref,
3361
+ RegExp: () => RegExp2,
3362
+ Required: () => Required,
3363
+ Rest: () => Rest,
3364
+ ReturnType: () => ReturnType,
3365
+ Strict: () => Strict,
3366
+ String: () => String,
3367
+ Symbol: () => Symbol2,
3368
+ TemplateLiteral: () => TemplateLiteral,
3369
+ Transform: () => Transform,
3370
+ Tuple: () => Tuple,
3371
+ Uint8Array: () => Uint8Array2,
3372
+ Uncapitalize: () => Uncapitalize,
3373
+ Undefined: () => Undefined,
3374
+ Union: () => Union,
3375
+ Unknown: () => Unknown,
3376
+ Unsafe: () => Unsafe,
3377
+ Uppercase: () => Uppercase,
3378
+ Void: () => Void
3379
+ });
3380
+
3381
+ // ../../node_modules/@sinclair/typebox/build/esm/type/void/void.mjs
3382
+ function Void(options = {}) {
3383
+ return {
3384
+ ...options,
3385
+ [Kind]: "Void",
3386
+ type: "void"
3387
+ };
3388
+ }
3389
+
3390
+ // ../../node_modules/@sinclair/typebox/build/esm/type/type/index.mjs
3391
+ var Type = type_exports3;
3392
+
3393
+ // ../noya-schemas/src/filesSchema.ts
3394
+ var encodingSchema = Type.Union([
3395
+ Type.Literal("utf-8"),
3396
+ Type.Literal("base64")
3397
+ ]);
3398
+ var folderMediaItemSchema = Type.Object({
3399
+ id: Type.String({ format: "uuid", default: "" }),
3400
+ kind: Type.Literal("folder")
3401
+ });
3402
+ var assetMediaItemSchema = Type.Object({
3403
+ id: Type.String({ format: "uuid", default: "" }),
3404
+ kind: Type.Literal("asset"),
3405
+ assetId: Type.String()
3406
+ });
3407
+ var fileSchema = Type.Object({
3408
+ id: Type.String({ format: "uuid", default: "" }),
3409
+ kind: Type.Literal("file"),
3410
+ content: Type.String(),
3411
+ encoding: encodingSchema
3412
+ });
3413
+ var mediaItemSchema = Type.Union(
3414
+ [folderMediaItemSchema, assetMediaItemSchema, fileSchema],
3415
+ {
3416
+ discriminator: "kind"
3417
+ }
3418
+ );
3419
+ var mediaMapSchema = Type.Record(Type.String(), mediaItemSchema);
3420
+
3421
+ // ../noya-schemas/src/jsonSchema.ts
3422
+ var jsonSchema = Type.Recursive(
3423
+ (This) => Type.Union(
3424
+ [
3425
+ Type.Object({
3426
+ type: Type.Literal("string"),
3427
+ default: Type.Optional(Type.String()),
3428
+ _kind: Type.Literal("String")
3429
+ }),
3430
+ Type.Object({
3431
+ type: Type.Literal("number"),
3432
+ default: Type.Optional(Type.Number()),
3433
+ minimum: Type.Optional(Type.Number()),
3434
+ maximum: Type.Optional(Type.Number()),
3435
+ _kind: Type.Literal("Number")
3436
+ }),
3437
+ Type.Object({
3438
+ type: Type.Literal("boolean"),
3439
+ default: Type.Optional(Type.Boolean()),
3440
+ _kind: Type.Literal("Boolean")
3441
+ }),
3442
+ Type.Object({
3443
+ type: Type.Literal("null"),
3444
+ _kind: Type.Literal("Null")
3445
+ }),
3446
+ Type.Object({
3447
+ type: Type.Literal("array"),
3448
+ items: This,
3449
+ // default: Type.Optional(Type.Array(Type.Any())),
3450
+ // minItems: Type.Optional(Type.Number()),
3451
+ // maxItems: Type.Optional(Type.Number()),
3452
+ _kind: Type.Literal("Array")
3453
+ }),
3454
+ Type.Object({
3455
+ type: Type.Literal("object"),
3456
+ properties: Type.Record(Type.String(), This),
3457
+ required: Type.Optional(Type.Array(Type.String())),
3458
+ // default: Type.Optional(Type.Record(Type.String(), Type.Any())),
3459
+ _kind: Type.Literal("Object")
3460
+ })
3461
+ ],
3462
+ {
3463
+ discriminator: "type"
3464
+ }
3465
+ ),
3466
+ {
3467
+ $id: "jsonSchema"
3468
+ }
3469
+ );
3470
+
3471
+ // ../noya-schemas/src/input.ts
3472
+ function Nullable(type) {
3473
+ return Type.Union([type, Type.Null()]);
3474
+ }
3475
+ var inputSchemaBase = {
3476
+ id: Type.String({ format: "uuid", default: "" }),
3477
+ name: Type.String(),
3478
+ description: Nullable(Type.String()),
3479
+ required: Type.Boolean({ default: false })
3480
+ };
3481
+ var fileInputSchema = Type.Object({
3482
+ ...inputSchemaBase,
3483
+ kind: Type.Literal("file"),
3484
+ toolId: Nullable(Type.String())
3485
+ });
3486
+ var dataInputSchema = Type.Object({
3487
+ ...inputSchemaBase,
3488
+ kind: Type.Literal("data"),
3489
+ schema: Nullable(jsonSchema)
3490
+ });
3491
+ var secretInputSchema = Type.Object({
3492
+ ...inputSchemaBase,
3493
+ kind: Type.Literal("secret")
3494
+ });
3495
+ var inputSchema = Type.Union(
3496
+ [fileInputSchema, dataInputSchema, secretInputSchema],
3497
+ {
3498
+ discriminator: "kind"
3499
+ }
3500
+ );
3501
+ var outputTransformSchemaBase = {
3502
+ id: Type.String({ format: "uuid", default: "" }),
3503
+ order: Type.Number()
3504
+ };
3505
+ var scriptOutputTransformSchema = Type.Object({
3506
+ ...outputTransformSchemaBase,
3507
+ kind: Type.Literal("script"),
3508
+ location: Type.Union([Type.Literal("state"), Type.Literal("url")]),
3509
+ value: Type.String()
3510
+ });
3511
+ var jsonPointerOutputTransformSchema = Type.Object({
3512
+ ...outputTransformSchemaBase,
3513
+ kind: Type.Literal("jsonPointer"),
3514
+ value: Type.String()
3515
+ });
3516
+ var outputTransformSchema = Type.Union(
3517
+ [scriptOutputTransformSchema, jsonPointerOutputTransformSchema],
3518
+ { discriminator: "kind" }
3519
+ );
3520
+
3521
+ // ../../node_modules/@sinclair/typebox/build/esm/value/guard/guard.mjs
3522
+ function IsObject4(value) {
3523
+ return value !== null && typeof value === "object";
3524
+ }
3525
+ function IsArray4(value) {
3526
+ return Array.isArray(value) && !ArrayBuffer.isView(value);
4561
3527
  }
4562
-
4563
- // ../../node_modules/@sinclair/typebox/build/esm/type/return-type/return-type.mjs
4564
- function ReturnType(schema, options = {}) {
4565
- return CloneType(schema.returns, options);
3528
+ function IsUndefined4(value) {
3529
+ return value === void 0;
4566
3530
  }
4567
-
4568
- // ../../node_modules/@sinclair/typebox/build/esm/type/strict/strict.mjs
4569
- function Strict(schema) {
4570
- return JSON.parse(JSON.stringify(schema));
3531
+ function IsNumber4(value) {
3532
+ return typeof value === "number";
4571
3533
  }
4572
3534
 
4573
- // ../../node_modules/@sinclair/typebox/build/esm/type/transform/transform.mjs
4574
- var TransformDecodeBuilder = class {
4575
- schema;
4576
- constructor(schema) {
4577
- this.schema = schema;
3535
+ // ../../node_modules/@sinclair/typebox/build/esm/system/policy.mjs
3536
+ var TypeSystemPolicy;
3537
+ (function(TypeSystemPolicy2) {
3538
+ TypeSystemPolicy2.ExactOptionalPropertyTypes = false;
3539
+ TypeSystemPolicy2.AllowArrayObject = false;
3540
+ TypeSystemPolicy2.AllowNaN = false;
3541
+ TypeSystemPolicy2.AllowNullVoid = false;
3542
+ function IsExactOptionalProperty(value, key) {
3543
+ return TypeSystemPolicy2.ExactOptionalPropertyTypes ? key in value : value[key] !== void 0;
4578
3544
  }
4579
- Decode(decode) {
4580
- return new TransformEncodeBuilder(this.schema, decode);
3545
+ TypeSystemPolicy2.IsExactOptionalProperty = IsExactOptionalProperty;
3546
+ function IsObjectLike(value) {
3547
+ const isObject = IsObject4(value);
3548
+ return TypeSystemPolicy2.AllowArrayObject ? isObject : isObject && !IsArray4(value);
4581
3549
  }
4582
- };
4583
- var TransformEncodeBuilder = class {
4584
- schema;
4585
- decode;
4586
- constructor(schema, decode) {
4587
- this.schema = schema;
4588
- this.decode = decode;
3550
+ TypeSystemPolicy2.IsObjectLike = IsObjectLike;
3551
+ function IsRecordLike(value) {
3552
+ return IsObjectLike(value) && !(value instanceof Date) && !(value instanceof Uint8Array);
4589
3553
  }
4590
- EncodeTransform(encode, schema) {
4591
- const Encode = (value) => schema[TransformKind].Encode(encode(value));
4592
- const Decode = (value) => this.decode(schema[TransformKind].Decode(value));
4593
- const Codec = { Encode, Decode };
4594
- return { ...schema, [TransformKind]: Codec };
3554
+ TypeSystemPolicy2.IsRecordLike = IsRecordLike;
3555
+ function IsNumberLike(value) {
3556
+ return TypeSystemPolicy2.AllowNaN ? IsNumber4(value) : Number.isFinite(value);
4595
3557
  }
4596
- EncodeSchema(encode, schema) {
4597
- const Codec = { Decode: this.decode, Encode: encode };
4598
- return { ...schema, [TransformKind]: Codec };
3558
+ TypeSystemPolicy2.IsNumberLike = IsNumberLike;
3559
+ function IsVoidLike(value) {
3560
+ const isUndefined = IsUndefined4(value);
3561
+ return TypeSystemPolicy2.AllowNullVoid ? isUndefined || value === null : isUndefined;
4599
3562
  }
4600
- Encode(encode) {
4601
- const schema = CloneType(this.schema);
4602
- return IsTransform(schema) ? this.EncodeTransform(encode, schema) : this.EncodeSchema(encode, schema);
3563
+ TypeSystemPolicy2.IsVoidLike = IsVoidLike;
3564
+ })(TypeSystemPolicy || (TypeSystemPolicy = {}));
3565
+
3566
+ // ../../node_modules/@sinclair/typebox/build/esm/system/system.mjs
3567
+ var TypeSystemDuplicateTypeKind = class extends TypeBoxError {
3568
+ constructor(kind) {
3569
+ super(`Duplicate type kind '${kind}' detected`);
4603
3570
  }
4604
3571
  };
4605
- function Transform(schema) {
4606
- return new TransformDecodeBuilder(schema);
4607
- }
3572
+ var TypeSystemDuplicateFormat = class extends TypeBoxError {
3573
+ constructor(kind) {
3574
+ super(`Duplicate string format '${kind}' detected`);
3575
+ }
3576
+ };
3577
+ var TypeSystem;
3578
+ (function(TypeSystem2) {
3579
+ function Type2(kind, check) {
3580
+ if (type_exports2.Has(kind))
3581
+ throw new TypeSystemDuplicateTypeKind(kind);
3582
+ type_exports2.Set(kind, check);
3583
+ return (options = {}) => Unsafe({ ...options, [Kind]: kind });
3584
+ }
3585
+ TypeSystem2.Type = Type2;
3586
+ function Format(format, check) {
3587
+ if (format_exports.Has(format))
3588
+ throw new TypeSystemDuplicateFormat(format);
3589
+ format_exports.Set(format, check);
3590
+ return format;
3591
+ }
3592
+ TypeSystem2.Format = Format;
3593
+ })(TypeSystem || (TypeSystem = {}));
4608
3594
 
4609
- // ../../node_modules/@sinclair/typebox/build/esm/type/unsafe/unsafe.mjs
4610
- function Unsafe(options = {}) {
4611
- return {
4612
- ...options,
4613
- [Kind]: options[Kind] ?? "Unsafe"
4614
- };
4615
- }
3595
+ // ../../node_modules/@sinclair/typebox/build/esm/value/hash/hash.mjs
3596
+ var ByteMarker;
3597
+ (function(ByteMarker2) {
3598
+ ByteMarker2[ByteMarker2["Undefined"] = 0] = "Undefined";
3599
+ ByteMarker2[ByteMarker2["Null"] = 1] = "Null";
3600
+ ByteMarker2[ByteMarker2["Boolean"] = 2] = "Boolean";
3601
+ ByteMarker2[ByteMarker2["Number"] = 3] = "Number";
3602
+ ByteMarker2[ByteMarker2["String"] = 4] = "String";
3603
+ ByteMarker2[ByteMarker2["Object"] = 5] = "Object";
3604
+ ByteMarker2[ByteMarker2["Array"] = 6] = "Array";
3605
+ ByteMarker2[ByteMarker2["Date"] = 7] = "Date";
3606
+ ByteMarker2[ByteMarker2["Uint8Array"] = 8] = "Uint8Array";
3607
+ ByteMarker2[ByteMarker2["Symbol"] = 9] = "Symbol";
3608
+ ByteMarker2[ByteMarker2["BigInt"] = 10] = "BigInt";
3609
+ })(ByteMarker || (ByteMarker = {}));
3610
+ var Accumulator = BigInt("14695981039346656037");
3611
+ var [Prime, Size] = [BigInt("1099511628211"), BigInt("2") ** BigInt("64")];
3612
+ var Bytes = Array.from({ length: 256 }).map((_, i) => BigInt(i));
3613
+ var F64 = new Float64Array(1);
3614
+ var F64In = new DataView(F64.buffer);
3615
+ var F64Out = new Uint8Array(F64.buffer);
4616
3616
 
4617
- // ../../node_modules/@sinclair/typebox/build/esm/type/type/type.mjs
4618
- var type_exports3 = {};
4619
- __export(type_exports3, {
4620
- Any: () => Any,
4621
- Array: () => Array2,
4622
- AsyncIterator: () => AsyncIterator,
4623
- Awaited: () => Awaited,
4624
- BigInt: () => BigInt2,
4625
- Boolean: () => Boolean,
4626
- Capitalize: () => Capitalize,
4627
- Composite: () => Composite,
4628
- Const: () => Const,
4629
- Constructor: () => Constructor,
4630
- ConstructorParameters: () => ConstructorParameters,
4631
- Date: () => Date2,
4632
- Deref: () => Deref,
4633
- Enum: () => Enum,
4634
- Exclude: () => Exclude,
4635
- Extends: () => Extends,
4636
- Extract: () => Extract,
4637
- Function: () => Function2,
4638
- Index: () => Index,
4639
- InstanceType: () => InstanceType,
4640
- Integer: () => Integer,
4641
- Intersect: () => Intersect,
4642
- Iterator: () => Iterator,
4643
- KeyOf: () => KeyOf,
4644
- Literal: () => Literal,
4645
- Lowercase: () => Lowercase,
4646
- Mapped: () => Mapped,
4647
- Never: () => Never,
4648
- Not: () => Not,
4649
- Null: () => Null,
4650
- Number: () => Number2,
4651
- Object: () => Object2,
4652
- Omit: () => Omit,
4653
- Optional: () => Optional,
4654
- Parameters: () => Parameters,
4655
- Partial: () => Partial,
4656
- Pick: () => Pick,
4657
- Promise: () => Promise2,
4658
- Readonly: () => Readonly,
4659
- ReadonlyOptional: () => ReadonlyOptional,
4660
- Record: () => Record,
4661
- Recursive: () => Recursive,
4662
- Ref: () => Ref,
4663
- RegExp: () => RegExp2,
4664
- Required: () => Required,
4665
- Rest: () => Rest,
4666
- ReturnType: () => ReturnType,
4667
- Strict: () => Strict,
4668
- String: () => String,
4669
- Symbol: () => Symbol2,
4670
- TemplateLiteral: () => TemplateLiteral,
4671
- Transform: () => Transform,
4672
- Tuple: () => Tuple,
4673
- Uint8Array: () => Uint8Array2,
4674
- Uncapitalize: () => Uncapitalize,
4675
- Undefined: () => Undefined,
4676
- Union: () => Union,
4677
- Unknown: () => Unknown,
4678
- Unsafe: () => Unsafe,
4679
- Uppercase: () => Uppercase,
4680
- Void: () => Void
3617
+ // ../../node_modules/@sinclair/typebox/build/esm/errors/errors.mjs
3618
+ var ValueErrorType;
3619
+ (function(ValueErrorType2) {
3620
+ ValueErrorType2[ValueErrorType2["ArrayContains"] = 0] = "ArrayContains";
3621
+ ValueErrorType2[ValueErrorType2["ArrayMaxContains"] = 1] = "ArrayMaxContains";
3622
+ ValueErrorType2[ValueErrorType2["ArrayMaxItems"] = 2] = "ArrayMaxItems";
3623
+ ValueErrorType2[ValueErrorType2["ArrayMinContains"] = 3] = "ArrayMinContains";
3624
+ ValueErrorType2[ValueErrorType2["ArrayMinItems"] = 4] = "ArrayMinItems";
3625
+ ValueErrorType2[ValueErrorType2["ArrayUniqueItems"] = 5] = "ArrayUniqueItems";
3626
+ ValueErrorType2[ValueErrorType2["Array"] = 6] = "Array";
3627
+ ValueErrorType2[ValueErrorType2["AsyncIterator"] = 7] = "AsyncIterator";
3628
+ ValueErrorType2[ValueErrorType2["BigIntExclusiveMaximum"] = 8] = "BigIntExclusiveMaximum";
3629
+ ValueErrorType2[ValueErrorType2["BigIntExclusiveMinimum"] = 9] = "BigIntExclusiveMinimum";
3630
+ ValueErrorType2[ValueErrorType2["BigIntMaximum"] = 10] = "BigIntMaximum";
3631
+ ValueErrorType2[ValueErrorType2["BigIntMinimum"] = 11] = "BigIntMinimum";
3632
+ ValueErrorType2[ValueErrorType2["BigIntMultipleOf"] = 12] = "BigIntMultipleOf";
3633
+ ValueErrorType2[ValueErrorType2["BigInt"] = 13] = "BigInt";
3634
+ ValueErrorType2[ValueErrorType2["Boolean"] = 14] = "Boolean";
3635
+ ValueErrorType2[ValueErrorType2["DateExclusiveMaximumTimestamp"] = 15] = "DateExclusiveMaximumTimestamp";
3636
+ ValueErrorType2[ValueErrorType2["DateExclusiveMinimumTimestamp"] = 16] = "DateExclusiveMinimumTimestamp";
3637
+ ValueErrorType2[ValueErrorType2["DateMaximumTimestamp"] = 17] = "DateMaximumTimestamp";
3638
+ ValueErrorType2[ValueErrorType2["DateMinimumTimestamp"] = 18] = "DateMinimumTimestamp";
3639
+ ValueErrorType2[ValueErrorType2["DateMultipleOfTimestamp"] = 19] = "DateMultipleOfTimestamp";
3640
+ ValueErrorType2[ValueErrorType2["Date"] = 20] = "Date";
3641
+ ValueErrorType2[ValueErrorType2["Function"] = 21] = "Function";
3642
+ ValueErrorType2[ValueErrorType2["IntegerExclusiveMaximum"] = 22] = "IntegerExclusiveMaximum";
3643
+ ValueErrorType2[ValueErrorType2["IntegerExclusiveMinimum"] = 23] = "IntegerExclusiveMinimum";
3644
+ ValueErrorType2[ValueErrorType2["IntegerMaximum"] = 24] = "IntegerMaximum";
3645
+ ValueErrorType2[ValueErrorType2["IntegerMinimum"] = 25] = "IntegerMinimum";
3646
+ ValueErrorType2[ValueErrorType2["IntegerMultipleOf"] = 26] = "IntegerMultipleOf";
3647
+ ValueErrorType2[ValueErrorType2["Integer"] = 27] = "Integer";
3648
+ ValueErrorType2[ValueErrorType2["IntersectUnevaluatedProperties"] = 28] = "IntersectUnevaluatedProperties";
3649
+ ValueErrorType2[ValueErrorType2["Intersect"] = 29] = "Intersect";
3650
+ ValueErrorType2[ValueErrorType2["Iterator"] = 30] = "Iterator";
3651
+ ValueErrorType2[ValueErrorType2["Kind"] = 31] = "Kind";
3652
+ ValueErrorType2[ValueErrorType2["Literal"] = 32] = "Literal";
3653
+ ValueErrorType2[ValueErrorType2["Never"] = 33] = "Never";
3654
+ ValueErrorType2[ValueErrorType2["Not"] = 34] = "Not";
3655
+ ValueErrorType2[ValueErrorType2["Null"] = 35] = "Null";
3656
+ ValueErrorType2[ValueErrorType2["NumberExclusiveMaximum"] = 36] = "NumberExclusiveMaximum";
3657
+ ValueErrorType2[ValueErrorType2["NumberExclusiveMinimum"] = 37] = "NumberExclusiveMinimum";
3658
+ ValueErrorType2[ValueErrorType2["NumberMaximum"] = 38] = "NumberMaximum";
3659
+ ValueErrorType2[ValueErrorType2["NumberMinimum"] = 39] = "NumberMinimum";
3660
+ ValueErrorType2[ValueErrorType2["NumberMultipleOf"] = 40] = "NumberMultipleOf";
3661
+ ValueErrorType2[ValueErrorType2["Number"] = 41] = "Number";
3662
+ ValueErrorType2[ValueErrorType2["ObjectAdditionalProperties"] = 42] = "ObjectAdditionalProperties";
3663
+ ValueErrorType2[ValueErrorType2["ObjectMaxProperties"] = 43] = "ObjectMaxProperties";
3664
+ ValueErrorType2[ValueErrorType2["ObjectMinProperties"] = 44] = "ObjectMinProperties";
3665
+ ValueErrorType2[ValueErrorType2["ObjectRequiredProperty"] = 45] = "ObjectRequiredProperty";
3666
+ ValueErrorType2[ValueErrorType2["Object"] = 46] = "Object";
3667
+ ValueErrorType2[ValueErrorType2["Promise"] = 47] = "Promise";
3668
+ ValueErrorType2[ValueErrorType2["RegExp"] = 48] = "RegExp";
3669
+ ValueErrorType2[ValueErrorType2["StringFormatUnknown"] = 49] = "StringFormatUnknown";
3670
+ ValueErrorType2[ValueErrorType2["StringFormat"] = 50] = "StringFormat";
3671
+ ValueErrorType2[ValueErrorType2["StringMaxLength"] = 51] = "StringMaxLength";
3672
+ ValueErrorType2[ValueErrorType2["StringMinLength"] = 52] = "StringMinLength";
3673
+ ValueErrorType2[ValueErrorType2["StringPattern"] = 53] = "StringPattern";
3674
+ ValueErrorType2[ValueErrorType2["String"] = 54] = "String";
3675
+ ValueErrorType2[ValueErrorType2["Symbol"] = 55] = "Symbol";
3676
+ ValueErrorType2[ValueErrorType2["TupleLength"] = 56] = "TupleLength";
3677
+ ValueErrorType2[ValueErrorType2["Tuple"] = 57] = "Tuple";
3678
+ ValueErrorType2[ValueErrorType2["Uint8ArrayMaxByteLength"] = 58] = "Uint8ArrayMaxByteLength";
3679
+ ValueErrorType2[ValueErrorType2["Uint8ArrayMinByteLength"] = 59] = "Uint8ArrayMinByteLength";
3680
+ ValueErrorType2[ValueErrorType2["Uint8Array"] = 60] = "Uint8Array";
3681
+ ValueErrorType2[ValueErrorType2["Undefined"] = 61] = "Undefined";
3682
+ ValueErrorType2[ValueErrorType2["Union"] = 62] = "Union";
3683
+ ValueErrorType2[ValueErrorType2["Void"] = 63] = "Void";
3684
+ })(ValueErrorType || (ValueErrorType = {}));
3685
+
3686
+ // ../../node_modules/@sinclair/typebox/build/esm/value/delta/delta.mjs
3687
+ var Insert = Object2({
3688
+ type: Literal("insert"),
3689
+ path: String(),
3690
+ value: Unknown()
3691
+ });
3692
+ var Update = Object2({
3693
+ type: Literal("update"),
3694
+ path: String(),
3695
+ value: Unknown()
3696
+ });
3697
+ var Delete3 = Object2({
3698
+ type: Literal("delete"),
3699
+ path: String()
4681
3700
  });
3701
+ var Edit = Union([Insert, Update, Delete3]);
4682
3702
 
4683
- // ../../node_modules/@sinclair/typebox/build/esm/type/void/void.mjs
4684
- function Void(options = {}) {
4685
- return {
4686
- ...options,
4687
- [Kind]: "Void",
4688
- type: "void"
4689
- };
3703
+ // ../noya-schemas/src/SchemaTree.ts
3704
+ var import_tree_visit = __toESM(require_lib());
3705
+ var SchemaTree = (0, import_tree_visit.defineTree)((schema) => {
3706
+ if (type_exports.IsUnion(schema)) {
3707
+ return schema.anyOf;
3708
+ } else if (type_exports.IsObject(schema)) {
3709
+ return Object.values(schema.properties);
3710
+ } else if (type_exports.IsArray(schema)) {
3711
+ return [schema.items];
3712
+ }
3713
+ return [];
3714
+ }).withOptions({
3715
+ getLabel(node) {
3716
+ return node[Kind] ?? "<UnknownKind>";
3717
+ }
3718
+ });
3719
+ function findAllDefs(schema) {
3720
+ if (!schema) return [];
3721
+ return SchemaTree.flatMap(schema, (node) => {
3722
+ return node.$id ? [node] : [];
3723
+ });
4690
3724
  }
4691
3725
 
4692
- // ../../node_modules/@sinclair/typebox/build/esm/type/type/index.mjs
4693
- var Type = type_exports3;
3726
+ // ../noya-schemas/src/index.ts
3727
+ function validateUUID(value) {
3728
+ return /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.test(
3729
+ value
3730
+ );
3731
+ }
3732
+ format_exports.Set("color", () => true);
3733
+ format_exports.Set("uuid", validateUUID);
4694
3734
 
4695
- // ../noya-schemas/src/jsonSchema.ts
4696
- var jsonSchema = Type.Recursive(
4697
- (This) => Type.Union(
4698
- [
4699
- Type.Object({
4700
- type: Type.Literal("string"),
4701
- default: Type.Optional(Type.String()),
4702
- _kind: Type.Literal("String")
4703
- }),
4704
- Type.Object({
4705
- type: Type.Literal("number"),
4706
- default: Type.Optional(Type.Number()),
4707
- minimum: Type.Optional(Type.Number()),
4708
- maximum: Type.Optional(Type.Number()),
4709
- _kind: Type.Literal("Number")
4710
- }),
4711
- Type.Object({
4712
- type: Type.Literal("boolean"),
4713
- default: Type.Optional(Type.Boolean()),
4714
- _kind: Type.Literal("Boolean")
4715
- }),
4716
- Type.Object({
4717
- type: Type.Literal("null"),
4718
- _kind: Type.Literal("Null")
4719
- }),
4720
- Type.Object({
4721
- type: Type.Literal("array"),
4722
- items: This,
4723
- // default: Type.Optional(Type.Array(Type.Any())),
4724
- // minItems: Type.Optional(Type.Number()),
4725
- // maxItems: Type.Optional(Type.Number()),
4726
- _kind: Type.Literal("Array")
4727
- }),
4728
- Type.Object({
4729
- type: Type.Literal("object"),
4730
- properties: Type.Record(Type.String(), This),
4731
- required: Type.Optional(Type.Array(Type.String())),
4732
- // default: Type.Optional(Type.Record(Type.String(), Type.Any())),
4733
- _kind: Type.Literal("Object")
4734
- })
4735
- ],
4736
- {
4737
- discriminator: "type"
4738
- }
4739
- ),
4740
- {
4741
- $id: "jsonSchema"
4742
- }
4743
- );
3735
+ // src/noyaApp.ts
3736
+ var import_state_manager2 = require("@noya-app/state-manager");
3737
+ var import_react6 = require("react");
4744
3738
 
4745
- // ../noya-schemas/src/input.ts
4746
- function Nullable(type) {
4747
- return Type.Union([type, Type.Null()]);
4748
- }
4749
- var inputSchemaBase = {
4750
- id: Type.String({ format: "uuid", default: "" }),
4751
- name: Type.String(),
4752
- description: Nullable(Type.String()),
4753
- required: Type.Boolean({ default: false })
4754
- };
4755
- var fileInputSchema = Type.Object({
4756
- ...inputSchemaBase,
4757
- kind: Type.Literal("file"),
4758
- toolId: Nullable(Type.String())
4759
- });
4760
- var dataInputSchema = Type.Object({
4761
- ...inputSchemaBase,
4762
- kind: Type.Literal("data"),
4763
- schema: Nullable(jsonSchema)
4764
- });
4765
- var inputSchema = Type.Union([fileInputSchema, dataInputSchema], {
4766
- discriminator: "kind"
4767
- });
4768
- var outputTransformSchemaBase = {
4769
- id: Type.String({ format: "uuid", default: "" }),
4770
- order: Type.Number()
4771
- };
4772
- var scriptOutputTransformSchema = Type.Object({
4773
- ...outputTransformSchemaBase,
4774
- kind: Type.Literal("script"),
4775
- location: Type.Union([Type.Literal("state"), Type.Literal("url")]),
4776
- value: Type.String()
4777
- });
4778
- var jsonPointerOutputTransformSchema = Type.Object({
4779
- ...outputTransformSchemaBase,
4780
- kind: Type.Literal("jsonPointer"),
4781
- value: Type.String()
3739
+ // src/hooks.ts
3740
+ var import_state_manager = require("@noya-app/state-manager");
3741
+ var import_react5 = require("react");
3742
+ var import_client2 = require("react-dom/client");
3743
+
3744
+ // src/components/ErrorOverlay.tsx
3745
+ var React = __toESM(require("react"));
3746
+ var ErrorOverlay = React.memo(function ErrorOverlay2({
3747
+ error
3748
+ }) {
3749
+ return /* @__PURE__ */ React.createElement(
3750
+ "div",
3751
+ {
3752
+ style: {
3753
+ position: "fixed",
3754
+ top: "20px",
3755
+ left: "50%",
3756
+ transform: "translateX(-50%)",
3757
+ maxWidth: "80%",
3758
+ width: "fit-content",
3759
+ padding: "12px 20px",
3760
+ background: "white",
3761
+ color: "black",
3762
+ zIndex: 1e4,
3763
+ display: "flex",
3764
+ flexDirection: "column",
3765
+ justifyContent: "center",
3766
+ borderRadius: "4px",
3767
+ boxShadow: "0 4px 6px rgba(0, 0, 0, 0.1)",
3768
+ fontFamily: "'__Inter_6b0edc', '__Inter_Fallback_6b0edc', -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Segoe UI', Roboto, Helvetica, Arial, sans-serif",
3769
+ fontSize: "14px",
3770
+ fontWeight: 400,
3771
+ lineHeight: "19px"
3772
+ }
3773
+ },
3774
+ error.reason === "schemaMigration" ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("p", null, "An updated version of Noya is available. Please reload the page to continue.")) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("p", null, "An error occurred:", " ", /* @__PURE__ */ React.createElement(
3775
+ "code",
3776
+ {
3777
+ style: {
3778
+ background: "rgba(255, 0, 0, 0.1)",
3779
+ color: "rgba(255, 0, 0, 0.5)",
3780
+ padding: "2px 4px",
3781
+ borderRadius: "4px"
3782
+ }
3783
+ },
3784
+ error.reason
3785
+ ), ". Please reload the page to continue.", /* @__PURE__ */ React.createElement("br", null), /* @__PURE__ */ React.createElement("br", null), "If this happens repeatedly, please get in touch and the Noya team can help.")),
3786
+ /* @__PURE__ */ React.createElement(
3787
+ "div",
3788
+ {
3789
+ style: {
3790
+ height: "1px",
3791
+ background: "rgba(0, 0, 0, 0.1)",
3792
+ margin: "12px -20px"
3793
+ }
3794
+ }
3795
+ ),
3796
+ /* @__PURE__ */ React.createElement(
3797
+ "button",
3798
+ {
3799
+ style: {
3800
+ background: "black",
3801
+ color: "white",
3802
+ padding: "8px 16px",
3803
+ borderRadius: "4px",
3804
+ cursor: "pointer",
3805
+ fontSize: "14px",
3806
+ fontWeight: 700,
3807
+ lineHeight: "19px"
3808
+ },
3809
+ onClick: () => {
3810
+ window.location.reload();
3811
+ }
3812
+ },
3813
+ "Reload"
3814
+ )
3815
+ );
4782
3816
  });
4783
- var outputTransformSchema = Type.Union(
4784
- [scriptOutputTransformSchema, jsonPointerOutputTransformSchema],
4785
- { discriminator: "kind" }
4786
- );
4787
3817
 
4788
- // ../../node_modules/@sinclair/typebox/build/esm/value/guard/guard.mjs
4789
- function IsObject4(value) {
4790
- return value !== null && typeof value === "object";
4791
- }
4792
- function IsArray4(value) {
4793
- return Array.isArray(value) && !ArrayBuffer.isView(value);
4794
- }
4795
- function IsUndefined4(value) {
4796
- return value === void 0;
3818
+ // src/inspector/useStateInspector.tsx
3819
+ var import_react4 = __toESM(require("react"));
3820
+ var import_client = require("react-dom/client");
3821
+
3822
+ // src/inspector/StateInspector.tsx
3823
+ var import_react_utils = require("@noya-app/react-utils");
3824
+ var import_react3 = __toESM(require("react"));
3825
+ var import_react_inspector = require("react-inspector");
3826
+
3827
+ // src/useObservable.ts
3828
+ var import_react = require("react");
3829
+ function useObservable(observable, pathOrSelector, options) {
3830
+ const { get, listen } = (0, import_react.useMemo)(() => {
3831
+ if (!observable) {
3832
+ return {
3833
+ get: () => void 0,
3834
+ listen: () => () => {
3835
+ }
3836
+ };
3837
+ }
3838
+ if (typeof pathOrSelector === "function") {
3839
+ const mappedObservable = observable.map(pathOrSelector, {
3840
+ isEqual: options?.isEqual
3841
+ });
3842
+ return {
3843
+ get: mappedObservable.get,
3844
+ listen: mappedObservable.subscribe
3845
+ };
3846
+ }
3847
+ const listen2 = pathOrSelector ? (callback) => observable.subscribe(pathOrSelector, callback) : observable.subscribe;
3848
+ const get2 = pathOrSelector ? () => observable.get(pathOrSelector) : observable.get;
3849
+ return { get: get2, listen: listen2 };
3850
+ }, [observable, pathOrSelector, options?.isEqual]);
3851
+ return (0, import_react.useSyncExternalStore)(listen, get, get);
4797
3852
  }
4798
- function IsNumber4(value) {
4799
- return typeof value === "number";
3853
+
3854
+ // src/inspector/useLocalStorageState.tsx
3855
+ var import_react2 = __toESM(require("react"));
3856
+ var localStorage = typeof window !== "undefined" ? window.localStorage : null;
3857
+ function useLocalStorageState(key, defaultValue) {
3858
+ const [state, setState] = import_react2.default.useState(() => {
3859
+ const value = localStorage?.getItem(key);
3860
+ let result = defaultValue;
3861
+ if (value) {
3862
+ try {
3863
+ result = JSON.parse(value);
3864
+ } catch (error) {
3865
+ console.error("Error parsing localStorage value", error);
3866
+ }
3867
+ }
3868
+ return result;
3869
+ });
3870
+ const setLocalStorageState = (value) => {
3871
+ localStorage?.setItem(key, JSON.stringify(value));
3872
+ setState(value);
3873
+ };
3874
+ return [state, setLocalStorageState];
4800
3875
  }
4801
3876
 
4802
- // ../../node_modules/@sinclair/typebox/build/esm/system/policy.mjs
4803
- var TypeSystemPolicy;
4804
- (function(TypeSystemPolicy2) {
4805
- TypeSystemPolicy2.ExactOptionalPropertyTypes = false;
4806
- TypeSystemPolicy2.AllowArrayObject = false;
4807
- TypeSystemPolicy2.AllowNaN = false;
4808
- TypeSystemPolicy2.AllowNullVoid = false;
4809
- function IsExactOptionalProperty(value, key) {
4810
- return TypeSystemPolicy2.ExactOptionalPropertyTypes ? key in value : value[key] !== void 0;
4811
- }
4812
- TypeSystemPolicy2.IsExactOptionalProperty = IsExactOptionalProperty;
4813
- function IsObjectLike(value) {
4814
- const isObject = IsObject4(value);
4815
- return TypeSystemPolicy2.AllowArrayObject ? isObject : isObject && !IsArray4(value);
4816
- }
4817
- TypeSystemPolicy2.IsObjectLike = IsObjectLike;
4818
- function IsRecordLike(value) {
4819
- return IsObjectLike(value) && !(value instanceof Date) && !(value instanceof Uint8Array);
4820
- }
4821
- TypeSystemPolicy2.IsRecordLike = IsRecordLike;
4822
- function IsNumberLike(value) {
4823
- return TypeSystemPolicy2.AllowNaN ? IsNumber4(value) : Number.isFinite(value);
3877
+ // src/inspector/StateInspector.tsx
3878
+ var lightTheme = {
3879
+ ...import_react_inspector.chromeLight,
3880
+ BASE_BACKGROUND_COLOR: "transparent",
3881
+ OBJECT_NAME_COLOR: "rgba(0,0,0,0.7)"
3882
+ };
3883
+ var darkTheme = {
3884
+ ...import_react_inspector.chromeDark,
3885
+ BASE_BACKGROUND_COLOR: "transparent",
3886
+ OBJECT_NAME_COLOR: "rgba(255,255,255,0.7)"
3887
+ };
3888
+ var styles = {
3889
+ sectionInner: {
3890
+ flex: "1 1 0",
3891
+ overflowY: "auto",
3892
+ overflowX: "hidden",
3893
+ display: "flex",
3894
+ flexDirection: "column"
4824
3895
  }
4825
- TypeSystemPolicy2.IsNumberLike = IsNumberLike;
4826
- function IsVoidLike(value) {
4827
- const isUndefined = IsUndefined4(value);
4828
- return TypeSystemPolicy2.AllowNullVoid ? isUndefined || value === null : isUndefined;
3896
+ };
3897
+ function ToggleButton({
3898
+ showInspector,
3899
+ setShowInspector,
3900
+ theme,
3901
+ anchor
3902
+ }) {
3903
+ return /* @__PURE__ */ import_react3.default.createElement(
3904
+ "span",
3905
+ {
3906
+ role: "button",
3907
+ style: {
3908
+ flex: "0",
3909
+ appearance: "none",
3910
+ color: theme.BASE_COLOR,
3911
+ border: "none",
3912
+ fontSize: "12px",
3913
+ whiteSpace: "nowrap",
3914
+ display: "inline-flex",
3915
+ alignItems: "center",
3916
+ justifyContent: "center",
3917
+ padding: "2px 0"
3918
+ },
3919
+ onClick: (event) => {
3920
+ event.stopPropagation();
3921
+ setShowInspector(!showInspector);
3922
+ }
3923
+ },
3924
+ /* @__PURE__ */ import_react3.default.createElement("span", { style: { width: "12px", height: "12px" } }, showInspector === (anchor === "right") ? /* @__PURE__ */ import_react3.default.createElement(
3925
+ "svg",
3926
+ {
3927
+ xmlns: "http://www.w3.org/2000/svg",
3928
+ fill: "none",
3929
+ viewBox: "0 0 24 24",
3930
+ strokeWidth: 1.5,
3931
+ stroke: "currentColor",
3932
+ className: "size-6"
3933
+ },
3934
+ /* @__PURE__ */ import_react3.default.createElement(
3935
+ "path",
3936
+ {
3937
+ strokeLinecap: "round",
3938
+ strokeLinejoin: "round",
3939
+ d: "m5.25 4.5 7.5 7.5-7.5 7.5m6-15 7.5 7.5-7.5 7.5"
3940
+ }
3941
+ )
3942
+ ) : /* @__PURE__ */ import_react3.default.createElement(
3943
+ "svg",
3944
+ {
3945
+ xmlns: "http://www.w3.org/2000/svg",
3946
+ fill: "none",
3947
+ viewBox: "0 0 24 24",
3948
+ strokeWidth: 1.5,
3949
+ stroke: "currentColor",
3950
+ className: "size-6"
3951
+ },
3952
+ /* @__PURE__ */ import_react3.default.createElement(
3953
+ "path",
3954
+ {
3955
+ strokeLinecap: "round",
3956
+ strokeLinejoin: "round",
3957
+ d: "m18.75 4.5-7.5 7.5 7.5 7.5m-6-15L5.25 12l7.5 7.5"
3958
+ }
3959
+ )
3960
+ ))
3961
+ );
3962
+ }
3963
+ function DisclosureSection({
3964
+ open,
3965
+ setOpen,
3966
+ title,
3967
+ right,
3968
+ children,
3969
+ colorScheme,
3970
+ isFirst,
3971
+ style
3972
+ }) {
3973
+ const theme = colorScheme === "light" ? lightTheme : darkTheme;
3974
+ const borderColor = colorScheme === "light" ? "rgba(0,0,0,0.1)" : "rgba(255,255,255,0.1)";
3975
+ return /* @__PURE__ */ import_react3.default.createElement(
3976
+ "div",
3977
+ {
3978
+ style: {
3979
+ flex: open ? "1 1 0" : "0",
3980
+ display: "flex",
3981
+ flexDirection: "column",
3982
+ ...style
3983
+ }
3984
+ },
3985
+ /* @__PURE__ */ import_react3.default.createElement(
3986
+ "div",
3987
+ {
3988
+ onClick: () => setOpen?.(!open),
3989
+ style: {
3990
+ cursor: "default",
3991
+ fontSize: "12px",
3992
+ padding: "4px 10px",
3993
+ display: "flex",
3994
+ alignItems: "center",
3995
+ ...!isFirst && { borderTop: `1px solid ${borderColor}` },
3996
+ ...open && { borderBottom: `1px solid ${borderColor}` }
3997
+ }
3998
+ },
3999
+ setOpen && /* @__PURE__ */ import_react3.default.createElement(
4000
+ Arrow,
4001
+ {
4002
+ expanded: open,
4003
+ style: {
4004
+ fontSize: theme.ARROW_FONT_SIZE,
4005
+ marginRight: theme.ARROW_MARGIN_RIGHT + 1,
4006
+ color: theme.ARROW_COLOR
4007
+ }
4008
+ }
4009
+ ),
4010
+ /* @__PURE__ */ import_react3.default.createElement("span", { style: { flex: "1 1 0", userSelect: "none" } }, title),
4011
+ right
4012
+ ),
4013
+ open && children
4014
+ );
4015
+ }
4016
+ function InspectorRow({
4017
+ children,
4018
+ colorScheme,
4019
+ selected,
4020
+ style,
4021
+ variant
4022
+ }) {
4023
+ const solidBorderColor = colorScheme === "light" ? "rgb(223 223 223)" : "rgb(29 29 29)";
4024
+ return /* @__PURE__ */ import_react3.default.createElement(
4025
+ "div",
4026
+ {
4027
+ style: {
4028
+ borderBottom: `1px solid ${solidBorderColor}`,
4029
+ fontSize: "12px",
4030
+ fontFamily: "Menlo, monospace",
4031
+ padding: "2px 12px 1px",
4032
+ display: "flex",
4033
+ alignItems: "center",
4034
+ background: variant === "up" ? "rgba(0,255,0,0.1)" : variant === "down" ? "transparent" : selected ? "rgb(59 130 246 / 15%)" : void 0,
4035
+ // background:
4036
+ // colorScheme === "light"
4037
+ // ? "rgba(0,0,0,0.05)"
4038
+ // : "rgba(255,255,255,0.05)",
4039
+ ...style
4040
+ }
4041
+ },
4042
+ /* @__PURE__ */ import_react3.default.createElement(
4043
+ "span",
4044
+ {
4045
+ style: {
4046
+ fontFamily: "Menlo, monospace",
4047
+ fontSize: "11px",
4048
+ borderRadius: 4,
4049
+ display: "inline-block"
4050
+ }
4051
+ },
4052
+ children
4053
+ )
4054
+ );
4055
+ }
4056
+ var HISTORY_ELEMENT_PREFIX = "noya-multiplayer-history-";
4057
+ var StateInspector = (0, import_react_utils.memoGeneric)(function StateInspector2({
4058
+ noyaManager,
4059
+ colorScheme = "light",
4060
+ anchor = "right",
4061
+ unstyled = false,
4062
+ ...props
4063
+ }) {
4064
+ const {
4065
+ multiplayerStateManager,
4066
+ assetManager,
4067
+ connectedUsersManager,
4068
+ secretManager,
4069
+ ephemeralUserDataManager,
4070
+ connectionEventManager,
4071
+ taskManager,
4072
+ ioManager
4073
+ } = noyaManager;
4074
+ const [didMount, setDidMount] = import_react3.default.useState(false);
4075
+ const tasks = useObservable(taskManager.tasks$);
4076
+ const inputs = useObservable(ioManager.inputs$);
4077
+ const outputTransforms = useObservable(ioManager.outputTransforms$);
4078
+ (0, import_react3.useLayoutEffect)(() => {
4079
+ setDidMount(true);
4080
+ }, []);
4081
+ const eventsContainerRef = import_react3.default.useRef(null);
4082
+ const historyContainerRef = import_react3.default.useRef(null);
4083
+ const [showInspector, setShowInspector] = useLocalStorageState(
4084
+ "noya-multiplayer-react-show-inspector",
4085
+ true
4086
+ );
4087
+ const [showEvents, setShowEvents] = useLocalStorageState(
4088
+ "noya-multiplayer-react-show-events",
4089
+ false
4090
+ );
4091
+ const [showHistory, setShowHistory] = useLocalStorageState(
4092
+ "noya-multiplayer-react-show-history",
4093
+ false
4094
+ );
4095
+ const [showUsers, setShowUsers] = useLocalStorageState(
4096
+ "noya-multiplayer-react-show-users",
4097
+ true
4098
+ );
4099
+ const [showData, setShowData] = useLocalStorageState(
4100
+ "noya-multiplayer-react-show-data",
4101
+ true
4102
+ );
4103
+ const [showTasks, setShowTasks] = useLocalStorageState(
4104
+ "noya-multiplayer-react-show-tasks",
4105
+ false
4106
+ );
4107
+ const [showEphemeral, setShowEphemeral] = useLocalStorageState(
4108
+ "noya-multiplayer-react-show-ephemeral",
4109
+ false
4110
+ );
4111
+ const [showAssets, setShowAssets] = useLocalStorageState(
4112
+ "noya-multiplayer-react-show-assets",
4113
+ false
4114
+ );
4115
+ const [showSecrets, setShowSecrets] = useLocalStorageState(
4116
+ "noya-multiplayer-react-show-secrets",
4117
+ false
4118
+ );
4119
+ const [showInputs, setShowInputs] = useLocalStorageState(
4120
+ "noya-multiplayer-react-show-inputs",
4121
+ false
4122
+ );
4123
+ const [showOutputTransforms, setShowOutputTransforms] = useLocalStorageState(
4124
+ "noya-multiplayer-react-show-output-transforms",
4125
+ false
4126
+ );
4127
+ const connectionEvents = useObservable(connectionEventManager.events$);
4128
+ (0, import_react3.useEffect)(() => {
4129
+ if (eventsContainerRef.current) {
4130
+ eventsContainerRef.current.scrollTop = eventsContainerRef.current.scrollHeight;
4131
+ }
4132
+ }, [connectionEvents]);
4133
+ const multipeerStateInitialized = useObservable(
4134
+ multiplayerStateManager.isInitialized$
4135
+ );
4136
+ const ephemeral = useObservable(ephemeralUserDataManager.data$);
4137
+ const historySnapshot = useManagedHistory(multiplayerStateManager.sm);
4138
+ const assets = useObservable(assetManager.assets$);
4139
+ const assetsInitialized = useObservable(assetManager.isInitialized$);
4140
+ const secrets = useObservable(secretManager.secrets$);
4141
+ const secretsInitialized = useObservable(secretManager.isInitialized$);
4142
+ const connectedUsers = useObservable(connectedUsersManager.connectedUsers$);
4143
+ const userId = useObservable(connectedUsersManager.currentUserId$);
4144
+ const state = useObservable(multiplayerStateManager.optimisticState$);
4145
+ const inputsInitialized = useObservable(ioManager.inputsInitialized$);
4146
+ const outputTransformsInitialized = useObservable(
4147
+ ioManager.outputTransformsInitialized$
4148
+ );
4149
+ (0, import_react3.useEffect)(() => {
4150
+ if (historyContainerRef.current) {
4151
+ historyContainerRef.current.scrollTop = historyContainerRef.current.scrollHeight;
4152
+ }
4153
+ }, [historySnapshot]);
4154
+ (0, import_react3.useEffect)(() => {
4155
+ if (!historyContainerRef.current) return;
4156
+ const historyEntry = historyContainerRef.current.querySelector(
4157
+ `#${HISTORY_ELEMENT_PREFIX}${historySnapshot.historyIndex}`
4158
+ );
4159
+ if (historyEntry) {
4160
+ historyEntry.scrollIntoView({
4161
+ block: "nearest",
4162
+ inline: "nearest"
4163
+ });
4164
+ }
4165
+ }, [historySnapshot.historyIndex]);
4166
+ const theme = colorScheme === "light" ? lightTheme : darkTheme;
4167
+ const solidBorderColor = colorScheme === "light" ? "rgb(223 223 223)" : "rgb(29 29 29)";
4168
+ const baseStyle = {
4169
+ position: "fixed",
4170
+ top: 12,
4171
+ ...anchor.includes("right") ? { right: 12 } : { left: 12 },
4172
+ bottom: 12,
4173
+ width: 400,
4174
+ background: colorScheme === "light" ? "rgba(255,255,255,0.95)" : "rgba(0,0,0,0.95)",
4175
+ backdropFilter: "blur(48px)",
4176
+ border: `1px solid ${solidBorderColor}`,
4177
+ // outlineOffset: -1,
4178
+ borderRadius: 4,
4179
+ display: "flex",
4180
+ flexDirection: "column",
4181
+ // gap: 12,
4182
+ color: theme.BASE_COLOR,
4183
+ overflow: "hidden",
4184
+ zIndex: 9999,
4185
+ lineHeight: "13px"
4186
+ };
4187
+ if (!didMount) return null;
4188
+ if (!showInspector) {
4189
+ return /* @__PURE__ */ import_react3.default.createElement(
4190
+ "div",
4191
+ {
4192
+ ...props,
4193
+ style: {
4194
+ ...baseStyle,
4195
+ padding: "4px 10px",
4196
+ width: void 0,
4197
+ ...anchor.includes("bottom") ? { bottom: 12, top: void 0 } : { bottom: void 0 }
4198
+ },
4199
+ onClick: () => setShowInspector(true)
4200
+ },
4201
+ /* @__PURE__ */ import_react3.default.createElement(
4202
+ ToggleButton,
4203
+ {
4204
+ showInspector,
4205
+ setShowInspector,
4206
+ theme,
4207
+ anchor
4208
+ }
4209
+ )
4210
+ );
4829
4211
  }
4830
- TypeSystemPolicy2.IsVoidLike = IsVoidLike;
4831
- })(TypeSystemPolicy || (TypeSystemPolicy = {}));
4832
-
4833
- // ../../node_modules/@sinclair/typebox/build/esm/system/system.mjs
4834
- var TypeSystemDuplicateTypeKind = class extends TypeBoxError {
4835
- constructor(kind) {
4836
- super(`Duplicate type kind '${kind}' detected`);
4212
+ return /* @__PURE__ */ import_react3.default.createElement(
4213
+ "div",
4214
+ {
4215
+ ...props,
4216
+ style: {
4217
+ ...!unstyled && baseStyle,
4218
+ ...props.style
4219
+ }
4220
+ },
4221
+ /* @__PURE__ */ import_react3.default.createElement(
4222
+ DisclosureSection,
4223
+ {
4224
+ isFirst: true,
4225
+ open: showUsers,
4226
+ setOpen: setShowUsers,
4227
+ title: "Users",
4228
+ colorScheme,
4229
+ style: {
4230
+ flex: "0 0 auto",
4231
+ maxHeight: "200px"
4232
+ },
4233
+ right: /* @__PURE__ */ import_react3.default.createElement(
4234
+ ToggleButton,
4235
+ {
4236
+ showInspector,
4237
+ setShowInspector,
4238
+ theme,
4239
+ anchor
4240
+ }
4241
+ )
4242
+ },
4243
+ /* @__PURE__ */ import_react3.default.createElement("div", { style: { ...styles.sectionInner, flex: "0 0 auto" } }, connectedUsers?.map((user) => /* @__PURE__ */ import_react3.default.createElement(
4244
+ InspectorRow,
4245
+ {
4246
+ key: user.id,
4247
+ colorScheme,
4248
+ variant: user.id === userId ? "up" : void 0
4249
+ },
4250
+ user.image && /* @__PURE__ */ import_react3.default.createElement(
4251
+ "img",
4252
+ {
4253
+ src: user.image,
4254
+ alt: user.name,
4255
+ style: {
4256
+ width: "13px",
4257
+ height: "13px",
4258
+ borderRadius: "50%",
4259
+ marginRight: "4px",
4260
+ display: "inline-block",
4261
+ position: "relative",
4262
+ background: solidBorderColor,
4263
+ verticalAlign: "middle"
4264
+ }
4265
+ }
4266
+ ),
4267
+ user.name,
4268
+ " (",
4269
+ ellipsis(user.id.toString(), 8, "middle"),
4270
+ ")"
4271
+ )), !connectedUsers && /* @__PURE__ */ import_react3.default.createElement(
4272
+ "div",
4273
+ {
4274
+ style: {
4275
+ padding: "12px",
4276
+ fontSize: "12px",
4277
+ display: "flex",
4278
+ flexDirection: "column",
4279
+ gap: "4px"
4280
+ }
4281
+ },
4282
+ /* @__PURE__ */ import_react3.default.createElement("span", null, "No connected users")
4283
+ ))
4284
+ ),
4285
+ /* @__PURE__ */ import_react3.default.createElement(
4286
+ DisclosureSection,
4287
+ {
4288
+ title: /* @__PURE__ */ import_react3.default.createElement(TitleLabel, null, "Data", /* @__PURE__ */ import_react3.default.createElement(
4289
+ ColoredDot,
4290
+ {
4291
+ type: multipeerStateInitialized ? "success" : "error"
4292
+ }
4293
+ )),
4294
+ colorScheme,
4295
+ setOpen: setShowData,
4296
+ open: showData,
4297
+ right: /* @__PURE__ */ import_react3.default.createElement(
4298
+ "span",
4299
+ {
4300
+ style: {
4301
+ display: "flex",
4302
+ gap: "4px"
4303
+ }
4304
+ },
4305
+ /* @__PURE__ */ import_react3.default.createElement(
4306
+ SmallButton,
4307
+ {
4308
+ theme,
4309
+ onClick: () => {
4310
+ noyaManager.forceInit();
4311
+ }
4312
+ },
4313
+ "Reset"
4314
+ )
4315
+ )
4316
+ },
4317
+ /* @__PURE__ */ import_react3.default.createElement("div", { style: styles.sectionInner }, /* @__PURE__ */ import_react3.default.createElement(InspectorRow, { colorScheme }, /* @__PURE__ */ import_react3.default.createElement(
4318
+ import_react_inspector.ObjectInspector,
4319
+ {
4320
+ name: multiplayerStateManager.schema ? "state" : void 0,
4321
+ data: state,
4322
+ theme
4323
+ }
4324
+ )), multiplayerStateManager.schema && /* @__PURE__ */ import_react3.default.createElement(InspectorRow, { colorScheme }, /* @__PURE__ */ import_react3.default.createElement(
4325
+ import_react_inspector.ObjectInspector,
4326
+ {
4327
+ name: "schema",
4328
+ data: multiplayerStateManager.schema,
4329
+ theme
4330
+ }
4331
+ )))
4332
+ ),
4333
+ /* @__PURE__ */ import_react3.default.createElement(
4334
+ DisclosureSection,
4335
+ {
4336
+ open: showHistory,
4337
+ setOpen: setShowHistory,
4338
+ title: "History",
4339
+ colorScheme,
4340
+ right: /* @__PURE__ */ import_react3.default.createElement(
4341
+ "span",
4342
+ {
4343
+ style: {
4344
+ display: "flex",
4345
+ gap: "4px"
4346
+ }
4347
+ },
4348
+ /* @__PURE__ */ import_react3.default.createElement(
4349
+ SmallButton,
4350
+ {
4351
+ disabled: !historySnapshot.canUndo,
4352
+ theme,
4353
+ onClick: () => {
4354
+ multiplayerStateManager.undo();
4355
+ }
4356
+ },
4357
+ /* @__PURE__ */ import_react3.default.createElement("span", { style: { width: "12px", height: "12px" } }, /* @__PURE__ */ import_react3.default.createElement(
4358
+ "svg",
4359
+ {
4360
+ xmlns: "http://www.w3.org/2000/svg",
4361
+ width: "1em",
4362
+ height: "1em",
4363
+ viewBox: "0 0 20 20"
4364
+ },
4365
+ /* @__PURE__ */ import_react3.default.createElement(
4366
+ "path",
4367
+ {
4368
+ fill: "currentColor",
4369
+ d: "M12 5H7V2L1 6l6 4V7h5c2.2 0 4 1.8 4 4s-1.8 4-4 4H7v2h5c3.3 0 6-2.7 6-6s-2.7-6-6-6"
4370
+ }
4371
+ )
4372
+ ))
4373
+ ),
4374
+ /* @__PURE__ */ import_react3.default.createElement(
4375
+ SmallButton,
4376
+ {
4377
+ disabled: !historySnapshot.canRedo,
4378
+ theme,
4379
+ onClick: () => {
4380
+ multiplayerStateManager.redo();
4381
+ }
4382
+ },
4383
+ /* @__PURE__ */ import_react3.default.createElement("span", { style: { width: "12px", height: "12px" } }, /* @__PURE__ */ import_react3.default.createElement(
4384
+ "svg",
4385
+ {
4386
+ xmlns: "http://www.w3.org/2000/svg",
4387
+ width: "1em",
4388
+ height: "1em",
4389
+ viewBox: "0 0 20 20"
4390
+ },
4391
+ /* @__PURE__ */ import_react3.default.createElement(
4392
+ "path",
4393
+ {
4394
+ fill: "currentColor",
4395
+ d: "M8 5h5V2l6 4l-6 4V7H8c-2.2 0-4 1.8-4 4s1.8 4 4 4h5v2H8c-3.3 0-6-2.7-6-6s2.7-6 6-6"
4396
+ }
4397
+ )
4398
+ ))
4399
+ )
4400
+ )
4401
+ },
4402
+ /* @__PURE__ */ import_react3.default.createElement("div", { ref: historyContainerRef, style: styles.sectionInner }, /* @__PURE__ */ import_react3.default.createElement(
4403
+ "div",
4404
+ {
4405
+ id: `${HISTORY_ELEMENT_PREFIX}0`,
4406
+ style: {
4407
+ borderBottom: `1px solid ${solidBorderColor}`,
4408
+ fontSize: "12px",
4409
+ fontFamily: "Menlo, monospace",
4410
+ padding: "2px 12px 1px",
4411
+ display: "flex",
4412
+ alignItems: "center",
4413
+ background: historySnapshot.historyIndex === 0 ? "rgb(59 130 246 / 15%)" : void 0
4414
+ }
4415
+ },
4416
+ /* @__PURE__ */ import_react3.default.createElement(
4417
+ "span",
4418
+ {
4419
+ style: {
4420
+ fontFamily: "Menlo, monospace",
4421
+ fontSize: "11px",
4422
+ borderRadius: 4,
4423
+ display: "inline-block"
4424
+ }
4425
+ },
4426
+ "Initial state"
4427
+ )
4428
+ ), historySnapshot.history.map((entry, index) => /* @__PURE__ */ import_react3.default.createElement(
4429
+ "div",
4430
+ {
4431
+ id: `${HISTORY_ELEMENT_PREFIX}${index + 1}`,
4432
+ key: index,
4433
+ style: {
4434
+ padding: "0px 12px 1px",
4435
+ borderBottom: `1px solid ${solidBorderColor}`,
4436
+ background: index + 1 === historySnapshot.historyIndex ? "rgb(59 130 246 / 15%)" : void 0
4437
+ }
4438
+ },
4439
+ "name" in entry.metadata && typeof entry.metadata.name === "string" && /* @__PURE__ */ import_react3.default.createElement(
4440
+ "pre",
4441
+ {
4442
+ style: {
4443
+ fontSize: "11px",
4444
+ display: "flex",
4445
+ flexWrap: "wrap",
4446
+ margin: 0
4447
+ }
4448
+ },
4449
+ entry.metadata.name
4450
+ ),
4451
+ entry.redoPatches?.map((patch, j) => /* @__PURE__ */ import_react3.default.createElement(
4452
+ "pre",
4453
+ {
4454
+ key: j,
4455
+ style: {
4456
+ fontSize: "11px",
4457
+ display: "flex",
4458
+ flexWrap: "wrap",
4459
+ margin: 0
4460
+ }
4461
+ },
4462
+ patch.op === "add" && /* @__PURE__ */ import_react3.default.createElement(import_react3.default.Fragment, null, /* @__PURE__ */ import_react3.default.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path)), " = ", /* @__PURE__ */ import_react3.default.createElement(import_react_inspector.ObjectInspector, { data: patch.value, theme })),
4463
+ patch.op === "replace" && /* @__PURE__ */ import_react3.default.createElement(import_react3.default.Fragment, null, /* @__PURE__ */ import_react3.default.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path)), " = ", /* @__PURE__ */ import_react3.default.createElement(import_react_inspector.ObjectInspector, { data: patch.value, theme })),
4464
+ patch.op === "remove" && /* @__PURE__ */ import_react3.default.createElement(import_react3.default.Fragment, null, /* @__PURE__ */ import_react3.default.createElement("span", { style: { color: theme.OBJECT_VALUE_STRING_COLOR } }, "delete", " "), /* @__PURE__ */ import_react3.default.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path))),
4465
+ patch.op === "move" && /* @__PURE__ */ import_react3.default.createElement(import_react3.default.Fragment, null, /* @__PURE__ */ import_react3.default.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.from)), " -> ", /* @__PURE__ */ import_react3.default.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path)))
4466
+ ))
4467
+ )))
4468
+ ),
4469
+ /* @__PURE__ */ import_react3.default.createElement(
4470
+ DisclosureSection,
4471
+ {
4472
+ open: showAssets,
4473
+ setOpen: setShowAssets,
4474
+ title: /* @__PURE__ */ import_react3.default.createElement(TitleLabel, null, "Assets", /* @__PURE__ */ import_react3.default.createElement(ColoredDot, { type: assetsInitialized ? "success" : "error" })),
4475
+ colorScheme,
4476
+ right: /* @__PURE__ */ import_react3.default.createElement("span", { style: { display: "flex", gap: "10px" } }, /* @__PURE__ */ import_react3.default.createElement(
4477
+ SmallButton,
4478
+ {
4479
+ theme,
4480
+ onClick: () => {
4481
+ console.info(
4482
+ "[StateInspector] Reloading assets",
4483
+ noyaManager.id
4484
+ );
4485
+ assetManager.fetch();
4486
+ }
4487
+ },
4488
+ "Reload"
4489
+ ), /* @__PURE__ */ import_react3.default.createElement(
4490
+ SmallButton,
4491
+ {
4492
+ theme,
4493
+ onClick: () => {
4494
+ const input = document.createElement("input");
4495
+ input.type = "file";
4496
+ input.onchange = () => {
4497
+ const file = input.files?.[0];
4498
+ if (file) {
4499
+ const reader = new FileReader();
4500
+ reader.onload = () => {
4501
+ const buffer = reader.result;
4502
+ assetManager.create(new Uint8Array(buffer));
4503
+ };
4504
+ reader.readAsArrayBuffer(file);
4505
+ }
4506
+ };
4507
+ input.click();
4508
+ }
4509
+ },
4510
+ "Upload"
4511
+ ))
4512
+ },
4513
+ /* @__PURE__ */ import_react3.default.createElement("div", { style: styles.sectionInner }, assets.map((asset) => /* @__PURE__ */ import_react3.default.createElement(InspectorRow, { key: asset.id, colorScheme }, /* @__PURE__ */ import_react3.default.createElement(import_react_inspector.ObjectInspector, { name: asset.id, data: asset, theme }), /* @__PURE__ */ import_react3.default.createElement(
4514
+ SmallButton,
4515
+ {
4516
+ theme,
4517
+ onClick: () => assetManager.delete(asset.id)
4518
+ },
4519
+ "Delete"
4520
+ ))))
4521
+ ),
4522
+ /* @__PURE__ */ import_react3.default.createElement(
4523
+ DisclosureSection,
4524
+ {
4525
+ title: /* @__PURE__ */ import_react3.default.createElement(TitleLabel, null, "Secrets", /* @__PURE__ */ import_react3.default.createElement(ColoredDot, { type: secretsInitialized ? "success" : "error" })),
4526
+ colorScheme,
4527
+ open: showSecrets,
4528
+ setOpen: setShowSecrets,
4529
+ right: /* @__PURE__ */ import_react3.default.createElement(
4530
+ SmallButton,
4531
+ {
4532
+ theme,
4533
+ onClick: () => {
4534
+ const name = prompt("Enter secret name");
4535
+ if (!name) return;
4536
+ const value = prompt("Enter secret value");
4537
+ if (!value) return;
4538
+ secretManager.createSecret(name, value);
4539
+ }
4540
+ },
4541
+ "Create"
4542
+ )
4543
+ },
4544
+ /* @__PURE__ */ import_react3.default.createElement("div", { style: styles.sectionInner }, secrets.map((secret) => /* @__PURE__ */ import_react3.default.createElement(InspectorRow, { key: secret.id, colorScheme }, /* @__PURE__ */ import_react3.default.createElement(import_react_inspector.ObjectInspector, { data: secret, theme }), /* @__PURE__ */ import_react3.default.createElement(
4545
+ SmallButton,
4546
+ {
4547
+ theme,
4548
+ onClick: () => secretManager.deleteSecret(secret.name)
4549
+ },
4550
+ "Delete"
4551
+ ))))
4552
+ ),
4553
+ " ",
4554
+ /* @__PURE__ */ import_react3.default.createElement(
4555
+ DisclosureSection,
4556
+ {
4557
+ open: showInputs,
4558
+ setOpen: setShowInputs,
4559
+ title: /* @__PURE__ */ import_react3.default.createElement(TitleLabel, null, "Inputs", /* @__PURE__ */ import_react3.default.createElement(ColoredDot, { type: inputsInitialized ? "success" : "error" })),
4560
+ colorScheme
4561
+ },
4562
+ /* @__PURE__ */ import_react3.default.createElement("div", { style: styles.sectionInner }, inputs?.map((input) => /* @__PURE__ */ import_react3.default.createElement(InspectorRow, { key: input.id, colorScheme }, /* @__PURE__ */ import_react3.default.createElement(import_react_inspector.ObjectInspector, { data: input, theme }))), !inputs?.length && /* @__PURE__ */ import_react3.default.createElement(
4563
+ "div",
4564
+ {
4565
+ style: {
4566
+ padding: "12px",
4567
+ fontSize: "12px",
4568
+ display: "flex",
4569
+ flexDirection: "column",
4570
+ gap: "4px"
4571
+ }
4572
+ },
4573
+ /* @__PURE__ */ import_react3.default.createElement("span", null, "No inputs")
4574
+ ))
4575
+ ),
4576
+ /* @__PURE__ */ import_react3.default.createElement(
4577
+ DisclosureSection,
4578
+ {
4579
+ open: showOutputTransforms,
4580
+ setOpen: setShowOutputTransforms,
4581
+ title: /* @__PURE__ */ import_react3.default.createElement(TitleLabel, null, "Output Transforms", /* @__PURE__ */ import_react3.default.createElement(
4582
+ ColoredDot,
4583
+ {
4584
+ type: outputTransformsInitialized ? "success" : "error"
4585
+ }
4586
+ )),
4587
+ colorScheme
4588
+ },
4589
+ /* @__PURE__ */ import_react3.default.createElement("div", { style: styles.sectionInner }, outputTransforms?.map((transform) => /* @__PURE__ */ import_react3.default.createElement(InspectorRow, { key: transform.id, colorScheme }, /* @__PURE__ */ import_react3.default.createElement(import_react_inspector.ObjectInspector, { data: transform, theme }))), !outputTransforms?.length && /* @__PURE__ */ import_react3.default.createElement(
4590
+ "div",
4591
+ {
4592
+ style: {
4593
+ padding: "12px",
4594
+ fontSize: "12px",
4595
+ display: "flex",
4596
+ flexDirection: "column",
4597
+ gap: "4px"
4598
+ }
4599
+ },
4600
+ /* @__PURE__ */ import_react3.default.createElement("span", null, "No output transforms")
4601
+ ))
4602
+ ),
4603
+ /* @__PURE__ */ import_react3.default.createElement(
4604
+ DisclosureSection,
4605
+ {
4606
+ title: "Tasks",
4607
+ colorScheme,
4608
+ open: showTasks,
4609
+ setOpen: setShowTasks
4610
+ },
4611
+ /* @__PURE__ */ import_react3.default.createElement("div", { style: styles.sectionInner }, tasks?.map((task) => /* @__PURE__ */ import_react3.default.createElement(
4612
+ InspectorRow,
4613
+ {
4614
+ key: task.id,
4615
+ colorScheme,
4616
+ style: {
4617
+ backgroundColor: task.status === "done" ? "rgba(0,255,0,0.2)" : task.status === "error" ? "rgba(255,0,0,0.2)" : void 0
4618
+ }
4619
+ },
4620
+ /* @__PURE__ */ import_react3.default.createElement(
4621
+ import_react_inspector.ObjectInspector,
4622
+ {
4623
+ name: task.name,
4624
+ data: task.payload,
4625
+ theme
4626
+ }
4627
+ )
4628
+ )))
4629
+ ),
4630
+ /* @__PURE__ */ import_react3.default.createElement(
4631
+ DisclosureSection,
4632
+ {
4633
+ open: showEphemeral,
4634
+ setOpen: setShowEphemeral,
4635
+ title: "Ephemeral User Data",
4636
+ colorScheme
4637
+ },
4638
+ /* @__PURE__ */ import_react3.default.createElement("div", { style: styles.sectionInner }, Object.entries(ephemeral).map(([key, value]) => /* @__PURE__ */ import_react3.default.createElement(InspectorRow, { key, colorScheme }, /* @__PURE__ */ import_react3.default.createElement(
4639
+ import_react_inspector.ObjectInspector,
4640
+ {
4641
+ name: key,
4642
+ data: value,
4643
+ theme,
4644
+ expandLevel: 10
4645
+ }
4646
+ ))))
4647
+ ),
4648
+ /* @__PURE__ */ import_react3.default.createElement(
4649
+ DisclosureSection,
4650
+ {
4651
+ open: showEvents,
4652
+ setOpen: setShowEvents,
4653
+ title: "Events",
4654
+ colorScheme
4655
+ },
4656
+ /* @__PURE__ */ import_react3.default.createElement("div", { ref: eventsContainerRef, style: styles.sectionInner }, connectionEvents?.map(
4657
+ (event, index) => event.type === "stateChange" ? /* @__PURE__ */ import_react3.default.createElement(InspectorRow, { key: index, colorScheme }, "connection:", " ", /* @__PURE__ */ import_react3.default.createElement("span", { style: { fontStyle: "italic" } }, event.state.toLowerCase())) : /* @__PURE__ */ import_react3.default.createElement(
4658
+ InspectorRow,
4659
+ {
4660
+ key: index,
4661
+ colorScheme,
4662
+ variant: event.type === "send" ? "up" : "down",
4663
+ style: {
4664
+ padding: "0px 12px 1px"
4665
+ }
4666
+ },
4667
+ /* @__PURE__ */ import_react3.default.createElement(
4668
+ import_react_inspector.ObjectInspector,
4669
+ {
4670
+ data: event.type === "error" ? event.error : event.message,
4671
+ theme,
4672
+ nodeRenderer: ({
4673
+ depth,
4674
+ name,
4675
+ data,
4676
+ isNonenumerable
4677
+ }) => {
4678
+ const direction = event.type === "send" ? "up" : "down";
4679
+ return depth === 0 ? /* @__PURE__ */ import_react3.default.createElement(ObjectRootLabel, { direction, data }) : /* @__PURE__ */ import_react3.default.createElement(
4680
+ import_react_inspector.ObjectLabel,
4681
+ {
4682
+ direction,
4683
+ name,
4684
+ data,
4685
+ isNonenumerable
4686
+ }
4687
+ );
4688
+ }
4689
+ }
4690
+ )
4691
+ )
4692
+ ), !connectionEvents && /* @__PURE__ */ import_react3.default.createElement(
4693
+ "div",
4694
+ {
4695
+ style: {
4696
+ padding: "12px",
4697
+ fontSize: "12px",
4698
+ display: "flex",
4699
+ flexDirection: "column",
4700
+ gap: "4px"
4701
+ }
4702
+ },
4703
+ /* @__PURE__ */ import_react3.default.createElement("span", null, "No recorded events")
4704
+ ))
4705
+ )
4706
+ );
4707
+ });
4708
+ var ObjectRootLabel = ({ name, data, direction }) => {
4709
+ if (typeof name === "string") {
4710
+ return /* @__PURE__ */ import_react3.default.createElement("span", null, /* @__PURE__ */ import_react3.default.createElement(import_react_inspector.ObjectName, { name }), /* @__PURE__ */ import_react3.default.createElement("span", null, ": "), /* @__PURE__ */ import_react3.default.createElement(import_react_inspector.ObjectPreview, { data }));
4837
4711
  }
4838
- };
4839
- var TypeSystemDuplicateFormat = class extends TypeBoxError {
4840
- constructor(kind) {
4841
- super(`Duplicate string format '${kind}' detected`);
4712
+ if (direction === "up" || direction === "down") {
4713
+ const arrow = direction === "up" ? "\u2191" : "\u2193";
4714
+ return /* @__PURE__ */ import_react3.default.createElement("span", null, /* @__PURE__ */ import_react3.default.createElement(
4715
+ "span",
4716
+ {
4717
+ style: {
4718
+ background: direction === "up" ? "rgba(0,255,0,0.2)" : "rgba(255,0,0,0.2)",
4719
+ // color: "white",
4720
+ width: 12,
4721
+ height: 12,
4722
+ borderRadius: 2,
4723
+ display: "inline-flex",
4724
+ justifyContent: "center",
4725
+ alignItems: "center",
4726
+ marginRight: 4,
4727
+ lineHeight: "12px"
4728
+ }
4729
+ },
4730
+ arrow
4731
+ ), /* @__PURE__ */ import_react3.default.createElement(import_react_inspector.ObjectPreview, { data }));
4732
+ } else {
4733
+ return /* @__PURE__ */ import_react3.default.createElement(import_react_inspector.ObjectPreview, { data });
4842
4734
  }
4843
4735
  };
4844
- var TypeSystem;
4845
- (function(TypeSystem2) {
4846
- function Type2(kind, check) {
4847
- if (type_exports2.Has(kind))
4848
- throw new TypeSystemDuplicateTypeKind(kind);
4849
- type_exports2.Set(kind, check);
4850
- return (options = {}) => Unsafe({ ...options, [Kind]: kind });
4851
- }
4852
- TypeSystem2.Type = Type2;
4853
- function Format(format, check) {
4854
- if (format_exports.Has(format))
4855
- throw new TypeSystemDuplicateFormat(format);
4856
- format_exports.Set(format, check);
4857
- return format;
4736
+ function Arrow({
4737
+ expanded,
4738
+ onClick,
4739
+ style
4740
+ }) {
4741
+ return /* @__PURE__ */ import_react3.default.createElement(
4742
+ "span",
4743
+ {
4744
+ role: "button",
4745
+ onClick,
4746
+ style: {
4747
+ display: "inline-block",
4748
+ textAlign: "center",
4749
+ transform: expanded ? "rotate(0deg)" : "rotate(-90deg)",
4750
+ fontFamily: "Menlo, monospace",
4751
+ ...style
4752
+ }
4753
+ },
4754
+ "\u25BC"
4755
+ );
4756
+ }
4757
+ function pathToString(extendedPath) {
4758
+ return extendedPath.map(
4759
+ (key) => typeof key === "object" ? `:${ellipsis(key.id.toString(), 8, "middle")}` : key
4760
+ ).map(
4761
+ (key, index) => index === 0 || typeof key === "string" && key.startsWith(":") ? key : `.${key}`
4762
+ ).join("");
4763
+ }
4764
+ function ellipsis(str, maxLength, position = "end") {
4765
+ if (str.length <= maxLength) return str;
4766
+ switch (position) {
4767
+ case "start":
4768
+ return `\u2026${str.slice(str.length - maxLength)}`;
4769
+ case "middle":
4770
+ const halfLength = Math.floor(maxLength / 2);
4771
+ return `${str.slice(0, halfLength)}\u2026${str.slice(str.length - halfLength)}`;
4772
+ case "end":
4773
+ return `${str.slice(0, maxLength)}\u2026`;
4858
4774
  }
4859
- TypeSystem2.Format = Format;
4860
- })(TypeSystem || (TypeSystem = {}));
4861
-
4862
- // ../../node_modules/@sinclair/typebox/build/esm/value/hash/hash.mjs
4863
- var ByteMarker;
4864
- (function(ByteMarker2) {
4865
- ByteMarker2[ByteMarker2["Undefined"] = 0] = "Undefined";
4866
- ByteMarker2[ByteMarker2["Null"] = 1] = "Null";
4867
- ByteMarker2[ByteMarker2["Boolean"] = 2] = "Boolean";
4868
- ByteMarker2[ByteMarker2["Number"] = 3] = "Number";
4869
- ByteMarker2[ByteMarker2["String"] = 4] = "String";
4870
- ByteMarker2[ByteMarker2["Object"] = 5] = "Object";
4871
- ByteMarker2[ByteMarker2["Array"] = 6] = "Array";
4872
- ByteMarker2[ByteMarker2["Date"] = 7] = "Date";
4873
- ByteMarker2[ByteMarker2["Uint8Array"] = 8] = "Uint8Array";
4874
- ByteMarker2[ByteMarker2["Symbol"] = 9] = "Symbol";
4875
- ByteMarker2[ByteMarker2["BigInt"] = 10] = "BigInt";
4876
- })(ByteMarker || (ByteMarker = {}));
4877
- var Accumulator = BigInt("14695981039346656037");
4878
- var [Prime, Size] = [BigInt("1099511628211"), BigInt("2") ** BigInt("64")];
4879
- var Bytes = Array.from({ length: 256 }).map((_, i) => BigInt(i));
4880
- var F64 = new Float64Array(1);
4881
- var F64In = new DataView(F64.buffer);
4882
- var F64Out = new Uint8Array(F64.buffer);
4883
-
4884
- // ../../node_modules/@sinclair/typebox/build/esm/errors/errors.mjs
4885
- var ValueErrorType;
4886
- (function(ValueErrorType2) {
4887
- ValueErrorType2[ValueErrorType2["ArrayContains"] = 0] = "ArrayContains";
4888
- ValueErrorType2[ValueErrorType2["ArrayMaxContains"] = 1] = "ArrayMaxContains";
4889
- ValueErrorType2[ValueErrorType2["ArrayMaxItems"] = 2] = "ArrayMaxItems";
4890
- ValueErrorType2[ValueErrorType2["ArrayMinContains"] = 3] = "ArrayMinContains";
4891
- ValueErrorType2[ValueErrorType2["ArrayMinItems"] = 4] = "ArrayMinItems";
4892
- ValueErrorType2[ValueErrorType2["ArrayUniqueItems"] = 5] = "ArrayUniqueItems";
4893
- ValueErrorType2[ValueErrorType2["Array"] = 6] = "Array";
4894
- ValueErrorType2[ValueErrorType2["AsyncIterator"] = 7] = "AsyncIterator";
4895
- ValueErrorType2[ValueErrorType2["BigIntExclusiveMaximum"] = 8] = "BigIntExclusiveMaximum";
4896
- ValueErrorType2[ValueErrorType2["BigIntExclusiveMinimum"] = 9] = "BigIntExclusiveMinimum";
4897
- ValueErrorType2[ValueErrorType2["BigIntMaximum"] = 10] = "BigIntMaximum";
4898
- ValueErrorType2[ValueErrorType2["BigIntMinimum"] = 11] = "BigIntMinimum";
4899
- ValueErrorType2[ValueErrorType2["BigIntMultipleOf"] = 12] = "BigIntMultipleOf";
4900
- ValueErrorType2[ValueErrorType2["BigInt"] = 13] = "BigInt";
4901
- ValueErrorType2[ValueErrorType2["Boolean"] = 14] = "Boolean";
4902
- ValueErrorType2[ValueErrorType2["DateExclusiveMaximumTimestamp"] = 15] = "DateExclusiveMaximumTimestamp";
4903
- ValueErrorType2[ValueErrorType2["DateExclusiveMinimumTimestamp"] = 16] = "DateExclusiveMinimumTimestamp";
4904
- ValueErrorType2[ValueErrorType2["DateMaximumTimestamp"] = 17] = "DateMaximumTimestamp";
4905
- ValueErrorType2[ValueErrorType2["DateMinimumTimestamp"] = 18] = "DateMinimumTimestamp";
4906
- ValueErrorType2[ValueErrorType2["DateMultipleOfTimestamp"] = 19] = "DateMultipleOfTimestamp";
4907
- ValueErrorType2[ValueErrorType2["Date"] = 20] = "Date";
4908
- ValueErrorType2[ValueErrorType2["Function"] = 21] = "Function";
4909
- ValueErrorType2[ValueErrorType2["IntegerExclusiveMaximum"] = 22] = "IntegerExclusiveMaximum";
4910
- ValueErrorType2[ValueErrorType2["IntegerExclusiveMinimum"] = 23] = "IntegerExclusiveMinimum";
4911
- ValueErrorType2[ValueErrorType2["IntegerMaximum"] = 24] = "IntegerMaximum";
4912
- ValueErrorType2[ValueErrorType2["IntegerMinimum"] = 25] = "IntegerMinimum";
4913
- ValueErrorType2[ValueErrorType2["IntegerMultipleOf"] = 26] = "IntegerMultipleOf";
4914
- ValueErrorType2[ValueErrorType2["Integer"] = 27] = "Integer";
4915
- ValueErrorType2[ValueErrorType2["IntersectUnevaluatedProperties"] = 28] = "IntersectUnevaluatedProperties";
4916
- ValueErrorType2[ValueErrorType2["Intersect"] = 29] = "Intersect";
4917
- ValueErrorType2[ValueErrorType2["Iterator"] = 30] = "Iterator";
4918
- ValueErrorType2[ValueErrorType2["Kind"] = 31] = "Kind";
4919
- ValueErrorType2[ValueErrorType2["Literal"] = 32] = "Literal";
4920
- ValueErrorType2[ValueErrorType2["Never"] = 33] = "Never";
4921
- ValueErrorType2[ValueErrorType2["Not"] = 34] = "Not";
4922
- ValueErrorType2[ValueErrorType2["Null"] = 35] = "Null";
4923
- ValueErrorType2[ValueErrorType2["NumberExclusiveMaximum"] = 36] = "NumberExclusiveMaximum";
4924
- ValueErrorType2[ValueErrorType2["NumberExclusiveMinimum"] = 37] = "NumberExclusiveMinimum";
4925
- ValueErrorType2[ValueErrorType2["NumberMaximum"] = 38] = "NumberMaximum";
4926
- ValueErrorType2[ValueErrorType2["NumberMinimum"] = 39] = "NumberMinimum";
4927
- ValueErrorType2[ValueErrorType2["NumberMultipleOf"] = 40] = "NumberMultipleOf";
4928
- ValueErrorType2[ValueErrorType2["Number"] = 41] = "Number";
4929
- ValueErrorType2[ValueErrorType2["ObjectAdditionalProperties"] = 42] = "ObjectAdditionalProperties";
4930
- ValueErrorType2[ValueErrorType2["ObjectMaxProperties"] = 43] = "ObjectMaxProperties";
4931
- ValueErrorType2[ValueErrorType2["ObjectMinProperties"] = 44] = "ObjectMinProperties";
4932
- ValueErrorType2[ValueErrorType2["ObjectRequiredProperty"] = 45] = "ObjectRequiredProperty";
4933
- ValueErrorType2[ValueErrorType2["Object"] = 46] = "Object";
4934
- ValueErrorType2[ValueErrorType2["Promise"] = 47] = "Promise";
4935
- ValueErrorType2[ValueErrorType2["RegExp"] = 48] = "RegExp";
4936
- ValueErrorType2[ValueErrorType2["StringFormatUnknown"] = 49] = "StringFormatUnknown";
4937
- ValueErrorType2[ValueErrorType2["StringFormat"] = 50] = "StringFormat";
4938
- ValueErrorType2[ValueErrorType2["StringMaxLength"] = 51] = "StringMaxLength";
4939
- ValueErrorType2[ValueErrorType2["StringMinLength"] = 52] = "StringMinLength";
4940
- ValueErrorType2[ValueErrorType2["StringPattern"] = 53] = "StringPattern";
4941
- ValueErrorType2[ValueErrorType2["String"] = 54] = "String";
4942
- ValueErrorType2[ValueErrorType2["Symbol"] = 55] = "Symbol";
4943
- ValueErrorType2[ValueErrorType2["TupleLength"] = 56] = "TupleLength";
4944
- ValueErrorType2[ValueErrorType2["Tuple"] = 57] = "Tuple";
4945
- ValueErrorType2[ValueErrorType2["Uint8ArrayMaxByteLength"] = 58] = "Uint8ArrayMaxByteLength";
4946
- ValueErrorType2[ValueErrorType2["Uint8ArrayMinByteLength"] = 59] = "Uint8ArrayMinByteLength";
4947
- ValueErrorType2[ValueErrorType2["Uint8Array"] = 60] = "Uint8Array";
4948
- ValueErrorType2[ValueErrorType2["Undefined"] = 61] = "Undefined";
4949
- ValueErrorType2[ValueErrorType2["Union"] = 62] = "Union";
4950
- ValueErrorType2[ValueErrorType2["Void"] = 63] = "Void";
4951
- })(ValueErrorType || (ValueErrorType = {}));
4952
-
4953
- // ../../node_modules/@sinclair/typebox/build/esm/value/delta/delta.mjs
4954
- var Insert = Object2({
4955
- type: Literal("insert"),
4956
- path: String(),
4957
- value: Unknown()
4958
- });
4959
- var Update = Object2({
4960
- type: Literal("update"),
4961
- path: String(),
4962
- value: Unknown()
4963
- });
4964
- var Delete3 = Object2({
4965
- type: Literal("delete"),
4966
- path: String()
4967
- });
4968
- var Edit = Union([Insert, Update, Delete3]);
4775
+ }
4776
+ function SmallButton({
4777
+ children,
4778
+ onClick,
4779
+ style,
4780
+ theme,
4781
+ disabled
4782
+ }) {
4783
+ return /* @__PURE__ */ import_react3.default.createElement(
4784
+ "button",
4785
+ {
4786
+ type: "button",
4787
+ disabled,
4788
+ onClick: (event) => {
4789
+ event.stopPropagation();
4790
+ onClick();
4791
+ },
4792
+ style: {
4793
+ flex: "0",
4794
+ appearance: "none",
4795
+ background: "none",
4796
+ color: theme.BASE_COLOR,
4797
+ opacity: disabled ? 0.25 : 1,
4798
+ border: "none",
4799
+ fontSize: "12px",
4800
+ whiteSpace: "nowrap",
4801
+ display: "inline-flex",
4802
+ alignItems: "center",
4803
+ justifyContent: "center",
4804
+ padding: "0",
4805
+ cursor: "pointer",
4806
+ ...style
4807
+ }
4808
+ },
4809
+ children
4810
+ );
4811
+ }
4812
+ function ColoredDot({ type }) {
4813
+ return /* @__PURE__ */ import_react3.default.createElement(
4814
+ "span",
4815
+ {
4816
+ style: {
4817
+ display: "inline-block",
4818
+ width: 6,
4819
+ height: 6,
4820
+ background: type === "success" ? "rgba(0,200,0,0.8)" : "rgba(200,0,0,0.8)",
4821
+ borderRadius: "50%",
4822
+ verticalAlign: "middle"
4823
+ }
4824
+ }
4825
+ );
4826
+ }
4827
+ function TitleLabel({ children }) {
4828
+ return /* @__PURE__ */ import_react3.default.createElement("span", { style: { display: "flex", alignItems: "center", gap: "4px" } }, children);
4829
+ }
4969
4830
 
4970
- // ../noya-schemas/src/SchemaTree.ts
4971
- var import_tree_visit = __toESM(require_lib());
4972
- var SchemaTree = (0, import_tree_visit.defineTree)((schema) => {
4973
- if (type_exports.IsUnion(schema)) {
4974
- return schema.anyOf;
4975
- } else if (type_exports.IsObject(schema)) {
4976
- return Object.values(schema.properties);
4977
- } else if (type_exports.IsArray(schema)) {
4978
- return [schema.items];
4979
- }
4980
- return [];
4981
- }).withOptions({
4982
- getLabel(node) {
4983
- return node[Kind] ?? "<UnknownKind>";
4984
- }
4985
- });
4986
- function findAllDefs(schema) {
4987
- if (!schema) return [];
4988
- return SchemaTree.flatMap(schema, (node) => {
4989
- return node.$id ? [node] : [];
4990
- });
4831
+ // src/inspector/useStateInspector.tsx
4832
+ function createShadowRootElement() {
4833
+ const host = document.createElement("div");
4834
+ host.id = "noya-multiplayer-react-inspector-host";
4835
+ const shadowRoot = host.attachShadow({ mode: "open" });
4836
+ const container = document.createElement("div");
4837
+ shadowRoot.appendChild(container);
4838
+ return { host, container };
4839
+ }
4840
+ function useStateInspector({
4841
+ noyaManager,
4842
+ disabled = false,
4843
+ colorScheme,
4844
+ anchor
4845
+ }) {
4846
+ const [root, setRoot] = import_react4.default.useState(null);
4847
+ (0, import_react4.useLayoutEffect)(() => {
4848
+ if (disabled) return;
4849
+ const { host, container } = createShadowRootElement();
4850
+ const root2 = (0, import_client.createRoot)(container);
4851
+ document.body.appendChild(host);
4852
+ setRoot(root2);
4853
+ return () => {
4854
+ document.body.removeChild(host);
4855
+ };
4856
+ }, [disabled]);
4857
+ (0, import_react4.useLayoutEffect)(() => {
4858
+ if (!root) return;
4859
+ root.render(
4860
+ /* @__PURE__ */ import_react4.default.createElement(
4861
+ StateInspector,
4862
+ {
4863
+ colorScheme,
4864
+ anchor,
4865
+ noyaManager
4866
+ }
4867
+ )
4868
+ );
4869
+ }, [noyaManager, anchor, colorScheme, root]);
4991
4870
  }
4992
4871
 
4993
- // ../noya-schemas/src/index.ts
4994
- function validateUUID(value) {
4995
- return /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/.test(
4996
- value
4872
+ // src/hooks.ts
4873
+ function useSyncStateManager(stateManager, path) {
4874
+ const getSnapshot = (0, import_react5.useCallback)(
4875
+ () => typeof path === "string" ? stateManager.getState(path) : stateManager.getState(),
4876
+ [stateManager, path]
4877
+ );
4878
+ return (0, import_react5.useSyncExternalStore)(
4879
+ stateManager.addListener,
4880
+ getSnapshot,
4881
+ getSnapshot
4997
4882
  );
4998
4883
  }
4999
- format_exports.Set("color", () => true);
5000
- format_exports.Set("uuid", validateUUID);
4884
+ function useManagedState(createInitialState, options) {
4885
+ const [stateManager] = (0, import_react5.useState)(
4886
+ () => new import_state_manager.StateManager(createInitialState(), options)
4887
+ );
4888
+ const state = useSyncStateManager(stateManager);
4889
+ const setState = (0, import_react5.useCallback)(
4890
+ (...args) => {
4891
+ const [metadata, action] = args.length === 1 ? [void 0, args[0]] : args;
4892
+ if (metadata === void 0) {
4893
+ const performActionNoMetadata = stateManager.performAction;
4894
+ if (action instanceof Function) {
4895
+ performActionNoMetadata({
4896
+ run: action,
4897
+ undo: () => state
4898
+ });
4899
+ } else {
4900
+ performActionNoMetadata({
4901
+ run: () => action,
4902
+ undo: () => state
4903
+ });
4904
+ }
4905
+ } else {
4906
+ const performActionWithMetadata = stateManager.performAction;
4907
+ if (action instanceof Function) {
4908
+ performActionWithMetadata(metadata, {
4909
+ run: action,
4910
+ undo: () => state
4911
+ });
4912
+ } else {
4913
+ performActionWithMetadata(metadata, {
4914
+ run: () => action,
4915
+ undo: () => state
4916
+ });
4917
+ }
4918
+ }
4919
+ },
4920
+ [state, stateManager]
4921
+ );
4922
+ return [state, setState, stateManager];
4923
+ }
4924
+ function useManagedHistory(stateManager) {
4925
+ return (0, import_react5.useSyncExternalStore)(
4926
+ stateManager.historyEmittor.addListener,
4927
+ stateManager.getHistorySnapshot,
4928
+ stateManager.getHistorySnapshot
4929
+ );
4930
+ }
4931
+ var defaultStubSync = (0, import_state_manager.stubSync)();
4932
+ function useMultiplayerState(initialState, options) {
4933
+ const {
4934
+ sync = defaultStubSync,
4935
+ inspector,
4936
+ ...rest
4937
+ } = options ?? {};
4938
+ const [noyaManager] = (0, import_react5.useState)(
4939
+ () => new import_state_manager.NoyaManager(initialState, rest)
4940
+ );
4941
+ const state = useObservable(
4942
+ noyaManager.multiplayerStateManager.optimisticState$
4943
+ );
4944
+ const assets = useObservable(noyaManager.assetManager.assets$);
4945
+ const extras = (0, import_react5.useMemo)(() => {
4946
+ return {
4947
+ noyaManager,
4948
+ taskManager: noyaManager.taskManager,
4949
+ connectionEventManager: noyaManager.connectionEventManager,
4950
+ connectedUsersManager: noyaManager.connectedUsersManager,
4951
+ ephemeralUserDataManager: noyaManager.ephemeralUserDataManager,
4952
+ multiplayerStateManager: noyaManager.multiplayerStateManager,
4953
+ assetManager: noyaManager.assetManager,
4954
+ aiManager: noyaManager.aiManager,
4955
+ rpcManager: noyaManager.rpcManager,
4956
+ pipelineManager: noyaManager.pipelineManager,
4957
+ secretManager: noyaManager.secretManager,
4958
+ menuItemsManager: noyaManager.menuManager,
4959
+ createAsset: noyaManager.assetManager.create,
4960
+ deleteAsset: noyaManager.assetManager.delete,
4961
+ assets
4962
+ };
4963
+ }, [noyaManager, assets]);
4964
+ const syncRef = (0, import_react5.useRef)(sync);
4965
+ (0, import_react5.useEffect)(() => {
4966
+ if (syncRef.current) {
4967
+ return syncRef.current({ noyaManager });
4968
+ }
4969
+ }, [noyaManager]);
4970
+ useErrorOverlay(noyaManager);
4971
+ useStateInspector({
4972
+ noyaManager,
4973
+ disabled: !inspector,
4974
+ ...typeof inspector === "object" && inspector
4975
+ });
4976
+ return [state, noyaManager.multiplayerStateManager.setState, extras];
4977
+ }
4978
+ function useErrorOverlay(noyaManager) {
4979
+ const unrecoverableError = useObservable(noyaManager.unrecoverableError);
4980
+ (0, import_react5.useEffect)(() => {
4981
+ if (!unrecoverableError) return;
4982
+ const el = document.createElement("div");
4983
+ el.id = "noya-multiplayer-react-error-overlay";
4984
+ document.body.appendChild(el);
4985
+ const root = (0, import_client2.createRoot)(el);
4986
+ root.render((0, import_react5.createElement)(ErrorOverlay, { error: unrecoverableError }));
4987
+ return () => {
4988
+ root.unmount();
4989
+ el.remove();
4990
+ };
4991
+ });
4992
+ }
5001
4993
 
5002
4994
  // src/noyaApp.ts
5003
- var import_state_manager2 = require("@noya-app/state-manager");
5004
- var import_react7 = require("react");
5005
4995
  function createDefaultAppData(initialState) {
5006
4996
  return {
5007
4997
  theme: "light",
@@ -5050,12 +5040,12 @@ function useNoyaState(...args) {
5050
5040
  theme,
5051
5041
  viewType
5052
5042
  }
5053
- ] = (0, import_react7.useState)(() => {
5043
+ ] = (0, import_react6.useState)(() => {
5054
5044
  return getAppData(initialState, options?.schema, {
5055
5045
  overrideExistingState: options?.overrideExistingState
5056
5046
  });
5057
5047
  });
5058
- const sync = (0, import_react7.useMemo)(() => {
5048
+ const sync = (0, import_react6.useMemo)(() => {
5059
5049
  return (0, import_state_manager2.isEmbeddedApp)() ? (0, import_state_manager2.parentFrameSync)({ debug: options?.debug }) : multiplayerUrl ? (0, import_state_manager2.webSocketSync)({
5060
5050
  url: multiplayerUrl,
5061
5051
  debug: options?.debug
@@ -5067,18 +5057,16 @@ function useNoyaState(...args) {
5067
5057
  sync: options?.sync ?? sync
5068
5058
  });
5069
5059
  const [, , extras] = result;
5070
- const mergedExtras = (0, import_react7.useMemo)(() => {
5060
+ const mergedExtras = (0, import_react6.useMemo)(() => {
5071
5061
  return { ...extras, theme, viewType };
5072
5062
  }, [extras, theme, viewType]);
5073
5063
  return [result[0], result[1], mergedExtras];
5074
5064
  }
5075
5065
 
5076
5066
  // src/NoyaStateContext.tsx
5077
- var import_observable = require("@noya-app/observable");
5078
- var import_react8 = __toESM(require("react"));
5079
- var AnyNoyaStateContext = (0, import_react8.createContext)(void 0);
5067
+ var AnyNoyaStateContext = (0, import_react7.createContext)(void 0);
5080
5068
  function useAnyNoyaStateContext() {
5081
- const value = (0, import_react8.useContext)(AnyNoyaStateContext);
5069
+ const value = (0, import_react7.useContext)(AnyNoyaStateContext);
5082
5070
  if (!value) {
5083
5071
  throw new Error(
5084
5072
  "useNoyaStateContext must be used within a NoyaStateProvider"
@@ -5104,7 +5092,7 @@ function useAssets() {
5104
5092
  }
5105
5093
  function useAsset(id) {
5106
5094
  const { noyaManager } = useAnyNoyaStateContext();
5107
- const observable = (0, import_react8.useMemo)(
5095
+ const observable = (0, import_react7.useMemo)(
5108
5096
  () => noyaManager.assetManager.assets$.map(
5109
5097
  (assets) => assets.find((a) => a.id === id)
5110
5098
  ),
@@ -5115,7 +5103,7 @@ function useAsset(id) {
5115
5103
  function useAssetManager() {
5116
5104
  const { noyaManager } = useAnyNoyaStateContext();
5117
5105
  const isInitialized = useObservable(noyaManager.assetManager.isInitialized$);
5118
- return (0, import_react8.useMemo)(
5106
+ return (0, import_react7.useMemo)(
5119
5107
  () => ({
5120
5108
  create: noyaManager.assetManager.create,
5121
5109
  delete: noyaManager.assetManager.delete,
@@ -5140,7 +5128,7 @@ function useSecret(name) {
5140
5128
  const { noyaManager } = useAnyNoyaStateContext();
5141
5129
  return useObservable(
5142
5130
  noyaManager.secretManager.secrets$,
5143
- (0, import_react8.useCallback)((secrets) => secrets.find((s) => s.name === name), [name])
5131
+ (0, import_react7.useCallback)((secrets) => secrets.find((s) => s.name === name), [name])
5144
5132
  );
5145
5133
  }
5146
5134
  function useInputs() {
@@ -5157,7 +5145,7 @@ function useIOManager() {
5157
5145
  }
5158
5146
  function useIsInitialized() {
5159
5147
  const { noyaManager, viewType } = useAnyNoyaStateContext();
5160
- const isInitializedObservable = (0, import_react8.useMemo)(
5148
+ const isInitializedObservable = (0, import_react7.useMemo)(
5161
5149
  () => import_observable.Observable.combine(
5162
5150
  [
5163
5151
  ...viewType === "preview" ? [] : [noyaManager.multiplayerStateManager.isInitialized$],
@@ -5170,17 +5158,17 @@ function useIsInitialized() {
5170
5158
  );
5171
5159
  return useObservable(isInitializedObservable);
5172
5160
  }
5173
- function useWorkflowManager() {
5161
+ function usePipelineManager() {
5174
5162
  const { noyaManager } = useAnyNoyaStateContext();
5175
- return noyaManager.workflowManager;
5163
+ return noyaManager.pipelineManager;
5176
5164
  }
5177
- var ConnectedUsersContext = (0, import_react8.createContext)(void 0);
5165
+ var ConnectedUsersContext = (0, import_react7.createContext)(void 0);
5178
5166
  function useConnectedUsersManager() {
5179
- return (0, import_react8.useContext)(ConnectedUsersContext);
5167
+ return (0, import_react7.useContext)(ConnectedUsersContext);
5180
5168
  }
5181
- var AnyEphemeralUserDataManagerContext = (0, import_react8.createContext)(void 0);
5169
+ var AnyEphemeralUserDataManagerContext = (0, import_react7.createContext)(void 0);
5182
5170
  function useAnyEphemeralUserData() {
5183
- return (0, import_react8.useContext)(AnyEphemeralUserDataManagerContext);
5171
+ return (0, import_react7.useContext)(AnyEphemeralUserDataManagerContext);
5184
5172
  }
5185
5173
  function useCurrentUserId() {
5186
5174
  const connectedUsersManager = useConnectedUsersManager();
@@ -5216,7 +5204,7 @@ function createNoyaContext({
5216
5204
  ...options
5217
5205
  }
5218
5206
  );
5219
- const contextValue = (0, import_react8.useMemo)(
5207
+ const contextValue = (0, import_react7.useMemo)(
5220
5208
  () => ({
5221
5209
  noyaManager,
5222
5210
  theme,
@@ -5224,24 +5212,24 @@ function createNoyaContext({
5224
5212
  }),
5225
5213
  [noyaManager, theme, viewType]
5226
5214
  );
5227
- return /* @__PURE__ */ import_react8.default.createElement(AnyNoyaStateContext.Provider, { value: contextValue }, /* @__PURE__ */ import_react8.default.createElement(
5215
+ return /* @__PURE__ */ import_react7.default.createElement(AnyNoyaStateContext.Provider, { value: contextValue }, /* @__PURE__ */ import_react7.default.createElement(
5228
5216
  ConnectedUsersContext.Provider,
5229
5217
  {
5230
5218
  value: noyaManager.connectedUsersManager
5231
5219
  },
5232
- /* @__PURE__ */ import_react8.default.createElement(
5220
+ /* @__PURE__ */ import_react7.default.createElement(
5233
5221
  EphemeralUserDataManagerContext.Provider,
5234
5222
  {
5235
5223
  value: noyaManager.ephemeralUserDataManager
5236
5224
  },
5237
- options.fallback !== void 0 ? /* @__PURE__ */ import_react8.default.createElement(FallbackUntilInitialized, { fallback: options.fallback }, children) : children
5225
+ options.fallback !== void 0 ? /* @__PURE__ */ import_react7.default.createElement(FallbackUntilInitialized, { fallback: options.fallback }, children) : children
5238
5226
  )
5239
5227
  ));
5240
5228
  }
5241
5229
  function useValue(path, options) {
5242
5230
  const { noyaManager } = useAnyNoyaStateContext();
5243
5231
  let actualPath = typeof path === "function" || !path ? "" : path;
5244
- const mappedObservable = (0, import_react8.useMemo)(() => {
5232
+ const mappedObservable = (0, import_react7.useMemo)(() => {
5245
5233
  if (typeof path === "function") {
5246
5234
  return noyaManager.multiplayerStateManager.optimisticState$.map(path, {
5247
5235
  isEqual: options?.isEqual
@@ -5254,7 +5242,7 @@ function createNoyaContext({
5254
5242
  }
5255
5243
  function useSetValue(path) {
5256
5244
  const { noyaManager } = useAnyNoyaStateContext();
5257
- const setValue = (0, import_react8.useCallback)(
5245
+ const setValue = (0, import_react7.useCallback)(
5258
5246
  (...args) => {
5259
5247
  const [metadata, value] = args.length === 2 ? args : [{}, args[0]];
5260
5248
  noyaManager.multiplayerStateManager.setStateAtPath(
@@ -5278,7 +5266,7 @@ function createNoyaContext({
5278
5266
  return noyaManager.multiplayerStateManager;
5279
5267
  }
5280
5268
  function useEphemeralUserDataManager() {
5281
- const ephemeralUserData = (0, import_react8.useContext)(EphemeralUserDataManagerContext);
5269
+ const ephemeralUserData = (0, import_react7.useContext)(EphemeralUserDataManagerContext);
5282
5270
  if (!ephemeralUserData) {
5283
5271
  throw new Error(
5284
5272
  "useEphemeralUserData must be used within a NoyaStateProvider"
@@ -5295,7 +5283,7 @@ function createNoyaContext({
5295
5283
  }
5296
5284
  function useSetLeftMenuItems(leftMenuItems) {
5297
5285
  const { menuManager } = useNoyaManager();
5298
- (0, import_react8.useEffect)(() => {
5286
+ (0, import_react7.useEffect)(() => {
5299
5287
  if (leftMenuItems) {
5300
5288
  menuManager.setLeftMenuItems(leftMenuItems);
5301
5289
  }
@@ -5307,7 +5295,7 @@ function createNoyaContext({
5307
5295
  }
5308
5296
  function useSetRightMenuItems(rightMenuItems) {
5309
5297
  const { menuManager } = useNoyaManager();
5310
- (0, import_react8.useEffect)(() => {
5298
+ (0, import_react7.useEffect)(() => {
5311
5299
  if (rightMenuItems) {
5312
5300
  menuManager.setRightMenuItems(rightMenuItems);
5313
5301
  }
@@ -5315,19 +5303,19 @@ function createNoyaContext({
5315
5303
  }
5316
5304
  function useHandleMenuItem(callback) {
5317
5305
  const { menuManager } = useNoyaManager();
5318
- (0, import_react8.useEffect)(() => {
5306
+ (0, import_react7.useEffect)(() => {
5319
5307
  return menuManager.addListener(callback);
5320
5308
  }, [menuManager, callback]);
5321
5309
  }
5322
5310
  function useOnSelectMenuItemCallback() {
5323
5311
  const { menuManager } = useNoyaManager();
5324
- return (0, import_react8.useCallback)((type) => menuManager.emit(type), [menuManager]);
5312
+ return (0, import_react7.useCallback)((type) => menuManager.emit(type), [menuManager]);
5325
5313
  }
5326
5314
  function useMenu(options) {
5327
5315
  const { leftMenuItems, rightMenuItems, onSelectMenuItem } = options;
5328
5316
  useSetLeftMenuItems(leftMenuItems);
5329
5317
  useSetRightMenuItems(rightMenuItems);
5330
- const noop = (0, import_react8.useCallback)(() => {
5318
+ const noop = (0, import_react7.useCallback)(() => {
5331
5319
  }, []);
5332
5320
  useHandleMenuItem(onSelectMenuItem ?? noop);
5333
5321
  }
@@ -5350,6 +5338,75 @@ function createNoyaContext({
5350
5338
  };
5351
5339
  }
5352
5340
 
5341
+ // src/ai.ts
5342
+ function useRegisterAITool(tool) {
5343
+ const aiManager = useAIManager();
5344
+ (0, import_react8.useEffect)(() => {
5345
+ return aiManager.registerTool(tool);
5346
+ }, [aiManager, tool]);
5347
+ }
5348
+ function useCallableAITools() {
5349
+ const aiManager = useAIManager();
5350
+ return useObservable(aiManager.callableTools$);
5351
+ }
5352
+
5353
+ // src/components/UserPointersOverlay.tsx
5354
+ var import_react_utils2 = require("@noya-app/react-utils");
5355
+ var import_react9 = __toESM(require("react"));
5356
+ function shouldShow(hideAfter, updatedAt) {
5357
+ return !!updatedAt && Date.now() - updatedAt < hideAfter;
5358
+ }
5359
+ var UserPointerInternal = (0, import_react_utils2.memoGeneric)(function UserPointerInternal2({
5360
+ user,
5361
+ ephemeralUserDataManager,
5362
+ hideAfter = 5e3,
5363
+ renderUserPointer
5364
+ }) {
5365
+ const metadata = useObservable(ephemeralUserDataManager.metadata$, [
5366
+ user.id
5367
+ ]);
5368
+ const data = useObservable(ephemeralUserDataManager.data$, [
5369
+ user.id
5370
+ ]);
5371
+ const [, setForceUpdate] = (0, import_react9.useState)(0);
5372
+ const updatedAt = metadata?.updatedAt ?? 0;
5373
+ const show = shouldShow(hideAfter, updatedAt);
5374
+ (0, import_react9.useEffect)(() => {
5375
+ if (!show) return;
5376
+ const timeoutId = setTimeout(() => {
5377
+ setForceUpdate((prev) => prev + 1);
5378
+ }, hideAfter);
5379
+ return () => clearTimeout(timeoutId);
5380
+ }, [hideAfter, show, updatedAt]);
5381
+ if (!data?.pointer) return null;
5382
+ return renderUserPointer({
5383
+ userId: user.id,
5384
+ name: user.name,
5385
+ point: data.pointer,
5386
+ visible: show
5387
+ });
5388
+ });
5389
+ var UserPointersOverlay = (0, import_react_utils2.memoGeneric)(function UserPointers({
5390
+ connectedUsersManager,
5391
+ ephemeralUserDataManager,
5392
+ renderUserPointer
5393
+ }) {
5394
+ const currentUserId = useObservable(ephemeralUserDataManager.currentUserId$);
5395
+ const connectedUsers = useObservable(connectedUsersManager.connectedUsers$);
5396
+ return /* @__PURE__ */ import_react9.default.createElement(import_react9.default.Fragment, null, connectedUsers.map((user) => {
5397
+ if (user.id === currentUserId) return null;
5398
+ return /* @__PURE__ */ import_react9.default.createElement(
5399
+ UserPointerInternal,
5400
+ {
5401
+ key: user.id,
5402
+ user,
5403
+ ephemeralUserDataManager,
5404
+ renderUserPointer
5405
+ }
5406
+ );
5407
+ }));
5408
+ });
5409
+
5353
5410
  // src/WebSocketConnection.ts
5354
5411
  var import_state_manager3 = require("@noya-app/state-manager");
5355
5412
  var WebSocketConnection = class {
@@ -5365,32 +5422,13 @@ var WebSocketConnection = class {
5365
5422
  });
5366
5423
  }
5367
5424
  ws;
5368
- pingCount = 0;
5369
- pendingPingId;
5370
- intervalId;
5425
+ closedForever = false;
5371
5426
  async connect() {
5427
+ if (this.closedForever) return;
5372
5428
  this.ws.connect(this.url.toString());
5373
- this.intervalId = setInterval(() => {
5374
- if (this.ws.state !== "OPEN") return;
5375
- if (this.pendingPingId) {
5376
- this.ws.close();
5377
- return;
5378
- }
5379
- const pingId = (this.pingCount++).toString();
5380
- const message = {
5381
- type: "ping",
5382
- id: pingId
5383
- };
5384
- this.pendingPingId = message.id;
5385
- this.options.onConnectionEvent?.({
5386
- type: "send",
5387
- message
5388
- });
5389
- this.ws.send(JSON.stringify(message));
5390
- }, 1e4);
5391
5429
  }
5392
5430
  handleOpen = () => {
5393
- this.pendingPingId = void 0;
5431
+ if (this.closedForever) return;
5394
5432
  if (this.options.debug) {
5395
5433
  console.info("ws connected");
5396
5434
  }
@@ -5400,6 +5438,7 @@ var WebSocketConnection = class {
5400
5438
  });
5401
5439
  };
5402
5440
  handleMessage = (event) => {
5441
+ if (this.closedForever) return;
5403
5442
  if (this.options.debug) {
5404
5443
  console.info("ws receiving message ", event.data);
5405
5444
  }
@@ -5408,12 +5447,9 @@ var WebSocketConnection = class {
5408
5447
  type: "receive",
5409
5448
  message: parsed
5410
5449
  });
5411
- if (parsed.type === "pong" && parsed.id === this.pendingPingId) {
5412
- this.pendingPingId = void 0;
5413
- }
5414
5450
  };
5415
5451
  handleClose = () => {
5416
- this.pendingPingId = void 0;
5452
+ if (this.closedForever) return;
5417
5453
  if (this.options.debug) {
5418
5454
  console.info("ws disconnected");
5419
5455
  }
@@ -5423,6 +5459,7 @@ var WebSocketConnection = class {
5423
5459
  });
5424
5460
  };
5425
5461
  send(message) {
5462
+ if (this.closedForever) return;
5426
5463
  if (this.options.debug) {
5427
5464
  console.info("ws sending message", message);
5428
5465
  }
@@ -5433,10 +5470,12 @@ var WebSocketConnection = class {
5433
5470
  this.ws.send(JSON.stringify(message));
5434
5471
  }
5435
5472
  close() {
5436
- if (this.intervalId) {
5437
- clearInterval(this.intervalId);
5438
- }
5473
+ if (this.closedForever) return;
5474
+ this.closedForever = true;
5439
5475
  this.ws.shutdown();
5476
+ this.ws.listeners.forEach((listener) => {
5477
+ this.ws.removeListener(listener);
5478
+ });
5440
5479
  }
5441
5480
  addListener(listener) {
5442
5481
  return this.ws.addListener(listener);
@@ -5448,6 +5487,7 @@ var WebSocketConnection = class {
5448
5487
  // Annotate the CommonJS export names for ESM import in node:
5449
5488
  0 && (module.exports = {
5450
5489
  AnyEphemeralUserDataManagerContext,
5490
+ AnyNoyaStateContext,
5451
5491
  ConnectedUsersContext,
5452
5492
  FallbackUntilInitialized,
5453
5493
  StateInspector,
@@ -5465,6 +5505,7 @@ var WebSocketConnection = class {
5465
5505
  useAsset,
5466
5506
  useAssetManager,
5467
5507
  useAssets,
5508
+ useCallableAITools,
5468
5509
  useColorScheme,
5469
5510
  useConnectedUsersManager,
5470
5511
  useCurrentUserId,
@@ -5477,12 +5518,13 @@ var WebSocketConnection = class {
5477
5518
  useNoyaState,
5478
5519
  useObservable,
5479
5520
  useOutputTransforms,
5521
+ usePipelineManager,
5522
+ useRegisterAITool,
5480
5523
  useSecret,
5481
5524
  useSecretManager,
5482
5525
  useSecrets,
5483
5526
  useSyncStateManager,
5484
5527
  useViewType,
5485
- useWorkflowManager,
5486
5528
  ...require("@noya-app/state-manager")
5487
5529
  });
5488
5530
  //# sourceMappingURL=index.js.map