@mudlet/mudlet-web 0.3.1 → 0.4.1

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 (97) hide show
  1. package/README.md +8 -0
  2. package/dist-lib/assets/qt-resources/index.d.ts +16 -0
  3. package/dist-lib/branding.d.ts +1 -1
  4. package/dist-lib/hooks/useMudSession.d.ts +1 -1
  5. package/dist-lib/hooks/useOutput.d.ts +3 -1
  6. package/dist-lib/import/defaultPackages.d.ts +35 -2
  7. package/dist-lib/import/defaults/generic_mapper/generic_mapper.mpackage +0 -0
  8. package/dist-lib/import/defaults/gui-drop/gui-drop.mpackage +0 -0
  9. package/dist-lib/import/defaults/{run-lua-code.mpackage → mudlet-base-ui/mudlet-base-ui.mpackage} +0 -0
  10. package/dist-lib/import/defaults/run-lua-code/run-lua-code.mpackage +0 -0
  11. package/dist-lib/import/packageExport.d.ts +71 -0
  12. package/dist-lib/import/packageInstaller.d.ts +4 -1
  13. package/dist-lib/index.js +45929 -40688
  14. package/dist-lib/logging/SessionLogger.d.ts +66 -1
  15. package/dist-lib/map/MapStore.d.ts +32 -4
  16. package/dist-lib/map/mapImageExport.d.ts +1 -1
  17. package/dist-lib/map/mapZoom.d.ts +71 -0
  18. package/dist-lib/mud/ItemIdSequence.d.ts +23 -0
  19. package/dist-lib/mud/MudSession.d.ts +113 -11
  20. package/dist-lib/mud/PatternEngine.d.ts +6 -1
  21. package/dist-lib/mud/commandSplit.d.ts +16 -0
  22. package/dist-lib/mud/connection/LineAssembler.d.ts +56 -0
  23. package/dist-lib/mud/connection/MudClient.d.ts +120 -16
  24. package/dist-lib/mud/connection/TelnetNegotiator.d.ts +39 -0
  25. package/dist-lib/mud/connection/telnetByteTags.d.ts +35 -0
  26. package/dist-lib/mud/events.d.ts +19 -4
  27. package/dist-lib/mud/games/bundledGames.d.ts +29 -0
  28. package/dist-lib/mud/games/gameIcons.d.ts +5 -0
  29. package/dist-lib/mud/keybindings/KeyEngine.d.ts +9 -2
  30. package/dist-lib/mud/keybindings/browserReservedKeys.d.ts +5 -1
  31. package/dist-lib/mud/keybindings/keyEventTarget.d.ts +17 -0
  32. package/dist-lib/mud/keybindings/qtKeys.d.ts +2 -0
  33. package/dist-lib/mud/protocol/charLoginFlow.d.ts +68 -0
  34. package/dist-lib/mud/protocol/charset.d.ts +27 -5
  35. package/dist-lib/mud/protocol/constants.d.ts +1 -0
  36. package/dist-lib/mud/protocol/gmcp.d.ts +19 -3
  37. package/dist-lib/mud/protocol/index.d.ts +1 -1
  38. package/dist-lib/mud/protocol/mxp.d.ts +28 -5
  39. package/dist-lib/mud/replay/ReplayPlayer.d.ts +17 -0
  40. package/dist-lib/mud/text/Console.d.ts +64 -0
  41. package/dist-lib/mud/text/FormatState.d.ts +66 -3
  42. package/dist-lib/mud/text/hyperlinkVisibility.d.ts +35 -0
  43. package/dist-lib/mud/text/osc8Docs.d.ts +23 -0
  44. package/dist-lib/mud/text/serverWrap.d.ts +191 -0
  45. package/dist-lib/mud/timers/TimerEngine.d.ts +43 -12
  46. package/dist-lib/mud/triggers/TriggerEngine.d.ts +112 -3
  47. package/dist-lib/scripting/EngineHost.d.ts +56 -3
  48. package/dist-lib/scripting/IScriptingRuntime.d.ts +16 -0
  49. package/dist-lib/scripting/MxpFrameManager.d.ts +118 -0
  50. package/dist-lib/scripting/ScriptingAPI.d.ts +323 -54
  51. package/dist-lib/scripting/ScriptingEngine.d.ts +180 -23
  52. package/dist-lib/scripting/http/HttpService.d.ts +51 -1
  53. package/dist-lib/scripting/lua/LuaRuntime.d.ts +151 -2
  54. package/dist-lib/scripting/lua/bindings/map.d.ts +0 -12
  55. package/dist-lib/scripting/lua/utf8Patterns.d.ts +59 -0
  56. package/dist-lib/storage/index.d.ts +1 -1
  57. package/dist-lib/storage/persistentStorage.d.ts +10 -0
  58. package/dist-lib/storage/schema.d.ts +116 -0
  59. package/dist-lib/styles.css +1 -1
  60. package/dist-lib/ui/BundledGameGrid.d.ts +21 -0
  61. package/dist-lib/ui/CommandBar.d.ts +7 -1
  62. package/dist-lib/ui/ConnectionGrid.d.ts +4 -1
  63. package/dist-lib/ui/FilePickerModal.d.ts +3 -3
  64. package/dist-lib/ui/HelpModal.d.ts +11 -0
  65. package/dist-lib/ui/LogBrowserModal.d.ts +4 -1
  66. package/dist-lib/ui/PlayerMarkerPreview.d.ts +20 -0
  67. package/dist-lib/ui/Toolbar.d.ts +2 -1
  68. package/dist-lib/ui/VfsPickerModal.d.ts +26 -0
  69. package/dist-lib/ui/components/FileSourceButton.d.ts +47 -0
  70. package/dist-lib/ui/components/index.d.ts +1 -0
  71. package/dist-lib/ui/helpTopics.d.ts +19 -0
  72. package/dist-lib/ui/labels/LabelManager.d.ts +7 -0
  73. package/dist-lib/ui/layout/ScriptWindow.d.ts +11 -2
  74. package/dist-lib/ui/markdown.d.ts +10 -1
  75. package/dist-lib/ui/output/OutputArea.d.ts +11 -1
  76. package/dist-lib/ui/output/OutputContextMenu.d.ts +3 -1
  77. package/dist-lib/ui/output/OutputRenderer.d.ts +7 -1
  78. package/dist-lib/ui/output/OutputSearchBar.d.ts +25 -0
  79. package/dist-lib/ui/output/StickyOutputPanel.d.ts +5 -1
  80. package/dist-lib/ui/output/outputSearch.d.ts +130 -0
  81. package/dist-lib/ui/search/matcher.d.ts +15 -0
  82. package/dist-lib/ui/search/useDebounced.d.ts +3 -0
  83. package/dist-lib/ui/tts/TtsManager.d.ts +3 -0
  84. package/dist-lib/ui/useCommandHistory.d.ts +4 -2
  85. package/dist-lib/ui/useOpenProfiles.d.ts +26 -0
  86. package/dist-lib/ui/video/VideoManager.d.ts +17 -0
  87. package/dist-lib/ui/windows/WindowManager.d.ts +132 -2
  88. package/dist-lib/ui/windows/panels/MapPanel.d.ts +4 -1
  89. package/dist-lib/ui/windows/panels/PackageExportModal.d.ts +18 -0
  90. package/dist-lib/ui/windows/panels/TextPanel.d.ts +3 -1
  91. package/dist-lib/ui/windows/types.d.ts +35 -0
  92. package/dist-lib/utils/describeThrown.d.ts +22 -0
  93. package/dist-lib/utils/fontLoader.d.ts +5 -0
  94. package/dist-lib/vite.js +22 -0
  95. package/package.json +10 -6
  96. package/dist-lib/scripting/lua/mudlet-lua/generic-mapper/generic_mapper.mpackage +0 -0
  97. package/dist-lib/ui/windows/panels/VfsModulePickerModal.d.ts +0 -8
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Lua patterns compiled to JavaScript regular expressions, for the `utf8`
3
+ * module's find/match/gmatch/gsub.
4
+ *
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
7
+ * enough for the sub/len/char half of the module but not for the pattern half,
8
+ * in two ways that both matter:
9
+ *
10
+ * * **Its character classes are ASCII.** `classMatchGenerator` writes `%a` as
11
+ * the two ranges A-Z and a-z, so `caf%a` does not match `café` — while
12
+ * luautf8 decides every class from Unicode tables. A pattern class is
13
+ * supposed to be the one part of `utf8.*` that is not byte-wise.
14
+ * * **It is slow enough to be a hazard.** One `find` over a 35-character line
15
+ * costs ~35,000 Lua VM instructions — it walks the subject a character at a
16
+ * time through a generated closure chain. `replaceAll` calls it once per
17
+ * replacement, on trigger output.
18
+ *
19
+ * So the pattern is translated to a JS `RegExp` and matched natively, with the
20
+ * Lua implementation kept as the fallback for the constructs that have no
21
+ * regex equivalent (`%b`, `%f`, position captures, back-references — see
22
+ * `compileLuaPattern` returning null). Nothing gets worse for those; everything
23
+ * else gets Unicode classes and native speed.
24
+ *
25
+ * Positions cross the boundary as Lua sees them: 1-based, inclusive, and
26
+ * counted in CODE POINTS. JS regex indices are UTF-16 code units, so a subject
27
+ * holding anything outside the BMP needs the map `codePointOffsets` builds.
28
+ */
29
+ export type CompiledLuaPattern = {
30
+ re: RegExp;
31
+ /** `^` at the start of a Lua pattern anchors at `init`, not at the start of
32
+ * the subject — which is a sticky regex, not a `^`. */
33
+ anchored: boolean;
34
+ captures: number;
35
+ };
36
+ /** Compile a Lua pattern, or null when it uses something a regex cannot express
37
+ * (`%b`, `%f`, a position capture, a back-reference) and the caller should fall
38
+ * back to the Lua implementation. */
39
+ export declare function compileLuaPattern(pattern: string): CompiledLuaPattern | null;
40
+ export type LuaFindResult =
41
+ /** The pattern needs a construct a regex cannot express — use the Lua one. */
42
+ {
43
+ kind: 'unsupported';
44
+ } | {
45
+ kind: 'nomatch';
46
+ }
47
+ /** `start`/`end` are Lua positions: 1-based, inclusive, in code points. An
48
+ * empty match reports `end === start - 1`, as `string.find` does. */
49
+ | {
50
+ kind: 'match';
51
+ start: number;
52
+ end: number;
53
+ captures: string[];
54
+ };
55
+ /**
56
+ * `string.find` over UTF-8, natively. `init` follows Lua: 1-based, negative
57
+ * counts from the end, and past the end of the subject there is no match.
58
+ */
59
+ export declare function findLuaPattern(subject: string, pattern: string, init: number, plain: boolean): LuaFindResult;
@@ -1,4 +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, effectiveProxyUrl, proxyCanInspectCertificates, selectProfileField } from './schema';
1
+ export { type AppSchema, type MudConnection, type ConnectionMode, type ClientSettings, type ProfileSettings, type MapperSettings, type PlayerMarkerSettings, type MapInfoBgColor, type ProtocolSettings, type BooleanProtocolKey, type Theme, type OutputFontSource, APP_DEFAULTS, PROFILE_DEFAULTS, MAPPER_DEFAULTS, PLAYER_MARKER_DEFAULTS, MAP_INFO_BG_DEFAULT, PROTOCOL_DEFAULTS, WS_SUBPROTOCOL_CHOICES, DEFAULT_PROXY_URL, connectionUrl, connectionDisplayAddr, connectionSecureTransport, connectionNameTaken, uniqueConnectionName, effectiveProxyUrl, proxyCanInspectCertificates, selectProfileField } from './schema';
2
2
  export { useAppStore } from './appStore';
