@noya-app/noya-multiplayer-react 0.1.35 → 0.1.37

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.mjs CHANGED
@@ -195,6 +195,7 @@ var UserPointerIcon = memo(function CursorIcon({
195
195
 
196
196
  // src/hooks.ts
197
197
  import {
198
+ AssetManager,
198
199
  EphemeralUserData,
199
200
  MultiplayerStateManager,
200
201
  StateManager,
@@ -521,6 +522,7 @@ var StateInspector = memo2(function StateInspector2({
521
522
  unstyled,
522
523
  colorScheme = "light",
523
524
  multiplayerStateManager,
525
+ assetManager,
524
526
  ephemeralUserData,
525
527
  anchor = "right",
526
528
  forceInit,
@@ -560,6 +562,10 @@ var StateInspector = memo2(function StateInspector2({
560
562
  "noya-multiplayer-react-show-ephemeral",
561
563
  false
562
564
  );
565
+ const [showAssets, setShowAssets] = useLocalStorageState(
566
+ "noya-multiplayer-react-show-assets",
567
+ false
568
+ );
563
569
  useEffect2(() => {
564
570
  shouldTrackEvents$.set(showEvents);
565
571
  }, [showEvents]);
@@ -573,6 +579,7 @@ var StateInspector = memo2(function StateInspector2({
573
579
  }, [connectionEvents]);
574
580
  const ephemeral = useEphemeralUserData(ephemeralUserData);
575
581
  const historySnapshot = useManagedHistory(multiplayerStateManager.sm);
582
+ const assets = useObservable(assetManager.assets$);
576
583
  useEffect2(() => {
577
584
  if (historyContainerRef.current) {
578
585
  historyContainerRef.current.scrollTop = historyContainerRef.current.scrollHeight;
@@ -888,6 +895,46 @@ var StateInspector = memo2(function StateInspector2({
888
895
  ))
889
896
  )))
890
897
  ),
898
+ /* @__PURE__ */ React4.createElement(
899
+ DisclosureSection,
900
+ {
901
+ open: showAssets,
902
+ setOpen: setShowAssets,
903
+ title: "Assets",
904
+ colorScheme,
905
+ right: /* @__PURE__ */ React4.createElement("span", { style: { display: "flex", gap: "4px" } }, /* @__PURE__ */ React4.createElement(
906
+ SmallButton,
907
+ {
908
+ theme,
909
+ onClick: () => {
910
+ const input = document.createElement("input");
911
+ input.type = "file";
912
+ input.onchange = () => {
913
+ const file = input.files?.[0];
914
+ if (file) {
915
+ const reader = new FileReader();
916
+ reader.onload = () => {
917
+ const buffer = reader.result;
918
+ assetManager.create(new Uint8Array(buffer));
919
+ };
920
+ reader.readAsArrayBuffer(file);
921
+ }
922
+ };
923
+ input.click();
924
+ }
925
+ },
926
+ "Upload"
927
+ ))
928
+ },
929
+ /* @__PURE__ */ React4.createElement("div", { style: styles.sectionInner }, assets.map((asset) => /* @__PURE__ */ React4.createElement(InspectorRow, { key: asset.id, colorScheme }, /* @__PURE__ */ React4.createElement(ObjectInspector, { name: asset.id, data: asset, theme }), /* @__PURE__ */ React4.createElement(
930
+ SmallButton,
931
+ {
932
+ theme,
933
+ onClick: () => assetManager.delete(asset.id)
934
+ },
935
+ "Delete"
936
+ ))))
937
+ ),
891
938
  /* @__PURE__ */ React4.createElement(
892
939
  DisclosureSection,
893
940
  {
@@ -1091,7 +1138,7 @@ function SmallButton({
1091
1138
  display: "inline-flex",
1092
1139
  alignItems: "center",
1093
1140
  justifyContent: "center",
1094
- padding: "2px 0",
1141
+ padding: "0",
1095
1142
  cursor: "pointer",
1096
1143
  ...style
1097
1144
  }
@@ -1101,10 +1148,13 @@ function SmallButton({
1101
1148
  }
1102
1149
 
1103
1150
  // src/inspector/useStateInspector.tsx
1104
- function createPortalElement() {
1105
- const el = document.createElement("div");
1106
- el.id = "noya-multiplayer-react-inspector-portal";
1107
- return el;
1151
+ function createShadowRootElement() {
1152
+ const host = document.createElement("div");
1153
+ host.id = "noya-multiplayer-react-inspector-host";
1154
+ const shadowRoot = host.attachShadow({ mode: "open" });
1155
+ const container = document.createElement("div");
1156
+ shadowRoot.appendChild(container);
1157
+ return { host, container };
1108
1158
  }
1109
1159
  function useStateInspector({
1110
1160
  state,
@@ -1116,6 +1166,7 @@ function useStateInspector({
1116
1166
  colorScheme,
1117
1167
  anchor,
1118
1168
  multiplayerStateManager,
1169
+ assetManager,
1119
1170
  ephemeralUserData,
1120
1171
  forceInit
1121
1172
  }) {
@@ -1123,12 +1174,12 @@ function useStateInspector({
1123
1174
  useLayoutEffect2(() => {
1124
1175
  if (disabled)
1125
1176
  return;
1126
- const portalElement = createPortalElement();
1127
- const root2 = createRoot(portalElement);
1128
- document.body.appendChild(portalElement);
1177
+ const { host, container } = createShadowRootElement();
1178
+ const root2 = createRoot(container);
1179
+ document.body.appendChild(host);
1129
1180
  setRoot(root2);
1130
1181
  return () => {
1131
- document.body.removeChild(portalElement);
1182
+ document.body.removeChild(host);
1132
1183
  };
1133
1184
  }, [disabled]);
1134
1185
  useLayoutEffect2(() => {
@@ -1147,6 +1198,7 @@ function useStateInspector({
1147
1198
  anchor,
1148
1199
  forceInit,
1149
1200
  multiplayerStateManager,
1201
+ assetManager,
1150
1202
  ephemeralUserData
1151
1203
  }
1152
1204
  )
@@ -1162,7 +1214,8 @@ function useStateInspector({
1162
1214
  userId,
1163
1215
  tasks,
1164
1216
  forceInit,
1165
- ephemeralUserData
1217
+ ephemeralUserData,
1218
+ assetManager
1166
1219
  ]);
1167
1220
  }
1168
1221
 
@@ -1277,6 +1330,7 @@ function useMultiplayerState(initialState, options) {
1277
1330
  const [multiplayerStateManager] = useState2(
1278
1331
  () => new MultiplayerStateManager(initialState, rest)
1279
1332
  );
1333
+ const [assetManager] = useState2(() => new AssetManager());
1280
1334
  const syncRef = useRef(sync);
1281
1335
  const [connectionEvents, setConnectionEvents] = useState2();
1282
1336
  const [connectedUsers, setConnectedUsers] = useState2([]);
@@ -1285,6 +1339,7 @@ function useMultiplayerState(initialState, options) {
1285
1339
  );
1286
1340
  const [tasks, setTasks] = useState2([]);
1287
1341
  const [userId, setUserId] = useState2();
1342
+ const assets = useObservable(assetManager.assets$);
1288
1343
  const extras = useMemo3(() => {
1289
1344
  return {
1290
1345
  tasks,
@@ -1292,7 +1347,10 @@ function useMultiplayerState(initialState, options) {
1292
1347
  connectionEvents,
1293
1348
  connectedUsers,
1294
1349
  ephemeralUserData,
1295
- multiplayerStateManager
1350
+ multiplayerStateManager,
1351
+ assets,
1352
+ createAsset: assetManager.create,
1353
+ deleteAsset: assetManager.delete
1296
1354
  // evaluate: async (code: string) => {
1297
1355
  // const payload = await rpcManager.request({ type: "eval", code });
1298
1356
  // if (payload.type !== "eval") {
@@ -1306,7 +1364,9 @@ function useMultiplayerState(initialState, options) {
1306
1364
  connectionEvents,
1307
1365
  connectedUsers,
1308
1366
  ephemeralUserData,
1309
- multiplayerStateManager
1367
+ multiplayerStateManager,
1368
+ assetManager,
1369
+ assets
1310
1370
  ]);
1311
1371
  const globalTrackEvents = useObservable(shouldTrackEvents$);
1312
1372
  const globalTrackTasks = useObservable(shouldTrackTasks$);
@@ -1340,13 +1400,14 @@ function useMultiplayerState(initialState, options) {
1340
1400
  if (syncRef.current) {
1341
1401
  return syncRef.current({
1342
1402
  ms: multiplayerStateManager,
1403
+ assetManager,
1343
1404
  ephemeralUserData,
1344
1405
  onConnectionEvent: (e) => trackEventsCallbackRef.current?.(e),
1345
1406
  onChangeConnectedUsers: (users, userId2) => trackConnectedUsersCallbackRef.current?.(users, userId2),
1346
1407
  onChangeTasks: (tasks2) => trackTasksCallbackRef.current?.(tasks2)
1347
1408
  });
1348
1409
  }
1349
- }, [ephemeralUserData, multiplayerStateManager]);
1410
+ }, [assetManager, ephemeralUserData, multiplayerStateManager]);
1350
1411
  const state = useSyncMultiplayerStateManager(multiplayerStateManager);
1351
1412
  const forceInit = useCallback(() => {
1352
1413
  const state2 = initialState instanceof Function ? initialState() : initialState;
@@ -1376,6 +1437,7 @@ function useMultiplayerState(initialState, options) {
1376
1437
  useStateInspector({
1377
1438
  ephemeralUserData,
1378
1439
  multiplayerStateManager,
1440
+ assetManager,
1379
1441
  state,
1380
1442
  connectionEvents,
1381
1443
  connectedUsers,
@@ -1394,6 +1456,7 @@ import {
1394
1456
  findAllDefs,
1395
1457
  localStorageSync,
1396
1458
  stubSync as stubSync2,
1459
+ TypeGuard,
1397
1460
  webSocketSync
1398
1461
  } from "@noya-app/state-manager";
1399
1462
  import { useEffect as useEffect4, useMemo as useMemo4, useState as useState3 } from "react";
@@ -1471,7 +1534,8 @@ function useBroadcastMenuItems(menuItems, handleSelectMenuItem) {
1471
1534
  function isEmbeddedApp() {
1472
1535
  return window.self !== window.top;
1473
1536
  }
1474
- function useNoyaAppState(initialState, options) {
1537
+ function useNoyaState(...args) {
1538
+ const [initialState, options] = typeof args[0] === "object" && args[0] !== null && "schema" in args[0] && TypeGuard.IsSchema(args[0].schema) ? [null, args[0]] : [args[0], args[1]];
1475
1539
  const [
1476
1540
  {
1477
1541
  multiplayerUrl,
@@ -1520,7 +1584,7 @@ export {
1520
1584
  useManagedHistory,
1521
1585
  useManagedState,
1522
1586
  useMultiplayerState,
1523
- useNoyaAppState,
1587
+ useNoyaState,
1524
1588
  useObservable,
1525
1589
  useSyncMultiplayerStateManager,
1526
1590
  useSyncStateManager