@noya-app/noya-multiplayer-react 0.1.62 → 0.1.63
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/.turbo/turbo-build.log +11 -11
- package/CHANGELOG.md +10 -0
- package/dist/index.bundle.js +50 -17
- package/dist/index.d.mts +62 -22
- package/dist/index.d.ts +62 -22
- package/dist/index.js +1352 -585
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1350 -593
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
- package/src/NoyaStateContext.tsx +23 -9
- package/src/__tests__/serialize.test.ts +126 -0
- package/src/ai.ts +2 -0
- package/src/index.ts +1 -0
- package/src/inspector/ColoredDot.tsx +17 -0
- package/src/inspector/ObjectRootLabel.tsx +48 -0
- package/src/inspector/StateInspector.tsx +125 -721
- package/src/inspector/StateInspectorArrow.tsx +28 -0
- package/src/inspector/StateInspectorButton.tsx +45 -0
- package/src/inspector/StateInspectorDisclosureSection.tsx +97 -0
- package/src/inspector/StateInspectorRow.tsx +57 -0
- package/src/inspector/StateInspectorToggleButton.tsx +82 -0
- package/src/inspector/inspectorTheme.ts +21 -0
- package/src/inspector/sections/EventsSection.tsx +89 -0
- package/src/inspector/sections/HistorySection.tsx +236 -0
- package/src/inspector/serialization.ts +202 -0
- package/src/inspector/utils.ts +60 -0
- package/src/inspector/zip/TinyZip.ts +464 -0
- package/src/inspector/zip/crc32.ts +16 -0
- package/src/inspector/zip/struct.ts +117 -0
- package/src/noyaApp.ts +2 -1
- package/src/useObservable.ts +2 -0
package/dist/index.mjs
CHANGED
|
@@ -1108,18 +1108,18 @@ var require_lib = __commonJS({
|
|
|
1108
1108
|
export * from "@noya-app/state-manager";
|
|
1109
1109
|
|
|
1110
1110
|
// src/ai.ts
|
|
1111
|
-
import { useEffect as
|
|
1111
|
+
import { useEffect as useEffect5 } from "react";
|
|
1112
1112
|
|
|
1113
1113
|
// src/NoyaStateContext.tsx
|
|
1114
1114
|
import {
|
|
1115
1115
|
Observable
|
|
1116
1116
|
} from "@noya-app/observable";
|
|
1117
1117
|
import { useStableCallback } from "@noya-app/react-utils";
|
|
1118
|
-
import
|
|
1118
|
+
import React14, {
|
|
1119
1119
|
createContext,
|
|
1120
|
-
useCallback as
|
|
1120
|
+
useCallback as useCallback3,
|
|
1121
1121
|
useContext,
|
|
1122
|
-
useEffect as
|
|
1122
|
+
useEffect as useEffect4,
|
|
1123
1123
|
useMemo as useMemo4
|
|
1124
1124
|
} from "react";
|
|
1125
1125
|
|
|
@@ -3547,6 +3547,71 @@ function Void(options = {}) {
|
|
|
3547
3547
|
// ../../node_modules/@sinclair/typebox/build/esm/type/type/index.mjs
|
|
3548
3548
|
var Type = type_exports3;
|
|
3549
3549
|
|
|
3550
|
+
// ../noya-schemas/src/asset.ts
|
|
3551
|
+
var assetSchema = Type.Object({
|
|
3552
|
+
id: Type.String(),
|
|
3553
|
+
url: Type.String(),
|
|
3554
|
+
createdAt: Type.String(),
|
|
3555
|
+
size: Type.Number(),
|
|
3556
|
+
contentType: Type.Optional(Type.String())
|
|
3557
|
+
});
|
|
3558
|
+
|
|
3559
|
+
// ../noya-schemas/src/encode.ts
|
|
3560
|
+
var SchemaMap = /* @__PURE__ */ new Map([
|
|
3561
|
+
[Kind, "_kind"],
|
|
3562
|
+
[Hint, "_hint"]
|
|
3563
|
+
]);
|
|
3564
|
+
var InverseSchemaMap = new Map(
|
|
3565
|
+
Array.from(SchemaMap.entries()).map(([key, value]) => [value, key])
|
|
3566
|
+
);
|
|
3567
|
+
function encodeSchema(obj, symMap = SchemaMap) {
|
|
3568
|
+
function replaceSymbols(item) {
|
|
3569
|
+
if (Array.isArray(item)) {
|
|
3570
|
+
return item.map(replaceSymbols);
|
|
3571
|
+
} else if (typeof item === "object" && item !== null) {
|
|
3572
|
+
const newObj = {};
|
|
3573
|
+
for (const key in item) {
|
|
3574
|
+
if (Object.prototype.hasOwnProperty.call(item, key)) {
|
|
3575
|
+
const value = item[key];
|
|
3576
|
+
newObj[key] = replaceSymbols(value);
|
|
3577
|
+
}
|
|
3578
|
+
}
|
|
3579
|
+
for (const sym of Object.getOwnPropertySymbols(item)) {
|
|
3580
|
+
const stringKey = symMap.get(sym);
|
|
3581
|
+
if (stringKey) {
|
|
3582
|
+
newObj[stringKey] = replaceSymbols(item[sym]);
|
|
3583
|
+
}
|
|
3584
|
+
}
|
|
3585
|
+
return newObj;
|
|
3586
|
+
}
|
|
3587
|
+
return item;
|
|
3588
|
+
}
|
|
3589
|
+
return replaceSymbols(obj);
|
|
3590
|
+
}
|
|
3591
|
+
function decodeSchema(obj, strMap = InverseSchemaMap) {
|
|
3592
|
+
function replaceStringKeys(item) {
|
|
3593
|
+
if (Array.isArray(item)) {
|
|
3594
|
+
return item.map(replaceStringKeys);
|
|
3595
|
+
} else if (typeof item === "object" && item !== null) {
|
|
3596
|
+
const newObj = {};
|
|
3597
|
+
for (const key in item) {
|
|
3598
|
+
if (Object.prototype.hasOwnProperty.call(item, key)) {
|
|
3599
|
+
const value = item[key];
|
|
3600
|
+
const symbolKey = strMap.get(key);
|
|
3601
|
+
if (symbolKey) {
|
|
3602
|
+
newObj[symbolKey] = replaceStringKeys(value);
|
|
3603
|
+
} else {
|
|
3604
|
+
newObj[key] = replaceStringKeys(value);
|
|
3605
|
+
}
|
|
3606
|
+
}
|
|
3607
|
+
}
|
|
3608
|
+
return newObj;
|
|
3609
|
+
}
|
|
3610
|
+
return item;
|
|
3611
|
+
}
|
|
3612
|
+
return replaceStringKeys(obj);
|
|
3613
|
+
}
|
|
3614
|
+
|
|
3550
3615
|
// ../noya-schemas/src/filesSchema.ts
|
|
3551
3616
|
var encodingSchema = Type.Union([
|
|
3552
3617
|
Type.Literal("utf-8"),
|
|
@@ -3567,8 +3632,13 @@ var fileSchema = Type.Object({
|
|
|
3567
3632
|
content: Type.String(),
|
|
3568
3633
|
encoding: encodingSchema
|
|
3569
3634
|
});
|
|
3635
|
+
var noyaFileSchema = Type.Object({
|
|
3636
|
+
id: Type.String({ format: "uuid", default: "" }),
|
|
3637
|
+
kind: Type.Literal("noyaFile"),
|
|
3638
|
+
fileId: Type.String()
|
|
3639
|
+
});
|
|
3570
3640
|
var mediaItemSchema = Type.Union(
|
|
3571
|
-
[folderMediaItemSchema, assetMediaItemSchema, fileSchema],
|
|
3641
|
+
[folderMediaItemSchema, assetMediaItemSchema, fileSchema, noyaFileSchema],
|
|
3572
3642
|
{
|
|
3573
3643
|
discriminator: "kind"
|
|
3574
3644
|
}
|
|
@@ -3922,16 +3992,16 @@ import { useMemo as useMemo3, useState as useState2 } from "react";
|
|
|
3922
3992
|
|
|
3923
3993
|
// src/hooks.ts
|
|
3924
3994
|
import {
|
|
3925
|
-
NoyaManager,
|
|
3995
|
+
NoyaManager as NoyaManager2,
|
|
3926
3996
|
StateManager,
|
|
3927
3997
|
stubSync
|
|
3928
3998
|
} from "@noya-app/state-manager";
|
|
3929
3999
|
import {
|
|
3930
4000
|
createElement as createElement2,
|
|
3931
|
-
useCallback,
|
|
3932
|
-
useEffect as
|
|
4001
|
+
useCallback as useCallback2,
|
|
4002
|
+
useEffect as useEffect3,
|
|
3933
4003
|
useMemo as useMemo2,
|
|
3934
|
-
useRef,
|
|
4004
|
+
useRef as useRef2,
|
|
3935
4005
|
useState,
|
|
3936
4006
|
useSyncExternalStore as useSyncExternalStore2
|
|
3937
4007
|
} from "react";
|
|
@@ -4012,24 +4082,18 @@ var ErrorOverlay = React.memo(function ErrorOverlay2({
|
|
|
4012
4082
|
});
|
|
4013
4083
|
|
|
4014
4084
|
// src/inspector/useStateInspector.tsx
|
|
4015
|
-
import
|
|
4085
|
+
import React13 from "react";
|
|
4016
4086
|
import { createRoot } from "react-dom/client";
|
|
4017
4087
|
import { useIsomorphicLayoutEffect } from "@noya-app/react-utils";
|
|
4018
4088
|
|
|
4019
4089
|
// src/inspector/StateInspector.tsx
|
|
4020
|
-
import { memoGeneric } from "@noya-app/react-utils";
|
|
4021
|
-
import
|
|
4022
|
-
|
|
4090
|
+
import { downloadBlob, memoGeneric } from "@noya-app/react-utils";
|
|
4091
|
+
import React12, {
|
|
4092
|
+
useCallback,
|
|
4093
|
+
useEffect as useEffect2,
|
|
4023
4094
|
useLayoutEffect
|
|
4024
4095
|
} from "react";
|
|
4025
|
-
import {
|
|
4026
|
-
ObjectInspector,
|
|
4027
|
-
ObjectLabel,
|
|
4028
|
-
ObjectName,
|
|
4029
|
-
ObjectPreview,
|
|
4030
|
-
chromeDark,
|
|
4031
|
-
chromeLight
|
|
4032
|
-
} from "react-inspector";
|
|
4096
|
+
import { ObjectInspector as ObjectInspector3 } from "react-inspector";
|
|
4033
4097
|
|
|
4034
4098
|
// src/useObservable.ts
|
|
4035
4099
|
import { useMemo, useSyncExternalStore } from "react";
|
|
@@ -4058,119 +4122,110 @@ function useObservable(observable, pathOrSelector, options) {
|
|
|
4058
4122
|
return useSyncExternalStore(listen, get, get);
|
|
4059
4123
|
}
|
|
4060
4124
|
|
|
4061
|
-
// src/inspector/
|
|
4125
|
+
// src/inspector/ColoredDot.tsx
|
|
4062
4126
|
import React2 from "react";
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4127
|
+
function ColoredDot({ type }) {
|
|
4128
|
+
return /* @__PURE__ */ React2.createElement(
|
|
4129
|
+
"span",
|
|
4130
|
+
{
|
|
4131
|
+
style: {
|
|
4132
|
+
display: "inline-block",
|
|
4133
|
+
width: 6,
|
|
4134
|
+
height: 6,
|
|
4135
|
+
background: type === "success" ? "rgba(0,200,0,0.8)" : "rgba(200,0,0,0.8)",
|
|
4136
|
+
borderRadius: "50%",
|
|
4137
|
+
verticalAlign: "middle"
|
|
4073
4138
|
}
|
|
4074
4139
|
}
|
|
4075
|
-
|
|
4076
|
-
});
|
|
4077
|
-
const setLocalStorageState = (value) => {
|
|
4078
|
-
localStorage?.setItem(key, JSON.stringify(value));
|
|
4079
|
-
setState(value);
|
|
4080
|
-
};
|
|
4081
|
-
return [state, setLocalStorageState];
|
|
4140
|
+
);
|
|
4082
4141
|
}
|
|
4083
4142
|
|
|
4084
|
-
// src/inspector/
|
|
4085
|
-
|
|
4143
|
+
// src/inspector/inspectorTheme.ts
|
|
4144
|
+
import { chromeDark, chromeLight } from "react-inspector";
|
|
4145
|
+
var lightInspectorTheme = {
|
|
4086
4146
|
...chromeLight,
|
|
4087
4147
|
BASE_BACKGROUND_COLOR: "transparent",
|
|
4088
4148
|
OBJECT_NAME_COLOR: "rgba(0,0,0,0.7)"
|
|
4089
4149
|
};
|
|
4090
|
-
var
|
|
4150
|
+
var darkInspectorTheme = {
|
|
4091
4151
|
...chromeDark,
|
|
4092
4152
|
BASE_BACKGROUND_COLOR: "transparent",
|
|
4093
4153
|
OBJECT_NAME_COLOR: "rgba(255,255,255,0.7)"
|
|
4094
4154
|
};
|
|
4095
|
-
var
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
|
|
4155
|
+
var getStateInspectorTheme = (colorScheme) => {
|
|
4156
|
+
return colorScheme === "light" ? lightInspectorTheme : darkInspectorTheme;
|
|
4157
|
+
};
|
|
4158
|
+
var getStateInspectorBorderColor = (colorScheme) => {
|
|
4159
|
+
return colorScheme === "light" ? "rgb(223 223 223)" : "rgb(29 29 29)";
|
|
4160
|
+
};
|
|
4161
|
+
|
|
4162
|
+
// src/inspector/sections/EventsSection.tsx
|
|
4163
|
+
import React7 from "react";
|
|
4164
|
+
import { ObjectInspector, ObjectLabel } from "react-inspector";
|
|
4165
|
+
|
|
4166
|
+
// src/inspector/ObjectRootLabel.tsx
|
|
4167
|
+
import React3 from "react";
|
|
4168
|
+
import { ObjectName, ObjectPreview } from "react-inspector";
|
|
4169
|
+
var ObjectRootLabel = ({ name, data, direction }) => {
|
|
4170
|
+
if (typeof name === "string") {
|
|
4171
|
+
return /* @__PURE__ */ React3.createElement("span", null, /* @__PURE__ */ React3.createElement(ObjectName, { name }), /* @__PURE__ */ React3.createElement("span", null, ": "), /* @__PURE__ */ React3.createElement(ObjectPreview, { data }));
|
|
4172
|
+
}
|
|
4173
|
+
if (direction === "up" || direction === "down") {
|
|
4174
|
+
const arrow = direction === "up" ? "\u2191" : "\u2193";
|
|
4175
|
+
return /* @__PURE__ */ React3.createElement("span", null, /* @__PURE__ */ React3.createElement(
|
|
4176
|
+
"span",
|
|
4177
|
+
{
|
|
4178
|
+
style: {
|
|
4179
|
+
background: direction === "up" ? "rgba(0,255,0,0.2)" : "rgba(255,0,0,0.2)",
|
|
4180
|
+
// color: "white",
|
|
4181
|
+
width: 12,
|
|
4182
|
+
height: 12,
|
|
4183
|
+
borderRadius: 2,
|
|
4184
|
+
display: "inline-flex",
|
|
4185
|
+
justifyContent: "center",
|
|
4186
|
+
alignItems: "center",
|
|
4187
|
+
marginRight: 4,
|
|
4188
|
+
lineHeight: "12px"
|
|
4189
|
+
}
|
|
4190
|
+
},
|
|
4191
|
+
arrow
|
|
4192
|
+
), /* @__PURE__ */ React3.createElement(ObjectPreview, { data }));
|
|
4193
|
+
} else {
|
|
4194
|
+
return /* @__PURE__ */ React3.createElement(ObjectPreview, { data });
|
|
4102
4195
|
}
|
|
4103
4196
|
};
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4197
|
+
|
|
4198
|
+
// src/inspector/StateInspectorDisclosureSection.tsx
|
|
4199
|
+
import React5, {
|
|
4200
|
+
forwardRef
|
|
4201
|
+
} from "react";
|
|
4202
|
+
|
|
4203
|
+
// src/inspector/StateInspectorArrow.tsx
|
|
4204
|
+
import React4 from "react";
|
|
4205
|
+
function StateInspectorArrow({
|
|
4206
|
+
expanded,
|
|
4207
|
+
onClick,
|
|
4208
|
+
style
|
|
4109
4209
|
}) {
|
|
4110
|
-
|
|
4111
|
-
const rightIcon = /* @__PURE__ */ React3.createElement(
|
|
4112
|
-
"svg",
|
|
4113
|
-
{
|
|
4114
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
4115
|
-
fill: "none",
|
|
4116
|
-
viewBox: "0 0 24 24",
|
|
4117
|
-
strokeWidth: 1.5,
|
|
4118
|
-
stroke: "currentColor",
|
|
4119
|
-
className: "size-6"
|
|
4120
|
-
},
|
|
4121
|
-
/* @__PURE__ */ React3.createElement(
|
|
4122
|
-
"path",
|
|
4123
|
-
{
|
|
4124
|
-
strokeLinecap: "round",
|
|
4125
|
-
strokeLinejoin: "round",
|
|
4126
|
-
d: "m5.25 4.5 7.5 7.5-7.5 7.5m6-15 7.5 7.5-7.5 7.5"
|
|
4127
|
-
}
|
|
4128
|
-
)
|
|
4129
|
-
);
|
|
4130
|
-
const leftIcon = /* @__PURE__ */ React3.createElement(
|
|
4131
|
-
"svg",
|
|
4132
|
-
{
|
|
4133
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
4134
|
-
fill: "none",
|
|
4135
|
-
viewBox: "0 0 24 24",
|
|
4136
|
-
strokeWidth: 1.5,
|
|
4137
|
-
stroke: "currentColor",
|
|
4138
|
-
className: "size-6"
|
|
4139
|
-
},
|
|
4140
|
-
/* @__PURE__ */ React3.createElement(
|
|
4141
|
-
"path",
|
|
4142
|
-
{
|
|
4143
|
-
strokeLinecap: "round",
|
|
4144
|
-
strokeLinejoin: "round",
|
|
4145
|
-
d: "m18.75 4.5-7.5 7.5 7.5 7.5m-6-15L5.25 12l7.5 7.5"
|
|
4146
|
-
}
|
|
4147
|
-
)
|
|
4148
|
-
);
|
|
4149
|
-
return /* @__PURE__ */ React3.createElement(
|
|
4210
|
+
return /* @__PURE__ */ React4.createElement(
|
|
4150
4211
|
"span",
|
|
4151
4212
|
{
|
|
4152
4213
|
role: "button",
|
|
4214
|
+
onClick,
|
|
4153
4215
|
style: {
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
whiteSpace: "nowrap",
|
|
4160
|
-
display: "inline-flex",
|
|
4161
|
-
alignItems: "center",
|
|
4162
|
-
justifyContent: "center",
|
|
4163
|
-
padding: "2px 0"
|
|
4164
|
-
},
|
|
4165
|
-
onClick: (event) => {
|
|
4166
|
-
event.stopPropagation();
|
|
4167
|
-
setShowInspector(!showInspector);
|
|
4216
|
+
display: "inline-block",
|
|
4217
|
+
textAlign: "center",
|
|
4218
|
+
transform: expanded ? "rotate(0deg)" : "rotate(-90deg)",
|
|
4219
|
+
fontFamily: "Menlo, monospace",
|
|
4220
|
+
...style
|
|
4168
4221
|
}
|
|
4169
4222
|
},
|
|
4170
|
-
|
|
4223
|
+
"\u25BC"
|
|
4171
4224
|
);
|
|
4172
4225
|
}
|
|
4173
|
-
|
|
4226
|
+
|
|
4227
|
+
// src/inspector/StateInspectorDisclosureSection.tsx
|
|
4228
|
+
function StateInspectorDisclosureSection({
|
|
4174
4229
|
open,
|
|
4175
4230
|
setOpen,
|
|
4176
4231
|
title,
|
|
@@ -4180,9 +4235,9 @@ function DisclosureSection({
|
|
|
4180
4235
|
isFirst,
|
|
4181
4236
|
style
|
|
4182
4237
|
}) {
|
|
4183
|
-
const theme = colorScheme === "light" ?
|
|
4238
|
+
const theme = colorScheme === "light" ? lightInspectorTheme : darkInspectorTheme;
|
|
4184
4239
|
const borderColor = colorScheme === "light" ? "rgba(0,0,0,0.1)" : "rgba(255,255,255,0.1)";
|
|
4185
|
-
return /* @__PURE__ */
|
|
4240
|
+
return /* @__PURE__ */ React5.createElement(
|
|
4186
4241
|
"div",
|
|
4187
4242
|
{
|
|
4188
4243
|
style: {
|
|
@@ -4192,7 +4247,7 @@ function DisclosureSection({
|
|
|
4192
4247
|
...style
|
|
4193
4248
|
}
|
|
4194
4249
|
},
|
|
4195
|
-
/* @__PURE__ */
|
|
4250
|
+
/* @__PURE__ */ React5.createElement(
|
|
4196
4251
|
"div",
|
|
4197
4252
|
{
|
|
4198
4253
|
onClick: () => setOpen?.(!open),
|
|
@@ -4206,8 +4261,8 @@ function DisclosureSection({
|
|
|
4206
4261
|
...open && { borderBottom: `1px solid ${borderColor}` }
|
|
4207
4262
|
}
|
|
4208
4263
|
},
|
|
4209
|
-
setOpen && /* @__PURE__ */
|
|
4210
|
-
|
|
4264
|
+
setOpen && /* @__PURE__ */ React5.createElement(
|
|
4265
|
+
StateInspectorArrow,
|
|
4211
4266
|
{
|
|
4212
4267
|
expanded: open,
|
|
4213
4268
|
style: {
|
|
@@ -4217,13 +4272,35 @@ function DisclosureSection({
|
|
|
4217
4272
|
}
|
|
4218
4273
|
}
|
|
4219
4274
|
),
|
|
4220
|
-
/* @__PURE__ */
|
|
4275
|
+
/* @__PURE__ */ React5.createElement("span", { style: { flex: "1 1 0", userSelect: "none" } }, title),
|
|
4221
4276
|
right
|
|
4222
4277
|
),
|
|
4223
4278
|
open && children
|
|
4224
4279
|
);
|
|
4225
4280
|
}
|
|
4226
|
-
|
|
4281
|
+
var StateInspectorDisclosureRowInner = forwardRef(
|
|
4282
|
+
function StateInspectorDisclosureRowInner2(props, forwardedRef) {
|
|
4283
|
+
return /* @__PURE__ */ React5.createElement(
|
|
4284
|
+
"div",
|
|
4285
|
+
{
|
|
4286
|
+
style: {
|
|
4287
|
+
flex: "1 1 0",
|
|
4288
|
+
overflowY: "auto",
|
|
4289
|
+
overflowX: "hidden",
|
|
4290
|
+
display: "flex",
|
|
4291
|
+
flexDirection: "column",
|
|
4292
|
+
...props.style
|
|
4293
|
+
},
|
|
4294
|
+
...props,
|
|
4295
|
+
ref: forwardedRef
|
|
4296
|
+
}
|
|
4297
|
+
);
|
|
4298
|
+
}
|
|
4299
|
+
);
|
|
4300
|
+
|
|
4301
|
+
// src/inspector/StateInspectorRow.tsx
|
|
4302
|
+
import React6 from "react";
|
|
4303
|
+
function StateInspectorRow({
|
|
4227
4304
|
children,
|
|
4228
4305
|
colorScheme,
|
|
4229
4306
|
selected,
|
|
@@ -4231,7 +4308,7 @@ function InspectorRow({
|
|
|
4231
4308
|
variant
|
|
4232
4309
|
}) {
|
|
4233
4310
|
const solidBorderColor = colorScheme === "light" ? "rgb(223 223 223)" : "rgb(29 29 29)";
|
|
4234
|
-
return /* @__PURE__ */
|
|
4311
|
+
return /* @__PURE__ */ React6.createElement(
|
|
4235
4312
|
"div",
|
|
4236
4313
|
{
|
|
4237
4314
|
style: {
|
|
@@ -4249,7 +4326,7 @@ function InspectorRow({
|
|
|
4249
4326
|
...style
|
|
4250
4327
|
}
|
|
4251
4328
|
},
|
|
4252
|
-
/* @__PURE__ */
|
|
4329
|
+
/* @__PURE__ */ React6.createElement(
|
|
4253
4330
|
"span",
|
|
4254
4331
|
{
|
|
4255
4332
|
style: {
|
|
@@ -4263,68 +4340,1035 @@ function InspectorRow({
|
|
|
4263
4340
|
)
|
|
4264
4341
|
);
|
|
4265
4342
|
}
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4343
|
+
|
|
4344
|
+
// src/inspector/sections/EventsSection.tsx
|
|
4345
|
+
function EventsSection({
|
|
4346
|
+
showEvents,
|
|
4347
|
+
setShowEvents,
|
|
4348
|
+
colorScheme,
|
|
4349
|
+
eventsContainerRef,
|
|
4350
|
+
connectionEvents
|
|
4273
4351
|
}) {
|
|
4274
|
-
const
|
|
4275
|
-
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4352
|
+
const theme = getStateInspectorTheme(colorScheme);
|
|
4353
|
+
return /* @__PURE__ */ React7.createElement(
|
|
4354
|
+
StateInspectorDisclosureSection,
|
|
4355
|
+
{
|
|
4356
|
+
open: showEvents,
|
|
4357
|
+
setOpen: setShowEvents,
|
|
4358
|
+
title: "Events",
|
|
4359
|
+
colorScheme
|
|
4360
|
+
},
|
|
4361
|
+
/* @__PURE__ */ React7.createElement(StateInspectorDisclosureRowInner, { ref: eventsContainerRef }, connectionEvents?.map(
|
|
4362
|
+
(event, index) => event.type === "stateChange" ? /* @__PURE__ */ React7.createElement(StateInspectorRow, { key: index, colorScheme }, "connection:", " ", /* @__PURE__ */ React7.createElement("span", { style: { fontStyle: "italic" } }, event.state.toLowerCase())) : /* @__PURE__ */ React7.createElement(
|
|
4363
|
+
StateInspectorRow,
|
|
4364
|
+
{
|
|
4365
|
+
key: index,
|
|
4366
|
+
colorScheme,
|
|
4367
|
+
variant: event.type === "send" ? "up" : "down",
|
|
4368
|
+
style: {
|
|
4369
|
+
padding: "0px 12px 1px"
|
|
4370
|
+
}
|
|
4371
|
+
},
|
|
4372
|
+
/* @__PURE__ */ React7.createElement(
|
|
4373
|
+
ObjectInspector,
|
|
4374
|
+
{
|
|
4375
|
+
data: event.type === "error" ? event.error : event.message,
|
|
4376
|
+
theme,
|
|
4377
|
+
nodeRenderer: ({ depth, name, data, isNonenumerable }) => {
|
|
4378
|
+
const direction = event.type === "send" ? "up" : "down";
|
|
4379
|
+
return depth === 0 ? /* @__PURE__ */ React7.createElement(ObjectRootLabel, { direction, data }) : /* @__PURE__ */ React7.createElement(
|
|
4380
|
+
ObjectLabel,
|
|
4381
|
+
{
|
|
4382
|
+
direction,
|
|
4383
|
+
name,
|
|
4384
|
+
data,
|
|
4385
|
+
isNonenumerable
|
|
4386
|
+
}
|
|
4387
|
+
);
|
|
4388
|
+
}
|
|
4389
|
+
}
|
|
4390
|
+
)
|
|
4391
|
+
)
|
|
4392
|
+
), !connectionEvents && /* @__PURE__ */ React7.createElement(
|
|
4393
|
+
"div",
|
|
4394
|
+
{
|
|
4395
|
+
style: {
|
|
4396
|
+
padding: "12px",
|
|
4397
|
+
fontSize: "12px",
|
|
4398
|
+
display: "flex",
|
|
4399
|
+
flexDirection: "column",
|
|
4400
|
+
gap: "4px"
|
|
4401
|
+
}
|
|
4402
|
+
},
|
|
4403
|
+
/* @__PURE__ */ React7.createElement("span", null, "No recorded events")
|
|
4404
|
+
))
|
|
4405
|
+
);
|
|
4406
|
+
}
|
|
4407
|
+
|
|
4408
|
+
// src/inspector/sections/HistorySection.tsx
|
|
4409
|
+
import React9, { useEffect, useRef } from "react";
|
|
4410
|
+
import { ObjectInspector as ObjectInspector2 } from "react-inspector";
|
|
4411
|
+
|
|
4412
|
+
// src/inspector/StateInspectorButton.tsx
|
|
4413
|
+
import React8 from "react";
|
|
4414
|
+
function StateInspectorButton({
|
|
4415
|
+
children,
|
|
4416
|
+
onClick,
|
|
4417
|
+
style,
|
|
4418
|
+
theme,
|
|
4419
|
+
disabled
|
|
4420
|
+
}) {
|
|
4421
|
+
return /* @__PURE__ */ React8.createElement(
|
|
4422
|
+
"button",
|
|
4423
|
+
{
|
|
4424
|
+
type: "button",
|
|
4425
|
+
disabled,
|
|
4426
|
+
onClick: (event) => {
|
|
4427
|
+
event.stopPropagation();
|
|
4428
|
+
onClick();
|
|
4429
|
+
},
|
|
4430
|
+
style: {
|
|
4431
|
+
flex: "0",
|
|
4432
|
+
appearance: "none",
|
|
4433
|
+
background: "none",
|
|
4434
|
+
color: theme.BASE_COLOR,
|
|
4435
|
+
opacity: disabled ? 0.25 : 1,
|
|
4436
|
+
border: "none",
|
|
4437
|
+
fontSize: "12px",
|
|
4438
|
+
whiteSpace: "nowrap",
|
|
4439
|
+
display: "inline-flex",
|
|
4440
|
+
alignItems: "center",
|
|
4441
|
+
justifyContent: "center",
|
|
4442
|
+
padding: "0",
|
|
4443
|
+
cursor: "pointer",
|
|
4444
|
+
...style
|
|
4445
|
+
}
|
|
4446
|
+
},
|
|
4447
|
+
children
|
|
4448
|
+
);
|
|
4449
|
+
}
|
|
4450
|
+
|
|
4451
|
+
// src/inspector/utils.ts
|
|
4452
|
+
function pathToString(extendedPath) {
|
|
4453
|
+
return extendedPath.map(
|
|
4454
|
+
(key) => typeof key === "object" ? `:${ellipsis(key.id.toString(), 8, "middle")}` : key
|
|
4455
|
+
).map(
|
|
4456
|
+
(key, index) => index === 0 || typeof key === "string" && key.startsWith(":") ? key : `.${key}`
|
|
4457
|
+
).join("");
|
|
4458
|
+
}
|
|
4459
|
+
function ellipsis(str, maxLength, position = "end") {
|
|
4460
|
+
if (str.length <= maxLength) return str;
|
|
4461
|
+
switch (position) {
|
|
4462
|
+
case "start":
|
|
4463
|
+
return `\u2026${str.slice(str.length - maxLength)}`;
|
|
4464
|
+
case "middle": {
|
|
4465
|
+
const halfLength = Math.floor(maxLength / 2);
|
|
4466
|
+
return `${str.slice(0, halfLength)}\u2026${str.slice(str.length - halfLength)}`;
|
|
4467
|
+
}
|
|
4468
|
+
case "end":
|
|
4469
|
+
return `${str.slice(0, maxLength)}\u2026`;
|
|
4470
|
+
}
|
|
4471
|
+
}
|
|
4472
|
+
function uploadFile() {
|
|
4473
|
+
return new Promise((resolve, reject) => {
|
|
4474
|
+
const input = document.createElement("input");
|
|
4475
|
+
input.type = "file";
|
|
4476
|
+
input.onchange = () => {
|
|
4477
|
+
const file = input.files?.[0];
|
|
4478
|
+
if (file) {
|
|
4479
|
+
const reader = new FileReader();
|
|
4480
|
+
reader.onload = () => {
|
|
4481
|
+
const buffer = reader.result;
|
|
4482
|
+
const blob = new Blob([buffer]);
|
|
4483
|
+
resolve(blob);
|
|
4484
|
+
};
|
|
4485
|
+
reader.onerror = () => {
|
|
4486
|
+
reject(new Error("Failed to read file"));
|
|
4487
|
+
};
|
|
4488
|
+
reader.readAsArrayBuffer(file);
|
|
4489
|
+
}
|
|
4490
|
+
};
|
|
4491
|
+
input.click();
|
|
4492
|
+
});
|
|
4493
|
+
}
|
|
4494
|
+
|
|
4495
|
+
// src/inspector/sections/HistorySection.tsx
|
|
4496
|
+
var HISTORY_ELEMENT_PREFIX = "noya-multiplayer-history-";
|
|
4497
|
+
function HistorySection({
|
|
4498
|
+
showHistory,
|
|
4499
|
+
setShowHistory,
|
|
4500
|
+
colorScheme,
|
|
4501
|
+
historySnapshot,
|
|
4502
|
+
multiplayerStateManager
|
|
4503
|
+
}) {
|
|
4504
|
+
const ref = useRef(null);
|
|
4505
|
+
const theme = getStateInspectorTheme(colorScheme);
|
|
4506
|
+
const solidBorderColor = getStateInspectorBorderColor(colorScheme);
|
|
4507
|
+
useEffect(() => {
|
|
4508
|
+
if (ref.current) {
|
|
4509
|
+
ref.current.scrollTop = ref.current.scrollHeight;
|
|
4510
|
+
}
|
|
4511
|
+
}, [historySnapshot]);
|
|
4512
|
+
useEffect(() => {
|
|
4513
|
+
if (!ref.current) return;
|
|
4514
|
+
const historyEntry = ref.current.querySelector(
|
|
4515
|
+
`#${HISTORY_ELEMENT_PREFIX}${historySnapshot.historyIndex}`
|
|
4516
|
+
);
|
|
4517
|
+
if (historyEntry) {
|
|
4518
|
+
historyEntry.scrollIntoView({
|
|
4519
|
+
block: "nearest",
|
|
4520
|
+
inline: "nearest"
|
|
4521
|
+
});
|
|
4522
|
+
}
|
|
4523
|
+
}, [historySnapshot.historyIndex]);
|
|
4524
|
+
return /* @__PURE__ */ React9.createElement(
|
|
4525
|
+
StateInspectorDisclosureSection,
|
|
4526
|
+
{
|
|
4527
|
+
open: showHistory,
|
|
4528
|
+
setOpen: setShowHistory,
|
|
4529
|
+
title: "History",
|
|
4530
|
+
colorScheme,
|
|
4531
|
+
right: /* @__PURE__ */ React9.createElement(
|
|
4532
|
+
"span",
|
|
4533
|
+
{
|
|
4534
|
+
style: {
|
|
4535
|
+
display: "flex",
|
|
4536
|
+
gap: "4px"
|
|
4537
|
+
}
|
|
4538
|
+
},
|
|
4539
|
+
/* @__PURE__ */ React9.createElement(
|
|
4540
|
+
StateInspectorButton,
|
|
4541
|
+
{
|
|
4542
|
+
disabled: !historySnapshot.canUndo,
|
|
4543
|
+
theme,
|
|
4544
|
+
onClick: () => {
|
|
4545
|
+
multiplayerStateManager.undo();
|
|
4546
|
+
}
|
|
4547
|
+
},
|
|
4548
|
+
/* @__PURE__ */ React9.createElement("span", { style: { width: "12px", height: "12px" } }, /* @__PURE__ */ React9.createElement(
|
|
4549
|
+
"svg",
|
|
4550
|
+
{
|
|
4551
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
4552
|
+
width: "1em",
|
|
4553
|
+
height: "1em",
|
|
4554
|
+
viewBox: "0 0 20 20"
|
|
4555
|
+
},
|
|
4556
|
+
/* @__PURE__ */ React9.createElement(
|
|
4557
|
+
"path",
|
|
4558
|
+
{
|
|
4559
|
+
fill: "currentColor",
|
|
4560
|
+
d: "M12 5H7V2L1 6l6 4V7h5c2.2 0 4 1.8 4 4s-1.8 4-4 4H7v2h5c3.3 0 6-2.7 6-6s-2.7-6-6-6"
|
|
4561
|
+
}
|
|
4562
|
+
)
|
|
4563
|
+
))
|
|
4564
|
+
),
|
|
4565
|
+
/* @__PURE__ */ React9.createElement(
|
|
4566
|
+
StateInspectorButton,
|
|
4567
|
+
{
|
|
4568
|
+
disabled: !historySnapshot.canRedo,
|
|
4569
|
+
theme,
|
|
4570
|
+
onClick: () => {
|
|
4571
|
+
multiplayerStateManager.redo();
|
|
4572
|
+
}
|
|
4573
|
+
},
|
|
4574
|
+
/* @__PURE__ */ React9.createElement("span", { style: { width: "12px", height: "12px" } }, /* @__PURE__ */ React9.createElement(
|
|
4575
|
+
"svg",
|
|
4576
|
+
{
|
|
4577
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
4578
|
+
width: "1em",
|
|
4579
|
+
height: "1em",
|
|
4580
|
+
viewBox: "0 0 20 20"
|
|
4581
|
+
},
|
|
4582
|
+
/* @__PURE__ */ React9.createElement(
|
|
4583
|
+
"path",
|
|
4584
|
+
{
|
|
4585
|
+
fill: "currentColor",
|
|
4586
|
+
d: "M8 5h5V2l6 4l-6 4V7H8c-2.2 0-4 1.8-4 4s1.8 4 4 4h5v2H8c-3.3 0-6-2.7-6-6s2.7-6 6-6"
|
|
4587
|
+
}
|
|
4588
|
+
)
|
|
4589
|
+
))
|
|
4590
|
+
)
|
|
4591
|
+
)
|
|
4592
|
+
},
|
|
4593
|
+
/* @__PURE__ */ React9.createElement(StateInspectorDisclosureRowInner, { ref }, /* @__PURE__ */ React9.createElement(
|
|
4594
|
+
"div",
|
|
4595
|
+
{
|
|
4596
|
+
id: `${HISTORY_ELEMENT_PREFIX}0`,
|
|
4597
|
+
style: {
|
|
4598
|
+
borderBottom: `1px solid ${solidBorderColor}`,
|
|
4599
|
+
fontSize: "12px",
|
|
4600
|
+
fontFamily: "Menlo, monospace",
|
|
4601
|
+
padding: "2px 12px 1px",
|
|
4602
|
+
display: "flex",
|
|
4603
|
+
alignItems: "center",
|
|
4604
|
+
background: historySnapshot.historyIndex === 0 ? "rgb(59 130 246 / 15%)" : void 0
|
|
4605
|
+
}
|
|
4606
|
+
},
|
|
4607
|
+
/* @__PURE__ */ React9.createElement(
|
|
4608
|
+
"span",
|
|
4609
|
+
{
|
|
4610
|
+
style: {
|
|
4611
|
+
fontFamily: "Menlo, monospace",
|
|
4612
|
+
fontSize: "11px",
|
|
4613
|
+
borderRadius: 4,
|
|
4614
|
+
display: "inline-block"
|
|
4615
|
+
}
|
|
4616
|
+
},
|
|
4617
|
+
"Initial state"
|
|
4618
|
+
)
|
|
4619
|
+
), historySnapshot.history.map((entry, index) => {
|
|
4620
|
+
const metadata = entry.metadata;
|
|
4621
|
+
const { id, name, timestamp, ...rest } = metadata;
|
|
4622
|
+
return /* @__PURE__ */ React9.createElement(
|
|
4623
|
+
"div",
|
|
4624
|
+
{
|
|
4625
|
+
id: `${HISTORY_ELEMENT_PREFIX}${index + 1}`,
|
|
4626
|
+
key: index,
|
|
4627
|
+
style: {
|
|
4628
|
+
padding: "0px 12px 1px",
|
|
4629
|
+
borderBottom: `1px solid ${solidBorderColor}`,
|
|
4630
|
+
background: index + 1 === historySnapshot.historyIndex ? "rgb(59 130 246 / 15%)" : void 0
|
|
4631
|
+
}
|
|
4632
|
+
},
|
|
4633
|
+
typeof name === "string" && /* @__PURE__ */ React9.createElement(
|
|
4634
|
+
"pre",
|
|
4635
|
+
{
|
|
4636
|
+
style: {
|
|
4637
|
+
fontSize: "11px",
|
|
4638
|
+
display: "flex",
|
|
4639
|
+
flexWrap: "wrap",
|
|
4640
|
+
margin: 0
|
|
4641
|
+
}
|
|
4642
|
+
},
|
|
4643
|
+
entry.metadata.name,
|
|
4644
|
+
Object.keys(rest).length > 0 && /* @__PURE__ */ React9.createElement(ObjectInspector2, { data: rest, theme })
|
|
4645
|
+
),
|
|
4646
|
+
entry.redoPatches?.map((patch, j) => /* @__PURE__ */ React9.createElement(
|
|
4647
|
+
"pre",
|
|
4648
|
+
{
|
|
4649
|
+
key: j,
|
|
4650
|
+
style: {
|
|
4651
|
+
fontSize: "11px",
|
|
4652
|
+
display: "flex",
|
|
4653
|
+
flexWrap: "wrap",
|
|
4654
|
+
margin: 0
|
|
4655
|
+
}
|
|
4656
|
+
},
|
|
4657
|
+
patch.op === "add" && /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path)), " = ", /* @__PURE__ */ React9.createElement(ObjectInspector2, { data: patch.value, theme })),
|
|
4658
|
+
patch.op === "replace" && /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path)), " = ", /* @__PURE__ */ React9.createElement(ObjectInspector2, { data: patch.value, theme })),
|
|
4659
|
+
patch.op === "remove" && /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement("span", { style: { color: theme.OBJECT_VALUE_STRING_COLOR } }, "delete", " "), /* @__PURE__ */ React9.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path))),
|
|
4660
|
+
patch.op === "move" && /* @__PURE__ */ React9.createElement(React9.Fragment, null, /* @__PURE__ */ React9.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.from)), " -> ", /* @__PURE__ */ React9.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path)))
|
|
4661
|
+
))
|
|
4662
|
+
);
|
|
4663
|
+
}))
|
|
4664
|
+
);
|
|
4665
|
+
}
|
|
4666
|
+
|
|
4667
|
+
// src/inspector/serialization.ts
|
|
4668
|
+
import { createHash } from "@noya-app/state-manager";
|
|
4669
|
+
|
|
4670
|
+
// src/inspector/zip/crc32.ts
|
|
4671
|
+
var CRC_TABLE = (() => {
|
|
4672
|
+
const t = new Uint32Array(256);
|
|
4673
|
+
for (let i = 0; i < 256; i++) {
|
|
4674
|
+
let c = i;
|
|
4675
|
+
for (let k = 0; k < 8; k++) c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
|
|
4676
|
+
t[i] = c >>> 0;
|
|
4677
|
+
}
|
|
4678
|
+
return t;
|
|
4679
|
+
})();
|
|
4680
|
+
function crc32(u8) {
|
|
4681
|
+
let c = 4294967295;
|
|
4682
|
+
for (let i = 0; i < u8.length; i++)
|
|
4683
|
+
c = CRC_TABLE[(c ^ u8[i]) & 255] ^ c >>> 8;
|
|
4684
|
+
return (c ^ 4294967295) >>> 0;
|
|
4685
|
+
}
|
|
4686
|
+
|
|
4687
|
+
// src/inspector/zip/struct.ts
|
|
4688
|
+
var defineSchema = (s) => s;
|
|
4689
|
+
var defineSchemas = (m) => m;
|
|
4690
|
+
function sizeofFieldSpec(f, ctx) {
|
|
4691
|
+
if (f.type === "bytes")
|
|
4692
|
+
return typeof f.length === "function" ? f.length(ctx) : f.length;
|
|
4693
|
+
return f.type === "u8" ? 1 : f.type === "u16" ? 2 : 4;
|
|
4694
|
+
}
|
|
4695
|
+
function writeStruct(schema, values) {
|
|
4696
|
+
let total = 0;
|
|
4697
|
+
const ctx = { ...values };
|
|
4698
|
+
for (const f of schema) total += sizeofFieldSpec(f, ctx);
|
|
4699
|
+
const out = new Uint8Array(total);
|
|
4700
|
+
const view = new DataView(out.buffer);
|
|
4701
|
+
let o = 0;
|
|
4702
|
+
const vals = values;
|
|
4703
|
+
for (const f of schema) {
|
|
4704
|
+
if (f.type === "bytes") {
|
|
4705
|
+
const b = vals[f.name];
|
|
4706
|
+
out.set(b, o);
|
|
4707
|
+
o += b.length;
|
|
4708
|
+
continue;
|
|
4709
|
+
}
|
|
4710
|
+
const n = Number(vals[f.name]) >>> 0;
|
|
4711
|
+
if (f.type === "u8") {
|
|
4712
|
+
view.setUint8(o, n);
|
|
4713
|
+
o += 1;
|
|
4714
|
+
} else if (f.type === "u16") {
|
|
4715
|
+
view.setUint16(o, n, true);
|
|
4716
|
+
o += 2;
|
|
4717
|
+
} else {
|
|
4718
|
+
view.setUint32(o, n, true);
|
|
4719
|
+
o += 4;
|
|
4720
|
+
}
|
|
4721
|
+
}
|
|
4722
|
+
return out;
|
|
4723
|
+
}
|
|
4724
|
+
function readStruct(view, offset, schema) {
|
|
4725
|
+
const ctx = {};
|
|
4726
|
+
let o = offset;
|
|
4727
|
+
for (const f of schema) {
|
|
4728
|
+
if (f.type === "bytes") {
|
|
4729
|
+
const len = typeof f.length === "function" ? f.length(ctx) : f.length;
|
|
4730
|
+
const u8 = new Uint8Array(view.buffer, view.byteOffset + o, len);
|
|
4731
|
+
ctx[f.name] = new Uint8Array(u8);
|
|
4732
|
+
o += len;
|
|
4733
|
+
} else if (f.type === "u8") {
|
|
4734
|
+
ctx[f.name] = view.getUint8(o);
|
|
4735
|
+
o += 1;
|
|
4736
|
+
} else if (f.type === "u16") {
|
|
4737
|
+
ctx[f.name] = view.getUint16(o, true);
|
|
4738
|
+
o += 2;
|
|
4739
|
+
} else {
|
|
4740
|
+
ctx[f.name] = view.getUint32(o, true);
|
|
4741
|
+
o += 4;
|
|
4742
|
+
}
|
|
4743
|
+
}
|
|
4744
|
+
return { value: ctx, offset: o };
|
|
4745
|
+
}
|
|
4746
|
+
|
|
4747
|
+
// src/inspector/zip/TinyZip.ts
|
|
4748
|
+
var te = new TextEncoder();
|
|
4749
|
+
function utf8(s) {
|
|
4750
|
+
return te.encode(s);
|
|
4751
|
+
}
|
|
4752
|
+
function dosDateTime(d = /* @__PURE__ */ new Date()) {
|
|
4753
|
+
const time = d.getHours() << 11 | d.getMinutes() << 5 | Math.floor(d.getSeconds() / 2);
|
|
4754
|
+
const date = d.getFullYear() - 1980 << 9 | d.getMonth() + 1 << 5 | d.getDate();
|
|
4755
|
+
return { time, date };
|
|
4756
|
+
}
|
|
4757
|
+
var SIG = {
|
|
4758
|
+
LocalFile: 67324752,
|
|
4759
|
+
CentralFile: 33639248,
|
|
4760
|
+
EOCD: 101010256
|
|
4761
|
+
};
|
|
4762
|
+
var SCHEMA = defineSchemas({
|
|
4763
|
+
LocalFile: defineSchema([
|
|
4764
|
+
{ name: "signature", type: "u32" },
|
|
4765
|
+
{ name: "versionNeeded", type: "u16" },
|
|
4766
|
+
{ name: "flags", type: "u16" },
|
|
4767
|
+
{ name: "method", type: "u16" },
|
|
4768
|
+
{ name: "time", type: "u16" },
|
|
4769
|
+
{ name: "date", type: "u16" },
|
|
4770
|
+
{ name: "crc32", type: "u32" },
|
|
4771
|
+
{ name: "compSize", type: "u32" },
|
|
4772
|
+
{ name: "uncompSize", type: "u32" },
|
|
4773
|
+
{ name: "nameLen", type: "u16" },
|
|
4774
|
+
{ name: "extraLen", type: "u16" },
|
|
4775
|
+
{ name: "name", type: "bytes", length: (c) => c.nameLen },
|
|
4776
|
+
{ name: "extra", type: "bytes", length: (c) => c.extraLen }
|
|
4777
|
+
]),
|
|
4778
|
+
CentralFile: defineSchema([
|
|
4779
|
+
{ name: "signature", type: "u32" },
|
|
4780
|
+
{ name: "versionMadeBy", type: "u16" },
|
|
4781
|
+
{ name: "versionNeeded", type: "u16" },
|
|
4782
|
+
{ name: "flags", type: "u16" },
|
|
4783
|
+
{ name: "method", type: "u16" },
|
|
4784
|
+
{ name: "time", type: "u16" },
|
|
4785
|
+
{ name: "date", type: "u16" },
|
|
4786
|
+
{ name: "crc32", type: "u32" },
|
|
4787
|
+
{ name: "compSize", type: "u32" },
|
|
4788
|
+
{ name: "uncompSize", type: "u32" },
|
|
4789
|
+
{ name: "nameLen", type: "u16" },
|
|
4790
|
+
{ name: "extraLen", type: "u16" },
|
|
4791
|
+
{ name: "commentLen", type: "u16" },
|
|
4792
|
+
{ name: "diskStart", type: "u16" },
|
|
4793
|
+
{ name: "intAttrs", type: "u16" },
|
|
4794
|
+
{ name: "extAttrs", type: "u32" },
|
|
4795
|
+
{ name: "localHeaderOffset", type: "u32" },
|
|
4796
|
+
{ name: "name", type: "bytes", length: (c) => c.nameLen },
|
|
4797
|
+
{ name: "extra", type: "bytes", length: (c) => c.extraLen },
|
|
4798
|
+
{ name: "comment", type: "bytes", length: (c) => c.commentLen }
|
|
4799
|
+
]),
|
|
4800
|
+
EOCD: defineSchema([
|
|
4801
|
+
{ name: "signature", type: "u32" },
|
|
4802
|
+
{ name: "diskNum", type: "u16" },
|
|
4803
|
+
{ name: "cdStartDisk", type: "u16" },
|
|
4804
|
+
{ name: "cdRecordsOnDisk", type: "u16" },
|
|
4805
|
+
{ name: "cdRecordsTotal", type: "u16" },
|
|
4806
|
+
{ name: "cdSize", type: "u32" },
|
|
4807
|
+
{ name: "cdOffset", type: "u32" },
|
|
4808
|
+
{ name: "commentLen", type: "u16" },
|
|
4809
|
+
{ name: "comment", type: "bytes", length: (c) => c.commentLen }
|
|
4810
|
+
])
|
|
4811
|
+
});
|
|
4812
|
+
function ensureSig(v, expect, where) {
|
|
4813
|
+
if (v !== expect)
|
|
4814
|
+
throw new Error(`Invalid signature for ${where}: 0x${v.toString(16)}`);
|
|
4815
|
+
}
|
|
4816
|
+
var TinyZip = class _TinyZip {
|
|
4817
|
+
_chunks = [];
|
|
4818
|
+
_offset = 0;
|
|
4819
|
+
_files = [];
|
|
4820
|
+
_rootPrefix = "";
|
|
4821
|
+
// e.g. "my-archive/" or ""
|
|
4822
|
+
_rootDirAdded = false;
|
|
4823
|
+
constructor(opts = {}) {
|
|
4824
|
+
if (opts.root) {
|
|
4825
|
+
const r = opts.root.replace(/^\/+|\/+$/g, "");
|
|
4826
|
+
if (r) this._rootPrefix = r + "/";
|
|
4827
|
+
}
|
|
4828
|
+
}
|
|
4829
|
+
_push(...arrs) {
|
|
4830
|
+
for (const a of arrs) {
|
|
4831
|
+
this._chunks.push(a);
|
|
4832
|
+
this._offset += a.length;
|
|
4833
|
+
}
|
|
4834
|
+
}
|
|
4835
|
+
_withRoot(name) {
|
|
4836
|
+
return this._rootPrefix && !name.startsWith(this._rootPrefix) ? this._rootPrefix + name.replace(/^\/+/, "") : name;
|
|
4837
|
+
}
|
|
4838
|
+
_ensureRootDir(date = /* @__PURE__ */ new Date()) {
|
|
4839
|
+
if (!this._rootPrefix || this._rootDirAdded) return;
|
|
4840
|
+
this._rootDirAdded = true;
|
|
4841
|
+
const dirName = this._rootPrefix;
|
|
4842
|
+
const nameBytes = utf8(dirName);
|
|
4843
|
+
const { time, date: dosDate } = dosDateTime(date);
|
|
4844
|
+
const localHeader = writeStruct(SCHEMA.LocalFile, {
|
|
4845
|
+
signature: SIG.LocalFile,
|
|
4846
|
+
versionNeeded: 20,
|
|
4847
|
+
flags: 2048,
|
|
4848
|
+
method: 0,
|
|
4849
|
+
time,
|
|
4850
|
+
date: dosDate,
|
|
4851
|
+
crc32: 0,
|
|
4852
|
+
compSize: 0,
|
|
4853
|
+
uncompSize: 0,
|
|
4854
|
+
nameLen: nameBytes.length,
|
|
4855
|
+
extraLen: 0,
|
|
4856
|
+
name: nameBytes,
|
|
4857
|
+
extra: new Uint8Array(0)
|
|
4858
|
+
});
|
|
4859
|
+
const localHeaderOffset = this._offset;
|
|
4860
|
+
this._push(localHeader);
|
|
4861
|
+
this._files.push({
|
|
4862
|
+
nameBytes,
|
|
4863
|
+
crc: 0,
|
|
4864
|
+
compSize: 0,
|
|
4865
|
+
uncompSize: 0,
|
|
4866
|
+
method: 0,
|
|
4867
|
+
time,
|
|
4868
|
+
dosDate,
|
|
4869
|
+
localHeaderOffset,
|
|
4870
|
+
externalAttrs: 16
|
|
4871
|
+
});
|
|
4872
|
+
}
|
|
4873
|
+
/** Add a file to the zip. "name" uses forward slashes for paths (e.g., "dir/file.txt"). */
|
|
4874
|
+
addFile(name, data, opts = {}) {
|
|
4875
|
+
const { date = /* @__PURE__ */ new Date() } = opts;
|
|
4876
|
+
this._ensureRootDir(date);
|
|
4877
|
+
const u8 = toU8(data);
|
|
4878
|
+
const fullName = this._withRoot(name);
|
|
4879
|
+
const nameBytes = utf8(fullName);
|
|
4880
|
+
const { time, date: dosDate } = dosDateTime(date);
|
|
4881
|
+
const crc = crc32(u8);
|
|
4882
|
+
const compSize = u8.length >>> 0;
|
|
4883
|
+
const uncompSize = u8.length >>> 0;
|
|
4884
|
+
const localHeaderOffset = this._offset;
|
|
4885
|
+
const localHeader = writeStruct(SCHEMA.LocalFile, {
|
|
4886
|
+
signature: SIG.LocalFile,
|
|
4887
|
+
versionNeeded: 20,
|
|
4888
|
+
flags: 2048,
|
|
4889
|
+
method: 0,
|
|
4890
|
+
time,
|
|
4891
|
+
date: dosDate,
|
|
4892
|
+
crc32: crc,
|
|
4893
|
+
compSize,
|
|
4894
|
+
uncompSize,
|
|
4895
|
+
nameLen: nameBytes.length,
|
|
4896
|
+
extraLen: 0,
|
|
4897
|
+
name: nameBytes,
|
|
4898
|
+
extra: new Uint8Array(0)
|
|
4899
|
+
});
|
|
4900
|
+
this._push(localHeader, u8);
|
|
4901
|
+
this._files.push({
|
|
4902
|
+
nameBytes,
|
|
4903
|
+
crc,
|
|
4904
|
+
compSize,
|
|
4905
|
+
uncompSize,
|
|
4906
|
+
method: 0,
|
|
4907
|
+
time,
|
|
4908
|
+
dosDate,
|
|
4909
|
+
localHeaderOffset,
|
|
4910
|
+
externalAttrs: 0
|
|
4911
|
+
});
|
|
4912
|
+
}
|
|
4913
|
+
// Create an explicit directory entry (name should end with "/").
|
|
4914
|
+
addDirectory(name, opts = {}) {
|
|
4915
|
+
const { date = /* @__PURE__ */ new Date() } = opts;
|
|
4916
|
+
this._ensureRootDir(date);
|
|
4917
|
+
const dirNameRaw = name.endsWith("/") ? name : name + "/";
|
|
4918
|
+
const fullName = this._withRoot(dirNameRaw);
|
|
4919
|
+
const nameBytes = utf8(fullName);
|
|
4920
|
+
const { time, date: dosDate } = dosDateTime(date);
|
|
4921
|
+
const localHeader = writeStruct(SCHEMA.LocalFile, {
|
|
4922
|
+
signature: SIG.LocalFile,
|
|
4923
|
+
versionNeeded: 20,
|
|
4924
|
+
flags: 2048,
|
|
4925
|
+
method: 0,
|
|
4926
|
+
time,
|
|
4927
|
+
date: dosDate,
|
|
4928
|
+
crc32: 0,
|
|
4929
|
+
compSize: 0,
|
|
4930
|
+
uncompSize: 0,
|
|
4931
|
+
nameLen: nameBytes.length,
|
|
4932
|
+
extraLen: 0,
|
|
4933
|
+
name: nameBytes,
|
|
4934
|
+
extra: new Uint8Array(0)
|
|
4935
|
+
});
|
|
4936
|
+
const localHeaderOffset = this._offset;
|
|
4937
|
+
this._push(localHeader);
|
|
4938
|
+
this._files.push({
|
|
4939
|
+
nameBytes,
|
|
4940
|
+
crc: 0,
|
|
4941
|
+
compSize: 0,
|
|
4942
|
+
uncompSize: 0,
|
|
4943
|
+
method: 0,
|
|
4944
|
+
time,
|
|
4945
|
+
dosDate,
|
|
4946
|
+
localHeaderOffset,
|
|
4947
|
+
externalAttrs: 16
|
|
4948
|
+
});
|
|
4949
|
+
}
|
|
4950
|
+
finish() {
|
|
4951
|
+
const cdStart = this._offset;
|
|
4952
|
+
for (const f of this._files) {
|
|
4953
|
+
const central = writeStruct(SCHEMA.CentralFile, {
|
|
4954
|
+
signature: SIG.CentralFile,
|
|
4955
|
+
versionMadeBy: 20,
|
|
4956
|
+
versionNeeded: 20,
|
|
4957
|
+
flags: 2048,
|
|
4958
|
+
method: f.method,
|
|
4959
|
+
time: f.time,
|
|
4960
|
+
date: f.dosDate,
|
|
4961
|
+
crc32: f.crc,
|
|
4962
|
+
compSize: f.compSize,
|
|
4963
|
+
uncompSize: f.uncompSize,
|
|
4964
|
+
nameLen: f.nameBytes.length,
|
|
4965
|
+
extraLen: 0,
|
|
4966
|
+
commentLen: 0,
|
|
4967
|
+
diskStart: 0,
|
|
4968
|
+
intAttrs: 0,
|
|
4969
|
+
extAttrs: f.externalAttrs,
|
|
4970
|
+
localHeaderOffset: f.localHeaderOffset,
|
|
4971
|
+
name: f.nameBytes,
|
|
4972
|
+
extra: new Uint8Array(0),
|
|
4973
|
+
comment: new Uint8Array(0)
|
|
4974
|
+
});
|
|
4975
|
+
this._push(central);
|
|
4976
|
+
}
|
|
4977
|
+
const cdSize = this._offset - cdStart;
|
|
4978
|
+
const eocd = writeStruct(SCHEMA.EOCD, {
|
|
4979
|
+
signature: SIG.EOCD,
|
|
4980
|
+
diskNum: 0,
|
|
4981
|
+
cdStartDisk: 0,
|
|
4982
|
+
cdRecordsOnDisk: this._files.length,
|
|
4983
|
+
cdRecordsTotal: this._files.length,
|
|
4984
|
+
cdSize,
|
|
4985
|
+
cdOffset: cdStart,
|
|
4986
|
+
commentLen: 0,
|
|
4987
|
+
comment: new Uint8Array(0)
|
|
4988
|
+
});
|
|
4989
|
+
this._push(eocd);
|
|
4990
|
+
const merged = new Uint8Array(this._offset);
|
|
4991
|
+
let offset = 0;
|
|
4992
|
+
for (const chunk of this._chunks) {
|
|
4993
|
+
merged.set(chunk, offset);
|
|
4994
|
+
offset += chunk.length;
|
|
4995
|
+
}
|
|
4996
|
+
return merged;
|
|
4997
|
+
}
|
|
4998
|
+
static create(files, opts = {}) {
|
|
4999
|
+
const zip = new _TinyZip(opts);
|
|
5000
|
+
for (const [name, data] of Object.entries(files)) {
|
|
5001
|
+
if (name.endsWith("/")) zip.addDirectory(name);
|
|
5002
|
+
else zip.addFile(name, data);
|
|
5003
|
+
}
|
|
5004
|
+
return zip.finish();
|
|
5005
|
+
}
|
|
5006
|
+
static parse(input) {
|
|
5007
|
+
const u8 = toU8(input);
|
|
5008
|
+
const view = new DataView(u8.buffer, u8.byteOffset, u8.byteLength);
|
|
5009
|
+
const eocdOff = findEOCDOffset(u8);
|
|
5010
|
+
const { value: eocd } = readStruct(view, eocdOff, SCHEMA.EOCD);
|
|
5011
|
+
ensureSig(eocd.signature, SIG.EOCD, "EOCD");
|
|
5012
|
+
if (eocd.commentLen !== 0) throw new Error("Unsupported: EOCD comment");
|
|
5013
|
+
if (eocd.diskNum !== 0 || eocd.cdStartDisk !== 0)
|
|
5014
|
+
throw new Error("Unsupported: multi-disk");
|
|
5015
|
+
const entries = [];
|
|
5016
|
+
let cdPtr = eocd.cdOffset;
|
|
5017
|
+
for (let i = 0; i < eocd.cdRecordsTotal; i++) {
|
|
5018
|
+
const { value: cdf, offset: next } = readStruct(
|
|
5019
|
+
view,
|
|
5020
|
+
cdPtr,
|
|
5021
|
+
SCHEMA.CentralFile
|
|
5022
|
+
);
|
|
5023
|
+
ensureSig(cdf.signature, SIG.CentralFile, "Central Directory");
|
|
5024
|
+
const name = new TextDecoder().decode(cdf.name);
|
|
5025
|
+
const isDir = (cdf.extAttrs & 16) !== 0 || name.endsWith("/");
|
|
5026
|
+
if (cdf.extraLen !== 0 || cdf.commentLen !== 0)
|
|
5027
|
+
throw new Error("Unsupported: extra/comment in central dir");
|
|
5028
|
+
entries.push({
|
|
5029
|
+
name,
|
|
5030
|
+
isDirectory: isDir,
|
|
5031
|
+
crc32: cdf.crc32 >>> 0,
|
|
5032
|
+
size: cdf.uncompSize >>> 0,
|
|
5033
|
+
compSize: cdf.compSize >>> 0,
|
|
5034
|
+
time: cdf.time >>> 0,
|
|
5035
|
+
dosDate: cdf.date >>> 0,
|
|
5036
|
+
localHeaderOffset: cdf.localHeaderOffset >>> 0
|
|
5037
|
+
});
|
|
5038
|
+
cdPtr = next;
|
|
5039
|
+
}
|
|
5040
|
+
const results = [];
|
|
5041
|
+
for (const e of entries) {
|
|
5042
|
+
const { value: lfh, offset: afterHeader } = readStruct(
|
|
5043
|
+
view,
|
|
5044
|
+
e.localHeaderOffset,
|
|
5045
|
+
SCHEMA.LocalFile
|
|
5046
|
+
);
|
|
5047
|
+
ensureSig(lfh.signature, SIG.LocalFile, "Local File");
|
|
5048
|
+
if (lfh.flags !== 2048)
|
|
5049
|
+
throw new Error("Unsupported: flags (expect UTF-8 only)");
|
|
5050
|
+
if (lfh.method !== 0)
|
|
5051
|
+
throw new Error("Unsupported: compression (expect store only)");
|
|
5052
|
+
if (lfh.extraLen !== 0)
|
|
5053
|
+
throw new Error("Unsupported: extra fields in local header");
|
|
5054
|
+
const dataStart = afterHeader;
|
|
5055
|
+
const dataEnd = dataStart + lfh.compSize;
|
|
5056
|
+
const data = e.isDirectory ? new Uint8Array(0) : new Uint8Array(u8.subarray(dataStart, dataEnd));
|
|
5057
|
+
results.push({ ...e, data });
|
|
5058
|
+
}
|
|
5059
|
+
return results;
|
|
5060
|
+
}
|
|
5061
|
+
// Quick utility: return a map of file data (directories omitted)
|
|
5062
|
+
static extract(input) {
|
|
5063
|
+
const entries = this.parse(input);
|
|
5064
|
+
const out = {};
|
|
5065
|
+
for (const e of entries) if (!e.isDirectory) out[e.name] = e.data;
|
|
5066
|
+
return out;
|
|
5067
|
+
}
|
|
5068
|
+
};
|
|
5069
|
+
function toU8(input) {
|
|
5070
|
+
if (typeof input === "string") return utf8(input);
|
|
5071
|
+
if (input instanceof Uint8Array) return input;
|
|
5072
|
+
return new Uint8Array(input);
|
|
5073
|
+
}
|
|
5074
|
+
function findEOCDOffset(u8) {
|
|
5075
|
+
const view = new DataView(u8.buffer, u8.byteOffset, u8.byteLength);
|
|
5076
|
+
const minSize = 22;
|
|
5077
|
+
if (u8.length >= minSize) {
|
|
5078
|
+
const at = u8.length - minSize;
|
|
5079
|
+
if (view.getUint32(at, true) === SIG.EOCD) return at;
|
|
5080
|
+
}
|
|
5081
|
+
const start = Math.max(0, u8.length - 1024);
|
|
5082
|
+
for (let i = u8.length - 4; i >= start; i--) {
|
|
5083
|
+
if (view.getUint32(i, true) === SIG.EOCD) return i;
|
|
5084
|
+
}
|
|
5085
|
+
throw new Error("EOCD not found");
|
|
5086
|
+
}
|
|
5087
|
+
|
|
5088
|
+
// src/inspector/serialization.ts
|
|
5089
|
+
async function fetchAssetMap(assets) {
|
|
5090
|
+
const res = await Promise.all(
|
|
5091
|
+
assets.map(async (asset) => {
|
|
5092
|
+
const url = asset.url;
|
|
5093
|
+
const response = await fetch(url);
|
|
5094
|
+
const data = await response.arrayBuffer();
|
|
5095
|
+
return [asset.id, data];
|
|
5096
|
+
})
|
|
5097
|
+
);
|
|
5098
|
+
return Object.fromEntries(res);
|
|
5099
|
+
}
|
|
5100
|
+
async function exportAll(noyaManager) {
|
|
5101
|
+
const { multiplayerStateManager, assetManager } = noyaManager;
|
|
5102
|
+
const assetMap = await fetchAssetMap(assetManager.assets$.get());
|
|
5103
|
+
return encodeAll({
|
|
5104
|
+
state: multiplayerStateManager.optimisticState$.get(),
|
|
5105
|
+
schema: multiplayerStateManager.schema,
|
|
5106
|
+
assets: assetManager.assets$.get(),
|
|
5107
|
+
assetMap
|
|
5108
|
+
});
|
|
5109
|
+
}
|
|
5110
|
+
function encodeAll({
|
|
5111
|
+
state,
|
|
5112
|
+
schema,
|
|
5113
|
+
assets,
|
|
5114
|
+
assetMap
|
|
5115
|
+
}) {
|
|
5116
|
+
const zip = new TinyZip();
|
|
5117
|
+
zip.addFile("state.json", JSON.stringify(state, null, 2));
|
|
5118
|
+
if (schema) {
|
|
5119
|
+
const encodedSchema = encodeSchema(schema);
|
|
5120
|
+
zip.addFile("schema.json", JSON.stringify(encodedSchema, null, 2));
|
|
5121
|
+
}
|
|
5122
|
+
if (assets.length) {
|
|
5123
|
+
zip.addFile("assets.json", JSON.stringify(assets, null, 2));
|
|
5124
|
+
}
|
|
5125
|
+
for (const [id, data] of Object.entries(assetMap)) {
|
|
5126
|
+
zip.addFile(`assets/${id}`, data);
|
|
5127
|
+
}
|
|
5128
|
+
return zip.finish();
|
|
5129
|
+
}
|
|
5130
|
+
async function importAll(buffer, noyaManager, {
|
|
5131
|
+
shouldAllowSchemaChange
|
|
5132
|
+
} = {}) {
|
|
5133
|
+
let { state, schema, assets, assetMap } = await decodeAll(buffer);
|
|
5134
|
+
if (shouldAllowSchemaChange && noyaManager.options.schema && schema) {
|
|
5135
|
+
const oldSchemaHash = createHash(noyaManager.options.schema);
|
|
5136
|
+
const newSchemaHash = createHash(schema);
|
|
5137
|
+
if (oldSchemaHash !== newSchemaHash) {
|
|
5138
|
+
const shouldAllow = shouldAllowSchemaChange({
|
|
5139
|
+
oldSchema: noyaManager.options.schema,
|
|
5140
|
+
newSchema: schema
|
|
5141
|
+
});
|
|
5142
|
+
if (!shouldAllow) {
|
|
5143
|
+
throw new Error("Schema change not allowed");
|
|
5144
|
+
}
|
|
5145
|
+
}
|
|
5146
|
+
}
|
|
5147
|
+
if (assets.length) {
|
|
5148
|
+
await Promise.all(
|
|
5149
|
+
noyaManager.assetManager.assets$.get().map((asset) => noyaManager.assetManager.delete(asset.id))
|
|
5150
|
+
);
|
|
5151
|
+
const idPairs = await Promise.all(
|
|
5152
|
+
assets.map(async (asset) => {
|
|
5153
|
+
const newAsset = await noyaManager.assetManager.create({
|
|
5154
|
+
data: assetMap[asset.id],
|
|
5155
|
+
contentType: asset.contentType
|
|
5156
|
+
});
|
|
5157
|
+
return [asset.id, newAsset.id];
|
|
5158
|
+
})
|
|
5159
|
+
);
|
|
5160
|
+
const replacementMap = Object.fromEntries(idPairs);
|
|
5161
|
+
state = replaceDeep(state, replacementMap);
|
|
5162
|
+
}
|
|
5163
|
+
noyaManager.initialState = state;
|
|
5164
|
+
noyaManager.forceInit();
|
|
5165
|
+
}
|
|
5166
|
+
function decodeAll(buffer) {
|
|
5167
|
+
const zip = TinyZip.extract(buffer);
|
|
5168
|
+
const stateFile = zip["state.json"];
|
|
5169
|
+
const schemaFile = zip["schema.json"];
|
|
5170
|
+
const assetsFile = zip["assets.json"];
|
|
5171
|
+
if (!stateFile) {
|
|
5172
|
+
throw new Error("State file not found");
|
|
5173
|
+
}
|
|
5174
|
+
const state = JSON.parse(new TextDecoder().decode(stateFile));
|
|
5175
|
+
let schema;
|
|
5176
|
+
if (schemaFile) {
|
|
5177
|
+
const encodedSchema = JSON.parse(new TextDecoder().decode(schemaFile));
|
|
5178
|
+
schema = decodeSchema(encodedSchema);
|
|
5179
|
+
}
|
|
5180
|
+
let assets = [];
|
|
5181
|
+
let assetMap = {};
|
|
5182
|
+
if (assetsFile) {
|
|
5183
|
+
assets = JSON.parse(new TextDecoder().decode(assetsFile));
|
|
5184
|
+
for (const asset of assets) {
|
|
5185
|
+
const data = zip[`assets/${asset.id}`];
|
|
5186
|
+
if (!data) {
|
|
5187
|
+
throw new Error(`Asset ${asset.id} not found`);
|
|
5188
|
+
}
|
|
5189
|
+
assetMap[asset.id] = data;
|
|
5190
|
+
}
|
|
5191
|
+
}
|
|
5192
|
+
return { state, schema, assets, assetMap };
|
|
5193
|
+
}
|
|
5194
|
+
function replaceDeep(obj, replacementMap) {
|
|
5195
|
+
switch (typeof obj) {
|
|
5196
|
+
case "object":
|
|
5197
|
+
if (obj === null) {
|
|
5198
|
+
return obj;
|
|
5199
|
+
}
|
|
5200
|
+
if (Array.isArray(obj)) {
|
|
5201
|
+
return obj.map((item) => replaceDeep(item, replacementMap));
|
|
5202
|
+
}
|
|
5203
|
+
return Object.fromEntries(
|
|
5204
|
+
Object.entries(obj).map(([key, value]) => [
|
|
5205
|
+
key,
|
|
5206
|
+
replaceDeep(value, replacementMap)
|
|
5207
|
+
])
|
|
5208
|
+
);
|
|
5209
|
+
case "string":
|
|
5210
|
+
return replacementMap[obj] ?? obj;
|
|
5211
|
+
default:
|
|
5212
|
+
return obj;
|
|
5213
|
+
}
|
|
5214
|
+
}
|
|
5215
|
+
|
|
5216
|
+
// src/inspector/StateInspectorToggleButton.tsx
|
|
5217
|
+
import React10 from "react";
|
|
5218
|
+
function StateInspectorToggleButton({
|
|
5219
|
+
showInspector,
|
|
5220
|
+
setShowInspector,
|
|
5221
|
+
theme,
|
|
5222
|
+
anchor
|
|
5223
|
+
}) {
|
|
5224
|
+
const isRightAnchor = anchor === "right";
|
|
5225
|
+
const rightIcon = /* @__PURE__ */ React10.createElement(
|
|
5226
|
+
"svg",
|
|
5227
|
+
{
|
|
5228
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
5229
|
+
fill: "none",
|
|
5230
|
+
viewBox: "0 0 24 24",
|
|
5231
|
+
strokeWidth: 1.5,
|
|
5232
|
+
stroke: "currentColor",
|
|
5233
|
+
className: "size-6"
|
|
5234
|
+
},
|
|
5235
|
+
/* @__PURE__ */ React10.createElement(
|
|
5236
|
+
"path",
|
|
5237
|
+
{
|
|
5238
|
+
strokeLinecap: "round",
|
|
5239
|
+
strokeLinejoin: "round",
|
|
5240
|
+
d: "m5.25 4.5 7.5 7.5-7.5 7.5m6-15 7.5 7.5-7.5 7.5"
|
|
5241
|
+
}
|
|
5242
|
+
)
|
|
5243
|
+
);
|
|
5244
|
+
const leftIcon = /* @__PURE__ */ React10.createElement(
|
|
5245
|
+
"svg",
|
|
5246
|
+
{
|
|
5247
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
5248
|
+
fill: "none",
|
|
5249
|
+
viewBox: "0 0 24 24",
|
|
5250
|
+
strokeWidth: 1.5,
|
|
5251
|
+
stroke: "currentColor",
|
|
5252
|
+
className: "size-6"
|
|
5253
|
+
},
|
|
5254
|
+
/* @__PURE__ */ React10.createElement(
|
|
5255
|
+
"path",
|
|
5256
|
+
{
|
|
5257
|
+
strokeLinecap: "round",
|
|
5258
|
+
strokeLinejoin: "round",
|
|
5259
|
+
d: "m18.75 4.5-7.5 7.5 7.5 7.5m-6-15L5.25 12l7.5 7.5"
|
|
5260
|
+
}
|
|
5261
|
+
)
|
|
5262
|
+
);
|
|
5263
|
+
return /* @__PURE__ */ React10.createElement(
|
|
5264
|
+
"span",
|
|
5265
|
+
{
|
|
5266
|
+
role: "button",
|
|
5267
|
+
style: {
|
|
5268
|
+
flex: "0",
|
|
5269
|
+
appearance: "none",
|
|
5270
|
+
color: theme.BASE_COLOR,
|
|
5271
|
+
border: "none",
|
|
5272
|
+
fontSize: "12px",
|
|
5273
|
+
whiteSpace: "nowrap",
|
|
5274
|
+
display: "inline-flex",
|
|
5275
|
+
alignItems: "center",
|
|
5276
|
+
justifyContent: "center",
|
|
5277
|
+
padding: "2px 0"
|
|
5278
|
+
},
|
|
5279
|
+
onClick: (event) => {
|
|
5280
|
+
event.stopPropagation();
|
|
5281
|
+
setShowInspector(!showInspector);
|
|
5282
|
+
}
|
|
5283
|
+
},
|
|
5284
|
+
showInspector ? "Hide Inspector" : /* @__PURE__ */ React10.createElement("span", { style: { width: "12px", height: "12px" } }, isRightAnchor ? rightIcon : leftIcon)
|
|
5285
|
+
);
|
|
5286
|
+
}
|
|
5287
|
+
|
|
5288
|
+
// src/inspector/useLocalStorageState.tsx
|
|
5289
|
+
import React11 from "react";
|
|
5290
|
+
var localStorage = typeof window !== "undefined" ? window.localStorage : null;
|
|
5291
|
+
function useLocalStorageState(key, defaultValue) {
|
|
5292
|
+
const [state, setState] = React11.useState(() => {
|
|
5293
|
+
const value = localStorage?.getItem(key);
|
|
5294
|
+
let result = defaultValue;
|
|
5295
|
+
if (value) {
|
|
5296
|
+
try {
|
|
5297
|
+
result = JSON.parse(value);
|
|
5298
|
+
} catch (error) {
|
|
5299
|
+
console.error("Error parsing localStorage value", error);
|
|
5300
|
+
}
|
|
5301
|
+
}
|
|
5302
|
+
return result;
|
|
5303
|
+
});
|
|
5304
|
+
const setLocalStorageState = (value) => {
|
|
5305
|
+
localStorage?.setItem(key, JSON.stringify(value));
|
|
5306
|
+
setState(value);
|
|
5307
|
+
};
|
|
5308
|
+
return [state, setLocalStorageState];
|
|
5309
|
+
}
|
|
5310
|
+
|
|
5311
|
+
// src/inspector/StateInspector.tsx
|
|
5312
|
+
var StateInspector = memoGeneric(function StateInspector2({
|
|
5313
|
+
noyaManager,
|
|
5314
|
+
colorScheme = "light",
|
|
5315
|
+
anchor = "right",
|
|
5316
|
+
unstyled = false,
|
|
5317
|
+
...props
|
|
5318
|
+
}) {
|
|
5319
|
+
const {
|
|
5320
|
+
multiplayerStateManager,
|
|
5321
|
+
assetManager,
|
|
5322
|
+
connectedUsersManager,
|
|
5323
|
+
secretManager,
|
|
5324
|
+
ephemeralUserDataManager,
|
|
5325
|
+
connectionEventManager,
|
|
5326
|
+
taskManager,
|
|
5327
|
+
ioManager
|
|
5328
|
+
} = noyaManager;
|
|
5329
|
+
const [didMount, setDidMount] = React12.useState(false);
|
|
5330
|
+
const tasks = useObservable(taskManager.tasks$);
|
|
5331
|
+
const inputs = useObservable(ioManager.inputs$);
|
|
5332
|
+
const outputTransforms = useObservable(ioManager.outputTransforms$);
|
|
5333
|
+
useLayoutEffect(() => {
|
|
5334
|
+
setDidMount(true);
|
|
5335
|
+
}, []);
|
|
5336
|
+
const eventsContainerRef = React12.useRef(null);
|
|
5337
|
+
const [showInspector, setShowInspector] = useLocalStorageState(
|
|
5338
|
+
"noya-multiplayer-react-show-inspector",
|
|
5339
|
+
true
|
|
5340
|
+
);
|
|
5341
|
+
const [showEvents, setShowEvents] = useLocalStorageState(
|
|
5342
|
+
"noya-multiplayer-react-show-events",
|
|
5343
|
+
false
|
|
5344
|
+
);
|
|
5345
|
+
const [showHistory, setShowHistory] = useLocalStorageState(
|
|
5346
|
+
"noya-multiplayer-react-show-history",
|
|
5347
|
+
false
|
|
5348
|
+
);
|
|
5349
|
+
const [showUsers, setShowUsers] = useLocalStorageState(
|
|
5350
|
+
"noya-multiplayer-react-show-users",
|
|
5351
|
+
true
|
|
5352
|
+
);
|
|
5353
|
+
const [showData, setShowData] = useLocalStorageState(
|
|
5354
|
+
"noya-multiplayer-react-show-data",
|
|
5355
|
+
true
|
|
5356
|
+
);
|
|
5357
|
+
const [showTasks, setShowTasks] = useLocalStorageState(
|
|
5358
|
+
"noya-multiplayer-react-show-tasks",
|
|
5359
|
+
false
|
|
5360
|
+
);
|
|
5361
|
+
const [showEphemeral, setShowEphemeral] = useLocalStorageState(
|
|
5362
|
+
"noya-multiplayer-react-show-ephemeral",
|
|
5363
|
+
false
|
|
5364
|
+
);
|
|
5365
|
+
const [showAssets, setShowAssets] = useLocalStorageState(
|
|
5366
|
+
"noya-multiplayer-react-show-assets",
|
|
5367
|
+
false
|
|
5368
|
+
);
|
|
5369
|
+
const [showSecrets, setShowSecrets] = useLocalStorageState(
|
|
5370
|
+
"noya-multiplayer-react-show-secrets",
|
|
5371
|
+
false
|
|
4328
5372
|
);
|
|
4329
5373
|
const [showInputs, setShowInputs] = useLocalStorageState(
|
|
4330
5374
|
"noya-multiplayer-react-show-inputs",
|
|
@@ -4335,7 +5379,7 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
4335
5379
|
false
|
|
4336
5380
|
);
|
|
4337
5381
|
const connectionEvents = useObservable(connectionEventManager.events$);
|
|
4338
|
-
|
|
5382
|
+
useEffect2(() => {
|
|
4339
5383
|
if (eventsContainerRef.current) {
|
|
4340
5384
|
eventsContainerRef.current.scrollTop = eventsContainerRef.current.scrollHeight;
|
|
4341
5385
|
}
|
|
@@ -4356,25 +5400,8 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
4356
5400
|
const outputTransformsInitialized = useObservable(
|
|
4357
5401
|
ioManager.outputTransformsInitialized$
|
|
4358
5402
|
);
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
historyContainerRef.current.scrollTop = historyContainerRef.current.scrollHeight;
|
|
4362
|
-
}
|
|
4363
|
-
}, [historySnapshot]);
|
|
4364
|
-
useEffect(() => {
|
|
4365
|
-
if (!historyContainerRef.current) return;
|
|
4366
|
-
const historyEntry = historyContainerRef.current.querySelector(
|
|
4367
|
-
`#${HISTORY_ELEMENT_PREFIX}${historySnapshot.historyIndex}`
|
|
4368
|
-
);
|
|
4369
|
-
if (historyEntry) {
|
|
4370
|
-
historyEntry.scrollIntoView({
|
|
4371
|
-
block: "nearest",
|
|
4372
|
-
inline: "nearest"
|
|
4373
|
-
});
|
|
4374
|
-
}
|
|
4375
|
-
}, [historySnapshot.historyIndex]);
|
|
4376
|
-
const theme = colorScheme === "light" ? lightTheme : darkTheme;
|
|
4377
|
-
const solidBorderColor = colorScheme === "light" ? "rgb(223 223 223)" : "rgb(29 29 29)";
|
|
5403
|
+
const theme = getStateInspectorTheme(colorScheme);
|
|
5404
|
+
const solidBorderColor = getStateInspectorBorderColor(colorScheme);
|
|
4378
5405
|
const baseStyle = {
|
|
4379
5406
|
position: "fixed",
|
|
4380
5407
|
top: 12,
|
|
@@ -4394,9 +5421,24 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
4394
5421
|
zIndex: 9999,
|
|
4395
5422
|
lineHeight: "13px"
|
|
4396
5423
|
};
|
|
5424
|
+
const handleExportAll = useCallback(async () => {
|
|
5425
|
+
const buffer = await exportAll(noyaManager);
|
|
5426
|
+
downloadBlob(new Blob([buffer]), "state.zip");
|
|
5427
|
+
}, [noyaManager]);
|
|
5428
|
+
const handleImportAll = useCallback(async () => {
|
|
5429
|
+
const file = await uploadFile();
|
|
5430
|
+
const buffer = await file.arrayBuffer();
|
|
5431
|
+
importAll(buffer, noyaManager, {
|
|
5432
|
+
shouldAllowSchemaChange: () => {
|
|
5433
|
+
return confirm(
|
|
5434
|
+
`The imported state uses a different schema than the schema this app expects. Do you want to continue?`
|
|
5435
|
+
);
|
|
5436
|
+
}
|
|
5437
|
+
});
|
|
5438
|
+
}, [noyaManager]);
|
|
4397
5439
|
if (!didMount) return null;
|
|
4398
5440
|
if (!showInspector) {
|
|
4399
|
-
return /* @__PURE__ */
|
|
5441
|
+
return /* @__PURE__ */ React12.createElement(
|
|
4400
5442
|
"div",
|
|
4401
5443
|
{
|
|
4402
5444
|
...props,
|
|
@@ -4408,8 +5450,8 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
4408
5450
|
},
|
|
4409
5451
|
onClick: () => setShowInspector(true)
|
|
4410
5452
|
},
|
|
4411
|
-
/* @__PURE__ */
|
|
4412
|
-
|
|
5453
|
+
/* @__PURE__ */ React12.createElement(
|
|
5454
|
+
StateInspectorToggleButton,
|
|
4413
5455
|
{
|
|
4414
5456
|
showInspector,
|
|
4415
5457
|
setShowInspector,
|
|
@@ -4419,7 +5461,7 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
4419
5461
|
)
|
|
4420
5462
|
);
|
|
4421
5463
|
}
|
|
4422
|
-
return /* @__PURE__ */
|
|
5464
|
+
return /* @__PURE__ */ React12.createElement(
|
|
4423
5465
|
"div",
|
|
4424
5466
|
{
|
|
4425
5467
|
...props,
|
|
@@ -4428,8 +5470,8 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
4428
5470
|
...props.style
|
|
4429
5471
|
}
|
|
4430
5472
|
},
|
|
4431
|
-
/* @__PURE__ */
|
|
4432
|
-
|
|
5473
|
+
/* @__PURE__ */ React12.createElement(
|
|
5474
|
+
StateInspectorDisclosureSection,
|
|
4433
5475
|
{
|
|
4434
5476
|
isFirst: true,
|
|
4435
5477
|
open: showUsers,
|
|
@@ -4440,8 +5482,8 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
4440
5482
|
flex: "0 0 auto",
|
|
4441
5483
|
maxHeight: "200px"
|
|
4442
5484
|
},
|
|
4443
|
-
right: /* @__PURE__ */
|
|
4444
|
-
|
|
5485
|
+
right: /* @__PURE__ */ React12.createElement(
|
|
5486
|
+
StateInspectorToggleButton,
|
|
4445
5487
|
{
|
|
4446
5488
|
showInspector,
|
|
4447
5489
|
setShowInspector,
|
|
@@ -4450,14 +5492,14 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
4450
5492
|
}
|
|
4451
5493
|
)
|
|
4452
5494
|
},
|
|
4453
|
-
/* @__PURE__ */
|
|
4454
|
-
|
|
5495
|
+
/* @__PURE__ */ React12.createElement(StateInspectorDisclosureRowInner, { style: { flex: "0 0 auto" } }, connectedUsers?.map((user) => /* @__PURE__ */ React12.createElement(
|
|
5496
|
+
StateInspectorRow,
|
|
4455
5497
|
{
|
|
4456
5498
|
key: user.id,
|
|
4457
5499
|
colorScheme,
|
|
4458
5500
|
variant: user.id === userId ? "up" : void 0
|
|
4459
5501
|
},
|
|
4460
|
-
user.image && /* @__PURE__ */
|
|
5502
|
+
user.image && /* @__PURE__ */ React12.createElement(
|
|
4461
5503
|
"img",
|
|
4462
5504
|
{
|
|
4463
5505
|
src: user.image,
|
|
@@ -4478,7 +5520,7 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
4478
5520
|
" (",
|
|
4479
5521
|
ellipsis(user.id.toString(), 8, "middle"),
|
|
4480
5522
|
")"
|
|
4481
|
-
)), !connectedUsers && /* @__PURE__ */
|
|
5523
|
+
)), !connectedUsers && /* @__PURE__ */ React12.createElement(
|
|
4482
5524
|
"div",
|
|
4483
5525
|
{
|
|
4484
5526
|
style: {
|
|
@@ -4489,13 +5531,13 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
4489
5531
|
gap: "4px"
|
|
4490
5532
|
}
|
|
4491
5533
|
},
|
|
4492
|
-
/* @__PURE__ */
|
|
5534
|
+
/* @__PURE__ */ React12.createElement("span", null, "No connected users")
|
|
4493
5535
|
))
|
|
4494
5536
|
),
|
|
4495
|
-
/* @__PURE__ */
|
|
4496
|
-
|
|
5537
|
+
/* @__PURE__ */ React12.createElement(
|
|
5538
|
+
StateInspectorDisclosureSection,
|
|
4497
5539
|
{
|
|
4498
|
-
title: /* @__PURE__ */
|
|
5540
|
+
title: /* @__PURE__ */ React12.createElement(TitleLabel, null, "Data", /* @__PURE__ */ React12.createElement(
|
|
4499
5541
|
ColoredDot,
|
|
4500
5542
|
{
|
|
4501
5543
|
type: multipeerStateInitialized ? "success" : "error"
|
|
@@ -4504,16 +5546,18 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
4504
5546
|
colorScheme,
|
|
4505
5547
|
setOpen: setShowData,
|
|
4506
5548
|
open: showData,
|
|
4507
|
-
right: /* @__PURE__ */
|
|
5549
|
+
right: /* @__PURE__ */ React12.createElement(
|
|
4508
5550
|
"span",
|
|
4509
5551
|
{
|
|
4510
5552
|
style: {
|
|
4511
5553
|
display: "flex",
|
|
4512
|
-
gap: "
|
|
5554
|
+
gap: "12px"
|
|
4513
5555
|
}
|
|
4514
5556
|
},
|
|
4515
|
-
/* @__PURE__ */
|
|
4516
|
-
|
|
5557
|
+
/* @__PURE__ */ React12.createElement(StateInspectorButton, { theme, onClick: handleImportAll }, "Import"),
|
|
5558
|
+
/* @__PURE__ */ React12.createElement(StateInspectorButton, { theme, onClick: handleExportAll }, "Export"),
|
|
5559
|
+
/* @__PURE__ */ React12.createElement(
|
|
5560
|
+
StateInspectorButton,
|
|
4517
5561
|
{
|
|
4518
5562
|
theme,
|
|
4519
5563
|
onClick: () => {
|
|
@@ -4524,15 +5568,15 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
4524
5568
|
)
|
|
4525
5569
|
)
|
|
4526
5570
|
},
|
|
4527
|
-
/* @__PURE__ */
|
|
4528
|
-
|
|
5571
|
+
/* @__PURE__ */ React12.createElement(StateInspectorDisclosureRowInner, null, /* @__PURE__ */ React12.createElement(StateInspectorRow, { colorScheme }, /* @__PURE__ */ React12.createElement(
|
|
5572
|
+
ObjectInspector3,
|
|
4529
5573
|
{
|
|
4530
5574
|
name: multiplayerStateManager.schema ? "state" : void 0,
|
|
4531
5575
|
data: state,
|
|
4532
5576
|
theme
|
|
4533
5577
|
}
|
|
4534
|
-
)), multiplayerStateManager.schema && /* @__PURE__ */
|
|
4535
|
-
|
|
5578
|
+
)), multiplayerStateManager.schema && /* @__PURE__ */ React12.createElement(StateInspectorRow, { colorScheme }, /* @__PURE__ */ React12.createElement(
|
|
5579
|
+
ObjectInspector3,
|
|
4536
5580
|
{
|
|
4537
5581
|
name: "schema",
|
|
4538
5582
|
data: multiplayerStateManager.schema,
|
|
@@ -4540,151 +5584,25 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
4540
5584
|
}
|
|
4541
5585
|
)))
|
|
4542
5586
|
),
|
|
4543
|
-
/* @__PURE__ */
|
|
4544
|
-
|
|
5587
|
+
/* @__PURE__ */ React12.createElement(
|
|
5588
|
+
HistorySection,
|
|
4545
5589
|
{
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
title: "History",
|
|
5590
|
+
showHistory,
|
|
5591
|
+
setShowHistory,
|
|
4549
5592
|
colorScheme,
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
style: {
|
|
4554
|
-
display: "flex",
|
|
4555
|
-
gap: "4px"
|
|
4556
|
-
}
|
|
4557
|
-
},
|
|
4558
|
-
/* @__PURE__ */ React3.createElement(
|
|
4559
|
-
SmallButton,
|
|
4560
|
-
{
|
|
4561
|
-
disabled: !historySnapshot.canUndo,
|
|
4562
|
-
theme,
|
|
4563
|
-
onClick: () => {
|
|
4564
|
-
multiplayerStateManager.undo();
|
|
4565
|
-
}
|
|
4566
|
-
},
|
|
4567
|
-
/* @__PURE__ */ React3.createElement("span", { style: { width: "12px", height: "12px" } }, /* @__PURE__ */ React3.createElement(
|
|
4568
|
-
"svg",
|
|
4569
|
-
{
|
|
4570
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
4571
|
-
width: "1em",
|
|
4572
|
-
height: "1em",
|
|
4573
|
-
viewBox: "0 0 20 20"
|
|
4574
|
-
},
|
|
4575
|
-
/* @__PURE__ */ React3.createElement(
|
|
4576
|
-
"path",
|
|
4577
|
-
{
|
|
4578
|
-
fill: "currentColor",
|
|
4579
|
-
d: "M12 5H7V2L1 6l6 4V7h5c2.2 0 4 1.8 4 4s-1.8 4-4 4H7v2h5c3.3 0 6-2.7 6-6s-2.7-6-6-6"
|
|
4580
|
-
}
|
|
4581
|
-
)
|
|
4582
|
-
))
|
|
4583
|
-
),
|
|
4584
|
-
/* @__PURE__ */ React3.createElement(
|
|
4585
|
-
SmallButton,
|
|
4586
|
-
{
|
|
4587
|
-
disabled: !historySnapshot.canRedo,
|
|
4588
|
-
theme,
|
|
4589
|
-
onClick: () => {
|
|
4590
|
-
multiplayerStateManager.redo();
|
|
4591
|
-
}
|
|
4592
|
-
},
|
|
4593
|
-
/* @__PURE__ */ React3.createElement("span", { style: { width: "12px", height: "12px" } }, /* @__PURE__ */ React3.createElement(
|
|
4594
|
-
"svg",
|
|
4595
|
-
{
|
|
4596
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
4597
|
-
width: "1em",
|
|
4598
|
-
height: "1em",
|
|
4599
|
-
viewBox: "0 0 20 20"
|
|
4600
|
-
},
|
|
4601
|
-
/* @__PURE__ */ React3.createElement(
|
|
4602
|
-
"path",
|
|
4603
|
-
{
|
|
4604
|
-
fill: "currentColor",
|
|
4605
|
-
d: "M8 5h5V2l6 4l-6 4V7H8c-2.2 0-4 1.8-4 4s1.8 4 4 4h5v2H8c-3.3 0-6-2.7-6-6s2.7-6 6-6"
|
|
4606
|
-
}
|
|
4607
|
-
)
|
|
4608
|
-
))
|
|
4609
|
-
)
|
|
4610
|
-
)
|
|
4611
|
-
},
|
|
4612
|
-
/* @__PURE__ */ React3.createElement("div", { ref: historyContainerRef, style: styles.sectionInner }, /* @__PURE__ */ React3.createElement(
|
|
4613
|
-
"div",
|
|
4614
|
-
{
|
|
4615
|
-
id: `${HISTORY_ELEMENT_PREFIX}0`,
|
|
4616
|
-
style: {
|
|
4617
|
-
borderBottom: `1px solid ${solidBorderColor}`,
|
|
4618
|
-
fontSize: "12px",
|
|
4619
|
-
fontFamily: "Menlo, monospace",
|
|
4620
|
-
padding: "2px 12px 1px",
|
|
4621
|
-
display: "flex",
|
|
4622
|
-
alignItems: "center",
|
|
4623
|
-
background: historySnapshot.historyIndex === 0 ? "rgb(59 130 246 / 15%)" : void 0
|
|
4624
|
-
}
|
|
4625
|
-
},
|
|
4626
|
-
/* @__PURE__ */ React3.createElement(
|
|
4627
|
-
"span",
|
|
4628
|
-
{
|
|
4629
|
-
style: {
|
|
4630
|
-
fontFamily: "Menlo, monospace",
|
|
4631
|
-
fontSize: "11px",
|
|
4632
|
-
borderRadius: 4,
|
|
4633
|
-
display: "inline-block"
|
|
4634
|
-
}
|
|
4635
|
-
},
|
|
4636
|
-
"Initial state"
|
|
4637
|
-
)
|
|
4638
|
-
), historySnapshot.history.map((entry, index) => /* @__PURE__ */ React3.createElement(
|
|
4639
|
-
"div",
|
|
4640
|
-
{
|
|
4641
|
-
id: `${HISTORY_ELEMENT_PREFIX}${index + 1}`,
|
|
4642
|
-
key: index,
|
|
4643
|
-
style: {
|
|
4644
|
-
padding: "0px 12px 1px",
|
|
4645
|
-
borderBottom: `1px solid ${solidBorderColor}`,
|
|
4646
|
-
background: index + 1 === historySnapshot.historyIndex ? "rgb(59 130 246 / 15%)" : void 0
|
|
4647
|
-
}
|
|
4648
|
-
},
|
|
4649
|
-
"name" in entry.metadata && typeof entry.metadata.name === "string" && /* @__PURE__ */ React3.createElement(
|
|
4650
|
-
"pre",
|
|
4651
|
-
{
|
|
4652
|
-
style: {
|
|
4653
|
-
fontSize: "11px",
|
|
4654
|
-
display: "flex",
|
|
4655
|
-
flexWrap: "wrap",
|
|
4656
|
-
margin: 0
|
|
4657
|
-
}
|
|
4658
|
-
},
|
|
4659
|
-
entry.metadata.name
|
|
4660
|
-
),
|
|
4661
|
-
entry.redoPatches?.map((patch, j) => /* @__PURE__ */ React3.createElement(
|
|
4662
|
-
"pre",
|
|
4663
|
-
{
|
|
4664
|
-
key: j,
|
|
4665
|
-
style: {
|
|
4666
|
-
fontSize: "11px",
|
|
4667
|
-
display: "flex",
|
|
4668
|
-
flexWrap: "wrap",
|
|
4669
|
-
margin: 0
|
|
4670
|
-
}
|
|
4671
|
-
},
|
|
4672
|
-
patch.op === "add" && /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path)), " = ", /* @__PURE__ */ React3.createElement(ObjectInspector, { data: patch.value, theme })),
|
|
4673
|
-
patch.op === "replace" && /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path)), " = ", /* @__PURE__ */ React3.createElement(ObjectInspector, { data: patch.value, theme })),
|
|
4674
|
-
patch.op === "remove" && /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("span", { style: { color: theme.OBJECT_VALUE_STRING_COLOR } }, "delete", " "), /* @__PURE__ */ React3.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path))),
|
|
4675
|
-
patch.op === "move" && /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.from)), " -> ", /* @__PURE__ */ React3.createElement("span", { style: { fontStyle: "italic" } }, pathToString(patch.path)))
|
|
4676
|
-
))
|
|
4677
|
-
)))
|
|
5593
|
+
historySnapshot,
|
|
5594
|
+
multiplayerStateManager
|
|
5595
|
+
}
|
|
4678
5596
|
),
|
|
4679
|
-
/* @__PURE__ */
|
|
4680
|
-
|
|
5597
|
+
/* @__PURE__ */ React12.createElement(
|
|
5598
|
+
StateInspectorDisclosureSection,
|
|
4681
5599
|
{
|
|
4682
5600
|
open: showAssets,
|
|
4683
5601
|
setOpen: setShowAssets,
|
|
4684
|
-
title: /* @__PURE__ */
|
|
5602
|
+
title: /* @__PURE__ */ React12.createElement(TitleLabel, null, "Assets (", assets.length, ")", /* @__PURE__ */ React12.createElement(ColoredDot, { type: assetsInitialized ? "success" : "error" })),
|
|
4685
5603
|
colorScheme,
|
|
4686
|
-
right: /* @__PURE__ */
|
|
4687
|
-
|
|
5604
|
+
right: /* @__PURE__ */ React12.createElement("span", { style: { display: "flex", gap: "10px" } }, /* @__PURE__ */ React12.createElement(
|
|
5605
|
+
StateInspectorButton,
|
|
4688
5606
|
{
|
|
4689
5607
|
theme,
|
|
4690
5608
|
onClick: () => {
|
|
@@ -4696,8 +5614,8 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
4696
5614
|
}
|
|
4697
5615
|
},
|
|
4698
5616
|
"Reload"
|
|
4699
|
-
), /* @__PURE__ */
|
|
4700
|
-
|
|
5617
|
+
), /* @__PURE__ */ React12.createElement(
|
|
5618
|
+
StateInspectorButton,
|
|
4701
5619
|
{
|
|
4702
5620
|
theme,
|
|
4703
5621
|
onClick: () => {
|
|
@@ -4720,8 +5638,8 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
4720
5638
|
"Upload"
|
|
4721
5639
|
))
|
|
4722
5640
|
},
|
|
4723
|
-
/* @__PURE__ */
|
|
4724
|
-
|
|
5641
|
+
/* @__PURE__ */ React12.createElement(StateInspectorDisclosureRowInner, null, assets.map((asset) => /* @__PURE__ */ React12.createElement(StateInspectorRow, { key: asset.id, colorScheme }, /* @__PURE__ */ React12.createElement(ObjectInspector3, { name: asset.id, data: asset, theme }), /* @__PURE__ */ React12.createElement(
|
|
5642
|
+
StateInspectorButton,
|
|
4725
5643
|
{
|
|
4726
5644
|
theme,
|
|
4727
5645
|
onClick: () => assetManager.delete(asset.id)
|
|
@@ -4729,15 +5647,15 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
4729
5647
|
"Delete"
|
|
4730
5648
|
))))
|
|
4731
5649
|
),
|
|
4732
|
-
/* @__PURE__ */
|
|
4733
|
-
|
|
5650
|
+
/* @__PURE__ */ React12.createElement(
|
|
5651
|
+
StateInspectorDisclosureSection,
|
|
4734
5652
|
{
|
|
4735
|
-
title: /* @__PURE__ */
|
|
5653
|
+
title: /* @__PURE__ */ React12.createElement(TitleLabel, null, "Secrets", /* @__PURE__ */ React12.createElement(ColoredDot, { type: secretsInitialized ? "success" : "error" })),
|
|
4736
5654
|
colorScheme,
|
|
4737
5655
|
open: showSecrets,
|
|
4738
5656
|
setOpen: setShowSecrets,
|
|
4739
|
-
right: /* @__PURE__ */
|
|
4740
|
-
|
|
5657
|
+
right: /* @__PURE__ */ React12.createElement(
|
|
5658
|
+
StateInspectorButton,
|
|
4741
5659
|
{
|
|
4742
5660
|
theme,
|
|
4743
5661
|
onClick: () => {
|
|
@@ -4751,8 +5669,8 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
4751
5669
|
"Create"
|
|
4752
5670
|
)
|
|
4753
5671
|
},
|
|
4754
|
-
/* @__PURE__ */
|
|
4755
|
-
|
|
5672
|
+
/* @__PURE__ */ React12.createElement(StateInspectorDisclosureRowInner, null, secrets.map((secret) => /* @__PURE__ */ React12.createElement(StateInspectorRow, { key: secret.id, colorScheme }, /* @__PURE__ */ React12.createElement(ObjectInspector3, { data: secret, theme }), /* @__PURE__ */ React12.createElement(
|
|
5673
|
+
StateInspectorButton,
|
|
4756
5674
|
{
|
|
4757
5675
|
theme,
|
|
4758
5676
|
onClick: () => secretManager.deleteSecret(secret.id)
|
|
@@ -4761,15 +5679,15 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
4761
5679
|
))))
|
|
4762
5680
|
),
|
|
4763
5681
|
" ",
|
|
4764
|
-
/* @__PURE__ */
|
|
4765
|
-
|
|
5682
|
+
/* @__PURE__ */ React12.createElement(
|
|
5683
|
+
StateInspectorDisclosureSection,
|
|
4766
5684
|
{
|
|
4767
5685
|
open: showInputs,
|
|
4768
5686
|
setOpen: setShowInputs,
|
|
4769
|
-
title: /* @__PURE__ */
|
|
5687
|
+
title: /* @__PURE__ */ React12.createElement(TitleLabel, null, "Inputs", /* @__PURE__ */ React12.createElement(ColoredDot, { type: inputsInitialized ? "success" : "error" })),
|
|
4770
5688
|
colorScheme
|
|
4771
5689
|
},
|
|
4772
|
-
/* @__PURE__ */
|
|
5690
|
+
/* @__PURE__ */ React12.createElement(StateInspectorDisclosureRowInner, null, inputs?.map((input) => /* @__PURE__ */ React12.createElement(StateInspectorRow, { key: input.id, colorScheme }, /* @__PURE__ */ React12.createElement(ObjectInspector3, { data: input, theme }))), !inputs?.length && /* @__PURE__ */ React12.createElement(
|
|
4773
5691
|
"div",
|
|
4774
5692
|
{
|
|
4775
5693
|
style: {
|
|
@@ -4780,15 +5698,15 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
4780
5698
|
gap: "4px"
|
|
4781
5699
|
}
|
|
4782
5700
|
},
|
|
4783
|
-
/* @__PURE__ */
|
|
5701
|
+
/* @__PURE__ */ React12.createElement("span", null, "No inputs")
|
|
4784
5702
|
))
|
|
4785
5703
|
),
|
|
4786
|
-
/* @__PURE__ */
|
|
4787
|
-
|
|
5704
|
+
/* @__PURE__ */ React12.createElement(
|
|
5705
|
+
StateInspectorDisclosureSection,
|
|
4788
5706
|
{
|
|
4789
5707
|
open: showOutputTransforms,
|
|
4790
5708
|
setOpen: setShowOutputTransforms,
|
|
4791
|
-
title: /* @__PURE__ */
|
|
5709
|
+
title: /* @__PURE__ */ React12.createElement(TitleLabel, null, "Output Transforms", /* @__PURE__ */ React12.createElement(
|
|
4792
5710
|
ColoredDot,
|
|
4793
5711
|
{
|
|
4794
5712
|
type: outputTransformsInitialized ? "success" : "error"
|
|
@@ -4796,7 +5714,7 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
4796
5714
|
)),
|
|
4797
5715
|
colorScheme
|
|
4798
5716
|
},
|
|
4799
|
-
/* @__PURE__ */
|
|
5717
|
+
/* @__PURE__ */ React12.createElement(StateInspectorDisclosureRowInner, null, outputTransforms?.map((transform) => /* @__PURE__ */ React12.createElement(StateInspectorRow, { key: transform.id, colorScheme }, /* @__PURE__ */ React12.createElement(ObjectInspector3, { data: transform, theme }))), !outputTransforms?.length && /* @__PURE__ */ React12.createElement(
|
|
4800
5718
|
"div",
|
|
4801
5719
|
{
|
|
4802
5720
|
style: {
|
|
@@ -4807,19 +5725,19 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
4807
5725
|
gap: "4px"
|
|
4808
5726
|
}
|
|
4809
5727
|
},
|
|
4810
|
-
/* @__PURE__ */
|
|
5728
|
+
/* @__PURE__ */ React12.createElement("span", null, "No output transforms")
|
|
4811
5729
|
))
|
|
4812
5730
|
),
|
|
4813
|
-
/* @__PURE__ */
|
|
4814
|
-
|
|
5731
|
+
/* @__PURE__ */ React12.createElement(
|
|
5732
|
+
StateInspectorDisclosureSection,
|
|
4815
5733
|
{
|
|
4816
5734
|
title: "Tasks",
|
|
4817
5735
|
colorScheme,
|
|
4818
5736
|
open: showTasks,
|
|
4819
5737
|
setOpen: setShowTasks
|
|
4820
5738
|
},
|
|
4821
|
-
/* @__PURE__ */
|
|
4822
|
-
|
|
5739
|
+
/* @__PURE__ */ React12.createElement(StateInspectorDisclosureRowInner, null, tasks?.map((task) => /* @__PURE__ */ React12.createElement(
|
|
5740
|
+
StateInspectorRow,
|
|
4823
5741
|
{
|
|
4824
5742
|
key: task.id,
|
|
4825
5743
|
colorScheme,
|
|
@@ -4827,8 +5745,8 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
4827
5745
|
backgroundColor: task.status === "done" ? "rgba(0,255,0,0.2)" : task.status === "error" ? "rgba(255,0,0,0.2)" : void 0
|
|
4828
5746
|
}
|
|
4829
5747
|
},
|
|
4830
|
-
/* @__PURE__ */
|
|
4831
|
-
|
|
5748
|
+
/* @__PURE__ */ React12.createElement(
|
|
5749
|
+
ObjectInspector3,
|
|
4832
5750
|
{
|
|
4833
5751
|
name: task.name,
|
|
4834
5752
|
data: task.payload,
|
|
@@ -4837,16 +5755,16 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
4837
5755
|
)
|
|
4838
5756
|
)))
|
|
4839
5757
|
),
|
|
4840
|
-
/* @__PURE__ */
|
|
4841
|
-
|
|
5758
|
+
/* @__PURE__ */ React12.createElement(
|
|
5759
|
+
StateInspectorDisclosureSection,
|
|
4842
5760
|
{
|
|
4843
5761
|
open: showEphemeral,
|
|
4844
5762
|
setOpen: setShowEphemeral,
|
|
4845
5763
|
title: "Ephemeral User Data",
|
|
4846
5764
|
colorScheme
|
|
4847
5765
|
},
|
|
4848
|
-
/* @__PURE__ */
|
|
4849
|
-
|
|
5766
|
+
/* @__PURE__ */ React12.createElement(StateInspectorDisclosureRowInner, null, Object.entries(ephemeral).map(([key, value]) => /* @__PURE__ */ React12.createElement(StateInspectorRow, { key, colorScheme }, /* @__PURE__ */ React12.createElement(
|
|
5767
|
+
ObjectInspector3,
|
|
4850
5768
|
{
|
|
4851
5769
|
name: key,
|
|
4852
5770
|
data: value,
|
|
@@ -4855,187 +5773,20 @@ var StateInspector = memoGeneric(function StateInspector2({
|
|
|
4855
5773
|
}
|
|
4856
5774
|
))))
|
|
4857
5775
|
),
|
|
4858
|
-
/* @__PURE__ */
|
|
4859
|
-
|
|
5776
|
+
/* @__PURE__ */ React12.createElement(
|
|
5777
|
+
EventsSection,
|
|
4860
5778
|
{
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
|
|
4864
|
-
|
|
4865
|
-
|
|
4866
|
-
|
|
4867
|
-
(event, index) => event.type === "stateChange" ? /* @__PURE__ */ React3.createElement(InspectorRow, { key: index, colorScheme }, "connection:", " ", /* @__PURE__ */ React3.createElement("span", { style: { fontStyle: "italic" } }, event.state.toLowerCase())) : /* @__PURE__ */ React3.createElement(
|
|
4868
|
-
InspectorRow,
|
|
4869
|
-
{
|
|
4870
|
-
key: index,
|
|
4871
|
-
colorScheme,
|
|
4872
|
-
variant: event.type === "send" ? "up" : "down",
|
|
4873
|
-
style: {
|
|
4874
|
-
padding: "0px 12px 1px"
|
|
4875
|
-
}
|
|
4876
|
-
},
|
|
4877
|
-
/* @__PURE__ */ React3.createElement(
|
|
4878
|
-
ObjectInspector,
|
|
4879
|
-
{
|
|
4880
|
-
data: event.type === "error" ? event.error : event.message,
|
|
4881
|
-
theme,
|
|
4882
|
-
nodeRenderer: ({
|
|
4883
|
-
depth,
|
|
4884
|
-
name,
|
|
4885
|
-
data,
|
|
4886
|
-
isNonenumerable
|
|
4887
|
-
}) => {
|
|
4888
|
-
const direction = event.type === "send" ? "up" : "down";
|
|
4889
|
-
return depth === 0 ? /* @__PURE__ */ React3.createElement(ObjectRootLabel, { direction, data }) : /* @__PURE__ */ React3.createElement(
|
|
4890
|
-
ObjectLabel,
|
|
4891
|
-
{
|
|
4892
|
-
direction,
|
|
4893
|
-
name,
|
|
4894
|
-
data,
|
|
4895
|
-
isNonenumerable
|
|
4896
|
-
}
|
|
4897
|
-
);
|
|
4898
|
-
}
|
|
4899
|
-
}
|
|
4900
|
-
)
|
|
4901
|
-
)
|
|
4902
|
-
), !connectionEvents && /* @__PURE__ */ React3.createElement(
|
|
4903
|
-
"div",
|
|
4904
|
-
{
|
|
4905
|
-
style: {
|
|
4906
|
-
padding: "12px",
|
|
4907
|
-
fontSize: "12px",
|
|
4908
|
-
display: "flex",
|
|
4909
|
-
flexDirection: "column",
|
|
4910
|
-
gap: "4px"
|
|
4911
|
-
}
|
|
4912
|
-
},
|
|
4913
|
-
/* @__PURE__ */ React3.createElement("span", null, "No recorded events")
|
|
4914
|
-
))
|
|
5779
|
+
connectionEvents,
|
|
5780
|
+
colorScheme,
|
|
5781
|
+
eventsContainerRef,
|
|
5782
|
+
showEvents,
|
|
5783
|
+
setShowEvents
|
|
5784
|
+
}
|
|
4915
5785
|
)
|
|
4916
5786
|
);
|
|
4917
5787
|
});
|
|
4918
|
-
var ObjectRootLabel = ({ name, data, direction }) => {
|
|
4919
|
-
if (typeof name === "string") {
|
|
4920
|
-
return /* @__PURE__ */ React3.createElement("span", null, /* @__PURE__ */ React3.createElement(ObjectName, { name }), /* @__PURE__ */ React3.createElement("span", null, ": "), /* @__PURE__ */ React3.createElement(ObjectPreview, { data }));
|
|
4921
|
-
}
|
|
4922
|
-
if (direction === "up" || direction === "down") {
|
|
4923
|
-
const arrow = direction === "up" ? "\u2191" : "\u2193";
|
|
4924
|
-
return /* @__PURE__ */ React3.createElement("span", null, /* @__PURE__ */ React3.createElement(
|
|
4925
|
-
"span",
|
|
4926
|
-
{
|
|
4927
|
-
style: {
|
|
4928
|
-
background: direction === "up" ? "rgba(0,255,0,0.2)" : "rgba(255,0,0,0.2)",
|
|
4929
|
-
// color: "white",
|
|
4930
|
-
width: 12,
|
|
4931
|
-
height: 12,
|
|
4932
|
-
borderRadius: 2,
|
|
4933
|
-
display: "inline-flex",
|
|
4934
|
-
justifyContent: "center",
|
|
4935
|
-
alignItems: "center",
|
|
4936
|
-
marginRight: 4,
|
|
4937
|
-
lineHeight: "12px"
|
|
4938
|
-
}
|
|
4939
|
-
},
|
|
4940
|
-
arrow
|
|
4941
|
-
), /* @__PURE__ */ React3.createElement(ObjectPreview, { data }));
|
|
4942
|
-
} else {
|
|
4943
|
-
return /* @__PURE__ */ React3.createElement(ObjectPreview, { data });
|
|
4944
|
-
}
|
|
4945
|
-
};
|
|
4946
|
-
function Arrow({
|
|
4947
|
-
expanded,
|
|
4948
|
-
onClick,
|
|
4949
|
-
style
|
|
4950
|
-
}) {
|
|
4951
|
-
return /* @__PURE__ */ React3.createElement(
|
|
4952
|
-
"span",
|
|
4953
|
-
{
|
|
4954
|
-
role: "button",
|
|
4955
|
-
onClick,
|
|
4956
|
-
style: {
|
|
4957
|
-
display: "inline-block",
|
|
4958
|
-
textAlign: "center",
|
|
4959
|
-
transform: expanded ? "rotate(0deg)" : "rotate(-90deg)",
|
|
4960
|
-
fontFamily: "Menlo, monospace",
|
|
4961
|
-
...style
|
|
4962
|
-
}
|
|
4963
|
-
},
|
|
4964
|
-
"\u25BC"
|
|
4965
|
-
);
|
|
4966
|
-
}
|
|
4967
|
-
function pathToString(extendedPath) {
|
|
4968
|
-
return extendedPath.map(
|
|
4969
|
-
(key) => typeof key === "object" ? `:${ellipsis(key.id.toString(), 8, "middle")}` : key
|
|
4970
|
-
).map(
|
|
4971
|
-
(key, index) => index === 0 || typeof key === "string" && key.startsWith(":") ? key : `.${key}`
|
|
4972
|
-
).join("");
|
|
4973
|
-
}
|
|
4974
|
-
function ellipsis(str, maxLength, position = "end") {
|
|
4975
|
-
if (str.length <= maxLength) return str;
|
|
4976
|
-
switch (position) {
|
|
4977
|
-
case "start":
|
|
4978
|
-
return `\u2026${str.slice(str.length - maxLength)}`;
|
|
4979
|
-
case "middle":
|
|
4980
|
-
const halfLength = Math.floor(maxLength / 2);
|
|
4981
|
-
return `${str.slice(0, halfLength)}\u2026${str.slice(str.length - halfLength)}`;
|
|
4982
|
-
case "end":
|
|
4983
|
-
return `${str.slice(0, maxLength)}\u2026`;
|
|
4984
|
-
}
|
|
4985
|
-
}
|
|
4986
|
-
function SmallButton({
|
|
4987
|
-
children,
|
|
4988
|
-
onClick,
|
|
4989
|
-
style,
|
|
4990
|
-
theme,
|
|
4991
|
-
disabled
|
|
4992
|
-
}) {
|
|
4993
|
-
return /* @__PURE__ */ React3.createElement(
|
|
4994
|
-
"button",
|
|
4995
|
-
{
|
|
4996
|
-
type: "button",
|
|
4997
|
-
disabled,
|
|
4998
|
-
onClick: (event) => {
|
|
4999
|
-
event.stopPropagation();
|
|
5000
|
-
onClick();
|
|
5001
|
-
},
|
|
5002
|
-
style: {
|
|
5003
|
-
flex: "0",
|
|
5004
|
-
appearance: "none",
|
|
5005
|
-
background: "none",
|
|
5006
|
-
color: theme.BASE_COLOR,
|
|
5007
|
-
opacity: disabled ? 0.25 : 1,
|
|
5008
|
-
border: "none",
|
|
5009
|
-
fontSize: "12px",
|
|
5010
|
-
whiteSpace: "nowrap",
|
|
5011
|
-
display: "inline-flex",
|
|
5012
|
-
alignItems: "center",
|
|
5013
|
-
justifyContent: "center",
|
|
5014
|
-
padding: "0",
|
|
5015
|
-
cursor: "pointer",
|
|
5016
|
-
...style
|
|
5017
|
-
}
|
|
5018
|
-
},
|
|
5019
|
-
children
|
|
5020
|
-
);
|
|
5021
|
-
}
|
|
5022
|
-
function ColoredDot({ type }) {
|
|
5023
|
-
return /* @__PURE__ */ React3.createElement(
|
|
5024
|
-
"span",
|
|
5025
|
-
{
|
|
5026
|
-
style: {
|
|
5027
|
-
display: "inline-block",
|
|
5028
|
-
width: 6,
|
|
5029
|
-
height: 6,
|
|
5030
|
-
background: type === "success" ? "rgba(0,200,0,0.8)" : "rgba(200,0,0,0.8)",
|
|
5031
|
-
borderRadius: "50%",
|
|
5032
|
-
verticalAlign: "middle"
|
|
5033
|
-
}
|
|
5034
|
-
}
|
|
5035
|
-
);
|
|
5036
|
-
}
|
|
5037
5788
|
function TitleLabel({ children }) {
|
|
5038
|
-
return /* @__PURE__ */
|
|
5789
|
+
return /* @__PURE__ */ React12.createElement("span", { style: { display: "flex", alignItems: "center", gap: "4px" } }, children);
|
|
5039
5790
|
}
|
|
5040
5791
|
|
|
5041
5792
|
// src/inspector/useStateInspector.tsx
|
|
@@ -5053,7 +5804,7 @@ function useStateInspector({
|
|
|
5053
5804
|
colorScheme,
|
|
5054
5805
|
anchor
|
|
5055
5806
|
}) {
|
|
5056
|
-
const [root, setRoot] =
|
|
5807
|
+
const [root, setRoot] = React13.useState(null);
|
|
5057
5808
|
useIsomorphicLayoutEffect(() => {
|
|
5058
5809
|
if (disabled) return;
|
|
5059
5810
|
const { host, container } = createShadowRootElement();
|
|
@@ -5067,7 +5818,7 @@ function useStateInspector({
|
|
|
5067
5818
|
useIsomorphicLayoutEffect(() => {
|
|
5068
5819
|
if (!root) return;
|
|
5069
5820
|
root.render(
|
|
5070
|
-
/* @__PURE__ */
|
|
5821
|
+
/* @__PURE__ */ React13.createElement(
|
|
5071
5822
|
StateInspector,
|
|
5072
5823
|
{
|
|
5073
5824
|
colorScheme,
|
|
@@ -5081,7 +5832,7 @@ function useStateInspector({
|
|
|
5081
5832
|
|
|
5082
5833
|
// src/hooks.ts
|
|
5083
5834
|
function useSyncStateManager(stateManager, path) {
|
|
5084
|
-
const getSnapshot =
|
|
5835
|
+
const getSnapshot = useCallback2(
|
|
5085
5836
|
() => typeof path === "string" ? stateManager.getState(path) : stateManager.getState(),
|
|
5086
5837
|
[stateManager, path]
|
|
5087
5838
|
);
|
|
@@ -5096,7 +5847,7 @@ function useManagedState(createInitialState, options) {
|
|
|
5096
5847
|
() => new StateManager(createInitialState(), options)
|
|
5097
5848
|
);
|
|
5098
5849
|
const state = useSyncStateManager(stateManager);
|
|
5099
|
-
const setState =
|
|
5850
|
+
const setState = useCallback2(
|
|
5100
5851
|
(...args) => {
|
|
5101
5852
|
const [metadata, action] = args.length === 1 ? [void 0, args[0]] : args;
|
|
5102
5853
|
if (metadata === void 0) {
|
|
@@ -5145,7 +5896,7 @@ function useMultiplayerState(initialState, options) {
|
|
|
5145
5896
|
...rest
|
|
5146
5897
|
} = options ?? {};
|
|
5147
5898
|
const [noyaManager] = useState(
|
|
5148
|
-
() => new
|
|
5899
|
+
() => new NoyaManager2(initialState, rest)
|
|
5149
5900
|
);
|
|
5150
5901
|
const state = useObservable(
|
|
5151
5902
|
noyaManager.multiplayerStateManager.optimisticState$
|
|
@@ -5170,8 +5921,8 @@ function useMultiplayerState(initialState, options) {
|
|
|
5170
5921
|
assets
|
|
5171
5922
|
};
|
|
5172
5923
|
}, [noyaManager, assets]);
|
|
5173
|
-
const syncRef =
|
|
5174
|
-
|
|
5924
|
+
const syncRef = useRef2(sync);
|
|
5925
|
+
useEffect3(() => {
|
|
5175
5926
|
if (syncRef.current) {
|
|
5176
5927
|
return syncRef.current({ noyaManager });
|
|
5177
5928
|
}
|
|
@@ -5186,7 +5937,7 @@ function useMultiplayerState(initialState, options) {
|
|
|
5186
5937
|
}
|
|
5187
5938
|
function useErrorOverlay(noyaManager) {
|
|
5188
5939
|
const unrecoverableError = useObservable(noyaManager.unrecoverableError);
|
|
5189
|
-
|
|
5940
|
+
useEffect3(() => {
|
|
5190
5941
|
if (!unrecoverableError) return;
|
|
5191
5942
|
const el = document.createElement("div");
|
|
5192
5943
|
el.id = "noya-multiplayer-react-error-overlay";
|
|
@@ -5337,7 +6088,7 @@ function useSecret(name) {
|
|
|
5337
6088
|
const { noyaManager } = useAnyNoyaStateContext();
|
|
5338
6089
|
return useObservable(
|
|
5339
6090
|
noyaManager.secretManager.secrets$,
|
|
5340
|
-
|
|
6091
|
+
useCallback3((secrets) => secrets.find((s) => s.name === name), [name])
|
|
5341
6092
|
);
|
|
5342
6093
|
}
|
|
5343
6094
|
function useInputs() {
|
|
@@ -5355,7 +6106,7 @@ function useIOManager() {
|
|
|
5355
6106
|
function usePublish(callback) {
|
|
5356
6107
|
const { noyaManager } = useAnyNoyaStateContext();
|
|
5357
6108
|
const stableCallback = useStableCallback(callback);
|
|
5358
|
-
|
|
6109
|
+
useEffect4(() => {
|
|
5359
6110
|
noyaManager.publishingManager.setPublishingEnabled(true);
|
|
5360
6111
|
noyaManager.publishingManager.getFilesToPublish = stableCallback;
|
|
5361
6112
|
return () => {
|
|
@@ -5435,17 +6186,17 @@ function createNoyaContext({
|
|
|
5435
6186
|
}),
|
|
5436
6187
|
[noyaManager, theme, viewType]
|
|
5437
6188
|
);
|
|
5438
|
-
return /* @__PURE__ */
|
|
6189
|
+
return /* @__PURE__ */ React14.createElement(AnyNoyaStateContext.Provider, { value: contextValue }, /* @__PURE__ */ React14.createElement(
|
|
5439
6190
|
ConnectedUsersContext.Provider,
|
|
5440
6191
|
{
|
|
5441
6192
|
value: noyaManager.connectedUsersManager
|
|
5442
6193
|
},
|
|
5443
|
-
/* @__PURE__ */
|
|
6194
|
+
/* @__PURE__ */ React14.createElement(
|
|
5444
6195
|
EphemeralUserDataManagerContext.Provider,
|
|
5445
6196
|
{
|
|
5446
6197
|
value: noyaManager.ephemeralUserDataManager
|
|
5447
6198
|
},
|
|
5448
|
-
options.fallback !== void 0 ? /* @__PURE__ */
|
|
6199
|
+
options.fallback !== void 0 ? /* @__PURE__ */ React14.createElement(FallbackUntilInitialized, { fallback: options.fallback }, children) : children
|
|
5449
6200
|
)
|
|
5450
6201
|
));
|
|
5451
6202
|
}
|
|
@@ -5465,7 +6216,7 @@ function createNoyaContext({
|
|
|
5465
6216
|
}
|
|
5466
6217
|
function useSetValue(path) {
|
|
5467
6218
|
const { noyaManager } = useAnyNoyaStateContext();
|
|
5468
|
-
const setValue =
|
|
6219
|
+
const setValue = useCallback3(
|
|
5469
6220
|
(...args) => {
|
|
5470
6221
|
const [metadata, value] = args.length === 2 ? args : [{}, args[0]];
|
|
5471
6222
|
noyaManager.multiplayerStateManager.setStateAtPath(
|
|
@@ -5506,7 +6257,7 @@ function createNoyaContext({
|
|
|
5506
6257
|
}
|
|
5507
6258
|
function useSetLeftMenuItems(leftMenuItems) {
|
|
5508
6259
|
const { menuManager } = useNoyaManager();
|
|
5509
|
-
|
|
6260
|
+
useEffect4(() => {
|
|
5510
6261
|
if (leftMenuItems) {
|
|
5511
6262
|
menuManager.setLeftMenuItems(leftMenuItems);
|
|
5512
6263
|
}
|
|
@@ -5518,7 +6269,7 @@ function createNoyaContext({
|
|
|
5518
6269
|
}
|
|
5519
6270
|
function useSetRightMenuItems(rightMenuItems) {
|
|
5520
6271
|
const { menuManager } = useNoyaManager();
|
|
5521
|
-
|
|
6272
|
+
useEffect4(() => {
|
|
5522
6273
|
if (rightMenuItems) {
|
|
5523
6274
|
menuManager.setRightMenuItems(rightMenuItems);
|
|
5524
6275
|
}
|
|
@@ -5526,19 +6277,19 @@ function createNoyaContext({
|
|
|
5526
6277
|
}
|
|
5527
6278
|
function useHandleMenuItem(callback) {
|
|
5528
6279
|
const { menuManager } = useNoyaManager();
|
|
5529
|
-
|
|
6280
|
+
useEffect4(() => {
|
|
5530
6281
|
return menuManager.addListener(callback);
|
|
5531
6282
|
}, [menuManager, callback]);
|
|
5532
6283
|
}
|
|
5533
6284
|
function useOnSelectMenuItemCallback() {
|
|
5534
6285
|
const { menuManager } = useNoyaManager();
|
|
5535
|
-
return
|
|
6286
|
+
return useCallback3((type) => menuManager.emit(type), [menuManager]);
|
|
5536
6287
|
}
|
|
5537
6288
|
function useMenu(options) {
|
|
5538
6289
|
const { leftMenuItems, rightMenuItems, onSelectMenuItem } = options;
|
|
5539
6290
|
useSetLeftMenuItems(leftMenuItems);
|
|
5540
6291
|
useSetRightMenuItems(rightMenuItems);
|
|
5541
|
-
const noop =
|
|
6292
|
+
const noop = useCallback3(() => {
|
|
5542
6293
|
}, []);
|
|
5543
6294
|
useHandleMenuItem(onSelectMenuItem ?? noop);
|
|
5544
6295
|
}
|
|
@@ -5564,7 +6315,7 @@ function createNoyaContext({
|
|
|
5564
6315
|
// src/ai.ts
|
|
5565
6316
|
function useRegisterAITool(tool) {
|
|
5566
6317
|
const aiManager = useAIManager();
|
|
5567
|
-
|
|
6318
|
+
useEffect5(() => {
|
|
5568
6319
|
return aiManager.registerTool(tool);
|
|
5569
6320
|
}, [aiManager, tool]);
|
|
5570
6321
|
}
|
|
@@ -5576,7 +6327,7 @@ function useCallableAITools() {
|
|
|
5576
6327
|
// src/components/UserPointersOverlay.tsx
|
|
5577
6328
|
import { Observable as Observable2 } from "@noya-app/observable";
|
|
5578
6329
|
import { memoGeneric as memoGeneric2 } from "@noya-app/react-utils";
|
|
5579
|
-
import
|
|
6330
|
+
import React15, { useEffect as useEffect6, useMemo as useMemo5, useState as useState3 } from "react";
|
|
5580
6331
|
function shouldShow(hideAfter, updatedAt) {
|
|
5581
6332
|
return !!updatedAt && Date.now() - updatedAt < hideAfter;
|
|
5582
6333
|
}
|
|
@@ -5597,7 +6348,7 @@ var UserPointerInternal = memoGeneric2(function UserPointerInternal2({
|
|
|
5597
6348
|
const [, setForceUpdate] = useState3(0);
|
|
5598
6349
|
const updatedAt = metadata?.updatedAt ?? 0;
|
|
5599
6350
|
const show = shouldShow(hideAfter, updatedAt);
|
|
5600
|
-
|
|
6351
|
+
useEffect6(() => {
|
|
5601
6352
|
if (!show) return;
|
|
5602
6353
|
const timeoutId = setTimeout(() => {
|
|
5603
6354
|
setForceUpdate((prev) => prev + 1);
|
|
@@ -5619,9 +6370,9 @@ var UserPointersOverlay = memoGeneric2(function UserPointers({
|
|
|
5619
6370
|
}) {
|
|
5620
6371
|
const currentUserId = useObservable(ephemeralUserDataManager.currentUserId$);
|
|
5621
6372
|
const connectedUsers = useObservable(connectedUsersManager.connectedUsers$);
|
|
5622
|
-
return /* @__PURE__ */
|
|
6373
|
+
return /* @__PURE__ */ React15.createElement(React15.Fragment, null, connectedUsers.map((user) => {
|
|
5623
6374
|
if (user.id === currentUserId) return null;
|
|
5624
|
-
return /* @__PURE__ */
|
|
6375
|
+
return /* @__PURE__ */ React15.createElement(
|
|
5625
6376
|
UserPointerInternal,
|
|
5626
6377
|
{
|
|
5627
6378
|
key: user.id,
|
|
@@ -5723,9 +6474,15 @@ export {
|
|
|
5723
6474
|
WebSocketConnection,
|
|
5724
6475
|
createDefaultAppData,
|
|
5725
6476
|
createNoyaContext,
|
|
6477
|
+
decodeAll,
|
|
6478
|
+
encodeAll,
|
|
5726
6479
|
enforceSchema,
|
|
6480
|
+
exportAll,
|
|
6481
|
+
fetchAssetMap,
|
|
5727
6482
|
getAppData,
|
|
6483
|
+
importAll,
|
|
5728
6484
|
parseAppDataParameter,
|
|
6485
|
+
replaceDeep,
|
|
5729
6486
|
useAIManager,
|
|
5730
6487
|
useAnyEphemeralUserData,
|
|
5731
6488
|
useAnyNoyaManager,
|