3
3
  export { initCrossTabSync } from './crossTabSync';
4
4
  export { ConnectionIdContext, useConnectionId, useProfileField, useClientField, useEffectiveTheme } from './hooks';
@@ -0,0 +1,10 @@
1
+ /** Whether this browser can be asked at all. */
2
+ export declare function persistenceSupported(): boolean;
3
+ /** Whether the origin's storage is already exempt from eviction. Never throws. */
4
+ export declare function isPersisted(): Promise<boolean>;
5
+ /** Ask the browser to exempt this origin's storage from eviction, at most once
6
+ * per page session. Resolves to whether storage is persistent afterwards —
7
+ * `false` on refusal or on a browser without the API. Never throws. */
8
+ export declare function ensurePersistentStorage(): Promise<boolean>;
9
+ /** Test seam: forget the one-per-session attempt. */
10
+ export declare function resetPersistenceRequest(): void;
@@ -44,6 +44,13 @@ export interface MudConnection {
44
44
  * already ship them — Mudlet installs those only into brand-new profiles, so
45
45
  * their absence in an imported profile is a real choice, not a gap to fill. */
46
46
  mudletImported?: boolean;
47
+ /** ISO timestamp stamped by `addConnection` when the profile is created.
48
+ * **Absent means the profile predates this field**, which is exactly what
49
+ * it's for: it stands in for Mudlet's `experiencedMudletPlayer()` (any
50
+ * profile folder older than 6 months) so the starter UI only reaches
51
+ * profiles created after it shipped, and never lands on top of a layout
52
+ * someone already built. See `stockDefaults`. */
53
+ createdAt?: string;
47
54
  /** Connect to the game over TLS — Mudlet's `mSslTsl` / the connection
48
55
  * dialog's "secure connection" checkbox. Meaningful in `mud` (proxy) mode
49
56
  * only: the browser cannot wrap a raw socket itself, so the proxy performs
@@ -127,6 +134,16 @@ export interface ProfileSettings {
127
134
  * installed automatically). Disable to ignore those requests. Per-profile
128
135
  * so each MUD is trusted independently. */
129
136
  allowMudPackageInstall?: boolean;
137
+ /** When true (default — treat `undefined` as true), MUDs may drive playback
138
+ * through the GMCP `Client.Media` messages (MCMP): files named by the
139
+ * server are downloaded into the profile's `media/` folder and played.
140
+ * Disable to ignore those messages outright — nothing is fetched and
141
+ * nothing plays, which is what separates this from `muteMediaGame` (that
142
+ * one still downloads and plays, just silently). Mudlet's
143
+ * `mAcceptServerMedia` / "Allow server to download and play media", and
144
+ * like Mudlet it gates GMCP only — MSP has its own switch in
145
+ * `protocols.msp`. Per-profile, so each MUD is trusted independently. */
146
+ allowServerMedia?: boolean;
130
147
  /** When true (default), a server that advertises a TLS port via MSSP prompts
131
148
  * once to switch to it. Declining sets this false so the offer never
132
149
  * reappears for this profile. Mudlet calls it `mAskTlsAvailable`
@@ -382,6 +399,11 @@ export interface MapperSettings {
382
399
  backgroundColor?: string;
383
400
  /** renderer.settings.lineColor — exit color, hex (#rrggbb). */
384
401
  lineColor?: string;
402
+ /** Mudlet `TMap::mShowDefaultArea` — whether the unnamed catch-all area
403
+ * rooms land in before they are filed anywhere is offered in the area
404
+ * list. Set from Lua by `setDefaultAreaVisible`; read by MapPanel's area
405
+ * dropdown. Visible unless turned off. */
406
+ showDefaultArea?: boolean;
385
407
  /** renderer.settings.gridEnabled — background grid overlay. */
386
408
  gridEnabled?: boolean;
387
409
  /** renderer.settings.lodEnabled — level-of-detail for very dense planes.
@@ -403,12 +425,50 @@ export interface MapperSettings {
403
425
  * until you zoom in further. Measured against what the current viewport
404
426
  * materialises, not the whole level. */
405
427
  lodHitTestBudget?: number;
428
+ /** renderer.settings.playerMarker — styling for the ring drawn on the
429
+ * player's room. */
430
+ playerMarker?: PlayerMarkerSettings;
431
+ }
432
+ /** Styling for the player-position marker — the ring the renderer draws on
433
+ * whichever room `updatePositionMarker()` was last given.
434
+ *
435
+ * Mirrors the renderer's `PlayerMarkerStyle` one field at a time, except for
436
+ * the dash pattern: the renderer takes a `number[]`, but a pair of scalars
437
+ * patches independently and survives the JSON round-trip more simply, so
438
+ * {@link dashLength}/{@link dashGap} are recombined into `[len, gap]` in
439
+ * applyMapperSettings. Every field is optional — unset ones fall through to
440
+ * the renderer's own createSettings() defaults. */
441
+ export interface PlayerMarkerSettings {
442
+ /** Outline colour, hex (#rrggbb). */
443
+ strokeColor?: string;
444
+ /** Outline opacity, 0..1. */
445
+ strokeAlpha?: number;
446
+ /** Fill colour, hex (#rrggbb). Only visible when {@link fillAlpha} > 0. */
447
+ fillColor?: string;
448
+ /** Fill opacity, 0..1. 0 leaves the marker a hollow ring. */
449
+ fillAlpha?: number;
450
+ /** Outline thickness in map units (roughly 0.01–0.3). */
451
+ strokeWidth?: number;
452
+ /** Multiplier on `roomSize`. 1.0 makes the marker exactly room-sized;
453
+ * the renderer's default (1.7) rings the room from outside. */
454
+ sizeFactor?: number;
455
+ /** Dash length in map units — only drawn when {@link dashEnabled}. */
456
+ dashLength?: number;
457
+ /** Gap between dashes in map units — only drawn when {@link dashEnabled}. */
458
+ dashGap?: number;
459
+ /** Dash the outline instead of drawing it solid. */
460
+ dashEnabled?: boolean;
461
+ /** Follow {@link MapperSettings.roomShape} instead of always drawing a
462
+ * circle. Rectangle/rounded-rectangle rooms only; a circle room is
463
+ * already a circle. */
464
+ matchRoomShape?: boolean;
406
465
  }
