@noya-app/noya-multiplayer-react 0.1.71 → 0.1.73

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
@@ -4612,7 +4612,7 @@ import {
4612
4612
  Observable
4613
4613
  } from "@noya-app/observable";
4614
4614
  import { useJsonMemo, useStableCallback } from "@noya-app/react-utils";
4615
- import React17, {
4615
+ import React18, {
4616
4616
  createContext,
4617
4617
  useCallback as useCallback3,
4618
4618
  useContext,
@@ -4726,7 +4726,7 @@ var ErrorOverlay = React.memo(function ErrorOverlay2({
4726
4726
  });
4727
4727
 
4728
4728
  // src/inspector/useStateInspector.tsx
4729
- import React15 from "react";
4729
+ import React16 from "react";
4730
4730
  import { createRoot } from "react-dom/client";
4731
4731
  import { useIsomorphicLayoutEffect } from "@noya-app/react-utils";
4732
4732
 
@@ -4860,12 +4860,12 @@ function uuid() {
4860
4860
 
4861
4861
  // src/inspector/StateInspector.tsx
4862
4862
  import { downloadBlob, memoGeneric } from "@noya-app/react-utils";
4863
- import React14, {
4863
+ import React15, {
4864
4864
  useCallback,
4865
4865
  useEffect as useEffect2,
4866
4866
  useLayoutEffect
4867
4867
  } from "react";
4868
- import { ObjectInspector as ObjectInspector4 } from "react-inspector";
4868
+ import { ObjectInspector as ObjectInspector5 } from "react-inspector";
4869
4869
 
4870
4870
  // src/useObservable.ts
4871
4871
  import { useMemo, useSyncExternalStore } from "react";
@@ -5538,6 +5538,106 @@ function HistorySection({
5538
5538
  );
5539
5539
  }
5540
5540
 
5541
+ // src/inspector/sections/ServerScriptLogsSection.tsx
5542
+ import React11 from "react";
5543
+ import { ObjectInspector as ObjectInspector4 } from "react-inspector";
5544
+ var levelColors = {
5545
+ error: "#f87171",
5546
+ warn: "#facc15",
5547
+ log: "#9ca3af"
5548
+ };
5549
+ function formatTimestamp(timestamp) {
5550
+ return new Date(timestamp).toLocaleTimeString();
5551
+ }
5552
+ function ServerScriptLogsSection({
5553
+ showLogs,
5554
+ setShowLogs,
5555
+ colorScheme,
5556
+ logs,
5557
+ containerRef,
5558
+ paused,
5559
+ onTogglePaused
5560
+ }) {
5561
+ const theme = getStateInspectorTheme(colorScheme);
5562
+ return /* @__PURE__ */ React11.createElement(
5563
+ StateInspectorDisclosureSection,
5564
+ {
5565
+ open: showLogs,
5566
+ setOpen: setShowLogs,
5567
+ title: "Server Script Logs",
5568
+ colorScheme,
5569
+ right: /* @__PURE__ */ React11.createElement(StateInspectorButton, { theme, onClick: onTogglePaused }, paused ? "Resume" : "Pause")
5570
+ },
5571
+ /* @__PURE__ */ React11.createElement(StateInspectorDisclosureRowInner, { ref: containerRef }, paused && /* @__PURE__ */ React11.createElement(
5572
+ "div",
5573
+ {
5574
+ style: {
5575
+ padding: "4px 12px",
5576
+ fontSize: "11px",
5577
+ opacity: 0.7
5578
+ }
5579
+ },
5580
+ "Log streaming paused"
5581
+ ), logs.map((log) => /* @__PURE__ */ React11.createElement(StateInspectorRow, { key: log.id, colorScheme }, /* @__PURE__ */ React11.createElement(
5582
+ "div",
5583
+ {
5584
+ style: {
5585
+ display: "flex",
5586
+ gap: "6px",
5587
+ alignItems: "center",
5588
+ fontSize: "10px",
5589
+ color: "inherit",
5590
+ marginBottom: log.values.length ? "4px" : 0,
5591
+ textTransform: "uppercase"
5592
+ }
5593
+ },
5594
+ /* @__PURE__ */ React11.createElement("span", null, formatTimestamp(log.timestamp)),
5595
+ /* @__PURE__ */ React11.createElement("span", { style: { color: levelColors[log.level] } }, log.level),
5596
+ /* @__PURE__ */ React11.createElement(
5597
+ "span",
5598
+ {
5599
+ style: {
5600
+ fontFamily: "monospace",
5601
+ textTransform: "none",
5602
+ fontSize: "10px"
5603
+ }
5604
+ },
5605
+ log.scriptId
5606
+ )
5607
+ ), /* @__PURE__ */ React11.createElement(
5608
+ "div",
5609
+ {
5610
+ style: {
5611
+ display: "flex",
5612
+ flexDirection: "column",
5613
+ gap: "4px"
5614
+ }
5615
+ },
5616
+ log.values.length > 0 ? log.values.map((value, index) => /* @__PURE__ */ React11.createElement(
5617
+ ObjectInspector4,
5618
+ {
5619
+ key: index,
5620
+ data: value,
5621
+ theme,
5622
+ expandLevel: 3
5623
+ }
5624
+ )) : /* @__PURE__ */ React11.createElement("span", { style: { fontSize: "11px", opacity: 0.7 } }, "No data")
5625
+ ))), !logs?.length && /* @__PURE__ */ React11.createElement(
5626
+ "div",
5627
+ {
5628
+ style: {
5629
+ padding: "12px",
5630
+ fontSize: "12px",
5631
+ display: "flex",
5632
+ flexDirection: "column",
5633
+ gap: "4px"
5634
+ }
5635
+ },
5636
+ /* @__PURE__ */ React11.createElement("span", null, "No logs received")
5637
+ ))
5638
+ );
5639
+ }
5640
+
5541
5641
  // src/inspector/serialization.ts
5542
5642
  import { createHash } from "@noya-app/state-manager";
5543
5643
 
@@ -6086,15 +6186,15 @@ function replaceDeep(obj, replacementMap) {
6086
6186
  }
6087
6187
 
6088
6188
  // src/inspector/StateInspectorTitleLabel.tsx
6089
- import React11 from "react";
6189
+ import React12 from "react";
6090
6190
  function StateInspectorTitleLabel({
6091
6191
  children
6092
6192
  }) {
6093
- return /* @__PURE__ */ React11.createElement("span", { style: { display: "flex", alignItems: "center", gap: "4px" } }, children);
6193
+ return /* @__PURE__ */ React12.createElement("span", { style: { display: "flex", alignItems: "center", gap: "4px" } }, children);
6094
6194
  }
6095
6195
 
6096
6196
  // src/inspector/StateInspectorToggleButton.tsx
6097
- import React12 from "react";
6197
+ import React13 from "react";
6098
6198
  function StateInspectorToggleButton({
6099
6199
  showInspector,
6100
6200
  setShowInspector,
@@ -6102,7 +6202,7 @@ function StateInspectorToggleButton({
6102
6202
  anchor
6103
6203
  }) {
6104
6204
  const isRightAnchor = anchor === "right";
6105
- const rightIcon = /* @__PURE__ */ React12.createElement(
6205
+ const rightIcon = /* @__PURE__ */ React13.createElement(
6106
6206
  "svg",
6107
6207
  {
6108
6208
  xmlns: "http://www.w3.org/2000/svg",
@@ -6112,7 +6212,7 @@ function StateInspectorToggleButton({
6112
6212
  stroke: "currentColor",
6113
6213
  className: "size-6"
6114
6214
  },
6115
- /* @__PURE__ */ React12.createElement(
6215
+ /* @__PURE__ */ React13.createElement(
6116
6216
  "path",
6117
6217
  {
6118
6218
  strokeLinecap: "round",
@@ -6121,7 +6221,7 @@ function StateInspectorToggleButton({
6121
6221
  }
6122
6222
  )
6123
6223
  );
6124
- const leftIcon = /* @__PURE__ */ React12.createElement(
6224
+ const leftIcon = /* @__PURE__ */ React13.createElement(
6125
6225
  "svg",
6126
6226
  {
6127
6227
  xmlns: "http://www.w3.org/2000/svg",
@@ -6131,7 +6231,7 @@ function StateInspectorToggleButton({
6131
6231
  stroke: "currentColor",
6132
6232
  className: "size-6"
6133
6233
  },
6134
- /* @__PURE__ */ React12.createElement(
6234
+ /* @__PURE__ */ React13.createElement(
6135
6235
  "path",
6136
6236
  {
6137
6237
  strokeLinecap: "round",
@@ -6140,7 +6240,7 @@ function StateInspectorToggleButton({
6140
6240
  }
6141
6241
  )
6142
6242
  );
6143
- return /* @__PURE__ */ React12.createElement(
6243
+ return /* @__PURE__ */ React13.createElement(
6144
6244
  "span",
6145
6245
  {
6146
6246
  role: "button",
@@ -6161,15 +6261,15 @@ function StateInspectorToggleButton({
6161
6261
  setShowInspector(!showInspector);
6162
6262
  }
6163
6263
  },
6164
- showInspector ? "Hide Inspector" : /* @__PURE__ */ React12.createElement("span", { style: { width: "12px", height: "12px" } }, isRightAnchor ? rightIcon : leftIcon)
6264
+ showInspector ? "Hide Inspector" : /* @__PURE__ */ React13.createElement("span", { style: { width: "12px", height: "12px" } }, isRightAnchor ? rightIcon : leftIcon)
6165
6265
  );
6166
6266
  }
6167
6267
 
6168
6268
  // src/inspector/useLocalStorageState.tsx
6169
- import React13 from "react";
6269
+ import React14 from "react";
6170
6270
  var localStorage = typeof window !== "undefined" ? window.localStorage : null;
6171
6271
  function useLocalStorageState(key, defaultValue) {
6172
- const [state, setState] = React13.useState(() => {
6272
+ const [state, setState] = React14.useState(() => {
6173
6273
  const value = localStorage?.getItem(key);
6174
6274
  let result = defaultValue;
6175
6275
  if (value) {
@@ -6202,22 +6302,24 @@ var StateInspector = memoGeneric(function StateInspector2({
6202
6302
  assetManager,
6203
6303
  userManager,
6204
6304
  secretManager,
6205
- ephemeralUserDataManager,
6305
+ sharedConnectionDataManager,
6206
6306
  connectionEventManager,
6207
6307
  taskManager,
6208
6308
  ioManager,
6209
6309
  resourceManager,
6210
- activityEventsManager
6310
+ activityEventsManager,
6311
+ logManager
6211
6312
  } = noyaManager;
6212
- const [didMount, setDidMount] = React14.useState(false);
6313
+ const [didMount, setDidMount] = React15.useState(false);
6213
6314
  const tasks = useObservable(taskManager.tasks$);
6214
6315
  const inputs = useObservable(ioManager.inputs$);
6215
6316
  const outputTransforms = useObservable(ioManager.outputTransforms$);
6216
6317
  useLayoutEffect(() => {
6217
6318
  setDidMount(true);
6218
6319
  }, []);
6219
- const eventsContainerRef = React14.useRef(null);
6220
- const activityEventsContainerRef = React14.useRef(null);
6320
+ const eventsContainerRef = React15.useRef(null);
6321
+ const activityEventsContainerRef = React15.useRef(null);
6322
+ const serverLogsContainerRef = React15.useRef(null);
6221
6323
  const [showInspector, setShowInspector] = useLocalStorageState(
6222
6324
  "noya-multiplayer-react-show-inspector",
6223
6325
  true
@@ -6242,8 +6344,8 @@ var StateInspector = memoGeneric(function StateInspector2({
6242
6344
  "noya-multiplayer-react-show-tasks",
6243
6345
  false
6244
6346
  );
6245
- const [showEphemeral, setShowEphemeral] = useLocalStorageState(
6246
- "noya-multiplayer-react-show-ephemeral",
6347
+ const [showShared, setShowShared] = useLocalStorageState(
6348
+ "noya-multiplayer-react-show-shared",
6247
6349
  false
6248
6350
  );
6249
6351
  const [showAssets, setShowAssets] = useLocalStorageState(
@@ -6270,16 +6372,43 @@ var StateInspector = memoGeneric(function StateInspector2({
6270
6372
  "noya-multiplayer-react-show-activity-events",
6271
6373
  false
6272
6374
  );
6375
+ const [showServerLogs, setShowServerLogs] = useLocalStorageState(
6376
+ "noya-multiplayer-react-show-server-logs",
6377
+ false
6378
+ );
6273
6379
  const connectionEvents = useObservable(connectionEventManager.events$);
6274
6380
  useEffect2(() => {
6275
6381
  if (eventsContainerRef.current) {
6276
6382
  eventsContainerRef.current.scrollTop = eventsContainerRef.current.scrollHeight;
6277
6383
  }
6278
6384
  }, [connectionEvents]);
6385
+ const serverLogs = useObservable(logManager.logs$);
6386
+ const [serverLogsPaused, setServerLogsPaused] = React15.useState(false);
6387
+ const [visibleServerLogs, setVisibleServerLogs] = React15.useState(
6388
+ serverLogs ?? []
6389
+ );
6390
+ const toggleServerLogsPaused = useCallback(() => {
6391
+ setServerLogsPaused((value) => {
6392
+ if (!value) {
6393
+ setVisibleServerLogs(serverLogs ?? []);
6394
+ }
6395
+ return !value;
6396
+ });
6397
+ }, [serverLogs]);
6398
+ useEffect2(() => {
6399
+ if (serverLogsPaused) return;
6400
+ setVisibleServerLogs(serverLogs ?? []);
6401
+ }, [serverLogs, serverLogsPaused]);
6402
+ useEffect2(() => {
6403
+ if (!showServerLogs) return;
6404
+ if (serverLogsContainerRef.current) {
6405
+ serverLogsContainerRef.current.scrollTop = serverLogsContainerRef.current.scrollHeight;
6406
+ }
6407
+ }, [showServerLogs, visibleServerLogs]);
6279
6408
  const multipeerStateInitialized = useObservable(
6280
6409
  multiplayerStateManager.isInitialized$
6281
6410
  );
6282
- const ephemeral = useObservable(ephemeralUserDataManager.data$);
6411
+ const shared = useObservable(sharedConnectionDataManager.data$);
6283
6412
  const historySnapshot = useManagedHistory(multiplayerStateManager.sm);
6284
6413
  const assets = useObservable(assetManager.assets$);
6285
6414
  const resources = useObservable(resourceManager.resources$);
@@ -6288,7 +6417,7 @@ var StateInspector = memoGeneric(function StateInspector2({
6288
6417
  const secrets = useObservable(secretManager.secrets$);
6289
6418
  const secretsInitialized = useObservable(secretManager.isInitialized$);
6290
6419
  const connectedUsers = useObservable(userManager.connectedUsers$);
6291
- const userId = useObservable(userManager.currentUserId$);
6420
+ const connectionId = useObservable(userManager.currentConnectionId$);
6292
6421
  const state = useObservable(multiplayerStateManager.optimisticState$);
6293
6422
  const inputsInitialized = useObservable(ioManager.inputsInitialized$);
6294
6423
  const outputTransformsInitialized = useObservable(
@@ -6332,7 +6461,7 @@ var StateInspector = memoGeneric(function StateInspector2({
6332
6461
  }, [noyaManager]);
6333
6462
  if (!didMount) return null;
6334
6463
  if (!showInspector) {
6335
- return /* @__PURE__ */ React14.createElement(
6464
+ return /* @__PURE__ */ React15.createElement(
6336
6465
  "div",
6337
6466
  {
6338
6467
  ...props,
@@ -6344,7 +6473,7 @@ var StateInspector = memoGeneric(function StateInspector2({
6344
6473
  },
6345
6474
  onClick: () => setShowInspector(true)
6346
6475
  },
6347
- /* @__PURE__ */ React14.createElement(
6476
+ /* @__PURE__ */ React15.createElement(
6348
6477
  StateInspectorToggleButton,
6349
6478
  {
6350
6479
  showInspector,
@@ -6355,7 +6484,7 @@ var StateInspector = memoGeneric(function StateInspector2({
6355
6484
  )
6356
6485
  );
6357
6486
  }
6358
- return /* @__PURE__ */ React14.createElement(
6487
+ return /* @__PURE__ */ React15.createElement(
6359
6488
  "div",
6360
6489
  {
6361
6490
  ...props,
@@ -6364,7 +6493,7 @@ var StateInspector = memoGeneric(function StateInspector2({
6364
6493
  ...props.style
6365
6494
  }
6366
6495
  },
6367
- /* @__PURE__ */ React14.createElement(
6496
+ /* @__PURE__ */ React15.createElement(
6368
6497
  StateInspectorDisclosureSection,
6369
6498
  {
6370
6499
  isFirst: true,
@@ -6376,7 +6505,7 @@ var StateInspector = memoGeneric(function StateInspector2({
6376
6505
  flex: "0 0 auto",
6377
6506
  maxHeight: "200px"
6378
6507
  },
6379
- right: /* @__PURE__ */ React14.createElement(
6508
+ right: /* @__PURE__ */ React15.createElement(
6380
6509
  StateInspectorToggleButton,
6381
6510
  {
6382
6511
  showInspector,
@@ -6386,36 +6515,39 @@ var StateInspector = memoGeneric(function StateInspector2({
6386
6515
  }
6387
6516
  )
6388
6517
  },
6389
- /* @__PURE__ */ React14.createElement(StateInspectorDisclosureRowInner, { style: { flex: "0 0 auto" } }, connectedUsers?.map((user, index, array) => /* @__PURE__ */ React14.createElement(
6390
- StateInspectorRow,
6391
- {
6392
- key: user.id,
6393
- colorScheme,
6394
- variant: user.id === userId ? "up" : void 0,
6395
- bordered: index !== array.length - 1
6396
- },
6397
- user.image && /* @__PURE__ */ React14.createElement(
6398
- "img",
6518
+ /* @__PURE__ */ React15.createElement(StateInspectorDisclosureRowInner, { style: { flex: "0 0 auto" } }, connectedUsers?.map((user, index, array) => {
6519
+ const identifier = user.userId ?? user.connectionId;
6520
+ return /* @__PURE__ */ React15.createElement(
6521
+ StateInspectorRow,
6399
6522
  {
6400
- src: user.image,
6401
- alt: user.name,
6402
- style: {
6403
- width: "13px",
6404
- height: "13px",
6405
- borderRadius: "50%",
6406
- marginRight: "4px",
6407
- display: "inline-block",
6408
- position: "relative",
6409
- background: solidBorderColor,
6410
- verticalAlign: "middle"
6523
+ key: user.connectionId,
6524
+ colorScheme,
6525
+ variant: user.connectionId === connectionId ? "up" : void 0,
6526
+ bordered: index !== array.length - 1
6527
+ },
6528
+ user.image && /* @__PURE__ */ React15.createElement(
6529
+ "img",
6530
+ {
6531
+ src: user.image,
6532
+ alt: user.name,
6533
+ style: {
6534
+ width: "13px",
6535
+ height: "13px",
6536
+ borderRadius: "50%",
6537
+ marginRight: "4px",
6538
+ display: "inline-block",
6539
+ position: "relative",
6540
+ background: solidBorderColor,
6541
+ verticalAlign: "middle"
6542
+ }
6411
6543
  }
6412
- }
6413
- ),
6414
- user.name,
6415
- " (",
6416
- ellipsis(user.id.toString(), 8, "middle"),
6417
- ")"
6418
- )), !connectedUsers && /* @__PURE__ */ React14.createElement(
6544
+ ),
6545
+ user.name,
6546
+ " (",
6547
+ ellipsis(identifier, 8, "middle"),
6548
+ ")"
6549
+ );
6550
+ }), !connectedUsers && /* @__PURE__ */ React15.createElement(
6419
6551
  "div",
6420
6552
  {
6421
6553
  style: {
@@ -6426,13 +6558,13 @@ var StateInspector = memoGeneric(function StateInspector2({
6426
6558
  gap: "4px"
6427
6559
  }
6428
6560
  },
6429
- /* @__PURE__ */ React14.createElement("span", null, "No connected users")
6561
+ /* @__PURE__ */ React15.createElement("span", null, "No connected users")
6430
6562
  ))
6431
6563
  ),
6432
- /* @__PURE__ */ React14.createElement(
6564
+ /* @__PURE__ */ React15.createElement(
6433
6565
  StateInspectorDisclosureSection,
6434
6566
  {
6435
- title: /* @__PURE__ */ React14.createElement(StateInspectorTitleLabel, null, "Data", /* @__PURE__ */ React14.createElement(
6567
+ title: /* @__PURE__ */ React15.createElement(StateInspectorTitleLabel, null, "Data", /* @__PURE__ */ React15.createElement(
6436
6568
  ColoredDot,
6437
6569
  {
6438
6570
  type: multipeerStateInitialized ? "success" : "error"
@@ -6441,7 +6573,7 @@ var StateInspector = memoGeneric(function StateInspector2({
6441
6573
  colorScheme,
6442
6574
  setOpen: setShowData,
6443
6575
  open: showData,
6444
- right: /* @__PURE__ */ React14.createElement(
6576
+ right: /* @__PURE__ */ React15.createElement(
6445
6577
  "span",
6446
6578
  {
6447
6579
  style: {
@@ -6449,9 +6581,9 @@ var StateInspector = memoGeneric(function StateInspector2({
6449
6581
  gap: "12px"
6450
6582
  }
6451
6583
  },
6452
- /* @__PURE__ */ React14.createElement(StateInspectorButton, { theme, onClick: handleImportAll }, "Import"),
6453
- /* @__PURE__ */ React14.createElement(StateInspectorButton, { theme, onClick: handleExportAll }, "Export"),
6454
- /* @__PURE__ */ React14.createElement(
6584
+ /* @__PURE__ */ React15.createElement(StateInspectorButton, { theme, onClick: handleImportAll }, "Import"),
6585
+ /* @__PURE__ */ React15.createElement(StateInspectorButton, { theme, onClick: handleExportAll }, "Export"),
6586
+ /* @__PURE__ */ React15.createElement(
6455
6587
  StateInspectorButton,
6456
6588
  {
6457
6589
  theme,
@@ -6463,15 +6595,15 @@ var StateInspector = memoGeneric(function StateInspector2({
6463
6595
  )
6464
6596
  )
6465
6597
  },
6466
- /* @__PURE__ */ React14.createElement(StateInspectorDisclosureRowInner, null, /* @__PURE__ */ React14.createElement(StateInspectorRow, { colorScheme }, /* @__PURE__ */ React14.createElement(
6467
- ObjectInspector4,
6598
+ /* @__PURE__ */ React15.createElement(StateInspectorDisclosureRowInner, null, /* @__PURE__ */ React15.createElement(StateInspectorRow, { colorScheme }, /* @__PURE__ */ React15.createElement(
6599
+ ObjectInspector5,
6468
6600
  {
6469
6601
  name: multiplayerStateManager.schema ? "state" : void 0,
6470
6602
  data: state,
6471
6603
  theme
6472
6604
  }
6473
- )), multiplayerStateManager.schema && /* @__PURE__ */ React14.createElement(StateInspectorRow, { colorScheme }, /* @__PURE__ */ React14.createElement(
6474
- ObjectInspector4,
6605
+ )), multiplayerStateManager.schema && /* @__PURE__ */ React15.createElement(StateInspectorRow, { colorScheme }, /* @__PURE__ */ React15.createElement(
6606
+ ObjectInspector5,
6475
6607
  {
6476
6608
  name: "schema",
6477
6609
  data: multiplayerStateManager.schema,
@@ -6479,7 +6611,7 @@ var StateInspector = memoGeneric(function StateInspector2({
6479
6611
  }
6480
6612
  )))
6481
6613
  ),
6482
- /* @__PURE__ */ React14.createElement(
6614
+ /* @__PURE__ */ React15.createElement(
6483
6615
  HistorySection,
6484
6616
  {
6485
6617
  showHistory,
@@ -6489,14 +6621,14 @@ var StateInspector = memoGeneric(function StateInspector2({
6489
6621
  multiplayerStateManager
6490
6622
  }
6491
6623
  ),
6492
- /* @__PURE__ */ React14.createElement(
6624
+ /* @__PURE__ */ React15.createElement(
6493
6625
  StateInspectorDisclosureSection,
6494
6626
  {
6495
6627
  open: showAssets,
6496
6628
  setOpen: setShowAssets,
6497
- title: /* @__PURE__ */ React14.createElement(StateInspectorTitleLabel, null, "Assets (", assets.length, ")", /* @__PURE__ */ React14.createElement(ColoredDot, { type: assetsInitialized ? "success" : "error" })),
6629
+ title: /* @__PURE__ */ React15.createElement(StateInspectorTitleLabel, null, "Assets (", assets.length, ")", /* @__PURE__ */ React15.createElement(ColoredDot, { type: assetsInitialized ? "success" : "error" })),
6498
6630
  colorScheme,
6499
- right: /* @__PURE__ */ React14.createElement("span", { style: { display: "flex", gap: "10px" } }, /* @__PURE__ */ React14.createElement(
6631
+ right: /* @__PURE__ */ React15.createElement("span", { style: { display: "flex", gap: "10px" } }, /* @__PURE__ */ React15.createElement(
6500
6632
  StateInspectorButton,
6501
6633
  {
6502
6634
  theme,
@@ -6511,7 +6643,7 @@ var StateInspector = memoGeneric(function StateInspector2({
6511
6643
  }
6512
6644
  },
6513
6645
  "Delete all"
6514
- ), /* @__PURE__ */ React14.createElement(
6646
+ ), /* @__PURE__ */ React15.createElement(
6515
6647
  StateInspectorButton,
6516
6648
  {
6517
6649
  theme,
@@ -6524,7 +6656,7 @@ var StateInspector = memoGeneric(function StateInspector2({
6524
6656
  }
6525
6657
  },
6526
6658
  "Reload"
6527
- ), /* @__PURE__ */ React14.createElement(
6659
+ ), /* @__PURE__ */ React15.createElement(
6528
6660
  StateInspectorButton,
6529
6661
  {
6530
6662
  theme,
@@ -6548,14 +6680,14 @@ var StateInspector = memoGeneric(function StateInspector2({
6548
6680
  "Upload"
6549
6681
  ))
6550
6682
  },
6551
- /* @__PURE__ */ React14.createElement(StateInspectorDisclosureRowInner, null, assets.map((asset) => /* @__PURE__ */ React14.createElement(StateInspectorRow, { key: asset.id, colorScheme }, /* @__PURE__ */ React14.createElement(
6552
- ObjectInspector4,
6683
+ /* @__PURE__ */ React15.createElement(StateInspectorDisclosureRowInner, null, assets.map((asset) => /* @__PURE__ */ React15.createElement(StateInspectorRow, { key: asset.id, colorScheme }, /* @__PURE__ */ React15.createElement(
6684
+ ObjectInspector5,
6553
6685
  {
6554
6686
  name: asset.id,
6555
6687
  data: truncateAsset(asset),
6556
6688
  theme
6557
6689
  }
6558
- ), /* @__PURE__ */ React14.createElement(
6690
+ ), /* @__PURE__ */ React15.createElement(
6559
6691
  StateInspectorButton,
6560
6692
  {
6561
6693
  theme,
@@ -6564,14 +6696,14 @@ var StateInspector = memoGeneric(function StateInspector2({
6564
6696
  "Delete"
6565
6697
  ))))
6566
6698
  ),
6567
- advanced && /* @__PURE__ */ React14.createElement(
6699
+ advanced && /* @__PURE__ */ React15.createElement(
6568
6700
  StateInspectorDisclosureSection,
6569
6701
  {
6570
- title: /* @__PURE__ */ React14.createElement(StateInspectorTitleLabel, null, "Resources (", resources.length, ")", /* @__PURE__ */ React14.createElement(ColoredDot, { type: resourcesInitialized ? "success" : "error" })),
6702
+ title: /* @__PURE__ */ React15.createElement(StateInspectorTitleLabel, null, "Resources (", resources.length, ")", /* @__PURE__ */ React15.createElement(ColoredDot, { type: resourcesInitialized ? "success" : "error" })),
6571
6703
  colorScheme,
6572
6704
  open: showResources,
6573
6705
  setOpen: setShowResources,
6574
- right: /* @__PURE__ */ React14.createElement("span", { style: { display: "flex", gap: "10px" } }, /* @__PURE__ */ React14.createElement(
6706
+ right: /* @__PURE__ */ React15.createElement("span", { style: { display: "flex", gap: "10px" } }, /* @__PURE__ */ React15.createElement(
6575
6707
  StateInspectorButton,
6576
6708
  {
6577
6709
  theme,
@@ -6586,7 +6718,7 @@ var StateInspector = memoGeneric(function StateInspector2({
6586
6718
  }
6587
6719
  },
6588
6720
  "Delete all"
6589
- ), /* @__PURE__ */ React14.createElement(
6721
+ ), /* @__PURE__ */ React15.createElement(
6590
6722
  StateInspectorButton,
6591
6723
  {
6592
6724
  theme,
@@ -6599,7 +6731,7 @@ var StateInspector = memoGeneric(function StateInspector2({
6599
6731
  }
6600
6732
  },
6601
6733
  "Create Directory"
6602
- ), /* @__PURE__ */ React14.createElement(
6734
+ ), /* @__PURE__ */ React15.createElement(
6603
6735
  StateInspectorButton,
6604
6736
  {
6605
6737
  theme,
@@ -6619,21 +6751,21 @@ var StateInspector = memoGeneric(function StateInspector2({
6619
6751
  "Create Asset"
6620
6752
  ))
6621
6753
  },
6622
- /* @__PURE__ */ React14.createElement(StateInspectorDisclosureRowInner, null, resources?.map((resource) => /* @__PURE__ */ React14.createElement(StateInspectorRow, { key: resource.id, colorScheme }, /* @__PURE__ */ React14.createElement(
6623
- ObjectInspector4,
6754
+ /* @__PURE__ */ React15.createElement(StateInspectorDisclosureRowInner, null, resources?.map((resource) => /* @__PURE__ */ React15.createElement(StateInspectorRow, { key: resource.id, colorScheme }, /* @__PURE__ */ React15.createElement(
6755
+ ObjectInspector5,
6624
6756
  {
6625
6757
  name: resource.path,
6626
6758
  data: resource,
6627
6759
  theme
6628
6760
  }
6629
- ), /* @__PURE__ */ React14.createElement("div", { style: { display: "flex", gap: "4px" } }, /* @__PURE__ */ React14.createElement(
6761
+ ), /* @__PURE__ */ React15.createElement("div", { style: { display: "flex", gap: "4px" } }, /* @__PURE__ */ React15.createElement(
6630
6762
  StateInspectorButton,
6631
6763
  {
6632
6764
  theme,
6633
6765
  onClick: () => resourceManager.deleteResource({ id: resource.id })
6634
6766
  },
6635
6767
  "Delete"
6636
- ), /* @__PURE__ */ React14.createElement(
6768
+ ), /* @__PURE__ */ React15.createElement(
6637
6769
  StateInspectorButton,
6638
6770
  {
6639
6771
  theme,
@@ -6646,14 +6778,14 @@ var StateInspector = memoGeneric(function StateInspector2({
6646
6778
  "Rename"
6647
6779
  )))))
6648
6780
  ),
6649
- advanced && /* @__PURE__ */ React14.createElement(
6781
+ advanced && /* @__PURE__ */ React15.createElement(
6650
6782
  StateInspectorDisclosureSection,
6651
6783
  {
6652
- title: /* @__PURE__ */ React14.createElement(StateInspectorTitleLabel, null, "Secrets", /* @__PURE__ */ React14.createElement(ColoredDot, { type: secretsInitialized ? "success" : "error" })),
6784
+ title: /* @__PURE__ */ React15.createElement(StateInspectorTitleLabel, null, "Secrets", /* @__PURE__ */ React15.createElement(ColoredDot, { type: secretsInitialized ? "success" : "error" })),
6653
6785
  colorScheme,
6654
6786
  open: showSecrets,
6655
6787
  setOpen: setShowSecrets,
6656
- right: /* @__PURE__ */ React14.createElement(
6788
+ right: /* @__PURE__ */ React15.createElement(
6657
6789
  StateInspectorButton,
6658
6790
  {
6659
6791
  theme,
@@ -6668,7 +6800,7 @@ var StateInspector = memoGeneric(function StateInspector2({
6668
6800
  "Create"
6669
6801
  )
6670
6802
  },
6671
- /* @__PURE__ */ React14.createElement(StateInspectorDisclosureRowInner, null, secrets.map((secret) => /* @__PURE__ */ React14.createElement(StateInspectorRow, { key: secret.id, colorScheme }, /* @__PURE__ */ React14.createElement(ObjectInspector4, { data: secret, theme }), /* @__PURE__ */ React14.createElement(
6803
+ /* @__PURE__ */ React15.createElement(StateInspectorDisclosureRowInner, null, secrets.map((secret) => /* @__PURE__ */ React15.createElement(StateInspectorRow, { key: secret.id, colorScheme }, /* @__PURE__ */ React15.createElement(ObjectInspector5, { data: secret, theme }), /* @__PURE__ */ React15.createElement(
6672
6804
  StateInspectorButton,
6673
6805
  {
6674
6806
  theme,
@@ -6677,15 +6809,15 @@ var StateInspector = memoGeneric(function StateInspector2({
6677
6809
  "Delete"
6678
6810
  ))))
6679
6811
  ),
6680
- advanced && /* @__PURE__ */ React14.createElement(
6812
+ advanced && /* @__PURE__ */ React15.createElement(
6681
6813
  StateInspectorDisclosureSection,
6682
6814
  {
6683
6815
  open: showInputs,
6684
6816
  setOpen: setShowInputs,
6685
- title: /* @__PURE__ */ React14.createElement(StateInspectorTitleLabel, null, "Inputs", /* @__PURE__ */ React14.createElement(ColoredDot, { type: inputsInitialized ? "success" : "error" })),
6817
+ title: /* @__PURE__ */ React15.createElement(StateInspectorTitleLabel, null, "Inputs", /* @__PURE__ */ React15.createElement(ColoredDot, { type: inputsInitialized ? "success" : "error" })),
6686
6818
  colorScheme
6687
6819
  },
6688
- /* @__PURE__ */ React14.createElement(StateInspectorDisclosureRowInner, null, inputs?.map((input) => /* @__PURE__ */ React14.createElement(StateInspectorRow, { key: input.id, colorScheme }, /* @__PURE__ */ React14.createElement(ObjectInspector4, { data: input, theme }))), !inputs?.length && /* @__PURE__ */ React14.createElement(
6820
+ /* @__PURE__ */ React15.createElement(StateInspectorDisclosureRowInner, null, inputs?.map((input) => /* @__PURE__ */ React15.createElement(StateInspectorRow, { key: input.id, colorScheme }, /* @__PURE__ */ React15.createElement(ObjectInspector5, { data: input, theme }))), !inputs?.length && /* @__PURE__ */ React15.createElement(
6689
6821
  "div",
6690
6822
  {
6691
6823
  style: {
@@ -6696,15 +6828,15 @@ var StateInspector = memoGeneric(function StateInspector2({
6696
6828
  gap: "4px"
6697
6829
  }
6698
6830
  },
6699
- /* @__PURE__ */ React14.createElement("span", null, "No inputs")
6831
+ /* @__PURE__ */ React15.createElement("span", null, "No inputs")
6700
6832
  ))
6701
6833
  ),
6702
- advanced && /* @__PURE__ */ React14.createElement(
6834
+ advanced && /* @__PURE__ */ React15.createElement(
6703
6835
  StateInspectorDisclosureSection,
6704
6836
  {
6705
6837
  open: showOutputTransforms,
6706
6838
  setOpen: setShowOutputTransforms,
6707
- title: /* @__PURE__ */ React14.createElement(StateInspectorTitleLabel, null, "Output Transforms", /* @__PURE__ */ React14.createElement(
6839
+ title: /* @__PURE__ */ React15.createElement(StateInspectorTitleLabel, null, "Output Transforms", /* @__PURE__ */ React15.createElement(
6708
6840
  ColoredDot,
6709
6841
  {
6710
6842
  type: outputTransformsInitialized ? "success" : "error"
@@ -6712,7 +6844,7 @@ var StateInspector = memoGeneric(function StateInspector2({
6712
6844
  )),
6713
6845
  colorScheme
6714
6846
  },
6715
- /* @__PURE__ */ React14.createElement(StateInspectorDisclosureRowInner, null, outputTransforms?.map((transform) => /* @__PURE__ */ React14.createElement(StateInspectorRow, { key: transform.id, colorScheme }, /* @__PURE__ */ React14.createElement(ObjectInspector4, { data: transform, theme }))), !outputTransforms?.length && /* @__PURE__ */ React14.createElement(
6847
+ /* @__PURE__ */ React15.createElement(StateInspectorDisclosureRowInner, null, outputTransforms?.map((transform) => /* @__PURE__ */ React15.createElement(StateInspectorRow, { key: transform.id, colorScheme }, /* @__PURE__ */ React15.createElement(ObjectInspector5, { data: transform, theme }))), !outputTransforms?.length && /* @__PURE__ */ React15.createElement(
6716
6848
  "div",
6717
6849
  {
6718
6850
  style: {
@@ -6723,10 +6855,10 @@ var StateInspector = memoGeneric(function StateInspector2({
6723
6855
  gap: "4px"
6724
6856
  }
6725
6857
  },
6726
- /* @__PURE__ */ React14.createElement("span", null, "No output transforms")
6858
+ /* @__PURE__ */ React15.createElement("span", null, "No output transforms")
6727
6859
  ))
6728
6860
  ),
6729
- advanced && /* @__PURE__ */ React14.createElement(
6861
+ advanced && /* @__PURE__ */ React15.createElement(
6730
6862
  StateInspectorDisclosureSection,
6731
6863
  {
6732
6864
  title: "Tasks",
@@ -6734,7 +6866,7 @@ var StateInspector = memoGeneric(function StateInspector2({
6734
6866
  open: showTasks,
6735
6867
  setOpen: setShowTasks
6736
6868
  },
6737
- /* @__PURE__ */ React14.createElement(StateInspectorDisclosureRowInner, null, tasks?.map((task) => /* @__PURE__ */ React14.createElement(
6869
+ /* @__PURE__ */ React15.createElement(StateInspectorDisclosureRowInner, null, tasks?.map((task) => /* @__PURE__ */ React15.createElement(
6738
6870
  StateInspectorRow,
6739
6871
  {
6740
6872
  key: task.id,
@@ -6743,8 +6875,8 @@ var StateInspector = memoGeneric(function StateInspector2({
6743
6875
  backgroundColor: task.status === "done" ? "rgba(0,255,0,0.2)" : task.status === "error" ? "rgba(255,0,0,0.2)" : void 0
6744
6876
  }
6745
6877
  },
6746
- /* @__PURE__ */ React14.createElement(
6747
- ObjectInspector4,
6878
+ /* @__PURE__ */ React15.createElement(
6879
+ ObjectInspector5,
6748
6880
  {
6749
6881
  name: task.name,
6750
6882
  data: task.payload,
@@ -6753,16 +6885,16 @@ var StateInspector = memoGeneric(function StateInspector2({
6753
6885
  )
6754
6886
  )))
6755
6887
  ),
6756
- /* @__PURE__ */ React14.createElement(
6888
+ /* @__PURE__ */ React15.createElement(
6757
6889
  StateInspectorDisclosureSection,
6758
6890
  {
6759
- open: showEphemeral,
6760
- setOpen: setShowEphemeral,
6761
- title: "Ephemeral User Data",
6891
+ open: showShared,
6892
+ setOpen: setShowShared,
6893
+ title: "Shared Connection Data",
6762
6894
  colorScheme
6763
6895
  },
6764
- /* @__PURE__ */ React14.createElement(StateInspectorDisclosureRowInner, null, Object.entries(ephemeral).map(([key, value]) => /* @__PURE__ */ React14.createElement(StateInspectorRow, { key, colorScheme }, /* @__PURE__ */ React14.createElement(
6765
- ObjectInspector4,
6896
+ /* @__PURE__ */ React15.createElement(StateInspectorDisclosureRowInner, null, Object.entries(shared).map(([key, value]) => /* @__PURE__ */ React15.createElement(StateInspectorRow, { key, colorScheme }, /* @__PURE__ */ React15.createElement(
6897
+ ObjectInspector5,
6766
6898
  {
6767
6899
  name: key,
6768
6900
  data: value,
@@ -6771,7 +6903,19 @@ var StateInspector = memoGeneric(function StateInspector2({
6771
6903
  }
6772
6904
  ))))
6773
6905
  ),
6774
- advanced && /* @__PURE__ */ React14.createElement(
6906
+ /* @__PURE__ */ React15.createElement(
6907
+ ServerScriptLogsSection,
6908
+ {
6909
+ colorScheme,
6910
+ showLogs: showServerLogs,
6911
+ setShowLogs: setShowServerLogs,
6912
+ logs: visibleServerLogs,
6913
+ paused: serverLogsPaused,
6914
+ onTogglePaused: toggleServerLogsPaused,
6915
+ containerRef: serverLogsContainerRef
6916
+ }
6917
+ ),
6918
+ advanced && /* @__PURE__ */ React15.createElement(
6775
6919
  ActivityEventsSection,
6776
6920
  {
6777
6921
  colorScheme,
@@ -6781,7 +6925,7 @@ var StateInspector = memoGeneric(function StateInspector2({
6781
6925
  activityEventsManager
6782
6926
  }
6783
6927
  ),
6784
- /* @__PURE__ */ React14.createElement(
6928
+ /* @__PURE__ */ React15.createElement(
6785
6929
  EventsSection,
6786
6930
  {
6787
6931
  connectionEvents,
@@ -6827,7 +6971,7 @@ function useStateInspector({
6827
6971
  colorScheme,
6828
6972
  anchor
6829
6973
  }) {
6830
- const [root, setRoot] = React15.useState(null);
6974
+ const [root, setRoot] = React16.useState(null);
6831
6975
  useIsomorphicLayoutEffect(() => {
6832
6976
  if (disabled) return;
6833
6977
  const { root: root2, unmount } = createStateInspectorRoot();
@@ -6837,7 +6981,7 @@ function useStateInspector({
6837
6981
  useIsomorphicLayoutEffect(() => {
6838
6982
  if (!root) return;
6839
6983
  root.render(
6840
- /* @__PURE__ */ React15.createElement(
6984
+ /* @__PURE__ */ React16.createElement(
6841
6985
  StateInspector,
6842
6986
  {
6843
6987
  colorScheme,
@@ -6916,7 +7060,7 @@ function useBindNoyaManager(noyaManager, options) {
6916
7060
  taskManager: noyaManager.taskManager,
6917
7061
  connectionEventManager: noyaManager.connectionEventManager,
6918
7062
  userManager: noyaManager.userManager,
6919
- ephemeralUserDataManager: noyaManager.ephemeralUserDataManager,
7063
+ sharedConnectionDataManager: noyaManager.sharedConnectionDataManager,
6920
7064
  multiplayerStateManager: noyaManager.multiplayerStateManager,
6921
7065
  assetManager: noyaManager.assetManager,
6922
7066
  aiManager: noyaManager.aiManager,
@@ -6953,7 +7097,10 @@ function useMultiplayerState(initialState, options) {
6953
7097
  const [noyaManager] = useState2(
6954
7098
  () => new NoyaManager2(initialState, rest)
6955
7099
  );
6956
- return useBindNoyaManager(noyaManager, { sync, inspector });
7100
+ return useBindNoyaManager(noyaManager, {
7101
+ sync,
7102
+ inspector
7103
+ });
6957
7104
  }
6958
7105
  function useErrorOverlay(noyaManager) {
6959
7106
  const unrecoverableError = useObservable(noyaManager.unrecoverableError);
@@ -6978,7 +7125,8 @@ function createDefaultAppData(initialState) {
6978
7125
  viewType: "editable",
6979
7126
  initialState,
6980
7127
  inspector: false,
6981
- isDemo: false
7128
+ isDemo: false,
7129
+ access: void 0
6982
7130
  };
6983
7131
  }
6984
7132
  function enforceSchema(initialState, schema) {
@@ -7010,11 +7158,22 @@ function getAppData(initialState, schema, options) {
7010
7158
  }
7011
7159
  appData.initialState = enforceSchema(appData.initialState, schema);
7012
7160
  appData.isDemo = appData.isDemo ?? false;
7161
+ const fallbackAccess = appData.viewType === "editable" ? "write" : "read";
7162
+ appData.access = appData.access ?? fallbackAccess;
7013
7163
  return appData;
7014
7164
  }
7015
7165
  function getSyncAdapter(params) {
7016
- const { multiplayerUrl, offlineStorageKey, debug } = params ?? {};
7017
- return isEmbeddedApp() ? parentFrameSync({ debug }) : multiplayerUrl ? webSocketSync({ url: multiplayerUrl, debug }) : offlineStorageKey ? localStorageSync({ key: offlineStorageKey }) : stubSync2();
7166
+ const {
7167
+ multiplayerUrl,
7168
+ offlineStorageKey,
7169
+ debug,
7170
+ policyAuthContext,
7171
+ serverScripts
7172
+ } = params ?? {};
7173
+ return isEmbeddedApp() ? parentFrameSync({ debug, policyAuthContext }) : multiplayerUrl ? webSocketSync({ url: multiplayerUrl, debug }) : offlineStorageKey ? localStorageSync({
7174
+ key: offlineStorageKey,
7175
+ ...serverScripts ? { serverScripts } : {}
7176
+ }) : stubSync2();
7018
7177
  }
7019
7178
  function useNoyaStateInternal(...args) {
7020
7179
  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]];
@@ -7026,28 +7185,53 @@ function useNoyaStateInternal(...args) {
7026
7185
  theme,
7027
7186
  viewType,
7028
7187
  userId,
7029
- isDemo
7188
+ isDemo,
7189
+ access
7030
7190
  }
7031
7191
  ] = useState3(() => {
7032
7192
  return getAppData(initialState, options?.schema, {
7033
7193
  overrideExistingState: options?.overrideExistingState
7034
7194
  });
7035
7195
  });
7196
+ const basePolicyAuthContext = useMemo3(() => {
7197
+ if (!access && userId === void 0) return void 0;
7198
+ const context = {};
7199
+ if (access) {
7200
+ context.access = access;
7201
+ }
7202
+ if (userId !== void 0) {
7203
+ context.id = userId ?? null;
7204
+ }
7205
+ return context;
7206
+ }, [access, userId]);
7036
7207
  const sync = useMemo3(() => {
7037
7208
  return getSyncAdapter({
7038
7209
  multiplayerUrl,
7039
7210
  offlineStorageKey: options?.offlineStorageKey,
7040
- debug: options?.debug
7211
+ debug: options?.debug,
7212
+ policyAuthContext: basePolicyAuthContext
7041
7213
  });
7042
- }, [multiplayerUrl, options?.offlineStorageKey, options?.debug]);
7214
+ }, [
7215
+ multiplayerUrl,
7216
+ options?.offlineStorageKey,
7217
+ options?.debug,
7218
+ basePolicyAuthContext
7219
+ ]);
7043
7220
  const [noyaManager] = useState3(
7044
7221
  () => new NoyaManager3(noyaAppInitialState, options)
7045
7222
  );
7046
7223
  useEffect4(() => {
7047
7224
  if (!userId) return;
7048
- noyaManager.ephemeralUserDataManager.setCurrentUserId(userId);
7225
+ noyaManager.sharedConnectionDataManager.setCurrentConnectionId(userId);
7226
+ noyaManager.userManager.setCurrentConnectionId(userId);
7049
7227
  noyaManager.userManager.setCurrentUserId(userId);
7050
7228
  }, [noyaManager, userId]);
7229
+ useEffect4(() => {
7230
+ if (!basePolicyAuthContext) return;
7231
+ noyaManager.multiplayerStateManager.setPolicyAuthContext(
7232
+ basePolicyAuthContext
7233
+ );
7234
+ }, [noyaManager, basePolicyAuthContext]);
7051
7235
  const result = useBindNoyaManager(noyaManager, {
7052
7236
  inspector: options?.inspector ?? inspector,
7053
7237
  sync: options?.sync ?? sync
@@ -7063,7 +7247,7 @@ function useNoyaStateInternal(...args) {
7063
7247
  import {
7064
7248
  NoyaManager as NoyaManager4
7065
7249
  } from "@noya-app/state-manager";
7066
- import React16 from "react";
7250
+ import React17 from "react";
7067
7251
  var noyaManagerSingleton;
7068
7252
  var noyaSingletonBindings;
7069
7253
  function initializeNoyaSingleton(options) {
@@ -7080,6 +7264,7 @@ function initializeNoyaSingleton(options) {
7080
7264
  viewType,
7081
7265
  offlineStorageKey,
7082
7266
  multiplayerUrl,
7267
+ serverScripts,
7083
7268
  ...managerOptions
7084
7269
  } = options ?? {};
7085
7270
  const appData = getAppData(
@@ -7087,20 +7272,27 @@ function initializeNoyaSingleton(options) {
7087
7272
  managerOptions?.schema,
7088
7273
  { overrideExistingState: managerOptions?.overrideExistingState }
7089
7274
  );
7275
+ const policyAuthContext = appData.access || appData.userId !== void 0 ? {
7276
+ ...appData.access ? { access: appData.access } : {},
7277
+ ...appData.userId !== void 0 ? { id: appData.userId ?? null } : {}
7278
+ } : void 0;
7090
7279
  noyaManagerSingleton = new NoyaManager4(
7091
7280
  appData.initialState,
7092
7281
  managerOptions
7093
7282
  );
7094
7283
  if (appData.userId) {
7095
- noyaManagerSingleton.ephemeralUserDataManager.setCurrentUserId(
7284
+ noyaManagerSingleton.sharedConnectionDataManager.setCurrentConnectionId(
7096
7285
  appData.userId
7097
7286
  );
7287
+ noyaManagerSingleton.userManager.setCurrentConnectionId(appData.userId);
7098
7288
  noyaManagerSingleton.userManager.setCurrentUserId(appData.userId);
7099
7289
  }
7100
7290
  const resolvedSync = sync ?? getSyncAdapter({
7101
7291
  multiplayerUrl: multiplayerUrl ?? appData.multiplayerUrl,
7102
7292
  offlineStorageKey,
7103
- debug: managerOptions?.debug
7293
+ debug: managerOptions?.debug,
7294
+ serverScripts,
7295
+ policyAuthContext
7104
7296
  });
7105
7297
  try {
7106
7298
  resolvedSync({ noyaManager: noyaManagerSingleton });
@@ -7113,7 +7305,7 @@ function initializeNoyaSingleton(options) {
7113
7305
  if (resolvedInspector) {
7114
7306
  const { root } = createStateInspectorRoot();
7115
7307
  root.render(
7116
- /* @__PURE__ */ React16.createElement(
7308
+ /* @__PURE__ */ React17.createElement(
7117
7309
  StateInspector,
7118
7310
  {
7119
7311
  noyaManager: noyaManagerSingleton,
@@ -7181,40 +7373,38 @@ function resourceToCreateParameters(resource) {
7181
7373
  throw new Error(`Unknown resource type: ${resource.type}`);
7182
7374
  }
7183
7375
  }
7184
- function buildCreateResourcePayload({
7376
+ function buildResourcePatchPayload({
7185
7377
  addedResources,
7186
7378
  modifiedResources,
7187
- newResourceMap,
7188
- resourceMap
7379
+ removedResources
7189
7380
  }) {
7190
- const toCreateParameters = resourceToCreateParameters;
7191
- const resourcesById = new Map(
7192
- Object.values(resourceMap).map((resource) => [resource.id, resource])
7381
+ const createEntries = addedResources.map(resourceToCreateParameters);
7382
+ const dedupedCreateEntries = Array.from(
7383
+ new Map(createEntries.map((entry) => [entry.path, entry])).values()
7193
7384
  );
7194
- const payload = [
7195
- ...addedResources.map(toCreateParameters)
7196
- ];
7197
- const handledModifiedResourceIds = [];
7198
- const assetReplacements = modifiedResources.filter(
7199
- (resource) => resource.assetId !== void 0 || resource.asset !== void 0
7200
- ).map((resource) => {
7201
- const previousResource = resourcesById.get(resource.id);
7202
- const path2 = resource.path ?? previousResource?.path;
7203
- if (!path2) return void 0;
7204
- const updated = newResourceMap[path2];
7205
- if (!updated || updated.type !== "asset") return void 0;
7206
- handledModifiedResourceIds.push(resource.id);
7207
- return toCreateParameters(updated);
7208
- }).filter(
7209
- (resource) => resource !== void 0
7210
- );
7211
- const deduped = new Map(
7212
- [...payload, ...assetReplacements].map((item) => [item.path, item])
7385
+ const updateEntries = modifiedResources.map((resource) => {
7386
+ const update = {
7387
+ id: resource.id,
7388
+ ...resource.path !== void 0 ? { path: resource.path } : {},
7389
+ ...resource.assetId !== void 0 ? { assetId: resource.assetId } : {},
7390
+ ...resource.asset ? { asset: resource.asset } : {}
7391
+ };
7392
+ return update;
7393
+ }) ?? [];
7394
+ const deleteEntries = removedResources.map(
7395
+ (resource) => ({ id: resource.id })
7213
7396
  );
7214
- return {
7215
- payload: Array.from(deduped.values()),
7216
- consumedModifiedResourceIds: [...new Set(handledModifiedResourceIds)]
7217
- };
7397
+ const patch = {};
7398
+ if (dedupedCreateEntries.length) {
7399
+ patch.create = dedupedCreateEntries;
7400
+ }
7401
+ if (updateEntries.length) {
7402
+ patch.update = updateEntries;
7403
+ }
7404
+ if (deleteEntries.length) {
7405
+ patch.delete = deleteEntries;
7406
+ }
7407
+ return patch;
7218
7408
  }
7219
7409
  var AnyNoyaStateContext = createContext(void 0);
7220
7410
  function useAnyNoyaStateContext() {
@@ -7349,7 +7539,7 @@ function useConnectedUser(userId) {
7349
7539
  useCallback3(
7350
7540
  (users) => {
7351
7541
  return users.find((user) => {
7352
- const prefix = user.id.slice(0, 8);
7542
+ const prefix = user.connectionId.slice(0, 8);
7353
7543
  return userId?.includes(prefix);
7354
7544
  });
7355
7545
  },
@@ -7357,14 +7547,34 @@ function useConnectedUser(userId) {
7357
7547
  )
7358
7548
  );
7359
7549
  }
7360
- function useAnyEphemeralUserData() {
7550
+ function useAnySharedConnectionData() {
7551
+ const { noyaManager } = useAnyNoyaStateContext();
7552
+ return noyaManager.sharedConnectionDataManager;
7553
+ }
7554
+ function useEnqueueInput() {
7361
7555
  const { noyaManager } = useAnyNoyaStateContext();
7362
- return noyaManager.ephemeralUserDataManager;
7556
+ return noyaManager.enqueueInput;
7557
+ }
7558
+ function useNoyaUser() {
7559
+ const userManager = useUserManager();
7560
+ return useObservable(userManager?.currentUser$);
7561
+ }
7562
+ function useNoyaId() {
7563
+ const userManager = useUserManager();
7564
+ return useObservable(userManager?.currentId$);
7363
7565
  }
7364
- function useCurrentUserId() {
7566
+ function useNoyaUserId() {
7365
7567
  const userManager = useUserManager();
7366
7568
  return useObservable(userManager?.currentUserId$);
7367
7569
  }
7570
+ function useNoyaConnectionId() {
7571
+ const userManager = useUserManager();
7572
+ return useObservable(userManager?.currentConnectionId$);
7573
+ }
7574
+ function useNoyaClientId() {
7575
+ const userManager = useUserManager();
7576
+ return useObservable(userManager?.currentClientId$);
7577
+ }
7368
7578
  function useIsProcessing() {
7369
7579
  const { noyaManager } = useAnyNoyaStateContext();
7370
7580
  return useObservable(noyaManager.isProcessing$);
@@ -7386,6 +7596,21 @@ function useResourceManager() {
7386
7596
  const { noyaManager } = useAnyNoyaStateContext();
7387
7597
  return noyaManager.resourceManager;
7388
7598
  }
7599
+ function useNoyaTranscriptionManager() {
7600
+ const { noyaManager } = useAnyNoyaStateContext();
7601
+ return noyaManager.transcriptionManager;
7602
+ }
7603
+ function useNoyaAssetTranscription(assetId, options) {
7604
+ const transcriptionManager = useNoyaTranscriptionManager();
7605
+ const observable = useMemo4(() => {
7606
+ if (!assetId) return void 0;
7607
+ return transcriptionManager.getAssetTranscription$(assetId, {
7608
+ endpoint: options?.endpoint,
7609
+ apiKey: options?.apiKey
7610
+ });
7611
+ }, [transcriptionManager, assetId, options?.endpoint, options?.apiKey]);
7612
+ return useObservable(observable);
7613
+ }
7389
7614
  function resourceToMediaItem(resource) {
7390
7615
  switch (resource.type) {
7391
7616
  case "asset":
@@ -7413,24 +7638,15 @@ function useResources({
7413
7638
  async (action) => {
7414
7639
  const newResourceMap = action instanceof Function ? action(resourceMap) : action;
7415
7640
  const { addedResources, removedResources, modifiedResources } = diffResourceMaps(resourceMap, newResourceMap, "id");
7416
- const { payload: createPayload, consumedModifiedResourceIds } = buildCreateResourcePayload({
7641
+ const patchPayload = buildResourcePatchPayload({
7417
7642
  addedResources,
7418
7643
  modifiedResources,
7419
- newResourceMap,
7420
- resourceMap
7644
+ removedResources
7421
7645
  });
7422
- if (createPayload.length > 0) {
7423
- await resourceManager.createResource(createPayload);
7646
+ const hasPatchOperations = (patchPayload.create?.length ?? 0) > 0 || (patchPayload.update?.length ?? 0) > 0 || (patchPayload.delete?.length ?? 0) > 0;
7647
+ if (hasPatchOperations) {
7648
+ await resourceManager.patchResources(patchPayload);
7424
7649
  }
7425
- const consumedModifiedResourceIdsSet = new Set(
7426
- consumedModifiedResourceIds
7427
- );
7428
- const remainingModifiedResources = modifiedResources.filter(
7429
- (resource) => !consumedModifiedResourceIdsSet.has(resource.id)
7430
- );
7431
- await resourceManager.deleteResource(
7432
- removedResources.map((resource) => ({ id: resource.id }))
7433
- );
7434
7650
  if (shouldDeleteAssets) {
7435
7651
  for (const resource of removedResources) {
7436
7652
  if (resource.type === "asset") {
@@ -7438,16 +7654,6 @@ function useResources({
7438
7654
  }
7439
7655
  }
7440
7656
  }
7441
- await Promise.all(
7442
- remainingModifiedResources.map(
7443
- ({ id, path: path2, assetId, asset }) => resourceManager.updateResource({
7444
- id,
7445
- path: path2,
7446
- assetId,
7447
- ...assetId ? {} : asset ? { asset } : {}
7448
- })
7449
- )
7450
- );
7451
7657
  },
7452
7658
  [resourceMap, resourceManager, shouldDeleteAssets, assetManager]
7453
7659
  );
@@ -7495,7 +7701,7 @@ function createNoyaContext({
7495
7701
  children,
7496
7702
  contextValue
7497
7703
  }) {
7498
- return /* @__PURE__ */ React17.createElement(AnyNoyaStateContext.Provider, { value: contextValue }, children);
7704
+ return /* @__PURE__ */ React18.createElement(AnyNoyaStateContext.Provider, { value: contextValue }, children);
7499
7705
  }
7500
7706
  function NoyaStateProvider({
7501
7707
  children,
@@ -7518,7 +7724,7 @@ function createNoyaContext({
7518
7724
  }),
7519
7725
  [noyaManager, theme, viewType]
7520
7726
  );
7521
- return /* @__PURE__ */ React17.createElement(NoyaContextProvider, { contextValue }, options.fallback !== void 0 ? /* @__PURE__ */ React17.createElement(FallbackUntilInitialized, { fallback: options.fallback }, children) : children);
7727
+ return /* @__PURE__ */ React18.createElement(NoyaContextProvider, { contextValue }, options.fallback !== void 0 ? /* @__PURE__ */ React18.createElement(FallbackUntilInitialized, { fallback: options.fallback }, children) : children);
7522
7728
  }
7523
7729
  function useValue(path2, options) {
7524
7730
  const { noyaManager } = useAnyNoyaStateContext();
@@ -7559,9 +7765,9 @@ function createNoyaContext({
7559
7765
  const { noyaManager } = useAnyNoyaStateContext();
7560
7766
  return noyaManager.multiplayerStateManager;
7561
7767
  }
7562
- function useEphemeralUserDataManager() {
7768
+ function useSharedConnectionDataManager() {
7563
7769
  const { noyaManager } = useAnyNoyaStateContext();
7564
- return noyaManager.ephemeralUserDataManager;
7770
+ return noyaManager.sharedConnectionDataManager;
7565
7771
  }
7566
7772
  function useNoyaManager() {
7567
7773
  return useAnyNoyaStateContext().noyaManager;
@@ -7616,7 +7822,7 @@ function createNoyaContext({
7616
7822
  useSetValue,
7617
7823
  useValueState,
7618
7824
  useStateManager,
7619
- useEphemeralUserDataManager,
7825
+ useSharedConnectionDataManager,
7620
7826
  useLeftMenuItems,
7621
7827
  useSetLeftMenuItems,
7622
7828
  useRightMenuItems,
@@ -7643,23 +7849,23 @@ function useCallableAITools() {
7643
7849
  // src/components/UserPointersOverlay.tsx
7644
7850
  import { Observable as Observable2 } from "@noya-app/observable";
7645
7851
  import { memoGeneric as memoGeneric2 } from "@noya-app/react-utils";
7646
- import React18, { useEffect as useEffect7, useMemo as useMemo5, useState as useState5 } from "react";
7852
+ import React19, { useEffect as useEffect7, useMemo as useMemo5, useState as useState5 } from "react";
7647
7853
  function shouldShow(hideAfter, updatedAt) {
7648
7854
  return !!updatedAt && Date.now() - updatedAt < hideAfter;
7649
7855
  }
7650
7856
  var UserPointerInternal = memoGeneric2(function UserPointerInternal2({
7651
7857
  user,
7652
- ephemeralUserDataManager,
7858
+ sharedConnectionDataManager,
7653
7859
  hideAfter = 5e3,
7654
7860
  renderUserPointer
7655
7861
  }) {
7656
7862
  const observable = useMemo5(() => {
7657
- const metadata$ = ephemeralUserDataManager.metadata$.observePath([user.id]).throttle(50);
7658
- const data$ = ephemeralUserDataManager.data$.observePath([user.id]).throttle(50);
7863
+ const metadata$ = sharedConnectionDataManager.metadata$.observePath([user.connectionId]).throttle(50);
7864
+ const data$ = sharedConnectionDataManager.data$.observePath([user.connectionId]).throttle(50);
7659
7865
  return Observable2.combine([metadata$, data$], ([metadata2, data2]) => {
7660
7866
  return { metadata: metadata2, data: data2 };
7661
7867
  });
7662
- }, [ephemeralUserDataManager, user.id]);
7868
+ }, [sharedConnectionDataManager, user.connectionId]);
7663
7869
  const { metadata, data } = useObservable(observable);
7664
7870
  const [, setForceUpdate] = useState5(0);
7665
7871
  const updatedAt = metadata?.updatedAt ?? 0;
@@ -7673,7 +7879,7 @@ var UserPointerInternal = memoGeneric2(function UserPointerInternal2({
7673
7879
  }, [hideAfter, show, updatedAt]);
7674
7880
  if (!data?.pointer) return null;
7675
7881
  return renderUserPointer({
7676
- userId: user.id,
7882
+ userId: user.connectionId,
7677
7883
  name: user.name,
7678
7884
  point: data.pointer,
7679
7885
  visible: show
@@ -7681,19 +7887,21 @@ var UserPointerInternal = memoGeneric2(function UserPointerInternal2({
7681
7887
  });
7682
7888
  var UserPointersOverlay = memoGeneric2(function UserPointers({
7683
7889
  userManager,
7684
- ephemeralUserDataManager,
7890
+ sharedConnectionDataManager,
7685
7891
  renderUserPointer
7686
7892
  }) {
7687
- const currentUserId = useObservable(ephemeralUserDataManager.currentUserId$);
7893
+ const currentConnectionId = useObservable(
7894
+ sharedConnectionDataManager.currentConnectionId$
7895
+ );
7688
7896
  const connectedUsers = useObservable(userManager.connectedUsers$);
7689
- return /* @__PURE__ */ React18.createElement(React18.Fragment, null, connectedUsers.map((user) => {
7690
- if (user.id === currentUserId) return null;
7691
- return /* @__PURE__ */ React18.createElement(
7897
+ return /* @__PURE__ */ React19.createElement(React19.Fragment, null, connectedUsers.map((user) => {
7898
+ if (user.connectionId === currentConnectionId) return null;
7899
+ return /* @__PURE__ */ React19.createElement(
7692
7900
  UserPointerInternal,
7693
7901
  {
7694
- key: user.id,
7902
+ key: user.connectionId,
7695
7903
  user,
7696
- ephemeralUserDataManager,
7904
+ sharedConnectionDataManager,
7697
7905
  renderUserPointer
7698
7906
  }
7699
7907
  );
@@ -7786,7 +7994,7 @@ export {
7786
7994
  StateInspector,
7787
7995
  UserPointersOverlay,
7788
7996
  WebSocketConnection,
7789
- buildCreateResourcePayload,
7997
+ buildResourcePatchPayload,
7790
7998
  createDefaultAppData,
7791
7999
  createNoyaContext,
7792
8000
  createStateInspectorRoot,
@@ -7809,9 +8017,9 @@ export {
7809
8017
  useAIManager,
7810
8018
  useActivityEvents,
7811
8019
  useActivityEventsForManager,
7812
- useAnyEphemeralUserData,
7813
8020
  useAnyNoyaManager,
7814
8021
  useAnyNoyaStateContext,
8022
+ useAnySharedConnectionData,
7815
8023
  useAsset,
7816
8024
  useAssetManager,
7817
8025
  useAssets,
@@ -7820,7 +8028,7 @@ export {
7820
8028
  useColorScheme,
7821
8029
  useConnectedUser,
7822
8030
  useConnectedUsers,
7823
- useCurrentUserId,
8031
+ useEnqueueInput,
7824
8032
  useFileName,
7825
8033
  useFilePropertyManager,
7826
8034
  useIOManager,
@@ -7830,7 +8038,14 @@ export {
7830
8038
  useManagedHistory,
7831
8039
  useManagedState,
7832
8040
  useMultiplayerState,
8041
+ useNoyaAssetTranscription,
8042
+ useNoyaClientId,
8043
+ useNoyaConnectionId,
8044
+ useNoyaId,
7833
8045
  useNoyaStateInternal,
8046
+ useNoyaTranscriptionManager,
8047
+ useNoyaUser,
8048
+ useNoyaUserId,
7834
8049
  useObservable,
7835
8050
  useOutputTransforms,
7836
8051
  usePipelineManager,