@noya-app/noya-api-client-react 0.1.45 → 0.1.47

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
@@ -2289,8 +2289,6 @@ function useNoyaClientOrFallback() {
2289
2289
 
2290
2290
  // src/react/hooks.ts
2291
2291
  import { useSelector } from "@legendapp/state/react";
2292
- import { GENERATED_PAGE_NAME_COUNT } from "@noya-app/noya-api";
2293
- import { range } from "@noya-app/noya-utils";
2294
2292
  import { useObservable } from "@noya-app/observable-react";
2295
2293
  import { useCallback, useEffect, useMemo as useMemo2, useRef } from "react";
2296
2294
  function useNoyaTools(initial) {
@@ -2422,87 +2420,11 @@ function useMetadata(key) {
2422
2420
  const metadataItem = metadata.find((item) => item.key === key);
2423
2421
  return metadataItem?.value;
2424
2422
  }
2425
- function useGeneratedComponentNames(name) {
2426
- const key = name.trim().toLowerCase();
2427
- const { generatedNames$, loadingNames$ } = useNoyaClientOrFallback();
2428
- const result = useSelector(
2429
- () => generatedNames$[key].get()
2430
- );
2431
- const loading = useSelector(() => loadingNames$[key].get());
2432
- return useMemo2(() => ({ names: result ?? [], loading }), [loading, result]);
2433
- }
2434
- function useGeneratedComponentDescriptions() {
2435
- const { generatedDescriptions$, loadingDescriptions$ } = useNoyaClientOrFallback();
2436
- const descriptions = useSelector(generatedDescriptions$);
2437
- const loading = useSelector(loadingDescriptions$);
2438
- return useMemo2(() => ({ descriptions, loading }), [loading, descriptions]);
2439
- }
2440
- function useGeneratedComponentDescription(name) {
2441
- const key = name.trim().toLowerCase();
2442
- const { generatedDescriptions$, loadingDescriptions$ } = useNoyaClientOrFallback();
2443
- const description = useSelector(
2444
- () => generatedDescriptions$[key].get()
2445
- );
2446
- const loading = useSelector(() => loadingDescriptions$[key].get());
2447
- return useMemo2(() => ({ description, loading }), [loading, description]);
2448
- }
2449
- function useRandomImages() {
2450
- const { randomImages$, loadingRandomImages$ } = useNoyaClientOrFallback();
2451
- const images = useSelector(randomImages$);
2452
- const loading = useSelector(loadingRandomImages$);
2453
- return useMemo2(() => ({ images, loading }), [loading, images]);
2454
- }
2455
- function useRandomIcons() {
2456
- const { randomIcons$, loadingRandomIcons$ } = useNoyaClientOrFallback();
2457
- const icons = useSelector(randomIcons$);
2458
- const loading = useSelector(loadingRandomIcons$);
2459
- return useMemo2(() => ({ icons, loading }), [loading, icons]);
2460
- }
2461
2423
  function useNetworkRequests() {
2462
2424
  const { requests$ } = useNoyaClientOrFallback();
2463
2425
  const requests = useSelector(requests$);
2464
2426
  return requests;
2465
2427
  }
2466
- function useGeneratedPageNames() {
2467
- const { generatedPageNames$ } = useNoyaClientOrFallback();
2468
- const names = useSelector(generatedPageNames$);
2469
- const namesWithDefaultsAndTypes = useMemo2(() => {
2470
- const rangeArray = range(0, GENERATED_PAGE_NAME_COUNT);
2471
- const withDefaults = rangeArray.map((index) => {
2472
- const name = names[index];
2473
- return name ?? { name: `Page ${index + 1}`, loading: true, key: "" };
2474
- });
2475
- return withDefaults.map(
2476
- (name, index) => ({
2477
- ...name,
2478
- index,
2479
- type: "suggestion"
2480
- })
2481
- );
2482
- }, [names]);
2483
- return namesWithDefaultsAndTypes.slice(0, 3);
2484
- }
2485
- function useGeneratedPageComponentNames() {
2486
- const { generatedPageComponentNames$: generatedComponentNames$ } = useNoyaClientOrFallback();
2487
- const names = useSelector(
2488
- generatedComponentNames$
2489
- );
2490
- const namesWithDefaultsAndTypes = useMemo2(() => {
2491
- const rangeArray = range(0, GENERATED_PAGE_NAME_COUNT);
2492
- const withDefaults = rangeArray.map((index) => {
2493
- const name = names[index];
2494
- return name ?? { name: `Component ${index + 1}`, loading: true, key: "" };
2495
- });
2496
- return withDefaults.map(
2497
- (name, index) => ({
2498
- ...name,
2499
- index,
2500
- type: "suggestion"
2501
- })
2502
- );
2503
- }, [names]);
2504
- return namesWithDefaultsAndTypes.slice(0, 3);
2505
- }
2506
2428
  function useNoyaSites() {
2507
2429
  const sites = useSelector(useNoyaClientOrFallback().sites$);
2508
2430
  return sites;
@@ -2535,6 +2457,24 @@ function useNoyaWorkspaces() {
2535
2457
  }, [client, fetchWorkspaces]);
2536
2458
  return workspaces;
2537
2459
  }
2460
+ function useNoyaWorkspaceMembers(workspaceId) {
2461
+ const { workspaces, loading } = useNoyaWorkspaces();
2462
+ return useMemo2(() => {
2463
+ const workspace = workspaces.find((w) => w.id === workspaceId);
2464
+ const members = workspace?.members.map((m) => ({
2465
+ userId: m.userId,
2466
+ name: m.user.name,
2467
+ email: m.user.email,
2468
+ image: m.user.image,
2469
+ role: m.role
2470
+ })) ?? [];
2471
+ const membersById = /* @__PURE__ */ new Map();
2472
+ for (const member of members) {
2473
+ membersById.set(member.userId, member);
2474
+ }
2475
+ return { members, membersById, loading };
2476
+ }, [workspaces, workspaceId, loading]);
2477
+ }
2538
2478
  function useNoyaMultiplayerRoomToken(fileId) {
2539
2479
  const client = useNoyaClientOrFallback();
2540
2480
  const multiplayerRoomToken = useObservable(
@@ -3373,15 +3313,15 @@ function Or(pattern) {
3373
3313
  if (IsCloseParen(pattern, index))
3374
3314
  count -= 1;
3375
3315
  if (IsSeparator(pattern, index) && count === 0) {
3376
- const range3 = pattern.slice(start, index);
3377
- if (range3.length > 0)
3378
- expressions.push(TemplateLiteralParse(range3));
3316
+ const range2 = pattern.slice(start, index);
3317
+ if (range2.length > 0)
3318
+ expressions.push(TemplateLiteralParse(range2));
3379
3319
  start = index + 1;
3380
3320
  }
3381
3321
  }
3382
- const range2 = pattern.slice(start);
3383
- if (range2.length > 0)
3384
- expressions.push(TemplateLiteralParse(range2));
3322
+ const range = pattern.slice(start);
3323
+ if (range.length > 0)
3324
+ expressions.push(TemplateLiteralParse(range));
3385
3325
  if (expressions.length === 0)
3386
3326
  return { type: "const", const: "" };
3387
3327
  if (expressions.length === 1)
@@ -3414,14 +3354,14 @@ function And(pattern) {
3414
3354
  for (let index = 0; index < pattern.length; index++) {
3415
3355
  if (IsOpenParen(pattern, index)) {
3416
3356
  const [start, end] = Group(pattern, index);
3417
- const range2 = pattern.slice(start, end + 1);
3418
- expressions.push(TemplateLiteralParse(range2));
3357
+ const range = pattern.slice(start, end + 1);
3358
+ expressions.push(TemplateLiteralParse(range));
3419
3359
  index = end;
3420
3360
  } else {
3421
3361
  const [start, end] = Range(pattern, index);
3422
- const range2 = pattern.slice(start, end);
3423
- if (range2.length > 0)
3424
- expressions.push(TemplateLiteralParse(range2));
3362
+ const range = pattern.slice(start, end);
3363
+ if (range.length > 0)
3364
+ expressions.push(TemplateLiteralParse(range));
3425
3365
  index = end - 1;
3426
3366
  }
3427
3367
  }
@@ -5255,20 +5195,8 @@ import { isDeepEqual } from "@noya-app/noya-utils";
5255
5195
  import { Observable as Observable2 } from "@noya-app/observable";
5256
5196
 
5257
5197
  // ../state-manager/src/AssetManager.ts
5258
- import { Base64, memoize, uuid } from "@noya-app/noya-utils";
5198
+ import { Base64, uuid } from "@noya-app/noya-utils";
5259
5199
  import { Observable as Observable3 } from "@noya-app/observable";
5260
- var _toNoyaAsset = memoize(
5261
- (asset) => ({
5262
- id: asset.stableId,
5263
- url: asset.url,
5264
- createdAt: asset.createdAt,
5265
- size: asset.size,
5266
- contentType: asset.contentType,
5267
- width: asset.width ?? null,
5268
- height: asset.height ?? null,
5269
- userId: asset.userId ?? null
5270
- })
5271
- );
5272
5200
 
5273
5201
  // ../noya-schemas/src/nullable.ts
5274
5202
  var Nullable = (schema) => Type.Union([Type.Null(), schema]);
@@ -5331,6 +5259,10 @@ var activityEventSchema = Type.Object({
5331
5259
  });
5332
5260
 
5333
5261
  // ../noya-schemas/src/asset.ts
5262
+ var assetModeSchema = Type.Union([
5263
+ Type.Literal("immutable"),
5264
+ Type.Literal("mutable")
5265
+ ]);
5334
5266
  var assetSchema = Type.Object({
5335
5267
  id: Type.String(),
5336
5268
  stableId: Type.String(),
@@ -5340,7 +5272,9 @@ var assetSchema = Type.Object({
5340
5272
  contentType: Type.Optional(Type.String()),
5341
5273
  width: Type.Union([Type.Null(), Type.Number()]),
5342
5274
  height: Type.Union([Type.Null(), Type.Number()]),
5343
- userId: Type.Union([Type.Null(), Type.String()])
5275
+ userId: Type.Union([Type.Null(), Type.String()]),
5276
+ mode: Type.Optional(assetModeSchema),
5277
+ version: Type.Optional(Type.Number())
5344
5278
  });
5345
5279
 
5346
5280
  // ../noya-schemas/src/encode.ts
@@ -7261,6 +7195,13 @@ import { uuid as uuid2 } from "@noya-app/noya-utils";
7261
7195
  import { uuid as uuid3 } from "@noya-app/noya-utils";
7262
7196
  import { Observable as Observable5 } from "@noya-app/observable";
7263
7197
 
7198
+ // ../state-manager/src/multiplayer.ts
7199
+ import { Cache, hash, isDeepEqual as isDeepEqual3, uuid as uuid5 } from "@noya-app/noya-utils";
7200
+ import { Observable as Observable8, get as get2, set as set2 } from "@noya-app/observable";
7201
+
7202
+ // ../state-manager/src/LogManager.ts
7203
+ import { Observable as Observable6 } from "@noya-app/observable";
7204
+
7264
7205
  // ../state-manager/src/historyEntries.ts
7265
7206
  var HistoryEntries;
7266
7207
  ((HistoryEntries2) => {
@@ -7347,119 +7288,6 @@ var HistoryEntries;
7347
7288
  HistoryEntries2.pathsEqual = pathsEqual;
7348
7289
  })(HistoryEntries || (HistoryEntries = {}));
7349
7290
 
7350
- // ../state-manager/src/IOManager.ts
7351
- import { Observable as Observable6 } from "@noya-app/observable";
7352
-
7353
- // ../state-manager/src/jwt.ts
7354
- function base64UrlEncode(str) {
7355
- return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
7356
- }
7357
- function base64UrlDecode(str) {
7358
- str = str.replace(/-/g, "+").replace(/_/g, "/");
7359
- switch (str.length % 4) {
7360
- case 2:
7361
- str += "==";
7362
- break;
7363
- case 3:
7364
- str += "=";
7365
- break;
7366
- }
7367
- return atob(str);
7368
- }
7369
- var HEADER = {
7370
- alg: "HS256",
7371
- typ: "JWT"
7372
- };
7373
- var JWT_ERROR = {
7374
- INVALID_JWT_FORMAT: "Invalid JWT format"
7375
- // INVALID_SIGNATURE: "Invalid signature",
7376
- };
7377
- async function createJwt({
7378
- payload,
7379
- secret,
7380
- header
7381
- }) {
7382
- const encoder = new TextEncoder();
7383
- const encodedHeader = base64UrlEncode(
7384
- JSON.stringify({ ...HEADER, ...header })
7385
- );
7386
- const encodedPayload = base64UrlEncode(JSON.stringify(payload));
7387
- const dataToSign = `${encodedHeader}.${encodedPayload}`;
7388
- const key = await crypto.subtle.importKey(
7389
- "raw",
7390
- encoder.encode(secret),
7391
- { name: "HMAC", hash: "SHA-256" },
7392
- false,
7393
- ["sign"]
7394
- );
7395
- const signature = await crypto.subtle.sign(
7396
- "HMAC",
7397
- key,
7398
- encoder.encode(dataToSign)
7399
- );
7400
- const encodedSignature = base64UrlEncode(
7401
- String.fromCharCode(...new Uint8Array(signature))
7402
- );
7403
- return `${dataToSign}.${encodedSignature}`;
7404
- }
7405
- async function decodeJwt({
7406
- token,
7407
- secret
7408
- }) {
7409
- if (typeof token !== "string") {
7410
- throw new Error(JWT_ERROR.INVALID_JWT_FORMAT);
7411
- }
7412
- const [encodedHeader, encodedPayload, encodedSignature] = token.split(".");
7413
- if (!encodedHeader || !encodedPayload || !encodedSignature) {
7414
- throw new Error(JWT_ERROR.INVALID_JWT_FORMAT);
7415
- }
7416
- const headerJson = base64UrlDecode(encodedHeader);
7417
- const payloadJson = base64UrlDecode(encodedPayload);
7418
- const header = JSON.parse(headerJson);
7419
- const payload = JSON.parse(payloadJson);
7420
- const dataToVerify = `${encodedHeader}.${encodedPayload}`;
7421
- const encoder = new TextEncoder();
7422
- if (secret !== void 0) {
7423
- const key = await crypto.subtle.importKey(
7424
- "raw",
7425
- encoder.encode(secret),
7426
- { name: "HMAC", hash: "SHA-256" },
7427
- false,
7428
- ["verify"]
7429
- );
7430
- const binarySignature = base64UrlDecode(encodedSignature);
7431
- const signature = new Uint8Array(
7432
- [...binarySignature].map((char) => char.charCodeAt(0))
7433
- );
7434
- const valid = await crypto.subtle.verify(
7435
- "HMAC",
7436
- key,
7437
- signature,
7438
- encoder.encode(dataToVerify)
7439
- );
7440
- return { header, payload, valid };
7441
- }
7442
- return { header, payload, valid: false };
7443
- }
7444
- var jwt;
7445
- ((jwt2) => {
7446
- jwt2.encode = createJwt;
7447
- jwt2.decode = decodeJwt;
7448
- jwt2.ERROR = JWT_ERROR;
7449
- jwt2.DEFAULT_HEADER = HEADER;
7450
- })(jwt || (jwt = {}));
7451
-
7452
- // ../state-manager/src/LogManager.ts
7453
- import { Observable as Observable7 } from "@noya-app/observable";
7454
-
7455
- // ../state-manager/src/MenuManager.ts
7456
- import { isDeepEqual as isDeepEqual2 } from "@noya-app/noya-utils";
7457
- import { Observable as Observable8 } from "@noya-app/observable";
7458
-
7459
- // ../state-manager/src/multiplayer.ts
7460
- import { Cache, hash, isDeepEqual as isDeepEqual4, uuid as uuid5 } from "@noya-app/noya-utils";
7461
- import { Observable as Observable10, get as get2, set as set2 } from "@noya-app/observable";
7462
-
7463
7291
  // ../../node_modules/@marcbachmann/cel-js/lib/errors.js
7464
7292
  var ParseError = class extends Error {
7465
7293
  #wasConstructedWithAst = false;
@@ -10475,20 +10303,129 @@ celEnvironment.registerFunction("random(): double", () => Math.random()).registe
10475
10303
  var READ_DENIED = Symbol("readDenied");
10476
10304
 
10477
10305
  // ../state-manager/src/serverScripts.ts
10478
- import { uuid as createUuid, isDeepEqual as isDeepEqual3 } from "@noya-app/noya-utils";
10306
+ import { uuid as createUuid, isDeepEqual as isDeepEqual2 } from "@noya-app/noya-utils";
10479
10307
 
10480
10308
  // ../state-manager/src/stateManager.ts
10481
10309
  import {
10482
- Observable as Observable9,
10310
+ Observable as Observable7,
10483
10311
  get as getPath2
10484
10312
  } from "@noya-app/observable";
10485
10313
 
10486
10314
  // ../state-manager/src/multiplayer.ts
10487
10315
  var createHash = (value, options) => hash(value, { ...options, ignoreUndefinedProperties: true });
10488
10316
 
10317
+ // ../state-manager/src/GitManager.ts
10318
+ import { Observable as Observable9 } from "@noya-app/observable";
10319
+
10320
+ // ../state-manager/src/IOManager.ts
10321
+ import { Observable as Observable10 } from "@noya-app/observable";
10322
+
10323
+ // ../state-manager/src/jwt.ts
10324
+ function base64UrlEncode(str) {
10325
+ return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
10326
+ }
10327
+ function base64UrlDecode(str) {
10328
+ str = str.replace(/-/g, "+").replace(/_/g, "/");
10329
+ switch (str.length % 4) {
10330
+ case 2:
10331
+ str += "==";
10332
+ break;
10333
+ case 3:
10334
+ str += "=";
10335
+ break;
10336
+ }
10337
+ return atob(str);
10338
+ }
10339
+ var HEADER = {
10340
+ alg: "HS256",
10341
+ typ: "JWT"
10342
+ };
10343
+ var JWT_ERROR = {
10344
+ INVALID_JWT_FORMAT: "Invalid JWT format"
10345
+ // INVALID_SIGNATURE: "Invalid signature",
10346
+ };
10347
+ async function createJwt({
10348
+ payload,
10349
+ secret,
10350
+ header
10351
+ }) {
10352
+ const encoder = new TextEncoder();
10353
+ const encodedHeader = base64UrlEncode(
10354
+ JSON.stringify({ ...HEADER, ...header })
10355
+ );
10356
+ const encodedPayload = base64UrlEncode(JSON.stringify(payload));
10357
+ const dataToSign = `${encodedHeader}.${encodedPayload}`;
10358
+ const key = await crypto.subtle.importKey(
10359
+ "raw",
10360
+ encoder.encode(secret),
10361
+ { name: "HMAC", hash: "SHA-256" },
10362
+ false,
10363
+ ["sign"]
10364
+ );
10365
+ const signature = await crypto.subtle.sign(
10366
+ "HMAC",
10367
+ key,
10368
+ encoder.encode(dataToSign)
10369
+ );
10370
+ const encodedSignature = base64UrlEncode(
10371
+ String.fromCharCode(...new Uint8Array(signature))
10372
+ );
10373
+ return `${dataToSign}.${encodedSignature}`;
10374
+ }
10375
+ async function decodeJwt({
10376
+ token,
10377
+ secret
10378
+ }) {
10379
+ if (typeof token !== "string") {
10380
+ throw new Error(JWT_ERROR.INVALID_JWT_FORMAT);
10381
+ }
10382
+ const [encodedHeader, encodedPayload, encodedSignature] = token.split(".");
10383
+ if (!encodedHeader || !encodedPayload || !encodedSignature) {
10384
+ throw new Error(JWT_ERROR.INVALID_JWT_FORMAT);
10385
+ }
10386
+ const headerJson = base64UrlDecode(encodedHeader);
10387
+ const payloadJson = base64UrlDecode(encodedPayload);
10388
+ const header = JSON.parse(headerJson);
10389
+ const payload = JSON.parse(payloadJson);
10390
+ const dataToVerify = `${encodedHeader}.${encodedPayload}`;
10391
+ const encoder = new TextEncoder();
10392
+ if (secret !== void 0) {
10393
+ const key = await crypto.subtle.importKey(
10394
+ "raw",
10395
+ encoder.encode(secret),
10396
+ { name: "HMAC", hash: "SHA-256" },
10397
+ false,
10398
+ ["verify"]
10399
+ );
10400
+ const binarySignature = base64UrlDecode(encodedSignature);
10401
+ const signature = new Uint8Array(
10402
+ [...binarySignature].map((char) => char.charCodeAt(0))
10403
+ );
10404
+ const valid = await crypto.subtle.verify(
10405
+ "HMAC",
10406
+ key,
10407
+ signature,
10408
+ encoder.encode(dataToVerify)
10409
+ );
10410
+ return { header, payload, valid };
10411
+ }
10412
+ return { header, payload, valid: false };
10413
+ }
10414
+ var jwt;
10415
+ ((jwt2) => {
10416
+ jwt2.encode = createJwt;
10417
+ jwt2.decode = decodeJwt;
10418
+ jwt2.ERROR = JWT_ERROR;
10419
+ jwt2.DEFAULT_HEADER = HEADER;
10420
+ })(jwt || (jwt = {}));
10421
+
10422
+ // ../state-manager/src/MenuManager.ts
10423
+ import { isDeepEqual as isDeepEqual4 } from "@noya-app/noya-utils";
10424
+ import { Observable as Observable11 } from "@noya-app/observable";
10425
+
10489
10426
  // ../state-manager/src/NoyaManager.ts
10490
10427
  import { uuid as uuid12 } from "@noya-app/noya-utils";
10491
- import { Observable as Observable21, set as set3 } from "@noya-app/observable";
10428
+ import { Observable as Observable22, set as set3 } from "@noya-app/observable";
10492
10429
 
10493
10430
  // ../noya-pipeline/src/graphToTasks.ts
10494
10431
  import { get as get3 } from "@noya-app/observable";
@@ -10593,38 +10530,38 @@ var pipelineSchema = Type.Object(
10593
10530
  );
10594
10531
 
10595
10532
  // ../state-manager/src/PipelineManager.ts
10596
- import { Observable as Observable11 } from "@noya-app/observable";
10533
+ import { Observable as Observable12 } from "@noya-app/observable";
10597
10534
 
10598
10535
  // ../state-manager/src/PublishingManager.ts
10599
- import { Observable as Observable12 } from "@noya-app/observable";
10536
+ import { Observable as Observable13 } from "@noya-app/observable";
10600
10537
 
10601
10538
  // ../state-manager/src/ResourceManager.ts
10602
10539
  import { isDeepEqual as isDeepEqual5, uuid as uuid7 } from "@noya-app/noya-utils";
10603
- import { Observable as Observable13 } from "@noya-app/observable";
10540
+ import { Observable as Observable14 } from "@noya-app/observable";
10604
10541
 
10605
10542
  // ../state-manager/src/SandboxManager.ts
10606
- import { Observable as Observable14 } from "@noya-app/observable";
10543
+ import { Observable as Observable15 } from "@noya-app/observable";
10607
10544
 
10608
10545
  // ../state-manager/src/rpcManager.ts
10609
10546
  import { uuid as uuid8 } from "@noya-app/noya-utils";
10610
- import { Observable as Observable15 } from "@noya-app/observable";
10547
+ import { Observable as Observable16 } from "@noya-app/observable";
10611
10548
 
10612
10549
  // ../state-manager/src/SecretManager.ts
10613
- import { Observable as Observable16 } from "@noya-app/observable";
10550
+ import { Observable as Observable17 } from "@noya-app/observable";
10614
10551
 
10615
10552
  // ../state-manager/src/TaskManager.ts
10616
- import { Observable as Observable17 } from "@noya-app/observable";
10553
+ import { Observable as Observable18 } from "@noya-app/observable";
10617
10554
 
10618
10555
  // ../state-manager/src/TranscriptionManager.ts
10619
10556
  import { Base64 as Base642 } from "@noya-app/noya-utils";
10620
- import { Observable as Observable18 } from "@noya-app/observable";
10557
+ import { Observable as Observable19 } from "@noya-app/observable";
10621
10558
 
10622
10559
  // ../state-manager/src/UserManager.ts
10623
- import { Observable as Observable20 } from "@noya-app/observable";
10560
+ import { Observable as Observable21 } from "@noya-app/observable";
10624
10561
 
10625
10562
  // ../state-manager/src/sync/clientId.ts
10626
10563
  import { uuid as uuid9 } from "@noya-app/noya-utils";
10627
- import { Observable as Observable19 } from "@noya-app/observable";
10564
+ import { Observable as Observable20 } from "@noya-app/observable";
10628
10565
 
10629
10566
  // ../state-manager/src/sync/defaultNames.ts
10630
10567
  import { upperFirst } from "@noya-app/noya-utils";
@@ -10697,9 +10634,9 @@ function getClientAnimalFromName(name) {
10697
10634
  var CLIENT_ID_STORAGE_KEY = "noya-client-id";
10698
10635
  var CLIENT_NAME_STORAGE_KEY = "noya-client-name";
10699
10636
  var CLIENT_IMAGE_STORAGE_KEY = "noya-client-image";
10700
- var clientId$ = new Observable19(void 0);
10701
- var clientName$ = new Observable19(void 0);
10702
- var clientImage$ = new Observable19(void 0);
10637
+ var clientId$ = new Observable20(void 0);
10638
+ var clientName$ = new Observable20(void 0);
10639
+ var clientImage$ = new Observable20(void 0);
10703
10640
  var safeGetItem = (key) => {
10704
10641
  try {
10705
10642
  return typeof localStorage !== "undefined" ? localStorage.getItem(key) : null;
@@ -10872,11 +10809,11 @@ var createMutatorParametersSchema = Type.Object({
10872
10809
  });
10873
10810
 
10874
10811
  // ../noya-multiplayer-react/src/ai.ts
10875
- import { useEffect as useEffect17 } from "react";
10812
+ import { useEffect as useEffect18 } from "react";
10876
10813
 
10877
10814
  // ../noya-multiplayer-react/src/NoyaStateContext.tsx
10878
10815
  import {
10879
- Observable as Observable22
10816
+ Observable as Observable23
10880
10817
  } from "@noya-app/observable";
10881
10818
 
10882
10819
  // ../noya-react-utils/src/components/AutoSizer.tsx
@@ -11183,26 +11120,26 @@ function downloadBlob(...params) {
11183
11120
  }
11184
11121
 
11185
11122
  // ../noya-multiplayer-react/src/NoyaStateContext.tsx
11186
- import React36, {
11123
+ import React37, {
11187
11124
  createContext as createContext3,
11188
11125
  useCallback as useCallback14,
11189
11126
  useContext as useContext4,
11190
- useEffect as useEffect16,
11127
+ useEffect as useEffect17,
11191
11128
  useMemo as useMemo11,
11192
- useState as useState17
11129
+ useState as useState18
11193
11130
  } from "react";
11194
11131
 
11195
11132
  // ../noya-multiplayer-react/src/noyaApp.ts
11196
- import { useEffect as useEffect15, useMemo as useMemo10, useState as useState16 } from "react";
11133
+ import { useEffect as useEffect16, useMemo as useMemo10, useState as useState17 } from "react";
11197
11134
 
11198
11135
  // ../noya-multiplayer-react/src/hooks.ts
11199
11136
  import {
11200
11137
  createElement as createElement3,
11201
11138
  useCallback as useCallback13,
11202
- useEffect as useEffect14,
11139
+ useEffect as useEffect15,
11203
11140
  useMemo as useMemo9,
11204
- useRef as useRef11,
11205
- useState as useState15,
11141
+ useRef as useRef12,
11142
+ useState as useState16,
11206
11143
  useSyncExternalStore as useSyncExternalStore2
11207
11144
  } from "react";
11208
11145
  import { createRoot as createRoot2 } from "react-dom/client";
@@ -11282,14 +11219,14 @@ var ErrorOverlay = React6.memo(function ErrorOverlay2({
11282
11219
  });
11283
11220
 
11284
11221
  // ../noya-multiplayer-react/src/inspector/useStateInspector.tsx
11285
- import React34 from "react";
11222
+ import React35 from "react";
11286
11223
  import { createRoot } from "react-dom/client";
11287
11224
 
11288
11225
  // ../noya-multiplayer-react/src/inspector/StateInspector.tsx
11289
- import { Base64 as Base644, memoize as memoize2, uuid as uuid13 } from "@noya-app/noya-utils";
11290
- import React33, {
11226
+ import { Base64 as Base644, memoize, uuid as uuid13 } from "@noya-app/noya-utils";
11227
+ import React34, {
11291
11228
  useCallback as useCallback12,
11292
- useEffect as useEffect13,
11229
+ useEffect as useEffect14,
11293
11230
  useLayoutEffect as useLayoutEffect4
11294
11231
  } from "react";
11295
11232
 
@@ -12941,8 +12878,424 @@ function EventsSection({
12941
12878
  );
12942
12879
  }
12943
12880
 
12881
+ // ../noya-multiplayer-react/src/inspector/sections/GitSection.tsx
12882
+ import React27, { useEffect as useEffect12, useRef as useRef10, useState as useState15 } from "react";
12883
+
12884
+ // ../noya-multiplayer-react/src/inspector/StateInspectorTitleLabel.tsx
12885
+ import React26 from "react";
12886
+ function StateInspectorTitleLabel({
12887
+ children
12888
+ }) {
12889
+ return /* @__PURE__ */ React26.createElement("span", { style: { display: "flex", alignItems: "center", gap: "4px" } }, children);
12890
+ }
12891
+
12892
+ // ../noya-multiplayer-react/src/inspector/sections/GitSection.tsx
12893
+ function GitSection({
12894
+ showGit,
12895
+ setShowGit,
12896
+ colorScheme,
12897
+ gitManager
12898
+ }) {
12899
+ const theme3 = getStateInspectorTheme(colorScheme);
12900
+ const repos = useObservable2(gitManager.repos$);
12901
+ const isInitialized = useObservable2(gitManager.isInitialized$);
12902
+ const repoFiles = useObservable2(gitManager.repoFiles$);
12903
+ const [focusedRepoId, setFocusedRepoId] = useState15(null);
12904
+ const [editingFile, setEditingFile] = useState15(null);
12905
+ const editHandleRef = useRef10(null);
12906
+ const [editContent, setEditContent] = useState15("");
12907
+ const [isEditInitialized, setIsEditInitialized] = useState15(false);
12908
+ const focusedRepo = focusedRepoId ? repos.find((r) => r.id === focusedRepoId) : null;
12909
+ const focusedRepoFilesState = focusedRepoId ? repoFiles[focusedRepoId] : null;
12910
+ const handleFocusRepo = async (repoId) => {
12911
+ if (editHandleRef.current) {
12912
+ editHandleRef.current.close();
12913
+ editHandleRef.current = null;
12914
+ setEditingFile(null);
12915
+ setEditContent("");
12916
+ setIsEditInitialized(false);
12917
+ }
12918
+ setFocusedRepoId(repoId);
12919
+ if (repoId && !repoFiles[repoId]) {
12920
+ await gitManager.fetchRepoFiles(repoId);
12921
+ }
12922
+ };
12923
+ const handleEditFile = (filePath) => {
12924
+ if (!focusedRepoId || !focusedRepoFilesState) return;
12925
+ if (editHandleRef.current) {
12926
+ editHandleRef.current.close();
12927
+ }
12928
+ const handle = gitManager.openEditingHandle(
12929
+ focusedRepoId,
12930
+ filePath,
12931
+ focusedRepoFilesState.ref
12932
+ );
12933
+ editHandleRef.current = handle;
12934
+ setEditingFile(filePath);
12935
+ setIsEditInitialized(false);
12936
+ setEditContent("");
12937
+ };
12938
+ const handleCloseEdit = () => {
12939
+ if (editHandleRef.current) {
12940
+ editHandleRef.current.close();
12941
+ editHandleRef.current = null;
12942
+ }
12943
+ setEditingFile(null);
12944
+ setEditContent("");
12945
+ setIsEditInitialized(false);
12946
+ };
12947
+ useEffect12(() => {
12948
+ const handle = editHandleRef.current;
12949
+ if (!handle) return;
12950
+ const unsubContent = handle.content$.subscribe((content) => {
12951
+ setEditContent(content);
12952
+ });
12953
+ const unsubInitialized = handle.isInitialized$.subscribe((initialized) => {
12954
+ setIsEditInitialized(initialized);
12955
+ });
12956
+ return () => {
12957
+ unsubContent();
12958
+ unsubInitialized();
12959
+ };
12960
+ }, [editingFile]);
12961
+ const handleContentChange = (newContent) => {
12962
+ const handle = editHandleRef.current;
12963
+ if (!handle) return;
12964
+ handle.setState(newContent);
12965
+ };
12966
+ const handleBranchChange = async (ref) => {
12967
+ if (focusedRepoId) {
12968
+ await gitManager.fetchRepoFiles(focusedRepoId, ref);
12969
+ }
12970
+ };
12971
+ const handleAddFile = async () => {
12972
+ if (!focusedRepoId || !focusedRepoFilesState) return;
12973
+ const path2 = prompt("Enter file path (e.g., src/index.ts):");
12974
+ if (!path2) return;
12975
+ try {
12976
+ await gitManager.patchFiles(
12977
+ focusedRepoId,
12978
+ { create: [{ path: path2, content: "" }] },
12979
+ focusedRepoFilesState.ref
12980
+ );
12981
+ } catch (error) {
12982
+ alert(`Failed to create file: ${error}`);
12983
+ }
12984
+ };
12985
+ const handleRenameFile = async (oldPath) => {
12986
+ if (!focusedRepoId || !focusedRepoFilesState) return;
12987
+ const newPath = prompt(`Rename "${oldPath}" to:`, oldPath);
12988
+ if (!newPath || newPath === oldPath) return;
12989
+ try {
12990
+ await gitManager.patchFiles(
12991
+ focusedRepoId,
12992
+ { rename: [{ oldPath, newPath }] },
12993
+ focusedRepoFilesState.ref
12994
+ );
12995
+ } catch (error) {
12996
+ alert(`Failed to rename file: ${error}`);
12997
+ }
12998
+ };
12999
+ const handleDeleteFile = async (path2) => {
13000
+ if (!focusedRepoId || !focusedRepoFilesState) return;
13001
+ const confirmed = confirm(`Delete "${path2}"?`);
13002
+ if (!confirmed) return;
13003
+ try {
13004
+ await gitManager.patchFiles(
13005
+ focusedRepoId,
13006
+ { delete: [{ path: path2 }] },
13007
+ focusedRepoFilesState.ref
13008
+ );
13009
+ if (editingFile === path2) {
13010
+ handleCloseEdit();
13011
+ }
13012
+ } catch (error) {
13013
+ alert(`Failed to delete file: ${error}`);
13014
+ }
13015
+ };
13016
+ return /* @__PURE__ */ React27.createElement(
13017
+ StateInspectorDisclosureSection,
13018
+ {
13019
+ open: showGit,
13020
+ setOpen: setShowGit,
13021
+ title: /* @__PURE__ */ React27.createElement(StateInspectorTitleLabel, null, "Git Repos (", repos.length, ")", /* @__PURE__ */ React27.createElement(ColoredDot, { type: isInitialized ? "success" : "error" })),
13022
+ colorScheme,
13023
+ right: /* @__PURE__ */ React27.createElement("span", { style: { display: "flex", gap: "10px" } }, /* @__PURE__ */ React27.createElement(
13024
+ StateInspectorButton,
13025
+ {
13026
+ theme: theme3,
13027
+ onClick: async () => {
13028
+ try {
13029
+ await gitManager.initRepo();
13030
+ } catch (error) {
13031
+ console.error("[GitSection] Failed to create repo:", error);
13032
+ }
13033
+ }
13034
+ },
13035
+ "Init Repo"
13036
+ ))
13037
+ },
13038
+ /* @__PURE__ */ React27.createElement(StateInspectorDisclosureRowInner, null, /* @__PURE__ */ React27.createElement("div", { style: { padding: "4px 12px", display: "flex", gap: "4px" } }, /* @__PURE__ */ React27.createElement(
13039
+ "select",
13040
+ {
13041
+ name: "repoSelector",
13042
+ value: focusedRepoId ?? "",
13043
+ style: { flex: "1 1 auto", height: "19px", minWidth: 0 },
13044
+ onChange: (e) => {
13045
+ const value = e.target.value;
13046
+ handleFocusRepo(value || null);
13047
+ }
13048
+ },
13049
+ /* @__PURE__ */ React27.createElement("option", { value: "" }, "Select a repo..."),
13050
+ repos.map((repo) => /* @__PURE__ */ React27.createElement("option", { key: repo.id, value: repo.id }, repo.id))
13051
+ ), focusedRepoId && /* @__PURE__ */ React27.createElement(
13052
+ StateInspectorButton,
13053
+ {
13054
+ theme: theme3,
13055
+ onClick: () => gitManager.fetchRepoFiles(focusedRepoId)
13056
+ },
13057
+ "Refresh"
13058
+ ), /* @__PURE__ */ React27.createElement(
13059
+ "label",
13060
+ {
13061
+ style: {
13062
+ display: "flex",
13063
+ alignItems: "center",
13064
+ gap: "4px",
13065
+ fontSize: "11px",
13066
+ whiteSpace: "nowrap"
13067
+ }
13068
+ },
13069
+ "[Include Content = ",
13070
+ gitManager.includeContent ? "true" : "false",
13071
+ "]"
13072
+ )), focusedRepo && focusedRepoFilesState && /* @__PURE__ */ React27.createElement(React27.Fragment, null, /* @__PURE__ */ React27.createElement(
13073
+ "div",
13074
+ {
13075
+ style: {
13076
+ padding: "4px 12px",
13077
+ display: "flex",
13078
+ gap: "8px",
13079
+ alignItems: "center",
13080
+ fontSize: "12px"
13081
+ }
13082
+ },
13083
+ /* @__PURE__ */ React27.createElement("span", { style: { color: theme3.BASE_COLOR } }, "Branch:"),
13084
+ focusedRepoFilesState.branches.length > 0 ? /* @__PURE__ */ React27.createElement(
13085
+ "select",
13086
+ {
13087
+ value: focusedRepoFilesState.ref,
13088
+ style: { flex: "1 1 auto", height: "19px" },
13089
+ onChange: (e) => handleBranchChange(e.target.value)
13090
+ },
13091
+ focusedRepoFilesState.branches.map((branch) => /* @__PURE__ */ React27.createElement("option", { key: branch.name, value: branch.name }, branch.name))
13092
+ ) : /* @__PURE__ */ React27.createElement("span", { style: { opacity: 0.6, fontStyle: "italic" } }, focusedRepoFilesState.ref || "No branches"),
13093
+ focusedRepoFilesState.oid && /* @__PURE__ */ React27.createElement(
13094
+ "span",
13095
+ {
13096
+ style: {
13097
+ fontFamily: "monospace",
13098
+ fontSize: "10px",
13099
+ opacity: 0.6
13100
+ },
13101
+ title: focusedRepoFilesState.oid
13102
+ },
13103
+ focusedRepoFilesState.oid.slice(0, 7),
13104
+ focusedRepoFilesState.fetchState === "refreshing" && "\u2026"
13105
+ ),
13106
+ /* @__PURE__ */ React27.createElement(
13107
+ StateInspectorButton,
13108
+ {
13109
+ theme: theme3,
13110
+ onClick: handleAddFile,
13111
+ style: { fontSize: "10px", padding: "2px 6px" }
13112
+ },
13113
+ "+ Add File"
13114
+ )
13115
+ ), focusedRepoFilesState.fetchState === "loading" && /* @__PURE__ */ React27.createElement(
13116
+ "div",
13117
+ {
13118
+ style: {
13119
+ padding: "12px",
13120
+ fontSize: "12px"
13121
+ }
13122
+ },
13123
+ "Loading files..."
13124
+ ), focusedRepoFilesState.error && /* @__PURE__ */ React27.createElement(
13125
+ "div",
13126
+ {
13127
+ style: {
13128
+ padding: "12px",
13129
+ fontSize: "12px",
13130
+ color: "#f44"
13131
+ }
13132
+ },
13133
+ "Error: ",
13134
+ focusedRepoFilesState.error
13135
+ ), focusedRepoFilesState.fetchState !== "loading" && !focusedRepoFilesState.error && focusedRepoFilesState.files.length === 0 && /* @__PURE__ */ React27.createElement(
13136
+ "div",
13137
+ {
13138
+ style: {
13139
+ padding: "12px",
13140
+ fontSize: "12px"
13141
+ }
13142
+ },
13143
+ "No files (empty repo)"
13144
+ ), !editingFile && focusedRepoFilesState.files.map((file, index) => {
13145
+ const fileInfo = focusedRepoFilesState.fileContents?.find(
13146
+ (f) => f.path === file
13147
+ );
13148
+ let preview = "";
13149
+ if (fileInfo) {
13150
+ try {
13151
+ const decoded = atob(fileInfo.content);
13152
+ preview = decoded.slice(0, 40).replace(/\n/g, " ").replace(/\s+/g, " ");
13153
+ if (decoded.length > 40) preview += "\u2026";
13154
+ } catch {
13155
+ }
13156
+ }
13157
+ return /* @__PURE__ */ React27.createElement(
13158
+ "div",
13159
+ {
13160
+ key: index,
13161
+ style: {
13162
+ padding: "2px 12px",
13163
+ display: "flex",
13164
+ justifyContent: "space-between",
13165
+ alignItems: "center",
13166
+ gap: "8px",
13167
+ borderBottom: `1px solid ${colorScheme === "light" ? "rgb(223 223 223)" : "rgb(29 29 29)"}`
13168
+ }
13169
+ },
13170
+ /* @__PURE__ */ React27.createElement(
13171
+ "span",
13172
+ {
13173
+ style: {
13174
+ fontFamily: "monospace",
13175
+ fontSize: "11px",
13176
+ overflow: "hidden",
13177
+ textOverflow: "ellipsis",
13178
+ whiteSpace: "nowrap",
13179
+ minWidth: 0,
13180
+ display: "flex",
13181
+ gap: "8px"
13182
+ },
13183
+ title: file
13184
+ },
13185
+ /* @__PURE__ */ React27.createElement("span", null, file),
13186
+ preview && /* @__PURE__ */ React27.createElement("span", { style: { opacity: 0.5 } }, preview)
13187
+ ),
13188
+ /* @__PURE__ */ React27.createElement("span", { style: { display: "flex", gap: "4px", flexShrink: 0 } }, /* @__PURE__ */ React27.createElement(
13189
+ StateInspectorButton,
13190
+ {
13191
+ theme: theme3,
13192
+ onClick: () => handleEditFile(file),
13193
+ style: { fontSize: "10px", padding: "2px 6px" }
13194
+ },
13195
+ "Edit"
13196
+ ), /* @__PURE__ */ React27.createElement(
13197
+ StateInspectorButton,
13198
+ {
13199
+ theme: theme3,
13200
+ onClick: () => handleRenameFile(file),
13201
+ style: { fontSize: "10px", padding: "2px 6px" }
13202
+ },
13203
+ "Rename"
13204
+ ), /* @__PURE__ */ React27.createElement(
13205
+ StateInspectorButton,
13206
+ {
13207
+ theme: theme3,
13208
+ onClick: () => handleDeleteFile(file),
13209
+ style: { fontSize: "10px", padding: "2px 6px" }
13210
+ },
13211
+ "Delete"
13212
+ ))
13213
+ );
13214
+ }), editingFile && /* @__PURE__ */ React27.createElement(
13215
+ "div",
13216
+ {
13217
+ style: {
13218
+ padding: "8px 12px",
13219
+ borderTop: `1px solid ${theme3.DIVIDER_COLOR}`,
13220
+ flex: "1 1 auto",
13221
+ display: "flex",
13222
+ flexDirection: "column",
13223
+ minHeight: 0
13224
+ }
13225
+ },
13226
+ /* @__PURE__ */ React27.createElement(
13227
+ "div",
13228
+ {
13229
+ style: {
13230
+ display: "flex",
13231
+ justifyContent: "space-between",
13232
+ alignItems: "center",
13233
+ marginBottom: "8px",
13234
+ flexShrink: 0
13235
+ }
13236
+ },
13237
+ /* @__PURE__ */ React27.createElement(
13238
+ "span",
13239
+ {
13240
+ style: {
13241
+ fontFamily: "monospace",
13242
+ fontSize: "11px",
13243
+ fontWeight: "bold"
13244
+ }
13245
+ },
13246
+ editingFile,
13247
+ !isEditInitialized && /* @__PURE__ */ React27.createElement("span", { style: { opacity: 0.5, marginLeft: "8px" } }, "Loading...")
13248
+ ),
13249
+ /* @__PURE__ */ React27.createElement(
13250
+ StateInspectorButton,
13251
+ {
13252
+ theme: theme3,
13253
+ onClick: handleCloseEdit,
13254
+ style: { fontSize: "10px", padding: "2px 6px" }
13255
+ },
13256
+ "Close"
13257
+ )
13258
+ ),
13259
+ /* @__PURE__ */ React27.createElement(
13260
+ "textarea",
13261
+ {
13262
+ value: editContent,
13263
+ onChange: (e) => handleContentChange(e.target.value),
13264
+ disabled: !isEditInitialized,
13265
+ style: {
13266
+ width: "100%",
13267
+ flex: "1 1 auto",
13268
+ minHeight: "100px",
13269
+ fontFamily: "monospace",
13270
+ fontSize: "11px",
13271
+ padding: "8px",
13272
+ border: `1px solid ${theme3.DIVIDER_COLOR}`,
13273
+ borderRadius: "4px",
13274
+ backgroundColor: theme3.ROW_BACKGROUND,
13275
+ color: theme3.BASE_COLOR,
13276
+ resize: "none",
13277
+ boxSizing: "border-box"
13278
+ }
13279
+ }
13280
+ )
13281
+ )), repos.length === 0 && /* @__PURE__ */ React27.createElement(
13282
+ "div",
13283
+ {
13284
+ style: {
13285
+ padding: "12px",
13286
+ fontSize: "12px",
13287
+ display: "flex",
13288
+ flexDirection: "column",
13289
+ gap: "4px"
13290
+ }
13291
+ },
13292
+ /* @__PURE__ */ React27.createElement("span", null, "No git repos")
13293
+ ))
13294
+ );
13295
+ }
13296
+
12944
13297
  // ../noya-multiplayer-react/src/inspector/sections/HistorySection.tsx
12945
- import React26, { useEffect as useEffect12, useRef as useRef10 } from "react";
13298
+ import React28, { useEffect as useEffect13, useRef as useRef11 } from "react";
12946
13299
 
12947
13300
  // ../noya-multiplayer-react/src/inspector/utils.ts
12948
13301
  function pathToString(extendedPath) {
@@ -12997,15 +13350,15 @@ function HistorySection({
12997
13350
  historySnapshot,
12998
13351
  multiplayerStateManager
12999
13352
  }) {
13000
- const ref = useRef10(null);
13353
+ const ref = useRef11(null);
13001
13354
  const theme3 = getStateInspectorTheme(colorScheme);
13002
13355
  const solidBorderColor = getStateInspectorBorderColor(colorScheme);
13003
- useEffect12(() => {
13356
+ useEffect13(() => {
13004
13357
  if (ref.current) {
13005
13358
  ref.current.scrollTop = ref.current.scrollHeight;
13006
13359
  }
13007
13360
  }, [historySnapshot]);
13008
- useEffect12(() => {
13361
+ useEffect13(() => {
13009
13362
  if (!ref.current) return;
13010
13363
  const historyEntry = ref.current.querySelector(
13011
13364
  `#${HISTORY_ELEMENT_PREFIX}${historySnapshot.historyIndex}`
@@ -13017,14 +13370,14 @@ function HistorySection({
13017
13370
  });
13018
13371
  }
13019
13372
  }, [historySnapshot.historyIndex]);
13020
- return /* @__PURE__ */ React26.createElement(
13373
+ return /* @__PURE__ */ React28.createElement(
13021
13374
  StateInspectorDisclosureSection,
13022
13375
  {
13023
13376
  open: showHistory,
13024
13377
  setOpen: setShowHistory,
13025
13378
  title: "History",
13026
13379
  colorScheme,
13027
- right: /* @__PURE__ */ React26.createElement(
13380
+ right: /* @__PURE__ */ React28.createElement(
13028
13381
  "span",
13029
13382
  {
13030
13383
  style: {
@@ -13032,7 +13385,7 @@ function HistorySection({
13032
13385
  gap: "4px"
13033
13386
  }
13034
13387
  },
13035
- /* @__PURE__ */ React26.createElement(
13388
+ /* @__PURE__ */ React28.createElement(
13036
13389
  StateInspectorButton,
13037
13390
  {
13038
13391
  disabled: !historySnapshot.canUndo,
@@ -13041,7 +13394,7 @@ function HistorySection({
13041
13394
  multiplayerStateManager.undo();
13042
13395
  }
13043
13396
  },
13044
- /* @__PURE__ */ React26.createElement("span", { style: { width: "12px", height: "12px" } }, /* @__PURE__ */ React26.createElement(
13397
+ /* @__PURE__ */ React28.createElement("span", { style: { width: "12px", height: "12px" } }, /* @__PURE__ */ React28.createElement(
13045
13398
  "svg",
13046
13399
  {
13047
13400
  xmlns: "http://www.w3.org/2000/svg",
@@ -13049,7 +13402,7 @@ function HistorySection({
13049
13402
  height: "1em",
13050
13403
  viewBox: "0 0 20 20"
13051
13404
  },
13052
- /* @__PURE__ */ React26.createElement(
13405
+ /* @__PURE__ */ React28.createElement(
13053
13406
  "path",
13054
13407
  {
13055
13408
  fill: "currentColor",
@@ -13058,7 +13411,7 @@ function HistorySection({
13058
13411
  )
13059
13412
  ))
13060
13413
  ),
13061
- /* @__PURE__ */ React26.createElement(
13414
+ /* @__PURE__ */ React28.createElement(
13062
13415
  StateInspectorButton,
13063
13416
  {
13064
13417
  disabled: !historySnapshot.canRedo,
@@ -13067,7 +13420,7 @@ function HistorySection({
13067
13420
  multiplayerStateManager.redo();
13068
13421
  }
13069
13422
  },
13070
- /* @__PURE__ */ React26.createElement("span", { style: { width: "12px", height: "12px" } }, /* @__PURE__ */ React26.createElement(
13423
+ /* @__PURE__ */ React28.createElement("span", { style: { width: "12px", height: "12px" } }, /* @__PURE__ */ React28.createElement(
13071
13424
  "svg",
13072
13425
  {
13073
13426
  xmlns: "http://www.w3.org/2000/svg",
@@ -13075,7 +13428,7 @@ function HistorySection({
13075
13428
  height: "1em",
13076
13429
  viewBox: "0 0 20 20"
13077
13430
  },
13078
- /* @__PURE__ */ React26.createElement(
13431
+ /* @__PURE__ */ React28.createElement(
13079
13432
  "path",
13080
13433
  {
13081
13434
  fill: "currentColor",
@@ -13086,7 +13439,7 @@ function HistorySection({
13086
13439
  )
13087
13440
  )
13088
13441
  },
13089
- /* @__PURE__ */ React26.createElement(StateInspectorDisclosureRowInner, { ref }, /* @__PURE__ */ React26.createElement(
13442
+ /* @__PURE__ */ React28.createElement(StateInspectorDisclosureRowInner, { ref }, /* @__PURE__ */ React28.createElement(
13090
13443
  "div",
13091
13444
  {
13092
13445
  id: `${HISTORY_ELEMENT_PREFIX}0`,
@@ -13100,7 +13453,7 @@ function HistorySection({
13100
13453
  background: historySnapshot.historyIndex === 0 ? "rgb(59 130 246 / 15%)" : void 0
13101
13454
  }
13102
13455
  },
13103
- /* @__PURE__ */ React26.createElement(
13456
+ /* @__PURE__ */ React28.createElement(
13104
13457
  "span",
13105
13458
  {
13106
13459
  style: {
@@ -13115,7 +13468,7 @@ function HistorySection({
13115
13468
  ), historySnapshot.history.map((entry, index) => {
13116
13469
  const metadata = entry.metadata;
13117
13470
  const { id, name, timestamp, ...rest } = metadata;
13118
- return /* @__PURE__ */ React26.createElement(
13471
+ return /* @__PURE__ */ React28.createElement(
13119
13472
  "div",
13120
13473
  {
13121
13474
  id: `${HISTORY_ELEMENT_PREFIX}${index + 1}`,
@@ -13126,7 +13479,7 @@ function HistorySection({
13126
13479
  background: index + 1 === historySnapshot.historyIndex ? "rgb(59 130 246 / 15%)" : void 0
13127
13480
  }
13128
13481
  },
13129
- typeof name === "string" && /* @__PURE__ */ React26.createElement(
13482
+ typeof name === "string" && /* @__PURE__ */ React28.createElement(
13130
13483
  "pre",
13131
13484
  {
13132
13485
  style: {
@@ -13137,9 +13490,9 @@ function HistorySection({
13137
13490
  }
13138
13491
  },
13139
13492
  entry.metadata.name,
13140
- Object.keys(rest).length > 0 && /* @__PURE__ */ React26.createElement(themedObjectInspector, { data: rest, theme: theme3 })
13493
+ Object.keys(rest).length > 0 && /* @__PURE__ */ React28.createElement(themedObjectInspector, { data: rest, theme: theme3 })
13141
13494
  ),
13142
- entry.redoPatches?.map((patch, j) => /* @__PURE__ */ React26.createElement(
13495
+ entry.redoPatches?.map((patch, j) => /* @__PURE__ */ React28.createElement(
13143
13496
  "pre",
13144
13497
  {
13145
13498
  key: j,
@@ -13150,10 +13503,10 @@ function HistorySection({
13150
13503
  margin: 0
13151
13504
  }
13152
13505
  },
13153
- patch.op === "add" && /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path)), " = ", /* @__PURE__ */ React26.createElement(themedObjectInspector, { data: patch.value, theme: theme3 })),
13154
- patch.op === "replace" && /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path)), " = ", /* @__PURE__ */ React26.createElement(themedObjectInspector, { data: patch.value, theme: theme3 })),
13155
- patch.op === "remove" && /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement("span", { style: { color: theme3.OBJECT_VALUE_STRING_COLOR } }, "delete", " "), /* @__PURE__ */ React26.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path))),
13156
- patch.op === "move" && /* @__PURE__ */ React26.createElement(React26.Fragment, null, /* @__PURE__ */ React26.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.from)), " -> ", /* @__PURE__ */ React26.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path)))
13506
+ patch.op === "add" && /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path)), " = ", /* @__PURE__ */ React28.createElement(themedObjectInspector, { data: patch.value, theme: theme3 })),
13507
+ patch.op === "replace" && /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path)), " = ", /* @__PURE__ */ React28.createElement(themedObjectInspector, { data: patch.value, theme: theme3 })),
13508
+ patch.op === "remove" && /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement("span", { style: { color: theme3.OBJECT_VALUE_STRING_COLOR } }, "delete", " "), /* @__PURE__ */ React28.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path))),
13509
+ patch.op === "move" && /* @__PURE__ */ React28.createElement(React28.Fragment, null, /* @__PURE__ */ React28.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.from)), " -> ", /* @__PURE__ */ React28.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path)))
13157
13510
  ))
13158
13511
  );
13159
13512
  }))
@@ -13161,7 +13514,7 @@ function HistorySection({
13161
13514
  }
13162
13515
 
13163
13516
  // ../noya-multiplayer-react/src/inspector/sections/ServerScriptLogsSection.tsx
13164
- import React27 from "react";
13517
+ import React29 from "react";
13165
13518
  var levelColors = {
13166
13519
  error: "#f87171",
13167
13520
  warn: "#facc15",
@@ -13181,16 +13534,16 @@ function ServerScriptLogsSection({
13181
13534
  title = "Server Script Logs"
13182
13535
  }) {
13183
13536
  const theme3 = getStateInspectorTheme(colorScheme);
13184
- return /* @__PURE__ */ React27.createElement(
13537
+ return /* @__PURE__ */ React29.createElement(
13185
13538
  StateInspectorDisclosureSection,
13186
13539
  {
13187
13540
  open: showLogs,
13188
13541
  setOpen: setShowLogs,
13189
13542
  title,
13190
13543
  colorScheme,
13191
- right: /* @__PURE__ */ React27.createElement(StateInspectorButton, { theme: theme3, onClick: onTogglePaused }, paused ? "Resume" : "Pause")
13544
+ right: /* @__PURE__ */ React29.createElement(StateInspectorButton, { theme: theme3, onClick: onTogglePaused }, paused ? "Resume" : "Pause")
13192
13545
  },
13193
- /* @__PURE__ */ React27.createElement(StateInspectorDisclosureRowInner, { ref: containerRef }, paused && /* @__PURE__ */ React27.createElement(
13546
+ /* @__PURE__ */ React29.createElement(StateInspectorDisclosureRowInner, { ref: containerRef }, paused && /* @__PURE__ */ React29.createElement(
13194
13547
  "div",
13195
13548
  {
13196
13549
  style: {
@@ -13200,7 +13553,7 @@ function ServerScriptLogsSection({
13200
13553
  }
13201
13554
  },
13202
13555
  "Log streaming paused"
13203
- ), logs.map((log) => /* @__PURE__ */ React27.createElement(StateInspectorRow, { key: log.id, colorScheme }, /* @__PURE__ */ React27.createElement(
13556
+ ), logs.map((log) => /* @__PURE__ */ React29.createElement(StateInspectorRow, { key: log.id, colorScheme }, /* @__PURE__ */ React29.createElement(
13204
13557
  "div",
13205
13558
  {
13206
13559
  style: {
@@ -13213,9 +13566,9 @@ function ServerScriptLogsSection({
13213
13566
  textTransform: "uppercase"
13214
13567
  }
13215
13568
  },
13216
- /* @__PURE__ */ React27.createElement("span", null, formatTimestamp(log.timestamp)),
13217
- /* @__PURE__ */ React27.createElement("span", { style: { color: levelColors[log.level] } }, log.level),
13218
- (log.origin || log.target || log.mode) && /* @__PURE__ */ React27.createElement(
13569
+ /* @__PURE__ */ React29.createElement("span", null, formatTimestamp(log.timestamp)),
13570
+ /* @__PURE__ */ React29.createElement("span", { style: { color: levelColors[log.level] } }, log.level),
13571
+ (log.origin || log.target || log.mode) && /* @__PURE__ */ React29.createElement(
13219
13572
  "span",
13220
13573
  {
13221
13574
  style: {
@@ -13227,7 +13580,7 @@ function ServerScriptLogsSection({
13227
13580
  },
13228
13581
  [log.origin ?? log.target, log.mode].filter(Boolean).join(" / ")
13229
13582
  ),
13230
- /* @__PURE__ */ React27.createElement(
13583
+ /* @__PURE__ */ React29.createElement(
13231
13584
  "span",
13232
13585
  {
13233
13586
  style: {
@@ -13238,7 +13591,7 @@ function ServerScriptLogsSection({
13238
13591
  },
13239
13592
  log.scriptId
13240
13593
  )
13241
- ), /* @__PURE__ */ React27.createElement(
13594
+ ), /* @__PURE__ */ React29.createElement(
13242
13595
  "div",
13243
13596
  {
13244
13597
  style: {
@@ -13247,15 +13600,15 @@ function ServerScriptLogsSection({
13247
13600
  gap: "4px"
13248
13601
  }
13249
13602
  },
13250
- log.values.length > 0 ? log.values.map((value, index) => /* @__PURE__ */ React27.createElement(
13603
+ log.values.length > 0 ? log.values.map((value, index) => /* @__PURE__ */ React29.createElement(
13251
13604
  themedObjectInspector,
13252
13605
  {
13253
13606
  key: index,
13254
13607
  data: value,
13255
13608
  theme: theme3
13256
13609
  }
13257
- )) : /* @__PURE__ */ React27.createElement("span", { style: { fontSize: "11px", opacity: 0.7 } }, "No data")
13258
- ))), !logs?.length && /* @__PURE__ */ React27.createElement(
13610
+ )) : /* @__PURE__ */ React29.createElement("span", { style: { fontSize: "11px", opacity: 0.7 } }, "No data")
13611
+ ))), !logs?.length && /* @__PURE__ */ React29.createElement(
13259
13612
  "div",
13260
13613
  {
13261
13614
  style: {
@@ -13266,7 +13619,7 @@ function ServerScriptLogsSection({
13266
13619
  gap: "4px"
13267
13620
  }
13268
13621
  },
13269
- /* @__PURE__ */ React27.createElement("span", null, "No logs received")
13622
+ /* @__PURE__ */ React29.createElement("span", null, "No logs received")
13270
13623
  ))
13271
13624
  );
13272
13625
  }
@@ -13794,16 +14147,8 @@ function decodeAll(buffer) {
13794
14147
  return { state, schema, assets, assetMap };
13795
14148
  }
13796
14149
 
13797
- // ../noya-multiplayer-react/src/inspector/StateInspectorTitleLabel.tsx
13798
- import React28 from "react";
13799
- function StateInspectorTitleLabel({
13800
- children
13801
- }) {
13802
- return /* @__PURE__ */ React28.createElement("span", { style: { display: "flex", alignItems: "center", gap: "4px" } }, children);
13803
- }
13804
-
13805
14150
  // ../noya-multiplayer-react/src/inspector/StateInspectorToggleButton.tsx
13806
- import React29 from "react";
14151
+ import React30 from "react";
13807
14152
  function StateInspectorToggleButton({
13808
14153
  showInspector,
13809
14154
  setShowInspector,
@@ -13811,7 +14156,7 @@ function StateInspectorToggleButton({
13811
14156
  anchor
13812
14157
  }) {
13813
14158
  const isRightAnchor = anchor === "right";
13814
- const rightIcon = /* @__PURE__ */ React29.createElement(
14159
+ const rightIcon = /* @__PURE__ */ React30.createElement(
13815
14160
  "svg",
13816
14161
  {
13817
14162
  xmlns: "http://www.w3.org/2000/svg",
@@ -13821,7 +14166,7 @@ function StateInspectorToggleButton({
13821
14166
  stroke: "currentColor",
13822
14167
  className: "size-6"
13823
14168
  },
13824
- /* @__PURE__ */ React29.createElement(
14169
+ /* @__PURE__ */ React30.createElement(
13825
14170
  "path",
13826
14171
  {
13827
14172
  strokeLinecap: "round",
@@ -13830,7 +14175,7 @@ function StateInspectorToggleButton({
13830
14175
  }
13831
14176
  )
13832
14177
  );
13833
- const leftIcon = /* @__PURE__ */ React29.createElement(
14178
+ const leftIcon = /* @__PURE__ */ React30.createElement(
13834
14179
  "svg",
13835
14180
  {
13836
14181
  xmlns: "http://www.w3.org/2000/svg",
@@ -13840,7 +14185,7 @@ function StateInspectorToggleButton({
13840
14185
  stroke: "currentColor",
13841
14186
  className: "size-6"
13842
14187
  },
13843
- /* @__PURE__ */ React29.createElement(
14188
+ /* @__PURE__ */ React30.createElement(
13844
14189
  "path",
13845
14190
  {
13846
14191
  strokeLinecap: "round",
@@ -13849,7 +14194,7 @@ function StateInspectorToggleButton({
13849
14194
  }
13850
14195
  )
13851
14196
  );
13852
- return /* @__PURE__ */ React29.createElement(
14197
+ return /* @__PURE__ */ React30.createElement(
13853
14198
  "span",
13854
14199
  {
13855
14200
  role: "button",
@@ -13870,15 +14215,15 @@ function StateInspectorToggleButton({
13870
14215
  setShowInspector(!showInspector);
13871
14216
  }
13872
14217
  },
13873
- showInspector ? "Hide Inspector" : /* @__PURE__ */ React29.createElement("span", { style: { width: "12px", height: "12px" } }, isRightAnchor ? rightIcon : leftIcon)
14218
+ showInspector ? "Hide Inspector" : /* @__PURE__ */ React30.createElement("span", { style: { width: "12px", height: "12px" } }, isRightAnchor ? rightIcon : leftIcon)
13874
14219
  );
13875
14220
  }
13876
14221
 
13877
14222
  // ../noya-multiplayer-react/src/inspector/useLocalStorageState.tsx
13878
- import React30 from "react";
14223
+ import React31 from "react";
13879
14224
  var localStorage2 = typeof window !== "undefined" ? window.localStorage : null;
13880
14225
  function useLocalStorageState(key, defaultValue) {
13881
- const [state, setState] = React30.useState(() => {
14226
+ const [state, setState] = React31.useState(() => {
13882
14227
  const value = localStorage2?.getItem(key);
13883
14228
  let result = defaultValue;
13884
14229
  if (value) {
@@ -13898,11 +14243,11 @@ function useLocalStorageState(key, defaultValue) {
13898
14243
  }
13899
14244
 
13900
14245
  // ../noya-multiplayer-react/src/inspector/usePausedStream.ts
13901
- import React31 from "react";
14246
+ import React33 from "react";
13902
14247
  function usePausedStream(items) {
13903
- const [paused, setPaused] = React31.useState(false);
13904
- const [visibleItems, setVisibleItems] = React31.useState(items ?? []);
13905
- const togglePaused = React31.useCallback(() => {
14248
+ const [paused, setPaused] = React33.useState(false);
14249
+ const [visibleItems, setVisibleItems] = React33.useState(items ?? []);
14250
+ const togglePaused = React33.useCallback(() => {
13906
14251
  setPaused((value) => {
13907
14252
  if (!value) {
13908
14253
  setVisibleItems(items ?? []);
@@ -13910,7 +14255,7 @@ function usePausedStream(items) {
13910
14255
  return !value;
13911
14256
  });
13912
14257
  }, [items]);
13913
- React31.useEffect(() => {
14258
+ React33.useEffect(() => {
13914
14259
  if (paused) return;
13915
14260
  setVisibleItems(items ?? []);
13916
14261
  }, [items, paused]);
@@ -13942,19 +14287,20 @@ var StateInspector = memoGeneric(function StateInspector2({
13942
14287
  ioManager,
13943
14288
  resourceManager,
13944
14289
  activityEventsManager,
13945
- logManager
14290
+ logManager,
14291
+ gitManager
13946
14292
  } = noyaManager;
13947
- const [didMount, setDidMount] = React33.useState(false);
14293
+ const [didMount, setDidMount] = React34.useState(false);
13948
14294
  const tasks = useObservable2(taskManager.tasks$);
13949
14295
  const inputs = useObservable2(ioManager.inputs$);
13950
14296
  const outputTransforms = useObservable2(ioManager.outputTransforms$);
13951
14297
  useLayoutEffect4(() => {
13952
14298
  setDidMount(true);
13953
14299
  }, []);
13954
- const eventsContainerRef = React33.useRef(null);
13955
- const activityEventsContainerRef = React33.useRef(null);
13956
- const serverLogsContainerRef = React33.useRef(null);
13957
- const serverSimulationLogsContainerRef = React33.useRef(null);
14300
+ const eventsContainerRef = React34.useRef(null);
14301
+ const activityEventsContainerRef = React34.useRef(null);
14302
+ const serverLogsContainerRef = React34.useRef(null);
14303
+ const serverSimulationLogsContainerRef = React34.useRef(null);
13958
14304
  const [showInspector, setShowInspector] = useLocalStorageState(
13959
14305
  "noya-multiplayer-react-show-inspector",
13960
14306
  true
@@ -14019,6 +14365,10 @@ var StateInspector = memoGeneric(function StateInspector2({
14019
14365
  "noya-multiplayer-react-show-server-simulation-logs",
14020
14366
  false
14021
14367
  );
14368
+ const [showGit, setShowGit] = useLocalStorageState(
14369
+ "noya-multiplayer-react-show-git",
14370
+ false
14371
+ );
14022
14372
  const [showSimulation, setShowSimulation] = useLocalStorageState(
14023
14373
  "noya-multiplayer-react-show-simulation",
14024
14374
  false
@@ -14029,7 +14379,7 @@ var StateInspector = memoGeneric(function StateInspector2({
14029
14379
  paused: connectionEventsPaused,
14030
14380
  togglePaused: toggleConnectionEventsPaused
14031
14381
  } = usePausedStream(connectionEvents);
14032
- useEffect13(() => {
14382
+ useEffect14(() => {
14033
14383
  if (eventsContainerRef.current) {
14034
14384
  eventsContainerRef.current.scrollTop = eventsContainerRef.current.scrollHeight;
14035
14385
  }
@@ -14048,13 +14398,13 @@ var StateInspector = memoGeneric(function StateInspector2({
14048
14398
  paused: serverSimulationLogsPaused,
14049
14399
  togglePaused: toggleServerSimulationLogsPaused
14050
14400
  } = usePausedStream(serverSimulationLogs);
14051
- useEffect13(() => {
14401
+ useEffect14(() => {
14052
14402
  if (!showServerLogs) return;
14053
14403
  if (serverLogsContainerRef.current) {
14054
14404
  serverLogsContainerRef.current.scrollTop = serverLogsContainerRef.current.scrollHeight;
14055
14405
  }
14056
14406
  }, [showServerLogs, visibleServerLogs]);
14057
- useEffect13(() => {
14407
+ useEffect14(() => {
14058
14408
  if (!showServerSimulationLogs) return;
14059
14409
  if (serverSimulationLogsContainerRef.current) {
14060
14410
  serverSimulationLogsContainerRef.current.scrollTop = serverSimulationLogsContainerRef.current.scrollHeight;
@@ -14118,7 +14468,7 @@ var StateInspector = memoGeneric(function StateInspector2({
14118
14468
  }, [noyaManager]);
14119
14469
  if (!didMount) return null;
14120
14470
  if (!showInspector) {
14121
- return /* @__PURE__ */ React33.createElement(
14471
+ return /* @__PURE__ */ React34.createElement(
14122
14472
  "div",
14123
14473
  {
14124
14474
  ...props,
@@ -14130,7 +14480,7 @@ var StateInspector = memoGeneric(function StateInspector2({
14130
14480
  },
14131
14481
  onClick: () => setShowInspector(true)
14132
14482
  },
14133
- /* @__PURE__ */ React33.createElement(
14483
+ /* @__PURE__ */ React34.createElement(
14134
14484
  StateInspectorToggleButton,
14135
14485
  {
14136
14486
  showInspector,
@@ -14141,7 +14491,7 @@ var StateInspector = memoGeneric(function StateInspector2({
14141
14491
  )
14142
14492
  );
14143
14493
  }
14144
- return /* @__PURE__ */ React33.createElement(
14494
+ return /* @__PURE__ */ React34.createElement(
14145
14495
  "div",
14146
14496
  {
14147
14497
  ...props,
@@ -14150,7 +14500,7 @@ var StateInspector = memoGeneric(function StateInspector2({
14150
14500
  ...props.style
14151
14501
  }
14152
14502
  },
14153
- /* @__PURE__ */ React33.createElement(
14503
+ /* @__PURE__ */ React34.createElement(
14154
14504
  StateInspectorDisclosureSection,
14155
14505
  {
14156
14506
  isFirst: true,
@@ -14163,14 +14513,14 @@ var StateInspector = memoGeneric(function StateInspector2({
14163
14513
  maxHeight: "50%",
14164
14514
  overflowY: "auto"
14165
14515
  },
14166
- right: /* @__PURE__ */ React33.createElement("span", { style: { display: "flex", gap: "10px" } }, /* @__PURE__ */ React33.createElement(
14516
+ right: /* @__PURE__ */ React34.createElement("span", { style: { display: "flex", gap: "10px" } }, /* @__PURE__ */ React34.createElement(
14167
14517
  StateInspectorButton,
14168
14518
  {
14169
14519
  theme: theme3,
14170
14520
  onClick: () => setShowUserDetails(!showUserDetails)
14171
14521
  },
14172
14522
  "Toggle details"
14173
- ), /* @__PURE__ */ React33.createElement(
14523
+ ), /* @__PURE__ */ React34.createElement(
14174
14524
  StateInspectorToggleButton,
14175
14525
  {
14176
14526
  showInspector,
@@ -14180,8 +14530,8 @@ var StateInspector = memoGeneric(function StateInspector2({
14180
14530
  }
14181
14531
  ))
14182
14532
  },
14183
- /* @__PURE__ */ React33.createElement(StateInspectorDisclosureRowInner, { style: { flex: "0 0 auto" } }, connectedUsers?.filter((user) => showUserDetails || !user.inactive).map((user, index, array) => {
14184
- return /* @__PURE__ */ React33.createElement(
14533
+ /* @__PURE__ */ React34.createElement(StateInspectorDisclosureRowInner, { style: { flex: "0 0 auto" } }, connectedUsers?.filter((user) => showUserDetails || !user.inactive).map((user, index, array) => {
14534
+ return /* @__PURE__ */ React34.createElement(
14185
14535
  StateInspectorRow,
14186
14536
  {
14187
14537
  key: user.connectionId,
@@ -14192,7 +14542,7 @@ var StateInspector = memoGeneric(function StateInspector2({
14192
14542
  opacity: user.inactive ? 0.5 : 1
14193
14543
  }
14194
14544
  },
14195
- user.image && /* @__PURE__ */ React33.createElement(
14545
+ user.image && /* @__PURE__ */ React34.createElement(
14196
14546
  "img",
14197
14547
  {
14198
14548
  src: user.image,
@@ -14209,9 +14559,9 @@ var StateInspector = memoGeneric(function StateInspector2({
14209
14559
  }
14210
14560
  }
14211
14561
  ),
14212
- showUserDetails ? /* @__PURE__ */ React33.createElement(themedObjectInspector, { data: user, theme: theme3 }) : user.name
14562
+ showUserDetails ? /* @__PURE__ */ React34.createElement(themedObjectInspector, { data: user, theme: theme3 }) : user.name
14213
14563
  );
14214
- }), !connectedUsers && /* @__PURE__ */ React33.createElement(
14564
+ }), !connectedUsers && /* @__PURE__ */ React34.createElement(
14215
14565
  "div",
14216
14566
  {
14217
14567
  style: {
@@ -14222,13 +14572,13 @@ var StateInspector = memoGeneric(function StateInspector2({
14222
14572
  gap: "4px"
14223
14573
  }
14224
14574
  },
14225
- /* @__PURE__ */ React33.createElement("span", null, "No connected users")
14575
+ /* @__PURE__ */ React34.createElement("span", null, "No connected users")
14226
14576
  ))
14227
14577
  ),
14228
- /* @__PURE__ */ React33.createElement(
14578
+ /* @__PURE__ */ React34.createElement(
14229
14579
  StateInspectorDisclosureSection,
14230
14580
  {
14231
- title: /* @__PURE__ */ React33.createElement(StateInspectorTitleLabel, null, "Data", /* @__PURE__ */ React33.createElement(
14581
+ title: /* @__PURE__ */ React34.createElement(StateInspectorTitleLabel, null, "Data", /* @__PURE__ */ React34.createElement(
14232
14582
  ColoredDot,
14233
14583
  {
14234
14584
  type: multipeerStateInitialized ? "success" : "error"
@@ -14237,7 +14587,7 @@ var StateInspector = memoGeneric(function StateInspector2({
14237
14587
  colorScheme,
14238
14588
  setOpen: setShowData,
14239
14589
  open: showData,
14240
- right: /* @__PURE__ */ React33.createElement(
14590
+ right: /* @__PURE__ */ React34.createElement(
14241
14591
  "span",
14242
14592
  {
14243
14593
  style: {
@@ -14245,9 +14595,9 @@ var StateInspector = memoGeneric(function StateInspector2({
14245
14595
  gap: "12px"
14246
14596
  }
14247
14597
  },
14248
- /* @__PURE__ */ React33.createElement(StateInspectorButton, { theme: theme3, onClick: handleImportAll }, "Import"),
14249
- /* @__PURE__ */ React33.createElement(StateInspectorButton, { theme: theme3, onClick: handleExportAll }, "Export"),
14250
- /* @__PURE__ */ React33.createElement(
14598
+ /* @__PURE__ */ React34.createElement(StateInspectorButton, { theme: theme3, onClick: handleImportAll }, "Import"),
14599
+ /* @__PURE__ */ React34.createElement(StateInspectorButton, { theme: theme3, onClick: handleExportAll }, "Export"),
14600
+ /* @__PURE__ */ React34.createElement(
14251
14601
  StateInspectorButton,
14252
14602
  {
14253
14603
  theme: theme3,
@@ -14259,14 +14609,14 @@ var StateInspector = memoGeneric(function StateInspector2({
14259
14609
  )
14260
14610
  )
14261
14611
  },
14262
- /* @__PURE__ */ React33.createElement(StateInspectorDisclosureRowInner, null, /* @__PURE__ */ React33.createElement(StateInspectorRow, { colorScheme }, /* @__PURE__ */ React33.createElement(
14612
+ /* @__PURE__ */ React34.createElement(StateInspectorDisclosureRowInner, null, /* @__PURE__ */ React34.createElement(StateInspectorRow, { colorScheme }, /* @__PURE__ */ React34.createElement(
14263
14613
  themedObjectInspector,
14264
14614
  {
14265
14615
  name: multiplayerStateManager.schema ? "state" : void 0,
14266
14616
  data: state,
14267
14617
  theme: theme3
14268
14618
  }
14269
- )), multiplayerStateManager.schema && /* @__PURE__ */ React33.createElement(StateInspectorRow, { colorScheme }, /* @__PURE__ */ React33.createElement(
14619
+ )), multiplayerStateManager.schema && /* @__PURE__ */ React34.createElement(StateInspectorRow, { colorScheme }, /* @__PURE__ */ React34.createElement(
14270
14620
  themedObjectInspector,
14271
14621
  {
14272
14622
  name: "schema",
@@ -14275,7 +14625,7 @@ var StateInspector = memoGeneric(function StateInspector2({
14275
14625
  }
14276
14626
  )))
14277
14627
  ),
14278
- /* @__PURE__ */ React33.createElement(
14628
+ /* @__PURE__ */ React34.createElement(
14279
14629
  HistorySection,
14280
14630
  {
14281
14631
  showHistory,
@@ -14285,14 +14635,14 @@ var StateInspector = memoGeneric(function StateInspector2({
14285
14635
  multiplayerStateManager
14286
14636
  }
14287
14637
  ),
14288
- /* @__PURE__ */ React33.createElement(
14638
+ /* @__PURE__ */ React34.createElement(
14289
14639
  StateInspectorDisclosureSection,
14290
14640
  {
14291
14641
  open: showAssets,
14292
14642
  setOpen: setShowAssets,
14293
- title: /* @__PURE__ */ React33.createElement(StateInspectorTitleLabel, null, "Assets (", assets.length, ")", /* @__PURE__ */ React33.createElement(ColoredDot, { type: assetsInitialized ? "success" : "error" })),
14643
+ title: /* @__PURE__ */ React34.createElement(StateInspectorTitleLabel, null, "Assets (", assets.length, ")", /* @__PURE__ */ React34.createElement(ColoredDot, { type: assetsInitialized ? "success" : "error" })),
14294
14644
  colorScheme,
14295
- right: /* @__PURE__ */ React33.createElement("span", { style: { display: "flex", gap: "10px" } }, /* @__PURE__ */ React33.createElement(
14645
+ right: /* @__PURE__ */ React34.createElement("span", { style: { display: "flex", gap: "10px" } }, /* @__PURE__ */ React34.createElement(
14296
14646
  StateInspectorButton,
14297
14647
  {
14298
14648
  theme: theme3,
@@ -14307,7 +14657,7 @@ var StateInspector = memoGeneric(function StateInspector2({
14307
14657
  }
14308
14658
  },
14309
14659
  "Delete all"
14310
- ), /* @__PURE__ */ React33.createElement(
14660
+ ), /* @__PURE__ */ React34.createElement(
14311
14661
  StateInspectorButton,
14312
14662
  {
14313
14663
  theme: theme3,
@@ -14320,54 +14670,69 @@ var StateInspector = memoGeneric(function StateInspector2({
14320
14670
  }
14321
14671
  },
14322
14672
  "Reload"
14323
- ), /* @__PURE__ */ React33.createElement(
14673
+ ), /* @__PURE__ */ React34.createElement(
14324
14674
  StateInspectorButton,
14325
14675
  {
14326
14676
  theme: theme3,
14327
- onClick: () => {
14328
- const input = document.createElement("input");
14329
- input.type = "file";
14330
- input.onchange = () => {
14331
- const file = input.files?.[0];
14332
- if (file) {
14333
- const reader = new FileReader();
14334
- reader.onload = () => {
14335
- const buffer = reader.result;
14336
- assetManager.create(new Uint8Array(buffer));
14337
- };
14338
- reader.readAsArrayBuffer(file);
14339
- }
14340
- };
14341
- input.click();
14677
+ onClick: async () => {
14678
+ const file = await uploadFile();
14679
+ assetManager.create(file);
14342
14680
  }
14343
14681
  },
14344
14682
  "Upload"
14683
+ ), /* @__PURE__ */ React34.createElement(
14684
+ StateInspectorButton,
14685
+ {
14686
+ theme: theme3,
14687
+ onClick: async () => {
14688
+ const file = await uploadFile();
14689
+ assetManager.create({
14690
+ data: new Uint8Array(await file.arrayBuffer()),
14691
+ contentType: file.type,
14692
+ mode: "mutable"
14693
+ });
14694
+ }
14695
+ },
14696
+ "Upload Mutable"
14345
14697
  ))
14346
14698
  },
14347
- /* @__PURE__ */ React33.createElement(StateInspectorDisclosureRowInner, null, assets.map((asset) => /* @__PURE__ */ React33.createElement(StateInspectorRow, { key: asset.id, colorScheme }, /* @__PURE__ */ React33.createElement(
14699
+ /* @__PURE__ */ React34.createElement(StateInspectorDisclosureRowInner, null, assets.map((asset) => /* @__PURE__ */ React34.createElement(StateInspectorRow, { key: asset.id, colorScheme }, /* @__PURE__ */ React34.createElement(
14348
14700
  themedObjectInspector,
14349
14701
  {
14350
14702
  name: asset.id,
14351
14703
  data: truncateAsset(asset),
14352
14704
  theme: theme3
14353
14705
  }
14354
- ), /* @__PURE__ */ React33.createElement(
14706
+ ), /* @__PURE__ */ React34.createElement("div", { style: { display: "flex", gap: "4px" } }, asset.mode === "mutable" && /* @__PURE__ */ React34.createElement(
14707
+ StateInspectorButton,
14708
+ {
14709
+ theme: theme3,
14710
+ onClick: async () => {
14711
+ const file = await uploadFile();
14712
+ assetManager.update(asset.id, {
14713
+ data: new Uint8Array(await file.arrayBuffer()),
14714
+ contentType: file.type
14715
+ });
14716
+ }
14717
+ },
14718
+ "Replace"
14719
+ ), /* @__PURE__ */ React34.createElement(
14355
14720
  StateInspectorButton,
14356
14721
  {
14357
14722
  theme: theme3,
14358
14723
  onClick: () => assetManager.delete(asset.id)
14359
14724
  },
14360
14725
  "Delete"
14361
- ))))
14726
+ )))))
14362
14727
  ),
14363
- advanced && /* @__PURE__ */ React33.createElement(
14728
+ advanced && /* @__PURE__ */ React34.createElement(
14364
14729
  StateInspectorDisclosureSection,
14365
14730
  {
14366
- title: /* @__PURE__ */ React33.createElement(StateInspectorTitleLabel, null, "Resources (", resources.length, ")", /* @__PURE__ */ React33.createElement(ColoredDot, { type: resourcesInitialized ? "success" : "error" })),
14731
+ title: /* @__PURE__ */ React34.createElement(StateInspectorTitleLabel, null, "Resources (", resources.length, ")", /* @__PURE__ */ React34.createElement(ColoredDot, { type: resourcesInitialized ? "success" : "error" })),
14367
14732
  colorScheme,
14368
14733
  open: showResources,
14369
14734
  setOpen: setShowResources,
14370
- right: /* @__PURE__ */ React33.createElement("span", { style: { display: "flex", gap: "10px" } }, /* @__PURE__ */ React33.createElement(
14735
+ right: /* @__PURE__ */ React34.createElement("span", { style: { display: "flex", gap: "10px" } }, /* @__PURE__ */ React34.createElement(
14371
14736
  StateInspectorButton,
14372
14737
  {
14373
14738
  theme: theme3,
@@ -14382,7 +14747,7 @@ var StateInspector = memoGeneric(function StateInspector2({
14382
14747
  }
14383
14748
  },
14384
14749
  "Delete all"
14385
- ), /* @__PURE__ */ React33.createElement(
14750
+ ), /* @__PURE__ */ React34.createElement(
14386
14751
  StateInspectorButton,
14387
14752
  {
14388
14753
  theme: theme3,
@@ -14395,7 +14760,7 @@ var StateInspector = memoGeneric(function StateInspector2({
14395
14760
  }
14396
14761
  },
14397
14762
  "Create Directory"
14398
- ), /* @__PURE__ */ React33.createElement(
14763
+ ), /* @__PURE__ */ React34.createElement(
14399
14764
  StateInspectorButton,
14400
14765
  {
14401
14766
  theme: theme3,
@@ -14415,21 +14780,21 @@ var StateInspector = memoGeneric(function StateInspector2({
14415
14780
  "Create Asset"
14416
14781
  ))
14417
14782
  },
14418
- /* @__PURE__ */ React33.createElement(StateInspectorDisclosureRowInner, null, resources?.map((resource) => /* @__PURE__ */ React33.createElement(StateInspectorRow, { key: resource.id, colorScheme }, /* @__PURE__ */ React33.createElement(
14783
+ /* @__PURE__ */ React34.createElement(StateInspectorDisclosureRowInner, null, resources?.map((resource) => /* @__PURE__ */ React34.createElement(StateInspectorRow, { key: resource.id, colorScheme }, /* @__PURE__ */ React34.createElement(
14419
14784
  themedObjectInspector,
14420
14785
  {
14421
14786
  name: resource.path,
14422
14787
  data: resource,
14423
14788
  theme: theme3
14424
14789
  }
14425
- ), /* @__PURE__ */ React33.createElement("div", { style: { display: "flex", gap: "4px" } }, /* @__PURE__ */ React33.createElement(
14790
+ ), /* @__PURE__ */ React34.createElement("div", { style: { display: "flex", gap: "4px" } }, /* @__PURE__ */ React34.createElement(
14426
14791
  StateInspectorButton,
14427
14792
  {
14428
14793
  theme: theme3,
14429
14794
  onClick: () => resourceManager.deleteResource({ id: resource.id })
14430
14795
  },
14431
14796
  "Delete"
14432
- ), /* @__PURE__ */ React33.createElement(
14797
+ ), /* @__PURE__ */ React34.createElement(
14433
14798
  StateInspectorButton,
14434
14799
  {
14435
14800
  theme: theme3,
@@ -14442,14 +14807,23 @@ var StateInspector = memoGeneric(function StateInspector2({
14442
14807
  "Rename"
14443
14808
  )))))
14444
14809
  ),
14445
- advanced && /* @__PURE__ */ React33.createElement(
14810
+ advanced && /* @__PURE__ */ React34.createElement(
14446
14811
  StateInspectorDisclosureSection,
14447
14812
  {
14448
- title: /* @__PURE__ */ React33.createElement(StateInspectorTitleLabel, null, "Secrets", /* @__PURE__ */ React33.createElement(ColoredDot, { type: secretsInitialized ? "success" : "error" })),
14813
+ title: /* @__PURE__ */ React34.createElement(StateInspectorTitleLabel, null, "Secrets (", secrets.length, ")", /* @__PURE__ */ React34.createElement(ColoredDot, { type: secretsInitialized ? "success" : "error" })),
14449
14814
  colorScheme,
14450
14815
  open: showSecrets,
14451
14816
  setOpen: setShowSecrets,
14452
- right: /* @__PURE__ */ React33.createElement(
14817
+ right: /* @__PURE__ */ React34.createElement("span", { style: { display: "flex", gap: "10px" } }, /* @__PURE__ */ React34.createElement(
14818
+ StateInspectorButton,
14819
+ {
14820
+ theme: theme3,
14821
+ onClick: () => {
14822
+ void secretManager.fetchSecrets();
14823
+ }
14824
+ },
14825
+ "Refresh"
14826
+ ), /* @__PURE__ */ React34.createElement(
14453
14827
  StateInspectorButton,
14454
14828
  {
14455
14829
  theme: theme3,
@@ -14462,9 +14836,9 @@ var StateInspector = memoGeneric(function StateInspector2({
14462
14836
  }
14463
14837
  },
14464
14838
  "Create"
14465
- )
14839
+ ))
14466
14840
  },
14467
- /* @__PURE__ */ React33.createElement(StateInspectorDisclosureRowInner, null, secrets.map((secret) => /* @__PURE__ */ React33.createElement(StateInspectorRow, { key: secret.id, colorScheme }, /* @__PURE__ */ React33.createElement(themedObjectInspector, { data: secret, theme: theme3 }), /* @__PURE__ */ React33.createElement(
14841
+ /* @__PURE__ */ React34.createElement(StateInspectorDisclosureRowInner, null, secrets.map((secret) => /* @__PURE__ */ React34.createElement(StateInspectorRow, { key: secret.id, colorScheme }, /* @__PURE__ */ React34.createElement(themedObjectInspector, { data: secret, theme: theme3 }), /* @__PURE__ */ React34.createElement(
14468
14842
  StateInspectorButton,
14469
14843
  {
14470
14844
  theme: theme3,
@@ -14473,15 +14847,24 @@ var StateInspector = memoGeneric(function StateInspector2({
14473
14847
  "Delete"
14474
14848
  ))))
14475
14849
  ),
14476
- advanced && /* @__PURE__ */ React33.createElement(
14850
+ advanced && /* @__PURE__ */ React34.createElement(
14851
+ GitSection,
14852
+ {
14853
+ showGit,
14854
+ setShowGit,
14855
+ colorScheme,
14856
+ gitManager
14857
+ }
14858
+ ),
14859
+ advanced && /* @__PURE__ */ React34.createElement(
14477
14860
  StateInspectorDisclosureSection,
14478
14861
  {
14479
14862
  open: showInputs,
14480
14863
  setOpen: setShowInputs,
14481
- title: /* @__PURE__ */ React33.createElement(StateInspectorTitleLabel, null, "Inputs", /* @__PURE__ */ React33.createElement(ColoredDot, { type: inputsInitialized ? "success" : "error" })),
14864
+ title: /* @__PURE__ */ React34.createElement(StateInspectorTitleLabel, null, "Inputs (", inputs.length, ")", /* @__PURE__ */ React34.createElement(ColoredDot, { type: inputsInitialized ? "success" : "error" })),
14482
14865
  colorScheme
14483
14866
  },
14484
- /* @__PURE__ */ React33.createElement(StateInspectorDisclosureRowInner, null, inputs?.map((input) => /* @__PURE__ */ React33.createElement(StateInspectorRow, { key: input.id, colorScheme }, /* @__PURE__ */ React33.createElement(themedObjectInspector, { data: input, theme: theme3 }))), !inputs?.length && /* @__PURE__ */ React33.createElement(
14867
+ /* @__PURE__ */ React34.createElement(StateInspectorDisclosureRowInner, null, inputs?.map((input) => /* @__PURE__ */ React34.createElement(StateInspectorRow, { key: input.id, colorScheme }, /* @__PURE__ */ React34.createElement(themedObjectInspector, { data: input, theme: theme3 }))), !inputs?.length && /* @__PURE__ */ React34.createElement(
14485
14868
  "div",
14486
14869
  {
14487
14870
  style: {
@@ -14492,15 +14875,15 @@ var StateInspector = memoGeneric(function StateInspector2({
14492
14875
  gap: "4px"
14493
14876
  }
14494
14877
  },
14495
- /* @__PURE__ */ React33.createElement("span", null, "No inputs")
14878
+ /* @__PURE__ */ React34.createElement("span", null, "No inputs")
14496
14879
  ))
14497
14880
  ),
14498
- advanced && /* @__PURE__ */ React33.createElement(
14881
+ advanced && /* @__PURE__ */ React34.createElement(
14499
14882
  StateInspectorDisclosureSection,
14500
14883
  {
14501
14884
  open: showOutputTransforms,
14502
14885
  setOpen: setShowOutputTransforms,
14503
- title: /* @__PURE__ */ React33.createElement(StateInspectorTitleLabel, null, "Output Transforms", /* @__PURE__ */ React33.createElement(
14886
+ title: /* @__PURE__ */ React34.createElement(StateInspectorTitleLabel, null, "Output Transforms (", outputTransforms.length, ")", /* @__PURE__ */ React34.createElement(
14504
14887
  ColoredDot,
14505
14888
  {
14506
14889
  type: outputTransformsInitialized ? "success" : "error"
@@ -14508,7 +14891,7 @@ var StateInspector = memoGeneric(function StateInspector2({
14508
14891
  )),
14509
14892
  colorScheme
14510
14893
  },
14511
- /* @__PURE__ */ React33.createElement(StateInspectorDisclosureRowInner, null, outputTransforms?.map((transform) => /* @__PURE__ */ React33.createElement(StateInspectorRow, { key: transform.id, colorScheme }, /* @__PURE__ */ React33.createElement(themedObjectInspector, { data: transform, theme: theme3 }))), !outputTransforms?.length && /* @__PURE__ */ React33.createElement(
14894
+ /* @__PURE__ */ React34.createElement(StateInspectorDisclosureRowInner, null, outputTransforms?.map((transform) => /* @__PURE__ */ React34.createElement(StateInspectorRow, { key: transform.id, colorScheme }, /* @__PURE__ */ React34.createElement(themedObjectInspector, { data: transform, theme: theme3 }))), !outputTransforms?.length && /* @__PURE__ */ React34.createElement(
14512
14895
  "div",
14513
14896
  {
14514
14897
  style: {
@@ -14519,10 +14902,10 @@ var StateInspector = memoGeneric(function StateInspector2({
14519
14902
  gap: "4px"
14520
14903
  }
14521
14904
  },
14522
- /* @__PURE__ */ React33.createElement("span", null, "No output transforms")
14905
+ /* @__PURE__ */ React34.createElement("span", null, "No output transforms")
14523
14906
  ))
14524
14907
  ),
14525
- advanced && /* @__PURE__ */ React33.createElement(
14908
+ advanced && /* @__PURE__ */ React34.createElement(
14526
14909
  StateInspectorDisclosureSection,
14527
14910
  {
14528
14911
  title: "Tasks",
@@ -14530,7 +14913,7 @@ var StateInspector = memoGeneric(function StateInspector2({
14530
14913
  open: showTasks,
14531
14914
  setOpen: setShowTasks
14532
14915
  },
14533
- /* @__PURE__ */ React33.createElement(StateInspectorDisclosureRowInner, null, tasks?.map((task) => /* @__PURE__ */ React33.createElement(
14916
+ /* @__PURE__ */ React34.createElement(StateInspectorDisclosureRowInner, null, tasks?.map((task) => /* @__PURE__ */ React34.createElement(
14534
14917
  StateInspectorRow,
14535
14918
  {
14536
14919
  key: task.id,
@@ -14539,7 +14922,7 @@ var StateInspector = memoGeneric(function StateInspector2({
14539
14922
  backgroundColor: task.status === "done" ? "rgba(0,255,0,0.2)" : task.status === "error" ? "rgba(255,0,0,0.2)" : void 0
14540
14923
  }
14541
14924
  },
14542
- /* @__PURE__ */ React33.createElement(
14925
+ /* @__PURE__ */ React34.createElement(
14543
14926
  themedObjectInspector,
14544
14927
  {
14545
14928
  name: task.name,
@@ -14549,7 +14932,7 @@ var StateInspector = memoGeneric(function StateInspector2({
14549
14932
  )
14550
14933
  )))
14551
14934
  ),
14552
- /* @__PURE__ */ React33.createElement(
14935
+ /* @__PURE__ */ React34.createElement(
14553
14936
  StateInspectorDisclosureSection,
14554
14937
  {
14555
14938
  open: showShared,
@@ -14557,7 +14940,7 @@ var StateInspector = memoGeneric(function StateInspector2({
14557
14940
  title: "Shared Connection Data",
14558
14941
  colorScheme
14559
14942
  },
14560
- /* @__PURE__ */ React33.createElement(StateInspectorDisclosureRowInner, null, Object.entries(shared).map(([key, value]) => /* @__PURE__ */ React33.createElement(StateInspectorRow, { key, colorScheme }, /* @__PURE__ */ React33.createElement(
14943
+ /* @__PURE__ */ React34.createElement(StateInspectorDisclosureRowInner, null, Object.entries(shared).map(([key, value]) => /* @__PURE__ */ React34.createElement(StateInspectorRow, { key, colorScheme }, /* @__PURE__ */ React34.createElement(
14561
14944
  themedObjectInspector,
14562
14945
  {
14563
14946
  name: key,
@@ -14567,7 +14950,7 @@ var StateInspector = memoGeneric(function StateInspector2({
14567
14950
  }
14568
14951
  ))))
14569
14952
  ),
14570
- /* @__PURE__ */ React33.createElement(
14953
+ /* @__PURE__ */ React34.createElement(
14571
14954
  ServerScriptLogsSection,
14572
14955
  {
14573
14956
  colorScheme,
@@ -14579,7 +14962,7 @@ var StateInspector = memoGeneric(function StateInspector2({
14579
14962
  containerRef: serverLogsContainerRef
14580
14963
  }
14581
14964
  ),
14582
- showSimulationLogsSection && /* @__PURE__ */ React33.createElement(
14965
+ showSimulationLogsSection && /* @__PURE__ */ React34.createElement(
14583
14966
  ServerScriptLogsSection,
14584
14967
  {
14585
14968
  title: "Server Script Simulation Logs",
@@ -14592,7 +14975,7 @@ var StateInspector = memoGeneric(function StateInspector2({
14592
14975
  containerRef: serverSimulationLogsContainerRef
14593
14976
  }
14594
14977
  ),
14595
- /* @__PURE__ */ React33.createElement(
14978
+ /* @__PURE__ */ React34.createElement(
14596
14979
  StateInspectorDisclosureSection,
14597
14980
  {
14598
14981
  open: showSimulation,
@@ -14600,7 +14983,7 @@ var StateInspector = memoGeneric(function StateInspector2({
14600
14983
  title: "Server Simulation",
14601
14984
  colorScheme
14602
14985
  },
14603
- /* @__PURE__ */ React33.createElement(StateInspectorDisclosureRowInner, null, /* @__PURE__ */ React33.createElement(StateInspectorRow, { colorScheme }, /* @__PURE__ */ React33.createElement(
14986
+ /* @__PURE__ */ React34.createElement(StateInspectorDisclosureRowInner, null, /* @__PURE__ */ React34.createElement(StateInspectorRow, { colorScheme }, /* @__PURE__ */ React34.createElement(
14604
14987
  themedObjectInspector,
14605
14988
  {
14606
14989
  name: "status",
@@ -14616,7 +14999,7 @@ var StateInspector = memoGeneric(function StateInspector2({
14616
14999
  }
14617
15000
  )))
14618
15001
  ),
14619
- advanced && /* @__PURE__ */ React33.createElement(
15002
+ advanced && /* @__PURE__ */ React34.createElement(
14620
15003
  ActivityEventsSection,
14621
15004
  {
14622
15005
  colorScheme,
@@ -14626,7 +15009,7 @@ var StateInspector = memoGeneric(function StateInspector2({
14626
15009
  activityEventsManager
14627
15010
  }
14628
15011
  ),
14629
- /* @__PURE__ */ React33.createElement(
15012
+ /* @__PURE__ */ React34.createElement(
14630
15013
  EventsSection,
14631
15014
  {
14632
15015
  connectionEvents: visibleConnectionEvents,
@@ -14640,7 +15023,7 @@ var StateInspector = memoGeneric(function StateInspector2({
14640
15023
  )
14641
15024
  );
14642
15025
  });
14643
- var truncateAsset = memoize2((asset) => {
15026
+ var truncateAsset = memoize((asset) => {
14644
15027
  if (asset.url.startsWith("data:") || asset.url.startsWith("blob:")) {
14645
15028
  return { ...asset, url: ellipsis(asset.url, 40) };
14646
15029
  }
@@ -14657,15 +15040,15 @@ function useManagedHistory(stateManager) {
14657
15040
  }
14658
15041
 
14659
15042
  // ../noya-multiplayer-react/src/singleton.tsx
14660
- import React35 from "react";
15043
+ import React36 from "react";
14661
15044
 
14662
15045
  // ../noya-multiplayer-react/src/NoyaStateContext.tsx
14663
15046
  var AnyNoyaStateContext = createContext3(void 0);
14664
15047
  var emptyArray = [];
14665
15048
  function useActivityEventsForManager(streamFilter, activityEventsManager) {
14666
- const [streamId, setStreamId] = useState17(void 0);
15049
+ const [streamId, setStreamId] = useState18(void 0);
14667
15050
  const stableStreamFilter = useJsonMemo(streamFilter);
14668
- useEffect16(() => {
15051
+ useEffect17(() => {
14669
15052
  if (!stableStreamFilter) return;
14670
15053
  const streamId2 = activityEventsManager.subscribe(stableStreamFilter);
14671
15054
  setStreamId(streamId2);
@@ -14679,8 +15062,8 @@ function useActivityEventsForManager(streamFilter, activityEventsManager) {
14679
15062
  }
14680
15063
 
14681
15064
  // ../noya-multiplayer-react/src/components/UserPointersOverlay.tsx
14682
- import { Observable as Observable23 } from "@noya-app/observable";
14683
- import React37, { useEffect as useEffect18, useMemo as useMemo12, useState as useState18 } from "react";
15065
+ import { Observable as Observable24 } from "@noya-app/observable";
15066
+ import React38, { useEffect as useEffect19, useMemo as useMemo12, useState as useState19 } from "react";
14684
15067
  function shouldShow(hideAfter, updatedAt) {
14685
15068
  return !!updatedAt && Date.now() - updatedAt < hideAfter;
14686
15069
  }
@@ -14693,15 +15076,15 @@ var UserPointerInternal = memoGeneric(function UserPointerInternal2({
14693
15076
  const observable = useMemo12(() => {
14694
15077
  const metadata$ = sharedConnectionDataManager.metadata$.observePath([user.connectionId]).throttle(50);
14695
15078
  const data$ = sharedConnectionDataManager.data$.observePath([user.connectionId]).throttle(50);
14696
- return Observable23.combine([metadata$, data$], ([metadata2, data2]) => {
15079
+ return Observable24.combine([metadata$, data$], ([metadata2, data2]) => {
14697
15080
  return { metadata: metadata2, data: data2 };
14698
15081
  });
14699
15082
  }, [sharedConnectionDataManager, user.connectionId]);
14700
15083
  const { metadata, data } = useObservable2(observable);
14701
- const [, setForceUpdate] = useState18(0);
15084
+ const [, setForceUpdate] = useState19(0);
14702
15085
  const updatedAt = metadata?.updatedAt ?? 0;
14703
15086
  const show = shouldShow(hideAfter, updatedAt);
14704
- useEffect18(() => {
15087
+ useEffect19(() => {
14705
15088
  if (!show) return;
14706
15089
  const timeoutId = setTimeout(() => {
14707
15090
  setForceUpdate((prev) => prev + 1);
@@ -14725,9 +15108,9 @@ var UserPointersOverlay = memoGeneric(function UserPointers({
14725
15108
  sharedConnectionDataManager.currentConnectionId$
14726
15109
  );
14727
15110
  const connectedUsers = useObservable2(userManager.connectedUsers$);
14728
- return /* @__PURE__ */ React37.createElement(React37.Fragment, null, connectedUsers.map((user) => {
15111
+ return /* @__PURE__ */ React38.createElement(React38.Fragment, null, connectedUsers.map((user) => {
14729
15112
  if (user.connectionId === currentConnectionId) return null;
14730
- return /* @__PURE__ */ React37.createElement(
15113
+ return /* @__PURE__ */ React38.createElement(
14731
15114
  UserPointerInternal,
14732
15115
  {
14733
15116
  key: user.connectionId,
@@ -14743,7 +15126,7 @@ var UserPointersOverlay = memoGeneric(function UserPointers({
14743
15126
  import {
14744
15127
  RefetchableObservable
14745
15128
  } from "@noya-app/observable-store";
14746
- import { useCallback as useCallback15, useEffect as useEffect19, useMemo as useMemo13 } from "react";
15129
+ import { useCallback as useCallback15, useEffect as useEffect20, useMemo as useMemo13 } from "react";
14747
15130
  function useTable(table, {
14748
15131
  where,
14749
15132
  select
@@ -14787,7 +15170,7 @@ function useTable(table, {
14787
15170
  }
14788
15171
  );
14789
15172
  }, [stableSelect, stableWhere, table, options.policy, options.debug]);
14790
- useEffect19(() => {
15173
+ useEffect20(() => {
14791
15174
  observable.start?.();
14792
15175
  }, [observable]);
14793
15176
  const { status, data } = useObservable2(observable);
@@ -14886,11 +15269,6 @@ export {
14886
15269
  useActivityEventsList,
14887
15270
  useFileList,
14888
15271
  useFileListItem,
14889
- useGeneratedComponentDescription,
14890
- useGeneratedComponentDescriptions,
14891
- useGeneratedComponentNames,
14892
- useGeneratedPageComponentNames,
14893
- useGeneratedPageNames,
14894
15272
  useIsBeta,
14895
15273
  useMetadata,
14896
15274
  useNetworkRequests,
@@ -14915,6 +15293,7 @@ export {
14915
15293
  useNoyaUserData,
14916
15294
  useNoyaWorkspaceBilling,
14917
15295
  useNoyaWorkspaceInvitations,
15296
+ useNoyaWorkspaceMembers,
14918
15297
  useNoyaWorkspaces,
14919
15298
  useOptionalNoyaClient,
14920
15299
  useOptionalNoyaCreators,
@@ -14922,8 +15301,6 @@ export {
14922
15301
  useOptionalNoyaTags,
14923
15302
  useOptionalNoyaTools,
14924
15303
  useOptionalNoyaUserData,
14925
- useRandomIcons,
14926
- useRandomImages,
14927
15304
  useResourcesList,
14928
15305
  useTable,
14929
15306
  useUser