@mudlet/mudlet-web 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/dist-lib/assets/qt-resources/index.d.ts +16 -0
- package/dist-lib/branding.d.ts +1 -1
- package/dist-lib/hooks/useMudSession.d.ts +1 -1
- package/dist-lib/hooks/useOutput.d.ts +3 -1
- package/dist-lib/import/defaultPackages.d.ts +35 -2
- package/dist-lib/import/defaults/generic_mapper/generic_mapper.mpackage +0 -0
- package/dist-lib/import/defaults/gui-drop/gui-drop.mpackage +0 -0
- package/dist-lib/import/defaults/{run-lua-code.mpackage → mudlet-base-ui/mudlet-base-ui.mpackage} +0 -0
- package/dist-lib/import/defaults/run-lua-code/run-lua-code.mpackage +0 -0
- package/dist-lib/import/packageExport.d.ts +71 -0
- package/dist-lib/import/packageInstaller.d.ts +4 -1
- package/dist-lib/index.js +45935 -40688
- package/dist-lib/logging/SessionLogger.d.ts +66 -1
- package/dist-lib/map/MapStore.d.ts +32 -4
- package/dist-lib/map/mapImageExport.d.ts +1 -1
- package/dist-lib/map/mapZoom.d.ts +71 -0
- package/dist-lib/mud/ItemIdSequence.d.ts +23 -0
- package/dist-lib/mud/MudSession.d.ts +113 -11
- package/dist-lib/mud/PatternEngine.d.ts +6 -1
- package/dist-lib/mud/commandSplit.d.ts +16 -0
- package/dist-lib/mud/connection/LineAssembler.d.ts +56 -0
- package/dist-lib/mud/connection/MudClient.d.ts +120 -16
- package/dist-lib/mud/connection/TelnetNegotiator.d.ts +39 -0
- package/dist-lib/mud/connection/telnetByteTags.d.ts +35 -0
- package/dist-lib/mud/events.d.ts +19 -4
- package/dist-lib/mud/games/bundledGames.d.ts +29 -0
- package/dist-lib/mud/games/gameIcons.d.ts +5 -0
- package/dist-lib/mud/keybindings/KeyEngine.d.ts +9 -2
- package/dist-lib/mud/keybindings/browserReservedKeys.d.ts +5 -1
- package/dist-lib/mud/keybindings/keyEventTarget.d.ts +17 -0
- package/dist-lib/mud/keybindings/qtKeys.d.ts +2 -0
- package/dist-lib/mud/protocol/charLoginFlow.d.ts +68 -0
- package/dist-lib/mud/protocol/charset.d.ts +27 -5
- package/dist-lib/mud/protocol/constants.d.ts +1 -0
- package/dist-lib/mud/protocol/gmcp.d.ts +19 -3
- package/dist-lib/mud/protocol/index.d.ts +1 -1
- package/dist-lib/mud/protocol/mxp.d.ts +28 -5
- package/dist-lib/mud/replay/ReplayPlayer.d.ts +17 -0
- package/dist-lib/mud/text/Console.d.ts +64 -0
- package/dist-lib/mud/text/FormatState.d.ts +66 -3
- package/dist-lib/mud/text/hyperlinkVisibility.d.ts +35 -0
- package/dist-lib/mud/text/osc8Docs.d.ts +23 -0
- package/dist-lib/mud/text/serverWrap.d.ts +191 -0
- package/dist-lib/mud/timers/TimerEngine.d.ts +43 -12
- package/dist-lib/mud/triggers/TriggerEngine.d.ts +112 -3
- package/dist-lib/scripting/EngineHost.d.ts +56 -3
- package/dist-lib/scripting/IScriptingRuntime.d.ts +16 -0
- package/dist-lib/scripting/MxpFrameManager.d.ts +118 -0
- package/dist-lib/scripting/ScriptingAPI.d.ts +323 -54
- package/dist-lib/scripting/ScriptingEngine.d.ts +180 -23
- package/dist-lib/scripting/http/HttpService.d.ts +51 -1
- package/dist-lib/scripting/lua/LuaRuntime.d.ts +151 -2
- package/dist-lib/scripting/lua/bindings/map.d.ts +0 -12
- package/dist-lib/scripting/lua/utf8Patterns.d.ts +59 -0
- package/dist-lib/storage/index.d.ts +1 -1
- package/dist-lib/storage/persistentStorage.d.ts +10 -0
- package/dist-lib/storage/schema.d.ts +116 -0
- package/dist-lib/styles.css +1 -1
- package/dist-lib/ui/BundledGameGrid.d.ts +21 -0
- package/dist-lib/ui/CommandBar.d.ts +7 -1
- package/dist-lib/ui/ConnectionGrid.d.ts +4 -1
- package/dist-lib/ui/FilePickerModal.d.ts +3 -3
- package/dist-lib/ui/HelpModal.d.ts +11 -0
- package/dist-lib/ui/LogBrowserModal.d.ts +4 -1
- package/dist-lib/ui/PlayerMarkerPreview.d.ts +20 -0
- package/dist-lib/ui/Toolbar.d.ts +2 -1
- package/dist-lib/ui/VfsPickerModal.d.ts +26 -0
- package/dist-lib/ui/components/FileSourceButton.d.ts +47 -0
- package/dist-lib/ui/components/index.d.ts +1 -0
- package/dist-lib/ui/helpTopics.d.ts +19 -0
- package/dist-lib/ui/labels/LabelManager.d.ts +7 -0
- package/dist-lib/ui/layout/ScriptWindow.d.ts +11 -2
- package/dist-lib/ui/markdown.d.ts +10 -1
- package/dist-lib/ui/output/OutputArea.d.ts +11 -1
- package/dist-lib/ui/output/OutputContextMenu.d.ts +3 -1
- package/dist-lib/ui/output/OutputRenderer.d.ts +7 -1
- package/dist-lib/ui/output/OutputSearchBar.d.ts +25 -0
- package/dist-lib/ui/output/StickyOutputPanel.d.ts +5 -1
- package/dist-lib/ui/output/outputSearch.d.ts +130 -0
- package/dist-lib/ui/search/matcher.d.ts +15 -0
- package/dist-lib/ui/search/useDebounced.d.ts +3 -0
- package/dist-lib/ui/tts/TtsManager.d.ts +3 -0
- package/dist-lib/ui/useCommandHistory.d.ts +4 -2
- package/dist-lib/ui/useOpenProfiles.d.ts +26 -0
- package/dist-lib/ui/video/VideoManager.d.ts +17 -0
- package/dist-lib/ui/windows/WindowManager.d.ts +132 -2
- package/dist-lib/ui/windows/panels/MapPanel.d.ts +4 -1
- package/dist-lib/ui/windows/panels/PackageExportModal.d.ts +18 -0
- package/dist-lib/ui/windows/panels/TextPanel.d.ts +3 -1
- package/dist-lib/ui/windows/types.d.ts +35 -0
- package/dist-lib/utils/describeThrown.d.ts +22 -0
- package/dist-lib/utils/fontLoader.d.ts +5 -0
- package/dist-lib/vite.js +22 -0
- package/package.json +10 -6
- package/dist-lib/scripting/lua/mudlet-lua/generic-mapper/generic_mapper.mpackage +0 -0
- package/dist-lib/ui/windows/panels/VfsModulePickerModal.d.ts +0 -8
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import type { MudSession } from '../mud/MudSession';
|
|
2
|
+
import type { LogFormat } from '../logging/SessionLogger';
|
|
2
3
|
import type { AliasEngine } from '../mud/aliases/AliasEngine';
|
|
3
4
|
import { TriggerEngine } from '../mud/triggers/TriggerEngine';
|
|
4
5
|
import type { TimerEngine } from '../mud/timers/TimerEngine';
|
|
5
6
|
import type { KeyEngine } from '../mud/keybindings/KeyEngine';
|
|
6
7
|
import type { ButtonNode, ScriptNode } from '../storage/schema';
|
|
7
8
|
import { type InstallOutcome } from './ScriptingAPI';
|
|
8
|
-
import type
|
|
9
|
+
import { type EngineHost, type TempComplexTriggerSpec } from './EngineHost';
|
|
10
|
+
import { ItemIdSequence } from '../mud/ItemIdSequence';
|
|
9
11
|
import type { LuaGlobalEntry } from './IScriptingRuntime';
|
|
10
12
|
import { ProfileVFS } from './vfs/ProfileVFS';
|
|
11
13
|
import type { PackageManifest } from '../storage/schema';
|
|
@@ -74,13 +76,18 @@ export declare class ScriptingEngine implements EngineHost {
|
|
|
74
76
|
/** For a linked Mudlet profile: the timestamped current/*.xml filename this
|
|
75
77
|
* session writes back to (created lazily on first write, reused thereafter). */
|
|
76
78
|
private mudletSaveName;
|
|
77
|
-
private mspBaseUrl
|
|
79
|
+
private mspBaseUrl?;
|
|
78
80
|
private gmcpMediaDefaultUrl;
|
|
79
81
|
private exitFired;
|
|
80
82
|
private readonly beforeUnload;
|
|
81
83
|
private uuidToNumericId;
|
|
82
|
-
|
|
84
|
+
/** The profile's single item-id sequence, shared with every engine and with
|
|
85
|
+
* the Lua runtime's temporary items — see {@link ItemIdSequence}. */
|
|
86
|
+
readonly itemIds: ItemIdSequence;
|
|
83
87
|
private numericIdFor;
|
|
88
|
+
/** Hand out the next item id. Backs the Lua runtime's temporary items, so a
|
|
89
|
+
* temp and a permanent item can never collide on one number. */
|
|
90
|
+
allocateItemId(): number;
|
|
84
91
|
constructor(session: MudSession, aliasEngine: AliasEngine, triggerEngine: TriggerEngine, timerEngine: TimerEngine, keyEngine: KeyEngine, connectionId: string, connectionName?: string, proxyUrlGetter?: () => string | undefined, injectedVfs?: ProfileVFS | null);
|
|
85
92
|
/**
|
|
86
93
|
* Subscribe to the appStore and apply diffs synchronously on every
|
|
@@ -168,6 +175,19 @@ export declare class ScriptingEngine implements EngineHost {
|
|
|
168
175
|
getModulePriority(moduleName: string): number;
|
|
169
176
|
/** List installed module names. Order matches install order. */
|
|
170
177
|
getModuleNames(): string[];
|
|
178
|
+
/**
|
|
179
|
+
* Write every module flagged to sync back out to its own file.
|
|
180
|
+
*
|
|
181
|
+
* Called by saveProfile, which is the only moment it happens — and the
|
|
182
|
+
* moment it has to: a module shared between profiles carries this one's
|
|
183
|
+
* edits to the others through its file, so a save that skipped this left
|
|
184
|
+
* them in our store alone, to be lost the next time another profile read
|
|
185
|
+
* the module back.
|
|
186
|
+
*
|
|
187
|
+
* Fire-and-forget per module, like syncModule itself: the write is async,
|
|
188
|
+
* and a save reports on what it started rather than waiting.
|
|
189
|
+
*/
|
|
190
|
+
saveSyncedModules(): void;
|
|
171
191
|
/** Snapshot of a module's manifest, or null if not installed / not a module. */
|
|
172
192
|
getModuleInfo(moduleName: string): PackageManifest | null;
|
|
173
193
|
/**
|
|
@@ -246,8 +266,31 @@ export declare class ScriptingEngine implements EngineHost {
|
|
|
246
266
|
private initRuntime;
|
|
247
267
|
/** Run a chunk of Lua on behalf of a clicked hyperlink. */
|
|
248
268
|
runLinkCode(code: string): void;
|
|
249
|
-
/**
|
|
250
|
-
*
|
|
269
|
+
/**
|
|
270
|
+
* Mudlet `Host::send(cmd, wantPrint, dontExpandAliases = false)` — the one
|
|
271
|
+
* path every command the player types, and every item's built-in `command`
|
|
272
|
+
* field, travels down. Three stages, in this order:
|
|
273
|
+
*
|
|
274
|
+
* 1. echo the **whole, unsplit** text under the showSentText mode;
|
|
275
|
+
* 2. split it on the profile's command separator;
|
|
276
|
+
* 3. run each part through the aliases, and put on the wire whatever no
|
|
277
|
+
* alias consumed.
|
|
278
|
+
*
|
|
279
|
+
* The order is the point. Echoing before the alias pass is why typing an
|
|
280
|
+
* alias shows the text you typed even though the alias swallows it — and
|
|
281
|
+
* why the alias's own command field, arriving back here in turn, is echoed
|
|
282
|
+
* again as a second line. Splitting after the echo is why `n;;s` echoes as
|
|
283
|
+
* one line but sends two commands.
|
|
284
|
+
*
|
|
285
|
+
* Lua `send()` skips only stage 3 ({@link ScriptingAPI.send}); Mudlet's
|
|
286
|
+
* `expandAlias(text, echo)` is exactly this function.
|
|
287
|
+
*/
|
|
288
|
+
hostSend(text: string, echo?: boolean): void;
|
|
289
|
+
/** Nesting depth of {@link hostSend} — see the runaway-alias note there. */
|
|
290
|
+
private sendDepth;
|
|
291
|
+
private static readonly MAX_SEND_DEPTH;
|
|
292
|
+
/** Mudlet `expandAlias(text, echo)` — `Host::send` with both defaults, i.e.
|
|
293
|
+
* "run this as though I had typed it". */
|
|
251
294
|
expandAlias(text: string, echo: boolean): void;
|
|
252
295
|
/** Mudlet `reconnect()` — redial the last URL, refused during teardown. */
|
|
253
296
|
requestReconnect(): boolean;
|
|
@@ -255,7 +298,11 @@ export declare class ScriptingEngine implements EngineHost {
|
|
|
255
298
|
dispatchSendRequest(text: string): boolean;
|
|
256
299
|
/** Names of every package installed in this profile. */
|
|
257
300
|
getPackageNames(): string[];
|
|
258
|
-
/**
|
|
301
|
+
/** What the module's config.lua declared, with Lua-set overrides applied.
|
|
302
|
+
* The same contract as getPackageInfo — see manifestInfoBase. This used to
|
|
303
|
+
* hand back the whole manifest, so callers saw mudix's own bookkeeping
|
|
304
|
+
* (installedAt, sourceFile, and latterly declaredInfo itself) alongside the
|
|
305
|
+
* fields the module author actually wrote. */
|
|
259
306
|
getModuleInfoRecord(name: string): Record<string, unknown> | null;
|
|
260
307
|
/** Rewrite VFS-relative url(...) references to service-worker paths. */
|
|
261
308
|
rewriteCss(css: string): string;
|
|
@@ -267,6 +314,8 @@ export declare class ScriptingEngine implements EngineHost {
|
|
|
267
314
|
* getMudletHomeDir()-prefixed paths work) and relative ones against the
|
|
268
315
|
* profile root. */
|
|
269
316
|
readFileBytes(path: string): Uint8Array | null;
|
|
317
|
+
writeFileBytes(path: string, bytes: Uint8Array): boolean;
|
|
318
|
+
configDirectory(): string | null;
|
|
270
319
|
private createRuntime;
|
|
271
320
|
/**
|
|
272
321
|
* Tear down a script's event-handler registrations. Used when a script is
|
|
@@ -284,7 +333,7 @@ export declare class ScriptingEngine implements EngineHost {
|
|
|
284
333
|
* loads the new scripts synchronously inside that commit, so by the time
|
|
285
334
|
* this method runs the package's event handlers are already registered.
|
|
286
335
|
*/
|
|
287
|
-
notifyPackageInstalled(packageName: string): void;
|
|
336
|
+
notifyPackageInstalled(packageName: string, fileName?: string): void;
|
|
288
337
|
/**
|
|
289
338
|
* Raise sysUninstall / sysUninstallPackage. Call this BEFORE removing the
|
|
290
339
|
* package's items from the store so the package's own handlers (and the
|
|
@@ -342,6 +391,21 @@ export declare class ScriptingEngine implements EngineHost {
|
|
|
342
391
|
* reloads. Returns null when the file can't be located or fetched.
|
|
343
392
|
*/
|
|
344
393
|
private resolveMspMedia;
|
|
394
|
+
/**
|
|
395
|
+
* Last-resort media location when a server plays a file without ever
|
|
396
|
+
* announcing where it lives — neither an MSP `U=` nor a GMCP
|
|
397
|
+
* `Client.Media.Default { url }`. Mudlet guesses the MUD's own website:
|
|
398
|
+
* `https://www.<host>/media/` (TMedia::parseUrl). The host is the telnet
|
|
399
|
+
* host — for a `websocket`-mode profile, the endpoint's hostname — the same
|
|
400
|
+
* value getConnectionInfo() reports, standing in for Mudlet's `Host::mUrl`.
|
|
401
|
+
*
|
|
402
|
+
* The one deviation from Mudlet: it prepends `www.` unconditionally, which
|
|
403
|
+
* turns an already-qualified `www.example.com` into `www.www.example.com`.
|
|
404
|
+
* We skip the prefix when the host already carries it. Returns undefined
|
|
405
|
+
* when there's no host to guess from, so the caller reports "no base URL"
|
|
406
|
+
* rather than fetching a nonsense URL.
|
|
407
|
+
*/
|
|
408
|
+
private defaultMediaLocation;
|
|
345
409
|
/**
|
|
346
410
|
* Resolve a media `file` (+ optional base `url` directory) to a VFS-relative
|
|
347
411
|
* path under `media/` the SoundManager loader can read, downloading and
|
|
@@ -349,8 +413,9 @@ export declare class ScriptingEngine implements EngineHost {
|
|
|
349
413
|
* protocol (`handleClientMedia`). The whole filename — including any
|
|
350
414
|
* subdirectories — is appended to the base URL and mirrored under `media/`,
|
|
351
415
|
* so the cache layout matches the server's. `..`/`.` segments are rejected
|
|
352
|
-
* so a hostile server can't escape the cache root.
|
|
353
|
-
*
|
|
416
|
+
* so a hostile server can't escape the cache root. With no base URL at all,
|
|
417
|
+
* {@link defaultMediaLocation} guesses one from the MUD's host. Returns null
|
|
418
|
+
* when the file can't be located or fetched.
|
|
354
419
|
*/
|
|
355
420
|
private resolveMediaFile;
|
|
356
421
|
/**
|
|
@@ -379,9 +444,15 @@ export declare class ScriptingEngine implements EngineHost {
|
|
|
379
444
|
*/
|
|
380
445
|
uninstallPackageByName(packageName: string): boolean;
|
|
381
446
|
/**
|
|
382
|
-
* Toggle
|
|
447
|
+
* Toggle scripts' enabled flag by name (Mudlet enableScript/disableScript).
|
|
383
448
|
* The store subscription picks up the change synchronously and either loads
|
|
384
449
|
* or unloads handlers in the runtime.
|
|
450
|
+
*
|
|
451
|
+
* Every script sharing the name flips, not just the first — same rule as
|
|
452
|
+
* {@link toggleTriggerByName}, and Other_spec pins it. Names are not unique
|
|
453
|
+
* in the tree, so stopping at the first match would leave duplicates in a
|
|
454
|
+
* state the caller never asked for and `isActive(name)` would disagree with
|
|
455
|
+
* `exists(name)`.
|
|
385
456
|
*/
|
|
386
457
|
toggleScriptByName(name: string, enabled: boolean): boolean;
|
|
387
458
|
/**
|
|
@@ -438,6 +509,19 @@ export declare class ScriptingEngine implements EngineHost {
|
|
|
438
509
|
* Those live in the Lua runtime, not the saved tree. */
|
|
439
510
|
setTempItemEnabled(id: number, enabled: boolean): boolean;
|
|
440
511
|
setForceMxpProcessorOn(on: boolean): void;
|
|
512
|
+
/** Mudlet `cTelnet::autoEnableMXPProcessor`. Runs when MXP started from an
|
|
513
|
+
* in-band `ESC[<n>z` rather than a telnet option-91 handshake: such servers
|
|
514
|
+
* are IRE-style and never send mode switches, they just emit secure tags —
|
|
515
|
+
* so without the secure-mode lock every `<SEND>`/`<A>`/definition tag would
|
|
516
|
+
* be discarded as unsafe. The `promptForMXPProcessorOn` latch records that
|
|
517
|
+
* this profile has been auto-enabled once, which is what lets a user turn
|
|
518
|
+
* `specialForceMXPProcessorOn` back off without being overridden on the
|
|
519
|
+
* next connect (the gate lives in MudClient → TelnetNegotiator).
|
|
520
|
+
*
|
|
521
|
+
* A second detection while already forced on is a *re-initialisation* (a
|
|
522
|
+
* server re-announcing MXP after e.g. `config mxp on`): re-apply the lock,
|
|
523
|
+
* but stay silent — Mudlet returns before its postMessage there. */
|
|
524
|
+
private autoEnableMxpProcessor;
|
|
441
525
|
existsByName(nameOrId: string | number, type: string): number;
|
|
442
526
|
/**
|
|
443
527
|
* Mudlet `isActive(nameOrId, type [, checkAncestors])`. Returns the count of
|
|
@@ -452,6 +536,7 @@ export declare class ScriptingEngine implements EngineHost {
|
|
|
452
536
|
* findItems, isAncestorsActive). Type aliases mirror Mudlet: "key" and
|
|
453
537
|
* "keybind" both target keybindings. Unknown types return an empty list.
|
|
454
538
|
*/
|
|
539
|
+
isKnownItemType(type: string): boolean;
|
|
455
540
|
private nodeListForType;
|
|
456
541
|
private nodeTypeLabel;
|
|
457
542
|
/**
|
|
@@ -473,7 +558,7 @@ export declare class ScriptingEngine implements EngineHost {
|
|
|
473
558
|
* true) toggles exact vs substring; `caseSensitive` (default true) toggles
|
|
474
559
|
* case folding. Empty array when nothing matches or the type is unknown.
|
|
475
560
|
*/
|
|
476
|
-
findItemsByName(name: string, type: string, exact: boolean, caseSensitive: boolean): number[];
|
|
561
|
+
findItemsByName(name: string, type: string, exact: boolean, caseSensitive: boolean): number[] | null;
|
|
477
562
|
/**
|
|
478
563
|
* Mudlet `isAncestorsActive(id, type)`. True when every ancestor group of
|
|
479
564
|
* the item is enabled (the item's own state is ignored); true when the item
|
|
@@ -533,6 +618,33 @@ export declare class ScriptingEngine implements EngineHost {
|
|
|
533
618
|
*/
|
|
534
619
|
createPermPromptTrigger(name: string, parent: string, code: string): number;
|
|
535
620
|
private createPermTrigger;
|
|
621
|
+
/**
|
|
622
|
+
* Mudlet `tempComplexRegexTrigger(...)`. A session-scoped trigger with
|
|
623
|
+
* everything a permanent one can have — an AND chain across lines, a filter
|
|
624
|
+
* that hands its captures to children, a fire length, a line delta, colour
|
|
625
|
+
* patterns — because that is what the call offers and none of it fits the
|
|
626
|
+
* flat temp-trigger primitive. So it makes a real node, marked temporary so
|
|
627
|
+
* it is not saved with the profile.
|
|
628
|
+
*
|
|
629
|
+
* Calling it again with a name that is already taken does not replace that
|
|
630
|
+
* trigger — it ADDS to it. Mudlet names the argument "trigger name create
|
|
631
|
+
* or add to": the new pattern is appended to the ones already there and the
|
|
632
|
+
* trigger is rebuilt around the longer list, which is how a multiline AND
|
|
633
|
+
* chain is assembled one condition per call.
|
|
634
|
+
*/
|
|
635
|
+
createTempComplexTrigger(spec: TempComplexTriggerSpec): number;
|
|
636
|
+
/**
|
|
637
|
+
* Remove a temporary trigger by the numeric id `tempComplexRegexTrigger`
|
|
638
|
+
* handed the script. False when that id names no temporary trigger — a
|
|
639
|
+
* permanent one is refused, as Mudlet's killTrigger refuses it.
|
|
640
|
+
*/
|
|
641
|
+
removeTemporaryTriggerById(id: number): boolean;
|
|
642
|
+
/** Remove a trigger and everything under it. A child outlives its parent
|
|
643
|
+
* nowhere in the tree, and a permanent trigger parented to a temporary one
|
|
644
|
+
* goes with it — which is the only way it could have been reached. */
|
|
645
|
+
private removeTriggerSubtree;
|
|
646
|
+
/** The root ancestor of a trigger node — what a lineage is recorded against. */
|
|
647
|
+
private rootTriggerOf;
|
|
536
648
|
/**
|
|
537
649
|
* Mudlet `permAlias(name, parent, regex, luaCode)`. Creates a saved alias
|
|
538
650
|
* named `name` under the alias group `parent` (empty = root). The pattern
|
|
@@ -574,6 +686,16 @@ export declare class ScriptingEngine implements EngineHost {
|
|
|
574
686
|
createTempButtonToolbar(name: string, orientation: number, location: number): number;
|
|
575
687
|
/** Mudlet `setButtonState(name, state)`. Flips the buttonState on the named
|
|
576
688
|
* two-state button. */
|
|
689
|
+
/**
|
|
690
|
+
* What `name` refers to, so the Lua side can say which of Mudlet's several
|
|
691
|
+
* refusals applies: no such button, or a button that has no state to set
|
|
692
|
+
* because it is not a two-state one.
|
|
693
|
+
*/
|
|
694
|
+
buttonKindByName(name: string): 'missing' | 'plain' | 'pushdown';
|
|
695
|
+
/** True when the state actually changed. Mudlet answers false for a button
|
|
696
|
+
* that was already in the state asked for — "nothing to do" rather than
|
|
697
|
+
* "could not do it", which is why the caller can tell them apart only by
|
|
698
|
+
* having checked the name first. */
|
|
577
699
|
setButtonStateByName(name: string, state: boolean): boolean;
|
|
578
700
|
/** Mudlet `getButtonState(name)`. Reads the pressed state on a two-state
|
|
579
701
|
* button by name. Returns null when no such button (the Lua binding maps
|
|
@@ -582,10 +704,24 @@ export declare class ScriptingEngine implements EngineHost {
|
|
|
582
704
|
/** Mudlet `setButtonStyleSheet(name, css)`. Stores raw CSS on the
|
|
583
705
|
* ButtonNode; ButtonsBar applies it inline. */
|
|
584
706
|
setButtonStyleSheetByName(name: string, css: string): boolean;
|
|
585
|
-
/**
|
|
586
|
-
*
|
|
587
|
-
*
|
|
588
|
-
|
|
707
|
+
/**
|
|
708
|
+
* Mudlet `showToolBar(name)` / `hideToolBar(name)`. Toggles the toolbar's
|
|
709
|
+
* own enabled flag — the ButtonsBar filters by isEffectivelyEnabled, so that
|
|
710
|
+
* is the show/hide hook. Returns null on success, or the reason it moved
|
|
711
|
+
* nothing (which the Bridge shapes into Mudlet's `(nil, errMsg)`).
|
|
712
|
+
*
|
|
713
|
+
* Three rules from `ActionUnit::setToolBarActive`, none of them obvious:
|
|
714
|
+
*
|
|
715
|
+
* - A toolbar that came in a package answers to its OWN name, and the
|
|
716
|
+
* package's root node is left alone. Reaching a toolbar through its
|
|
717
|
+
* package used to be the only way, which meant hiding one hid every bar
|
|
718
|
+
* that package installed.
|
|
719
|
+
* - The package's name still works, and then it moves every toolbar in it.
|
|
720
|
+
* - A floating toolbar is refused, and says so: these functions dock and
|
|
721
|
+
* undock, and a floating bar is not in the docking arrangement at all.
|
|
722
|
+
* Reporting it as missing sent scripts looking for a name they had right.
|
|
723
|
+
*/
|
|
724
|
+
toggleToolBarByName(name: string, show: boolean): string | null;
|
|
589
725
|
/**
|
|
590
726
|
* Mudlet `setScript(name, luaCode[, pos])`. Replaces the source of the
|
|
591
727
|
* `pos`-th script (1-indexed; default 1) named `name`. Updating via the
|
|
@@ -595,14 +731,15 @@ export declare class ScriptingEngine implements EngineHost {
|
|
|
595
731
|
*/
|
|
596
732
|
setScriptByName(name: string, code: string, pos: number): number;
|
|
597
733
|
/**
|
|
598
|
-
* Mudlet `getScript(name [, pos]) → code,
|
|
599
|
-
* pos-th (1-indexed; default 1) script named `name` and
|
|
600
|
-
*
|
|
601
|
-
* turns that into (
|
|
734
|
+
* Mudlet `getScript(name [, pos]) → code, id`. Returns the source of the
|
|
735
|
+
* pos-th (1-indexed; default 1) script named `name` and that script's own
|
|
736
|
+
* numeric id. Null when nothing sits at that position — the Bridge.lua
|
|
737
|
+
* wrapper turns that into Mudlet's (-1, message).
|
|
602
738
|
*/
|
|
739
|
+
removeScriptById(id: number): boolean;
|
|
603
740
|
getScriptByName(name: string, pos: number): {
|
|
604
741
|
code: string;
|
|
605
|
-
|
|
742
|
+
id: number;
|
|
606
743
|
} | null;
|
|
607
744
|
/**
|
|
608
745
|
* Mudlet `killTimer/killAlias/killTrigger/killKey(name)` deletes every
|
|
@@ -638,12 +775,18 @@ export declare class ScriptingEngine implements EngineHost {
|
|
|
638
775
|
private runScriptLoad;
|
|
639
776
|
get currentVFS(): ProfileVFS | null;
|
|
640
777
|
/**
|
|
641
|
-
*
|
|
642
|
-
*
|
|
778
|
+
* Submit one line from the command bar — Mudlet's `TCommandLine` calling
|
|
779
|
+
* `Host::send` per newline-separated line. Echoes it, splits it on the
|
|
780
|
+
* command separator, runs the parts through the aliases, and sends what
|
|
781
|
+
* survives (raising sysDataSendRequest per part, so a handler calling
|
|
782
|
+
* denyCurrentSend() can still abort an individual command).
|
|
643
783
|
*/
|
|
644
784
|
sendCommand(text: string): void;
|
|
645
785
|
/** Run input through aliases. Returns true if an alias matched (caller should not send). */
|
|
646
786
|
processInput(text: string): boolean;
|
|
787
|
+
/** Nesting depth of {@link processInput} — see the note there. */
|
|
788
|
+
private aliasDepth;
|
|
789
|
+
private processInputPass;
|
|
647
790
|
/** Process a keyboard event. Returns true if a keybinding consumed it. */
|
|
648
791
|
processKey(event: KeyboardEvent): boolean;
|
|
649
792
|
raiseEvent(event: string, args?: unknown[]): void;
|
|
@@ -658,7 +801,9 @@ export declare class ScriptingEngine implements EngineHost {
|
|
|
658
801
|
setCmdLineValue(text: string): void;
|
|
659
802
|
/** Hand the API a startLogging hook. Wired by ProfileSession, which owns
|
|
660
803
|
* the actual SessionLogger lifecycle. */
|
|
661
|
-
setLoggingToggler(fn: ((enabled: boolean) => boolean) | null): void;
|
|
804
|
+
setLoggingToggler(fn: ((enabled: boolean, format: LogFormat) => boolean) | null): void;
|
|
805
|
+
/** Where the live logger is writing, so startLogging can report the file. */
|
|
806
|
+
setLoggingPathProvider(fn: (() => string | null) | null): void;
|
|
662
807
|
/** Mudlet's "Show errors in main console" — when on, script errors are also
|
|
663
808
|
* echoed (in red) into the main output window, not just the Errors tab. */
|
|
664
809
|
setShowErrorsInMainWindow(enabled: boolean): void;
|
|
@@ -774,7 +919,19 @@ export declare class ScriptingEngine implements EngineHost {
|
|
|
774
919
|
processFlushBatch(groups: {
|
|
775
920
|
text: string;
|
|
776
921
|
type: string;
|
|
922
|
+
fromServer?: boolean;
|
|
777
923
|
}[]): void;
|
|
924
|
+
/**
|
|
925
|
+
* Free everything killed while this batch was processed.
|
|
926
|
+
*
|
|
927
|
+
* Mudlet's alias/trigger/timer/key units each defer freeing a killed item to
|
|
928
|
+
* the end of the line that killed it, rather than dropping it at the kill.
|
|
929
|
+
* That is what makes a killed item still findable for the rest of the pass —
|
|
930
|
+
* `exists` finds it, `isActive` says 0, and a second kill can tell "already
|
|
931
|
+
* dead" (false) from "never existed" (also false, but for the other reason).
|
|
932
|
+
* Nothing can fire in the meantime: killing unsubscribes immediately.
|
|
933
|
+
*/
|
|
934
|
+
private reapKilledTempItems;
|
|
778
935
|
/**
|
|
779
936
|
* Attach clickable hyperlinks for the MXP `<SEND>`/`<A>` ranges the parser
|
|
780
937
|
* found. `setHyperlink` overlays each range while preserving the segments'
|
|
@@ -2,20 +2,70 @@ import type { ProfileVFS } from '../vfs/ProfileVFS';
|
|
|
2
2
|
type EmitFn = (event: string, args: unknown[]) => void;
|
|
3
3
|
type VFSGetter = () => ProfileVFS | null;
|
|
4
4
|
type ProxyUrlGetter = () => string | undefined;
|
|
5
|
+
/** Runs `fn` off the current call stack. See {@link HttpService.emitLater}. */
|
|
6
|
+
type DeferFn = (fn: () => void) => void;
|
|
7
|
+
/** Bytes behind a path in a read-only bundled namespace, or null. */
|
|
8
|
+
type LocalReader = (path: string) => Uint8Array | null;
|
|
5
9
|
export declare class HttpService {
|
|
6
10
|
private readonly emit;
|
|
7
11
|
private readonly vfsGetter;
|
|
8
12
|
private readonly proxyUrlGetter;
|
|
13
|
+
private readonly defer;
|
|
14
|
+
/** Consulted before the profile VFS when serving a `file:` URL, so a
|
|
15
|
+
* bundled path resolves the same way Lua's io.open resolves it. */
|
|
16
|
+
private readonly localReader;
|
|
9
17
|
private readonly proxiedOrigins;
|
|
10
|
-
|
|
18
|
+
/**
|
|
19
|
+
* The response record Mudlet hands to every HTTP event as its last argument:
|
|
20
|
+
* `{ headers = {...}, cookies = {...} }`. Scripts read it to branch on what
|
|
21
|
+
* came back — a content type, a rate-limit header — and we were passing an
|
|
22
|
+
* empty string, so `response.headers` was an index into nothing.
|
|
23
|
+
*
|
|
24
|
+
* `cookies` is always empty, and has to be: a browser never exposes
|
|
25
|
+
* `Set-Cookie` to script, cross-origin or not. It is still present, because
|
|
26
|
+
* the shape is the contract — a script doing `response.cookies["session"]`
|
|
27
|
+
* should read nil, not fail on indexing a missing table.
|
|
28
|
+
*/
|
|
29
|
+
private responseRecord;
|
|
30
|
+
constructor(emit: EmitFn, vfsGetter: VFSGetter, proxyUrlGetter?: ProxyUrlGetter, defer?: DeferFn,
|
|
31
|
+
/** Consulted before the profile VFS when serving a `file:` URL, so a
|
|
32
|
+
* bundled path resolves the same way Lua's io.open resolves it. */
|
|
33
|
+
localReader?: LocalReader);
|
|
11
34
|
downloadFile(saveTo: string, url: string): void;
|
|
12
35
|
getHTTP(url: string, headers?: Record<string, string>): void;
|
|
13
36
|
postHTTP(data: string | null, url: string, headers?: Record<string, string>, file?: string): void;
|
|
14
37
|
putHTTP(data: string | null, url: string, headers?: Record<string, string>, file?: string): void;
|
|
15
38
|
deleteHTTP(url: string, headers?: Record<string, string>): void;
|
|
16
39
|
customHTTP(method: string, data: string | null, url: string, headers?: Record<string, string>, file?: string): void;
|
|
40
|
+
/**
|
|
41
|
+
* Serve a `file:` URL out of the VFS, reporting through the same
|
|
42
|
+
* sysDownloadDone/sysDownloadError a network download would.
|
|
43
|
+
*
|
|
44
|
+
* The path is the URL's own, percent-decoded — `file:///lua/x` reads
|
|
45
|
+
* `/lua/x`, which may be the read-only bundled namespace as readily as the
|
|
46
|
+
* profile, exactly as Lua's io.open sees both.
|
|
47
|
+
*/
|
|
48
|
+
private copyLocalFile;
|
|
17
49
|
private runDownload;
|
|
18
50
|
private readWithProgress;
|
|
51
|
+
/**
|
|
52
|
+
* Emit on a later turn of the event loop.
|
|
53
|
+
*
|
|
54
|
+
* Every other emit here fires from an async continuation, so it is already
|
|
55
|
+
* off the call that started the request. The synchronous failures are the
|
|
56
|
+
* exception — building an upload body, or refusing a url scheme outright —
|
|
57
|
+
* because they would otherwise emit, and therefore dispatch Lua event
|
|
58
|
+
* handlers, while still inside the `__postHTTP`/`__downloadFile` binding
|
|
59
|
+
* that Lua itself called. Re-entering the Lua state mid-call crashes
|
|
60
|
+
* wasmoon outright ("memory access out of bounds"), taking the whole
|
|
61
|
+
* runtime with it rather than failing one call.
|
|
62
|
+
*
|
|
63
|
+
* The caller supplies the deferral so it can pick a queue a script can
|
|
64
|
+
* actually observe: microtasks are fine in the app, but a synchronous Lua
|
|
65
|
+
* run (the busted harness) never yields to one, and the runtime hands us
|
|
66
|
+
* its timer queue instead.
|
|
67
|
+
*/
|
|
68
|
+
private emitLater;
|
|
19
69
|
private bodyForUpload;
|
|
20
70
|
private runRequest;
|
|
21
71
|
private fetchWithFallback;
|
|
@@ -7,8 +7,13 @@ export declare class LuaRuntime implements IScriptingRuntime {
|
|
|
7
7
|
private readonly api;
|
|
8
8
|
private vfs;
|
|
9
9
|
private readonly proxyUrlGetter;
|
|
10
|
+
/** Script-created temp aliases/triggers by id. `dead` marks one killed but
|
|
11
|
+
* not yet reaped: Mudlet frees a killed unit in the deferred cleanup it
|
|
12
|
+
* runs at the end of a line, not at the kill, so until then it is still
|
|
13
|
+
* findable while no longer firing — `exists` says 1, `isActive` says 0, and
|
|
14
|
+
* a second kill finds a corpse and answers false. {@link reapKilledTempItems}
|
|
15
|
+
* does the freeing. */
|
|
10
16
|
private readonly tempIds;
|
|
11
|
-
private nextTempId;
|
|
12
17
|
private readonly labelCbIds;
|
|
13
18
|
private cmdLineActionCbId;
|
|
14
19
|
private windowCmdLineActionCbIds;
|
|
@@ -17,8 +22,53 @@ export declare class LuaRuntime implements IScriptingRuntime {
|
|
|
17
22
|
private currentCaptureSpans;
|
|
18
23
|
private currentNamedSpans;
|
|
19
24
|
private currentFullMatchSpan;
|
|
25
|
+
/**
|
|
26
|
+
* Move the capture positions recorded for the line being processed to
|
|
27
|
+
* follow `delta` characters inserted at column `at`.
|
|
28
|
+
*
|
|
29
|
+
* A trigger that calls `insertText` before its own match and then
|
|
30
|
+
* `selectCaptureGroup` would otherwise select the text that has slid into
|
|
31
|
+
* where the capture used to be. A capture that starts at or after the
|
|
32
|
+
* insert moves whole; one the insert lands inside grows by it.
|
|
33
|
+
*/
|
|
34
|
+
shiftCaptureSpans(at: number, delta: number): void;
|
|
20
35
|
private _denyCurrentSend;
|
|
36
|
+
/** The read-only `/lua/` namespace: bundled Mudlet Lua, and in busted builds
|
|
37
|
+
* the spec corpus and its fixtures. Values are Latin-1 byte-strings. */
|
|
38
|
+
private builtinFiles;
|
|
39
|
+
/**
|
|
40
|
+
* Bytes behind a built-in `/lua/` path, or null when the path is not one.
|
|
41
|
+
*
|
|
42
|
+
* Lua's own `io.open` reaches these through the VFS shim, but a caller
|
|
43
|
+
* working in bytes does not: the package installer is handed a path and
|
|
44
|
+
* reads it through the *profile* VFS, which knows nothing about this
|
|
45
|
+
* namespace. That is why installing one of the corpus's fixture packages
|
|
46
|
+
* reported "file not found" for a file Lua could open perfectly well.
|
|
47
|
+
*/
|
|
48
|
+
readBuiltinBytes(path: string): Uint8Array | null;
|
|
21
49
|
private destroyed;
|
|
50
|
+
/**
|
|
51
|
+
* Set once the Lua WASM module has terminated for good — an Emscripten
|
|
52
|
+
* `ExitStatus` or `WebAssembly.RuntimeError` unwinding out of a call.
|
|
53
|
+
*
|
|
54
|
+
* Lua reaches `exit(EXIT_FAILURE)` in `luaD_throw` whenever an error is
|
|
55
|
+
* raised with no protected frame to catch it: a panic, or an allocation
|
|
56
|
+
* failure inside a JS-side API call (`lua_newthread`, `lua_pushstring`, …)
|
|
57
|
+
* that runs on the main state rather than inside a pcall. Emscripten then
|
|
58
|
+
* latches its own ABORT flag, so every later call into the module throws the
|
|
59
|
+
* same thing — one identical error per timer tick, forever, with nothing
|
|
60
|
+
* saying the engine is gone.
|
|
61
|
+
*
|
|
62
|
+
* Tracked apart from {@link destroyed} because teardown still has to run:
|
|
63
|
+
* the JS-side resources (global event channel, TTS, map dispatchers) outlive
|
|
64
|
+
* the WASM module and must still be released.
|
|
65
|
+
*/
|
|
66
|
+
private fatal;
|
|
67
|
+
/** Notified once, when {@link fatal} latches. The engine uses it to stop the
|
|
68
|
+
* timer pump — the only thing left that would keep calling in. */
|
|
69
|
+
onFatalError: (() => void) | null;
|
|
70
|
+
/** True once nothing can be executed any more, for either reason. */
|
|
71
|
+
private get inert();
|
|
22
72
|
private readonly watchedPaths;
|
|
23
73
|
private readonly rawFnPtrs;
|
|
24
74
|
private http;
|
|
@@ -29,6 +79,34 @@ export declare class LuaRuntime implements IScriptingRuntime {
|
|
|
29
79
|
private constructor();
|
|
30
80
|
static create(api: ScriptingAPI, vfs?: ProfileVFS | null, proxyUrlGetter?: () => string | undefined): Promise<LuaRuntime>;
|
|
31
81
|
private setup;
|
|
82
|
+
/**
|
|
83
|
+
* Make `tostring(someFunction)` safe — and Mudlet-shaped.
|
|
84
|
+
*
|
|
85
|
+
* wasmoon pushes every JS function as a C closure and gives it a metatable
|
|
86
|
+
* carrying `__tostring`/`__index` that dereference the JS value behind it.
|
|
87
|
+
* But Lua 5.1's `lua_setmetatable` on a non-table, non-userdata value sets
|
|
88
|
+
* the metatable for that *whole type* (`G(L)->mt[ttype(o)]`), so the last JS
|
|
89
|
+
* function bound here becomes the metatable of EVERY Lua function. Call
|
|
90
|
+
* `tostring` on an ordinary one and wasmoon looks up a JS ref that was never
|
|
91
|
+
* registered, gets `undefined`, and throws `Cannot read properties of
|
|
92
|
+
* undefined (reading 'toString')` — a JS TypeError, not a Lua error, so it
|
|
93
|
+
* unwinds straight through `pcall` and out of `doStringSync`, killing the
|
|
94
|
+
* whole lua_State. `tostring(print)`, `display{f = print}` and Mudlet's own
|
|
95
|
+
* `printTable` on a table holding a function all hit it.
|
|
96
|
+
*
|
|
97
|
+
* The fix replaces the global `tostring` rather than the metamethod: a JS
|
|
98
|
+
* function pushed later installs a *fresh* metatable and would silently
|
|
99
|
+
* revert a metamethod patch, whereas nothing rebinds this global. Clearing
|
|
100
|
+
* the shared metatable for the duration of the call takes Lua's own
|
|
101
|
+
* `function: 0x…` path — which is what Mudlet prints too, so this also drops
|
|
102
|
+
* wasmoon's habit of stringifying a bound global into its entire JS source.
|
|
103
|
+
* Lua 5.1's `print` reads the global at call time, so it follows along.
|
|
104
|
+
*
|
|
105
|
+
* Installed after every `global.set` above and before Bridge.lua, so no
|
|
106
|
+
* bundled or user chunk can capture the unsafe version as an upvalue.
|
|
107
|
+
*/
|
|
108
|
+
private installSafeFunctionTostring;
|
|
109
|
+
private installMudletLuaOverrides;
|
|
32
110
|
private installFastColorEcho;
|
|
33
111
|
private setupAnsiColorTable;
|
|
34
112
|
/**
|
|
@@ -37,8 +115,36 @@ export declare class LuaRuntime implements IScriptingRuntime {
|
|
|
37
115
|
* don't live in the persisted store the way permanent items do.
|
|
38
116
|
*/
|
|
39
117
|
tempItemExists(id: number, type: string): boolean;
|
|
118
|
+
/** A live temp item of `type` carrying this Mudlet-supplied name — how
|
|
119
|
+
* exists()/killTrigger() reach a tempComplexRegexTrigger. */
|
|
120
|
+
tempItemIdByName(name: string, type: string): number | null;
|
|
121
|
+
/**
|
|
122
|
+
* killAlias/killTrigger with a numeric id, for a script-created item.
|
|
123
|
+
*
|
|
124
|
+
* The item is unsubscribed and its callback released straight away — it must
|
|
125
|
+
* not fire again, including later in the very line pass that killed it — but
|
|
126
|
+
* the entry stays in the map, marked dead, until {@link reapKilledTempItems}.
|
|
127
|
+
* That is Mudlet's deferred cleanup: until the line ends, the corpse is still
|
|
128
|
+
* findable, which is what lets a second kill report `false` rather than
|
|
129
|
+
* mistaking the id for one that never existed.
|
|
130
|
+
*/
|
|
131
|
+
/** Resolve a killTrigger/killAlias argument to a live temp item's id: the
|
|
132
|
+
* number itself, or the name a tempComplexRegexTrigger was given. */
|
|
133
|
+
tempItemId(idOrName: number | string, type: 'alias' | 'trigger'): number | null;
|
|
134
|
+
private killTempItem;
|
|
135
|
+
/**
|
|
136
|
+
* Free every temp alias/trigger killed since the last call, or only those of
|
|
137
|
+
* `type` when given.
|
|
138
|
+
*
|
|
139
|
+
* Mudlet cleans up per unit, at the end of whatever pass that unit runs:
|
|
140
|
+
* aliases when nested expandAlias processing unwinds, triggers when the line
|
|
141
|
+
* finishes. Passing the type keeps those independent, so an alias pass can't
|
|
142
|
+
* reap a trigger the current line is still walking past.
|
|
143
|
+
*/
|
|
144
|
+
reapKilledTempItems(type?: 'alias' | 'trigger'): void;
|
|
40
145
|
/** enableTrigger/disableTrigger/enableAlias/disableAlias with a numeric id.
|
|
41
|
-
* False when no temp item of that id is live
|
|
146
|
+
* False when no temp item of that id is live — a killed one is still
|
|
147
|
+
* findable until the reap, but re-enabling it would resurrect it. */
|
|
42
148
|
setTempItemEnabled(id: number, enabled: boolean): boolean;
|
|
43
149
|
/** Whether a live temp item is enabled — backs isActive(id, type). */
|
|
44
150
|
tempItemEnabled(id: number): boolean;
|
|
@@ -79,8 +185,30 @@ export declare class LuaRuntime implements IScriptingRuntime {
|
|
|
79
185
|
* unmatched optional group (`undefined`) is left unset → nil, as before. */
|
|
80
186
|
private pushMatchesTable;
|
|
81
187
|
private exec;
|
|
188
|
+
private static readonly LUA_GCCOUNT;
|
|
189
|
+
private static readonly MEMORY_WARN_MB;
|
|
190
|
+
private static readonly MEMORY_SAMPLE_EVERY;
|
|
191
|
+
private memoryWarnIndex;
|
|
192
|
+
private dispatchesSinceMemorySample;
|
|
193
|
+
/** Sample Lua's own memory every few thousand dispatches and warn once per
|
|
194
|
+
* threshold crossed. Called from the two execution funnels; the counter
|
|
195
|
+
* keeps the `lua_gc` call itself off the hot path. */
|
|
196
|
+
private checkMemoryPressure;
|
|
197
|
+
/**
|
|
198
|
+
* Latch a WASM-level termination — see {@link fatal}. Emscripten throws its
|
|
199
|
+
* `ExitStatus` from the `proc_exit` import (C `exit()`) and a
|
|
200
|
+
* `WebAssembly.RuntimeError` from `abort()`; either means the module is
|
|
201
|
+
* gone, not that this one script failed, so the per-entity error report is
|
|
202
|
+
* wrong and repeating it every tick is worse.
|
|
203
|
+
*
|
|
204
|
+
* Returns true when `e` was such a termination, so the caller drops its own
|
|
205
|
+
* reporting. The one user-facing line is printed here, on the first one.
|
|
206
|
+
*/
|
|
207
|
+
private markFatal;
|
|
82
208
|
private execInner;
|
|
209
|
+
private execOnThread;
|
|
83
210
|
private runChunk;
|
|
211
|
+
private runChunkOnThread;
|
|
84
212
|
private static readonly FILE_DIALOG_SENTINEL;
|
|
85
213
|
/** Threads suspended in invokeFileDialog, tracked so destroy() forgets
|
|
86
214
|
* them (their registry refs die with the closed Lua state). */
|
|
@@ -112,6 +240,19 @@ export declare class LuaRuntime implements IScriptingRuntime {
|
|
|
112
240
|
*/
|
|
113
241
|
startSpeedWalk(from: number, to: number): void;
|
|
114
242
|
private execModule;
|
|
243
|
+
/**
|
|
244
|
+
* The native matcher behind `utf8.find`, and so behind `utf8.match`,
|
|
245
|
+
* `gmatch` and `gsub` — utf8.lua routes all four through one local, which
|
|
246
|
+
* calls this first and keeps its own matcher for whatever this declines.
|
|
247
|
+
* See utf8Patterns.ts for why (ASCII-only classes, ~35k VM instructions a
|
|
248
|
+
* find). Bound before the module loads, though the Lua side looks it up per
|
|
249
|
+
* call, so a runtime without it still works.
|
|
250
|
+
*
|
|
251
|
+
* The result crosses as a flat array — wasmoon hands JS arrays over
|
|
252
|
+
* 0-indexed — of `start, end, capture…`, or `false` for "no match" as
|
|
253
|
+
* distinct from nil's "not my pattern, use yours".
|
|
254
|
+
*/
|
|
255
|
+
private installNativeUtf8Find;
|
|
115
256
|
private dispatchingEvent;
|
|
116
257
|
private readonly pendingEvents;
|
|
117
258
|
emitEvent(event: string, args: unknown[]): void;
|
|
@@ -133,6 +274,14 @@ export declare class LuaRuntime implements IScriptingRuntime {
|
|
|
133
274
|
* raises sysUnzipDone / sysUnzipError. Always fire-and-forget.
|
|
134
275
|
*/
|
|
135
276
|
private runUnzipAsync;
|
|
277
|
+
/** Run `fn` off the current call stack, on the queue a blocked script still
|
|
278
|
+
* pumps. See the note in HttpService.emitLater: a microtask would never be
|
|
279
|
+
* reached by a script sitting in waitForEvent. */
|
|
280
|
+
private deferToTimerQueue;
|
|
281
|
+
/** The line the global `line` currently holds, so a caller can put it back
|
|
282
|
+
* after a nested feedTriggers has processed a line of its own. */
|
|
283
|
+
getCurrentLine(): string;
|
|
284
|
+
private currentLineText;
|
|
136
285
|
setCurrentLine(line: string, _isPrompt: boolean): void;
|
|
137
286
|
setCommand(command: string): void;
|
|
138
287
|
dispatchSendRequest(text: string): boolean;
|
|
@@ -1,14 +1,2 @@
|
|
|
1
1
|
import type { BindingContext } from './context';
|
|
2
|
-
/**
|
|
3
|
-
* Mudlet's map API: the 2D view, room and area CRUD, exits, doors, custom
|
|
4
|
-
* lines, labels, highlights, selection, per-room styling, user data, and the
|
|
5
|
-
* mapInfo / context-menu extension points.
|
|
6
|
-
*
|
|
7
|
-
* This is by far the widest binding surface in the runtime — it mirrors
|
|
8
|
-
* Mudlet's map Lua API essentially one-for-one — so it lives in its own
|
|
9
|
-
* module. The heavy lifting is all in MapStore behind `api.map`; the code
|
|
10
|
-
* here is argument coercion and Mudlet's return-shape conventions (notably
|
|
11
|
-
* alse where Mudlet returns nil, which Bridge.lua unpacks into the
|
|
12
|
-
* documented (nil, errMsg) multi-returns).
|
|
13
|
-
*/
|
|
14
2
|
export declare function installMapBindings({ lua, api, vfs, channel, emitEvent, unregisterCb, pushJsValue, registerRawGlobal, evaluateMapInfo, evaluateExitWeightFilter, }: BindingContext): void;
|