@noya-app/noya-multiplayer-react 0.1.41 → 0.1.42

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/avatarStyle.ts","../src/components/UserPointersOverlay.tsx","../src/useObservable.ts","../src/hooks.ts","../src/components/ErrorOverlay.tsx","../src/globals.ts","../src/inspector/useStateInspector.tsx","../src/inspector/StateInspector.tsx","../src/inspector/useLocalStorageState.tsx","../src/noyaApp.ts","../src/NoyaStateContext.tsx"],"sourcesContent":["export * from \"@noya-app/state-manager\";\nexport * from \"./avatarStyle\";\nexport * from \"./components/UserPointersOverlay\";\nexport * from \"./hooks\";\nexport * from \"./inspector/StateInspector\";\nexport * from \"./noyaApp\";\nexport * from \"./NoyaStateContext\";\nexport * from \"./useObservable\";\n","function hashCode(string: string) {\n let hash = 0;\n\n for (const char of string) {\n hash = char.charCodeAt(0) + ((hash << 5) - hash);\n }\n\n return hash;\n}\n\nfunction elementFromHash<T>(array: T[], hash: number): T {\n return array[Math.abs(hash) % array.length];\n}\n\nexport function getAvatarInitials(name: string) {\n return name\n .split(\" \")\n .filter((c) => c.length > 0)\n .map((c) => c[0])\n .join(\"\")\n .toLocaleUpperCase();\n}\n\n/**\n * Create a background color and initials from a name\n *\n * Adapted from https://mui.com/material-ui/react-avatar/\n */\nexport function getAvatarStyle(name: string) {\n const hash = hashCode(name);\n const color = elementFromHash(Object.values(colors500), hash);\n // const darkerColor = elementFromHash(Object.values(colors800), hash);\n\n return {\n color: \"white\",\n backgroundColor: color,\n // primaryColors: {\n // \"500\": color,\n // \"800\": darkerColor,\n // },\n };\n}\n\nconst colors500 = {\n red500: \"#ef4444\",\n orange500: \"#f97316\",\n amber500: \"#f59e0b\",\n yellow500: \"#eab308\",\n lime500: \"#84cc16\",\n green500: \"#22c55e\",\n emerald500: \"#10b981\",\n teal500: \"#14b8a6\",\n cyan500: \"#06b6d4\",\n sky500: \"#0ea5e9\",\n blue500: \"#3b82f6\",\n indigo500: \"#6366f1\",\n violet500: \"#8b5cf6\",\n purple500: \"#a855f7\",\n fuchsia500: \"#d946ef\",\n pink500: \"#ec4899\",\n rose500: \"#f43f5e\",\n};\n\n// const colors800 = {\n// red800: \"#991b1b\",\n// orange800: \"#9a3412\",\n// amber800: \"#92400e\",\n// yellow800: \"#854d0e\",\n// lime800: \"#3f6212\",\n// green800: \"#166534\",\n// emerald800: \"#065f46\",\n// teal800: \"#115e59\",\n// cyan800: \"#155e75\",\n// sky800: \"#075985\",\n// blue800: \"#1e40af\",\n// indigo800: \"#3730a3\",\n// violet800: \"#5b21b6\",\n// purple800: \"#6b21a8\",\n// fuchsia800: \"#86198f\",\n// pink800: \"#9d174d\",\n// rose800: \"#9f1239\",\n// };\n","\"use client\";\n\nimport { EphemeralUserData, MultiplayerUser } from \"@noya-app/state-manager\";\nimport React, { memo, useEffect, useMemo, useState } from \"react\";\nimport { getAvatarStyle } from \"../avatarStyle\";\nimport { useObservable } from \"../useObservable\";\n\ntype Point = { x: number; y: number };\n\nexport type UserPointerData = { pointer?: Point };\n\nexport type UserPointerProps<E extends UserPointerData> = {\n user: MultiplayerUser;\n ephemeralUserData: EphemeralUserData<E>;\n hideAfter?: number;\n};\n\nfunction shouldShow(hideAfter: number, updatedAt: number) {\n return !!updatedAt && Date.now() - updatedAt < hideAfter;\n}\n\nconst UserPointer_ = function UserPointer<E extends UserPointerData>({\n user,\n ephemeralUserData,\n hideAfter = 5000,\n}: UserPointerProps<E>) {\n const metadata = useObservable(ephemeralUserData.metadata$, [\n user.id,\n ] as const);\n const data = useObservable(ephemeralUserData.data$, [user.id] as const);\n const avatarStyle = useMemo(() => getAvatarStyle(user.id), [user.id]);\n\n const [, setForceUpdate] = useState(0);\n\n const updatedAt = metadata?.updatedAt ?? 0;\n\n useEffect(() => {\n if (!shouldShow(hideAfter, updatedAt)) return;\n\n const timeoutId = setTimeout(() => {\n setForceUpdate((prev) => prev + 1);\n }, hideAfter);\n\n return () => clearTimeout(timeoutId);\n }, [hideAfter, updatedAt]);\n\n const show = shouldShow(hideAfter, updatedAt);\n\n if (!data || !data.pointer) return null;\n\n return (\n <UserPointerContainer key={user.id} point={data.pointer} show={show}>\n <UserPointerIcon color={avatarStyle.backgroundColor} />\n <UserNameTag background={avatarStyle.backgroundColor}>\n {user.name}\n </UserNameTag>\n </UserPointerContainer>\n );\n};\n\nexport const UserPointer = memo(UserPointer_) as typeof UserPointer_;\n\nexport const UserPointerContainer = memo(function UserPointerContainer({\n point,\n children,\n show = true,\n}: {\n point: Point;\n children: React.ReactNode;\n show?: boolean;\n}) {\n return (\n <div\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n transform: `translate(${Math.round(point.x)}px, ${Math.round(\n point.y\n )}px)`,\n opacity: show ? 1 : 0,\n transition: \"transform 0.1s, opacity 0.2s\",\n }}\n >\n {children}\n </div>\n );\n});\n\nexport const UserNameTag = memo(function UserNameTag({\n background,\n children,\n}: {\n background: string;\n children: React.ReactNode;\n}) {\n return (\n <span\n style={{\n position: \"relative\",\n top: \"8px\",\n left: \"15px\",\n fontSize: 11,\n lineHeight: \"1\",\n fontWeight: 500,\n boxShadow: \"0 1px 1px rgba(0,0,0,0.1)\",\n padding: \"2px 4px 3px\",\n pointerEvents: \"none\",\n letterSpacing: \"-0.3px\",\n outline: `1px solid rgba(255,255,255,0.3)`,\n outlineOffset: \"-1px\",\n background,\n color: \"white\",\n }}\n >\n {children}\n </span>\n );\n});\n\nexport type UserPointersOverlayProps<E extends UserPointerData> = {\n connectedUsers: MultiplayerUser[];\n ephemeralUserData: EphemeralUserData<E>;\n};\n\nexport const UserPointersOverlay = memo(function UserPointers<\n E extends UserPointerData,\n>({ connectedUsers, ephemeralUserData }: UserPointersOverlayProps<E>) {\n const currentUserId = useObservable(ephemeralUserData.currentUserId$);\n\n return (\n <>\n {connectedUsers.map((user) => {\n if (user.id === currentUserId) return null;\n\n return (\n <UserPointer\n key={user.id}\n user={user}\n ephemeralUserData={\n ephemeralUserData as unknown as EphemeralUserData<E>\n }\n />\n );\n })}\n </>\n );\n});\n\nexport const UserPointerIcon = memo(function CursorIcon({\n color = \"black\",\n}: {\n color?: string;\n}) {\n return (\n <svg\n width=\"15\"\n height=\"15\"\n viewBox=\"0 0 15 15\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n style={{\n position: \"absolute\",\n filter: \"drop-shadow(0 1px 1px rgba(0,0,0,0.1))\",\n // filter: \"drop-shadow(0 1px 1px rgba(0,0,0,0.6))\",\n }}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M3.29227 0.0451998C3.47033 -0.0361222 3.67946 -0.00606629 3.8274 0.122107L12.8587 7.94648C13.0134 8.08054 13.0708 8.29538 13.0035 8.48873C12.9362 8.68208 12.7578 8.81488 12.5533 8.8239L9.21887 8.97096L11.1504 13.2149C11.2648 13.4662 11.1538 13.7626 10.9026 13.877L8.75024 14.8575C8.499 14.972 8.20255 14.8611 8.08802 14.6099L6.15339 10.3665L3.86279 12.7817C3.72196 12.9302 3.50487 12.9779 3.31479 12.9021C3.1247 12.8263 3 12.6423 3 12.4376V0.500008C3 0.304264 3.11422 0.126522 3.29227 0.0451998Z\"\n fill={color}\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M3.29227 0.048984C3.47033 -0.032338 3.67946 -0.00228211 3.8274 0.125891L12.8587 7.95026C13.0134 8.08432 13.0708 8.29916 13.0035 8.49251C12.9362 8.68586 12.7578 8.81866 12.5533 8.82768L9.21887 8.97474L11.1504 13.2187C11.2648 13.47 11.1538 13.7664 10.9026 13.8808L8.75024 14.8613C8.499 14.9758 8.20255 14.8649 8.08802 14.6137L6.15339 10.3703L3.86279 12.7855C3.72196 12.934 3.50487 12.9817 3.31479 12.9059C3.1247 12.8301 3 12.6461 3 12.4414V0.503792C3 0.308048 3.11422 0.130306 3.29227 0.048984ZM4 1.59852V11.1877L5.93799 9.14425C6.05238 9.02363 6.21924 8.96776 6.38319 8.99516C6.54715 9.02256 6.68677 9.12965 6.75573 9.2809L8.79056 13.7441L10.0332 13.178L8.00195 8.71497C7.93313 8.56376 7.94391 8.38824 8.03072 8.24659C8.11753 8.10494 8.26903 8.01566 8.435 8.00834L11.2549 7.88397L4 1.59852Z\"\n fill=\"rgba(255,255,255,0.5)\"\n />\n </svg>\n );\n});\n","import { GetAtPath, Observable, PathKey } from \"@noya-app/observable\";\nimport { useMemo, useSyncExternalStore } from \"react\";\n\nexport function useObservable<T>(observable: Observable<T>): T;\nexport function useObservable<T, P extends PathKey[] | string>(\n observable: Observable<T>,\n path: P\n): GetAtPath<T, P>;\nexport function useObservable<T, P extends PathKey[]>(\n observable: Observable<T>,\n path?: P\n) {\n const { get, listen } = useMemo(() => {\n const listen = path\n ? (callback: (value: GetAtPath<T, P>) => void) =>\n observable.subscribe(path, callback)\n : observable.subscribe;\n\n const get: () => void = path ? () => observable.get(path) : observable.get;\n\n return { get, listen };\n }, [observable, path]);\n\n return useSyncExternalStore(listen, get, get);\n}\n","\"use client\";\n\nimport { GetAtPath } from \"@noya-app/observable\";\nimport {\n ActionHandler,\n AssetManager,\n ConnectionEvent,\n EphemeralUserData,\n MultiplayerStateManager,\n MultiplayerStateManagerError,\n MultiplayerStateManagerOptions,\n MultiplayerUser,\n StateManager,\n StateManagerOptions,\n stubSync,\n SyncAdapter,\n SyncAdapterOptions,\n Task,\n} from \"@noya-app/state-manager\";\nimport {\n createElement,\n SetStateAction,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport { ErrorOverlay } from \"./components/ErrorOverlay\";\nimport { shouldTrackEvents$, shouldTrackTasks$ } from \"./globals\";\nimport { StateInspectorOptions } from \"./inspector/StateInspector\";\nimport { useStateInspector } from \"./inspector/useStateInspector\";\nimport { useObservable } from \"./useObservable\";\n\nexport function useSyncStateManager<S, M>(stateManager: StateManager<S, M>): S;\nexport function useSyncStateManager<S, M, P extends string>(\n stateManager: StateManager<S, M>,\n path: P\n): GetAtPath<S, P>;\nexport function useSyncStateManager<S, M>(\n stateManager: StateManager<S, M>,\n path?: string\n) {\n const getSnapshot = useCallback(\n () =>\n typeof path === \"string\"\n ? stateManager.getState(path)\n : stateManager.getState(),\n [stateManager, path]\n );\n\n return useSyncExternalStore(\n stateManager.addListener,\n getSnapshot,\n getSnapshot\n );\n}\n\nexport function useManagedState<S, M = void>(\n createInitialState: () => S,\n options?: StateManagerOptions<S, M>\n) {\n const [stateManager] = useState(\n () => new StateManager<S, M>(createInitialState(), options)\n );\n\n const state = useSyncStateManager(stateManager);\n\n const setState = useCallback(\n (\n ...args: M extends {}\n ? [metadata: M, action: SetStateAction<S>]\n : [action: SetStateAction<S>]\n ) => {\n const [metadata, action] =\n args.length === 1 ? [undefined, args[0]] : args;\n\n if (metadata === undefined) {\n const performActionNoMetadata = stateManager.performAction as (\n handler: ActionHandler<S>\n ) => void;\n\n if (action instanceof Function) {\n performActionNoMetadata({\n run: action,\n undo: () => state,\n });\n } else {\n performActionNoMetadata({\n run: () => action,\n undo: () => state,\n });\n }\n } else {\n const performActionWithMetadata = stateManager.performAction as (\n metadata: M,\n handler: ActionHandler<S>\n ) => void;\n\n if (action instanceof Function) {\n performActionWithMetadata(metadata, {\n run: action,\n undo: () => state,\n });\n } else {\n performActionWithMetadata(metadata, {\n run: () => action,\n undo: () => state,\n });\n }\n }\n },\n [state, stateManager]\n );\n\n return [state, setState, stateManager] as const;\n}\n\nexport function useManagedHistory<S, M = void>(\n stateManager: StateManager<S, M>\n) {\n return useSyncExternalStore(\n stateManager.historyEmittor.addListener,\n stateManager.getHistorySnapshot,\n stateManager.getHistorySnapshot\n );\n}\n\nexport function useSyncMultiplayerStateManager<S, M = void>(\n multiplayerStateManager: MultiplayerStateManager<S, M>\n) {\n return useSyncExternalStore(\n multiplayerStateManager.addListener,\n multiplayerStateManager.getOptimisticState,\n multiplayerStateManager.getOptimisticState\n );\n}\n\nfunction throttle<F extends (...args: any[]) => any>(fn: F, ms: number) {\n let lastCall = 0;\n let timeoutId: number | null = null;\n return (...args: Parameters<F>) => {\n const now = Date.now();\n if (now - lastCall < ms) {\n if (timeoutId) clearTimeout(timeoutId);\n timeoutId = setTimeout(\n () => {\n lastCall = now;\n fn(...args);\n },\n ms - (now - lastCall)\n ) as unknown as number;\n return;\n }\n lastCall = now;\n return fn(...args);\n };\n}\n\nexport function useEphemeralUserData<E>(\n ephemeralUserData: EphemeralUserData<E>,\n options?: {\n throttle?: number;\n }\n) {\n const throttledAddListener = useMemo(() => {\n const throttleMs = options?.throttle ?? 0;\n\n if (throttleMs > 0) {\n const addListener = (\n fn: Parameters<typeof ephemeralUserData.addListener>[0]\n ) => {\n const throttledFn = throttle(fn, throttleMs);\n return ephemeralUserData.addListener(throttledFn);\n };\n\n return addListener;\n }\n\n return ephemeralUserData.addListener;\n }, [ephemeralUserData, options?.throttle]);\n\n return useSyncExternalStore(\n throttledAddListener,\n ephemeralUserData.getSnapshot,\n ephemeralUserData.getSnapshot\n );\n}\n\nconst defaultStubSync = stubSync();\n\nexport type UseMultiplayerStateOptions<\n S,\n M = void,\n E = void,\n> = MultiplayerStateManagerOptions<S, M> & {\n sync?: (\n options: Pick<\n SyncAdapterOptions<S, M, E>,\n \"ms\" | \"ephemeralUserData\" | \"assetManager\"\n >\n ) => void;\n trackConnectionEvents?: boolean;\n trackTasks?: boolean;\n inspector?: boolean | StateInspectorOptions;\n};\n\nexport function useMultiplayerState<S, M = void, E = void>(\n initialState: S | (() => S),\n options?: UseMultiplayerStateOptions<S, M, E>\n) {\n const { sync = defaultStubSync as unknown as SyncAdapter<S, M, E>, ...rest } =\n options ?? {};\n\n const [multiplayerStateManager] = useState(\n () => new MultiplayerStateManager<S, M>(initialState, rest)\n );\n const [assetManager] = useState(() => new AssetManager());\n const syncRef = useRef(sync);\n\n const [connectionEvents, setConnectionEvents] = useState<\n ConnectionEvent<S>[] | undefined\n >();\n\n const [connectedUsers, setConnectedUsers] = useState<MultiplayerUser[]>([]);\n const [ephemeralUserData] = useState<EphemeralUserData<E>>(\n () => new EphemeralUserData()\n );\n const [tasks, setTasks] = useState<Task[]>([]);\n const [userId, setUserId] = useState<string | undefined>();\n const assets = useObservable(assetManager.assets$);\n\n const extras = useMemo(() => {\n return {\n tasks,\n userId,\n connectionEvents,\n connectedUsers,\n ephemeralUserData,\n multiplayerStateManager,\n assets,\n assetManager,\n createAsset: assetManager.create,\n deleteAsset: assetManager.delete,\n // evaluate: async (code: string) => {\n // const payload = await rpcManager.request({ type: \"eval\", code });\n\n // if (payload.type !== \"eval\") {\n // throw new Error(`Unexpected rpc response type: ${payload.type}`);\n // }\n // },\n };\n }, [\n tasks,\n userId,\n connectionEvents,\n connectedUsers,\n ephemeralUserData,\n multiplayerStateManager,\n assetManager,\n assets,\n ]);\n\n const globalTrackEvents = useObservable(shouldTrackEvents$);\n const globalTrackTasks = useObservable(shouldTrackTasks$);\n\n const shouldTrackEvents = options?.trackConnectionEvents ?? globalTrackEvents;\n const shouldTrackTasks = options?.trackTasks ?? globalTrackTasks;\n\n const trackEventsCallbackRef = useRef<\n ((e: ConnectionEvent<S>) => void) | undefined\n >();\n const trackConnectedUsersCallbackRef = useRef<\n ((users: MultiplayerUser[], userId: string) => void) | undefined\n >();\n const trackTasksCallbackRef = useRef<((tasks: Task[]) => void) | undefined>();\n\n useEffect(() => {\n trackEventsCallbackRef.current = shouldTrackEvents\n ? (e) =>\n setConnectionEvents((events) => {\n const updated = events ? [...events, e] : [e];\n return updated.length > 50 ? updated.slice(-50) : updated;\n })\n : undefined;\n }, [shouldTrackEvents]);\n\n useEffect(() => {\n trackConnectedUsersCallbackRef.current = (users, userId) => {\n setConnectedUsers(users);\n setUserId(userId);\n };\n }, []);\n\n useEffect(() => {\n trackTasksCallbackRef.current = shouldTrackTasks\n ? (tasks) => {\n setTasks((old) => {\n const newIds = new Set(tasks.map((t) => t.id));\n\n // merge old and new tasks, preferring new tasks\n const unchanged = old.filter((t) => !newIds.has(t.id));\n\n return [...unchanged, ...tasks];\n });\n }\n : undefined;\n }, [shouldTrackTasks]);\n\n useEffect(() => {\n if (syncRef.current) {\n return syncRef.current({\n ms: multiplayerStateManager,\n assetManager,\n ephemeralUserData,\n onConnectionEvent: (e) => trackEventsCallbackRef.current?.(e),\n onChangeConnectedUsers: (users, userId) =>\n trackConnectedUsersCallbackRef.current?.(users, userId),\n onChangeTasks: (tasks) => trackTasksCallbackRef.current?.(tasks),\n });\n }\n }, [assetManager, ephemeralUserData, multiplayerStateManager]);\n\n const state = useSyncMultiplayerStateManager(multiplayerStateManager);\n\n const forceInit = useCallback(() => {\n const state =\n initialState instanceof Function ? initialState() : initialState;\n const schema = options?.schema;\n multiplayerStateManager.sm.clearHistory();\n multiplayerStateManager.sendInit({ force: true, state, schema });\n }, [initialState, multiplayerStateManager, options?.schema]);\n\n const [unrecoverableError, setUnrecoverableError] = useState<\n MultiplayerStateManagerError | undefined\n >();\n\n useEffect(() => {\n return multiplayerStateManager.errorEmitter.addListener((error) => {\n switch (error.reason) {\n case \"invalidDataType\":\n case \"schemaMismatch\":\n case \"outdatedSchema\":\n case \"dataMigrationFailure\":\n case \"schemaMigration\":\n setUnrecoverableError(error);\n break;\n }\n });\n }, [multiplayerStateManager]);\n\n useEffect(() => {\n if (!unrecoverableError) return;\n const el = document.createElement(\"div\");\n el.id = \"noya-multiplayer-react-error-overlay\";\n document.body.appendChild(el);\n const root = createRoot(el);\n root.render(createElement(ErrorOverlay, { error: unrecoverableError }));\n return () => {\n root.unmount();\n el.remove();\n };\n });\n\n useStateInspector({\n ephemeralUserData,\n multiplayerStateManager,\n assetManager,\n state,\n connectionEvents,\n connectedUsers,\n tasks,\n userId,\n forceInit,\n disabled: !options?.inspector,\n ...(typeof options?.inspector === \"object\" && options.inspector),\n });\n\n return [state, multiplayerStateManager.setState, extras] as const;\n}\n","import { MultiplayerStateManagerError } from \"@noya-app/state-manager\";\nimport React from \"react\";\n\nexport function ErrorOverlay({\n error,\n}: {\n error: MultiplayerStateManagerError;\n}) {\n return (\n <div\n style={{\n position: \"fixed\",\n top: \"20px\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n maxWidth: \"80%\",\n width: \"fit-content\",\n padding: \"12px 20px\",\n background: \"white\",\n color: \"black\",\n zIndex: 10000,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n borderRadius: \"4px\",\n boxShadow: \"0 4px 6px rgba(0, 0, 0, 0.1)\",\n fontFamily:\n \"'__Inter_6b0edc', '__Inter_Fallback_6b0edc', -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Segoe UI', Roboto, Helvetica, Arial, sans-serif\",\n fontSize: \"14px\",\n fontWeight: 400,\n lineHeight: \"19px\",\n }}\n >\n {error.reason === \"schemaMigration\" ? (\n <>\n <p>\n An updated version of Noya is available. Please reload the page to\n continue.\n </p>\n </>\n ) : (\n <>\n <p>\n An error occurred:{\" \"}\n <code\n style={{\n background: \"rgba(255, 0, 0, 0.1)\",\n color: \"rgba(255, 0, 0, 0.5)\",\n padding: \"2px 4px\",\n borderRadius: \"4px\",\n }}\n >\n {error.reason}\n </code>\n . Please reload the page to continue.\n <br />\n <br />\n If this happens repeatedly, please get in touch and the Noya team\n can help.\n </p>\n </>\n )}\n <div\n style={{\n height: \"1px\",\n background: \"rgba(0, 0, 0, 0.1)\",\n margin: \"12px -20px\",\n }}\n />\n <button\n style={{\n background: \"black\",\n color: \"white\",\n padding: \"8px 16px\",\n borderRadius: \"4px\",\n cursor: \"pointer\",\n fontSize: \"14px\",\n fontWeight: 700,\n lineHeight: \"19px\",\n }}\n onClick={() => {\n window.location.reload();\n }}\n >\n Reload\n </button>\n </div>\n );\n}\n","import { Observable } from \"@noya-app/observable\";\n\nexport const shouldTrackEvents$ = new Observable(false);\nexport const shouldTrackTasks$ = new Observable(false);\n","\"use client\";\n\nimport {\n AssetManager,\n ConnectionEvent,\n EphemeralUserData,\n MultiplayerStateManager,\n MultiplayerUser,\n Task,\n} from \"@noya-app/state-manager\";\nimport React, { ComponentProps, useLayoutEffect } from \"react\";\nimport { createRoot } from \"react-dom/client\";\n\nimport { Root } from \"react-dom/client\";\nimport { StateInspector } from \"./StateInspector\";\n\nfunction createShadowRootElement() {\n const host = document.createElement(\"div\");\n host.id = \"noya-multiplayer-react-inspector-host\";\n const shadowRoot = host.attachShadow({ mode: \"open\" });\n const container = document.createElement(\"div\");\n shadowRoot.appendChild(container);\n return { host, container };\n}\n\nexport function useStateInspector<S, M, E>({\n state,\n connectionEvents,\n connectedUsers,\n tasks,\n userId,\n disabled = false,\n colorScheme,\n anchor,\n multiplayerStateManager,\n assetManager,\n ephemeralUserData,\n forceInit,\n}: {\n state: S;\n connectionEvents?: ConnectionEvent<S>[];\n connectedUsers?: MultiplayerUser[];\n tasks?: Task[];\n userId?: string;\n disabled: boolean;\n multiplayerStateManager: MultiplayerStateManager<S, M>;\n assetManager: AssetManager;\n ephemeralUserData: EphemeralUserData<E>;\n forceInit: () => void;\n} & Pick<ComponentProps<typeof StateInspector>, \"colorScheme\" | \"anchor\">) {\n const [root, setRoot] = React.useState<Root | null>(null);\n\n useLayoutEffect(() => {\n if (disabled) return;\n\n const { host, container } = createShadowRootElement();\n const root = createRoot(container);\n\n document.body.appendChild(host);\n\n setRoot(root);\n\n return () => {\n document.body.removeChild(host);\n };\n }, [disabled]);\n\n useLayoutEffect(() => {\n if (!root) return;\n\n root.render(\n <StateInspector\n state={state}\n connectionEvents={connectionEvents}\n connectedUsers={connectedUsers}\n tasks={tasks}\n userId={userId}\n colorScheme={colorScheme}\n anchor={anchor}\n forceInit={forceInit}\n multiplayerStateManager={\n multiplayerStateManager as MultiplayerStateManager<any, any>\n }\n assetManager={assetManager}\n ephemeralUserData={ephemeralUserData as EphemeralUserData<any>}\n />\n );\n }, [\n anchor,\n colorScheme,\n connectedUsers,\n connectionEvents,\n root,\n state,\n multiplayerStateManager,\n userId,\n tasks,\n forceInit,\n ephemeralUserData,\n assetManager,\n ]);\n}\n","\"use client\";\n\nimport {\n AssetManager,\n ConnectionEvent,\n EphemeralUserData,\n ExtendedPathKey,\n MultiplayerStateManager,\n MultiplayerUser,\n Task,\n} from \"@noya-app/state-manager\";\nimport React, {\n CSSProperties,\n ComponentPropsWithoutRef,\n FC,\n memo,\n useEffect,\n useLayoutEffect,\n} from \"react\";\nimport {\n ObjectInspector,\n ObjectLabel,\n ObjectName,\n ObjectPreview,\n chromeDark,\n chromeLight,\n} from \"react-inspector\";\nimport { shouldTrackEvents$, shouldTrackTasks$ } from \"../globals\";\nimport { useEphemeralUserData, useManagedHistory } from \"../hooks\";\nimport { useObservable } from \"../useObservable\";\nimport { useLocalStorageState } from \"./useLocalStorageState\";\n\nconst lightTheme = {\n ...chromeLight,\n BASE_BACKGROUND_COLOR: \"transparent\",\n OBJECT_NAME_COLOR: \"rgba(0,0,0,0.7)\",\n} as any;\n\nconst darkTheme = {\n ...chromeDark,\n BASE_BACKGROUND_COLOR: \"transparent\",\n OBJECT_NAME_COLOR: \"rgba(255,255,255,0.7)\",\n} as any;\n\nconst styles = {\n sectionInner: {\n flex: \"1 1 0\",\n overflowY: \"auto\",\n overflowX: \"hidden\",\n display: \"flex\",\n flexDirection: \"column\",\n },\n} as const;\n\nfunction ToggleButton({\n showInspector,\n setShowInspector,\n theme,\n anchor,\n}: {\n showInspector: boolean;\n setShowInspector: (value: boolean) => void;\n theme: typeof chromeLight;\n anchor: StateInspectorAnchor;\n}) {\n return (\n <span\n role=\"button\"\n style={{\n flex: \"0\",\n appearance: \"none\",\n color: theme.BASE_COLOR,\n border: \"none\",\n fontSize: \"12px\",\n whiteSpace: \"nowrap\",\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"2px 0\",\n }}\n onClick={(event) => {\n event.stopPropagation();\n\n setShowInspector(!showInspector);\n }}\n >\n <span style={{ width: \"12px\", height: \"12px\" }}>\n {showInspector === (anchor === \"right\") ? (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n strokeWidth={1.5}\n stroke=\"currentColor\"\n className=\"size-6\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"m5.25 4.5 7.5 7.5-7.5 7.5m6-15 7.5 7.5-7.5 7.5\"\n />\n </svg>\n ) : (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n strokeWidth={1.5}\n stroke=\"currentColor\"\n className=\"size-6\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"m18.75 4.5-7.5 7.5 7.5 7.5m-6-15L5.25 12l7.5 7.5\"\n />\n </svg>\n )}\n </span>\n </span>\n );\n}\n\nfunction DisclosureSection({\n open,\n setOpen,\n title,\n right,\n children,\n colorScheme,\n isFirst,\n style,\n}: {\n open: boolean;\n setOpen?: (value: boolean) => void;\n title: string;\n right?: React.ReactNode;\n children: React.ReactNode;\n colorScheme: \"light\" | \"dark\";\n isFirst?: boolean;\n style?: CSSProperties;\n}) {\n const theme = colorScheme === \"light\" ? lightTheme : darkTheme;\n\n const borderColor =\n colorScheme === \"light\" ? \"rgba(0,0,0,0.1)\" : \"rgba(255,255,255,0.1)\";\n\n return (\n <div\n style={{\n flex: open ? \"1 1 0\" : \"0\",\n display: \"flex\",\n flexDirection: \"column\",\n ...style,\n }}\n >\n <div\n onClick={() => setOpen?.(!open)}\n style={{\n cursor: \"default\",\n fontSize: \"12px\",\n padding: \"4px 10px\",\n display: \"flex\",\n alignItems: \"center\",\n ...(!isFirst && { borderTop: `1px solid ${borderColor}` }),\n ...(open && { borderBottom: `1px solid ${borderColor}` }),\n }}\n >\n {setOpen && (\n <Arrow\n expanded={open}\n style={{\n fontSize: theme.ARROW_FONT_SIZE,\n marginRight: theme.ARROW_MARGIN_RIGHT + 1,\n color: theme.ARROW_COLOR,\n }}\n />\n )}\n <span style={{ flex: \"1 1 0\", userSelect: \"none\" }}>{title}</span>\n {right}\n </div>\n {open && children}\n </div>\n );\n}\n\nfunction InspectorRow({\n children,\n colorScheme,\n selected,\n style,\n variant,\n}: {\n children: React.ReactNode;\n colorScheme: \"light\" | \"dark\";\n selected?: boolean;\n style?: CSSProperties;\n variant?: \"up\" | \"down\";\n}) {\n const solidBorderColor =\n colorScheme === \"light\" ? \"rgb(223 223 223)\" : \"rgb(29 29 29)\";\n\n return (\n <div\n style={{\n borderBottom: `1px solid ${solidBorderColor}`,\n fontSize: \"12px\",\n fontFamily: \"Menlo, monospace\",\n padding: \"2px 12px 1px\",\n display: \"flex\",\n alignItems: \"center\",\n background:\n variant === \"up\"\n ? \"rgba(0,255,0,0.1)\"\n : variant === \"down\"\n ? \"rgba(255,0,0,0.1)\"\n : selected\n ? \"rgb(59 130 246 / 15%)\"\n : undefined,\n // background:\n // colorScheme === \"light\"\n // ? \"rgba(0,0,0,0.05)\"\n // : \"rgba(255,255,255,0.05)\",\n ...style,\n }}\n >\n <span\n style={{\n fontFamily: \"Menlo, monospace\",\n fontSize: \"11px\",\n borderRadius: 4,\n display: \"inline-block\",\n }}\n >\n {children}\n </span>\n </div>\n );\n}\n\nconst HISTORY_ELEMENT_PREFIX = \"noya-multiplayer-history-\";\n\nexport type StateInspectorAnchor =\n | \"left\"\n | \"right\"\n | \"bottom left\"\n | \"bottom right\";\n\nexport type StateInspectorOptions = {\n colorScheme?: \"light\" | \"dark\";\n anchor?: StateInspectorAnchor;\n};\n\nexport const StateInspector = memo(function StateInspector<S, M, E>({\n state,\n connectionEvents,\n connectedUsers,\n tasks,\n userId,\n unstyled,\n colorScheme = \"light\",\n multiplayerStateManager,\n assetManager,\n ephemeralUserData,\n anchor = \"right\",\n forceInit,\n ...props\n}: {\n state: S;\n connectionEvents?: ConnectionEvent<S>[];\n connectedUsers?: MultiplayerUser[];\n tasks?: Task[];\n userId?: string;\n unstyled?: boolean;\n multiplayerStateManager: MultiplayerStateManager<S, M>;\n assetManager: AssetManager;\n ephemeralUserData: EphemeralUserData<E>;\n forceInit: () => void;\n} & StateInspectorOptions &\n ComponentPropsWithoutRef<\"div\">) {\n const [didMount, setDidMount] = React.useState(false);\n\n useLayoutEffect(() => {\n setDidMount(true);\n }, []);\n\n const eventsContainerRef = React.useRef<HTMLDivElement>(null);\n const historyContainerRef = React.useRef<HTMLDivElement>(null);\n\n const [showInspector, setShowInspector] = useLocalStorageState(\n \"noya-multiplayer-react-show-inspector\",\n true\n );\n const [showEvents, setShowEvents] = useLocalStorageState(\n \"noya-multiplayer-react-show-events\",\n false\n );\n const [showHistory, setShowHistory] = useLocalStorageState(\n \"noya-multiplayer-react-show-history\",\n false\n );\n const [showUsers, setShowUsers] = useLocalStorageState(\n \"noya-multiplayer-react-show-users\",\n true\n );\n const [showData, setShowData] = useLocalStorageState(\n \"noya-multiplayer-react-show-data\",\n true\n );\n const [showTasks, setShowTasks] = useLocalStorageState(\n \"noya-multiplayer-react-show-tasks\",\n false\n );\n const [showEphemeral, setShowEphemeral] = useLocalStorageState(\n \"noya-multiplayer-react-show-ephemeral\",\n false\n );\n const [showAssets, setShowAssets] = useLocalStorageState(\n \"noya-multiplayer-react-show-assets\",\n false\n );\n\n useEffect(() => {\n shouldTrackEvents$.set(showEvents);\n }, [showEvents]);\n\n useEffect(() => {\n shouldTrackTasks$.set(showTasks);\n }, [showTasks]);\n\n useEffect(() => {\n if (eventsContainerRef.current) {\n eventsContainerRef.current.scrollTop =\n eventsContainerRef.current.scrollHeight;\n }\n }, [connectionEvents]);\n\n const ephemeral = useEphemeralUserData(ephemeralUserData);\n const historySnapshot = useManagedHistory(multiplayerStateManager.sm);\n const assets = useObservable(assetManager.assets$);\n\n useEffect(() => {\n if (historyContainerRef.current) {\n historyContainerRef.current.scrollTop =\n historyContainerRef.current.scrollHeight;\n }\n }, [historySnapshot]);\n\n // If history index changes, scroll to the new history entry into view\n useEffect(() => {\n if (!historyContainerRef.current) return;\n\n const historyEntry = historyContainerRef.current.querySelector(\n `#${HISTORY_ELEMENT_PREFIX}${historySnapshot.historyIndex}`\n );\n\n if (historyEntry) {\n historyEntry.scrollIntoView({\n block: \"nearest\",\n inline: \"nearest\",\n });\n }\n }, [historySnapshot.historyIndex]);\n\n const theme = colorScheme === \"light\" ? lightTheme : darkTheme;\n // const borderColor =\n // colorScheme === \"light\" ? \"rgba(0,0,0,0.1)\" : \"rgba(255,255,255,0.1)\";\n const solidBorderColor =\n colorScheme === \"light\" ? \"rgb(223 223 223)\" : \"rgb(29 29 29)\";\n\n const baseStyle: CSSProperties = {\n position: \"fixed\",\n top: 12,\n ...(anchor.includes(\"right\") ? { right: 12 } : { left: 12 }),\n bottom: 12,\n width: 400,\n background:\n colorScheme === \"light\" ? \"rgba(255,255,255,0.95)\" : \"rgba(0,0,0,0.95)\",\n backdropFilter: \"blur(48px)\",\n border: `1px solid ${solidBorderColor}`,\n // outlineOffset: -1,\n borderRadius: 4,\n display: \"flex\",\n flexDirection: \"column\",\n // gap: 12,\n color: theme.BASE_COLOR,\n overflow: \"hidden\",\n zIndex: 9999,\n lineHeight: \"13px\",\n };\n\n if (!didMount) return null;\n\n if (!showInspector) {\n return (\n <div\n {...props}\n style={{\n ...baseStyle,\n padding: \"4px 10px\",\n width: undefined,\n ...(anchor.includes(\"bottom\")\n ? { bottom: 12, top: undefined }\n : { bottom: undefined }),\n }}\n onClick={() => setShowInspector(true)}\n >\n <ToggleButton\n showInspector={showInspector}\n setShowInspector={setShowInspector}\n theme={theme}\n anchor={anchor}\n />\n </div>\n );\n }\n\n return (\n <div\n {...props}\n style={{\n ...(!unstyled && baseStyle),\n ...props.style,\n }}\n >\n <DisclosureSection\n isFirst\n open={showUsers}\n setOpen={setShowUsers}\n title=\"Users\"\n colorScheme={colorScheme}\n style={{\n flex: \"0 0 auto\",\n maxHeight: \"200px\",\n }}\n right={\n <ToggleButton\n showInspector={showInspector}\n setShowInspector={setShowInspector}\n theme={theme}\n anchor={anchor}\n />\n }\n >\n <div style={{ ...styles.sectionInner, flex: \"0 0 auto\" }}>\n {connectedUsers?.map((user) => (\n <InspectorRow\n key={user.id}\n colorScheme={colorScheme}\n variant={user.id === userId ? \"up\" : undefined}\n >\n {user.image && (\n <img\n src={user.image}\n alt={user.name}\n style={{\n width: \"12px\",\n height: \"12px\",\n borderRadius: \"50%\",\n marginRight: \"4px\",\n display: \"inline-block\",\n position: \"relative\",\n top: \"-1px\",\n background: solidBorderColor,\n }}\n />\n )}\n {user.name} ({ellipsis(user.id.toString(), 8, \"middle\")})\n </InspectorRow>\n ))}\n {!connectedUsers && (\n <div\n style={{\n padding: \"12px\",\n fontSize: \"12px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"4px\",\n }}\n >\n <span>No connected users</span>\n </div>\n )}\n </div>\n </DisclosureSection>\n <DisclosureSection\n title=\"Data\"\n colorScheme={colorScheme}\n setOpen={setShowData}\n open={showData}\n right={\n <span\n style={{\n display: \"flex\",\n gap: \"4px\",\n }}\n >\n <SmallButton\n // disabled={!historySnapshot.canUndo}\n theme={theme}\n onClick={() => {\n forceInit();\n }}\n >\n Reset\n </SmallButton>\n </span>\n }\n >\n <div style={styles.sectionInner}>\n <InspectorRow colorScheme={colorScheme}>\n <ObjectInspector\n name={multiplayerStateManager.schema ? \"state\" : undefined}\n data={state}\n theme={theme}\n />\n </InspectorRow>\n {multiplayerStateManager.schema && (\n <InspectorRow colorScheme={colorScheme}>\n <ObjectInspector\n name=\"schema\"\n data={multiplayerStateManager.schema}\n theme={theme}\n />\n </InspectorRow>\n )}\n </div>\n </DisclosureSection>\n <DisclosureSection\n open={showHistory}\n setOpen={setShowHistory}\n title=\"History\"\n colorScheme={colorScheme}\n right={\n <span\n style={{\n display: \"flex\",\n gap: \"4px\",\n }}\n >\n <SmallButton\n disabled={!historySnapshot.canUndo}\n theme={theme}\n onClick={() => {\n multiplayerStateManager.undo();\n }}\n >\n <span style={{ width: \"12px\", height: \"12px\" }}>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"1em\"\n height=\"1em\"\n viewBox=\"0 0 20 20\"\n >\n <path\n fill=\"currentColor\"\n 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\"\n />\n </svg>\n </span>\n </SmallButton>\n <SmallButton\n disabled={!historySnapshot.canRedo}\n theme={theme}\n onClick={() => {\n multiplayerStateManager.redo();\n }}\n >\n <span style={{ width: \"12px\", height: \"12px\" }}>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"1em\"\n height=\"1em\"\n viewBox=\"0 0 20 20\"\n >\n <path\n fill=\"currentColor\"\n 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\"\n />\n </svg>\n </span>\n </SmallButton>\n </span>\n }\n >\n <div ref={historyContainerRef} style={styles.sectionInner}>\n <div\n id={`${HISTORY_ELEMENT_PREFIX}0`}\n style={{\n borderBottom: `1px solid ${solidBorderColor}`,\n fontSize: \"12px\",\n fontFamily: \"Menlo, monospace\",\n padding: \"2px 12px 1px\",\n display: \"flex\",\n alignItems: \"center\",\n background:\n historySnapshot.historyIndex === 0\n ? \"rgb(59 130 246 / 15%)\"\n : undefined,\n }}\n >\n <span\n style={{\n fontFamily: \"Menlo, monospace\",\n fontSize: \"11px\",\n borderRadius: 4,\n display: \"inline-block\",\n }}\n >\n Initial state\n </span>\n </div>\n {historySnapshot.history.map((entry, index) => (\n <div\n id={`${HISTORY_ELEMENT_PREFIX}${index + 1}`}\n key={index}\n style={{\n padding: \"0px 12px 1px\",\n borderBottom: `1px solid ${solidBorderColor}`,\n background:\n index + 1 === historySnapshot.historyIndex\n ? \"rgb(59 130 246 / 15%)\"\n : undefined,\n }}\n >\n {\"name\" in entry.metadata &&\n typeof entry.metadata.name === \"string\" && (\n <pre\n style={{\n fontSize: \"11px\",\n display: \"flex\",\n flexWrap: \"wrap\",\n }}\n >\n {entry.metadata.name}\n </pre>\n )}\n {entry.redoPatches?.map((patch, j) => (\n <pre\n key={j}\n style={{\n fontSize: \"11px\",\n display: \"flex\",\n flexWrap: \"wrap\",\n }}\n >\n {patch.op === \"add\" && (\n <>\n <span style={{ fontStyle: \"italic\" }}>\n {pathToString(patch.path)}\n </span>\n {\" = \"}\n <ObjectInspector data={patch.value} theme={theme} />\n </>\n )}\n {patch.op === \"replace\" && (\n <>\n <span style={{ fontStyle: \"italic\" }}>\n {pathToString(patch.path)}\n </span>\n {\" = \"}\n <ObjectInspector data={patch.value} theme={theme} />\n </>\n )}\n {patch.op === \"remove\" && (\n <>\n <span style={{ color: theme.OBJECT_VALUE_STRING_COLOR }}>\n delete{\" \"}\n </span>\n <span style={{ fontStyle: \"italic\" }}>\n {pathToString(patch.path)}\n </span>\n </>\n )}\n {patch.op === \"move\" && (\n <>\n <span style={{ fontStyle: \"italic\" }}>\n {pathToString(patch.from!)}\n </span>\n {\" -> \"}\n <span style={{ fontStyle: \"italic\" }}>\n {pathToString(patch.path)}\n </span>\n </>\n )}\n </pre>\n ))}\n </div>\n ))}\n </div>\n </DisclosureSection>\n <DisclosureSection\n open={showAssets}\n setOpen={setShowAssets}\n title=\"Assets\"\n colorScheme={colorScheme}\n right={\n <span style={{ display: \"flex\", gap: \"4px\" }}>\n <SmallButton\n theme={theme}\n onClick={() => {\n // get file input\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.onchange = () => {\n const file = input.files?.[0];\n if (file) {\n const reader = new FileReader();\n reader.onload = () => {\n const buffer = reader.result as ArrayBuffer;\n assetManager.create(new Uint8Array(buffer));\n };\n reader.readAsArrayBuffer(file);\n }\n };\n input.click();\n }}\n >\n Upload\n </SmallButton>\n </span>\n }\n >\n <div style={styles.sectionInner}>\n {assets.map((asset) => (\n <InspectorRow key={asset.id} colorScheme={colorScheme}>\n <ObjectInspector name={asset.id} data={asset} theme={theme} />\n <SmallButton\n theme={theme}\n onClick={() => assetManager.delete(asset.id)}\n >\n Delete\n </SmallButton>\n </InspectorRow>\n ))}\n </div>\n </DisclosureSection>\n <DisclosureSection\n title=\"Tasks\"\n colorScheme={colorScheme}\n open={showTasks}\n setOpen={setShowTasks}\n >\n <div style={styles.sectionInner}>\n {tasks?.map((task) => (\n <InspectorRow\n key={task.id}\n colorScheme={colorScheme}\n style={{\n backgroundColor:\n task.status === \"done\"\n ? \"rgba(0,255,0,0.2)\"\n : task.status === \"error\"\n ? \"rgba(255,0,0,0.2)\"\n : undefined,\n }}\n >\n <ObjectInspector\n name={task.name}\n data={task.payload}\n theme={theme}\n />\n </InspectorRow>\n ))}\n </div>\n </DisclosureSection>\n <DisclosureSection\n open={showEphemeral}\n setOpen={setShowEphemeral}\n title=\"Ephemeral User Data\"\n colorScheme={colorScheme}\n >\n <div style={styles.sectionInner}>\n {Object.entries(ephemeral).map(([key, value]) => (\n <InspectorRow key={key} colorScheme={colorScheme}>\n <ObjectInspector\n name={key}\n data={value}\n theme={theme}\n expandLevel={10}\n />\n </InspectorRow>\n ))}\n </div>\n </DisclosureSection>\n <DisclosureSection\n open={showEvents}\n setOpen={setShowEvents}\n title=\"Events\"\n colorScheme={colorScheme}\n >\n <div ref={eventsContainerRef} style={styles.sectionInner}>\n {connectionEvents?.map((event, index) =>\n event.type === \"stateChange\" ? (\n <InspectorRow key={index} colorScheme={colorScheme}>\n connection:{\" \"}\n <span style={{ fontStyle: \"italic\" }}>\n {event.state.toLowerCase()}\n </span>\n </InspectorRow>\n ) : (\n <InspectorRow\n key={index}\n colorScheme={colorScheme}\n variant={event.type === \"send\" ? \"up\" : \"down\"}\n style={{\n padding: \"0px 12px 1px\",\n }}\n >\n <ObjectInspector\n data={event.type === \"error\" ? event.error : event.message}\n theme={theme}\n nodeRenderer={({\n depth,\n name,\n data,\n isNonenumerable,\n expanded,\n }: any) => {\n const direction = event.type === \"send\" ? \"up\" : \"down\";\n\n return depth === 0 ? (\n <ObjectRootLabel direction={direction} data={data} />\n ) : (\n <ObjectLabel\n direction={direction}\n name={name}\n data={data}\n isNonenumerable={isNonenumerable}\n />\n );\n }}\n />\n </InspectorRow>\n )\n )}\n {!connectionEvents && (\n <div\n style={{\n padding: \"12px\",\n fontSize: \"12px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"4px\",\n }}\n >\n <span>No recorded events</span>\n </div>\n )}\n </div>\n </DisclosureSection>\n </div>\n );\n});\n\ntype MessageDirection = \"up\" | \"down\";\n\nconst ObjectRootLabel: FC<{\n name?: string;\n data: any;\n direction?: MessageDirection;\n}> = ({ name, data, direction }) => {\n if (typeof name === \"string\") {\n return (\n <span>\n <ObjectName name={name} />\n <span>: </span>\n <ObjectPreview data={data} />\n </span>\n );\n }\n if (direction === \"up\" || direction === \"down\") {\n const arrow = direction === \"up\" ? \"↑\" : \"↓\";\n\n return (\n <span>\n <span\n style={{\n background:\n direction === \"up\" ? \"rgba(0,255,0,0.2)\" : \"rgba(255,0,0,0.2)\",\n // color: \"white\",\n width: 12,\n height: 12,\n borderRadius: 2,\n display: \"inline-flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n marginRight: 4,\n lineHeight: \"12px\",\n }}\n >\n {arrow}\n </span>\n <ObjectPreview data={data} />\n </span>\n );\n } else {\n return <ObjectPreview data={data} />;\n }\n};\n\n// Rotates ▶️ or ▼ based on expanded state\nfunction Arrow({\n expanded,\n onClick,\n style,\n}: {\n expanded: boolean;\n onClick?: () => void;\n style?: CSSProperties;\n}) {\n return (\n <span\n role=\"button\"\n onClick={onClick}\n style={{\n display: \"inline-block\",\n textAlign: \"center\",\n transform: expanded ? \"rotate(0deg)\" : \"rotate(-90deg)\",\n fontFamily: \"Menlo, monospace\",\n ...style,\n }}\n >\n {\"▼\"}\n </span>\n );\n}\n\nfunction pathToString(extendedPath: ExtendedPathKey[]) {\n return extendedPath\n .map((key) =>\n typeof key === \"object\"\n ? `:${ellipsis(key.id.toString(), 8, \"middle\")}`\n : key\n )\n .map((key, index) =>\n index === 0 || (typeof key === \"string\" && key.startsWith(\":\"))\n ? key\n : `.${key}`\n )\n .join(\"\");\n}\n\ntype EllipsisPosition = \"start\" | \"middle\" | \"end\";\n\nfunction ellipsis(\n str: string,\n maxLength: number,\n position: EllipsisPosition = \"end\"\n) {\n if (str.length <= maxLength) return str;\n\n switch (position) {\n case \"start\":\n return `…${str.slice(str.length - maxLength)}`;\n case \"middle\":\n const halfLength = Math.floor(maxLength / 2);\n return `${str.slice(0, halfLength)}…${str.slice(str.length - halfLength)}`;\n case \"end\":\n return `${str.slice(0, maxLength)}…`;\n }\n}\n\nfunction SmallButton({\n children,\n onClick,\n style,\n theme,\n disabled,\n}: {\n children: React.ReactNode;\n onClick: () => void;\n style?: CSSProperties;\n theme: typeof chromeLight;\n disabled?: boolean;\n}) {\n return (\n <button\n type=\"button\"\n disabled={disabled}\n onClick={(event) => {\n event.stopPropagation();\n onClick();\n }}\n style={{\n flex: \"0\",\n appearance: \"none\",\n background: \"none\",\n color: theme.BASE_COLOR,\n opacity: disabled ? 0.25 : 1,\n border: \"none\",\n fontSize: \"12px\",\n whiteSpace: \"nowrap\",\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"0\",\n cursor: \"pointer\",\n ...style,\n }}\n >\n {children}\n </button>\n );\n}\n","\"use client\";\n\nimport React from \"react\";\n\nconst localStorage = typeof window !== \"undefined\" ? window.localStorage : null;\n\nexport function useLocalStorageState<S>(\n key: string,\n defaultValue: S\n): [S, (value: S) => void] {\n const [state, setState] = React.useState<S>(() => {\n const value = localStorage?.getItem(key);\n let result = defaultValue;\n if (value) {\n try {\n result = JSON.parse(value);\n } catch (error) {\n console.error(\"Error parsing localStorage value\", error);\n }\n }\n return result;\n });\n\n const setLocalStorageState = (value: S) => {\n localStorage?.setItem(key, JSON.stringify(value));\n setState(value);\n };\n\n return [state, setLocalStorageState];\n}\n","/* eslint-disable no-restricted-globals */\nimport {\n createOrCastValue,\n findAllDefs,\n localStorageSync,\n MultiplayerUser,\n Static,\n stubSync,\n SyncAdapter,\n TSchema,\n TypeGuard,\n webSocketSync,\n} from \"@noya-app/state-manager\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useMultiplayerState, UseMultiplayerStateOptions } from \"./hooks\";\nimport { StateInspectorOptions } from \"./inspector/StateInspector\";\n\nexport type AppViewType = \"editable\" | \"readOnly\" | \"preview\";\n\nexport type AppTheme = \"light\" | \"dark\";\n\nexport type AppData<State> = {\n multiplayerUrl?: string;\n theme: AppTheme;\n viewType: AppViewType;\n initialState: State;\n inspector: boolean | StateInspectorOptions;\n};\n\nexport function createDefaultAppData<State>(\n initialState: State\n): AppData<State> {\n return {\n theme: \"light\",\n viewType: \"editable\",\n initialState,\n inspector: false,\n };\n}\n\nexport type GetAppDataOptions = {\n window?: { location: { hash: string } };\n overrideExistingState?: boolean;\n};\n\nexport function enforceSchema<State>(\n initialState: State,\n schema?: TSchema\n): State {\n return schema\n ? (createOrCastValue({\n schema,\n value: initialState,\n defs: findAllDefs(schema),\n }) as State)\n : initialState;\n}\n\nexport function parseAppDataParameter(\n options?: GetAppDataOptions\n): AppData<unknown> | null {\n const window = options?.window ?? globalThis;\n const location = window.location;\n if (!location) return null;\n const urlHash = (location.hash || \"\").replace(/^#/, \"\");\n const params = new URLSearchParams(urlHash);\n const data = params.get(\"data\");\n if (!data) return null;\n try {\n return JSON.parse(data);\n } catch (e) {\n return null;\n }\n}\n\nexport function getAppData<State>(\n initialState: State | (() => State),\n schema?: TSchema,\n options?: GetAppDataOptions\n): AppData<State> {\n const resolvedInitialState =\n initialState instanceof Function ? initialState() : initialState;\n\n let appData =\n parseAppDataParameter(options) ??\n createDefaultAppData(resolvedInitialState);\n\n if (options?.overrideExistingState) {\n appData.initialState = resolvedInitialState;\n }\n\n appData.initialState = enforceSchema(appData.initialState, schema) as State;\n\n return appData as AppData<State>;\n}\n\nexport type IframeToHostMessage =\n | {\n type: \"application.setMenuItems\";\n payload: {\n menuItems: any[];\n };\n }\n | {\n type: \"multiplayer.setUsers\";\n payload: {\n users: any[];\n };\n };\n\nexport type HostToIframeMessage = {\n type: \"application.selectMenuItem\";\n payload: {\n value: string;\n };\n};\n\nexport function useBroadcastConnectedUsers(connectedUsers: MultiplayerUser[]) {\n useEffect(() => {\n if (!isEmbeddedApp()) return;\n\n const message: IframeToHostMessage = {\n type: \"multiplayer.setUsers\",\n payload: { users: connectedUsers },\n };\n\n parent?.postMessage(message, \"*\");\n }, [connectedUsers]);\n}\n\nexport function useBroadcastMenuItems<T>(\n menuItems: any[],\n handleSelectMenuItem: (value: T) => void\n) {\n useEffect(() => {\n if (!isEmbeddedApp()) return;\n\n const message: IframeToHostMessage = {\n type: \"application.setMenuItems\",\n payload: { menuItems },\n };\n\n parent?.postMessage(message, \"*\");\n\n const listener = (event: MessageEvent<HostToIframeMessage>) => {\n if (event.data.type === \"application.selectMenuItem\") {\n handleSelectMenuItem(event.data.payload.value as T);\n }\n };\n\n window.addEventListener(\"message\", listener);\n\n return () => {\n window.removeEventListener(\"message\", listener);\n };\n }, [handleSelectMenuItem, menuItems]);\n}\n\nexport function isEmbeddedApp() {\n return window.self !== window.top;\n}\n\nexport type UseNoyaStateOptions<\n S,\n M = void,\n E = void,\n> = UseMultiplayerStateOptions<S, M, E> & {\n offlineStorageKey?: string;\n};\n\nexport type UseNoyaStateResult<S, M = void, E = void> = [\n ReturnType<typeof useMultiplayerState<S, M, E>>[0],\n ReturnType<typeof useMultiplayerState<S, M, E>>[1],\n ReturnType<typeof useMultiplayerState<S, M, E>>[2] & {\n theme: AppTheme;\n viewType: AppViewType;\n },\n];\n\n/**\n * Sync data locally or to a multiplayer server.\n *\n * There are 3 ways to use this hook:\n *\n * 1. Pass an initial state: `useNoyaState(initialState)`\n * 2. Pass an initial state and a schema: `useNoyaState(initialState, { schema })`\n * 3. Pass only a schema, and a conforming initial state is created automatically: `useNoyaState({ schema })`\n */\nexport function useNoyaState<\n S,\n M = void,\n E = void,\n O extends UseNoyaStateOptions<S, M, E> = UseNoyaStateOptions<S, M, E>,\n>(\n ...args:\n | [\n initialState: O[\"schema\"] extends TSchema\n ? Static<O[\"schema\"]> | (() => Static<O[\"schema\"]>)\n : S | (() => S),\n options?: O,\n ]\n | [options: O & { schema: TSchema }]\n): UseNoyaStateResult<\n O[\"schema\"] extends TSchema ? Static<O[\"schema\"]> : S,\n M,\n E\n> {\n const [initialState, options] =\n typeof args[0] === \"object\" &&\n args[0] !== null &&\n \"schema\" in args[0] &&\n TypeGuard.IsSchema(args[0].schema)\n ? [null, args[0]]\n : [args[0], args[1]];\n\n // Keep these stable after initial render\n const [\n {\n multiplayerUrl,\n inspector,\n initialState: noyaAppInitialState,\n theme,\n viewType,\n },\n ] = useState(() => {\n return getAppData(initialState, options?.schema, {\n overrideExistingState: options?.overrideExistingState,\n });\n });\n\n const sync = useMemo((): SyncAdapter<S, M, E> => {\n return multiplayerUrl\n ? webSocketSync(multiplayerUrl)\n : options?.offlineStorageKey\n ? localStorageSync({ key: options.offlineStorageKey })\n : stubSync();\n }, [multiplayerUrl, options?.offlineStorageKey]);\n\n const result = useMultiplayerState(noyaAppInitialState as S, {\n ...options,\n inspector: options?.inspector ?? inspector,\n sync: options?.sync ?? sync,\n });\n\n const [, , extras] = result;\n\n useBroadcastConnectedUsers(extras.connectedUsers);\n\n const mergedExtras = useMemo(() => {\n return { ...extras, theme, viewType } as const;\n }, [extras, theme, viewType]);\n\n return [result[0], result[1], mergedExtras] as UseNoyaStateResult<\n O[\"schema\"] extends TSchema ? Static<O[\"schema\"]> : S,\n M,\n E\n >;\n}\n\n// function typeTest() {\n// const [a, setA] = useNoyaState(7);\n// const [b, setB] = useNoyaState(7, {\n// schema: Type.Number(),\n// });\n// const [c, setC] = useNoyaState({\n// schema: Type.Number(),\n// });\n// }\n","import { GetAtPath, ObservableOptions, PathKey } from \"@noya-app/observable\";\nimport {\n AssetManager,\n MultiplayerStateManager,\n StateManagerOptions,\n Static,\n TSchema,\n} from \"@noya-app/state-manager\";\nimport React, {\n createContext,\n SetStateAction,\n useCallback,\n useContext,\n useMemo,\n} from \"react\";\nimport { useNoyaState, UseNoyaStateOptions } from \"./noyaApp\";\nimport { useObservable } from \"./useObservable\";\n\ninterface NoyaStateProviderProps<S, M, E>\n extends Omit<UseNoyaStateOptions<S, M, E>, \"schema\" | \"mergeHistoryEntries\"> {\n children: React.ReactNode;\n initialState?: S;\n}\n\nconst AnyNoyaStateContext = createContext<\n | { ms: MultiplayerStateManager<any, any>; assetManager: AssetManager }\n | undefined\n>(undefined);\n\nfunction useAnyNoyaStateContext() {\n const value = useContext(AnyNoyaStateContext);\n\n if (!value) {\n throw new Error(\n \"useNoyaStateContext must be used within a NoyaStateProvider\"\n );\n }\n\n return value;\n}\n\nexport function useAssets() {\n const { assetManager } = useAnyNoyaStateContext();\n return useObservable(assetManager.assets$);\n}\n\nexport function useAsset(id: string | undefined) {\n const { assetManager } = useAnyNoyaStateContext();\n const observable = useMemo(\n () => assetManager.assets$.map((assets) => assets.find((a) => a.id === id)),\n [assetManager, id]\n );\n return useObservable(observable);\n}\n\nexport function useAssetManager() {\n const { assetManager } = useAnyNoyaStateContext();\n return useMemo(\n () => ({\n create: assetManager.create,\n delete: assetManager.delete,\n }),\n [assetManager]\n );\n}\n\nexport function createNoyaContext<Schema extends TSchema, M = void, E = void>({\n schema,\n mergeHistoryEntries,\n}: {\n schema: Schema;\n mergeHistoryEntries?: StateManagerOptions<\n Static<Schema>,\n M\n >[\"mergeHistoryEntries\"];\n}) {\n type S = Static<Schema>;\n\n const NoyaStateContext = AnyNoyaStateContext as React.Context<\n | {\n ms: MultiplayerStateManager<S, M>;\n assetManager: AssetManager;\n }\n | undefined\n >;\n\n function NoyaStateProvider({\n children,\n initialState,\n ...options\n }: NoyaStateProviderProps<S, M, E>) {\n const [, , { multiplayerStateManager, assetManager }] = useNoyaState(\n initialState,\n {\n ...(options as any),\n schema,\n mergeHistoryEntries,\n }\n );\n\n const value = useMemo(\n () => ({\n ms: multiplayerStateManager as MultiplayerStateManager<any, any>,\n assetManager,\n }),\n [multiplayerStateManager, assetManager]\n );\n\n return (\n <AnyNoyaStateContext.Provider value={value}>\n {children}\n </AnyNoyaStateContext.Provider>\n );\n }\n\n function useValue(): S;\n function useValue<A>(\n selector: (value: S) => A,\n options?: Pick<ObservableOptions, \"isEqual\">\n ): A;\n function useValue<P extends PathKey[] | string>(path: P): GetAtPath<S, P>;\n function useValue(\n path?: PathKey[] | string | ((value: S) => any),\n options?: Pick<ObservableOptions, \"isEqual\">\n ) {\n const { ms } = useAnyNoyaStateContext();\n\n let actualPath: PathKey[] | string =\n typeof path === \"function\" || !path ? \"\" : path;\n\n const mappedObservable = useMemo(() => {\n if (typeof path === \"function\") {\n return ms.optimisticState$.map(path, { isEqual: options?.isEqual });\n }\n return ms.optimisticState$;\n }, [ms, path, options?.isEqual]);\n\n const value = useObservable(mappedObservable, actualPath);\n\n return value;\n }\n\n function useSetValue(): M extends {}\n ? (metadata: M, value: SetStateAction<S>) => void\n : (value: SetStateAction<S>) => void;\n function useSetValue<P extends PathKey[] | string>(\n path: P\n ): M extends {}\n ? (metadata: M, value: SetStateAction<GetAtPath<S, P>>) => void\n : (value: SetStateAction<GetAtPath<S, P>>) => void;\n function useSetValue<P extends PathKey[] | string>(path?: P) {\n const { ms } = useAnyNoyaStateContext();\n\n const setValue = useCallback(\n (\n ...args: M extends {}\n ? [metadata: M, value: SetStateAction<GetAtPath<S, P>>]\n : [value: SetStateAction<GetAtPath<S, P>>]\n ): void => {\n const [metadata, value] =\n args.length === 2 ? args : [undefined as M, args[0]];\n\n const setStateAtPath = ms.setStateAtPath as (\n metadata: M,\n path: P,\n value: GetAtPath<S, P>\n ) => void;\n\n setStateAtPath(metadata, (path ?? \"\") as P, value as never);\n },\n [ms, path]\n );\n\n return setValue as M extends {}\n ? (metadata: M, value: SetStateAction<GetAtPath<S, P>>) => void\n : (value: SetStateAction<GetAtPath<S, P>>) => void;\n }\n\n function useValueState(): [\n S,\n M extends {}\n ? (metadata: M, value: SetStateAction<S>) => void\n : (value: SetStateAction<S>) => void,\n ];\n function useValueState<A>(\n selector: (value: S) => A,\n options?: ObservableOptions\n ): [\n A,\n M extends {}\n ? (metadata: M, value: SetStateAction<S>) => void\n : (value: SetStateAction<S>) => void,\n ];\n function useValueState<P extends PathKey[] | string>(\n path?: P\n ): [\n GetAtPath<S, P>,\n M extends {}\n ? (metadata: M, value: SetStateAction<GetAtPath<S, P>>) => void\n : (value: SetStateAction<GetAtPath<S, P>>) => void,\n ];\n function useValueState<P extends PathKey[] | string>(\n ...args: [P?] | [selector: (value: S) => any, options?: ObservableOptions]\n ) {\n const [selector, options, path] =\n args.length >= 1 && typeof args[0] === \"function\"\n ? [args[0], args[1], undefined]\n : [undefined, undefined, args[0] as P | undefined];\n\n const value = useValue((selector ?? path ?? \"\") as any, options);\n const setValue = useSetValue(path ?? \"\");\n return [value, setValue];\n }\n\n function useStateManager() {\n const { ms } = useAnyNoyaStateContext() as {\n ms: MultiplayerStateManager<S, M>;\n };\n\n return ms;\n }\n\n return {\n Context: NoyaStateContext,\n Provider: NoyaStateProvider,\n useValue,\n useSetValue,\n useValueState,\n useStateManager,\n // useAssets,\n // useAssetManager,\n // useAsset,\n };\n}\n"],"mappings":"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","names":["useMemo","listen","get","useMemo","UserPointer","UserPointerContainer","UserNameTag","useEffect","useMemo","useState","useSyncExternalStore","createRoot","React","React","useLayoutEffect","React","memo","useEffect","React","React","memo","StateInspector","useEffect","React","useLayoutEffect","root","useSyncExternalStore","useState","useMemo","useEffect","userId","tasks","state","createRoot","stubSync","useEffect","useMemo","useState","window","useEffect","useState","useMemo","stubSync","React","useCallback","useMemo","useMemo","React","useCallback"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/avatarStyle.ts","../src/components/UserPointersOverlay.tsx","../src/useObservable.ts","../src/hooks.ts","../src/components/ErrorOverlay.tsx","../src/globals.ts","../src/inspector/useStateInspector.tsx","../src/inspector/StateInspector.tsx","../src/inspector/useLocalStorageState.tsx","../src/noyaApp.ts","../src/NoyaStateContext.tsx"],"sourcesContent":["export * from \"@noya-app/state-manager\";\nexport * from \"./avatarStyle\";\nexport * from \"./components/UserPointersOverlay\";\nexport * from \"./hooks\";\nexport * from \"./inspector/StateInspector\";\nexport * from \"./noyaApp\";\nexport * from \"./NoyaStateContext\";\nexport * from \"./useObservable\";\n","function hashCode(string: string) {\n let hash = 0;\n\n for (const char of string) {\n hash = char.charCodeAt(0) + ((hash << 5) - hash);\n }\n\n return hash;\n}\n\nfunction elementFromHash<T>(array: T[], hash: number): T {\n return array[Math.abs(hash) % array.length];\n}\n\nexport function getAvatarInitials(name: string) {\n return name\n .split(\" \")\n .filter((c) => c.length > 0)\n .map((c) => c[0])\n .join(\"\")\n .toLocaleUpperCase();\n}\n\n/**\n * Create a background color and initials from a name\n *\n * Adapted from https://mui.com/material-ui/react-avatar/\n */\nexport function getAvatarStyle(name: string) {\n const hash = hashCode(name);\n const color = elementFromHash(Object.values(colors500), hash);\n // const darkerColor = elementFromHash(Object.values(colors800), hash);\n\n return {\n color: \"white\",\n backgroundColor: color,\n // primaryColors: {\n // \"500\": color,\n // \"800\": darkerColor,\n // },\n };\n}\n\nconst colors500 = {\n red500: \"#ef4444\",\n orange500: \"#f97316\",\n amber500: \"#f59e0b\",\n yellow500: \"#eab308\",\n lime500: \"#84cc16\",\n green500: \"#22c55e\",\n emerald500: \"#10b981\",\n teal500: \"#14b8a6\",\n cyan500: \"#06b6d4\",\n sky500: \"#0ea5e9\",\n blue500: \"#3b82f6\",\n indigo500: \"#6366f1\",\n violet500: \"#8b5cf6\",\n purple500: \"#a855f7\",\n fuchsia500: \"#d946ef\",\n pink500: \"#ec4899\",\n rose500: \"#f43f5e\",\n};\n\n// const colors800 = {\n// red800: \"#991b1b\",\n// orange800: \"#9a3412\",\n// amber800: \"#92400e\",\n// yellow800: \"#854d0e\",\n// lime800: \"#3f6212\",\n// green800: \"#166534\",\n// emerald800: \"#065f46\",\n// teal800: \"#115e59\",\n// cyan800: \"#155e75\",\n// sky800: \"#075985\",\n// blue800: \"#1e40af\",\n// indigo800: \"#3730a3\",\n// violet800: \"#5b21b6\",\n// purple800: \"#6b21a8\",\n// fuchsia800: \"#86198f\",\n// pink800: \"#9d174d\",\n// rose800: \"#9f1239\",\n// };\n","\"use client\";\n\nimport { EphemeralUserData, MultiplayerUser } from \"@noya-app/state-manager\";\nimport React, { memo, useEffect, useMemo, useState } from \"react\";\nimport { getAvatarStyle } from \"../avatarStyle\";\nimport { useObservable } from \"../useObservable\";\n\ntype Point = { x: number; y: number };\n\nexport type UserPointerData = { pointer?: Point };\n\nexport type UserPointerProps<E extends UserPointerData> = {\n user: MultiplayerUser;\n ephemeralUserData: EphemeralUserData<E>;\n hideAfter?: number;\n};\n\nfunction shouldShow(hideAfter: number, updatedAt: number) {\n return !!updatedAt && Date.now() - updatedAt < hideAfter;\n}\n\nconst UserPointer_ = function UserPointer<E extends UserPointerData>({\n user,\n ephemeralUserData,\n hideAfter = 5000,\n}: UserPointerProps<E>) {\n const metadata = useObservable(ephemeralUserData.metadata$, [\n user.id,\n ] as const);\n const data = useObservable(ephemeralUserData.data$, [user.id] as const);\n const avatarStyle = useMemo(() => getAvatarStyle(user.id), [user.id]);\n\n const [, setForceUpdate] = useState(0);\n\n const updatedAt = metadata?.updatedAt ?? 0;\n\n useEffect(() => {\n if (!shouldShow(hideAfter, updatedAt)) return;\n\n const timeoutId = setTimeout(() => {\n setForceUpdate((prev) => prev + 1);\n }, hideAfter);\n\n return () => clearTimeout(timeoutId);\n }, [hideAfter, updatedAt]);\n\n const show = shouldShow(hideAfter, updatedAt);\n\n if (!data || !data.pointer) return null;\n\n return (\n <UserPointerContainer key={user.id} point={data.pointer} show={show}>\n <UserPointerIcon color={avatarStyle.backgroundColor} />\n <UserNameTag background={avatarStyle.backgroundColor}>\n {user.name}\n </UserNameTag>\n </UserPointerContainer>\n );\n};\n\nexport const UserPointer = memo(UserPointer_) as typeof UserPointer_;\n\nexport const UserPointerContainer = memo(function UserPointerContainer({\n point,\n children,\n show = true,\n}: {\n point: Point;\n children: React.ReactNode;\n show?: boolean;\n}) {\n return (\n <div\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n transform: `translate(${Math.round(point.x)}px, ${Math.round(\n point.y\n )}px)`,\n opacity: show ? 1 : 0,\n transition: \"transform 0.1s, opacity 0.2s\",\n }}\n >\n {children}\n </div>\n );\n});\n\nexport const UserNameTag = memo(function UserNameTag({\n background,\n children,\n}: {\n background: string;\n children: React.ReactNode;\n}) {\n return (\n <span\n style={{\n position: \"relative\",\n top: \"8px\",\n left: \"15px\",\n fontSize: 11,\n lineHeight: \"1\",\n fontWeight: 500,\n boxShadow: \"0 1px 1px rgba(0,0,0,0.1)\",\n padding: \"2px 4px 3px\",\n pointerEvents: \"none\",\n letterSpacing: \"-0.3px\",\n outline: `1px solid rgba(255,255,255,0.3)`,\n outlineOffset: \"-1px\",\n background,\n color: \"white\",\n }}\n >\n {children}\n </span>\n );\n});\n\nexport type UserPointersOverlayProps<E extends UserPointerData> = {\n connectedUsers: MultiplayerUser[];\n ephemeralUserData: EphemeralUserData<E>;\n};\n\nexport const UserPointersOverlay = memo(function UserPointers<\n E extends UserPointerData,\n>({ connectedUsers, ephemeralUserData }: UserPointersOverlayProps<E>) {\n const currentUserId = useObservable(ephemeralUserData.currentUserId$);\n\n return (\n <>\n {connectedUsers.map((user) => {\n if (user.id === currentUserId) return null;\n\n return (\n <UserPointer\n key={user.id}\n user={user}\n ephemeralUserData={\n ephemeralUserData as unknown as EphemeralUserData<E>\n }\n />\n );\n })}\n </>\n );\n});\n\nexport const UserPointerIcon = memo(function CursorIcon({\n color = \"black\",\n}: {\n color?: string;\n}) {\n return (\n <svg\n width=\"15\"\n height=\"15\"\n viewBox=\"0 0 15 15\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n style={{\n position: \"absolute\",\n filter: \"drop-shadow(0 1px 1px rgba(0,0,0,0.1))\",\n // filter: \"drop-shadow(0 1px 1px rgba(0,0,0,0.6))\",\n }}\n >\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M3.29227 0.0451998C3.47033 -0.0361222 3.67946 -0.00606629 3.8274 0.122107L12.8587 7.94648C13.0134 8.08054 13.0708 8.29538 13.0035 8.48873C12.9362 8.68208 12.7578 8.81488 12.5533 8.8239L9.21887 8.97096L11.1504 13.2149C11.2648 13.4662 11.1538 13.7626 10.9026 13.877L8.75024 14.8575C8.499 14.972 8.20255 14.8611 8.08802 14.6099L6.15339 10.3665L3.86279 12.7817C3.72196 12.9302 3.50487 12.9779 3.31479 12.9021C3.1247 12.8263 3 12.6423 3 12.4376V0.500008C3 0.304264 3.11422 0.126522 3.29227 0.0451998Z\"\n fill={color}\n />\n <path\n fillRule=\"evenodd\"\n clipRule=\"evenodd\"\n d=\"M3.29227 0.048984C3.47033 -0.032338 3.67946 -0.00228211 3.8274 0.125891L12.8587 7.95026C13.0134 8.08432 13.0708 8.29916 13.0035 8.49251C12.9362 8.68586 12.7578 8.81866 12.5533 8.82768L9.21887 8.97474L11.1504 13.2187C11.2648 13.47 11.1538 13.7664 10.9026 13.8808L8.75024 14.8613C8.499 14.9758 8.20255 14.8649 8.08802 14.6137L6.15339 10.3703L3.86279 12.7855C3.72196 12.934 3.50487 12.9817 3.31479 12.9059C3.1247 12.8301 3 12.6461 3 12.4414V0.503792C3 0.308048 3.11422 0.130306 3.29227 0.048984ZM4 1.59852V11.1877L5.93799 9.14425C6.05238 9.02363 6.21924 8.96776 6.38319 8.99516C6.54715 9.02256 6.68677 9.12965 6.75573 9.2809L8.79056 13.7441L10.0332 13.178L8.00195 8.71497C7.93313 8.56376 7.94391 8.38824 8.03072 8.24659C8.11753 8.10494 8.26903 8.01566 8.435 8.00834L11.2549 7.88397L4 1.59852Z\"\n fill=\"rgba(255,255,255,0.5)\"\n />\n </svg>\n );\n});\n","import { GetAtPath, Observable, PathKey } from \"@noya-app/observable\";\nimport { useMemo, useSyncExternalStore } from \"react\";\n\nexport function useObservable<T>(observable: Observable<T>): T;\nexport function useObservable<T, P extends PathKey[] | string>(\n observable: Observable<T>,\n path: P\n): GetAtPath<T, P>;\nexport function useObservable<T, P extends PathKey[]>(\n observable: Observable<T>,\n path?: P\n) {\n const { get, listen } = useMemo(() => {\n const listen = path\n ? (callback: (value: GetAtPath<T, P>) => void) =>\n observable.subscribe(path, callback)\n : observable.subscribe;\n\n const get: () => void = path ? () => observable.get(path) : observable.get;\n\n return { get, listen };\n }, [observable, path]);\n\n return useSyncExternalStore(listen, get, get);\n}\n","\"use client\";\n\nimport { GetAtPath } from \"@noya-app/observable\";\nimport {\n ActionHandler,\n AssetManager,\n ConnectionEvent,\n EphemeralUserData,\n MultiplayerStateManager,\n MultiplayerStateManagerError,\n MultiplayerStateManagerOptions,\n MultiplayerUser,\n StateManager,\n StateManagerOptions,\n stubSync,\n SyncAdapter,\n SyncAdapterOptions,\n Task,\n} from \"@noya-app/state-manager\";\nimport {\n createElement,\n SetStateAction,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n} from \"react\";\nimport { createRoot } from \"react-dom/client\";\nimport { ErrorOverlay } from \"./components/ErrorOverlay\";\nimport { shouldTrackEvents$, shouldTrackTasks$ } from \"./globals\";\nimport { StateInspectorOptions } from \"./inspector/StateInspector\";\nimport { useStateInspector } from \"./inspector/useStateInspector\";\nimport { useObservable } from \"./useObservable\";\n\nexport function useSyncStateManager<S, M>(stateManager: StateManager<S, M>): S;\nexport function useSyncStateManager<S, M, P extends string>(\n stateManager: StateManager<S, M>,\n path: P\n): GetAtPath<S, P>;\nexport function useSyncStateManager<S, M>(\n stateManager: StateManager<S, M>,\n path?: string\n) {\n const getSnapshot = useCallback(\n () =>\n typeof path === \"string\"\n ? stateManager.getState(path)\n : stateManager.getState(),\n [stateManager, path]\n );\n\n return useSyncExternalStore(\n stateManager.addListener,\n getSnapshot,\n getSnapshot\n );\n}\n\nexport function useManagedState<S, M = void>(\n createInitialState: () => S,\n options?: StateManagerOptions<S, M>\n) {\n const [stateManager] = useState(\n () => new StateManager<S, M>(createInitialState(), options)\n );\n\n const state = useSyncStateManager(stateManager);\n\n const setState = useCallback(\n (\n ...args: M extends {}\n ? [metadata: M, action: SetStateAction<S>]\n : [action: SetStateAction<S>]\n ) => {\n const [metadata, action] =\n args.length === 1 ? [undefined, args[0]] : args;\n\n if (metadata === undefined) {\n const performActionNoMetadata = stateManager.performAction as (\n handler: ActionHandler<S>\n ) => void;\n\n if (action instanceof Function) {\n performActionNoMetadata({\n run: action,\n undo: () => state,\n });\n } else {\n performActionNoMetadata({\n run: () => action,\n undo: () => state,\n });\n }\n } else {\n const performActionWithMetadata = stateManager.performAction as (\n metadata: M,\n handler: ActionHandler<S>\n ) => void;\n\n if (action instanceof Function) {\n performActionWithMetadata(metadata, {\n run: action,\n undo: () => state,\n });\n } else {\n performActionWithMetadata(metadata, {\n run: () => action,\n undo: () => state,\n });\n }\n }\n },\n [state, stateManager]\n );\n\n return [state, setState, stateManager] as const;\n}\n\nexport function useManagedHistory<S, M = void>(\n stateManager: StateManager<S, M>\n) {\n return useSyncExternalStore(\n stateManager.historyEmittor.addListener,\n stateManager.getHistorySnapshot,\n stateManager.getHistorySnapshot\n );\n}\n\nexport function useSyncMultiplayerStateManager<S, M = void>(\n multiplayerStateManager: MultiplayerStateManager<S, M>\n) {\n return useSyncExternalStore(\n multiplayerStateManager.addListener,\n multiplayerStateManager.getOptimisticState,\n multiplayerStateManager.getOptimisticState\n );\n}\n\nfunction throttle<F extends (...args: any[]) => any>(fn: F, ms: number) {\n let lastCall = 0;\n let timeoutId: number | null = null;\n return (...args: Parameters<F>) => {\n const now = Date.now();\n if (now - lastCall < ms) {\n if (timeoutId) clearTimeout(timeoutId);\n timeoutId = setTimeout(\n () => {\n lastCall = now;\n fn(...args);\n },\n ms - (now - lastCall)\n ) as unknown as number;\n return;\n }\n lastCall = now;\n return fn(...args);\n };\n}\n\nexport function useEphemeralUserData<E>(\n ephemeralUserData: EphemeralUserData<E>,\n options?: {\n throttle?: number;\n }\n) {\n const throttledAddListener = useMemo(() => {\n const throttleMs = options?.throttle ?? 0;\n\n if (throttleMs > 0) {\n const addListener = (\n fn: Parameters<typeof ephemeralUserData.addListener>[0]\n ) => {\n const throttledFn = throttle(fn, throttleMs);\n return ephemeralUserData.addListener(throttledFn);\n };\n\n return addListener;\n }\n\n return ephemeralUserData.addListener;\n }, [ephemeralUserData, options?.throttle]);\n\n return useSyncExternalStore(\n throttledAddListener,\n ephemeralUserData.getSnapshot,\n ephemeralUserData.getSnapshot\n );\n}\n\nconst defaultStubSync = stubSync();\n\nexport type UseMultiplayerStateOptions<\n S,\n M = void,\n E = void,\n> = MultiplayerStateManagerOptions<S, M> & {\n sync?: (\n options: Pick<\n SyncAdapterOptions<S, M, E>,\n \"ms\" | \"ephemeralUserData\" | \"assetManager\"\n >\n ) => void;\n trackConnectionEvents?: boolean;\n trackTasks?: boolean;\n inspector?: boolean | StateInspectorOptions;\n};\n\nexport function useMultiplayerState<S, M = void, E = void>(\n initialState: S | (() => S),\n options?: UseMultiplayerStateOptions<S, M, E>\n) {\n const { sync = defaultStubSync as unknown as SyncAdapter<S, M, E>, ...rest } =\n options ?? {};\n\n const [multiplayerStateManager] = useState(\n () => new MultiplayerStateManager<S, M>(initialState, rest)\n );\n const [assetManager] = useState(() => new AssetManager());\n const syncRef = useRef(sync);\n\n const [connectionEvents, setConnectionEvents] = useState<\n ConnectionEvent<S>[] | undefined\n >();\n\n const [connectedUsers, setConnectedUsers] = useState<MultiplayerUser[]>([]);\n const [ephemeralUserData] = useState<EphemeralUserData<E>>(\n () => new EphemeralUserData()\n );\n const [tasks, setTasks] = useState<Task[]>([]);\n const [userId, setUserId] = useState<string | undefined>();\n const assets = useObservable(assetManager.assets$);\n\n const extras = useMemo(() => {\n return {\n tasks,\n userId,\n connectionEvents,\n connectedUsers,\n ephemeralUserData,\n multiplayerStateManager,\n assets,\n assetManager,\n createAsset: assetManager.create,\n deleteAsset: assetManager.delete,\n // evaluate: async (code: string) => {\n // const payload = await rpcManager.request({ type: \"eval\", code });\n\n // if (payload.type !== \"eval\") {\n // throw new Error(`Unexpected rpc response type: ${payload.type}`);\n // }\n // },\n };\n }, [\n tasks,\n userId,\n connectionEvents,\n connectedUsers,\n ephemeralUserData,\n multiplayerStateManager,\n assetManager,\n assets,\n ]);\n\n const globalTrackEvents = useObservable(shouldTrackEvents$);\n const globalTrackTasks = useObservable(shouldTrackTasks$);\n\n const shouldTrackEvents = options?.trackConnectionEvents ?? globalTrackEvents;\n const shouldTrackTasks = options?.trackTasks ?? globalTrackTasks;\n\n const trackEventsCallbackRef = useRef<\n ((e: ConnectionEvent<S>) => void) | undefined\n >();\n const trackConnectedUsersCallbackRef = useRef<\n ((users: MultiplayerUser[], userId: string) => void) | undefined\n >();\n const trackTasksCallbackRef = useRef<((tasks: Task[]) => void) | undefined>();\n\n useEffect(() => {\n trackEventsCallbackRef.current = shouldTrackEvents\n ? (e) =>\n setConnectionEvents((events) => {\n const updated = events ? [...events, e] : [e];\n return updated.length > 50 ? updated.slice(-50) : updated;\n })\n : undefined;\n }, [shouldTrackEvents]);\n\n useEffect(() => {\n trackConnectedUsersCallbackRef.current = (users, userId) => {\n setConnectedUsers(users);\n setUserId(userId);\n };\n }, []);\n\n useEffect(() => {\n trackTasksCallbackRef.current = shouldTrackTasks\n ? (tasks) => {\n setTasks((old) => {\n const newIds = new Set(tasks.map((t) => t.id));\n\n // merge old and new tasks, preferring new tasks\n const unchanged = old.filter((t) => !newIds.has(t.id));\n\n return [...unchanged, ...tasks];\n });\n }\n : undefined;\n }, [shouldTrackTasks]);\n\n useEffect(() => {\n if (syncRef.current) {\n return syncRef.current({\n ms: multiplayerStateManager,\n assetManager,\n ephemeralUserData,\n onConnectionEvent: (e) => trackEventsCallbackRef.current?.(e),\n onChangeConnectedUsers: (users, userId) =>\n trackConnectedUsersCallbackRef.current?.(users, userId),\n onChangeTasks: (tasks) => trackTasksCallbackRef.current?.(tasks),\n });\n }\n }, [assetManager, ephemeralUserData, multiplayerStateManager]);\n\n const state = useSyncMultiplayerStateManager(multiplayerStateManager);\n\n const forceInit = useCallback(() => {\n const state =\n initialState instanceof Function ? initialState() : initialState;\n const schema = options?.schema;\n multiplayerStateManager.sm.clearHistory();\n multiplayerStateManager.sendInit({ force: true, state, schema });\n }, [initialState, multiplayerStateManager, options?.schema]);\n\n const [unrecoverableError, setUnrecoverableError] = useState<\n MultiplayerStateManagerError | undefined\n >();\n\n useEffect(() => {\n return multiplayerStateManager.errorEmitter.addListener((error) => {\n switch (error.reason) {\n case \"invalidDataType\":\n case \"schemaMismatch\":\n case \"outdatedSchema\":\n case \"dataMigrationFailure\":\n case \"schemaMigration\":\n setUnrecoverableError(error);\n break;\n }\n });\n }, [multiplayerStateManager]);\n\n useEffect(() => {\n if (!unrecoverableError) return;\n const el = document.createElement(\"div\");\n el.id = \"noya-multiplayer-react-error-overlay\";\n document.body.appendChild(el);\n const root = createRoot(el);\n root.render(createElement(ErrorOverlay, { error: unrecoverableError }));\n return () => {\n root.unmount();\n el.remove();\n };\n });\n\n useStateInspector({\n ephemeralUserData,\n multiplayerStateManager,\n assetManager,\n state,\n connectionEvents,\n connectedUsers,\n tasks,\n userId,\n forceInit,\n disabled: !options?.inspector,\n ...(typeof options?.inspector === \"object\" && options.inspector),\n });\n\n return [state, multiplayerStateManager.setState, extras] as const;\n}\n","import { MultiplayerStateManagerError } from \"@noya-app/state-manager\";\nimport React from \"react\";\n\nexport function ErrorOverlay({\n error,\n}: {\n error: MultiplayerStateManagerError;\n}) {\n return (\n <div\n style={{\n position: \"fixed\",\n top: \"20px\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n maxWidth: \"80%\",\n width: \"fit-content\",\n padding: \"12px 20px\",\n background: \"white\",\n color: \"black\",\n zIndex: 10000,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n borderRadius: \"4px\",\n boxShadow: \"0 4px 6px rgba(0, 0, 0, 0.1)\",\n fontFamily:\n \"'__Inter_6b0edc', '__Inter_Fallback_6b0edc', -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Segoe UI', Roboto, Helvetica, Arial, sans-serif\",\n fontSize: \"14px\",\n fontWeight: 400,\n lineHeight: \"19px\",\n }}\n >\n {error.reason === \"schemaMigration\" ? (\n <>\n <p>\n An updated version of Noya is available. Please reload the page to\n continue.\n </p>\n </>\n ) : (\n <>\n <p>\n An error occurred:{\" \"}\n <code\n style={{\n background: \"rgba(255, 0, 0, 0.1)\",\n color: \"rgba(255, 0, 0, 0.5)\",\n padding: \"2px 4px\",\n borderRadius: \"4px\",\n }}\n >\n {error.reason}\n </code>\n . Please reload the page to continue.\n <br />\n <br />\n If this happens repeatedly, please get in touch and the Noya team\n can help.\n </p>\n </>\n )}\n <div\n style={{\n height: \"1px\",\n background: \"rgba(0, 0, 0, 0.1)\",\n margin: \"12px -20px\",\n }}\n />\n <button\n style={{\n background: \"black\",\n color: \"white\",\n padding: \"8px 16px\",\n borderRadius: \"4px\",\n cursor: \"pointer\",\n fontSize: \"14px\",\n fontWeight: 700,\n lineHeight: \"19px\",\n }}\n onClick={() => {\n window.location.reload();\n }}\n >\n Reload\n </button>\n </div>\n );\n}\n","import { Observable } from \"@noya-app/observable\";\n\nexport const shouldTrackEvents$ = new Observable(false);\nexport const shouldTrackTasks$ = new Observable(false);\n","\"use client\";\n\nimport {\n AssetManager,\n ConnectionEvent,\n EphemeralUserData,\n MultiplayerStateManager,\n MultiplayerUser,\n Task,\n} from \"@noya-app/state-manager\";\nimport React, { ComponentProps, useLayoutEffect } from \"react\";\nimport { createRoot } from \"react-dom/client\";\n\nimport { Root } from \"react-dom/client\";\nimport { StateInspector } from \"./StateInspector\";\n\nfunction createShadowRootElement() {\n const host = document.createElement(\"div\");\n host.id = \"noya-multiplayer-react-inspector-host\";\n const shadowRoot = host.attachShadow({ mode: \"open\" });\n const container = document.createElement(\"div\");\n shadowRoot.appendChild(container);\n return { host, container };\n}\n\nexport function useStateInspector<S, M, E>({\n state,\n connectionEvents,\n connectedUsers,\n tasks,\n userId,\n disabled = false,\n colorScheme,\n anchor,\n multiplayerStateManager,\n assetManager,\n ephemeralUserData,\n forceInit,\n}: {\n state: S;\n connectionEvents?: ConnectionEvent<S>[];\n connectedUsers?: MultiplayerUser[];\n tasks?: Task[];\n userId?: string;\n disabled: boolean;\n multiplayerStateManager: MultiplayerStateManager<S, M>;\n assetManager: AssetManager;\n ephemeralUserData: EphemeralUserData<E>;\n forceInit: () => void;\n} & Pick<ComponentProps<typeof StateInspector>, \"colorScheme\" | \"anchor\">) {\n const [root, setRoot] = React.useState<Root | null>(null);\n\n useLayoutEffect(() => {\n if (disabled) return;\n\n const { host, container } = createShadowRootElement();\n const root = createRoot(container);\n\n document.body.appendChild(host);\n\n setRoot(root);\n\n return () => {\n document.body.removeChild(host);\n };\n }, [disabled]);\n\n useLayoutEffect(() => {\n if (!root) return;\n\n root.render(\n <StateInspector\n state={state}\n connectionEvents={connectionEvents}\n connectedUsers={connectedUsers}\n tasks={tasks}\n userId={userId}\n colorScheme={colorScheme}\n anchor={anchor}\n forceInit={forceInit}\n multiplayerStateManager={\n multiplayerStateManager as MultiplayerStateManager<any, any>\n }\n assetManager={assetManager}\n ephemeralUserData={ephemeralUserData as EphemeralUserData<any>}\n />\n );\n }, [\n anchor,\n colorScheme,\n connectedUsers,\n connectionEvents,\n root,\n state,\n multiplayerStateManager,\n userId,\n tasks,\n forceInit,\n ephemeralUserData,\n assetManager,\n ]);\n}\n","\"use client\";\n\nimport {\n AssetManager,\n ConnectionEvent,\n EphemeralUserData,\n ExtendedPathKey,\n MultiplayerStateManager,\n MultiplayerUser,\n Task,\n} from \"@noya-app/state-manager\";\nimport React, {\n CSSProperties,\n ComponentPropsWithoutRef,\n FC,\n memo,\n useEffect,\n useLayoutEffect,\n} from \"react\";\nimport {\n ObjectInspector,\n ObjectLabel,\n ObjectName,\n ObjectPreview,\n chromeDark,\n chromeLight,\n} from \"react-inspector\";\nimport { shouldTrackEvents$, shouldTrackTasks$ } from \"../globals\";\nimport { useEphemeralUserData, useManagedHistory } from \"../hooks\";\nimport { useObservable } from \"../useObservable\";\nimport { useLocalStorageState } from \"./useLocalStorageState\";\n\nconst lightTheme = {\n ...chromeLight,\n BASE_BACKGROUND_COLOR: \"transparent\",\n OBJECT_NAME_COLOR: \"rgba(0,0,0,0.7)\",\n} as any;\n\nconst darkTheme = {\n ...chromeDark,\n BASE_BACKGROUND_COLOR: \"transparent\",\n OBJECT_NAME_COLOR: \"rgba(255,255,255,0.7)\",\n} as any;\n\nconst styles = {\n sectionInner: {\n flex: \"1 1 0\",\n overflowY: \"auto\",\n overflowX: \"hidden\",\n display: \"flex\",\n flexDirection: \"column\",\n },\n} as const;\n\nfunction ToggleButton({\n showInspector,\n setShowInspector,\n theme,\n anchor,\n}: {\n showInspector: boolean;\n setShowInspector: (value: boolean) => void;\n theme: typeof chromeLight;\n anchor: StateInspectorAnchor;\n}) {\n return (\n <span\n role=\"button\"\n style={{\n flex: \"0\",\n appearance: \"none\",\n color: theme.BASE_COLOR,\n border: \"none\",\n fontSize: \"12px\",\n whiteSpace: \"nowrap\",\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"2px 0\",\n }}\n onClick={(event) => {\n event.stopPropagation();\n\n setShowInspector(!showInspector);\n }}\n >\n <span style={{ width: \"12px\", height: \"12px\" }}>\n {showInspector === (anchor === \"right\") ? (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n strokeWidth={1.5}\n stroke=\"currentColor\"\n className=\"size-6\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"m5.25 4.5 7.5 7.5-7.5 7.5m6-15 7.5 7.5-7.5 7.5\"\n />\n </svg>\n ) : (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n strokeWidth={1.5}\n stroke=\"currentColor\"\n className=\"size-6\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n d=\"m18.75 4.5-7.5 7.5 7.5 7.5m-6-15L5.25 12l7.5 7.5\"\n />\n </svg>\n )}\n </span>\n </span>\n );\n}\n\nfunction DisclosureSection({\n open,\n setOpen,\n title,\n right,\n children,\n colorScheme,\n isFirst,\n style,\n}: {\n open: boolean;\n setOpen?: (value: boolean) => void;\n title: string;\n right?: React.ReactNode;\n children: React.ReactNode;\n colorScheme: \"light\" | \"dark\";\n isFirst?: boolean;\n style?: CSSProperties;\n}) {\n const theme = colorScheme === \"light\" ? lightTheme : darkTheme;\n\n const borderColor =\n colorScheme === \"light\" ? \"rgba(0,0,0,0.1)\" : \"rgba(255,255,255,0.1)\";\n\n return (\n <div\n style={{\n flex: open ? \"1 1 0\" : \"0\",\n display: \"flex\",\n flexDirection: \"column\",\n ...style,\n }}\n >\n <div\n onClick={() => setOpen?.(!open)}\n style={{\n cursor: \"default\",\n fontSize: \"12px\",\n padding: \"4px 10px\",\n display: \"flex\",\n alignItems: \"center\",\n ...(!isFirst && { borderTop: `1px solid ${borderColor}` }),\n ...(open && { borderBottom: `1px solid ${borderColor}` }),\n }}\n >\n {setOpen && (\n <Arrow\n expanded={open}\n style={{\n fontSize: theme.ARROW_FONT_SIZE,\n marginRight: theme.ARROW_MARGIN_RIGHT + 1,\n color: theme.ARROW_COLOR,\n }}\n />\n )}\n <span style={{ flex: \"1 1 0\", userSelect: \"none\" }}>{title}</span>\n {right}\n </div>\n {open && children}\n </div>\n );\n}\n\nfunction InspectorRow({\n children,\n colorScheme,\n selected,\n style,\n variant,\n}: {\n children: React.ReactNode;\n colorScheme: \"light\" | \"dark\";\n selected?: boolean;\n style?: CSSProperties;\n variant?: \"up\" | \"down\";\n}) {\n const solidBorderColor =\n colorScheme === \"light\" ? \"rgb(223 223 223)\" : \"rgb(29 29 29)\";\n\n return (\n <div\n style={{\n borderBottom: `1px solid ${solidBorderColor}`,\n fontSize: \"12px\",\n fontFamily: \"Menlo, monospace\",\n padding: \"2px 12px 1px\",\n display: \"flex\",\n alignItems: \"center\",\n background:\n variant === \"up\"\n ? \"rgba(0,255,0,0.1)\"\n : variant === \"down\"\n ? \"rgba(255,0,0,0.1)\"\n : selected\n ? \"rgb(59 130 246 / 15%)\"\n : undefined,\n // background:\n // colorScheme === \"light\"\n // ? \"rgba(0,0,0,0.05)\"\n // : \"rgba(255,255,255,0.05)\",\n ...style,\n }}\n >\n <span\n style={{\n fontFamily: \"Menlo, monospace\",\n fontSize: \"11px\",\n borderRadius: 4,\n display: \"inline-block\",\n }}\n >\n {children}\n </span>\n </div>\n );\n}\n\nconst HISTORY_ELEMENT_PREFIX = \"noya-multiplayer-history-\";\n\nexport type StateInspectorAnchor =\n | \"left\"\n | \"right\"\n | \"bottom left\"\n | \"bottom right\";\n\nexport type StateInspectorOptions = {\n colorScheme?: \"light\" | \"dark\";\n anchor?: StateInspectorAnchor;\n};\n\nexport const StateInspector = memo(function StateInspector<S, M, E>({\n state,\n connectionEvents,\n connectedUsers,\n tasks,\n userId,\n unstyled,\n colorScheme = \"light\",\n multiplayerStateManager,\n assetManager,\n ephemeralUserData,\n anchor = \"right\",\n forceInit,\n ...props\n}: {\n state: S;\n connectionEvents?: ConnectionEvent<S>[];\n connectedUsers?: MultiplayerUser[];\n tasks?: Task[];\n userId?: string;\n unstyled?: boolean;\n multiplayerStateManager: MultiplayerStateManager<S, M>;\n assetManager: AssetManager;\n ephemeralUserData: EphemeralUserData<E>;\n forceInit: () => void;\n} & StateInspectorOptions &\n ComponentPropsWithoutRef<\"div\">) {\n const [didMount, setDidMount] = React.useState(false);\n\n useLayoutEffect(() => {\n setDidMount(true);\n }, []);\n\n const eventsContainerRef = React.useRef<HTMLDivElement>(null);\n const historyContainerRef = React.useRef<HTMLDivElement>(null);\n\n const [showInspector, setShowInspector] = useLocalStorageState(\n \"noya-multiplayer-react-show-inspector\",\n true\n );\n const [showEvents, setShowEvents] = useLocalStorageState(\n \"noya-multiplayer-react-show-events\",\n false\n );\n const [showHistory, setShowHistory] = useLocalStorageState(\n \"noya-multiplayer-react-show-history\",\n false\n );\n const [showUsers, setShowUsers] = useLocalStorageState(\n \"noya-multiplayer-react-show-users\",\n true\n );\n const [showData, setShowData] = useLocalStorageState(\n \"noya-multiplayer-react-show-data\",\n true\n );\n const [showTasks, setShowTasks] = useLocalStorageState(\n \"noya-multiplayer-react-show-tasks\",\n false\n );\n const [showEphemeral, setShowEphemeral] = useLocalStorageState(\n \"noya-multiplayer-react-show-ephemeral\",\n false\n );\n const [showAssets, setShowAssets] = useLocalStorageState(\n \"noya-multiplayer-react-show-assets\",\n false\n );\n\n useEffect(() => {\n shouldTrackEvents$.set(showEvents);\n }, [showEvents]);\n\n useEffect(() => {\n shouldTrackTasks$.set(showTasks);\n }, [showTasks]);\n\n useEffect(() => {\n if (eventsContainerRef.current) {\n eventsContainerRef.current.scrollTop =\n eventsContainerRef.current.scrollHeight;\n }\n }, [connectionEvents]);\n\n const ephemeral = useEphemeralUserData(ephemeralUserData);\n const historySnapshot = useManagedHistory(multiplayerStateManager.sm);\n const assets = useObservable(assetManager.assets$);\n\n useEffect(() => {\n if (historyContainerRef.current) {\n historyContainerRef.current.scrollTop =\n historyContainerRef.current.scrollHeight;\n }\n }, [historySnapshot]);\n\n // If history index changes, scroll to the new history entry into view\n useEffect(() => {\n if (!historyContainerRef.current) return;\n\n const historyEntry = historyContainerRef.current.querySelector(\n `#${HISTORY_ELEMENT_PREFIX}${historySnapshot.historyIndex}`\n );\n\n if (historyEntry) {\n historyEntry.scrollIntoView({\n block: \"nearest\",\n inline: \"nearest\",\n });\n }\n }, [historySnapshot.historyIndex]);\n\n const theme = colorScheme === \"light\" ? lightTheme : darkTheme;\n // const borderColor =\n // colorScheme === \"light\" ? \"rgba(0,0,0,0.1)\" : \"rgba(255,255,255,0.1)\";\n const solidBorderColor =\n colorScheme === \"light\" ? \"rgb(223 223 223)\" : \"rgb(29 29 29)\";\n\n const baseStyle: CSSProperties = {\n position: \"fixed\",\n top: 12,\n ...(anchor.includes(\"right\") ? { right: 12 } : { left: 12 }),\n bottom: 12,\n width: 400,\n background:\n colorScheme === \"light\" ? \"rgba(255,255,255,0.95)\" : \"rgba(0,0,0,0.95)\",\n backdropFilter: \"blur(48px)\",\n border: `1px solid ${solidBorderColor}`,\n // outlineOffset: -1,\n borderRadius: 4,\n display: \"flex\",\n flexDirection: \"column\",\n // gap: 12,\n color: theme.BASE_COLOR,\n overflow: \"hidden\",\n zIndex: 9999,\n lineHeight: \"13px\",\n };\n\n if (!didMount) return null;\n\n if (!showInspector) {\n return (\n <div\n {...props}\n style={{\n ...baseStyle,\n padding: \"4px 10px\",\n width: undefined,\n ...(anchor.includes(\"bottom\")\n ? { bottom: 12, top: undefined }\n : { bottom: undefined }),\n }}\n onClick={() => setShowInspector(true)}\n >\n <ToggleButton\n showInspector={showInspector}\n setShowInspector={setShowInspector}\n theme={theme}\n anchor={anchor}\n />\n </div>\n );\n }\n\n return (\n <div\n {...props}\n style={{\n ...(!unstyled && baseStyle),\n ...props.style,\n }}\n >\n <DisclosureSection\n isFirst\n open={showUsers}\n setOpen={setShowUsers}\n title=\"Users\"\n colorScheme={colorScheme}\n style={{\n flex: \"0 0 auto\",\n maxHeight: \"200px\",\n }}\n right={\n <ToggleButton\n showInspector={showInspector}\n setShowInspector={setShowInspector}\n theme={theme}\n anchor={anchor}\n />\n }\n >\n <div style={{ ...styles.sectionInner, flex: \"0 0 auto\" }}>\n {connectedUsers?.map((user) => (\n <InspectorRow\n key={user.id}\n colorScheme={colorScheme}\n variant={user.id === userId ? \"up\" : undefined}\n >\n {user.image && (\n <img\n src={user.image}\n alt={user.name}\n style={{\n width: \"13px\",\n height: \"13px\",\n borderRadius: \"50%\",\n marginRight: \"4px\",\n display: \"inline-block\",\n position: \"relative\",\n background: solidBorderColor,\n verticalAlign: \"middle\",\n }}\n />\n )}\n {user.name} ({ellipsis(user.id.toString(), 8, \"middle\")})\n </InspectorRow>\n ))}\n {!connectedUsers && (\n <div\n style={{\n padding: \"12px\",\n fontSize: \"12px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"4px\",\n }}\n >\n <span>No connected users</span>\n </div>\n )}\n </div>\n </DisclosureSection>\n <DisclosureSection\n title=\"Data\"\n colorScheme={colorScheme}\n setOpen={setShowData}\n open={showData}\n right={\n <span\n style={{\n display: \"flex\",\n gap: \"4px\",\n }}\n >\n <SmallButton\n // disabled={!historySnapshot.canUndo}\n theme={theme}\n onClick={() => {\n forceInit();\n }}\n >\n Reset\n </SmallButton>\n </span>\n }\n >\n <div style={styles.sectionInner}>\n <InspectorRow colorScheme={colorScheme}>\n <ObjectInspector\n name={multiplayerStateManager.schema ? \"state\" : undefined}\n data={state}\n theme={theme}\n />\n </InspectorRow>\n {multiplayerStateManager.schema && (\n <InspectorRow colorScheme={colorScheme}>\n <ObjectInspector\n name=\"schema\"\n data={multiplayerStateManager.schema}\n theme={theme}\n />\n </InspectorRow>\n )}\n </div>\n </DisclosureSection>\n <DisclosureSection\n open={showHistory}\n setOpen={setShowHistory}\n title=\"History\"\n colorScheme={colorScheme}\n right={\n <span\n style={{\n display: \"flex\",\n gap: \"4px\",\n }}\n >\n <SmallButton\n disabled={!historySnapshot.canUndo}\n theme={theme}\n onClick={() => {\n multiplayerStateManager.undo();\n }}\n >\n <span style={{ width: \"12px\", height: \"12px\" }}>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"1em\"\n height=\"1em\"\n viewBox=\"0 0 20 20\"\n >\n <path\n fill=\"currentColor\"\n 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\"\n />\n </svg>\n </span>\n </SmallButton>\n <SmallButton\n disabled={!historySnapshot.canRedo}\n theme={theme}\n onClick={() => {\n multiplayerStateManager.redo();\n }}\n >\n <span style={{ width: \"12px\", height: \"12px\" }}>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"1em\"\n height=\"1em\"\n viewBox=\"0 0 20 20\"\n >\n <path\n fill=\"currentColor\"\n 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\"\n />\n </svg>\n </span>\n </SmallButton>\n </span>\n }\n >\n <div ref={historyContainerRef} style={styles.sectionInner}>\n <div\n id={`${HISTORY_ELEMENT_PREFIX}0`}\n style={{\n borderBottom: `1px solid ${solidBorderColor}`,\n fontSize: \"12px\",\n fontFamily: \"Menlo, monospace\",\n padding: \"2px 12px 1px\",\n display: \"flex\",\n alignItems: \"center\",\n background:\n historySnapshot.historyIndex === 0\n ? \"rgb(59 130 246 / 15%)\"\n : undefined,\n }}\n >\n <span\n style={{\n fontFamily: \"Menlo, monospace\",\n fontSize: \"11px\",\n borderRadius: 4,\n display: \"inline-block\",\n }}\n >\n Initial state\n </span>\n </div>\n {historySnapshot.history.map((entry, index) => (\n <div\n id={`${HISTORY_ELEMENT_PREFIX}${index + 1}`}\n key={index}\n style={{\n padding: \"0px 12px 1px\",\n borderBottom: `1px solid ${solidBorderColor}`,\n background:\n index + 1 === historySnapshot.historyIndex\n ? \"rgb(59 130 246 / 15%)\"\n : undefined,\n }}\n >\n {\"name\" in entry.metadata &&\n typeof entry.metadata.name === \"string\" && (\n <pre\n style={{\n fontSize: \"11px\",\n display: \"flex\",\n flexWrap: \"wrap\",\n margin: 0,\n }}\n >\n {entry.metadata.name}\n </pre>\n )}\n {entry.redoPatches?.map((patch, j) => (\n <pre\n key={j}\n style={{\n fontSize: \"11px\",\n display: \"flex\",\n flexWrap: \"wrap\",\n margin: 0,\n }}\n >\n {patch.op === \"add\" && (\n <>\n <span style={{ fontStyle: \"italic\" }}>\n {pathToString(patch.path)}\n </span>\n {\" = \"}\n <ObjectInspector data={patch.value} theme={theme} />\n </>\n )}\n {patch.op === \"replace\" && (\n <>\n <span style={{ fontStyle: \"italic\" }}>\n {pathToString(patch.path)}\n </span>\n {\" = \"}\n <ObjectInspector data={patch.value} theme={theme} />\n </>\n )}\n {patch.op === \"remove\" && (\n <>\n <span style={{ color: theme.OBJECT_VALUE_STRING_COLOR }}>\n delete{\" \"}\n </span>\n <span style={{ fontStyle: \"italic\" }}>\n {pathToString(patch.path)}\n </span>\n </>\n )}\n {patch.op === \"move\" && (\n <>\n <span style={{ fontStyle: \"italic\" }}>\n {pathToString(patch.from!)}\n </span>\n {\" -> \"}\n <span style={{ fontStyle: \"italic\" }}>\n {pathToString(patch.path)}\n </span>\n </>\n )}\n </pre>\n ))}\n </div>\n ))}\n </div>\n </DisclosureSection>\n <DisclosureSection\n open={showAssets}\n setOpen={setShowAssets}\n title=\"Assets\"\n colorScheme={colorScheme}\n right={\n <span style={{ display: \"flex\", gap: \"4px\" }}>\n <SmallButton\n theme={theme}\n onClick={() => {\n // get file input\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.onchange = () => {\n const file = input.files?.[0];\n if (file) {\n const reader = new FileReader();\n reader.onload = () => {\n const buffer = reader.result as ArrayBuffer;\n assetManager.create(new Uint8Array(buffer));\n };\n reader.readAsArrayBuffer(file);\n }\n };\n input.click();\n }}\n >\n Upload\n </SmallButton>\n </span>\n }\n >\n <div style={styles.sectionInner}>\n {assets.map((asset) => (\n <InspectorRow key={asset.id} colorScheme={colorScheme}>\n <ObjectInspector name={asset.id} data={asset} theme={theme} />\n <SmallButton\n theme={theme}\n onClick={() => assetManager.delete(asset.id)}\n >\n Delete\n </SmallButton>\n </InspectorRow>\n ))}\n </div>\n </DisclosureSection>\n <DisclosureSection\n title=\"Tasks\"\n colorScheme={colorScheme}\n open={showTasks}\n setOpen={setShowTasks}\n >\n <div style={styles.sectionInner}>\n {tasks?.map((task) => (\n <InspectorRow\n key={task.id}\n colorScheme={colorScheme}\n style={{\n backgroundColor:\n task.status === \"done\"\n ? \"rgba(0,255,0,0.2)\"\n : task.status === \"error\"\n ? \"rgba(255,0,0,0.2)\"\n : undefined,\n }}\n >\n <ObjectInspector\n name={task.name}\n data={task.payload}\n theme={theme}\n />\n </InspectorRow>\n ))}\n </div>\n </DisclosureSection>\n <DisclosureSection\n open={showEphemeral}\n setOpen={setShowEphemeral}\n title=\"Ephemeral User Data\"\n colorScheme={colorScheme}\n >\n <div style={styles.sectionInner}>\n {Object.entries(ephemeral).map(([key, value]) => (\n <InspectorRow key={key} colorScheme={colorScheme}>\n <ObjectInspector\n name={key}\n data={value}\n theme={theme}\n expandLevel={10}\n />\n </InspectorRow>\n ))}\n </div>\n </DisclosureSection>\n <DisclosureSection\n open={showEvents}\n setOpen={setShowEvents}\n title=\"Events\"\n colorScheme={colorScheme}\n >\n <div ref={eventsContainerRef} style={styles.sectionInner}>\n {connectionEvents?.map((event, index) =>\n event.type === \"stateChange\" ? (\n <InspectorRow key={index} colorScheme={colorScheme}>\n connection:{\" \"}\n <span style={{ fontStyle: \"italic\" }}>\n {event.state.toLowerCase()}\n </span>\n </InspectorRow>\n ) : (\n <InspectorRow\n key={index}\n colorScheme={colorScheme}\n variant={event.type === \"send\" ? \"up\" : \"down\"}\n style={{\n padding: \"0px 12px 1px\",\n }}\n >\n <ObjectInspector\n data={event.type === \"error\" ? event.error : event.message}\n theme={theme}\n nodeRenderer={({\n depth,\n name,\n data,\n isNonenumerable,\n expanded,\n }: any) => {\n const direction = event.type === \"send\" ? \"up\" : \"down\";\n\n return depth === 0 ? (\n <ObjectRootLabel direction={direction} data={data} />\n ) : (\n <ObjectLabel\n direction={direction}\n name={name}\n data={data}\n isNonenumerable={isNonenumerable}\n />\n );\n }}\n />\n </InspectorRow>\n )\n )}\n {!connectionEvents && (\n <div\n style={{\n padding: \"12px\",\n fontSize: \"12px\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"4px\",\n }}\n >\n <span>No recorded events</span>\n </div>\n )}\n </div>\n </DisclosureSection>\n </div>\n );\n});\n\ntype MessageDirection = \"up\" | \"down\";\n\nconst ObjectRootLabel: FC<{\n name?: string;\n data: any;\n direction?: MessageDirection;\n}> = ({ name, data, direction }) => {\n if (typeof name === \"string\") {\n return (\n <span>\n <ObjectName name={name} />\n <span>: </span>\n <ObjectPreview data={data} />\n </span>\n );\n }\n if (direction === \"up\" || direction === \"down\") {\n const arrow = direction === \"up\" ? \"↑\" : \"↓\";\n\n return (\n <span>\n <span\n style={{\n background:\n direction === \"up\" ? \"rgba(0,255,0,0.2)\" : \"rgba(255,0,0,0.2)\",\n // color: \"white\",\n width: 12,\n height: 12,\n borderRadius: 2,\n display: \"inline-flex\",\n justifyContent: \"center\",\n alignItems: \"center\",\n marginRight: 4,\n lineHeight: \"12px\",\n }}\n >\n {arrow}\n </span>\n <ObjectPreview data={data} />\n </span>\n );\n } else {\n return <ObjectPreview data={data} />;\n }\n};\n\n// Rotates ▶️ or ▼ based on expanded state\nfunction Arrow({\n expanded,\n onClick,\n style,\n}: {\n expanded: boolean;\n onClick?: () => void;\n style?: CSSProperties;\n}) {\n return (\n <span\n role=\"button\"\n onClick={onClick}\n style={{\n display: \"inline-block\",\n textAlign: \"center\",\n transform: expanded ? \"rotate(0deg)\" : \"rotate(-90deg)\",\n fontFamily: \"Menlo, monospace\",\n ...style,\n }}\n >\n {\"▼\"}\n </span>\n );\n}\n\nfunction pathToString(extendedPath: ExtendedPathKey[]) {\n return extendedPath\n .map((key) =>\n typeof key === \"object\"\n ? `:${ellipsis(key.id.toString(), 8, \"middle\")}`\n : key\n )\n .map((key, index) =>\n index === 0 || (typeof key === \"string\" && key.startsWith(\":\"))\n ? key\n : `.${key}`\n )\n .join(\"\");\n}\n\ntype EllipsisPosition = \"start\" | \"middle\" | \"end\";\n\nfunction ellipsis(\n str: string,\n maxLength: number,\n position: EllipsisPosition = \"end\"\n) {\n if (str.length <= maxLength) return str;\n\n switch (position) {\n case \"start\":\n return `…${str.slice(str.length - maxLength)}`;\n case \"middle\":\n const halfLength = Math.floor(maxLength / 2);\n return `${str.slice(0, halfLength)}…${str.slice(str.length - halfLength)}`;\n case \"end\":\n return `${str.slice(0, maxLength)}…`;\n }\n}\n\nfunction SmallButton({\n children,\n onClick,\n style,\n theme,\n disabled,\n}: {\n children: React.ReactNode;\n onClick: () => void;\n style?: CSSProperties;\n theme: typeof chromeLight;\n disabled?: boolean;\n}) {\n return (\n <button\n type=\"button\"\n disabled={disabled}\n onClick={(event) => {\n event.stopPropagation();\n onClick();\n }}\n style={{\n flex: \"0\",\n appearance: \"none\",\n background: \"none\",\n color: theme.BASE_COLOR,\n opacity: disabled ? 0.25 : 1,\n border: \"none\",\n fontSize: \"12px\",\n whiteSpace: \"nowrap\",\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n padding: \"0\",\n cursor: \"pointer\",\n ...style,\n }}\n >\n {children}\n </button>\n );\n}\n","\"use client\";\n\nimport React from \"react\";\n\nconst localStorage = typeof window !== \"undefined\" ? window.localStorage : null;\n\nexport function useLocalStorageState<S>(\n key: string,\n defaultValue: S\n): [S, (value: S) => void] {\n const [state, setState] = React.useState<S>(() => {\n const value = localStorage?.getItem(key);\n let result = defaultValue;\n if (value) {\n try {\n result = JSON.parse(value);\n } catch (error) {\n console.error(\"Error parsing localStorage value\", error);\n }\n }\n return result;\n });\n\n const setLocalStorageState = (value: S) => {\n localStorage?.setItem(key, JSON.stringify(value));\n setState(value);\n };\n\n return [state, setLocalStorageState];\n}\n","/* eslint-disable no-restricted-globals */\nimport {\n createOrCastValue,\n findAllDefs,\n localStorageSync,\n MultiplayerUser,\n Static,\n stubSync,\n SyncAdapter,\n TSchema,\n TypeGuard,\n webSocketSync,\n} from \"@noya-app/state-manager\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport { useMultiplayerState, UseMultiplayerStateOptions } from \"./hooks\";\nimport { StateInspectorOptions } from \"./inspector/StateInspector\";\n\nexport type AppViewType = \"editable\" | \"readOnly\" | \"preview\";\n\nexport type AppTheme = \"light\" | \"dark\";\n\nexport type AppData<State> = {\n multiplayerUrl?: string;\n theme: AppTheme;\n viewType: AppViewType;\n initialState: State;\n inspector: boolean | StateInspectorOptions;\n};\n\nexport function createDefaultAppData<State>(\n initialState: State\n): AppData<State> {\n return {\n theme: \"light\",\n viewType: \"editable\",\n initialState,\n inspector: false,\n };\n}\n\nexport type GetAppDataOptions = {\n window?: { location: { hash: string } };\n overrideExistingState?: boolean;\n};\n\nexport function enforceSchema<State>(\n initialState: State,\n schema?: TSchema\n): State {\n return schema\n ? (createOrCastValue({\n schema,\n value: initialState,\n defs: findAllDefs(schema),\n }) as State)\n : initialState;\n}\n\nexport function parseAppDataParameter(\n options?: GetAppDataOptions\n): AppData<unknown> | null {\n const window = options?.window ?? globalThis;\n const location = window.location;\n if (!location) return null;\n const urlHash = (location.hash || \"\").replace(/^#/, \"\");\n const params = new URLSearchParams(urlHash);\n const data = params.get(\"data\");\n if (!data) return null;\n try {\n return JSON.parse(data);\n } catch (e) {\n return null;\n }\n}\n\nexport function getAppData<State>(\n initialState: State | (() => State),\n schema?: TSchema,\n options?: GetAppDataOptions\n): AppData<State> {\n const resolvedInitialState =\n initialState instanceof Function ? initialState() : initialState;\n\n let appData =\n parseAppDataParameter(options) ??\n createDefaultAppData(resolvedInitialState);\n\n if (options?.overrideExistingState) {\n appData.initialState = resolvedInitialState;\n }\n\n appData.initialState = enforceSchema(appData.initialState, schema) as State;\n\n return appData as AppData<State>;\n}\n\nexport type IframeToHostMessage =\n | {\n type: \"application.setMenuItems\";\n payload: {\n menuItems: any[];\n };\n }\n | {\n type: \"multiplayer.setUsers\";\n payload: {\n users: any[];\n };\n };\n\nexport type HostToIframeMessage = {\n type: \"application.selectMenuItem\";\n payload: {\n value: string;\n };\n};\n\nexport function useBroadcastConnectedUsers(connectedUsers: MultiplayerUser[]) {\n useEffect(() => {\n if (!isEmbeddedApp()) return;\n\n const message: IframeToHostMessage = {\n type: \"multiplayer.setUsers\",\n payload: { users: connectedUsers },\n };\n\n parent?.postMessage(message, \"*\");\n }, [connectedUsers]);\n}\n\nexport function useBroadcastMenuItems<T>(\n menuItems: any[],\n handleSelectMenuItem: (value: T) => void\n) {\n useEffect(() => {\n if (!isEmbeddedApp()) return;\n\n const message: IframeToHostMessage = {\n type: \"application.setMenuItems\",\n payload: { menuItems },\n };\n\n parent?.postMessage(message, \"*\");\n\n const listener = (event: MessageEvent<HostToIframeMessage>) => {\n if (event.data.type === \"application.selectMenuItem\") {\n handleSelectMenuItem(event.data.payload.value as T);\n }\n };\n\n window.addEventListener(\"message\", listener);\n\n return () => {\n window.removeEventListener(\"message\", listener);\n };\n }, [handleSelectMenuItem, menuItems]);\n}\n\nexport function isEmbeddedApp() {\n return window.self !== window.top;\n}\n\nexport type UseNoyaStateOptions<\n S,\n M = void,\n E = void,\n> = UseMultiplayerStateOptions<S, M, E> & {\n offlineStorageKey?: string;\n};\n\nexport type UseNoyaStateResult<S, M = void, E = void> = [\n ReturnType<typeof useMultiplayerState<S, M, E>>[0],\n ReturnType<typeof useMultiplayerState<S, M, E>>[1],\n ReturnType<typeof useMultiplayerState<S, M, E>>[2] & {\n theme: AppTheme;\n viewType: AppViewType;\n },\n];\n\n/**\n * Sync data locally or to a multiplayer server.\n *\n * There are 3 ways to use this hook:\n *\n * 1. Pass an initial state: `useNoyaState(initialState)`\n * 2. Pass an initial state and a schema: `useNoyaState(initialState, { schema })`\n * 3. Pass only a schema, and a conforming initial state is created automatically: `useNoyaState({ schema })`\n */\nexport function useNoyaState<\n S,\n M = void,\n E = void,\n O extends UseNoyaStateOptions<S, M, E> = UseNoyaStateOptions<S, M, E>,\n>(\n ...args:\n | [\n initialState: O[\"schema\"] extends TSchema\n ? Static<O[\"schema\"]> | (() => Static<O[\"schema\"]>)\n : S | (() => S),\n options?: O,\n ]\n | [options: O & { schema: TSchema }]\n): UseNoyaStateResult<\n O[\"schema\"] extends TSchema ? Static<O[\"schema\"]> : S,\n M,\n E\n> {\n const [initialState, options] =\n typeof args[0] === \"object\" &&\n args[0] !== null &&\n \"schema\" in args[0] &&\n TypeGuard.IsSchema(args[0].schema)\n ? [null, args[0]]\n : [args[0], args[1]];\n\n // Keep these stable after initial render\n const [\n {\n multiplayerUrl,\n inspector,\n initialState: noyaAppInitialState,\n theme,\n viewType,\n },\n ] = useState(() => {\n return getAppData(initialState, options?.schema, {\n overrideExistingState: options?.overrideExistingState,\n });\n });\n\n const sync = useMemo((): SyncAdapter<S, M, E> => {\n return multiplayerUrl\n ? webSocketSync(multiplayerUrl)\n : options?.offlineStorageKey\n ? localStorageSync({ key: options.offlineStorageKey })\n : stubSync();\n }, [multiplayerUrl, options?.offlineStorageKey]);\n\n const result = useMultiplayerState(noyaAppInitialState as S, {\n ...options,\n inspector: options?.inspector ?? inspector,\n sync: options?.sync ?? sync,\n });\n\n const [, , extras] = result;\n\n useBroadcastConnectedUsers(extras.connectedUsers);\n\n const mergedExtras = useMemo(() => {\n return { ...extras, theme, viewType } as const;\n }, [extras, theme, viewType]);\n\n return [result[0], result[1], mergedExtras] as UseNoyaStateResult<\n O[\"schema\"] extends TSchema ? Static<O[\"schema\"]> : S,\n M,\n E\n >;\n}\n\n// function typeTest() {\n// const [a, setA] = useNoyaState(7);\n// const [b, setB] = useNoyaState(7, {\n// schema: Type.Number(),\n// });\n// const [c, setC] = useNoyaState({\n// schema: Type.Number(),\n// });\n// }\n","import { GetAtPath, ObservableOptions, PathKey } from \"@noya-app/observable\";\nimport {\n AssetManager,\n MultiplayerStateManager,\n StateManagerOptions,\n Static,\n TSchema,\n} from \"@noya-app/state-manager\";\nimport React, {\n createContext,\n SetStateAction,\n useCallback,\n useContext,\n useMemo,\n} from \"react\";\nimport { useNoyaState, UseNoyaStateOptions } from \"./noyaApp\";\nimport { useObservable } from \"./useObservable\";\n\ninterface NoyaStateProviderProps<S, M, E>\n extends Omit<UseNoyaStateOptions<S, M, E>, \"schema\" | \"mergeHistoryEntries\"> {\n children: React.ReactNode;\n initialState?: S;\n}\n\nconst AnyNoyaStateContext = createContext<\n | { ms: MultiplayerStateManager<any, any>; assetManager: AssetManager }\n | undefined\n>(undefined);\n\nfunction useAnyNoyaStateContext() {\n const value = useContext(AnyNoyaStateContext);\n\n if (!value) {\n throw new Error(\n \"useNoyaStateContext must be used within a NoyaStateProvider\"\n );\n }\n\n return value;\n}\n\nexport function useAssets() {\n const { assetManager } = useAnyNoyaStateContext();\n return useObservable(assetManager.assets$);\n}\n\nexport function useAsset(id: string | undefined) {\n const { assetManager } = useAnyNoyaStateContext();\n const observable = useMemo(\n () => assetManager.assets$.map((assets) => assets.find((a) => a.id === id)),\n [assetManager, id]\n );\n return useObservable(observable);\n}\n\nexport function useAssetManager() {\n const { assetManager } = useAnyNoyaStateContext();\n return useMemo(\n () => ({\n create: assetManager.create,\n delete: assetManager.delete,\n }),\n [assetManager]\n );\n}\n\nexport function createNoyaContext<Schema extends TSchema, M = void, E = void>({\n schema,\n mergeHistoryEntries,\n}: {\n schema: Schema;\n mergeHistoryEntries?: StateManagerOptions<\n Static<Schema>,\n M\n >[\"mergeHistoryEntries\"];\n}) {\n type S = Static<Schema>;\n\n const NoyaStateContext = AnyNoyaStateContext as React.Context<\n | {\n ms: MultiplayerStateManager<S, M>;\n assetManager: AssetManager;\n }\n | undefined\n >;\n\n function NoyaStateProvider({\n children,\n initialState,\n ...options\n }: NoyaStateProviderProps<S, M, E>) {\n const [, , { multiplayerStateManager, assetManager }] = useNoyaState(\n initialState,\n {\n ...(options as any),\n schema,\n mergeHistoryEntries,\n }\n );\n\n const value = useMemo(\n () => ({\n ms: multiplayerStateManager as MultiplayerStateManager<any, any>,\n assetManager,\n }),\n [multiplayerStateManager, assetManager]\n );\n\n return (\n <AnyNoyaStateContext.Provider value={value}>\n {children}\n </AnyNoyaStateContext.Provider>\n );\n }\n\n function useValue(): S;\n function useValue<A>(\n selector: (value: S) => A,\n options?: Pick<ObservableOptions, \"isEqual\">\n ): A;\n function useValue<P extends PathKey[] | string>(path: P): GetAtPath<S, P>;\n function useValue(\n path?: PathKey[] | string | ((value: S) => any),\n options?: Pick<ObservableOptions, \"isEqual\">\n ) {\n const { ms } = useAnyNoyaStateContext();\n\n let actualPath: PathKey[] | string =\n typeof path === \"function\" || !path ? \"\" : path;\n\n const mappedObservable = useMemo(() => {\n if (typeof path === \"function\") {\n return ms.optimisticState$.map(path, { isEqual: options?.isEqual });\n }\n return ms.optimisticState$;\n }, [ms, path, options?.isEqual]);\n\n const value = useObservable(mappedObservable, actualPath);\n\n return value;\n }\n\n function useSetValue(): M extends {}\n ? (metadata: M, value: SetStateAction<S>) => void\n : (value: SetStateAction<S>) => void;\n function useSetValue<P extends PathKey[] | string>(\n path: P\n ): M extends {}\n ? (metadata: M, value: SetStateAction<GetAtPath<S, P>>) => void\n : (value: SetStateAction<GetAtPath<S, P>>) => void;\n function useSetValue<P extends PathKey[] | string>(path?: P) {\n const { ms } = useAnyNoyaStateContext();\n\n const setValue = useCallback(\n (\n ...args: M extends {}\n ? [metadata: M, value: SetStateAction<GetAtPath<S, P>>]\n : [value: SetStateAction<GetAtPath<S, P>>]\n ): void => {\n const [metadata, value] =\n args.length === 2 ? args : [undefined as M, args[0]];\n\n const setStateAtPath = ms.setStateAtPath as (\n metadata: M,\n path: P,\n value: GetAtPath<S, P>\n ) => void;\n\n setStateAtPath(metadata, (path ?? \"\") as P, value as never);\n },\n [ms, path]\n );\n\n return setValue as M extends {}\n ? (metadata: M, value: SetStateAction<GetAtPath<S, P>>) => void\n : (value: SetStateAction<GetAtPath<S, P>>) => void;\n }\n\n function useValueState(): [\n S,\n M extends {}\n ? (metadata: M, value: SetStateAction<S>) => void\n : (value: SetStateAction<S>) => void,\n ];\n function useValueState<A>(\n selector: (value: S) => A,\n options?: ObservableOptions\n ): [\n A,\n M extends {}\n ? (metadata: M, value: SetStateAction<S>) => void\n : (value: SetStateAction<S>) => void,\n ];\n function useValueState<P extends PathKey[] | string>(\n path?: P\n ): [\n GetAtPath<S, P>,\n M extends {}\n ? (metadata: M, value: SetStateAction<GetAtPath<S, P>>) => void\n : (value: SetStateAction<GetAtPath<S, P>>) => void,\n ];\n function useValueState<P extends PathKey[] | string>(\n ...args: [P?] | [selector: (value: S) => any, options?: ObservableOptions]\n ) {\n const [selector, options, path] =\n args.length >= 1 && typeof args[0] === \"function\"\n ? [args[0], args[1], undefined]\n : [undefined, undefined, args[0] as P | undefined];\n\n const value = useValue((selector ?? path ?? \"\") as any, options);\n const setValue = useSetValue(path ?? \"\");\n return [value, setValue];\n }\n\n function useStateManager() {\n const { ms } = useAnyNoyaStateContext() as {\n ms: MultiplayerStateManager<S, M>;\n };\n\n return ms;\n }\n\n return {\n Context: NoyaStateContext,\n Provider: NoyaStateProvider,\n useValue,\n useSetValue,\n useValueState,\n useStateManager,\n // useAssets,\n // useAssetManager,\n // useAsset,\n };\n}\n"],"mappings":"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","names":["useMemo","listen","get","useMemo","UserPointer","UserPointerContainer","UserNameTag","useEffect","useMemo","useState","useSyncExternalStore","createRoot","React","React","useLayoutEffect","React","memo","useEffect","React","React","memo","StateInspector","useEffect","React","useLayoutEffect","root","useSyncExternalStore","useState","useMemo","useEffect","userId","tasks","state","createRoot","stubSync","useEffect","useMemo","useState","window","useEffect","useState","useMemo","stubSync","React","useCallback","useMemo","useMemo","React","useCallback"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noya-app/noya-multiplayer-react",
3
- "version": "0.1.41",
3
+ "version": "0.1.42",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",
@@ -12,9 +12,9 @@
12
12
  "dev": "npm run build -- --watch"
13
13
  },
