@mudlet/mudlet-web 0.5.0 → 1.0.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 (301) hide show
  1. package/README.md +1 -1
  2. package/dist-lib/analytics.d.ts +27 -0
  3. package/dist-lib/assets/fonts/Vera.woff2 +0 -0
  4. package/dist-lib/assets/fonts/VeraBI.woff2 +0 -0
  5. package/dist-lib/assets/fonts/VeraBd.woff2 +0 -0
  6. package/dist-lib/assets/fonts/VeraIt.woff2 +0 -0
  7. package/dist-lib/assets/mapParser.worker-DrVZ3wg_.js +9 -0
  8. package/dist-lib/backupImport-wt8r7JXI.js +233 -0
  9. package/dist-lib/branding.d.ts +111 -13
  10. package/dist-lib/db/sqliteClient.d.ts +195 -7
  11. package/dist-lib/hooks/useAutoReconnect.d.ts +61 -0
  12. package/dist-lib/hooks/useDocumentFullscreen.d.ts +23 -0
  13. package/dist-lib/hooks/useKeyboardShortcuts.d.ts +37 -0
  14. package/dist-lib/hooks/useRecordLastPlayed.d.ts +10 -0
  15. package/dist-lib/import/applyMudletProfile.d.ts +35 -9
  16. package/dist-lib/import/backupImport.d.ts +118 -0
  17. package/dist-lib/import/collectProfileExport.d.ts +33 -2
  18. package/dist-lib/import/defaultPackages.d.ts +57 -14
  19. package/dist-lib/import/defaults/CF-loader/CF-loader.mpackage +0 -0
  20. package/dist-lib/import/defaults/MedBootstrap/MedBootstrap.mpackage +0 -0
  21. package/dist-lib/import/defaults/deleteOldProfiles/deleteOldProfiles.mpackage +0 -0
  22. package/dist-lib/import/defaults/echo/echo.mpackage +0 -0
  23. package/dist-lib/import/defaults/enable-accessibility/enable-accessibility.mpackage +0 -0
  24. package/dist-lib/import/defaults/generic_mapper/generic_mapper.mpackage +0 -0
  25. package/dist-lib/import/defaults/gui-drop/gui-drop.mpackage +0 -0
  26. package/dist-lib/import/defaults/icesus-loader/icesus-loader.mpackage +0 -0
  27. package/dist-lib/import/defaults/mg-loader/mg-loader.mpackage +0 -0
  28. package/dist-lib/import/defaults/mudlet-base-ui/mudlet-base-ui.mpackage +0 -0
  29. package/dist-lib/import/defaults/mudlet-mapper.xml +1215 -389
  30. package/dist-lib/import/mudletControlChars.d.ts +14 -0
  31. package/dist-lib/import/mudletHost.d.ts +73 -10
  32. package/dist-lib/import/mudletLink.d.ts +53 -2
  33. package/dist-lib/import/mudletProfileExport.d.ts +38 -5
  34. package/dist-lib/import/mudletProfileImport.d.ts +110 -12
  35. package/dist-lib/import/mudletVariables.d.ts +4 -3
  36. package/dist-lib/import/mudletWriteback.d.ts +15 -1
  37. package/dist-lib/import/mudletXmlImport.d.ts +46 -0
  38. package/dist-lib/import/packageFonts.d.ts +33 -0
  39. package/dist-lib/import/packageInstaller.d.ts +111 -7
  40. package/dist-lib/import/qtProfileData.d.ts +10 -0
  41. package/dist-lib/import/remotePackageInstall.d.ts +23 -7
  42. package/dist-lib/import/zipEntries.d.ts +45 -0
  43. package/dist-lib/index.d.ts +7 -3
  44. package/dist-lib/index.js +50508 -29836
  45. package/dist-lib/logging/SessionLogger.d.ts +75 -15
  46. package/dist-lib/map/MapSelectionOverlay.d.ts +2 -2
  47. package/dist-lib/map/MapStore.d.ts +387 -60
  48. package/dist-lib/map/MudletHighlightOverlay.d.ts +2 -2
  49. package/dist-lib/map/{MudixMapReader.d.ts → MudletMapReader.d.ts} +2 -2
  50. package/dist-lib/map/areaGraph.d.ts +120 -0
  51. package/dist-lib/map/environmentKit.d.ts +36 -0
  52. package/dist-lib/map/labelPixmap.d.ts +90 -0
  53. package/dist-lib/map/mapImageExport.d.ts +36 -2
  54. package/dist-lib/map/mapStyle.d.ts +11 -0
  55. package/dist-lib/map/mapVersion.d.ts +66 -0
  56. package/dist-lib/map/pathfinding.d.ts +2 -2
  57. package/dist-lib/mud/CharLoginController.d.ts +230 -0
  58. package/dist-lib/mud/ItemIdSequence.d.ts +1 -1
  59. package/dist-lib/mud/MudSession.d.ts +279 -22
  60. package/dist-lib/mud/PatternEngine.d.ts +153 -14
  61. package/dist-lib/mud/aliases/AliasEngine.d.ts +55 -9
  62. package/dist-lib/mud/autoLogin.d.ts +59 -0
  63. package/dist-lib/mud/commandSplit.d.ts +9 -0
  64. package/dist-lib/mud/connection/LineAssembler.d.ts +38 -11
  65. package/dist-lib/mud/connection/MudClient.d.ts +291 -53
  66. package/dist-lib/mud/connection/SubnegotiationRepair.d.ts +24 -0
  67. package/dist-lib/mud/connection/TelnetNegotiator.d.ts +208 -68
  68. package/dist-lib/mud/connection/telnetDebug.d.ts +8 -8
  69. package/dist-lib/mud/events.d.ts +102 -23
  70. package/dist-lib/mud/games/bundledGames.d.ts +12 -7
  71. package/dist-lib/mud/games/gameLinks.d.ts +40 -0
  72. package/dist-lib/mud/games/icons/3Kingdoms.png +0 -0
  73. package/dist-lib/mud/games/icons/3Scapes.png +0 -0
  74. package/dist-lib/mud/games/icons/achaea.png +0 -0
  75. package/dist-lib/mud/games/icons/aetolia.png +0 -0
  76. package/dist-lib/mud/games/icons/banner_astaria.png +0 -0
  77. package/dist-lib/mud/games/icons/banner_darkmists.png +0 -0
  78. package/dist-lib/mud/games/icons/banner_dreamland.png +0 -0
  79. package/dist-lib/mud/games/icons/banner_petria.jpg +0 -0
  80. package/dist-lib/mud/games/icons/banner_ropmud.png +0 -0
  81. package/dist-lib/mud/games/icons/blackmud.png +0 -0
  82. package/dist-lib/mud/games/icons/carrionfields.png +0 -0
  83. package/dist-lib/mud/games/icons/dragonfire_icon.png +0 -0
  84. package/dist-lib/mud/games/icons/fed2-logo.png +0 -0
  85. package/dist-lib/mud/games/icons/icesus_480x120.png +0 -0
  86. package/dist-lib/mud/games/icons/imperian.png +0 -0
  87. package/dist-lib/mud/games/icons/infinity_480x120.png +0 -0
  88. package/dist-lib/mud/games/icons/lusternia.png +0 -0
  89. package/dist-lib/mud/games/icons/morgengrauen_480x120.png +0 -0
  90. package/dist-lib/mud/games/icons/mudlet-tutorial.png +0 -0
  91. package/dist-lib/mud/games/icons/phoenixmud_480x120.png +0 -0
  92. package/dist-lib/mud/games/icons/starmourn.png +0 -0
  93. package/dist-lib/mud/games/icons/voidmud_icon.png +0 -0
  94. package/dist-lib/mud/games/icons/wotmudicon.png +0 -0
  95. package/dist-lib/mud/games/websiteLinks.d.ts +21 -0
  96. package/dist-lib/mud/keybindings/KeyEngine.d.ts +110 -4
  97. package/dist-lib/mud/keybindings/browserReservedKeys.d.ts +2 -2
  98. package/dist-lib/mud/keybindings/keyEventTarget.d.ts +61 -0
  99. package/dist-lib/mud/keybindings/qtKeys.d.ts +91 -12
  100. package/dist-lib/mud/protocol/atcp.d.ts +19 -0
  101. package/dist-lib/mud/protocol/byteString.d.ts +24 -0
  102. package/dist-lib/mud/protocol/charLoginFlow.d.ts +243 -16
  103. package/dist-lib/mud/protocol/charset.d.ts +111 -46
  104. package/dist-lib/mud/protocol/codePages.d.ts +10 -0
  105. package/dist-lib/mud/protocol/constants.d.ts +17 -10
  106. package/dist-lib/mud/protocol/echo.d.ts +23 -27
  107. package/dist-lib/mud/protocol/gmcp.d.ts +36 -6
  108. package/dist-lib/mud/protocol/index.d.ts +3 -2
  109. package/dist-lib/mud/protocol/luaLiteral.d.ts +12 -0
  110. package/dist-lib/mud/protocol/mccp.d.ts +83 -1
  111. package/dist-lib/mud/protocol/mnes.d.ts +41 -58
  112. package/dist-lib/mud/protocol/msdp.d.ts +11 -4
  113. package/dist-lib/mud/protocol/msp.d.ts +3 -2
  114. package/dist-lib/mud/protocol/mssp.d.ts +9 -4
  115. package/dist-lib/mud/protocol/multiByte.d.ts +51 -0
  116. package/dist-lib/mud/protocol/multiByteEncode.d.ts +42 -0
  117. package/dist-lib/mud/protocol/mxp.d.ts +193 -14
  118. package/dist-lib/mud/protocol/oauthClientFlow.d.ts +128 -0
  119. package/dist-lib/mud/protocol/qtCodePages.generated.d.ts +1 -0
  120. package/dist-lib/mud/protocol/tlsCodes.d.ts +40 -3
  121. package/dist-lib/mud/replay/ReplayPlayer.d.ts +16 -1
  122. package/dist-lib/mud/replay/replayFormat.d.ts +29 -2
  123. package/dist-lib/mud/text/Console.d.ts +255 -49
  124. package/dist-lib/mud/text/FormatState.d.ts +137 -14
  125. package/dist-lib/mud/text/ansiEscapes.d.ts +32 -16
  126. package/dist-lib/mud/text/colorParsers.d.ts +14 -2
  127. package/dist-lib/mud/text/colorSpaceId.d.ts +2 -0
  128. package/dist-lib/mud/text/colors.d.ts +17 -10
  129. package/dist-lib/mud/text/controlCharacterMode.d.ts +1 -1
  130. package/dist-lib/mud/text/hyperlinkVisibility.d.ts +1 -1
  131. package/dist-lib/mud/text/lineBreak.d.ts +5 -0
  132. package/dist-lib/mud/text/serverWrap.d.ts +2 -2
  133. package/dist-lib/mud/text/textAnalyzer.d.ts +79 -0
  134. package/dist-lib/mud/text/unicodeRuns.d.ts +11 -0
  135. package/dist-lib/mud/text/unicodeTables.generated.d.ts +3 -0
  136. package/dist-lib/mud/text/wcwidth.d.ts +27 -22
  137. package/dist-lib/mud/timers/TimerEngine.d.ts +163 -11
  138. package/dist-lib/mud/timers/workerClock.d.ts +67 -0
  139. package/dist-lib/mud/triggers/TriggerEngine.d.ts +449 -47
  140. package/dist-lib/mud/triggers/legacyColorPatterns.d.ts +58 -0
  141. package/dist-lib/mud/triggers/pcre/Pcre2.d.ts +83 -1
  142. package/dist-lib/oauth-callback.html +94 -0
  143. package/dist-lib/pcre2Wasm.d.ts +54 -0
  144. package/dist-lib/pcre2Wasm.js +241 -0
  145. package/dist-lib/scripting/EngineHost.d.ts +45 -21
  146. package/dist-lib/scripting/IScriptingRuntime.d.ts +103 -27
  147. package/dist-lib/scripting/MxpFrameManager.d.ts +10 -1
  148. package/dist-lib/scripting/ScriptingAPI.d.ts +1030 -213
  149. package/dist-lib/scripting/ScriptingEngine.d.ts +727 -106
  150. package/dist-lib/scripting/StopwatchManager.d.ts +97 -36
  151. package/dist-lib/scripting/http/HttpService.d.ts +9 -1
  152. package/dist-lib/scripting/http/userUrl.d.ts +41 -0
  153. package/dist-lib/scripting/lua/LuaRuntime.d.ts +352 -77
  154. package/dist-lib/scripting/lua/argContracts.d.ts +71 -0
  155. package/dist-lib/scripting/lua/bindings/automation.d.ts +1 -1
  156. package/dist-lib/scripting/lua/bindings/commands.d.ts +13 -0
  157. package/dist-lib/scripting/lua/bindings/context.d.ts +20 -2
  158. package/dist-lib/scripting/lua/bindings/diagnostics.d.ts +1 -1
  159. package/dist-lib/scripting/lua/bindings/map.d.ts +1 -1
  160. package/dist-lib/scripting/lua/bindings/media.d.ts +2 -2
  161. package/dist-lib/scripting/lua/bindings/output.d.ts +1 -1
  162. package/dist-lib/scripting/lua/bindings/session.d.ts +2 -2
  163. package/dist-lib/scripting/lua/bindings/textEdit.d.ts +1 -1
  164. package/dist-lib/scripting/lua/bindings/userWindows.d.ts +1 -1
  165. package/dist-lib/scripting/lua/byteArmor.d.ts +36 -0
  166. package/dist-lib/scripting/lua/imageSize.d.ts +7 -0
  167. package/dist-lib/scripting/lua/rex.d.ts +4 -2
  168. package/dist-lib/scripting/lua/sqlRowEncoder.d.ts +6 -1
  169. package/dist-lib/scripting/lua/utf8CaseMap.d.ts +1 -0
  170. package/dist-lib/scripting/lua/utf8Patterns.d.ts +21 -1
  171. package/dist-lib/scripting/lua/wellFormedStrings.d.ts +40 -0
  172. package/dist-lib/scripting/lua/yajl.d.ts +43 -5
  173. package/dist-lib/scripting/profilesPresence.d.ts +20 -2
  174. package/dist-lib/scripting/vfs/ProfileVFS.d.ts +164 -10
  175. package/dist-lib/scripting/vfs/fsErrors.d.ts +28 -0
  176. package/dist-lib/scripting/vfs/idbCommit.d.ts +20 -0
  177. package/dist-lib/storage/appStore.d.ts +24 -9
  178. package/dist-lib/storage/hooks.d.ts +5 -1
  179. package/dist-lib/storage/index.d.ts +2 -2
  180. package/dist-lib/storage/mapStorage.d.ts +2 -0
  181. package/dist-lib/storage/persistentStorage.d.ts +3 -1
  182. package/dist-lib/storage/profileStorage.d.ts +15 -0
  183. package/dist-lib/storage/profileVfsData.d.ts +3 -3
  184. package/dist-lib/storage/schema.d.ts +512 -40
  185. package/dist-lib/storage/storageMigration.d.ts +82 -0
  186. package/dist-lib/storage-g5V1b-c1.js +2039 -0
  187. package/dist-lib/styles.css +1 -1
  188. package/dist-lib/ui/AboutModal.d.ts +1 -1
  189. package/dist-lib/ui/BrandLoginFields.d.ts +1 -1
  190. package/dist-lib/ui/BrowserSignInModal.d.ts +23 -0
  191. package/dist-lib/ui/CmdLineMenuRegistry.d.ts +14 -5
  192. package/dist-lib/ui/CommandBar.d.ts +8 -8
  193. package/dist-lib/ui/ConnectionFormModal.d.ts +20 -1
  194. package/dist-lib/ui/ConnectionScreen.d.ts +9 -1
  195. package/dist-lib/ui/GameLinkPrompt.d.ts +28 -0
  196. package/dist-lib/ui/HelpModal.d.ts +5 -1
  197. package/dist-lib/ui/MapSymbolUsageModal.d.ts +32 -0
  198. package/dist-lib/ui/MouseEventRegistry.d.ts +31 -4
  199. package/dist-lib/ui/NotepadModal.d.ts +22 -0
  200. package/dist-lib/ui/ResizableModal.d.ts +16 -1
  201. package/dist-lib/ui/SettingsModal.d.ts +10 -1
  202. package/dist-lib/ui/TlsAlertBanner.d.ts +3 -1
  203. package/dist-lib/ui/Toolbar.d.ts +22 -1
  204. package/dist-lib/ui/VaultManageButton.d.ts +10 -5
  205. package/dist-lib/ui/VaultModal.d.ts +3 -0
  206. package/dist-lib/ui/buttons/ButtonsBar.d.ts +3 -1
  207. package/dist-lib/ui/buttons/inactiveButtons.d.ts +25 -0
  208. package/dist-lib/ui/cmdline/CommandLineManager.d.ts +19 -0
  209. package/dist-lib/ui/cmdline/plainText.d.ts +16 -0
  210. package/dist-lib/ui/cmdline/subCommandLine.d.ts +78 -0
  211. package/dist-lib/ui/cmdline/useCmdLineSelection.d.ts +26 -0
  212. package/dist-lib/ui/cmdline/useSubCommandLineKeys.d.ts +33 -0
  213. package/dist-lib/ui/codemirror/lineParagraphMarks.d.ts +19 -0
  214. package/dist-lib/ui/codemirror/luaHover.d.ts +7 -0
  215. package/dist-lib/ui/codemirror/options.d.ts +33 -0
  216. package/dist-lib/ui/codemirror/theme.d.ts +29 -5
  217. package/dist-lib/ui/commands/addonCommands.d.ts +134 -0
  218. package/dist-lib/ui/commands/appShortcuts.d.ts +86 -0
  219. package/dist-lib/ui/commands/hostCommands.d.ts +88 -0
  220. package/dist-lib/ui/commands/keyMatch.d.ts +20 -0
  221. package/dist-lib/ui/commands/keySequence.d.ts +57 -0
  222. package/dist-lib/ui/components/ContextMenu.d.ts +21 -1
  223. package/dist-lib/ui/components/FontPicker.d.ts +5 -1
  224. package/dist-lib/ui/components/useModalFocus.d.ts +13 -1
  225. package/dist-lib/ui/helpTopics.d.ts +15 -0
  226. package/dist-lib/ui/labels/LabelManager.d.ts +172 -9
  227. package/dist-lib/ui/labels/LabelOverlay.d.ts +19 -0
  228. package/dist-lib/ui/labels/backgroundImageSize.d.ts +19 -0
  229. package/dist-lib/ui/labels/labelModel.d.ts +64 -0
  230. package/dist-lib/ui/labels/qColor.d.ts +13 -0
  231. package/dist-lib/ui/labels/qtCss.d.ts +12 -4
  232. package/dist-lib/ui/landmarks.d.ts +9 -0
  233. package/dist-lib/ui/launcher/ActionMenu.d.ts +19 -0
  234. package/dist-lib/ui/launcher/GameDetails.d.ts +21 -0
  235. package/dist-lib/ui/launcher/GameSection.d.ts +18 -0
  236. package/dist-lib/ui/launcher/LauncherSearch.d.ts +23 -0
  237. package/dist-lib/ui/launcher/ProfileArt.d.ts +20 -0
  238. package/dist-lib/ui/launcher/ProfileSection.d.ts +43 -0
  239. package/dist-lib/ui/launcher/launcherModel.d.ts +72 -0
  240. package/dist-lib/ui/layout/overlayLayerOrder.d.ts +2 -2
  241. package/dist-lib/ui/menu/MenuBar.d.ts +31 -0
  242. package/dist-lib/ui/menu/SplitButton.d.ts +39 -0
  243. package/dist-lib/ui/menu/anchoredPopup.d.ts +74 -0
  244. package/dist-lib/ui/menu/appMenus.d.ts +65 -0
  245. package/dist-lib/ui/menu/menuModel.d.ts +88 -0
  246. package/dist-lib/ui/menu/toolbarModel.d.ts +56 -0
  247. package/dist-lib/ui/notepad.d.ts +76 -0
  248. package/dist-lib/ui/openSignInPage.d.ts +14 -0
  249. package/dist-lib/ui/output/OutputContextMenu.d.ts +14 -1
  250. package/dist-lib/ui/output/OutputRenderer.d.ts +5 -0
  251. package/dist-lib/ui/output/OutputSearchBar.d.ts +5 -1
  252. package/dist-lib/ui/output/StickyOutputPanel.d.ts +17 -3
  253. package/dist-lib/ui/output/TextAnalyzerModal.d.ts +25 -0
  254. package/dist-lib/ui/output/caretMode.d.ts +3 -2
  255. package/dist-lib/ui/output/clearSplit.d.ts +11 -0
  256. package/dist-lib/ui/output/outputCopy.d.ts +41 -2
  257. package/dist-lib/ui/output/outputRows.d.ts +43 -0
  258. package/dist-lib/ui/output/selectionGesture.d.ts +35 -0
  259. package/dist-lib/ui/output/wordSelection.d.ts +33 -0
  260. package/dist-lib/ui/search/matcher.d.ts +14 -4
  261. package/dist-lib/ui/settings/SettingsShell.d.ts +91 -0
  262. package/dist-lib/ui/settings/ShortcutEditor.d.ts +13 -0
  263. package/dist-lib/ui/sound/SoundManager.d.ts +210 -44
  264. package/dist-lib/ui/sound/closedCaption.d.ts +4 -1
  265. package/dist-lib/ui/sound/mediaDirection.d.ts +35 -0
  266. package/dist-lib/ui/tabCompletion.d.ts +53 -0
  267. package/dist-lib/ui/textedit/TextEditManager.d.ts +11 -2
  268. package/dist-lib/ui/useOpenProfiles.d.ts +1 -1
  269. package/dist-lib/ui/video/VideoManager.d.ts +7 -0
  270. package/dist-lib/ui/windows/WindowManager.d.ts +452 -37
  271. package/dist-lib/ui/windows/panels/ScriptEditorPanel.d.ts +14 -0
  272. package/dist-lib/ui/windows/panels/ScriptSearch.d.ts +6 -1
  273. package/dist-lib/ui/windows/panels/TextPanel.d.ts +4 -1
  274. package/dist-lib/ui/windows/panels/VariablesView.d.ts +37 -7
  275. package/dist-lib/ui/windows/panels/WindowCmdLine.d.ts +4 -2
  276. package/dist-lib/ui/windows/panels/aliasLoop.d.ts +24 -0
  277. package/dist-lib/ui/windows/panels/editorClipboard.d.ts +45 -0
  278. package/dist-lib/ui/windows/panels/editorUndo.d.ts +79 -0
  279. package/dist-lib/ui/windows/panels/mapAreaChange.d.ts +10 -0
  280. package/dist-lib/utils/appShellCache.d.ts +25 -0
  281. package/dist-lib/utils/fontFamilyName.d.ts +13 -0
  282. package/dist-lib/utils/fontLoader.d.ts +31 -0
  283. package/dist-lib/utils/formatBytes.d.ts +4 -0
  284. package/dist-lib/utils/mustBeOneOf.d.ts +9 -0
  285. package/dist-lib/utils/profileLock.d.ts +1 -1
  286. package/dist-lib/utils/systemTheme.d.ts +24 -0
  287. package/dist-lib/utils/timeZone.d.ts +10 -0
  288. package/dist-lib/vault/CredentialVault.d.ts +51 -5
  289. package/dist-lib/vault/deviceUnlock.d.ts +47 -0
  290. package/dist-lib/vault/vaultAccess.d.ts +24 -2
  291. package/dist-lib/vault/vaultHelpTopic.d.ts +9 -0
  292. package/dist-lib/vault/vaultRecord.d.ts +33 -1
  293. package/dist-lib/vfs-sw.js +220 -11
  294. package/dist-lib/vite.d.ts +1 -1
  295. package/dist-lib/vite.js +66 -43
  296. package/package.json +22 -14
  297. package/dist-lib/assets/mapParser.worker-t-3rd1zR.js +0 -9
  298. package/dist-lib/mud/connection/PingTracker.d.ts +0 -41
  299. package/dist-lib/ui/BundledGameGrid.d.ts +0 -21
  300. package/dist-lib/ui/ConnectionGrid.d.ts +0 -21
  301. package/dist-lib/ui/bufferWords.d.ts +0 -38
