@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.
Files changed (242) hide show
  1. package/LICENSE +338 -0
  2. package/README.md +150 -0
  3. package/dist-lib/App.d.ts +1 -0
  4. package/dist-lib/MudletWebApp.d.ts +11 -0
  5. package/dist-lib/ProfileSession.d.ts +15 -0
  6. package/dist-lib/assets/mapParser.worker-t-3rd1zR.js +9 -0
  7. package/dist-lib/branding.d.ts +213 -0
  8. package/dist-lib/core/EventBus.d.ts +29 -0
  9. package/dist-lib/db/sqliteClient.d.ts +25 -0
  10. package/dist-lib/hooks/useEngines.d.ts +12 -0
  11. package/dist-lib/hooks/useMudSession.d.ts +10 -0
  12. package/dist-lib/hooks/useOutput.d.ts +17 -0
  13. package/dist-lib/hooks/useViewportMode.d.ts +14 -0
  14. package/dist-lib/import/applyMudletProfile.d.ts +57 -0
  15. package/dist-lib/import/collectProfileExport.d.ts +16 -0
  16. package/dist-lib/import/defaultPackages.d.ts +81 -0
  17. package/dist-lib/import/defaults/mudlet-mapper.xml +13023 -0
  18. package/dist-lib/import/defaults/run-lua-code.mpackage +0 -0
  19. package/dist-lib/import/mudletHost.d.ts +67 -0
  20. package/dist-lib/import/mudletLink.d.ts +34 -0
  21. package/dist-lib/import/mudletProfileExport.d.ts +49 -0
  22. package/dist-lib/import/mudletProfileImport.d.ts +71 -0
  23. package/dist-lib/import/mudletVariables.d.ts +49 -0
  24. package/dist-lib/import/mudletWriteback.d.ts +12 -0
  25. package/dist-lib/import/mudletXmlExport.d.ts +16 -0
  26. package/dist-lib/import/mudletXmlImport.d.ts +21 -0
  27. package/dist-lib/import/packageInstaller.d.ts +72 -0
  28. package/dist-lib/import/packageRepository.d.ts +54 -0
  29. package/dist-lib/import/remotePackageInstall.d.ts +52 -0
  30. package/dist-lib/index.d.ts +30 -0
  31. package/dist-lib/index.js +42307 -0
  32. package/dist-lib/logging/SessionLogger.d.ts +41 -0
  33. package/dist-lib/main.d.ts +2 -0
  34. package/dist-lib/map/MapSelectionOverlay.d.ts +15 -0
  35. package/dist-lib/map/MapStore.d.ts +1067 -0
  36. package/dist-lib/map/MudixMapReader.d.ts +90 -0
  37. package/dist-lib/map/MudletHighlightOverlay.d.ts +18 -0
  38. package/dist-lib/map/mapImageExport.d.ts +26 -0
  39. package/dist-lib/map/mapParser.worker.d.ts +1 -0
  40. package/dist-lib/map/mapParserClient.d.ts +35 -0
  41. package/dist-lib/map/pathfinding.d.ts +52 -0
  42. package/dist-lib/map/xmlMapImport.d.ts +28 -0
  43. package/dist-lib/mud/MudSession.d.ts +236 -0
  44. package/dist-lib/mud/PatternEngine.d.ts +28 -0
  45. package/dist-lib/mud/aliases/AliasEngine.d.ts +15 -0
  46. package/dist-lib/mud/connection/LineAssembler.d.ts +84 -0
  47. package/dist-lib/mud/connection/MudClient.d.ts +268 -0
  48. package/dist-lib/mud/connection/PingTracker.d.ts +28 -0
  49. package/dist-lib/mud/connection/TelnetNegotiator.d.ts +188 -0
  50. package/dist-lib/mud/connection/telnetDebug.d.ts +54 -0
  51. package/dist-lib/mud/events.d.ts +160 -0
  52. package/dist-lib/mud/keybindings/KeyEngine.d.ts +36 -0
  53. package/dist-lib/mud/keybindings/browserReservedKeys.d.ts +45 -0
  54. package/dist-lib/mud/keybindings/qtKeys.d.ts +33 -0
  55. package/dist-lib/mud/protocol/charset.d.ts +105 -0
  56. package/dist-lib/mud/protocol/constants.d.ts +116 -0
  57. package/dist-lib/mud/protocol/echo.d.ts +63 -0
  58. package/dist-lib/mud/protocol/gmcp.d.ts +28 -0
  59. package/dist-lib/mud/protocol/index.d.ts +11 -0
  60. package/dist-lib/mud/protocol/mccp.d.ts +18 -0
  61. package/dist-lib/mud/protocol/mnes.d.ts +83 -0
  62. package/dist-lib/mud/protocol/msdp.d.ts +19 -0
  63. package/dist-lib/mud/protocol/msp.d.ts +47 -0
  64. package/dist-lib/mud/protocol/mssp.d.ts +25 -0
  65. package/dist-lib/mud/protocol/mxp.d.ts +188 -0
  66. package/dist-lib/mud/protocol/naws.d.ts +7 -0
  67. package/dist-lib/mud/replay/ReplayPlayer.d.ts +31 -0
  68. package/dist-lib/mud/replay/ReplayRecorder.d.ts +18 -0
  69. package/dist-lib/mud/replay/replayFormat.d.ts +49 -0
  70. package/dist-lib/mud/text/Console.d.ts +183 -0
  71. package/dist-lib/mud/text/FormatState.d.ts +256 -0
  72. package/dist-lib/mud/text/ansiEscapes.d.ts +88 -0
  73. package/dist-lib/mud/text/cellRender.d.ts +21 -0
  74. package/dist-lib/mud/text/colorParsers.d.ts +54 -0
  75. package/dist-lib/mud/text/colors.d.ts +31 -0
  76. package/dist-lib/mud/text/controlCharacterMode.d.ts +13 -0
  77. package/dist-lib/mud/text/controlChars.d.ts +31 -0
  78. package/dist-lib/mud/text/hyperlinkConfig.d.ts +164 -0
  79. package/dist-lib/mud/text/hyperlinkVisibility.d.ts +37 -0
  80. package/dist-lib/mud/text/oscLinkManager.d.ts +35 -0
  81. package/dist-lib/mud/text/wcwidth.d.ts +44 -0
  82. package/dist-lib/mud/text/xterm256.d.ts +2 -0
  83. package/dist-lib/mud/timers/TimerEngine.d.ts +61 -0
  84. package/dist-lib/mud/triggers/ChunkProcessor.d.ts +11 -0
  85. package/dist-lib/mud/triggers/TriggerEngine.d.ts +188 -0
  86. package/dist-lib/mud/triggers/pcre/Pcre2.d.ts +26 -0
  87. package/dist-lib/scripting/EngineHost.d.ts +152 -0
  88. package/dist-lib/scripting/GlobalEventChannel.d.ts +36 -0
  89. package/dist-lib/scripting/IScriptingRuntime.d.ts +95 -0
  90. package/dist-lib/scripting/MapOpenNotifier.d.ts +19 -0
  91. package/dist-lib/scripting/ScriptingAPI.d.ts +1691 -0
  92. package/dist-lib/scripting/ScriptingEngine.d.ts +806 -0
  93. package/dist-lib/scripting/StopwatchManager.d.ts +94 -0
  94. package/dist-lib/scripting/heldModifiers.d.ts +3 -0
  95. package/dist-lib/scripting/http/HttpService.d.ts +23 -0
  96. package/dist-lib/scripting/lua/LuaRuntime.d.ts +190 -0
  97. package/dist-lib/scripting/lua/bindings/automation.d.ts +10 -0
  98. package/dist-lib/scripting/lua/bindings/commandLine.d.ts +11 -0
  99. package/dist-lib/scripting/lua/bindings/context.d.ts +87 -0
  100. package/dist-lib/scripting/lua/bindings/cursor.d.ts +10 -0
  101. package/dist-lib/scripting/lua/bindings/diagnostics.d.ts +9 -0
  102. package/dist-lib/scripting/lua/bindings/map.d.ts +14 -0
  103. package/dist-lib/scripting/lua/bindings/media.d.ts +24 -0
  104. package/dist-lib/scripting/lua/bindings/output.d.ts +10 -0
  105. package/dist-lib/scripting/lua/bindings/packages.d.ts +10 -0
  106. package/dist-lib/scripting/lua/bindings/session.d.ts +16 -0
  107. package/dist-lib/scripting/lua/bindings/textEdit.d.ts +9 -0
  108. package/dist-lib/scripting/lua/bindings/userWindows.d.ts +11 -0
  109. package/dist-lib/scripting/lua/bindings/window.d.ts +10 -0
  110. package/dist-lib/scripting/lua/imageSize.d.ts +4 -0
  111. package/dist-lib/scripting/lua/luaCompletions.d.ts +9 -0
  112. package/dist-lib/scripting/lua/mudlet-lua/generic-mapper/generic_mapper.mpackage +0 -0
  113. package/dist-lib/scripting/lua/rex.d.ts +3 -0
  114. package/dist-lib/scripting/lua/sqlRowEncoder.d.ts +1 -0
  115. package/dist-lib/scripting/lua/yajl.d.ts +11 -0
  116. package/dist-lib/scripting/profilesPresence.d.ts +50 -0
  117. package/dist-lib/scripting/vfs/ProfileVFS.d.ts +62 -0
  118. package/dist-lib/scripting/vfs/cssRewrite.d.ts +21 -0
  119. package/dist-lib/scripting/vfs/folderHandleStore.d.ts +16 -0
  120. package/dist-lib/scripting/vfs/folderSync.d.ts +59 -0
  121. package/dist-lib/scripting/vfs/htmlRewrite.d.ts +26 -0
  122. package/dist-lib/scripting/vfs/vfsBridge.d.ts +16 -0
  123. package/dist-lib/services/cloudflare.d.ts +54 -0
  124. package/dist-lib/storage/appStore.d.ts +132 -0
  125. package/dist-lib/storage/crossTabSync.d.ts +3 -0
  126. package/dist-lib/storage/debouncedStorage.d.ts +18 -0
  127. package/dist-lib/storage/hooks.d.ts +17 -0
  128. package/dist-lib/storage/index.d.ts +4 -0
  129. package/dist-lib/storage/logExport.d.ts +32 -0
  130. package/dist-lib/storage/logStorage.d.ts +45 -0
  131. package/dist-lib/storage/mapStorage.d.ts +2 -0
  132. package/dist-lib/storage/profileVfsData.d.ts +47 -0
  133. package/dist-lib/storage/schema.d.ts +638 -0
  134. package/dist-lib/styles.css +2 -0
  135. package/dist-lib/ui/AboutModal.d.ts +8 -0
  136. package/dist-lib/ui/BrandLoginFields.d.ts +25 -0
  137. package/dist-lib/ui/BrandLoginScreen.d.ts +11 -0
  138. package/dist-lib/ui/CharLoginModal.d.ts +32 -0
  139. package/dist-lib/ui/CmdLineMenuRegistry.d.ts +27 -0
  140. package/dist-lib/ui/CodeEditorPreview.d.ts +19 -0
  141. package/dist-lib/ui/CommandBar.d.ts +17 -0
  142. package/dist-lib/ui/ConnectionFormModal.d.ts +13 -0
  143. package/dist-lib/ui/ConnectionGrid.d.ts +18 -0
  144. package/dist-lib/ui/ConnectionScreen.d.ts +14 -0
  145. package/dist-lib/ui/FileBrowserModal.d.ts +20 -0
  146. package/dist-lib/ui/FilePickerModal.d.ts +21 -0
  147. package/dist-lib/ui/FolderPermissionScreen.d.ts +16 -0
  148. package/dist-lib/ui/JsonPreview.d.ts +15 -0
  149. package/dist-lib/ui/LogBrowserModal.d.ts +7 -0
  150. package/dist-lib/ui/MapEditorModal.d.ts +9 -0
  151. package/dist-lib/ui/MarkdownPreview.d.ts +15 -0
  152. package/dist-lib/ui/MergeConflictModal.d.ts +17 -0
  153. package/dist-lib/ui/ModuleResolveModal.d.ts +22 -0
  154. package/dist-lib/ui/MouseEventRegistry.d.ts +31 -0
  155. package/dist-lib/ui/ProfileBusyScreen.d.ts +12 -0
  156. package/dist-lib/ui/ProfileExportModal.d.ts +7 -0
  157. package/dist-lib/ui/ProxyInfoModal.d.ts +6 -0
  158. package/dist-lib/ui/ProxyWhyModal.d.ts +6 -0
  159. package/dist-lib/ui/ProxyWizardModal.d.ts +6 -0
  160. package/dist-lib/ui/QuickOpenPalette.d.ts +8 -0
  161. package/dist-lib/ui/ResizableModal.d.ts +17 -0
  162. package/dist-lib/ui/ScriptingDocsModal.d.ts +12 -0
  163. package/dist-lib/ui/SettingsModal.d.ts +9 -0
  164. package/dist-lib/ui/Toolbar.d.ts +29 -0
  165. package/dist-lib/ui/bufferWords.d.ts +38 -0
  166. package/dist-lib/ui/buttons/ButtonsBar.d.ts +21 -0
  167. package/dist-lib/ui/cmdline/CommandLineManager.d.ts +97 -0
  168. package/dist-lib/ui/cmdline/CommandLineOverlay.d.ts +8 -0
  169. package/dist-lib/ui/codemirror/theme.d.ts +5 -0
  170. package/dist-lib/ui/commandHistory.d.ts +31 -0
  171. package/dist-lib/ui/components/Button.d.ts +9 -0
  172. package/dist-lib/ui/components/ConfirmDialog.d.ts +29 -0
  173. package/dist-lib/ui/components/ContextMenu.d.ts +9 -0
  174. package/dist-lib/ui/components/FontPicker.d.ts +9 -0
  175. package/dist-lib/ui/components/FormField.d.ts +16 -0
  176. package/dist-lib/ui/components/HelpTip.d.ts +7 -0
  177. package/dist-lib/ui/components/Input.d.ts +6 -0
  178. package/dist-lib/ui/components/Toggle.d.ts +10 -0
  179. package/dist-lib/ui/components/index.d.ts +9 -0
  180. package/dist-lib/ui/components/useModalFocus.d.ts +18 -0
  181. package/dist-lib/ui/labels/LabelManager.d.ts +220 -0
  182. package/dist-lib/ui/labels/LabelOverlay.d.ts +9 -0
  183. package/dist-lib/ui/labels/backgroundImageSize.d.ts +10 -0
  184. package/dist-lib/ui/labels/cursorShapes.d.ts +6 -0
  185. package/dist-lib/ui/labels/gifMovie.d.ts +100 -0
  186. package/dist-lib/ui/labels/qtCss.d.ts +57 -0
  187. package/dist-lib/ui/layout/ContentLayout.d.ts +19 -0
  188. package/dist-lib/ui/layout/DockArea.d.ts +14 -0
  189. package/dist-lib/ui/layout/DockedPanel.d.ts +13 -0
  190. package/dist-lib/ui/layout/FloatingWindowLayer.d.ts +10 -0
  191. package/dist-lib/ui/layout/MobileLayout.d.ts +22 -0
  192. package/dist-lib/ui/layout/PopoutWindow.d.ts +35 -0
  193. package/dist-lib/ui/layout/ScriptWindow.d.ts +29 -0
  194. package/dist-lib/ui/layout/SplitGroupPanel.d.ts +17 -0
  195. package/dist-lib/ui/layout/TabGroupPanel.d.ts +12 -0
  196. package/dist-lib/ui/layout/WindowContextMenu.d.ts +11 -0
  197. package/dist-lib/ui/layout/dockDetect.d.ts +26 -0
  198. package/dist-lib/ui/layout/overlayLayerOrder.d.ts +71 -0
  199. package/dist-lib/ui/markdown.d.ts +1 -0
  200. package/dist-lib/ui/output/CaretReviewPanel.d.ts +22 -0
  201. package/dist-lib/ui/output/OutputArea.d.ts +9 -0
  202. package/dist-lib/ui/output/OutputContextMenu.d.ts +23 -0
  203. package/dist-lib/ui/output/OutputRenderer.d.ts +64 -0
  204. package/dist-lib/ui/output/ScreenReaderLog.d.ts +23 -0
  205. package/dist-lib/ui/output/StickyOutputPanel.d.ts +28 -0
  206. package/dist-lib/ui/output/backgroundImageStyle.d.ts +17 -0
  207. package/dist-lib/ui/output/caretMode.d.ts +40 -0
  208. package/dist-lib/ui/output/linkNavigation.d.ts +29 -0
  209. package/dist-lib/ui/output/osc8Menu.d.ts +16 -0
  210. package/dist-lib/ui/output/outputCopy.d.ts +15 -0
  211. package/dist-lib/ui/preventPinchZoom.d.ts +1 -0
  212. package/dist-lib/ui/scrollbox/ScrollBoxManager.d.ts +62 -0
  213. package/dist-lib/ui/scrollbox/ScrollBoxOverlay.d.ts +25 -0
  214. package/dist-lib/ui/sound/SoundManager.d.ts +149 -0
  215. package/dist-lib/ui/sound/closedCaption.d.ts +37 -0
  216. package/dist-lib/ui/textedit/TextEditManager.d.ts +56 -0
  217. package/dist-lib/ui/tts/TtsManager.d.ts +68 -0
  218. package/dist-lib/ui/useBrandLogin.d.ts +19 -0
  219. package/dist-lib/ui/useCommandHistory.d.ts +7 -0
  220. package/dist-lib/ui/video/VideoManager.d.ts +56 -0
  221. package/dist-lib/ui/windows/ScriptEditorModal.d.ts +13 -0
  222. package/dist-lib/ui/windows/WindowManager.d.ts +694 -0
  223. package/dist-lib/ui/windows/panels/HtmlPanel.d.ts +27 -0
  224. package/dist-lib/ui/windows/panels/LuaEditor.d.ts +14 -0
  225. package/dist-lib/ui/windows/panels/MapPanel.d.ts +8 -0
  226. package/dist-lib/ui/windows/panels/PackageRepositoryModal.d.ts +18 -0
  227. package/dist-lib/ui/windows/panels/ScriptEditorPanel.d.ts +24 -0
  228. package/dist-lib/ui/windows/panels/ScriptSearch.d.ts +12 -0
  229. package/dist-lib/ui/windows/panels/TextPanel.d.ts +35 -0
  230. package/dist-lib/ui/windows/panels/VariablesView.d.ts +21 -0
  231. package/dist-lib/ui/windows/panels/VfsModulePickerModal.d.ts +8 -0
  232. package/dist-lib/ui/windows/panels/WindowCmdLine.d.ts +23 -0
  233. package/dist-lib/ui/windows/types.d.ts +145 -0
  234. package/dist-lib/utils/documentTitle.d.ts +33 -0
  235. package/dist-lib/utils/fontLoader.d.ts +52 -0
  236. package/dist-lib/utils/profileLock.d.ts +26 -0
  237. package/dist-lib/utils/sessionCredentials.d.ts +16 -0
  238. package/dist-lib/version.d.ts +39 -0
  239. package/dist-lib/vfs-sw.js +131 -0
  240. package/dist-lib/vite.d.ts +2 -0
  241. package/dist-lib/vite.js +154 -0
  242. package/package.json +93 -0
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Cross-tab view of which profiles are open and which are connected — backs
3
+ * Mudlet's `getProfiles()`. mudix runs one profile per browser tab, so two
4
+ * cross-tab signals are combined:
5
+ *
6
+ * - **loaded** (open & editable): every open profile holds an exclusive Web
7
+ * Lock named `mudix:profile:<id>` (see profileLock.ts). `navigator.locks
8
+ * .query()` lists held locks across all same-origin tabs, so the held
9
+ * profile locks ARE the loaded set. Authoritative and crash-safe (the browser
10
+ * auto-releases a lock when its tab closes/crashes). Polled on a slow interval
11
+ * since the query is async but `getProfiles()` is a synchronous Lua call.
12
+ *
13
+ * - **connected** (playing): not observable through Web Locks, so each tab
14
+ * announces its own live connection state over a `BroadcastChannel`. A tab
15
+ * announces on connect/disconnect and answers a `query` from a newly-opened
16
+ * tab; `bye` on teardown clears it eagerly (a crash is caught by the loaded
17
+ * set dropping). The owning tab's own state is always read live.
18
+ *
19
+ * Degrades gracefully where the platform lacks these APIs (legacy browser,
20
+ * insecure context, or the Node test environment): no Web Locks → loaded is just
21
+ * this profile; no BroadcastChannel → connected is just this profile's live
22
+ * state. That matches the old single-profile `getProfiles()` behaviour.
23
+ */
24
+ export declare class ProfilesPresence {
25
+ private readonly ownId;
26
+ /** This tab's live connected state, read whenever we announce. */
27
+ private readonly localConnected;
28
+ private channel;
29
+ private lockTimer;
30
+ /** Loaded profile ids from Web Locks (authoritative; always includes self). */
31
+ private loaded;
32
+ /** Last-announced connected state of OTHER tabs' profiles. */
33
+ private readonly remoteConnected;
34
+ constructor(ownId: string,
35
+ /** This tab's live connected state, read whenever we announce. */
36
+ localConnected: () => boolean, refreshMs?: number);
37
+ /** Broadcast this tab's current connected state to peers. Call on connect/
38
+ * disconnect. No-op without a channel. */
39
+ announce(): void;
40
+ /** Connection ids of all loaded profiles (best-effort snapshot, always
41
+ * including this profile's own id). */
42
+ loadedIds(): string[];
43
+ /** Connected state for a profile id: own → live, others → last announced
44
+ * (false when never announced). Callers gate this on `loaded` so a crashed
45
+ * tab's stale "connected" can't outlive its lock. */
46
+ isConnected(id: string): boolean;
47
+ private onMessage;
48
+ private refreshLoaded;
49
+ destroy(): void;
50
+ }
@@ -0,0 +1,62 @@
1
+ export type VFSSource = 'folder' | 'idb';
2
+ export declare class ProfileVFS {
3
+ readonly connectionId: string;
4
+ readonly profilePath: string;
5
+ private _cwd;
6
+ private _fs;
7
+ private _handle?;
8
+ readonly source: VFSSource;
9
+ readonly folderName?: string;
10
+ private constructor();
11
+ static mount(connectionId: string): Promise<ProfileVFS>;
12
+ private static doMount;
13
+ get cwd(): string;
14
+ resolvePath(path: string): string;
15
+ exists(path: string): boolean;
16
+ readFile(path: string): string;
17
+ readBinaryFile(path: string): Uint8Array;
18
+ writeFile(path: string, content: string): void;
19
+ writeBinaryFile(path: string, data: Uint8Array): void;
20
+ /**
21
+ * The linked-folder (WebAccess / FileSystemDirectoryHandle) backend overwrites
22
+ * a file from offset 0 but does NOT shrink it, so writing shorter content over
23
+ * longer leaves stale tail bytes — silently corrupting Lua `table.save` data,
24
+ * JSON, and the profile XML. Removing the file first forces a fresh,
25
+ * correctly-sized write. IndexedDB truncates on the `w` flag correctly, so it's
26
+ * left untouched (no extra op per save).
27
+ */
28
+ private clearForOverwrite;
29
+ appendFile(path: string, content: string): void;
30
+ deleteFile(path: string): void;
31
+ rename(oldPath: string, newPath: string): void;
32
+ mkdir(path: string): void;
33
+ rmdir(path: string): void;
34
+ readdir(path: string): string[];
35
+ stat(path: string): {
36
+ type: 'file' | 'dir';
37
+ size: number;
38
+ mtime: Date;
39
+ atime: Date;
40
+ } | null;
41
+ chdir(path: string): string | null;
42
+ /**
43
+ * Drain queued async writes to the underlying backend. For folder-backed
44
+ * mounts this writes RAM-cached changes through to disk; for IDB mounts
45
+ * it persists to IndexedDB. Safe to call on any source.
46
+ */
47
+ flush(): Promise<void>;
48
+ /**
49
+ * Re-walk the linked directory and rebuild the in-memory cache. Use after
50
+ * external edits (file added/changed in the OS file manager). No-op for
51
+ * IDB-backed profiles since their state is owned by the browser.
52
+ *
53
+ * Any Lua file handles opened before resync become invalid: ZenFS replaces
54
+ * the underlying FS instance, so subsequent reads on those handles will
55
+ * error. New `io.open` calls work normally.
56
+ */
57
+ resync(): Promise<void>;
58
+ /** Tell the VFS service worker to drop its cached copy of a file, keyed
59
+ * by its path relative to the profile root (matches vfsUrlFor's scheme). */
60
+ private invalidate;
61
+ unmount(): void;
62
+ }
@@ -0,0 +1,21 @@
1
+ import type { ProfileVFS } from './ProfileVFS';
2
+ /**
3
+ * Map one asset reference onto the URL the service worker serves, or return
4
+ * null when it must be left alone (empty, or already an absolute http/data/
5
+ * blob/__vfs URL). Paths are resolved through the VFS (honouring its cwd and
6
+ * profile root) and rebased onto the profile root.
7
+ *
8
+ * Shared by the stylesheet rewriter and the label-HTML rewriter so `url(...)`
9
+ * in a stylesheet and `<img src>` in label rich text resolve identically.
10
+ */
11
+ export declare function vfsRefToUrl(ref: string, connectionId: string, vfs: ProfileVFS): string | null;
12
+ /**
13
+ * Rewrite `url(<local-path>)` references in a Qt/CSS stylesheet to
14
+ * `url(/__vfs/<connectionId>/<path>)` so the registered service worker can
15
+ * serve the bytes from the connection's ProfileVFS. Already-absolute http/data/
16
+ * blob/__vfs URLs pass through untouched.
17
+ *
18
+ * Paths are resolved through the VFS (which honours its cwd and profile root)
19
+ * and rebased onto the profile root before being put into the URL.
20
+ */
21
+ export declare function rewriteVfsUrlsInCss(css: string, connectionId: string, vfs: ProfileVFS): string;
@@ -0,0 +1,16 @@
1
+ interface ShowDirectoryPickerOptions {
2
+ mode?: 'read' | 'readwrite';
3
+ }
4
+ declare global {
5
+ interface Window {
6
+ showDirectoryPicker?: (options?: ShowDirectoryPickerOptions) => Promise<FileSystemDirectoryHandle>;
7
+ }
8
+ }
9
+ export type FolderPermissionState = 'granted' | 'prompt' | 'denied' | 'unsupported';
10
+ export declare function isFolderLinkSupported(): boolean;
11
+ export declare function saveFolderHandle(connectionId: string, handle: FileSystemDirectoryHandle): Promise<void>;
12
+ export declare function loadFolderHandle(connectionId: string): Promise<FileSystemDirectoryHandle | null>;
13
+ export declare function clearFolderHandle(connectionId: string): Promise<void>;
14
+ export declare function checkFolderPermission(handle: FileSystemDirectoryHandle): Promise<FolderPermissionState>;
15
+ export declare function requestFolderPermission(handle: FileSystemDirectoryHandle): Promise<FolderPermissionState>;
16
+ export {};
@@ -0,0 +1,59 @@
1
+ import { readFileSync, statSync } from '@zenfs/core';
2
+ import type { ProfileVFS } from './ProfileVFS';
3
+ export type SideKind = 'local' | 'folder';
4
+ export interface FileEntry {
5
+ /** Relative path from the profile root, e.g. "scripts/foo.lua". No leading slash. */
6
+ path: string;
7
+ size: number;
8
+ mtimeMs: number;
9
+ }
10
+ export interface DiffResult {
11
+ /** Files present only in the local (IDB) side. */
12
+ onlyLocal: FileEntry[];
13
+ /** Files present only in the linked folder. */
14
+ onlyFolder: FileEntry[];
15
+ /** Files at the same path on both sides (need user resolution). */
16
+ conflicts: {
17
+ path: string;
18
+ local: FileEntry;
19
+ folder: FileEntry;
20
+ }[];
21
+ }
22
+ export declare function walkFolderHandle(root: FileSystemDirectoryHandle): Promise<FileEntry[]>;
23
+ /** Walk every file under the mounted profile, returning paths relative to the profile root. */
24
+ export declare function walkVfsTree(vfs: ProfileVFS): FileEntry[];
25
+ /**
26
+ * A file is considered "conflicting" if it exists at the same relative path on
27
+ * both sides, regardless of whether the bytes match. Comparing mtime/size is
28
+ * unreliable across filesystems (folder-backed mtime comes from disk,
29
+ * IDB-backed mtime comes from the inode index), so we let the user resolve.
30
+ */
31
+ export declare function diffSides(local: FileEntry[], folder: FileEntry[]): DiffResult;
32
+ /**
33
+ * Copy the listed relative paths from the mounted profile into the linked
34
+ * folder. Used on link to materialize IDB-only files (and "use local"
35
+ * resolutions) before the next mount picks up the folder as the source.
36
+ */
37
+ export declare function copyVfsToFolder(vfs: ProfileVFS, handle: FileSystemDirectoryHandle, relPaths: string[]): Promise<{
38
+ copied: number;
39
+ failed: {
40
+ path: string;
41
+ reason: string;
42
+ }[];
43
+ }>;
44
+ /**
45
+ * Side-mount a fresh IDB backend for the given connection at a temporary
46
+ * profile path, copy every file from the linked folder into it, then unmount.
47
+ * Used on unlink so the user's next mount (now IDB-backed because the handle
48
+ * is cleared) sees the folder's content. Idempotent: any prior data in the
49
+ * IDB store gets overwritten when paths collide.
50
+ */
51
+ export declare function copyFolderToIdb(handle: FileSystemDirectoryHandle, connectionId: string): Promise<{
52
+ copied: number;
53
+ failed: {
54
+ path: string;
55
+ reason: string;
56
+ }[];
57
+ }>;
58
+ export declare function hasAnyFile(entries: FileEntry[]): boolean;
59
+ export { readFileSync, statSync };
@@ -0,0 +1,26 @@
1
+ import type { ProfileVFS } from './ProfileVFS';
2
+ /**
3
+ * Rewrite profile-local asset references in Lua-supplied HTML to the
4
+ * `/__vfs/<connectionId>/<path>` URLs the service worker serves.
5
+ *
6
+ * Mudlet renders `echo(labelName, html)` as Qt rich text, where
7
+ * `<img src="/home/user/.config/mudlet/profiles/X/pkg/icon.png">` loads straight
8
+ * off the local filesystem. In the browser there is no such filesystem — the
9
+ * bytes live in the profile's ProfileVFS, reachable only through the service
10
+ * worker — so those paths have to be rebased or the images silently 404 (on a
11
+ * dev server they resolve to the SPA fallback `index.html`, which decodes as a
12
+ * broken image).
13
+ *
14
+ * Two kinds of reference are rewritten:
15
+ * - `src` attributes (`<img>`, and anything else Qt resolves as a resource)
16
+ * - `url(...)` refs inside an inline `style` attribute, via the same
17
+ * stylesheet rewriter used for setLabelStyleSheet
18
+ *
19
+ * `href` is deliberately left alone: label links are navigation targets
20
+ * (openUrl / setLinkStyle), not embedded resources, and rewriting them would
21
+ * turn an anchor into a VFS fetch.
22
+ *
23
+ * Absolute http(s)/data:/blob:/already-`__vfs` references pass through
24
+ * untouched, as do paths when no VFS is mounted.
25
+ */
26
+ export declare function rewriteVfsUrlsInHtml(html: string, connectionId: string, vfs: ProfileVFS): string;
@@ -0,0 +1,16 @@
1
+ import type { ProfileVFS } from './ProfileVFS';
2
+ export declare function vfsUrlPrefix(): string;
3
+ /** Register a mounted profile so the service worker can read its files. */
4
+ export declare function registerVfs(connectionId: string, vfs: ProfileVFS): void;
5
+ /** Drop the mapping and clear cached responses for this connection. */
6
+ export declare function unregisterVfs(connectionId: string): void;
7
+ /** Tell the SW to drop one cached file (call after writes). */
8
+ export declare function invalidateVfsPath(connectionId: string, path: string): void;
9
+ /** Build a URL the SW will resolve to bytes from `vfs.readBinaryFile(path)`. */
10
+ export declare function vfsUrlFor(connectionId: string, path: string): string;
11
+ /**
12
+ * Register the service worker and wait until it controls this page. Safe to
13
+ * call multiple times; resolves to false if the browser doesn't support SWs
14
+ * or registration failed.
15
+ */
16
+ export declare function registerVfsServiceWorker(): Promise<boolean>;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Minimal Cloudflare API client for the proxy-deploy wizard.
3
+ *
4
+ * The wizard uses the user's API token to:
5
+ * 1. List accounts the token has access to (verifyToken / listAccounts)
6
+ * 2. Upload the proxy worker script (deployWorker)
7
+ * 3. Enable the *.workers.dev route on it (enableWorkersDevRoute)
8
+ * 4. Look up the account's workers.dev subdomain (getWorkersSubdomain)
9
+ *
10
+ * Cloudflare's API rejects cross-origin browser requests, so every call is
11
+ * tunneled through a relay Worker's HTTP-forward mode (`?url=<target>`). The
12
+ * relay adds CORS headers and strips Origin/Referer/Cookie before forwarding;
13
+ * the Authorization header is preserved.
14
+ *
15
+ * The token never leaves component state — it's consumed once per deploy and
16
+ * never persisted.
17
+ */
18
+ export interface CloudflareAccount {
19
+ id: string;
20
+ name: string;
21
+ }
22
+ export declare class CloudflareApiError extends Error {
23
+ readonly status: number;
24
+ readonly cfErrors?: {
25
+ code: number;
26
+ message: string;
27
+ }[];
28
+ constructor(message: string, status: number, cfErrors?: {
29
+ code: number;
30
+ message: string;
31
+ }[]);
32
+ }
33
+ /**
34
+ * Lists accounts visible to the token. Doubles as a token-validity check:
35
+ * an invalid token returns a Cloudflare error envelope which we surface.
36
+ */
37
+ export declare function listAccounts(token: string, proxyBase?: string): Promise<CloudflareAccount[]>;
38
+ /**
39
+ * Uploads a Worker script via the multipart "modules" format. The script is
40
+ * sent as an ES module so `import { connect } from 'cloudflare:sockets'` works.
41
+ */
42
+ export declare function deployWorker(token: string, accountId: string, scriptName: string, scriptSource: string, proxyBase?: string): Promise<void>;
43
+ /**
44
+ * Enables (or disables) the auto-assigned *.workers.dev route for a script.
45
+ * Without this the script is uploaded but not reachable.
46
+ */
47
+ export declare function enableWorkersDevRoute(token: string, accountId: string, scriptName: string, proxyBase?: string): Promise<void>;
48
+ /**
49
+ * Returns the account's workers.dev subdomain (e.g. "yourname" → "*.yourname.workers.dev").
50
+ * If the user has never created one, the API returns an empty string and the
51
+ * wizard surfaces a friendlier error.
52
+ */
53
+ export declare function getWorkersSubdomain(token: string, accountId: string, proxyBase?: string): Promise<string>;
54
+ export declare function buildWorkerWssUrl(scriptName: string, subdomain: string): string;
@@ -0,0 +1,132 @@
1
+ import { type AppSchema, type MudConnection, type AliasNode, type ButtonNode, type KeyNode, type TimerNode, type TriggerNode, type ScriptNode, type ScriptEditorBounds, type ModalBounds, type ClientSettings, type ProfileSettings, type PackageManifest, type WindowLayoutSnapshot, type ProfileVariables } from './schema';
2
+ import type { MudletVariable } from '../import/mudletVariables';
3
+ import type { MudletImportResult } from '../import/mudletXmlImport';
4
+ import type { WindowOpenOptions } from '../ui/windows/types';
5
+ interface AppStore extends AppSchema {
6
+ /** Adds a connection and returns its newly generated id (so callers can
7
+ * immediately attach per-profile data like saved login credentials). */
8
+ addConnection: (data: Omit<MudConnection, 'id'>) => string;
9
+ updateConnection: (id: string, data: Omit<MudConnection, 'id'>) => void;
10
+ /** Partial update preserving fields the patch doesn't mention. Used for
11
+ * surgical edits (icon, login creds) that must not wipe the rest of the
12
+ * connection record. Keys set to `undefined` are removed. */
13
+ patchConnection: (id: string, patch: Partial<Omit<MudConnection, 'id'>>) => void;
14
+ removeConnection: (id: string) => void;
15
+ /** Reorder the profile list to match `orderedIds`. Ids not present in the
16
+ * list are ignored; any existing connection missing from `orderedIds` is
17
+ * appended in its current relative order (so a stale list can't drop
18
+ * profiles). Backs drag-to-rearrange on the connection screen. */
19
+ reorderConnections: (orderedIds: string[]) => void;
20
+ patchClient: (patch: Partial<ClientSettings>) => void;
21
+ patchConnectionProfile: (connectionId: string, patch: Partial<ProfileSettings>) => void;
22
+ saveWindowHint: (connectionId: string, panelId: string, hint: WindowOpenOptions) => void;
23
+ clearWindowHints: (connectionId: string) => void;
24
+ saveDockExtents: (connectionId: string, extents: Record<string, number>) => void;
25
+ saveLayoutSnapshot: (connectionId: string, snapshot: WindowLayoutSnapshot) => void;
26
+ /** Replace the set of global names flagged to persist (Mudlet save-list).
27
+ * Edited from the Variables view; triggers a profile-data save. */
28
+ setVariableSaveList: (connectionId: string, saveList: string[]) => void;
29
+ /** Replace the captured variable values without disturbing the save-list
30
+ * reference — so the engine can refresh them on save without re-triggering
31
+ * the save subscription (which keys on the save-list, not values). */
32
+ setVariableValues: (connectionId: string, values: MudletVariable[]) => void;
33
+ addScript: (connectionId: string, data: Omit<ScriptNode, 'id'>) => string;
34
+ updateScript: (connectionId: string, id: string, patch: Partial<Omit<ScriptNode, 'id'>>) => void;
35
+ removeScript: (connectionId: string, id: string) => void;
36
+ addAlias: (connectionId: string, data: Omit<AliasNode, 'id'>) => string;
37
+ updateAlias: (connectionId: string, id: string, patch: Partial<Omit<AliasNode, 'id'>>) => void;
38
+ updateAliases: (connectionId: string, patches: ReadonlyArray<{
39
+ id: string;
40
+ patch: Partial<Omit<AliasNode, 'id'>>;
41
+ }>) => void;
42
+ removeAlias: (connectionId: string, id: string) => void;
43
+ addTrigger: (connectionId: string, data: Omit<TriggerNode, 'id'>) => string;
44
+ updateTrigger: (connectionId: string, id: string, patch: Partial<Omit<TriggerNode, 'id'>>) => void;
45
+ /** Bulk apply enabled/disabled (or any partial) to many triggers in one set(). */
46
+ updateTriggers: (connectionId: string, patches: ReadonlyArray<{
47
+ id: string;
48
+ patch: Partial<Omit<TriggerNode, 'id'>>;
49
+ }>) => void;
50
+ removeTrigger: (connectionId: string, id: string) => void;
51
+ removeTriggers: (connectionId: string, ids: ReadonlyArray<string>) => void;
52
+ addTimer: (connectionId: string, data: Omit<TimerNode, 'id'>) => string;
53
+ updateTimer: (connectionId: string, id: string, patch: Partial<Omit<TimerNode, 'id'>>) => void;
54
+ updateTimers: (connectionId: string, patches: ReadonlyArray<{
55
+ id: string;
56
+ patch: Partial<Omit<TimerNode, 'id'>>;
57
+ }>) => void;
58
+ removeTimer: (connectionId: string, id: string) => void;
59
+ removeTimers: (connectionId: string, ids: ReadonlyArray<string>) => void;
60
+ removeAliases: (connectionId: string, ids: ReadonlyArray<string>) => void;
61
+ addKeybinding: (connectionId: string, data: Omit<KeyNode, 'id'>) => string;
62
+ updateKeybinding: (connectionId: string, id: string, patch: Partial<Omit<KeyNode, 'id'>>) => void;
63
+ removeKeybinding: (connectionId: string, id: string) => void;
64
+ removeKeybindings: (connectionId: string, ids: ReadonlyArray<string>) => void;
65
+ addButton: (connectionId: string, data: Omit<ButtonNode, 'id'>) => string;
66
+ updateButton: (connectionId: string, id: string, patch: Partial<Omit<ButtonNode, 'id'>>) => void;
67
+ removeButton: (connectionId: string, id: string) => void;
68
+ moveScript: (connectionId: string, id: string, newParentId: string | null, insertBeforeId: string | null) => void;
69
+ moveAlias: (connectionId: string, id: string, newParentId: string | null, insertBeforeId: string | null) => void;
70
+ moveTrigger: (connectionId: string, id: string, newParentId: string | null, insertBeforeId: string | null) => void;
71
+ moveTimer: (connectionId: string, id: string, newParentId: string | null, insertBeforeId: string | null) => void;
72
+ moveKeybinding: (connectionId: string, id: string, newParentId: string | null, insertBeforeId: string | null) => void;
73
+ moveButton: (connectionId: string, id: string, newParentId: string | null, insertBeforeId: string | null) => void;
74
+ saveScriptEditorBounds: (connectionId: string, bounds: ScriptEditorBounds) => void;
75
+ saveModalBounds: (connectionId: string, key: string, bounds: ModalBounds) => void;
76
+ installPackage: (connectionId: string, manifest: PackageManifest, data: MudletImportResult) => void;
77
+ uninstallPackage: (connectionId: string, packageName: string) => void;
78
+ updatePackageManifest: (connectionId: string, packageName: string, patch: Partial<Omit<PackageManifest, 'name'>>) => void;
79
+ /** Replace the VFS-persisted automation slices for one connection in a single
80
+ * set(). Called once on profile open, after its VFS mounts, to seed the
81
+ * store from `.mudix/profile.json`. Missing keys reset to empty arrays. */
82
+ hydrateConnectionData: (connectionId: string, data: PersistedConnectionData) => void;
83
+ }
84
+ /** The per-connection slices persisted in the profile VFS (see profileVfsData.ts). */
85
+ interface PersistedConnectionData {
86
+ scripts?: ScriptNode[];
87
+ aliases?: AliasNode[];
88
+ triggers?: TriggerNode[];
89
+ timers?: TimerNode[];
90
+ keybindings?: KeyNode[];
91
+ buttons?: ButtonNode[];
92
+ packages?: PackageManifest[];
93
+ profile?: Partial<ProfileSettings>;
94
+ windowHints?: Record<string, WindowOpenOptions>;
95
+ dockExtents?: Record<string, number>;
96
+ scriptEditorBounds?: ScriptEditorBounds;
97
+ modalBounds?: Record<string, ModalBounds>;
98
+ layoutSnapshot?: WindowLayoutSnapshot;
99
+ variables?: ProfileVariables;
100
+ }
101
+ /** localStorage key + schema version for the persisted store. Exported so the
102
+ * cross-tab sync (crossTabSync.ts) can match `storage` events to this store and
103
+ * reject writes from a different schema version. */
104
+ export declare const MUDIX_STORE_NAME = "mudix_v1";
105
+ export declare const MUDIX_STORE_VERSION = 21;
106
+ /** One-time localStorage key holding pre-v21 per-profile UI/layout/settings
107
+ * slices, stashed by the v21 migration so they can be moved into each profile's
108
+ * VFS (.mudix/profile.json) the first time it's opened. Kept separate from the
109
+ * persisted store blob so editing the connections list (which rewrites the
110
+ * blob) can't drop un-migrated profiles' data. Consumed per-profile by
111
+ * loadProfileData, then removed when empty. */
112
+ export declare const MIGRATION_BACKUP_KEY = "mudix_profile_migration_v21";
113
+ export declare const useAppStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<AppStore>, "setState" | "persist"> & {
114
+ setState(partial: AppStore | Partial<AppStore> | ((state: AppStore) => AppStore | Partial<AppStore>), replace?: false | undefined): unknown;
115
+ setState(state: AppStore | ((state: AppStore) => AppStore), replace: true): unknown;
116
+ persist: {
117
+ setOptions: (options: Partial<import("zustand/middleware").PersistOptions<AppStore, {
118
+ connections: MudConnection[];
119
+ client: ClientSettings;
120
+ }, unknown>>) => void;
121
+ clearStorage: () => void;
122
+ rehydrate: () => Promise<void> | void;
123
+ hasHydrated: () => boolean;
124
+ onHydrate: (fn: (state: AppStore) => void) => () => void;
125
+ onFinishHydration: (fn: (state: AppStore) => void) => () => void;
126
+ getOptions: () => Partial<import("zustand/middleware").PersistOptions<AppStore, {
127
+ connections: MudConnection[];
128
+ client: ClientSettings;
129
+ }, unknown>>;
130
+ };
131
+ }>;
132
+ export {};
@@ -0,0 +1,3 @@
1
+ /** Begin listening for other tabs' persisted-store writes and merging them in.
2
+ * Idempotent; safe to call more than once (e.g. across HMR reloads). */
3
+ export declare function initCrossTabSync(): void;
@@ -0,0 +1,18 @@
1
+ import type { PersistStorage } from 'zustand/middleware';
2
+ /**
3
+ * Zustand PersistStorage adapter that coalesces rapid mutations into a single
4
+ * write — *including* the JSON serialization step.
5
+ *
6
+ * Using `createJSONStorage` over a debounced Web-Storage wrapper only collapses
7
+ * the localStorage.setItem call; zustand still runs `JSON.stringify(state)`
8
+ * before each setItem, so N mutations cost N full serializations of the
9
+ * persisted blob (scripts, triggers, packages, …). Implementing PersistStorage
10
+ * directly lets us hold the unserialized object and stringify exactly once,
11
+ * at flush time.
12
+ *
13
+ * The latest pending value is flushed synchronously on `pagehide`,
14
+ * `visibilitychange→hidden`, and `beforeunload` so a tab close right after a
15
+ * mutation doesn't lose state. `getItem` honours an in-flight pending value so
16
+ * the adapter is internally consistent even mid-debounce.
17
+ */
18
+ export declare function createDebouncedJsonStorage<S>(delayMs: number): PersistStorage<S>;
@@ -0,0 +1,17 @@
1
+ import { type ClientSettings, type ProfileSettings, type Theme } from './schema';
2
+ /**
3
+ * Active profile id, provided by ProfileSession. `null` outside a profile
4
+ * (e.g. on the connection screen) — settings consumers fall through to
5
+ * PROFILE_DEFAULTS in that case.
6
+ */
7
+ export declare const ConnectionIdContext: import("react").Context<string | null>;
8
+ export declare function useConnectionId(): string | null;
9
+ /** Read one ProfileSettings field for the active profile (from context). */
10
+ export declare function useProfileField<K extends keyof ProfileSettings>(key: K): ProfileSettings[K];
11
+ /** Read one ClientSettings field. */
12
+ export declare function useClientField<K extends keyof ClientSettings>(key: K): ClientSettings[K];
13
+ /** The theme actually in effect: the active profile's override if it has one,
14
+ * else the launcher theme. Use anywhere a profile-scoped component needs the
15
+ * current theme (e.g. CodeMirror editors). Outside a profile (no context) it
16
+ * resolves to the launcher theme. */
17
+ export declare function useEffectiveTheme(): Theme;
@@ -0,0 +1,4 @@
1
+ export { type AppSchema, type MudConnection, type ConnectionMode, type ClientSettings, type ProfileSettings, type MapperSettings, type MapInfoBgColor, type ProtocolSettings, type BooleanProtocolKey, type Theme, type OutputFontSource, APP_DEFAULTS, PROFILE_DEFAULTS, MAPPER_DEFAULTS, MAP_INFO_BG_DEFAULT, PROTOCOL_DEFAULTS, WS_SUBPROTOCOL_CHOICES, DEFAULT_PROXY_URL, connectionUrl, connectionDisplayAddr, connectionSecureTransport, selectProfileField } from './schema';
2
+ export { useAppStore } from './appStore';
3
+ export { initCrossTabSync } from './crossTabSync';
4
+ export { ConnectionIdContext, useConnectionId, useProfileField, useClientField, useEffectiveTheme } from './hooks';
@@ -0,0 +1,32 @@
1
+ import { type LogEntry, type LogSession } from './logStorage';
2
+ /** `YYYY-MM-DD HH-MM-SS`, safe for filenames. */
3
+ export declare function formatSessionFileStamp(ts: number): string;
4
+ /** `HH:MM:SS` for per-line timestamps. */
5
+ export declare function formatTime(ts: number): string;
6
+ /** `YYYY-MM-DD HH:MM:SS` for session labels. */
7
+ export declare function formatDateTime(ts: number): string;
8
+ /** A standalone, self-contained HTML document for one session. */
9
+ export declare function buildSessionHtml(session: LogSession, entries: LogEntry[]): string;
10
+ /** Trigger a browser download for an in-memory blob. */
11
+ export declare function downloadBlob(filename: string, blob: Blob): void;
12
+ /** Download one session as a standalone `.html` file. */
13
+ export declare function exportSessionHtml(session: LogSession): Promise<void>;
14
+ /** Bundle several sessions into one `.zip`, one HTML file per session. */
15
+ export declare function exportSessionsZip(sessions: LogSession[]): Promise<void>;
16
+ /** Shape of the JSON export/import payload. */
17
+ export interface LogExportJson {
18
+ version: 1;
19
+ exportedAt: number;
20
+ sessions: Array<{
21
+ session: LogSession;
22
+ entries: LogEntry[];
23
+ }>;
24
+ }
25
+ /** Export sessions (with their entries) to a `.json` file. */
26
+ export declare function exportSessionsJson(sessions: LogSession[]): Promise<void>;
27
+ /**
28
+ * Import a previously exported JSON payload. Each session is re-keyed with a
29
+ * fresh id so re-importing never clobbers an existing session, and entry rows
30
+ * drop their old auto-increment ids. Returns the number of sessions imported.
31
+ */
32
+ export declare function importSessionsJson(text: string): Promise<number>;
@@ -0,0 +1,45 @@
1
+ /** One recorded gameplay session (a single profile open). */
2
+ export interface LogSession {
3
+ /** UUID; also the foreign key on every {@link LogEntry}. */
4
+ id: string;
5
+ connectionId: string;
6
+ /** Display name captured at record time, so the browser can label the
7
+ * session even after the connection is renamed or deleted. */
8
+ connectionName: string;
9
+ startedAt: number;
10
+ /** Updated on every flush; the wall-clock time of the last logged line. */
11
+ endedAt: number;
12
+ entryCount: number;
13
+ }
14
+ /** One captured output line. `html` is the styled, HTML-escaped render
15
+ * (snapshotted at emit time); `plain` is the unstyled text used for search. */
16
+ export interface LogEntry {
17
+ /** Auto-increment key, assigned by IndexedDB on insert. */
18
+ id?: number;
19
+ sessionId: string;
20
+ /** Monotonic ordering within the session (guards against equal timestamps). */
21
+ seq: number;
22
+ timestamp: number;
23
+ /** Mirrors the `message` event type: 'mud' | 'echo' | 'script' | 'info' | … */
24
+ type: string;
25
+ html: string;
26
+ plain: string;
27
+ }
28
+ /** Insert a session record (call once, on the first flush that has entries). */
29
+ export declare function createSession(session: LogSession): Promise<void>;
30
+ /** Merge a partial update into an existing session record (endedAt/entryCount). */
31
+ export declare function updateSession(id: string, patch: Partial<LogSession>): Promise<void>;
32
+ /** Append a batch of entries in a single transaction. */
33
+ export declare function appendEntries(entries: LogEntry[]): Promise<void>;
34
+ /** All sessions, newest first. Optionally filtered to one connection. */
35
+ export declare function listSessions(connectionId?: string): Promise<LogSession[]>;
36
+ /** All entries for a session, in capture order. */
37
+ export declare function getSessionEntries(sessionId: string): Promise<LogEntry[]>;
38
+ /** Delete a session and every entry that belongs to it. */
39
+ export declare function deleteSession(id: string): Promise<void>;
40
+ /** Delete several sessions (and their entries). */
41
+ export declare function deleteSessions(ids: string[]): Promise<void>;
42
+ /** Remove every log for a connection — called when the connection is deleted. */
43
+ export declare function deleteSessionsForConnection(connectionId: string): Promise<void>;
44
+ /** Wipe all recorded logs across every connection. */
45
+ export declare function clearAllLogs(): Promise<void>;
@@ -0,0 +1,2 @@
1
+ export declare function saveMap(connectionId: string, data: ArrayBuffer): Promise<void>;
2
+ export declare function loadMap(connectionId: string): Promise<ArrayBuffer | null>;
@@ -0,0 +1,47 @@
1
+ import type { ScriptNode, AliasNode, TriggerNode, TimerNode, KeyNode, ButtonNode, PackageManifest, ProfileSettings, ScriptEditorBounds, ModalBounds, WindowLayoutSnapshot, ProfileVariables } from './schema';
2
+ import type { WindowOpenOptions } from '../ui/windows/types';
3
+ import type { ProfileVFS } from '../scripting/vfs/ProfileVFS';
4
+ /**
5
+ * Per-profile data is stored inside that profile's own VFS rather than the
6
+ * shared localStorage blob — see the design notes in CLAUDE.md / the storage
7
+ * layer. One JSON file per profile holds the bulky tree data (scripts, aliases,
8
+ * triggers, …) AND the per-profile UI/settings/layout slices, so the only
9
+ * per-profile state left in localStorage is the connection record itself. That
10
+ * makes each profile single-writer (one tab owns it via the cross-tab lock),
11
+ * eliminating the multi-tab clobber the shared blob suffered.
12
+ *
13
+ * The file is dot-prefixed so it stays out of the way in the user-browsable
14
+ * file area. `ProfileVFS.writeFile` creates the `.mudix/` parent dir for us.
15
+ */
16
+ export declare const PROFILE_DATA_PATH = ".mudix/profile.json";
17
+ export interface PersistedProfileData {
18
+ version: number;
19
+ scripts: ScriptNode[];
20
+ aliases: AliasNode[];
21
+ triggers: TriggerNode[];
22
+ timers: TimerNode[];
23
+ keybindings: KeyNode[];
24
+ buttons: ButtonNode[];
25
+ packages: PackageManifest[];
26
+ /** Mudlet saved-variables: the save-list + last captured values. Optional so
27
+ * older files (no variables) still parse. */
28
+ variables?: ProfileVariables;
29
+ profile?: Partial<ProfileSettings>;
30
+ windowHints?: Record<string, WindowOpenOptions>;
31
+ dockExtents?: Record<string, number>;
32
+ scriptEditorBounds?: ScriptEditorBounds;
33
+ modalBounds?: Record<string, ModalBounds>;
34
+ layoutSnapshot?: WindowLayoutSnapshot;
35
+ }
36
+ /**
37
+ * Read `.mudix/profile.json` from the profile VFS and push it into the store
38
+ * for `connectionId`. Also completes the one-time v21 migration: if this
39
+ * profile's UI/settings/layout slices haven't moved into the VFS yet, they're
40
+ * pulled from the migration backup, hydrated, written to the VFS, and dropped
41
+ * from the backup. No-op for a fresh profile with nothing to load.
42
+ */
43
+ export declare function loadProfileData(vfs: ProfileVFS, connectionId: string): void;
44
+ /** Serialize a profile's automation + UI slices for `connectionId` from the store. */
45
+ export declare function serializeProfileData(connectionId: string): string;
46
+ /** Write the current store state for `connectionId` to the profile VFS. */
47
+ export declare function saveProfileData(vfs: ProfileVFS, connectionId: string): void;