@mudlet/mudlet-web 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +338 -0
- package/README.md +150 -0
- package/dist-lib/App.d.ts +1 -0
- package/dist-lib/MudletWebApp.d.ts +11 -0
- package/dist-lib/ProfileSession.d.ts +15 -0
- package/dist-lib/assets/mapParser.worker-t-3rd1zR.js +9 -0
- package/dist-lib/branding.d.ts +213 -0
- package/dist-lib/core/EventBus.d.ts +29 -0
- package/dist-lib/db/sqliteClient.d.ts +25 -0
- package/dist-lib/hooks/useEngines.d.ts +12 -0
- package/dist-lib/hooks/useMudSession.d.ts +10 -0
- package/dist-lib/hooks/useOutput.d.ts +17 -0
- package/dist-lib/hooks/useViewportMode.d.ts +14 -0
- package/dist-lib/import/applyMudletProfile.d.ts +57 -0
- package/dist-lib/import/collectProfileExport.d.ts +16 -0
- package/dist-lib/import/defaultPackages.d.ts +81 -0
- package/dist-lib/import/defaults/mudlet-mapper.xml +13023 -0
- package/dist-lib/import/defaults/run-lua-code.mpackage +0 -0
- package/dist-lib/import/mudletHost.d.ts +67 -0
- package/dist-lib/import/mudletLink.d.ts +34 -0
- package/dist-lib/import/mudletProfileExport.d.ts +49 -0
- package/dist-lib/import/mudletProfileImport.d.ts +71 -0
- package/dist-lib/import/mudletVariables.d.ts +49 -0
- package/dist-lib/import/mudletWriteback.d.ts +12 -0
- package/dist-lib/import/mudletXmlExport.d.ts +16 -0
- package/dist-lib/import/mudletXmlImport.d.ts +21 -0
- package/dist-lib/import/packageInstaller.d.ts +72 -0
- package/dist-lib/import/packageRepository.d.ts +54 -0
- package/dist-lib/import/remotePackageInstall.d.ts +52 -0
- package/dist-lib/index.d.ts +30 -0
- package/dist-lib/index.js +42307 -0
- package/dist-lib/logging/SessionLogger.d.ts +41 -0
- package/dist-lib/main.d.ts +2 -0
- package/dist-lib/map/MapSelectionOverlay.d.ts +15 -0
- package/dist-lib/map/MapStore.d.ts +1067 -0
- package/dist-lib/map/MudixMapReader.d.ts +90 -0
- package/dist-lib/map/MudletHighlightOverlay.d.ts +18 -0
- package/dist-lib/map/mapImageExport.d.ts +26 -0
- package/dist-lib/map/mapParser.worker.d.ts +1 -0
- package/dist-lib/map/mapParserClient.d.ts +35 -0
- package/dist-lib/map/pathfinding.d.ts +52 -0
- package/dist-lib/map/xmlMapImport.d.ts +28 -0
- package/dist-lib/mud/MudSession.d.ts +236 -0
- package/dist-lib/mud/PatternEngine.d.ts +28 -0
- package/dist-lib/mud/aliases/AliasEngine.d.ts +15 -0
- package/dist-lib/mud/connection/LineAssembler.d.ts +84 -0
- package/dist-lib/mud/connection/MudClient.d.ts +268 -0
- package/dist-lib/mud/connection/PingTracker.d.ts +28 -0
- package/dist-lib/mud/connection/TelnetNegotiator.d.ts +188 -0
- package/dist-lib/mud/connection/telnetDebug.d.ts +54 -0
- package/dist-lib/mud/events.d.ts +160 -0
- package/dist-lib/mud/keybindings/KeyEngine.d.ts +36 -0
- package/dist-lib/mud/keybindings/browserReservedKeys.d.ts +45 -0
- package/dist-lib/mud/keybindings/qtKeys.d.ts +33 -0
- package/dist-lib/mud/protocol/charset.d.ts +105 -0
- package/dist-lib/mud/protocol/constants.d.ts +116 -0
- package/dist-lib/mud/protocol/echo.d.ts +63 -0
- package/dist-lib/mud/protocol/gmcp.d.ts +28 -0
- package/dist-lib/mud/protocol/index.d.ts +11 -0
- package/dist-lib/mud/protocol/mccp.d.ts +18 -0
- package/dist-lib/mud/protocol/mnes.d.ts +83 -0
- package/dist-lib/mud/protocol/msdp.d.ts +19 -0
- package/dist-lib/mud/protocol/msp.d.ts +47 -0
- package/dist-lib/mud/protocol/mssp.d.ts +25 -0
- package/dist-lib/mud/protocol/mxp.d.ts +188 -0
- package/dist-lib/mud/protocol/naws.d.ts +7 -0
- package/dist-lib/mud/replay/ReplayPlayer.d.ts +31 -0
- package/dist-lib/mud/replay/ReplayRecorder.d.ts +18 -0
- package/dist-lib/mud/replay/replayFormat.d.ts +49 -0
- package/dist-lib/mud/text/Console.d.ts +183 -0
- package/dist-lib/mud/text/FormatState.d.ts +256 -0
- package/dist-lib/mud/text/ansiEscapes.d.ts +88 -0
- package/dist-lib/mud/text/cellRender.d.ts +21 -0
- package/dist-lib/mud/text/colorParsers.d.ts +54 -0
- package/dist-lib/mud/text/colors.d.ts +31 -0
- package/dist-lib/mud/text/controlCharacterMode.d.ts +13 -0
- package/dist-lib/mud/text/controlChars.d.ts +31 -0
- package/dist-lib/mud/text/hyperlinkConfig.d.ts +164 -0
- package/dist-lib/mud/text/hyperlinkVisibility.d.ts +37 -0
- package/dist-lib/mud/text/oscLinkManager.d.ts +35 -0
- package/dist-lib/mud/text/wcwidth.d.ts +44 -0
- package/dist-lib/mud/text/xterm256.d.ts +2 -0
- package/dist-lib/mud/timers/TimerEngine.d.ts +61 -0
- package/dist-lib/mud/triggers/ChunkProcessor.d.ts +11 -0
- package/dist-lib/mud/triggers/TriggerEngine.d.ts +188 -0
- package/dist-lib/mud/triggers/pcre/Pcre2.d.ts +26 -0
- package/dist-lib/scripting/EngineHost.d.ts +152 -0
- package/dist-lib/scripting/GlobalEventChannel.d.ts +36 -0
- package/dist-lib/scripting/IScriptingRuntime.d.ts +95 -0
- package/dist-lib/scripting/MapOpenNotifier.d.ts +19 -0
- package/dist-lib/scripting/ScriptingAPI.d.ts +1691 -0
- package/dist-lib/scripting/ScriptingEngine.d.ts +806 -0
- package/dist-lib/scripting/StopwatchManager.d.ts +94 -0
- package/dist-lib/scripting/heldModifiers.d.ts +3 -0
- package/dist-lib/scripting/http/HttpService.d.ts +23 -0
- package/dist-lib/scripting/lua/LuaRuntime.d.ts +190 -0
- package/dist-lib/scripting/lua/bindings/automation.d.ts +10 -0
- package/dist-lib/scripting/lua/bindings/commandLine.d.ts +11 -0
- package/dist-lib/scripting/lua/bindings/context.d.ts +87 -0
- package/dist-lib/scripting/lua/bindings/cursor.d.ts +10 -0
- package/dist-lib/scripting/lua/bindings/diagnostics.d.ts +9 -0
- package/dist-lib/scripting/lua/bindings/map.d.ts +14 -0
- package/dist-lib/scripting/lua/bindings/media.d.ts +24 -0
- package/dist-lib/scripting/lua/bindings/output.d.ts +10 -0
- package/dist-lib/scripting/lua/bindings/packages.d.ts +10 -0
- package/dist-lib/scripting/lua/bindings/session.d.ts +16 -0
- package/dist-lib/scripting/lua/bindings/textEdit.d.ts +9 -0
- package/dist-lib/scripting/lua/bindings/userWindows.d.ts +11 -0
- package/dist-lib/scripting/lua/bindings/window.d.ts +10 -0
- package/dist-lib/scripting/lua/imageSize.d.ts +4 -0
- package/dist-lib/scripting/lua/luaCompletions.d.ts +9 -0
- package/dist-lib/scripting/lua/mudlet-lua/generic-mapper/generic_mapper.mpackage +0 -0
- package/dist-lib/scripting/lua/rex.d.ts +3 -0
- package/dist-lib/scripting/lua/sqlRowEncoder.d.ts +1 -0
- package/dist-lib/scripting/lua/yajl.d.ts +11 -0
- package/dist-lib/scripting/profilesPresence.d.ts +50 -0
- package/dist-lib/scripting/vfs/ProfileVFS.d.ts +62 -0
- package/dist-lib/scripting/vfs/cssRewrite.d.ts +21 -0
- package/dist-lib/scripting/vfs/folderHandleStore.d.ts +16 -0
- package/dist-lib/scripting/vfs/folderSync.d.ts +59 -0
- package/dist-lib/scripting/vfs/htmlRewrite.d.ts +26 -0
- package/dist-lib/scripting/vfs/vfsBridge.d.ts +16 -0
- package/dist-lib/services/cloudflare.d.ts +54 -0
- package/dist-lib/storage/appStore.d.ts +132 -0
- package/dist-lib/storage/crossTabSync.d.ts +3 -0
- package/dist-lib/storage/debouncedStorage.d.ts +18 -0
- package/dist-lib/storage/hooks.d.ts +17 -0
- package/dist-lib/storage/index.d.ts +4 -0
- package/dist-lib/storage/logExport.d.ts +32 -0
- package/dist-lib/storage/logStorage.d.ts +45 -0
- package/dist-lib/storage/mapStorage.d.ts +2 -0
- package/dist-lib/storage/profileVfsData.d.ts +47 -0
- package/dist-lib/storage/schema.d.ts +638 -0
- package/dist-lib/styles.css +2 -0
- package/dist-lib/ui/AboutModal.d.ts +8 -0
- package/dist-lib/ui/BrandLoginFields.d.ts +25 -0
- package/dist-lib/ui/BrandLoginScreen.d.ts +11 -0
- package/dist-lib/ui/CharLoginModal.d.ts +32 -0
- package/dist-lib/ui/CmdLineMenuRegistry.d.ts +27 -0
- package/dist-lib/ui/CodeEditorPreview.d.ts +19 -0
- package/dist-lib/ui/CommandBar.d.ts +17 -0
- package/dist-lib/ui/ConnectionFormModal.d.ts +13 -0
- package/dist-lib/ui/ConnectionGrid.d.ts +18 -0
- package/dist-lib/ui/ConnectionScreen.d.ts +14 -0
- package/dist-lib/ui/FileBrowserModal.d.ts +20 -0
- package/dist-lib/ui/FilePickerModal.d.ts +21 -0
- package/dist-lib/ui/FolderPermissionScreen.d.ts +16 -0
- package/dist-lib/ui/JsonPreview.d.ts +15 -0
- package/dist-lib/ui/LogBrowserModal.d.ts +7 -0
- package/dist-lib/ui/MapEditorModal.d.ts +9 -0
- package/dist-lib/ui/MarkdownPreview.d.ts +15 -0
- package/dist-lib/ui/MergeConflictModal.d.ts +17 -0
- package/dist-lib/ui/ModuleResolveModal.d.ts +22 -0
- package/dist-lib/ui/MouseEventRegistry.d.ts +31 -0
- package/dist-lib/ui/ProfileBusyScreen.d.ts +12 -0
- package/dist-lib/ui/ProfileExportModal.d.ts +7 -0
- package/dist-lib/ui/ProxyInfoModal.d.ts +6 -0
- package/dist-lib/ui/ProxyWhyModal.d.ts +6 -0
- package/dist-lib/ui/ProxyWizardModal.d.ts +6 -0
- package/dist-lib/ui/QuickOpenPalette.d.ts +8 -0
- package/dist-lib/ui/ResizableModal.d.ts +17 -0
- package/dist-lib/ui/ScriptingDocsModal.d.ts +12 -0
- package/dist-lib/ui/SettingsModal.d.ts +9 -0
- package/dist-lib/ui/Toolbar.d.ts +29 -0
- package/dist-lib/ui/bufferWords.d.ts +38 -0
- package/dist-lib/ui/buttons/ButtonsBar.d.ts +21 -0
- package/dist-lib/ui/cmdline/CommandLineManager.d.ts +97 -0
- package/dist-lib/ui/cmdline/CommandLineOverlay.d.ts +8 -0
- package/dist-lib/ui/codemirror/theme.d.ts +5 -0
- package/dist-lib/ui/commandHistory.d.ts +31 -0
- package/dist-lib/ui/components/Button.d.ts +9 -0
- package/dist-lib/ui/components/ConfirmDialog.d.ts +29 -0
- package/dist-lib/ui/components/ContextMenu.d.ts +9 -0
- package/dist-lib/ui/components/FontPicker.d.ts +9 -0
- package/dist-lib/ui/components/FormField.d.ts +16 -0
- package/dist-lib/ui/components/HelpTip.d.ts +7 -0
- package/dist-lib/ui/components/Input.d.ts +6 -0
- package/dist-lib/ui/components/Toggle.d.ts +10 -0
- package/dist-lib/ui/components/index.d.ts +9 -0
- package/dist-lib/ui/components/useModalFocus.d.ts +18 -0
- package/dist-lib/ui/labels/LabelManager.d.ts +220 -0
- package/dist-lib/ui/labels/LabelOverlay.d.ts +9 -0
- package/dist-lib/ui/labels/backgroundImageSize.d.ts +10 -0
- package/dist-lib/ui/labels/cursorShapes.d.ts +6 -0
- package/dist-lib/ui/labels/gifMovie.d.ts +100 -0
- package/dist-lib/ui/labels/qtCss.d.ts +57 -0
- package/dist-lib/ui/layout/ContentLayout.d.ts +19 -0
- package/dist-lib/ui/layout/DockArea.d.ts +14 -0
- package/dist-lib/ui/layout/DockedPanel.d.ts +13 -0
- package/dist-lib/ui/layout/FloatingWindowLayer.d.ts +10 -0
- package/dist-lib/ui/layout/MobileLayout.d.ts +22 -0
- package/dist-lib/ui/layout/PopoutWindow.d.ts +35 -0
- package/dist-lib/ui/layout/ScriptWindow.d.ts +29 -0
- package/dist-lib/ui/layout/SplitGroupPanel.d.ts +17 -0
- package/dist-lib/ui/layout/TabGroupPanel.d.ts +12 -0
- package/dist-lib/ui/layout/WindowContextMenu.d.ts +11 -0
- package/dist-lib/ui/layout/dockDetect.d.ts +26 -0
- package/dist-lib/ui/layout/overlayLayerOrder.d.ts +71 -0
- package/dist-lib/ui/markdown.d.ts +1 -0
- package/dist-lib/ui/output/CaretReviewPanel.d.ts +22 -0
- package/dist-lib/ui/output/OutputArea.d.ts +9 -0
- package/dist-lib/ui/output/OutputContextMenu.d.ts +23 -0
- package/dist-lib/ui/output/OutputRenderer.d.ts +64 -0
- package/dist-lib/ui/output/ScreenReaderLog.d.ts +23 -0
- package/dist-lib/ui/output/StickyOutputPanel.d.ts +28 -0
- package/dist-lib/ui/output/backgroundImageStyle.d.ts +17 -0
- package/dist-lib/ui/output/caretMode.d.ts +40 -0
- package/dist-lib/ui/output/linkNavigation.d.ts +29 -0
- package/dist-lib/ui/output/osc8Menu.d.ts +16 -0
- package/dist-lib/ui/output/outputCopy.d.ts +15 -0
- package/dist-lib/ui/preventPinchZoom.d.ts +1 -0
- package/dist-lib/ui/scrollbox/ScrollBoxManager.d.ts +62 -0
- package/dist-lib/ui/scrollbox/ScrollBoxOverlay.d.ts +25 -0
- package/dist-lib/ui/sound/SoundManager.d.ts +149 -0
- package/dist-lib/ui/sound/closedCaption.d.ts +37 -0
- package/dist-lib/ui/textedit/TextEditManager.d.ts +56 -0
- package/dist-lib/ui/tts/TtsManager.d.ts +68 -0
- package/dist-lib/ui/useBrandLogin.d.ts +19 -0
- package/dist-lib/ui/useCommandHistory.d.ts +7 -0
- package/dist-lib/ui/video/VideoManager.d.ts +56 -0
- package/dist-lib/ui/windows/ScriptEditorModal.d.ts +13 -0
- package/dist-lib/ui/windows/WindowManager.d.ts +694 -0
- package/dist-lib/ui/windows/panels/HtmlPanel.d.ts +27 -0
- package/dist-lib/ui/windows/panels/LuaEditor.d.ts +14 -0
- package/dist-lib/ui/windows/panels/MapPanel.d.ts +8 -0
- package/dist-lib/ui/windows/panels/PackageRepositoryModal.d.ts +18 -0
- package/dist-lib/ui/windows/panels/ScriptEditorPanel.d.ts +24 -0
- package/dist-lib/ui/windows/panels/ScriptSearch.d.ts +12 -0
- package/dist-lib/ui/windows/panels/TextPanel.d.ts +35 -0
- package/dist-lib/ui/windows/panels/VariablesView.d.ts +21 -0
- package/dist-lib/ui/windows/panels/VfsModulePickerModal.d.ts +8 -0
- package/dist-lib/ui/windows/panels/WindowCmdLine.d.ts +23 -0
- package/dist-lib/ui/windows/types.d.ts +145 -0
- package/dist-lib/utils/documentTitle.d.ts +33 -0
- package/dist-lib/utils/fontLoader.d.ts +52 -0
- package/dist-lib/utils/profileLock.d.ts +26 -0
- package/dist-lib/utils/sessionCredentials.d.ts +16 -0
- package/dist-lib/version.d.ts +39 -0
- package/dist-lib/vfs-sw.js +131 -0
- package/dist-lib/vite.d.ts +2 -0
- package/dist-lib/vite.js +154 -0
- package/package.json +93 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { WindowManager } from '../WindowManager';
|
|
2
|
+
import type { LabelManager } from '../../labels/LabelManager';
|
|
3
|
+
import type { CommandLineManager } from '../../cmdline/CommandLineManager';
|
|
4
|
+
import type { ScrollBoxManager } from '../../scrollbox/ScrollBoxManager';
|
|
5
|
+
interface HtmlPanelProps {
|
|
6
|
+
id: string;
|
|
7
|
+
manager: WindowManager;
|
|
8
|
+
labels?: LabelManager;
|
|
9
|
+
cmdLines?: CommandLineManager;
|
|
10
|
+
scrollBoxes?: ScrollBoxManager;
|
|
11
|
+
backgroundColor?: {
|
|
12
|
+
r: number;
|
|
13
|
+
g: number;
|
|
14
|
+
b: number;
|
|
15
|
+
a: number;
|
|
16
|
+
};
|
|
17
|
+
backgroundImage?: {
|
|
18
|
+
url: string;
|
|
19
|
+
mode: number;
|
|
20
|
+
};
|
|
21
|
+
cmdLineEnabled?: boolean;
|
|
22
|
+
cmdLineStyleSheet?: string;
|
|
23
|
+
cmdLineValue?: string;
|
|
24
|
+
cmdLineValueSeq?: number;
|
|
25
|
+
}
|
|
26
|
+
export declare function HtmlPanel({ id, manager, labels, cmdLines, scrollBoxes, backgroundColor, backgroundImage, cmdLineEnabled, cmdLineStyleSheet, cmdLineValue, cmdLineValueSeq }: HtmlPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
value: string;
|
|
3
|
+
onChange: (value: string) => void;
|
|
4
|
+
/** Invoked when the user hits Ctrl/Cmd+S or Ctrl/Cmd+Enter inside the editor. */
|
|
5
|
+
onSave?: () => void;
|
|
6
|
+
/** Jump request from the parent (e.g. error log click). Bump `revision` to
|
|
7
|
+
* re-trigger a jump even when `line` is unchanged. */
|
|
8
|
+
gotoLine?: {
|
|
9
|
+
line: number;
|
|
10
|
+
revision: number;
|
|
11
|
+
} | null;
|
|
12
|
+
}
|
|
13
|
+
export declare function LuaEditor({ value, onChange, onSave, gotoLine }: Props): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { WindowManager } from '../WindowManager';
|
|
2
|
+
interface MapPanelProps {
|
|
3
|
+
id: string;
|
|
4
|
+
manager: WindowManager;
|
|
5
|
+
connectionId: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function MapPanel({ id, manager, connectionId }: MapPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type PackageRepoEntry } from '../../../import/packageRepository';
|
|
2
|
+
interface Props {
|
|
3
|
+
/** Names of packages already installed on this profile — used to flag matching entries. */
|
|
4
|
+
installedNames: Set<string>;
|
|
5
|
+
/** Active proxy URL, used to retry catalog/download fetches when a direct fetch fails CORS. */
|
|
6
|
+
proxyUrl?: string;
|
|
7
|
+
onClose: () => void;
|
|
8
|
+
/**
|
|
9
|
+
* Called after the user clicks Install on an entry. The caller fetches/installs/commits
|
|
10
|
+
* to the store — keeping that flow in ScriptEditorPanel means we don't need to plumb the
|
|
11
|
+
* VFS, scripting engine, or store mutators through the modal.
|
|
12
|
+
*
|
|
13
|
+
* Must throw on failure so the modal can surface the error inline.
|
|
14
|
+
*/
|
|
15
|
+
onInstall: (entry: PackageRepoEntry, bytes: Uint8Array) => Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
export declare function PackageRepositoryModal({ installedNames, proxyUrl, onClose, onInstall }: Props): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { MudSession } from '../../../mud/MudSession';
|
|
3
|
+
import type { ProfileVFS } from '../../../scripting/vfs/ProfileVFS';
|
|
4
|
+
import type { ScriptingEngine } from '../../../scripting/ScriptingEngine';
|
|
5
|
+
import './ScriptEditorPanel.css';
|
|
6
|
+
type Category = 'scripts' | 'aliases' | 'triggers' | 'timers' | 'keys' | 'buttons' | 'packages' | 'errors' | 'variables';
|
|
7
|
+
type EditCategory = Exclude<Category, 'errors' | 'packages' | 'variables'>;
|
|
8
|
+
interface ScriptEditorPanelProps {
|
|
9
|
+
connectionId: string;
|
|
10
|
+
session: MudSession;
|
|
11
|
+
vfs: ProfileVFS | null;
|
|
12
|
+
scriptingEngineRef?: React.RefObject<ScriptingEngine | null>;
|
|
13
|
+
initialListWidth?: number;
|
|
14
|
+
onSplitsChange?: (listWidth: number) => void;
|
|
15
|
+
onOpenVfsFile?: (path: string, line?: number) => void;
|
|
16
|
+
}
|
|
17
|
+
/** Imperative API exposed to the title-bar search box. */
|
|
18
|
+
export interface ScriptEditorPanelHandle {
|
|
19
|
+
/** Switch to the item's category, expand its ancestors, select it, and —
|
|
20
|
+
* when a line is given — move the editor cursor there. */
|
|
21
|
+
navigateToItem: (category: EditCategory, id: string, line?: number) => void;
|
|
22
|
+
}
|
|
23
|
+
export declare const ScriptEditorPanel: React.ForwardRefExoticComponent<ScriptEditorPanelProps & React.RefAttributes<ScriptEditorPanelHandle>>;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import './ScriptSearch.css';
|
|
2
|
+
export type EditCategory = 'scripts' | 'aliases' | 'triggers' | 'timers' | 'keys' | 'buttons';
|
|
3
|
+
interface ScriptSearchProps {
|
|
4
|
+
connectionId: string;
|
|
5
|
+
/** Navigate the editor to a matched item (and optionally a code line). */
|
|
6
|
+
onNavigate: (category: EditCategory, id: string, line?: number) => void;
|
|
7
|
+
}
|
|
8
|
+
/** Global search for the Scripts editor — lives in the modal title bar and
|
|
9
|
+
* drops a VS Code-style results overlay (rendered through a portal so it
|
|
10
|
+
* escapes the modal's `overflow: hidden`). */
|
|
11
|
+
export declare function ScriptSearch({ connectionId, onNavigate }: ScriptSearchProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { WindowManager } from '../WindowManager';
|
|
2
|
+
import type { LabelManager } from '../../labels/LabelManager';
|
|
3
|
+
import type { CommandLineManager } from '../../cmdline/CommandLineManager';
|
|
4
|
+
import type { ScrollBoxManager } from '../../scrollbox/ScrollBoxManager';
|
|
5
|
+
interface TextPanelProps {
|
|
6
|
+
id: string;
|
|
7
|
+
/** Human-readable window title (defaults to the id), used as the accessible
|
|
8
|
+
* name so a screen reader can identify and navigate to this user window. */
|
|
9
|
+
title?: string;
|
|
10
|
+
manager: WindowManager;
|
|
11
|
+
labels?: LabelManager;
|
|
12
|
+
cmdLines?: CommandLineManager;
|
|
13
|
+
scrollBoxes?: ScrollBoxManager;
|
|
14
|
+
fontSize?: number;
|
|
15
|
+
fontFamily?: string;
|
|
16
|
+
wrapAt?: number;
|
|
17
|
+
wrapIndent?: number;
|
|
18
|
+
wrapHangingIndent?: number;
|
|
19
|
+
backgroundColor?: {
|
|
20
|
+
r: number;
|
|
21
|
+
g: number;
|
|
22
|
+
b: number;
|
|
23
|
+
a: number;
|
|
24
|
+
};
|
|
25
|
+
backgroundImage?: {
|
|
26
|
+
url: string;
|
|
27
|
+
mode: number;
|
|
28
|
+
};
|
|
29
|
+
cmdLineEnabled?: boolean;
|
|
30
|
+
cmdLineStyleSheet?: string;
|
|
31
|
+
cmdLineValue?: string;
|
|
32
|
+
cmdLineValueSeq?: number;
|
|
33
|
+
}
|
|
34
|
+
export declare function TextPanel({ id, title, manager, labels, cmdLines, scrollBoxes, fontSize, fontFamily, wrapAt, wrapIndent, wrapHangingIndent, backgroundColor, backgroundImage, cmdLineEnabled, cmdLineStyleSheet, cmdLineValue, cmdLineValueSeq }: TextPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ScriptingEngine } from '../../../scripting/ScriptingEngine';
|
|
2
|
+
interface VariablesViewProps {
|
|
3
|
+
connectionId: string;
|
|
4
|
+
scriptingEngineRef?: React.RefObject<ScriptingEngine | null>;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Mudlet's Variables view: the live `_G` tree with a checkbox per top-level
|
|
8
|
+
* entry that toggles whether it persists across sessions (the profile's
|
|
9
|
+
* save-list / Mudlet `<VariablePackage>`). Built-in globals — the default Lua +
|
|
10
|
+
* Mudlet API namespace present at runtime boot — are hidden by default (toggle
|
|
11
|
+
* to show), so only your own variables appear. Tables expand to browse their
|
|
12
|
+
* contents (fetched eagerly, so expansion is instant). Functions/userdata are
|
|
13
|
+
* shown but not flaggable. Save flagging is top-level granularity (checking a
|
|
14
|
+
* table persists all of it); per-key flagging is a follow-up.
|
|
15
|
+
*
|
|
16
|
+
* Enumerating `_G` runs synchronously on the Lua/main thread, so we defer it a
|
|
17
|
+
* tick behind a loader: the spinner paints first, then the walk runs, keeping
|
|
18
|
+
* opening the tab responsive even for a large namespace.
|
|
19
|
+
*/
|
|
20
|
+
export declare function VariablesView({ connectionId, scriptingEngineRef }: VariablesViewProps): import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ProfileVFS } from '../../../scripting/vfs/ProfileVFS';
|
|
2
|
+
interface Props {
|
|
3
|
+
vfs: ProfileVFS;
|
|
4
|
+
onClose: () => void;
|
|
5
|
+
onPick: (absolutePath: string) => void;
|
|
6
|
+
}
|
|
7
|
+
export declare function VfsModulePickerModal({ vfs, onClose, onPick }: Props): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { WindowManager } from '../WindowManager';
|
|
2
|
+
interface WindowCmdLineProps {
|
|
3
|
+
id: string;
|
|
4
|
+
manager: WindowManager;
|
|
5
|
+
styleSheet?: string;
|
|
6
|
+
/** Latest script-pushed value (clearCmdLine, printCmdLine, appendCmdLine).
|
|
7
|
+
* Applied to the input one-shot whenever `seedSeq` changes. */
|
|
8
|
+
seedValue?: string;
|
|
9
|
+
seedSeq?: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Per-userwindow command line `<input>`. Backs Mudlet's enableCommandLine /
|
|
13
|
+
* setCmdLineAction / setCmdLineStyleSheet on a userwindow. The component owns
|
|
14
|
+
* the typed value as React state (so script-side seeds via printCmdLine /
|
|
15
|
+
* clearCmdLine can drive it through the seedSeq bump) and registers a probe
|
|
16
|
+
* with WindowManager so getCmdLine([name]) can read the live text.
|
|
17
|
+
*
|
|
18
|
+
* Enter dispatches to the bound Lua callback (setCmdLineAction). When no
|
|
19
|
+
* callback is bound, Enter is a no-op — userwindow command lines don't
|
|
20
|
+
* automatically send to the MUD the way the main command bar does.
|
|
21
|
+
*/
|
|
22
|
+
export declare function WindowCmdLine({ id, manager, styleSheet, seedValue, seedSeq }: WindowCmdLineProps): import("react/jsx-runtime").JSX.Element;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
export type PanelKind = 'output' | 'text' | 'html' | 'map';
|
|
2
|
+
export type DockSide = 'left' | 'right' | 'top' | 'bottom';
|
|
3
|
+
export interface DragState {
|
|
4
|
+
panelId: string;
|
|
5
|
+
potentialDock: DockSide | null;
|
|
6
|
+
insertSlotIndex: number | null;
|
|
7
|
+
/** Center zone drop — creates/joins a tab group. */
|
|
8
|
+
stackTargetId?: string;
|
|
9
|
+
/** Cross-axis edge drop — creates/joins a split group (vertical stack in horizontal dock). */
|
|
10
|
+
splitTargetId?: string;
|
|
11
|
+
/** true = insert before target in cross-axis; false = after. */
|
|
12
|
+
splitBefore?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface WindowOpenOptions {
|
|
15
|
+
title?: string;
|
|
16
|
+
kind?: 'text' | 'html' | 'map';
|
|
17
|
+
position?: 'right' | 'left' | 'above' | 'below';
|
|
18
|
+
x?: number;
|
|
19
|
+
y?: number;
|
|
20
|
+
width?: number;
|
|
21
|
+
height?: number;
|
|
22
|
+
activate?: boolean;
|
|
23
|
+
autoOpen?: boolean;
|
|
24
|
+
docked?: DockSide;
|
|
25
|
+
dockOrder?: number;
|
|
26
|
+
dockFlex?: number;
|
|
27
|
+
dockGroup?: string;
|
|
28
|
+
tabOrder?: number;
|
|
29
|
+
isActiveTab?: boolean;
|
|
30
|
+
splitGroup?: string;
|
|
31
|
+
splitOrder?: number;
|
|
32
|
+
splitFlex?: number;
|
|
33
|
+
/** If true, window is restored in hidden state. */
|
|
34
|
+
hidden?: boolean;
|
|
35
|
+
/** If false, skip restoring the saved hint (Mudlet restoreLayout=false). */
|
|
36
|
+
ignoreHint?: boolean;
|
|
37
|
+
/** If false, force floating regardless of dockingArea (Mudlet autoDock=false). */
|
|
38
|
+
autoDock?: boolean;
|
|
39
|
+
/** If true, the user cannot drag this window into a dock slot. Set
|
|
40
|
+
* automatically when openUserWindow(name, _, autoDock=false) is called,
|
|
41
|
+
* mirroring Mudlet's "autoDock=false locks the window floating" behaviour. */
|
|
42
|
+
lockFloating?: boolean;
|
|
43
|
+
/** Dock side to use when no saved hint exists (Mudlet dockingArea). "main" = floating. */
|
|
44
|
+
dockingArea?: string;
|
|
45
|
+
/** Output font size in pixels (Mudlet setFontSize). */
|
|
46
|
+
fontSize?: number;
|
|
47
|
+
/** Output font family override (Mudlet setFont). */
|
|
48
|
+
fontFamily?: string;
|
|
49
|
+
/** Character-column wrap width (Mudlet setWindowWrap). 0/undefined disables. */
|
|
50
|
+
wrapAt?: number;
|
|
51
|
+
/** Indent (in characters) of newline-started lines (Mudlet setWindowWrapIndent). */
|
|
52
|
+
wrapIndent?: number;
|
|
53
|
+
/** Indent (in characters) of wrapped continuation lines (Mudlet setWindowWrapHangingIndent). */
|
|
54
|
+
wrapHangingIndent?: number;
|
|
55
|
+
/** Window background fill (Mudlet setBackgroundColor). rgba 0..255. */
|
|
56
|
+
backgroundColor?: {
|
|
57
|
+
r: number;
|
|
58
|
+
g: number;
|
|
59
|
+
b: number;
|
|
60
|
+
a: number;
|
|
61
|
+
};
|
|
62
|
+
/** Mudlet setBackgroundImage. `url` is a resolved href for modes 1-3 or the
|
|
63
|
+
* raw stylesheet body for mode 4 (style). `mode` mirrors `mudlet.BgImageMode`:
|
|
64
|
+
* 1=border (stretched), 2=center, 3=tile, 4=style. */
|
|
65
|
+
backgroundImage?: {
|
|
66
|
+
url: string;
|
|
67
|
+
mode: number;
|
|
68
|
+
};
|
|
69
|
+
/** For miniconsoles, the parent userwindow id ('main' or another userwindow's
|
|
70
|
+
* name). When set to a non-main parent, the miniconsole is rendered inside
|
|
71
|
+
* that parent's viewport at parent-relative (x, y) coordinates. */
|
|
72
|
+
parent?: string;
|
|
73
|
+
}
|
|
74
|
+
export interface WindowHandle {
|
|
75
|
+
readonly id: string;
|
|
76
|
+
readonly kind: PanelKind;
|
|
77
|
+
readonly element: HTMLElement;
|
|
78
|
+
write(text: string): void;
|
|
79
|
+
clear(): void;
|
|
80
|
+
setTitle(title: string): void;
|
|
81
|
+
focus(): void;
|
|
82
|
+
close(): void;
|
|
83
|
+
}
|
|
84
|
+
export interface ScriptWindowRenderData {
|
|
85
|
+
id: string;
|
|
86
|
+
title: string;
|
|
87
|
+
kind: 'text' | 'html' | 'map';
|
|
88
|
+
visible: boolean;
|
|
89
|
+
x: number;
|
|
90
|
+
y: number;
|
|
91
|
+
width: number;
|
|
92
|
+
height: number;
|
|
93
|
+
zIndex: number;
|
|
94
|
+
docked?: DockSide;
|
|
95
|
+
dockOrder?: number;
|
|
96
|
+
dockFlex?: number;
|
|
97
|
+
dockGroup?: string;
|
|
98
|
+
tabOrder?: number;
|
|
99
|
+
isActiveTab?: boolean;
|
|
100
|
+
splitGroup?: string;
|
|
101
|
+
splitOrder?: number;
|
|
102
|
+
splitFlex?: number;
|
|
103
|
+
fontSize?: number;
|
|
104
|
+
fontFamily?: string;
|
|
105
|
+
wrapAt?: number;
|
|
106
|
+
wrapIndent?: number;
|
|
107
|
+
wrapHangingIndent?: number;
|
|
108
|
+
backgroundColor?: {
|
|
109
|
+
r: number;
|
|
110
|
+
g: number;
|
|
111
|
+
b: number;
|
|
112
|
+
a: number;
|
|
113
|
+
};
|
|
114
|
+
backgroundImage?: {
|
|
115
|
+
url: string;
|
|
116
|
+
mode: number;
|
|
117
|
+
};
|
|
118
|
+
/** For miniconsoles created with a parent userwindow — see WindowOpenOptions.parent. */
|
|
119
|
+
parent?: string;
|
|
120
|
+
/** When true, drag-to-dock is disabled for this floating window. See
|
|
121
|
+
* WindowOpenOptions.lockFloating. */
|
|
122
|
+
lockFloating?: boolean;
|
|
123
|
+
/** When true, the panel is detached into a separate browser window. Its
|
|
124
|
+
* portal-target div is appended into that window's document instead of a
|
|
125
|
+
* dock slot / floating frame; the component never unmounts (scrollback and
|
|
126
|
+
* live registrations survive). Closing the popout window pops it back in.
|
|
127
|
+
* This is transient runtime state — it is not persisted to the saved hint,
|
|
128
|
+
* so a reload restores the panel to its prior docked/floating position
|
|
129
|
+
* (re-opening a popup without a user gesture would be blocked anyway). */
|
|
130
|
+
poppedOut?: boolean;
|
|
131
|
+
/** Mudlet enableCommandLine(name) — when true, the panel renders a single-line
|
|
132
|
+
* input below the output area. Enter fires the registered cmd-line action;
|
|
133
|
+
* if none, the text is sent to the MUD via the main connection. */
|
|
134
|
+
cmdLineEnabled?: boolean;
|
|
135
|
+
/** Mudlet setCmdLineStyleSheet(name, qss) — Qt QSS for the per-window input.
|
|
136
|
+
* Translated through cmdLineQssToScopedCss at render time. */
|
|
137
|
+
cmdLineStyleSheet?: string;
|
|
138
|
+
/** Mudlet clearCmdLine / printCmdLine seed value. Drives the input's value
|
|
139
|
+
* one-shot on change so React stays in sync with script writes. */
|
|
140
|
+
cmdLineValue?: string;
|
|
141
|
+
/** Bumped each time cmdLineValue is written by script, so identical writes
|
|
142
|
+
* still trigger React's seed effect (otherwise printCmdLine('x') after a
|
|
143
|
+
* user types 'x' would do nothing). */
|
|
144
|
+
cmdLineValueSeq?: number;
|
|
145
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single owner of `document.title`.
|
|
3
|
+
*
|
|
4
|
+
* The tab title is composed from two parts that used to fight over it: a leading
|
|
5
|
+
* connection-status dot (🟢/🟡/🔴, set from React) and the profile label. On top
|
|
6
|
+
* of that sit transient flashes — Mudlet's `alert()` and the "notify on new
|
|
7
|
+
* data" feature. Everything goes through here so there's exactly one blink
|
|
8
|
+
* interval and one set of focus/visibility listeners for the whole app.
|
|
9
|
+
*
|
|
10
|
+
* The flash reuses the *same* status dot rather than adding a second one: while
|
|
11
|
+
* flashing, the leading dot blinks to white `⚪` and back. Both frames are emoji
|
|
12
|
+
* so they share an advance width and the title text never shifts as it blinks.
|
|
13
|
+
* If there's no status dot (connection indicator off) the flash falls back to a
|
|
14
|
+
* standalone 🟢 ↔ ⚪ dot so the notification is still visible.
|
|
15
|
+
*
|
|
16
|
+
* - `setBaseTitle()` updates the status dot + label; an active flash is preserved.
|
|
17
|
+
* - `flashTitle()` starts the blink, until the user returns to the tab (and,
|
|
18
|
+
* optionally, no longer than `maxSeconds` — Mudlet's `alert(seconds)`).
|
|
19
|
+
* - A flash is a no-op while the tab is already focused, matching Mudlet.
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Set the steady-state title: a leading status `dot` (pass '' for none) and the
|
|
23
|
+
* profile `text`. Any active flash keeps running on top of it.
|
|
24
|
+
*/
|
|
25
|
+
export declare function setBaseTitle(text: string, dot?: string): void;
|
|
26
|
+
/**
|
|
27
|
+
* Flash the title until the user returns to the tab. If `maxSeconds` is given it
|
|
28
|
+
* also caps the duration. No-op while the tab is focused. Calling again while a
|
|
29
|
+
* flash is active just refreshes the deadline (the blink keeps its phase).
|
|
30
|
+
*/
|
|
31
|
+
export declare function flashTitle(maxSeconds?: number): void;
|
|
32
|
+
/** Stop any active flash immediately. Does not change the base title. */
|
|
33
|
+
export declare function clearTitleFlash(): void;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { ProfileVFS } from '../scripting/vfs/ProfileVFS';
|
|
2
|
+
import type { OutputFontSource } from '../storage';
|
|
3
|
+
/** Synchronous detection. May false-negative on a system font whose face the
|
|
4
|
+
* browser hasn't materialized yet — use {@link ensureFontAvailable} when an
|
|
5
|
+
* await is acceptable. */
|
|
6
|
+
export declare function isFontAvailable(family: string): boolean;
|
|
7
|
+
/** Async variant: nudges the browser via document.fonts.load() first (this
|
|
8
|
+
* causes Chrome to materialize an installed system face into the FontFaceSet
|
|
9
|
+
* so subsequent measurements can see it), then measures via the DOM probe. */
|
|
10
|
+
export declare function ensureFontAvailable(family: string): Promise<boolean>;
|
|
11
|
+
export interface FontProbeRow {
|
|
12
|
+
fallback: string;
|
|
13
|
+
baselineWidth: number;
|
|
14
|
+
candidateWidth: number;
|
|
15
|
+
diverges: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface FontProbeReport {
|
|
18
|
+
family: string;
|
|
19
|
+
text: string;
|
|
20
|
+
fontSizePx: number;
|
|
21
|
+
rows: FontProbeRow[];
|
|
22
|
+
available: boolean;
|
|
23
|
+
fontsCheckSays: boolean;
|
|
24
|
+
fontsLoadFaces: number;
|
|
25
|
+
fontFamiliesInSet: number;
|
|
26
|
+
}
|
|
27
|
+
/** Run the probe and return raw measurements for debugging the detector. */
|
|
28
|
+
export declare function diagnoseFontProbe(family: string): Promise<FontProbeReport>;
|
|
29
|
+
export interface LocalFontEntry {
|
|
30
|
+
family: string;
|
|
31
|
+
fullName: string;
|
|
32
|
+
postscriptName: string;
|
|
33
|
+
style?: string;
|
|
34
|
+
}
|
|
35
|
+
export declare function isLocalFontApiSupported(): boolean;
|
|
36
|
+
export declare function queryLocalFonts(): Promise<LocalFontEntry[]>;
|
|
37
|
+
export declare function getUniversalDefaultFonts(): readonly string[];
|
|
38
|
+
export declare function getCachedLocalFonts(): string[];
|
|
39
|
+
export declare function setLocalFontsCache(families: Iterable<string>): void;
|
|
40
|
+
/** Fire-and-forget. If Local Font Access is supported AND permission was
|
|
41
|
+
* previously granted, query installed fonts and cache the family list.
|
|
42
|
+
* Never prompts the user. Idempotent: subsequent calls before the first
|
|
43
|
+
* resolves piggy-back on the in-flight promise. */
|
|
44
|
+
export declare function primeLocalFontsCache(): Promise<void>;
|
|
45
|
+
/** Families currently registered in document.fonts — URL stylesheets and
|
|
46
|
+
* FontFace-API uploads (the kind loaded by loadFontFromUrl / loadFontFromVfs)
|
|
47
|
+
* show up here once the browser has materialized the face. Quoted-string
|
|
48
|
+
* forms ("Family Name") are unwrapped to plain names. */
|
|
49
|
+
export declare function getRegisteredFontFamilies(): string[];
|
|
50
|
+
export declare function loadFontFromUrl(family: string, url: string): Promise<void>;
|
|
51
|
+
export declare function loadFontFromVfs(family: string, path: string, vfs: ProfileVFS): Promise<void>;
|
|
52
|
+
export declare function applyOutputFont(font: OutputFontSource | undefined, vfs: ProfileVFS | null): Promise<void>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** Shared prefix for every per-profile Web Lock name. */
|
|
2
|
+
export declare const PROFILE_LOCK_PREFIX = "mudix:profile:";
|
|
3
|
+
/** Web Lock name for a profile. */
|
|
4
|
+
export declare const profileLockName: (connectionId: string) => string;
|
|
5
|
+
/** Inverse of {@link profileLockName}: the connectionId encoded in a lock name,
|
|
6
|
+
* or null when the name isn't a profile lock. Used to enumerate which profiles
|
|
7
|
+
* are open across tabs from `navigator.locks.query()`. */
|
|
8
|
+
export declare const connectionIdFromLockName: (name: string) => string | null;
|
|
9
|
+
/** Best-effort check whether some tab currently holds the profile's lock. Used
|
|
10
|
+
* only to pick the initial "waiting for the other tab" message; the actual
|
|
11
|
+
* hand-off is the queued request in {@link acquireProfileLock}. */
|
|
12
|
+
export declare function isProfileLockHeld(connectionId: string): Promise<boolean>;
|
|
13
|
+
export interface ProfileLockHandle {
|
|
14
|
+
/** Resolves once this tab owns the profile — immediately when the lock is
|
|
15
|
+
* free, or later when the owning tab releases it. Rejects with AbortError
|
|
16
|
+
* if the signal fires before ownership is granted. */
|
|
17
|
+
readonly acquired: Promise<void>;
|
|
18
|
+
/** Release ownership. Idempotent; safe to call before `acquired` resolves
|
|
19
|
+
* (it then cancels the pending request via the same signal path). */
|
|
20
|
+
release(): void;
|
|
21
|
+
}
|
|
22
|
+
/** Acquire the profile's exclusive lock, queuing behind another tab if one
|
|
23
|
+
* already holds it. Pass an AbortSignal to stop waiting (e.g. the user backs
|
|
24
|
+
* out to the connection screen). Degrades to a no-op guard when the Web Locks
|
|
25
|
+
* API is unavailable (legacy browser or insecure context). */
|
|
26
|
+
export declare function acquireProfileLock(connectionId: string, signal: AbortSignal): ProfileLockHandle;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory login credentials, keyed by connection id. Used by branded builds,
|
|
3
|
+
* where credentials are **never persisted**: the login screen deposits them
|
|
4
|
+
* here and the auto-login paths (GMCP Char.Login, text-login prompts) read
|
|
5
|
+
* them with priority over the connection record's stored fields. Lifetime is
|
|
6
|
+
* the page — a reload starts back at the login form.
|
|
7
|
+
*/
|
|
8
|
+
export interface SessionCredentials {
|
|
9
|
+
account: string;
|
|
10
|
+
password: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function setSessionCredentials(connectionId: string, creds: SessionCredentials | null): void;
|
|
13
|
+
export declare function getSessionCredentials(connectionId: string): SessionCredentials | undefined;
|
|
14
|
+
/** The most recently entered credentials this page, regardless of profile —
|
|
15
|
+
* prefills the branded login form after closing a profile. */
|
|
16
|
+
export declare function getLastSessionCredentials(): SessionCredentials | undefined;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The client's own identity on the wire — one source of truth for every
|
|
3
|
+
* protocol that asks who we are: TTYPE/MTTS (`TelnetNegotiator`), MNES and
|
|
4
|
+
* NEW-ENVIRON (`protocol/mnes`), GMCP `Core.Hello` (`MudClient`), and the MXP
|
|
5
|
+
* `<VERSION>` reply (`protocol/mxp`). These four used to carry three different
|
|
6
|
+
* spellings and two different version numbers; keep them going through here.
|
|
7
|
+
*
|
|
8
|
+
* This is *our* version, not the Mudlet API level we implement. Scripts
|
|
9
|
+
* feature-gate on `getMudletVersion()` (Bridge.lua), which reports the Mudlet
|
|
10
|
+
* release whose Lua API this client targets and moves independently of the
|
|
11
|
+
* client's own release number — a script asking `mudletOlderThan(4, 10, 0)`
|
|
12
|
+
* wants to know which APIs exist, not which build of Mudlet Web it runs on.
|
|
13
|
+
*
|
|
14
|
+
* `CLIENT_VERSION` comes straight from package.json, substituted at build time
|
|
15
|
+
* by Vite `define` (see buildInfo.ts) — `src/` can't import package.json
|
|
16
|
+
* itself because tsconfig.lib.json pins `rootDir: "src"`.
|
|
17
|
+
*/
|
|
18
|
+
/** Client name reported to servers. Uppercase, hyphenated: TTYPE values are
|
|
19
|
+
* conventionally uppercase tokens (Mudlet sends `MUDLET`), and the MNES and
|
|
20
|
+
* GMCP slots reuse the same token so a server sees one consistent identity.
|
|
21
|
+
*
|
|
22
|
+
* Deliberately distinct from desktop Mudlet's `MUDLET`: server authors
|
|
23
|
+
* feature-detect off this, and Mudlet Web is not feature-identical to the
|
|
24
|
+
* desktop client. Claiming to be `MUDLET` would invite traffic we can't
|
|
25
|
+
* honour. */
|
|
26
|
+
export declare const CLIENT_NAME = "MUDLET-WEB";
|
|
27
|
+
/** Client version, reported alongside `CLIENT_NAME`. Always package.json's
|
|
28
|
+
* `version` — there is nothing to keep in sync by hand. */
|
|
29
|
+
export declare const CLIENT_VERSION: string;
|
|
30
|
+
/** Short git hash of the build, or '' when git wasn't available at build time.
|
|
31
|
+
* Shown in the About dialog next to the version: releases between version
|
|
32
|
+
* bumps are otherwise indistinguishable in a bug report. */
|
|
33
|
+
export declare const GIT_COMMIT: string;
|
|
34
|
+
/** Terminal type reported via TTYPE and MNES `TERMINAL_TYPE`. "ANSI-TRUECOLOR"
|
|
35
|
+
* (matching Mudlet) describes the real capability — ANSI with 24-bit colour —
|
|
36
|
+
* better than an xterm emulation claim; 256-colour/truecolour support is also
|
|
37
|
+
* signalled via MTTS and the 256_COLORS/TRUECOLOR vars, so capability
|
|
38
|
+
* detection doesn't rest on this name. */
|
|
39
|
+
export declare const TERMINAL_TYPE = "ANSI-TRUECOLOR";
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
// Service worker that serves ProfileVFS-backed assets at /__vfs/<connectionId>/<path>.
|
|
2
|
+
// The page is the source of truth for VFS contents (the SW can't share folder
|
|
3
|
+
// handles or always-open the same IDB store), so each request round-trips to
|
|
4
|
+
// the client via MessageChannel.
|
|
5
|
+
|
|
6
|
+
const CACHE_NAME = 'mudix-vfs-v1';
|
|
7
|
+
// Scope path always ends with '/'. On a root-served deploy this is '/'; on
|
|
8
|
+
// GitHub Pages or any subpath deploy it's '/<repo>/'. The intercept prefix is
|
|
9
|
+
// '<scope>__vfs/' so SW-controlled URLs stay inside scope.
|
|
10
|
+
const SCOPE_PATH = new URL(self.registration.scope).pathname;
|
|
11
|
+
const PREFIX = `${SCOPE_PATH}__vfs/`;
|
|
12
|
+
const READ_TIMEOUT_MS = 5000;
|
|
13
|
+
|
|
14
|
+
self.addEventListener('install', () => self.skipWaiting());
|
|
15
|
+
self.addEventListener('activate', (e) => e.waitUntil(self.clients.claim()));
|
|
16
|
+
|
|
17
|
+
self.addEventListener('fetch', (event) => {
|
|
18
|
+
const url = new URL(event.request.url);
|
|
19
|
+
if (url.origin !== self.location.origin) return;
|
|
20
|
+
if (!url.pathname.startsWith(PREFIX)) return;
|
|
21
|
+
event.respondWith(handle(event, url));
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
async function handle(event, url) {
|
|
25
|
+
const rest = url.pathname.slice(PREFIX.length).split('/').filter(Boolean);
|
|
26
|
+
if (rest.length < 2) return new Response('Bad request', { status: 400 });
|
|
27
|
+
const connectionId = decodeURIComponent(rest[0]);
|
|
28
|
+
const filePath = '/' + rest.slice(1).map(decodeURIComponent).join('/');
|
|
29
|
+
|
|
30
|
+
const cache = await caches.open(CACHE_NAME);
|
|
31
|
+
const cached = await cache.match(event.request);
|
|
32
|
+
if (cached) return cached;
|
|
33
|
+
|
|
34
|
+
const client = await pickClient(event);
|
|
35
|
+
if (!client) {
|
|
36
|
+
// Either there's no app tab loaded (direct URL hit in fresh tab) or
|
|
37
|
+
// the only candidate is the tab currently navigating to this URL.
|
|
38
|
+
return new Response('No app tab loaded; open mudix first', { status: 503 });
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const reply = await ask(client, { type: 'vfs:read', connectionId, path: filePath });
|
|
42
|
+
if (!reply || !reply.ok) {
|
|
43
|
+
return new Response(reply?.error ?? 'Not found', { status: 404 });
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const headers = new Headers();
|
|
47
|
+
headers.set('Content-Type', reply.contentType || 'application/octet-stream');
|
|
48
|
+
// no-store keeps this response out of the browser's own HTTP cache, which
|
|
49
|
+
// has no validator to revalidate against (we set none) and would otherwise
|
|
50
|
+
// race our explicit Cache Storage entry above — that race is what produced
|
|
51
|
+
// stale 304-with-no-body responses for cached images. The Cache Storage
|
|
52
|
+
// entry (invalidated on writes via postMessage) is the only cache that
|
|
53
|
+
// should own this decision.
|
|
54
|
+
headers.set('Cache-Control', 'no-store');
|
|
55
|
+
const response = new Response(reply.bytes, { headers });
|
|
56
|
+
cache.put(event.request, response.clone()).catch(() => {});
|
|
57
|
+
return response;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async function pickClient(event) {
|
|
61
|
+
// Prefer the client that issued this request — for sub-resource fetches
|
|
62
|
+
// that's the loaded app page, which can reply immediately.
|
|
63
|
+
const requestingId = event.clientId || event.resultingClientId || '';
|
|
64
|
+
if (requestingId) {
|
|
65
|
+
const c = await self.clients.get(requestingId);
|
|
66
|
+
if (c && isUsable(c)) return c;
|
|
67
|
+
}
|
|
68
|
+
const all = await self.clients.matchAll({ type: 'window', includeUncontrolled: true });
|
|
69
|
+
const usable = all.filter(isUsable);
|
|
70
|
+
return usable.find((c) => c.focused) ?? usable[0] ?? null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Skip clients that are themselves navigating to a /__vfs/ URL — those are
|
|
74
|
+
// fresh tabs in the middle of loading the SW response; they have no JS running
|
|
75
|
+
// and can't reply, so picking one guarantees a timeout.
|
|
76
|
+
function isUsable(client) {
|
|
77
|
+
try {
|
|
78
|
+
return !new URL(client.url).pathname.startsWith(PREFIX);
|
|
79
|
+
} catch {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function ask(client, message) {
|
|
85
|
+
return new Promise((resolve) => {
|
|
86
|
+
const channel = new MessageChannel();
|
|
87
|
+
const timer = setTimeout(() => {
|
|
88
|
+
channel.port1.close();
|
|
89
|
+
resolve({ ok: false, error: 'timeout' });
|
|
90
|
+
}, READ_TIMEOUT_MS);
|
|
91
|
+
channel.port1.onmessage = (e) => {
|
|
92
|
+
clearTimeout(timer);
|
|
93
|
+
channel.port1.close();
|
|
94
|
+
resolve(e.data);
|
|
95
|
+
};
|
|
96
|
+
client.postMessage(message, [channel.port2]);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
self.addEventListener('message', (event) => {
|
|
101
|
+
const data = event.data;
|
|
102
|
+
if (!data) return;
|
|
103
|
+
if (data.type === 'vfs:invalidate') {
|
|
104
|
+
event.waitUntil(invalidate(data));
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
async function invalidate({ connectionId, path }) {
|
|
109
|
+
if (!connectionId) {
|
|
110
|
+
await caches.delete(CACHE_NAME);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const cache = await caches.open(CACHE_NAME);
|
|
114
|
+
const connPrefix = `${PREFIX}${encodeURIComponent(connectionId)}/`;
|
|
115
|
+
const keys = await cache.keys();
|
|
116
|
+
if (path) {
|
|
117
|
+
const segs = path.split('/').filter(Boolean).map(encodeURIComponent).join('/');
|
|
118
|
+
const target = `${connPrefix}${segs}`;
|
|
119
|
+
await Promise.all(
|
|
120
|
+
keys
|
|
121
|
+
.filter((req) => new URL(req.url).pathname === target)
|
|
122
|
+
.map((req) => cache.delete(req)),
|
|
123
|
+
);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
await Promise.all(
|
|
127
|
+
keys
|
|
128
|
+
.filter((req) => new URL(req.url).pathname.startsWith(connPrefix))
|
|
129
|
+
.map((req) => cache.delete(req)),
|
|
130
|
+
);
|
|
131
|
+
}
|