@@ -49,7 +49,7 @@ export interface BindingContext {
49
49
  */
50
50
  channel(v: unknown): number | null;
51
51
  /**
52
- * Invoke a Lua callback previously registered through `__mudix_register_cb`.
52
+ * Invoke a Lua callback previously registered through `__mudlet_register_cb`.
53
53
  * `what` names the call site and is used only to attribute errors.
54
54
  */
55
55
  dispatchCb(id: number, what: string): void;
@@ -57,12 +57,27 @@ export interface BindingContext {
57
57
  releaseCb(id: number): void;
58
58
  /** Raise a Mudlet event on the Lua side (deferred if a dispatch is live). */
59
59
  emitEvent(name: string, args: unknown[]): void;
60
+ /** Park the dispatch state (`command`, `matches`, …) the calling script is
61
+ * holding before running an alias pass of its own, and hand it back at the
62
+ * depth the push answered with. See LuaRuntime.pushNestedDispatchState. */
63
+ pushNestedDispatchState(parkCommand?: boolean): number;
64
+ /** Whether an alias or trigger pass is running a script now — the
65
+ * nesting desktop's feedTriggers parks the caller's captures for. */
66
+ inDispatchPass(): boolean;
67
+ popNestedDispatchState(depth: number): void;
68
+ /** Whether `matches`/`multimatches` are being built — see
69
+ * LuaRuntime.buildingCaptureTables. */
70
+ buildingCaptureTables(): boolean;
60
71
  /** This profile's virtual filesystem, or null before one is mounted.
61
72
  * Never reassigned after the runtime is constructed, so a plain reference
62
73
  * is safe here. */
63
74
  readonly vfs: ProfileVFS | null;
75
+ /** The bytes behind a path in the read-only `/lua/` namespace (the bundled
76
+ * Lua, and in busted builds the spec corpus and its fixtures), or null
77
+ * for any other path. See LuaRuntime.readBuiltinBytes. */
78
+ readBuiltinBytes(path: string): Uint8Array | null;
64
79
  /** Drop a Lua-side callback registration by id (the registry slot behind
65
- * `__mudix_register_cb`). Distinct from {@link releaseCb}, which goes
80
+ * `__mudlet_register_cb`). Distinct from {@link releaseCb}, which goes
66
81
  * through Lua; this is the direct JS-side removal. */
67
82
  unregisterCb(cbId: number): void;
68
83
  /** Marshal a JS value onto the Lua stack. Used by the raw lua_CFunction
@@ -78,6 +93,9 @@ export interface BindingContext {
78
93
  * leaking it. Mutated in place and never reassigned, so a reference is
79
94
  * enough. */
80
95
  readonly overlayCmdLineActionCbIds: Map<string, number>;
96
+ /** The same for a miniconsole's or user window's own command line, keyed
97
+ * by the window's name. */
98
+ readonly windowCmdLineActionCbIds: Map<string, number>;
81
99
  /** Run a registerMapInfo callback and read back what it produced. */
82
100
  evaluateMapInfo(cbId: number, roomId: number | null, selectionSize: number, areaId: number, displayedAreaId: number): MapInfoEvaluation | null;
83
101
  /** Run a `setExitWeightFilter` callback for one candidate exit and read
@@ -6,4 +6,4 @@ import type { BindingContext } from './context';
6
6
  * than with the console: raising a script error the editor can attribute, and
7
7
  * expanding an alias without executing it.
8
8
  */
9
- export declare function installDiagnosticsBindings({ lua, api }: BindingContext): void;
9
+ export declare function installDiagnosticsBindings({ lua, api, pushNestedDispatchState, popNestedDispatchState, buildingCaptureTables }: BindingContext): void;
@@ -1,2 +1,2 @@
1
1
  import type { BindingContext } from './context';
2
- export declare function installMapBindings({ lua, api, vfs, channel, emitEvent, unregisterCb, pushJsValue, registerRawGlobal, evaluateMapInfo, evaluateExitWeightFilter, }: BindingContext): void;
2
+ export declare function installMapBindings({ lua, api, vfs, readBuiltinBytes, channel, emitEvent, unregisterCb, pushJsValue, registerRawGlobal, evaluateMapInfo, evaluateExitWeightFilter, }: BindingContext): void;
@@ -4,11 +4,11 @@ import type { BindingContext } from './context';
4
4
  * Mudlet playSoundFile / playMusicFile / stopSounds / stopMusic and friends.
5
5
  * Web Audio backend lives on session.sounds.
6
6
  */
7
- export declare function installSoundBindings({ lua, api }: BindingContext): void;
7
+ export declare function installSoundBindings(ctx: BindingContext): void;
8
8
  /**
9
9
  * Mudlet playVideoFile / pauseVideos / stopVideos.
10
10
  * Same VFS-or-URL loader as sounds; videos mount on the main viewport.
11
- * playVideoFile(path [, volume, loops]) | playVideoFile{name=..., ...}.
11
+ * playVideoFile{name=..., ...} (table form only, as in Mudlet).
12
12
  */
13
13
  export declare function installVideoBindings({ lua, api }: BindingContext): void;
14
14
  /**
@@ -7,4 +7,4 @@ import type { BindingContext } from './context';
7
7
  * Colour channels are validated through the shared 0..255 coercion; Mudlet
8
8
  * silently no-ops on an out-of-range channel rather than raising.
9
9
  */
10
- export declare function installOutputBindings({ lua, api }: BindingContext): void;
10
+ export declare function installOutputBindings({ lua, api, pushNestedDispatchState, popNestedDispatchState, inDispatchPass }: BindingContext): void;
@@ -3,7 +3,7 @@ import type { BindingContext } from './context';
3
3
  /**
4
4
  * Session-level introspection and event raising: stopwatches, the console
5
5
  * width, connection info, desktop notifications, screen-reader announcements,
6
- * the clock, and raiseEvent / raiseGlobalEvent.
6
+ * the clock, and raiseGlobalEvent (raiseEvent lives in Bridge.lua).
7
7
  *
8
8
  * These share no subsystem - what groups them is that each answers a question
9
9
  * about (or acts on) the session as a whole rather than a specific window,
@@ -13,4 +13,4 @@ import type { BindingContext } from './context';
13
13
  * and passed in: it needs the runtime's event emitter and the live profile
14
14
  * name, neither of which belongs in this module.
15
15
  */
16
- export declare function installSessionBindings({ lua, api, emitEvent }: BindingContext, globalEvents: GlobalEventChannel): void;
16
+ export declare function installSessionBindings({ lua, api, registerRawGlobal }: BindingContext, globalEvents: GlobalEventChannel): void;
@@ -6,4 +6,4 @@ import type { BindingContext } from './context';
6
6
  * Backed by TextEditManager, which is a pure data-model registry; the React
7
7
  * overlay renders whatever the model holds.
8
8
  */
9
- export declare function installTextEditBindings({ lua, api, channel }: BindingContext): void;
9
+ export declare function installTextEditBindings({ lua, api, channel, emitEvent }: BindingContext): void;
@@ -8,4 +8,4 @@ import type { BindingContext } from './context';
8
8
  * Lua-side callback slots the widget had bound before dropping it, or the
9
9
  * registry entry leaks for the lifetime of the runtime.
10
10
  */
11
- export declare function installUserWindowBindings({ lua, api, emitEvent, unregisterCb, overlayCmdLineActionCbIds, }: BindingContext): void;
11
+ export declare function installUserWindowBindings({ lua, api, emitEvent, unregisterCb, overlayCmdLineActionCbIds, windowCmdLineActionCbIds, vfs, }: BindingContext): void;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Binary armoring across the wasmoon bridge.
3
+ *
4
+ * wasmoon marshals strings between Lua and JS with emscripten's UTF8ToString /
5
+ * stringToUTF8: Lua→JS stops at the first NUL byte and UTF-8-*decodes* the
6
+ * rest, JS→Lua re-encodes chars >= 0x80 as multi-byte UTF-8. That is fine for
7
+ * text and silently destructive for bytes — `feedTelnet("\229\254\13")` does
8
+ * not deliver 0xE5 0xFE 0x0D, it delivers U+5F8D, because those three bytes
9
+ * happen to look like one three-byte sequence to the decoder. A replay file's
10
+ * int32 headers lost every \0 the same way.
11
+ *
12
+ * So every binding that carries game *bytes* rather than text crosses armored
13
+ * as pure ASCII: a marker char (\2 = raw, \1 = encoded) followed by the payload
14
+ * with NUL, '%' and 0x80–0xFF written as %XX escapes. `__mudlet_armor` /
15
+ * `__mudlet_unarmor` in Bridge.lua are the Lua half of the same scheme, and
16
+ * VFS.lua takes them as locals for its hot paths.
17
+ *
18
+ * A payload is a *byte-string*: one JS char per byte, 0x00–0xFF, which is what
19
+ * the socket layer produces and what every telnet/encoding path downstream
20
+ * expects.
21
+ */
22
+ /** Byte-string → armored ASCII, for a value on its way into Lua. */
23
+ export declare function armor(s: string): string;
24
+ /** Armored ASCII → byte-string, for a value that has just come out of Lua. */
25
+ export declare function unarmor(s: string): string;
26
+ /**
27
+ * An event argument that is bytes rather than text — desktop's
28
+ * ARGUMENT_TYPE_BYTES (sysTelnetEvent's payload). Handed to
29
+ * `LuaRuntime.emitEvent` in place of a string, it crosses armored and reaches
30
+ * the handlers as a Lua string of exactly those bytes, NULs and 0x80–0xFF
31
+ * included, where a plain string argument would be UTF-8-encoded on the way.
32
+ */
33
+ export declare class LuaBytes {
34
+ readonly bytes: string;
35
+ constructor(bytes: string);
36
+ }
@@ -2,3 +2,10 @@ export declare function parseImageSize(b: Uint8Array): {
2
2
  width: number;
3
3
  height: number;
4
4
  } | null;
5
+ /**
6
+ * Whether `bytes` hold something a QPixmap or QSvgRenderer would load, judged
7
+ * by content the way Qt's image readers are: a recognised raster header, an
8
+ * ICO/CUR or TIFF signature, or an SVG candidate (markup or gzip). A missing
9
+ * file, a text file, or an empty one is not an image.
10
+ */
11
+ export declare function looksLikeImage(b: Uint8Array): boolean;
@@ -1,3 +1,5 @@
1
1
  import type { Lua } from 'wasmoon-lua5.1';
2
- /** Register __rex_* JS helpers and put rex_pcre2 into package.loaded. */
3
- export declare function setupRex(lua: Lua): Promise<void>;
2
+ /** Register the __rex_* JS helpers and build the module. `run` executes the
3
+ * module's Lua source — LuaRuntime compiles it as its own ("=[C]") code, since
4
+ * desktop's rex is the lrexlib C library. */
5
+ export declare function setupRex(lua: Lua, run?: (code: string) => void): Promise<void>;
@@ -1 +1,6 @@
1
- export declare function encodeRowsToLuaSource(rows: unknown[][]): string;
1
+ /** Raw bytes as a Lua string literal: printable ASCII as itself, everything
2
+ * else as a `\DDD` escape. The source is pure ASCII, so it crosses the wasmoon
3
+ * bridge without being UTF-8 re-encoded — the bytes Lua gets are the bytes. */
4
+ export declare function encodeLuaBytes(buf: Uint8Array): string;
5
+ /** One row as a Lua array literal: `{...}`. */
6
+ export declare function encodeRowToLuaSource(row: unknown[]): string;
@@ -0,0 +1 @@
1
+ export declare function utf8CaseMap(): string;
@@ -3,7 +3,7 @@
3
3
  * module's find/match/gmatch/gsub.
4
4
  *
5
5
  * Mudlet links the C `luautf8` (starwing) for `utf8`; the browser has no such
6
- * library, so mudix bundles Stepets' pure-Lua `utf8.lua`. That shim is correct
6
+ * library, so Mudlet Web bundles Stepets' pure-Lua `utf8.lua`. That shim is correct
7
7
  * enough for the sub/len/char half of the module but not for the pattern half,
8
8
  * in two ways that both matter:
9
9
  *
@@ -57,3 +57,23 @@ export type LuaFindResult =
57
57
  * counts from the end, and past the end of the subject there is no match.
58
58
  */
59
59
  export declare function findLuaPattern(subject: string, pattern: string, init: number, plain: boolean): LuaFindResult;
60
+ /**
61
+ * `utf8.gsub` / `utf8.gmatch` walk the subject in BYTES, as luautf8 does, so
62
+ * their native search reports bytes: the first match at or after the 1-based
63
+ * byte position `initByte` (a character boundary), as `[first byte, byte after
64
+ * the match, capture…]`. Null when the pattern needs the Lua matcher, and for
65
+ * a subject or pattern holding U+FFFD — which is also what invalid UTF-8
66
+ * becomes on its way over the bridge, and luautf8 raises on that.
67
+ */
68
+ export declare function findLuaPatternBytes(subject: string, pattern: string, initByte: number): {
69
+ start: number;
70
+ end: number;
71
+ captures: string[];
72
+ } | false | null;
73
+ /**
74
+ * Whether codepoint `cp` is in Lua class `%<cl>` (lowercase: the class itself),
75
+ * by the same Unicode tables the native matcher uses — for luautf8's own
76
+ * matcher in utf8.lua, which takes the patterns a regex cannot express. `%t`
77
+ * is luautf8's "compose" class, the combining marks.
78
+ */
79
+ export declare function luaClassMatches(cl: string, cp: number): boolean;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Unpaired UTF-16 surrogates on their way into Lua.
3
+ *
4
+ * A buffer edit by column can split a surrogate pair — selectSection() over
5
+ * half an emoji, insertText() between its halves — and leave a lone surrogate
6
+ * in the line, exactly as it does in Mudlet's QString buffer. What differs is
7
+ * the trip into Lua. Mudlet converts with QString::toUtf8(), whose encoder
8
+ * drops a lone surrogate outright (its error handler writes a '?' through a
9
+ * copy of the output pointer, so the next character overwrites it). wasmoon
10
+ * converts with emscripten's stringToUTF8, which assumes every high surrogate
11
+ * is followed by a low one: it fuses a lone high surrogate with whatever comes
12
+ * next, swallowing that character into a bogus astral code point, and turns a
13
+ * lone low surrogate into a four-byte sequence too. So `getSelection()` over
14
+ * the first half of 😀 answered U+1F400 🐀 instead of desktop's "".
15
+ *
16
+ * Every JS string wasmoon hands to Lua goes through `lua_pushstring`, so that
17
+ * one entry point drops lone surrogates the way toUtf8() does.
18
+ */
19
+ /** `s` without its unpaired surrogates, as QString::toUtf8() would encode it. */
20
+ export declare function dropLoneSurrogates(s: string): string;
21
+ interface PushStringApi {
22
+ lua_pushstring: (L: number, s: string | null) => void;
23
+ }
24
+ /** Make `api.lua_pushstring` drop lone surrogates from the strings it pushes. */
25
+ export declare function installWellFormedPush(api: PushStringApi): void;
26
+ interface ToLStringApi {
27
+ lua_tolstring: (L: number, index: number, size: number | null) => string;
28
+ module: {
29
+ _lua_tolstring: (L: number, index: number, size: number) => number;
30
+ HEAPU8: Uint8Array;
31
+ };
32
+ }
33
+ /** QString::fromUtf8 over bytes that are not valid UTF-8: every byte that does
34
+ * not start a whole, valid sequence is one U+FFFD. Exported for tests. */
35
+ export declare function decodeUtf8LikeQt(bytes: Uint8Array): string;
36
+ /** Make `api.lua_tolstring` decode the way QString::fromUtf8 does. It still
37
+ * stops at the first NUL, as UTF8ToString did, so nothing that relied on
38
+ * that changes. */
39
+ export declare function installDesktopUtf8Read(api: ToLStringApi): void;
40
+ export {};
@@ -1,11 +1,49 @@
1
- import type { Lua } from 'wasmoon-lua5.1';
2
- export type LuaValueTransform = (v: unknown) => unknown;
1
+ import { type Lua } from 'wasmoon-lua5.1';
2
+ type LuaApi = Lua['global']['luaApi'];
3
+ type LuaState = Lua['global']['address'];
4
+ /**
5
+ * Stands for JSON null in a JS value about to be pushed to Lua; the raw pusher
6
+ * swaps it for the registry's `yajl.null` userdata. The GMCP/MSDP bridge never
7
+ * hands wasmoon the sentinel itself: wasmoon reads a userdata's first word as
8
+ * one of its own JS references, which is why the userdata built here is
9
+ * zero-filled (reference 0 is unused, so wasmoon sees `undefined`).
10
+ */
11
+ export declare const YAJL_NULL: unique symbol;
12
+ /**
13
+ * The deepest container nesting lua_yajl's to_value accepts: one more and
14
+ * lua_checkstack fails (see the header). Measured from the C, not guessed —
15
+ * 3 base slots + 3 per open level + the 4 it asks for must stay ≤ 8000.
16
+ */
17
+ export declare const MAX_DECODE_DEPTH = 2665;
18
+ /** The error lua_yajl raises past MAX_DECODE_DEPTH (luaL_error from a C frame: no position). */
19
+ export declare const DECODE_DEPTH_ERROR = "lua stack overflow";
3
20
  /**
4
21
  * Serialise a JSON-decoded value as a Lua chunk returning it. The chunk takes
5
22
  * the null sentinel as its vararg so nulls survive without a global lookup.
6
23
  * Returns null when the value nests too deeply to express as source.
7
24
  */
8
25
  export declare function luaChunkForValue(v: unknown): string | null;
9
- export declare function setupYajl(lua: Lua): {
10
- transform: LuaValueTransform;
11
- };
26
+ /** Container nesting depth of a JSON value (a scalar is 0, `[]` is 1), without recursing. */
27
+ export declare function jsonDepth(root: unknown): number;
28
+ /**
29
+ * Push a JSON-shaped value (plain arrays/objects/scalars, `null` or YAJL_NULL
30
+ * for JSON null) onto `L` with the raw lua_* API, the way lua_yajl's to_value
31
+ * builds it: arrays 1-indexed, nulls as the registry `yajl.null`.
32
+ *
33
+ * Iterative, so neither the JS nor the C stack grows with the document's depth
34
+ * — wasmoon's own pushValue recursed and wrote past the Lua stack, which is the
35
+ * "memory access out of bounds" that used to kill the VM on a deep document.
36
+ * Returns false, having pushed nothing, when the value is nested deeper than
37
+ * lua_yajl accepts (MAX_DECODE_DEPTH) or the Lua stack can't take it.
38
+ */
39
+ export declare function pushJsonValue(api: LuaApi, L: LuaState, root: unknown): boolean;
40
+ export interface YajlBridge {
41
+ /**
42
+ * Push a JSON-decoded value (JSON.parse output) onto `L` exactly as
43
+ * yajl.to_value would build it. False, with nothing pushed, if it is too
44
+ * deep for lua_yajl (see pushJsonValue).
45
+ */
46
+ pushValue(L: LuaState, value: unknown): boolean;
47
+ }
48
+ export declare function setupYajl(lua: Lua, registerRawGlobal: (name: string, fn: (L: LuaState) => number) => void): YajlBridge;
49
+ export {};
@@ -1,10 +1,10 @@
1
1
  /**
2
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
3
+ * Mudlet's `getProfiles()`. Mudlet Web runs one profile per browser tab, so two
4
4
  * cross-tab signals are combined:
5
5
  *
6
6
  * - **loaded** (open & editable): every open profile holds an exclusive Web
7
- * Lock named `mudix:profile:<id>` (see profileLock.ts). `navigator.locks
7
+ * Lock named `mudlet:profile:<id>` (see profileLock.ts). `navigator.locks
8
8
  * .query()` lists held locks across all same-origin tabs, so the held
9
9
  * profile locks ARE the loaded set. Authoritative and crash-safe (the browser
10
10
  * auto-releases a lock when its tab closes/crashes). Polled on a slow interval
@@ -20,6 +20,13 @@
20
20
  * insecure context, or the Node test environment): no Web Locks → loaded is just
21
21
  * this profile; no BroadcastChannel → connected is just this profile's live
22
22
  * state. That matches the old single-profile `getProfiles()` behaviour.
23
+ *
24
+ * The same channel carries `closeProfile(name)` for a profile open in another
25
+ * tab: the caller broadcasts `close` with the target's id and the tab owning it
26
+ * closes itself through {@link onCloseRequested}. `setActiveProfile(name)` for
27
+ * a profile open in another tab sends `attention` the same way: a page cannot
28
+ * bring another tab forward, so the owning tab flags itself instead
29
+ * ({@link onAttentionRequested}).
23
30
  */
24
31
  export declare class ProfilesPresence {
25
32
  private readonly ownId;
@@ -31,6 +38,11 @@ export declare class ProfilesPresence {
31
38
  private loaded;
32
39
  /** Last-announced connected state of OTHER tabs' profiles. */
33
40
  private readonly remoteConnected;
41
+ /** Called when another tab asks this profile to close (`closeProfile`). */
42
+ onCloseRequested: (() => void) | null;
43
+ /** Called when another tab asks this profile to come to the front
44
+ * (`setActiveProfile`). */
45
+ onAttentionRequested: (() => void) | null;
34
46
  constructor(ownId: string,
35
47
  /** This tab's live connected state, read whenever we announce. */
36
48
  localConnected: () => boolean, refreshMs?: number);
@@ -40,6 +52,12 @@ export declare class ProfilesPresence {
40
52
  /** Connection ids of all loaded profiles (best-effort snapshot, always
41
53
  * including this profile's own id). */
42
54
  loadedIds(): string[];
55
+ /** Ask the tab that has profile `id` open to close it. False when there is
56
+ * no channel to carry the request (the other tab cannot be reached). */
57
+ requestClose(id: string): boolean;
58
+ /** Ask the tab that has profile `id` open to draw the user's attention to
59
+ * itself. False when there is no channel to carry the request. */
60
+ requestAttention(id: string): boolean;
43
61
  /** Connected state for a profile id: own → live, others → last announced
44
62
  * (false when never announced). Callers gate this on `loaded` so a crashed
45
63
  * tab's stale "connected" can't outlive its lock. */
@@ -1,4 +1,30 @@
1
1
  export type VFSSource = 'folder' | 'idb';
2
+ /** How long an appended tail waits in memory before it is written out. */
3
+ export declare const APPEND_FLUSH_MS = 500;
4
+ /** A tail that has grown this large is written out at once. */
5
+ export declare const APPEND_FLUSH_BYTES: number;
6
+ /** {@link ProfileVFS.lstat}: a stat that can also be about a symbolic link. */
7
+ export type VfsLstat = Omit<VfsStat, 'type'> & {
8
+ type: VfsStat['type'] | 'link';
9
+ };
10
+ export interface VfsStat {
11
+ type: 'file' | 'dir';
12
+ size: number;
13
+ mtime: Date;
14
+ atime: Date;
15
+ /** Inode change time — what `lfs.attributes` reports as `change`. */
16
+ ctime: Date;
17
+ /** The full `st_mode`: file type bits and permission bits. */
18
+ mode: number;
19
+ dev: number;
20
+ ino: number;
21
+ nlink: number;
22
+ uid: number;
23
+ gid: number;
24
+ rdev: number;
25
+ blocks: number;
26
+ blksize: number;
27
+ }
2
28
  export declare class ProfileVFS {
3
29
  readonly connectionId: string;
4
30
  readonly profilePath: string;
@@ -7,16 +33,57 @@ export declare class ProfileVFS {
7
33
  private _handle?;
8
34
  readonly source: VFSSource;
9
35
  readonly folderName?: string;
36
+ private readBarrier;
37
+ private writeObserver;
38
+ /** See {@link writeGeneration}. Bumped in afterWrite, the one place every
39
+ * write, removal and rename already reports through. */
40
+ private readonly writeGenerations;
41
+ /** See {@link appendBinaryFile}. Keyed by absolute path. */
42
+ private readonly pendingAppends;
43
+ private appendFlushTimer;
10
44
  private constructor();
11
45
  static mount(connectionId: string): Promise<ProfileVFS>;
12
46
  private static doMount;
13
47
  get cwd(): string;
48
+ /**
49
+ * Run `barrier` with a file's absolute path before anything reads it.
50
+ * The sql bridge uses it to write a database's pending changes out first,
51
+ * so a file a script (or the file browser, or an upload) reads right after
52
+ * a db:add holds that row, as desktop's database file would. Null removes it.
53
+ */
54
+ setReadBarrier(barrier: ((absPath: string) => void) | null): void;
55
+ /**
56
+ * Install (or clear, with null) a hook told after a file has been written
57
+ * ('write') or removed, renamed away or replaced by a rename, or had its
58
+ * directory removed ('remove'). The sql bridge uses it so a database file
59
+ * changed underneath an open connection is changed for that connection
60
+ * too, as a file on disk is.
61
+ */
62
+ setWriteObserver(observer: ((absPath: string, kind: 'write' | 'remove') => void) | null): void;
63
+ private afterWrite;
64
+ private beforeRead;
14
65
  resolvePath(path: string): string;
66
+ /** Whether a component of `path` is longer than NAME_MAX — for a caller
67
+ * that must refuse such a name before it writes (io.open, as fopen does). */
68
+ nameTooLong(path: string): boolean;
15
69
  exists(path: string): boolean;
16
70
  readFile(path: string): string;
17
71
  readBinaryFile(path: string): Uint8Array;
72
+ /**
73
+ * A count that moves whenever the file at `path` is written, removed or
74
+ * renamed through this VFS, and never otherwise. For a reader that holds a
75
+ * file's bytes and must notice when they have gone stale, without reading
76
+ * the whole file again to find out — a replay being played comes back to
77
+ * its file once a chunk. A stat cannot stand in for it: mtime is in
78
+ * milliseconds, and a rewrite in place keeps the size.
79
+ */
80
+ writeGeneration(path: string): number;
18
81
  writeFile(path: string, content: string): void;
19
- writeBinaryFile(path: string, data: Uint8Array): void;
82
+ /** `createParents: false` writes only into a directory that already exists,
83
+ * throwing as open(2) would otherwise — what a download's QFile does. */
84
+ writeBinaryFile(path: string, data: Uint8Array, { createParents }?: {
85
+ createParents?: boolean;
86
+ }): void;
20
87
  /**
21
88
  * The linked-folder (WebAccess / FileSystemDirectoryHandle) backend overwrites
22
89
  * a file from offset 0 but does NOT shrink it, so writing shorter content over
@@ -27,17 +94,104 @@ export declare class ProfileVFS {
27
94
  */
28
95
  private clearForOverwrite;
29
96
  appendFile(path: string, content: string): void;
97
+ /**
98
+ * Add `data` to the end of a file, creating it when missing — what Lua's
99
+ * io.open(f, "a") writes through. The read barrier runs first so the bytes
100
+ * land after anything a database still has pending for that file.
101
+ *
102
+ * ZenFS keeps a file as one value in its store, and an append reads that
103
+ * value, copies it one longer and puts the whole of it back, so every
104
+ * append cost the size of the file: a chat log EMCO appends a line to
105
+ * per message took 30 ms a line at 5 MB (#457), where desktop's write is
106
+ * the line's bytes. So the bytes appended to a file already in the store
107
+ * are held here and written out together — after APPEND_FLUSH_MS, once
108
+ * they reach APPEND_FLUSH_BYTES, or as soon as anything reads, stats,
109
+ * rewrites, moves or removes the file (every such path goes through
110
+ * {@link settle}), and when the page is hidden or goes away. One write per
111
+ * window instead of one per line, and nothing can see the file without
112
+ * the tail: {@link stat} counts it into the size and {@link exists} knows
113
+ * the file is there.
114
+ *
115
+ * A file that is not there yet, a link, or an append while the page is
116
+ * going away is written straight through, as before.
117
+ */
118
+ appendBinaryFile(path: string, data: Uint8Array): void;
119
+ /** A regular file in the store with only this one name — the only kind
120
+ * whose appends can be held: a held tail is found again by its path. */
121
+ private isPlainFile;
122
+ private scheduleAppendFlush;
123
+ /**
124
+ * Write out the appended bytes held for `scope` — that file, or every
125
+ * file under it when it is a directory — or for every file when omitted.
126
+ * Returns `scope`, so a path can be settled on its way into a call.
127
+ */
128
+ flushAppends(scope?: string): string | undefined;
129
+ /** {@link flushAppends} for one absolute path, returned for chaining. */
130
+ private settle;
30
131
  deleteFile(path: string): void;
31
- rename(oldPath: string, newPath: string): void;
32
- mkdir(path: string): void;
33
- rmdir(path: string): void;
132
+ /**
133
+ * Move a file or directory. By default a missing parent of the target is
134
+ * created, which the app's own callers rely on. `{ posix: true }` is
135
+ * `rename(2)`, what Lua's `os.rename` is on desktop: the target's directory
136
+ * must already exist (ENOENT, or ENOTDIR under a file), a directory may
137
+ * replace only an empty directory (ENOTEMPTY otherwise, ENOTDIR for a
138
+ * file) and never move into itself (EINVAL), and a file never replaces a
139
+ * directory (EISDIR).
140
+ */
141
+ rename(oldPath: string, newPath: string, { posix }?: {
142
+ posix?: boolean;
143
+ }): void;
144
+ /**
145
+ * Create a directory. By default the whole chain is created and an existing
146
+ * directory is not an error, which is what the app's own callers want.
147
+ * `{ recursive: false }` is POSIX `mkdir(2)` — what LuaFileSystem's
148
+ * `lfs.mkdir` does on desktop: a missing parent is ENOENT, a parent that is
149
+ * a file is ENOTDIR, and an existing path is EEXIST.
150
+ */
151
+ mkdir(path: string, { recursive }?: {
152
+ recursive?: boolean;
153
+ }): void;
154
+ /**
155
+ * Remove a directory. By default it goes with everything in it — the app's
156
+ * own callers (the file browser, package reinstalls) mean exactly that.
157
+ * `{ recursive: false }` is POSIX `rmdir(2)`, what `lfs.rmdir` does on
158
+ * desktop: only an empty directory is removed, and a non-empty directory
159
+ * (ENOTEMPTY), a plain file (ENOTDIR) or a missing path (ENOENT) is left
160
+ * alone and reported. A script must never be able to wipe a folder of
161
+ * saved data with a call that desktop refuses.
162
+ */
163
+ rmdir(path: string, { recursive }?: {
164
+ recursive?: boolean;
165
+ }): void;
166
+ /**
167
+ * C's `remove(3)`, which Lua's `os.remove` is: a file is unlinked and an
168
+ * empty directory is removed, as `rmdir(2)` would.
169
+ */
170
+ remove(path: string): void;
171
+ /**
172
+ * The parts of the kernel's path walk that `resolvePath`'s normalising
173
+ * would hide: an empty path names nothing (ENOENT), a plain file can't
174
+ * have anything under it (ENOTDIR), and a path ending in "." or ".." is
175
+ * refused with `dotErrno` — the profile root is not what `os.remove(".")`
176
+ * means.
177
+ */
178
+ private checkPosixPath;
179
+ /**
180
+ * Set a path's access and modification times (`utime(2)`), which is all
181
+ * `lfs.touch` does — it never creates a file.
182
+ */
183
+ touch(path: string, atime: Date, mtime: Date): void;
34
184
  readdir(path: string): string[];
35
- stat(path: string): {
36
- type: 'file' | 'dir';
37
- size: number;
38
- mtime: Date;
39
- atime: Date;
40
- } | null;
185
+ stat(path: string): VfsStat | null;
186
+ /** `lstat(2)`: like {@link stat}, but about a symbolic link itself, which
187
+ * reports as type `link`. Throws the filesystem's error (ENOENT …). */
188
+ lstat(path: string): VfsLstat;
189
+ /** `readlink(2)`: a symbolic link's target, as stored. */
190
+ readlink(path: string): string;
191
+ /** `link(2)` / `symlink(2)` — what `lfs.link` makes. A symbolic link's
192
+ * target is stored as given (it may be relative, or dangle); a hard link's
193
+ * must exist. Throws the filesystem's error (EEXIST, ENOENT, ENOTSUP …). */
194
+ link(target: string, path: string, symbolic: boolean): void;
41
195
  chdir(path: string): string | null;
42
196
  /**
43
197
  * Drain queued async writes to the underlying backend. For folder-backed
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Filesystem errors in the shape C's `strerror`/`errno` give them, so the Lua
3
+ * `io`/`os`/`lfs` bindings can report failures the way stock Lua and
4
+ * LuaFileSystem do on desktop Mudlet: `nil, "<message>", <errno>`.
5
+ *
6
+ * ZenFS already throws errors carrying Linux errno numbers and codes, but its
7
+ * messages are its own ("EISDIR: File is a directory, open '/a'"), and scripts
8
+ * that match on the text — or show it to the player — expect glibc's wording.
9
+ */
10
+ /** Linux errno numbers, for errors raised here rather than by ZenFS. */
11
+ declare const ERRNO: Record<string, number>;
12
+ export type FsErrorCode = keyof typeof ERRNO & string;
13
+ /** An error thrown by ProfileVFS's own checks, shaped like ZenFS's. */
14
+ export declare class FsError extends Error {
15
+ readonly code: FsErrorCode;
16
+ readonly path?: string | undefined;
17
+ readonly errno: number;
18
+ constructor(code: FsErrorCode, path?: string | undefined);
19
+ }
20
+ export interface FsErrorDescription {
21
+ /** The `strerror` text, or the error's own message when it has no errno code. */
22
+ message: string;
23
+ /** The errno number, when the error carries one. */
24
+ errno?: number;
25
+ }
26
+ /** Reduce anything thrown by the VFS to `strerror` text and an errno. */
27
+ export declare function describeFsError(e: unknown): FsErrorDescription;
28
+ export {};
@@ -0,0 +1,20 @@
1
+ import type { FileSystem } from '@zenfs/core';
2
+ /**
3
+ * Make every synchronous write to an IndexedDB-backed StoreFS commit its
4
+ * IndexedDB transaction there and then (#438).
5
+ *
6
+ * ZenFS issues a sync write's put/delete requests at once, but never calls
7
+ * `IDBTransaction.commit()` — its `commitSync()` only marks the wrapper done
8
+ * — so the transaction is left to auto-commit. Chromium auto-commits from the
9
+ * page: once the requests' success events have been delivered back to it. A
10
+ * write made while the page is going away (sysExitEvent on pagehide, where
11
+ * Geyser's Adjustable.Container saves its layout) never gets those events, so
12
+ * the transaction is aborted with the page and the file is lost. An explicit
13
+ * commit hands the decision to the database itself, which finishes the
14
+ * transaction whether or not the page is still there to hear about it.
15
+ *
16
+ * Only the sync path is touched: async operations await their requests
17
+ * across tasks, and nothing here is in a hurry. A transaction that already
18
+ * finished (it had nothing to do) refuses `commit()`; that is not an error.
19
+ */
20
+ export declare function commitSyncWritesImmediately(fs: FileSystem): void;