14
14
  "dependencies": {
15
- "@noya-app/state-manager": "0.1.30",
15
+ "@noya-app/state-manager": "0.1.31",
16
16
  "@noya-app/emitter": "0.1.0",
17
- "@noya-app/observable": "0.1.2",
17
+ "@noya-app/observable": "0.1.3",
18
18
  "react-inspector": "6.0.2"
19
19
  },
20
20
  "peerDependencies": {
@@ -454,14 +454,14 @@ export const StateInspector = memo(function StateInspector<S, M, E>({
454
454
  src={user.image}
455
455
  alt={user.name}
456
456
  style={{
457
- width: "12px",
458
- height: "12px",
457
+ width: "13px",
458
+ height: "13px",
459
459
  borderRadius: "50%",
460
460
  marginRight: "4px",
461
461
  display: "inline-block",
462
462
  position: "relative",
463
- top: "-1px",
464
463
  background: solidBorderColor,
464
+ verticalAlign: "middle",
465
465
  }}
466
466
  />
467
467
  )}
@@ -630,6 +630,7 @@ export const StateInspector = memo(function StateInspector<S, M, E>({
630
630
  fontSize: "11px",
631
631
  display: "flex",
632
632
  flexWrap: "wrap",
633
+ margin: 0,
633
634
  }}
634
635
  >
635
636
  {entry.metadata.name}
@@ -642,6 +643,7 @@ export const StateInspector = memo(function StateInspector<S, M, E>({
642
643
  fontSize: "11px",
643
644
  display: "flex",
644
645
  flexWrap: "wrap",
646
+ margin: 0,
645
647
  }}
646
648
  >
647
649
  {patch.op === "add" && (