407
466
  /** Mirrors the renderer's createSettings() defaults so the Settings modal can
408
467
  * show meaningful placeholder/fallback values when a field is still
409
468
  * undefined. MapPanel itself does NOT use these — it only forwards fields
410
469
  * that the user has actually set, so the renderer's own defaults stay in
411
470
  * charge for anything untouched. */
471
+ export declare const PLAYER_MARKER_DEFAULTS: Required<PlayerMarkerSettings>;
412
472
  export declare const MAPPER_DEFAULTS: Required<MapperSettings>;
413
473
  /** RGBA channels (0..255) for the map-info widget background. Stored in the
414
474
  * profile `config` bag under `mapInfoColor` (Mudlet's `setConfig` key) and
@@ -455,6 +515,23 @@ export interface PackageManifest {
455
515
  xmlVfsPath?: string;
456
516
  /** Source filename (e.g. "GenericMapper.mpackage"), useful for display. */
457
517
  sourceFile?: string;
518
+ /** Absolute VFS path the install was given, when it came from one. This is
519
+ * what `getModulePath` answers with: the file the user picked, not whatever
520
+ * was unpacked out of it — a script uses it to reinstall, or to point the
521
+ * user back at their own file, and neither works with an internal path. */
522
+ sourcePath?: string;
523
+ /**
524
+ * Exactly what the package's `config.lua` declared, keys lower-cased,
525
+ * unmapped and unaugmented.
526
+ *
527
+ * This is what `getPackageInfo`/`getModuleInfo` answer with, so it has to
528
+ * stay the package author's own set: Mudlet reports what the manifest said
529
+ * and nothing more, which means a package that shipped no config.lua has no
530
+ * info at all rather than a table of things mudix worked out for itself
531
+ * (the derived name, the install timestamp). Absent when there was no
532
+ * config.lua to read.
533
+ */
534
+ declaredInfo?: Record<string, string>;
458
535
  /** When the package was installed via a remote URL (e.g. a `Client.GUI`
459
536
  * GMCP message), records the originating URL so subsequent install
460
537
  * requests for the same URL can be deduplicated against this manifest
@@ -512,6 +589,19 @@ export interface TriggerNode extends BaseNode {
512
589
  multiline: boolean;
513
590
  delta: number;
514
591
  isFilter: boolean;
592
+ /**
593
+ * Session-scoped: created by `tempComplexRegexTrigger`, which needs a real
594
+ * trigger node rather than the flat temp-trigger primitive because it can
595
+ * ask for multiline-AND, a filter chain, a fire length, a line delta — all
596
+ * of them properties of a node in the tree — and can be named as another
597
+ * trigger's parent.
598
+ *
599
+ * Not persisted (see serializeProfileData), and neither is anything hanging
600
+ * under it: a permanent trigger parented to a temporary one goes when its
601
+ * parent does, so saving it would restore a child pointing at a parent that
602
+ * no longer exists.
603
+ */
604
+ temporary?: boolean;
515
605
  highlight?: {
516
606
  fg?: string;
517
607
  bg?: string;
@@ -681,4 +771,30 @@ export declare function connectionDisplayAddr(c: MudConnection): string;
681
771
  * the proxy↔game hop: that leg is a plaintext telnet socket unless `tls` is set,
682
772
  * which makes the proxy perform a TLS handshake with the game instead. */
683
773
  export declare function connectionSecureTransport(c: MudConnection): boolean;
774
+ /**
775
+ * Whether `name` is already some other profile's, ignoring case.
776
+ *
777
+ * Case-insensitively, because that is how the scripting API resolves a profile
778
+ * name (`getProfileInformation("ACHAEA")` finds the Achaea profile — Mudlet
779
+ * looks the name up as a folder and the platforms it runs on mostly have
780
+ * case-insensitive ones). Two profiles differing only in case would make those
781
+ * calls pick between them arbitrarily.
782
+ *
783
+ * `exceptId` is the profile being edited, so renaming one to its own name is
784
+ * not a clash.
785
+ */
786
+ export declare function connectionNameTaken(name: string, connections: MudConnection[], exceptId?: string): boolean;
787
+ /**
788
+ * `name` if no other profile has it, otherwise the first free `name (2)`,
789
+ * `name (3)`, … — the same shape Mudlet gives a profile copied over an existing
790
+ * one.
791
+ *
792
+ * A last line of defence for the paths that create a profile without a form to
793
+ * validate: importing a Mudlet folder or zip, seeding a brand's profile, or
794
+ * starting a bundled game. Those must not fail on a name clash, but they must
795
+ * not produce two profiles sharing a name either — `getProfiles()` is keyed by
796
+ * name and would silently return only one of them, and every name-addressed
797
+ * script API would resolve to whichever came first.
798
+ */
799
+ export declare function uniqueConnectionName(name: string, connections: MudConnection[], exceptId?: string): string;
684
800
  export {};