@mudlet/mudlet-web 0.3.0 → 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/LICENSE +338 -338
- package/README.md +158 -150
- 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/mudlet-mapper.xml +13023 -13023
- 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 +45910 -39931
- 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 +136 -19
- 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 +86 -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/msspTls.d.ts +54 -0
- package/dist-lib/mud/protocol/mxp.d.ts +28 -5
- package/dist-lib/mud/protocol/tlsCodes.d.ts +4 -0
- 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 +22 -0
- package/dist-lib/scripting/MxpFrameManager.d.ts +118 -0
- package/dist-lib/scripting/ScriptingAPI.d.ts +331 -54
- package/dist-lib/scripting/ScriptingEngine.d.ts +181 -24
- package/dist-lib/scripting/http/HttpService.d.ts +51 -1
- package/dist-lib/scripting/lua/LuaRuntime.d.ts +159 -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 +166 -4
- package/dist-lib/styles.css +1 -1
- package/dist-lib/ui/BundledGameGrid.d.ts +21 -0
- package/dist-lib/ui/CharLoginModal.d.ts +5 -1
- package/dist-lib/ui/CommandBar.d.ts +7 -1
- package/dist-lib/ui/ConnectionGrid.d.ts +4 -1
- package/dist-lib/ui/FileBrowserModal.d.ts +1 -0
- 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/SettingsModal.d.ts +5 -1
- package/dist-lib/ui/TlsAlertBanner.d.ts +18 -0
- package/dist-lib/ui/TlsCertificateBox.d.ts +20 -0
- package/dist-lib/ui/TlsUpgradeModal.d.ts +16 -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/components/useModalFocus.d.ts +6 -0
- package/dist-lib/ui/helpTopics.d.ts +19 -0
- package/dist-lib/ui/labels/LabelManager.d.ts +32 -0
- package/dist-lib/ui/labels/labelLinks.d.ts +52 -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/linkNavigation.d.ts +22 -0
- 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 +149 -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/vfs-sw.js +131 -131
- package/dist-lib/vite.js +22 -0
- package/package.json +97 -93
- 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
package/dist-lib/vfs-sw.js
CHANGED
|
@@ -1,131 +1,131 @@
|
|
|
1
|
-
// Service worker that serves ProfileVFS-backed assets at /__vfs/<connectionId>/<path>.
|
|
2
|
-
// The page is the source of truth for VFS contents (the SW can't share folder
|
|
3
|
-
// handles or always-open the same IDB store), so each request round-trips to
|
|
4
|
-
// the client via MessageChannel.
|
|
5
|
-
|
|
6
|
-
const CACHE_NAME = 'mudix-vfs-v1';
|
|
7
|
-
// Scope path always ends with '/'. On a root-served deploy this is '/'; on
|
|
8
|
-
// GitHub Pages or any subpath deploy it's '/<repo>/'. The intercept prefix is
|
|
9
|
-
// '<scope>__vfs/' so SW-controlled URLs stay inside scope.
|
|
10
|
-
const SCOPE_PATH = new URL(self.registration.scope).pathname;
|
|
11
|
-
const PREFIX = `${SCOPE_PATH}__vfs/`;
|
|
12
|
-
const READ_TIMEOUT_MS = 5000;
|
|
13
|
-
|
|
14
|
-
self.addEventListener('install', () => self.skipWaiting());
|
|
15
|
-
self.addEventListener('activate', (e) => e.waitUntil(self.clients.claim()));
|
|
16
|
-
|
|
17
|
-
self.addEventListener('fetch', (event) => {
|
|
18
|
-
const url = new URL(event.request.url);
|
|
19
|
-
if (url.origin !== self.location.origin) return;
|
|
20
|
-
if (!url.pathname.startsWith(PREFIX)) return;
|
|
21
|
-
event.respondWith(handle(event, url));
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
async function handle(event, url) {
|
|
25
|
-
const rest = url.pathname.slice(PREFIX.length).split('/').filter(Boolean);
|
|
26
|
-
if (rest.length < 2) return new Response('Bad request', { status: 400 });
|
|
27
|
-
const connectionId = decodeURIComponent(rest[0]);
|
|
28
|
-
const filePath = '/' + rest.slice(1).map(decodeURIComponent).join('/');
|
|
29
|
-
|
|
30
|
-
const cache = await caches.open(CACHE_NAME);
|
|
31
|
-
const cached = await cache.match(event.request);
|
|
32
|
-
if (cached) return cached;
|
|
33
|
-
|
|
34
|
-
const client = await pickClient(event);
|
|
35
|
-
if (!client) {
|
|
36
|
-
// Either there's no app tab loaded (direct URL hit in fresh tab) or
|
|
37
|
-
// the only candidate is the tab currently navigating to this URL.
|
|
38
|
-
return new Response('No app tab loaded; open mudix first', { status: 503 });
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const reply = await ask(client, { type: 'vfs:read', connectionId, path: filePath });
|
|
42
|
-
if (!reply || !reply.ok) {
|
|
43
|
-
return new Response(reply?.error ?? 'Not found', { status: 404 });
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const headers = new Headers();
|
|
47
|
-
headers.set('Content-Type', reply.contentType || 'application/octet-stream');
|
|
48
|
-
// no-store keeps this response out of the browser's own HTTP cache, which
|
|
49
|
-
// has no validator to revalidate against (we set none) and would otherwise
|
|
50
|
-
// race our explicit Cache Storage entry above — that race is what produced
|
|
51
|
-
// stale 304-with-no-body responses for cached images. The Cache Storage
|
|
52
|
-
// entry (invalidated on writes via postMessage) is the only cache that
|
|
53
|
-
// should own this decision.
|
|
54
|
-
headers.set('Cache-Control', 'no-store');
|
|
55
|
-
const response = new Response(reply.bytes, { headers });
|
|
56
|
-
cache.put(event.request, response.clone()).catch(() => {});
|
|
57
|
-
return response;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
async function pickClient(event) {
|
|
61
|
-
// Prefer the client that issued this request — for sub-resource fetches
|
|
62
|
-
// that's the loaded app page, which can reply immediately.
|
|
63
|
-
const requestingId = event.clientId || event.resultingClientId || '';
|
|
64
|
-
if (requestingId) {
|
|
65
|
-
const c = await self.clients.get(requestingId);
|
|
66
|
-
if (c && isUsable(c)) return c;
|
|
67
|
-
}
|
|
68
|
-
const all = await self.clients.matchAll({ type: 'window', includeUncontrolled: true });
|
|
69
|
-
const usable = all.filter(isUsable);
|
|
70
|
-
return usable.find((c) => c.focused) ?? usable[0] ?? null;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Skip clients that are themselves navigating to a /__vfs/ URL — those are
|
|
74
|
-
// fresh tabs in the middle of loading the SW response; they have no JS running
|
|
75
|
-
// and can't reply, so picking one guarantees a timeout.
|
|
76
|
-
function isUsable(client) {
|
|
77
|
-
try {
|
|
78
|
-
return !new URL(client.url).pathname.startsWith(PREFIX);
|
|
79
|
-
} catch {
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function ask(client, message) {
|
|
85
|
-
return new Promise((resolve) => {
|
|
86
|
-
const channel = new MessageChannel();
|
|
87
|
-
const timer = setTimeout(() => {
|
|
88
|
-
channel.port1.close();
|
|
89
|
-
resolve({ ok: false, error: 'timeout' });
|
|
90
|
-
}, READ_TIMEOUT_MS);
|
|
91
|
-
channel.port1.onmessage = (e) => {
|
|
92
|
-
clearTimeout(timer);
|
|
93
|
-
channel.port1.close();
|
|
94
|
-
resolve(e.data);
|
|
95
|
-
};
|
|
96
|
-
client.postMessage(message, [channel.port2]);
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
self.addEventListener('message', (event) => {
|
|
101
|
-
const data = event.data;
|
|
102
|
-
if (!data) return;
|
|
103
|
-
if (data.type === 'vfs:invalidate') {
|
|
104
|
-
event.waitUntil(invalidate(data));
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
async function invalidate({ connectionId, path }) {
|
|
109
|
-
if (!connectionId) {
|
|
110
|
-
await caches.delete(CACHE_NAME);
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
const cache = await caches.open(CACHE_NAME);
|
|
114
|
-
const connPrefix = `${PREFIX}${encodeURIComponent(connectionId)}/`;
|
|
115
|
-
const keys = await cache.keys();
|
|
116
|
-
if (path) {
|
|
117
|
-
const segs = path.split('/').filter(Boolean).map(encodeURIComponent).join('/');
|
|
118
|
-
const target = `${connPrefix}${segs}`;
|
|
119
|
-
await Promise.all(
|
|
120
|
-
keys
|
|
121
|
-
.filter((req) => new URL(req.url).pathname === target)
|
|
122
|
-
.map((req) => cache.delete(req)),
|
|
123
|
-
);
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
await Promise.all(
|
|
127
|
-
keys
|
|
128
|
-
.filter((req) => new URL(req.url).pathname.startsWith(connPrefix))
|
|
129
|
-
.map((req) => cache.delete(req)),
|
|
130
|
-
);
|
|
131
|
-
}
|
|
1
|
+
// Service worker that serves ProfileVFS-backed assets at /__vfs/<connectionId>/<path>.
|
|
2
|
+
// The page is the source of truth for VFS contents (the SW can't share folder
|
|
3
|
+
// handles or always-open the same IDB store), so each request round-trips to
|
|
4
|
+
// the client via MessageChannel.
|
|
5
|
+
|
|
6
|
+
const CACHE_NAME = 'mudix-vfs-v1';
|
|
7
|
+
// Scope path always ends with '/'. On a root-served deploy this is '/'; on
|
|
8
|
+
// GitHub Pages or any subpath deploy it's '/<repo>/'. The intercept prefix is
|
|
9
|
+
// '<scope>__vfs/' so SW-controlled URLs stay inside scope.
|
|
10
|
+
const SCOPE_PATH = new URL(self.registration.scope).pathname;
|
|
11
|
+
const PREFIX = `${SCOPE_PATH}__vfs/`;
|
|
12
|
+
const READ_TIMEOUT_MS = 5000;
|
|
13
|
+
|
|
14
|
+
self.addEventListener('install', () => self.skipWaiting());
|
|
15
|
+
self.addEventListener('activate', (e) => e.waitUntil(self.clients.claim()));
|
|
16
|
+
|
|
17
|
+
self.addEventListener('fetch', (event) => {
|
|
18
|
+
const url = new URL(event.request.url);
|
|
19
|
+
if (url.origin !== self.location.origin) return;
|
|
20
|
+
if (!url.pathname.startsWith(PREFIX)) return;
|
|
21
|
+
event.respondWith(handle(event, url));
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
async function handle(event, url) {
|
|
25
|
+
const rest = url.pathname.slice(PREFIX.length).split('/').filter(Boolean);
|
|
26
|
+
if (rest.length < 2) return new Response('Bad request', { status: 400 });
|
|
27
|
+
const connectionId = decodeURIComponent(rest[0]);
|
|
28
|
+
const filePath = '/' + rest.slice(1).map(decodeURIComponent).join('/');
|
|
29
|
+
|
|
30
|
+
const cache = await caches.open(CACHE_NAME);
|
|
31
|
+
const cached = await cache.match(event.request);
|
|
32
|
+
if (cached) return cached;
|
|
33
|
+
|
|
34
|
+
const client = await pickClient(event);
|
|
35
|
+
if (!client) {
|
|
36
|
+
// Either there's no app tab loaded (direct URL hit in fresh tab) or
|
|
37
|
+
// the only candidate is the tab currently navigating to this URL.
|
|
38
|
+
return new Response('No app tab loaded; open mudix first', { status: 503 });
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const reply = await ask(client, { type: 'vfs:read', connectionId, path: filePath });
|
|
42
|
+
if (!reply || !reply.ok) {
|
|
43
|
+
return new Response(reply?.error ?? 'Not found', { status: 404 });
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const headers = new Headers();
|
|
47
|
+
headers.set('Content-Type', reply.contentType || 'application/octet-stream');
|
|
48
|
+
// no-store keeps this response out of the browser's own HTTP cache, which
|
|
49
|
+
// has no validator to revalidate against (we set none) and would otherwise
|
|
50
|
+
// race our explicit Cache Storage entry above — that race is what produced
|
|
51
|
+
// stale 304-with-no-body responses for cached images. The Cache Storage
|
|
52
|
+
// entry (invalidated on writes via postMessage) is the only cache that
|
|
53
|
+
// should own this decision.
|
|
54
|
+
headers.set('Cache-Control', 'no-store');
|
|
55
|
+
const response = new Response(reply.bytes, { headers });
|
|
56
|
+
cache.put(event.request, response.clone()).catch(() => {});
|
|
57
|
+
return response;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async function pickClient(event) {
|
|
61
|
+
// Prefer the client that issued this request — for sub-resource fetches
|
|
62
|
+
// that's the loaded app page, which can reply immediately.
|
|
63
|
+
const requestingId = event.clientId || event.resultingClientId || '';
|
|
64
|
+
if (requestingId) {
|
|
65
|
+
const c = await self.clients.get(requestingId);
|
|
66
|
+
if (c && isUsable(c)) return c;
|
|
67
|
+
}
|
|
68
|
+
const all = await self.clients.matchAll({ type: 'window', includeUncontrolled: true });
|
|
69
|
+
const usable = all.filter(isUsable);
|
|
70
|
+
return usable.find((c) => c.focused) ?? usable[0] ?? null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Skip clients that are themselves navigating to a /__vfs/ URL — those are
|
|
74
|
+
// fresh tabs in the middle of loading the SW response; they have no JS running
|
|
75
|
+
// and can't reply, so picking one guarantees a timeout.
|
|
76
|
+
function isUsable(client) {
|
|
77
|
+
try {
|
|
78
|
+
return !new URL(client.url).pathname.startsWith(PREFIX);
|
|
79
|
+
} catch {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function ask(client, message) {
|
|
85
|
+
return new Promise((resolve) => {
|
|
86
|
+
const channel = new MessageChannel();
|
|
87
|
+
const timer = setTimeout(() => {
|
|
88
|
+
channel.port1.close();
|
|
89
|
+
resolve({ ok: false, error: 'timeout' });
|
|
90
|
+
}, READ_TIMEOUT_MS);
|
|
91
|
+
channel.port1.onmessage = (e) => {
|
|
92
|
+
clearTimeout(timer);
|
|
93
|
+
channel.port1.close();
|
|
94
|
+
resolve(e.data);
|
|
95
|
+
};
|
|
96
|
+
client.postMessage(message, [channel.port2]);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
self.addEventListener('message', (event) => {
|
|
101
|
+
const data = event.data;
|
|
102
|
+
if (!data) return;
|
|
103
|
+
if (data.type === 'vfs:invalidate') {
|
|
104
|
+
event.waitUntil(invalidate(data));
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
async function invalidate({ connectionId, path }) {
|
|
109
|
+
if (!connectionId) {
|
|
110
|
+
await caches.delete(CACHE_NAME);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const cache = await caches.open(CACHE_NAME);
|
|
114
|
+
const connPrefix = `${PREFIX}${encodeURIComponent(connectionId)}/`;
|
|
115
|
+
const keys = await cache.keys();
|
|
116
|
+
if (path) {
|
|
117
|
+
const segs = path.split('/').filter(Boolean).map(encodeURIComponent).join('/');
|
|
118
|
+
const target = `${connPrefix}${segs}`;
|
|
119
|
+
await Promise.all(
|
|
120
|
+
keys
|
|
121
|
+
.filter((req) => new URL(req.url).pathname === target)
|
|
122
|
+
.map((req) => cache.delete(req)),
|
|
123
|
+
);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
await Promise.all(
|
|
127
|
+
keys
|
|
128
|
+
.filter((req) => new URL(req.url).pathname.startsWith(connPrefix))
|
|
129
|
+
.map((req) => cache.delete(req)),
|
|
130
|
+
);
|
|
131
|
+
}
|
package/dist-lib/vite.js
CHANGED
|
@@ -95,6 +95,28 @@ export default function mudix() {
|
|
|
95
95
|
{
|
|
96
96
|
name: 'mudix:config',
|
|
97
97
|
config: () => ({
|
|
98
|
+
resolve: {
|
|
99
|
+
// Exactly one React instance, always. `mudlet-map-editor`
|
|
100
|
+
// declares react/react-dom as plain *dependencies* (not
|
|
101
|
+
// peers), so the moment its range outruns the range the
|
|
102
|
+
// app resolved, the package manager nests a second copy
|
|
103
|
+
// under the editor. The editor's `App` is then rendered by
|
|
104
|
+
// mudix's React while its hooks come from the nested one,
|
|
105
|
+
// whose dispatcher is null — "Invalid hook call", and with
|
|
106
|
+
// no error boundary above the lazy boundary the throw
|
|
107
|
+
// unmounts the whole root, so opening the map editor
|
|
108
|
+
// blanked the entire UI in dev and in production alike.
|
|
109
|
+
// Deduping is the structural fix: it survives the next
|
|
110
|
+
// version skew, and consumers of the library (which
|
|
111
|
+
// externalizes react) get it through this plugin too.
|
|
112
|
+
dedupe: ['react', 'react-dom'],
|
|
113
|
+
},
|
|
114
|
+
// A Mudlet package archive is a zip, not source. `?url` imports
|
|
115
|
+
// get away without this (the explicit query short-circuits
|
|
116
|
+
// import analysis), but `?inline` — which the busted fixtures
|
|
117
|
+
// use to carry an archive into the VFS — reaches the asset
|
|
118
|
+
// pipeline and needs the extension declared.
|
|
119
|
+
assetsInclude: ['**/*.mpackage'],
|
|
98
120
|
optimizeDeps: {
|
|
99
121
|
// 'mudix': the library entry carries relative `?url` asset
|
|
100
122
|
// imports (external in the lib build); the dep optimizer's
|
package/package.json
CHANGED
|
@@ -1,93 +1,97 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@mudlet/mudlet-web",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"type": "module",
|
|
5
|
-
"description": "Mudlet Web — Mudlet in the browser, usable standalone or as a library for branded builds",
|
|
6
|
-
"license": "GPL-2.0-or-later",
|
|
7
|
-
"keywords": [
|
|
8
|
-
"mud",
|
|
9
|
-
"mudlet",
|
|
10
|
-
"mud-client",
|
|
11
|
-
"telnet",
|
|
12
|
-
"lua",
|
|
13
|
-
"game"
|
|
14
|
-
],
|
|
15
|
-
"homepage": "https://github.com/Mudlet/mudlet-web",
|
|
16
|
-
"repository": {
|
|
17
|
-
"url": "git+https://github.com/Mudlet/mudlet-web.git"
|
|
18
|
-
},
|
|
19
|
-
"publishConfig": {
|
|
20
|
-
"access": "public"
|
|
21
|
-
},
|
|
22
|
-
"exports": {
|
|
23
|
-
".": {
|
|
24
|
-
"types": "./dist-lib/index.d.ts",
|
|
25
|
-
"import": "./dist-lib/index.js"
|
|
26
|
-
},
|
|
27
|
-
"./vite": {
|
|
28
|
-
"types": "./dist-lib/vite.d.ts",
|
|
29
|
-
"import": "./dist-lib/vite.js"
|
|
30
|
-
},
|
|
31
|
-
"./styles.css": "./dist-lib/styles.css"
|
|
32
|
-
},
|
|
33
|
-
"main": "./dist-lib/index.js",
|
|
34
|
-
"types": "./dist-lib/index.d.ts",
|
|
35
|
-
"files": [
|
|
36
|
-
"dist-lib"
|
|
37
|
-
],
|
|
38
|
-
"scripts": {
|
|
39
|
-
"dev": "vite",
|
|
40
|
-
"build": "tsc && vite build",
|
|
41
|
-
"build:lib": "vite build --config vite.lib.config.ts && tsc -p tsconfig.lib.json && tsc -p tsconfig.vite-plugin.json && node scripts/copy-lib-assets.mjs",
|
|
42
|
-
"prepublishOnly": "yarn build:lib",
|
|
43
|
-
"preview": "vite preview",
|
|
44
|
-
"typecheck": "tsc -p tsconfig.test.json",
|
|
45
|
-
"test": "vitest run",
|
|
46
|
-
"test:watch": "vitest",
|
|
47
|
-
"dev:busted": "vite --mode busted --port 5174 --strictPort",
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
"sync:mudlet-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
"@codemirror/
|
|
56
|
-
"@codemirror/
|
|
57
|
-
"@codemirror/
|
|
58
|
-
"@codemirror/
|
|
59
|
-
"@codemirror/
|
|
60
|
-
"@codemirror/
|
|
61
|
-
"@codemirror/
|
|
62
|
-
"@
|
|
63
|
-
"@
|
|
64
|
-
"@
|
|
65
|
-
"@zenfs/
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"mudlet-map-
|
|
72
|
-
"mudlet-map-
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"react
|
|
77
|
-
"
|
|
78
|
-
"
|
|
79
|
-
"
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
"@
|
|
84
|
-
"@types/
|
|
85
|
-
"@types/
|
|
86
|
-
"@types/react
|
|
87
|
-
"@
|
|
88
|
-
"
|
|
89
|
-
"
|
|
90
|
-
"
|
|
91
|
-
"
|
|
92
|
-
|
|
93
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@mudlet/mudlet-web",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Mudlet Web — Mudlet in the browser, usable standalone or as a library for branded builds",
|
|
6
|
+
"license": "GPL-2.0-or-later",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"mud",
|
|
9
|
+
"mudlet",
|
|
10
|
+
"mud-client",
|
|
11
|
+
"telnet",
|
|
12
|
+
"lua",
|
|
13
|
+
"game"
|
|
14
|
+
],
|
|
15
|
+
"homepage": "https://github.com/Mudlet/mudlet-web",
|
|
16
|
+
"repository": {
|
|
17
|
+
"url": "git+https://github.com/Mudlet/mudlet-web.git"
|
|
18
|
+
},
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public"
|
|
21
|
+
},
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./dist-lib/index.d.ts",
|
|
25
|
+
"import": "./dist-lib/index.js"
|
|
26
|
+
},
|
|
27
|
+
"./vite": {
|
|
28
|
+
"types": "./dist-lib/vite.d.ts",
|
|
29
|
+
"import": "./dist-lib/vite.js"
|
|
30
|
+
},
|
|
31
|
+
"./styles.css": "./dist-lib/styles.css"
|
|
32
|
+
},
|
|
33
|
+
"main": "./dist-lib/index.js",
|
|
34
|
+
"types": "./dist-lib/index.d.ts",
|
|
35
|
+
"files": [
|
|
36
|
+
"dist-lib"
|
|
37
|
+
],
|
|
38
|
+
"scripts": {
|
|
39
|
+
"dev": "vite",
|
|
40
|
+
"build": "tsc && vite build",
|
|
41
|
+
"build:lib": "vite build --config vite.lib.config.ts && tsc -p tsconfig.lib.json && tsc -p tsconfig.vite-plugin.json && node scripts/copy-lib-assets.mjs",
|
|
42
|
+
"prepublishOnly": "yarn build:lib",
|
|
43
|
+
"preview": "vite preview",
|
|
44
|
+
"typecheck": "tsc -p tsconfig.test.json",
|
|
45
|
+
"test": "vitest run",
|
|
46
|
+
"test:watch": "vitest",
|
|
47
|
+
"dev:busted": "vite --mode busted --port 5174 --strictPort",
|
|
48
|
+
"test:e2e": "playwright test",
|
|
49
|
+
"busted:failures": "playwright test -c playwright.failures.config.ts",
|
|
50
|
+
"sync:mudlet-specs": "node scripts/sync-mudlet-specs.mjs",
|
|
51
|
+
"sync:mudlet-lua": "node scripts/sync-mudlet-lua.mjs",
|
|
52
|
+
"sync:mudlet-games": "node scripts/sync-mudlet-games.mjs"
|
|
53
|
+
},
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"@codemirror/autocomplete": "^6.20.1",
|
|
56
|
+
"@codemirror/commands": "^6.10.3",
|
|
57
|
+
"@codemirror/lang-json": "^6.0.2",
|
|
58
|
+
"@codemirror/language": "^6.12.3",
|
|
59
|
+
"@codemirror/legacy-modes": "^6.5.2",
|
|
60
|
+
"@codemirror/state": "^6.6.0",
|
|
61
|
+
"@codemirror/theme-one-dark": "^6.1.3",
|
|
62
|
+
"@codemirror/view": "^6.41.1",
|
|
63
|
+
"@sqlite.org/sqlite-wasm": "^3.53.0-build1",
|
|
64
|
+
"@types/dompurify": "^3.0.5",
|
|
65
|
+
"@zenfs/core": "^2.5.6",
|
|
66
|
+
"@zenfs/dom": "^1.2.9",
|
|
67
|
+
"dompurify": "^3.4.14",
|
|
68
|
+
"fflate": "^0.8.2",
|
|
69
|
+
"lucide-react": "^1.14.0",
|
|
70
|
+
"marked": "^18.0.4",
|
|
71
|
+
"mudlet-map-binary-reader": "^1.2.0",
|
|
72
|
+
"mudlet-map-editor": "^1.3.2",
|
|
73
|
+
"mudlet-map-renderer": "^2.6.1",
|
|
74
|
+
"pako": "^2.1.0",
|
|
75
|
+
"pcre2-wasm-universal": "^1.0.0",
|
|
76
|
+
"react": "^19.2.0",
|
|
77
|
+
"react-dom": "^19.2.0",
|
|
78
|
+
"vite-plugin-node-polyfills": "^0.26.0",
|
|
79
|
+
"wasmoon-lua5.1": "^1.18.10",
|
|
80
|
+
"zustand": "^5.0.12"
|
|
81
|
+
},
|
|
82
|
+
"devDependencies": {
|
|
83
|
+
"@playwright/test": "^1.61.1",
|
|
84
|
+
"@types/node": "^25.6.0",
|
|
85
|
+
"@types/pako": "^2.0.0",
|
|
86
|
+
"@types/react": "^19.2.0",
|
|
87
|
+
"@types/react-dom": "^19.2.0",
|
|
88
|
+
"@vitejs/plugin-react": "^6.0.1",
|
|
89
|
+
"happy-dom": "^20.9.0",
|
|
90
|
+
"typescript": "^5.0.0",
|
|
91
|
+
"vite": "8.0.16",
|
|
92
|
+
"vitest": "^4.1.7"
|
|
93
|
+
},
|
|
94
|
+
"resolutions": {
|
|
95
|
+
"dompurify": "^3.4.14"
|
|
96
|
+
}
|
|
97
|
+
}
|
|
Binary file
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { ProfileVFS } from '../../../scripting/vfs/ProfileVFS';
|
|
2
|
-
interface Props {
|
|
3
|
-
vfs: ProfileVFS;
|
|
4
|
-
onClose: () => void;
|
|
5
|
-
onPick: (absolutePath: string) => void;
|
|
6
|
-
}
|
|
7
|
-
export declare function VfsModulePickerModal({ vfs, onClose, onPick }: Props): import("react/jsx-runtime").JSX.Element;
|
|
8
|
-
export {};
|