@mudlet/mudlet-web 0.4.5 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist-lib/analytics.d.ts +27 -0
- package/dist-lib/assets/fonts/Vera.woff2 +0 -0
- package/dist-lib/assets/fonts/VeraBI.woff2 +0 -0
- package/dist-lib/assets/fonts/VeraBd.woff2 +0 -0
- package/dist-lib/assets/fonts/VeraIt.woff2 +0 -0
- package/dist-lib/assets/mapParser.worker-DrVZ3wg_.js +9 -0
- package/dist-lib/backupImport-wt8r7JXI.js +233 -0
- package/dist-lib/branding.d.ts +111 -13
- package/dist-lib/db/sqliteClient.d.ts +195 -7
- package/dist-lib/hooks/useAutoReconnect.d.ts +61 -0
- package/dist-lib/hooks/useDocumentFullscreen.d.ts +23 -0
- package/dist-lib/hooks/useKeyboardShortcuts.d.ts +37 -0
- package/dist-lib/hooks/useRecordLastPlayed.d.ts +10 -0
- package/dist-lib/import/applyMudletProfile.d.ts +35 -9
- package/dist-lib/import/backupImport.d.ts +118 -0
- package/dist-lib/import/collectProfileExport.d.ts +33 -2
- package/dist-lib/import/defaultPackages.d.ts +57 -14
- package/dist-lib/import/defaults/CF-loader/CF-loader.mpackage +0 -0
- package/dist-lib/import/defaults/MedBootstrap/MedBootstrap.mpackage +0 -0
- package/dist-lib/import/defaults/deleteOldProfiles/deleteOldProfiles.mpackage +0 -0
- package/dist-lib/import/defaults/echo/echo.mpackage +0 -0
- package/dist-lib/import/defaults/enable-accessibility/enable-accessibility.mpackage +0 -0
- 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/icesus-loader/icesus-loader.mpackage +0 -0
- package/dist-lib/import/defaults/mg-loader/mg-loader.mpackage +0 -0
- package/dist-lib/import/defaults/mudlet-base-ui/mudlet-base-ui.mpackage +0 -0
- package/dist-lib/import/defaults/mudlet-mapper.xml +1215 -389
- package/dist-lib/import/mudletControlChars.d.ts +14 -0
- package/dist-lib/import/mudletHost.d.ts +73 -10
- package/dist-lib/import/mudletLink.d.ts +53 -2
- package/dist-lib/import/mudletProfileExport.d.ts +38 -5
- package/dist-lib/import/mudletProfileImport.d.ts +110 -12
- package/dist-lib/import/mudletVariables.d.ts +4 -3
- package/dist-lib/import/mudletWriteback.d.ts +15 -1
- package/dist-lib/import/mudletXmlImport.d.ts +46 -0
- package/dist-lib/import/packageFonts.d.ts +33 -0
- package/dist-lib/import/packageInstaller.d.ts +111 -7
- package/dist-lib/import/qtProfileData.d.ts +10 -0
- package/dist-lib/import/remotePackageInstall.d.ts +23 -7
- package/dist-lib/import/zipEntries.d.ts +45 -0
- package/dist-lib/index.d.ts +7 -3
- package/dist-lib/index.js +50660 -29735
- package/dist-lib/logging/SessionLogger.d.ts +75 -15
- package/dist-lib/map/MapSelectionOverlay.d.ts +2 -2
- package/dist-lib/map/MapStore.d.ts +432 -59
- package/dist-lib/map/MudletHighlightOverlay.d.ts +2 -2
- package/dist-lib/map/{MudixMapReader.d.ts → MudletMapReader.d.ts} +2 -2
- package/dist-lib/map/areaGraph.d.ts +120 -0
- package/dist-lib/map/environmentKit.d.ts +36 -0
- package/dist-lib/map/labelPixmap.d.ts +90 -0
- package/dist-lib/map/mapImageExport.d.ts +36 -2
- package/dist-lib/map/mapStyle.d.ts +11 -0
- package/dist-lib/map/mapVersion.d.ts +66 -0
- package/dist-lib/map/pathfinding.d.ts +2 -2
- package/dist-lib/mud/CharLoginController.d.ts +230 -0
- package/dist-lib/mud/ItemIdSequence.d.ts +1 -1
- package/dist-lib/mud/MudSession.d.ts +279 -22
- package/dist-lib/mud/PatternEngine.d.ts +153 -14
- package/dist-lib/mud/aliases/AliasEngine.d.ts +55 -9
- package/dist-lib/mud/autoLogin.d.ts +59 -0
- package/dist-lib/mud/commandSplit.d.ts +9 -0
- package/dist-lib/mud/connection/LineAssembler.d.ts +38 -11
- package/dist-lib/mud/connection/MudClient.d.ts +291 -53
- package/dist-lib/mud/connection/SubnegotiationRepair.d.ts +24 -0
- package/dist-lib/mud/connection/TelnetNegotiator.d.ts +208 -68
- package/dist-lib/mud/connection/telnetDebug.d.ts +8 -8
- package/dist-lib/mud/events.d.ts +102 -23
- package/dist-lib/mud/games/bundledGames.d.ts +12 -7
- package/dist-lib/mud/games/gameLinks.d.ts +40 -0
- package/dist-lib/mud/games/icons/3Kingdoms.png +0 -0
- package/dist-lib/mud/games/icons/3Scapes.png +0 -0
- package/dist-lib/mud/games/icons/achaea.png +0 -0
- package/dist-lib/mud/games/icons/aetolia.png +0 -0
- package/dist-lib/mud/games/icons/banner_astaria.png +0 -0
- package/dist-lib/mud/games/icons/banner_darkmists.png +0 -0
- package/dist-lib/mud/games/icons/banner_dreamland.png +0 -0
- package/dist-lib/mud/games/icons/banner_petria.jpg +0 -0
- package/dist-lib/mud/games/icons/banner_ropmud.png +0 -0
- package/dist-lib/mud/games/icons/blackmud.png +0 -0
- package/dist-lib/mud/games/icons/carrionfields.png +0 -0
- package/dist-lib/mud/games/icons/dragonfire_icon.png +0 -0
- package/dist-lib/mud/games/icons/fed2-logo.png +0 -0
- package/dist-lib/mud/games/icons/icesus_480x120.png +0 -0
- package/dist-lib/mud/games/icons/imperian.png +0 -0
- package/dist-lib/mud/games/icons/infinity_480x120.png +0 -0
- package/dist-lib/mud/games/icons/lusternia.png +0 -0
- package/dist-lib/mud/games/icons/morgengrauen_480x120.png +0 -0
- package/dist-lib/mud/games/icons/mudlet-tutorial.png +0 -0
- package/dist-lib/mud/games/icons/phoenixmud_480x120.png +0 -0
- package/dist-lib/mud/games/icons/starmourn.png +0 -0
- package/dist-lib/mud/games/icons/voidmud_icon.png +0 -0
- package/dist-lib/mud/games/icons/wotmudicon.png +0 -0
- package/dist-lib/mud/games/websiteLinks.d.ts +21 -0
- package/dist-lib/mud/keybindings/KeyEngine.d.ts +110 -4
- package/dist-lib/mud/keybindings/browserReservedKeys.d.ts +2 -2
- package/dist-lib/mud/keybindings/keyEventTarget.d.ts +61 -0
- package/dist-lib/mud/keybindings/qtKeys.d.ts +91 -12
- package/dist-lib/mud/protocol/atcp.d.ts +19 -0
- package/dist-lib/mud/protocol/byteString.d.ts +24 -0
- package/dist-lib/mud/protocol/charLoginFlow.d.ts +243 -16
- package/dist-lib/mud/protocol/charset.d.ts +111 -46
- package/dist-lib/mud/protocol/codePages.d.ts +10 -0
- package/dist-lib/mud/protocol/constants.d.ts +17 -10
- package/dist-lib/mud/protocol/echo.d.ts +23 -27
- package/dist-lib/mud/protocol/gmcp.d.ts +36 -6
- package/dist-lib/mud/protocol/index.d.ts +3 -2
- package/dist-lib/mud/protocol/luaLiteral.d.ts +12 -0
- package/dist-lib/mud/protocol/mccp.d.ts +83 -1
- package/dist-lib/mud/protocol/mnes.d.ts +41 -58
- package/dist-lib/mud/protocol/msdp.d.ts +11 -4
- package/dist-lib/mud/protocol/msp.d.ts +3 -2
- package/dist-lib/mud/protocol/mssp.d.ts +9 -4
- package/dist-lib/mud/protocol/multiByte.d.ts +51 -0
- package/dist-lib/mud/protocol/multiByteEncode.d.ts +42 -0
- package/dist-lib/mud/protocol/mxp.d.ts +193 -14
- package/dist-lib/mud/protocol/oauthClientFlow.d.ts +128 -0
- package/dist-lib/mud/protocol/qtCodePages.generated.d.ts +1 -0
- package/dist-lib/mud/protocol/tlsCodes.d.ts +40 -3
- package/dist-lib/mud/replay/ReplayPlayer.d.ts +16 -1
- package/dist-lib/mud/replay/replayFormat.d.ts +29 -2
- package/dist-lib/mud/text/Console.d.ts +255 -49
- package/dist-lib/mud/text/FormatState.d.ts +137 -14
- package/dist-lib/mud/text/ansiEscapes.d.ts +32 -16
- package/dist-lib/mud/text/colorParsers.d.ts +14 -2
- package/dist-lib/mud/text/colorSpaceId.d.ts +2 -0
- package/dist-lib/mud/text/colors.d.ts +17 -10
- package/dist-lib/mud/text/controlCharacterMode.d.ts +1 -1
- package/dist-lib/mud/text/hyperlinkVisibility.d.ts +1 -1
- package/dist-lib/mud/text/lineBreak.d.ts +5 -0
- package/dist-lib/mud/text/serverWrap.d.ts +2 -2
- package/dist-lib/mud/text/textAnalyzer.d.ts +79 -0
- package/dist-lib/mud/text/unicodeRuns.d.ts +11 -0
- package/dist-lib/mud/text/unicodeTables.generated.d.ts +3 -0
- package/dist-lib/mud/text/wcwidth.d.ts +27 -22
- package/dist-lib/mud/timers/TimerEngine.d.ts +163 -11
- package/dist-lib/mud/timers/workerClock.d.ts +67 -0
- package/dist-lib/mud/triggers/TriggerEngine.d.ts +449 -47
- package/dist-lib/mud/triggers/legacyColorPatterns.d.ts +58 -0
- package/dist-lib/mud/triggers/pcre/Pcre2.d.ts +83 -1
- package/dist-lib/oauth-callback.html +94 -0
- package/dist-lib/pcre2Wasm.d.ts +54 -0
- package/dist-lib/pcre2Wasm.js +241 -0
- package/dist-lib/scripting/EngineHost.d.ts +54 -21
- package/dist-lib/scripting/IScriptingRuntime.d.ts +103 -27
- package/dist-lib/scripting/MxpFrameManager.d.ts +10 -1
- package/dist-lib/scripting/ScriptingAPI.d.ts +1039 -213
- package/dist-lib/scripting/ScriptingEngine.d.ts +753 -103
- package/dist-lib/scripting/StopwatchManager.d.ts +97 -36
- package/dist-lib/scripting/http/HttpService.d.ts +9 -1
- package/dist-lib/scripting/http/userUrl.d.ts +41 -0
- package/dist-lib/scripting/lua/LuaRuntime.d.ts +352 -77
- package/dist-lib/scripting/lua/argContracts.d.ts +71 -0
- package/dist-lib/scripting/lua/bindings/automation.d.ts +1 -1
- package/dist-lib/scripting/lua/bindings/commands.d.ts +13 -0
- package/dist-lib/scripting/lua/bindings/context.d.ts +20 -2
- package/dist-lib/scripting/lua/bindings/diagnostics.d.ts +1 -1
- package/dist-lib/scripting/lua/bindings/map.d.ts +1 -1
- package/dist-lib/scripting/lua/bindings/media.d.ts +2 -2
- package/dist-lib/scripting/lua/bindings/output.d.ts +1 -1
- package/dist-lib/scripting/lua/bindings/session.d.ts +2 -2
- package/dist-lib/scripting/lua/bindings/textEdit.d.ts +1 -1
- package/dist-lib/scripting/lua/bindings/userWindows.d.ts +1 -1
- package/dist-lib/scripting/lua/byteArmor.d.ts +36 -0
- package/dist-lib/scripting/lua/imageSize.d.ts +7 -0
- package/dist-lib/scripting/lua/rex.d.ts +4 -2
- package/dist-lib/scripting/lua/sqlRowEncoder.d.ts +6 -1
- package/dist-lib/scripting/lua/utf8CaseMap.d.ts +1 -0
- package/dist-lib/scripting/lua/utf8Patterns.d.ts +21 -1
- package/dist-lib/scripting/lua/wellFormedStrings.d.ts +40 -0
- package/dist-lib/scripting/lua/yajl.d.ts +43 -5
- package/dist-lib/scripting/profilesPresence.d.ts +20 -2
- package/dist-lib/scripting/vfs/ProfileVFS.d.ts +164 -10
- package/dist-lib/scripting/vfs/fsErrors.d.ts +28 -0
- package/dist-lib/scripting/vfs/idbCommit.d.ts +20 -0
- package/dist-lib/storage/appStore.d.ts +24 -9
- package/dist-lib/storage/hooks.d.ts +5 -1
- package/dist-lib/storage/index.d.ts +2 -2
- package/dist-lib/storage/mapStorage.d.ts +2 -0
- package/dist-lib/storage/persistentStorage.d.ts +3 -1
- package/dist-lib/storage/profileStorage.d.ts +15 -0
- package/dist-lib/storage/profileVfsData.d.ts +3 -3
- package/dist-lib/storage/schema.d.ts +521 -44
- package/dist-lib/storage/storageMigration.d.ts +82 -0
- package/dist-lib/storage-g5V1b-c1.js +2039 -0
- package/dist-lib/styles.css +1 -1
- package/dist-lib/ui/AboutModal.d.ts +1 -1
- package/dist-lib/ui/BrandLoginFields.d.ts +1 -1
- package/dist-lib/ui/BrowserSignInModal.d.ts +23 -0
- package/dist-lib/ui/CharLoginModal.d.ts +24 -15
- package/dist-lib/ui/CmdLineMenuRegistry.d.ts +14 -5
- package/dist-lib/ui/CommandBar.d.ts +8 -8
- package/dist-lib/ui/ConnectionFormModal.d.ts +25 -1
- package/dist-lib/ui/ConnectionScreen.d.ts +9 -1
- package/dist-lib/ui/GameLinkPrompt.d.ts +28 -0
- package/dist-lib/ui/HelpModal.d.ts +5 -1
- package/dist-lib/ui/MapSymbolUsageModal.d.ts +32 -0
- package/dist-lib/ui/MouseEventRegistry.d.ts +31 -4
- package/dist-lib/ui/NotepadModal.d.ts +22 -0
- package/dist-lib/ui/ResizableModal.d.ts +16 -1
- package/dist-lib/ui/SettingsModal.d.ts +10 -1
- package/dist-lib/ui/TlsAlertBanner.d.ts +3 -1
- package/dist-lib/ui/Toolbar.d.ts +22 -1
- package/dist-lib/ui/VaultManageButton.d.ts +20 -0
- package/dist-lib/ui/VaultModal.d.ts +5 -0
- package/dist-lib/ui/VaultUnlockPrompt.d.ts +15 -0
- package/dist-lib/ui/buttons/ButtonsBar.d.ts +3 -1
- package/dist-lib/ui/buttons/inactiveButtons.d.ts +25 -0
- package/dist-lib/ui/cmdline/CommandLineManager.d.ts +19 -0
- package/dist-lib/ui/cmdline/plainText.d.ts +16 -0
- package/dist-lib/ui/cmdline/subCommandLine.d.ts +78 -0
- package/dist-lib/ui/cmdline/useCmdLineSelection.d.ts +26 -0
- package/dist-lib/ui/cmdline/useSubCommandLineKeys.d.ts +33 -0
- package/dist-lib/ui/codemirror/lineParagraphMarks.d.ts +19 -0
- package/dist-lib/ui/codemirror/luaHover.d.ts +7 -0
- package/dist-lib/ui/codemirror/options.d.ts +33 -0
- package/dist-lib/ui/codemirror/theme.d.ts +29 -5
- package/dist-lib/ui/commands/addonCommands.d.ts +134 -0
- package/dist-lib/ui/commands/appShortcuts.d.ts +86 -0
- package/dist-lib/ui/commands/hostCommands.d.ts +88 -0
- package/dist-lib/ui/commands/keyMatch.d.ts +20 -0
- package/dist-lib/ui/commands/keySequence.d.ts +57 -0
- package/dist-lib/ui/components/ContextMenu.d.ts +21 -1
- package/dist-lib/ui/components/FontPicker.d.ts +5 -1
- package/dist-lib/ui/components/useModalFocus.d.ts +13 -1
- package/dist-lib/ui/helpTopics.d.ts +15 -0
- package/dist-lib/ui/labels/LabelManager.d.ts +172 -9
- package/dist-lib/ui/labels/LabelOverlay.d.ts +19 -0
- package/dist-lib/ui/labels/backgroundImageSize.d.ts +19 -0
- package/dist-lib/ui/labels/labelModel.d.ts +64 -0
- package/dist-lib/ui/labels/qColor.d.ts +13 -0
- package/dist-lib/ui/labels/qtCss.d.ts +12 -4
- package/dist-lib/ui/landmarks.d.ts +9 -0
- package/dist-lib/ui/launcher/ActionMenu.d.ts +19 -0
- package/dist-lib/ui/launcher/GameDetails.d.ts +21 -0
- package/dist-lib/ui/launcher/GameSection.d.ts +18 -0
- package/dist-lib/ui/launcher/LauncherSearch.d.ts +23 -0
- package/dist-lib/ui/launcher/ProfileArt.d.ts +20 -0
- package/dist-lib/ui/launcher/ProfileSection.d.ts +43 -0
- package/dist-lib/ui/launcher/launcherModel.d.ts +72 -0
- package/dist-lib/ui/layout/overlayLayerOrder.d.ts +2 -2
- package/dist-lib/ui/menu/MenuBar.d.ts +31 -0
- package/dist-lib/ui/menu/SplitButton.d.ts +39 -0
- package/dist-lib/ui/menu/anchoredPopup.d.ts +74 -0
- package/dist-lib/ui/menu/appMenus.d.ts +65 -0
- package/dist-lib/ui/menu/menuModel.d.ts +88 -0
- package/dist-lib/ui/menu/toolbarModel.d.ts +56 -0
- package/dist-lib/ui/notepad.d.ts +76 -0
- package/dist-lib/ui/openSignInPage.d.ts +14 -0
- package/dist-lib/ui/output/OutputContextMenu.d.ts +14 -1
- package/dist-lib/ui/output/OutputRenderer.d.ts +5 -0
- package/dist-lib/ui/output/OutputSearchBar.d.ts +5 -1
- package/dist-lib/ui/output/StickyOutputPanel.d.ts +17 -3
- package/dist-lib/ui/output/TextAnalyzerModal.d.ts +25 -0
- package/dist-lib/ui/output/caretMode.d.ts +3 -2
- package/dist-lib/ui/output/clearSplit.d.ts +11 -0
- package/dist-lib/ui/output/outputCopy.d.ts +41 -2
- package/dist-lib/ui/output/outputRows.d.ts +43 -0
- package/dist-lib/ui/output/selectionGesture.d.ts +35 -0
- package/dist-lib/ui/output/wordSelection.d.ts +33 -0
- package/dist-lib/ui/search/matcher.d.ts +14 -4
- package/dist-lib/ui/settings/SettingsShell.d.ts +91 -0
- package/dist-lib/ui/settings/ShortcutEditor.d.ts +13 -0
- package/dist-lib/ui/sound/SoundManager.d.ts +210 -44
- package/dist-lib/ui/sound/closedCaption.d.ts +4 -1
- package/dist-lib/ui/sound/mediaDirection.d.ts +35 -0
- package/dist-lib/ui/tabCompletion.d.ts +53 -0
- package/dist-lib/ui/textedit/TextEditManager.d.ts +11 -2
- package/dist-lib/ui/useOpenProfiles.d.ts +1 -1
- package/dist-lib/ui/useVaultSaver.d.ts +26 -0
- package/dist-lib/ui/video/VideoManager.d.ts +7 -0
- package/dist-lib/ui/windows/WindowManager.d.ts +452 -37
- package/dist-lib/ui/windows/panels/ScriptEditorPanel.d.ts +14 -0
- package/dist-lib/ui/windows/panels/ScriptSearch.d.ts +6 -1
- package/dist-lib/ui/windows/panels/TextPanel.d.ts +4 -1
- package/dist-lib/ui/windows/panels/VariablesView.d.ts +37 -7
- package/dist-lib/ui/windows/panels/WindowCmdLine.d.ts +4 -2
- package/dist-lib/ui/windows/panels/aliasLoop.d.ts +24 -0
- package/dist-lib/ui/windows/panels/editorClipboard.d.ts +45 -0
- package/dist-lib/ui/windows/panels/editorUndo.d.ts +79 -0
- package/dist-lib/ui/windows/panels/mapAreaChange.d.ts +10 -0
- package/dist-lib/utils/appShellCache.d.ts +25 -0
- package/dist-lib/utils/fontFamilyName.d.ts +13 -0
- package/dist-lib/utils/fontLoader.d.ts +31 -0
- package/dist-lib/utils/formatBytes.d.ts +4 -0
- package/dist-lib/utils/mustBeOneOf.d.ts +9 -0
- package/dist-lib/utils/profileLock.d.ts +1 -1
- package/dist-lib/utils/storedCredentials.d.ts +31 -0
- package/dist-lib/utils/systemTheme.d.ts +24 -0
- package/dist-lib/utils/timeZone.d.ts +10 -0
- package/dist-lib/vault/CredentialVault.d.ts +197 -0
- package/dist-lib/vault/deviceUnlock.d.ts +47 -0
- package/dist-lib/vault/passkeyPrf.d.ts +56 -0
- package/dist-lib/vault/useVault.d.ts +8 -0
- package/dist-lib/vault/vaultAccess.d.ts +80 -0
- package/dist-lib/vault/vaultCrypto.d.ts +56 -0
- package/dist-lib/vault/vaultHelpTopic.d.ts +9 -0
- package/dist-lib/vault/vaultRecord.d.ts +92 -0
- package/dist-lib/vfs-sw.js +220 -11
- package/dist-lib/vite.d.ts +1 -1
- package/dist-lib/vite.js +66 -43
- package/package.json +22 -14
- package/dist-lib/assets/mapParser.worker-t-3rd1zR.js +0 -9
- package/dist-lib/mud/connection/PingTracker.d.ts +0 -41
- package/dist-lib/ui/BundledGameGrid.d.ts +0 -21
- package/dist-lib/ui/ConnectionGrid.d.ts +0 -21
- package/dist-lib/ui/bufferWords.d.ts +0 -38
package/dist-lib/vfs-sw.js
CHANGED
|
@@ -1,26 +1,233 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
// the
|
|
1
|
+
// The Mudlet Web service worker. Two jobs that share nothing but this file:
|
|
2
|
+
//
|
|
3
|
+
// 1. ProfileVFS-backed assets at /__vfs/<connectionId>/<path>. The page is the
|
|
4
|
+
// source of truth for VFS contents (the SW can't share folder handles or
|
|
5
|
+
// always-open the same IDB store), so each request round-trips to the client
|
|
6
|
+
// via MessageChannel.
|
|
7
|
+
//
|
|
8
|
+
// 2. The app shell — the built HTML, JS, CSS and WASM — cached so an installed
|
|
9
|
+
// Mudlet Web opens offline instead of the browser's error page. There is no
|
|
10
|
+
// game to play without a network, but profiles, scripts, triggers, maps and
|
|
11
|
+
// logs all live in browser storage, and reaching them shouldn't need one.
|
|
12
|
+
// The manifest has advertised `display: standalone` since day one; this is
|
|
13
|
+
// what backs the promise (issue #71).
|
|
5
14
|
|
|
6
|
-
const CACHE_NAME = '
|
|
15
|
+
const CACHE_NAME = 'mudlet-vfs-v1';
|
|
16
|
+
const APP_CACHE = 'mudlet-app-v1';
|
|
7
17
|
// Scope path always ends with '/'. On a root-served deploy this is '/'; on
|
|
8
18
|
// GitHub Pages or any subpath deploy it's '/<repo>/'. The intercept prefix is
|
|
9
19
|
// '<scope>__vfs/' so SW-controlled URLs stay inside scope.
|
|
10
20
|
const SCOPE_PATH = new URL(self.registration.scope).pathname;
|
|
11
21
|
const PREFIX = `${SCOPE_PATH}__vfs/`;
|
|
22
|
+
// The one entry every navigation resolves to. Deep links (?profile=<id>) must
|
|
23
|
+
// not each earn a cache entry of their own, and any of them is served by this
|
|
24
|
+
// same document.
|
|
25
|
+
const SHELL_URL = SCOPE_PATH;
|
|
26
|
+
// Where the build id of the cached generation is kept — inside the cache it
|
|
27
|
+
// describes, so it survives the SW being killed and restarted without a second
|
|
28
|
+
// storage API. `__`-prefixed like `__vfs/`, which no real asset path uses.
|
|
29
|
+
const BUILD_KEY = `${SCOPE_PATH}__app-build`;
|
|
12
30
|
const READ_TIMEOUT_MS = 5000;
|
|
31
|
+
// Whether this registration is allowed to cache the app at all. Set from the
|
|
32
|
+
// script URL by the page (`vfs-sw.js?app-shell=1`), which only a built app asks
|
|
33
|
+
// for — a dev server has no content-hashed assets to cache, and caching the
|
|
34
|
+
// files it does serve under fixed names is cost with no offline to show for it.
|
|
35
|
+
// It has to be known here, at evaluation time, because the first fetch event can
|
|
36
|
+
// arrive long before any message from the page.
|
|
37
|
+
const APP_SHELL = new URL(self.location.href).searchParams.get('app-shell') === '1';
|
|
13
38
|
|
|
14
|
-
|
|
15
|
-
|
|
39
|
+
// What may be cached as part of the app. Deliberately narrow rather than
|
|
40
|
+
// "anything same-origin": it admits Vite's content-hashed output and the static
|
|
41
|
+
// files index.html names, and nothing else. That is also what keeps `yarn dev`
|
|
42
|
+
// honest — a dev server serves modules from /src/, /@vite/ and /node_modules/,
|
|
43
|
+
// none of which match, so hot reload never races a cached copy.
|
|
44
|
+
const HASHED_ASSET = /\/assets\/[^/]+-[A-Za-z0-9_-]{8,}\.[^/]+$/;
|
|
45
|
+
// The handful of app files that keep a fixed name: the icons and manifest
|
|
46
|
+
// index.html points at, and the WASM the plugin emits at the scope root
|
|
47
|
+
// (libpcre2.wasm) rather than into assets/.
|
|
48
|
+
const STATIC_FILE = /\/(?:manifest\.webmanifest|icon[a-z0-9-]*\.(?:svg|png)|favicon\.ico|[^/]+\.wasm)$/;
|
|
49
|
+
|
|
50
|
+
// Every app-cache lookup ignores Vary, and it is not an optimisation — without
|
|
51
|
+
// it the app does not load offline at all. Static hosts answer these files with
|
|
52
|
+
// `Vary: Origin` (vite preview and GitHub Pages both do), and Vite's built HTML
|
|
53
|
+
// asks for its bundle with `crossorigin`, so the parser's request carries an
|
|
54
|
+
// `Origin` header that the copy stored by `cache.add()` does not. Cache matching
|
|
55
|
+
// then declares them different requests, the cache misses, and the fetch behind
|
|
56
|
+
// it fails with the network gone — a blank page, from a cache holding exactly
|
|
57
|
+
// the right bytes under exactly the right URL. None of these responses actually
|
|
58
|
+
// differ by origin: they are static files on one origin.
|
|
59
|
+
const MATCH = { ignoreVary: true };
|
|
60
|
+
|
|
61
|
+
function inScope(url) {
|
|
62
|
+
return url.origin === self.location.origin
|
|
63
|
+
&& url.pathname.startsWith(SCOPE_PATH)
|
|
64
|
+
&& !url.pathname.startsWith(PREFIX);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function isAppAsset(url) {
|
|
68
|
+
return inScope(url) && (HASHED_ASSET.test(url.pathname) || STATIC_FILE.test(url.pathname));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
self.addEventListener('install', (event) => {
|
|
72
|
+
self.skipWaiting();
|
|
73
|
+
if (APP_SHELL) event.waitUntil(cacheShell());
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
self.addEventListener('activate', (event) => event.waitUntil((async () => {
|
|
77
|
+
// Anything left by an older worker of ours under a name this one no longer
|
|
78
|
+
// uses. Both prefixes: these caches were named `mudlet-*` before the storage
|
|
79
|
+
// rename, and an old worker's leftovers should be reclaimed rather than left
|
|
80
|
+
// to sit against the origin's quota forever. Scoped to our own prefixes
|
|
81
|
+
// rather than "every cache on the
|
|
82
|
+
// origin": a branded build embeds this worker in somebody else's site, and
|
|
83
|
+
// their caches are none of our business.
|
|
84
|
+
const names = await caches.keys();
|
|
85
|
+
await Promise.all(names
|
|
86
|
+
.filter((n) => (n.startsWith('mudlet-') || n.startsWith('mudix-'))
|
|
87
|
+
&& n !== CACHE_NAME && n !== APP_CACHE)
|
|
88
|
+
.map((n) => caches.delete(n)));
|
|
89
|
+
await self.clients.claim();
|
|
90
|
+
})()));
|
|
16
91
|
|
|
17
92
|
self.addEventListener('fetch', (event) => {
|
|
18
|
-
const
|
|
93
|
+
const request = event.request;
|
|
94
|
+
if (request.method !== 'GET') return;
|
|
95
|
+
const url = new URL(request.url);
|
|
19
96
|
if (url.origin !== self.location.origin) return;
|
|
20
|
-
if (
|
|
21
|
-
|
|
97
|
+
if (url.pathname.startsWith(PREFIX)) {
|
|
98
|
+
event.respondWith(handle(event, url));
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
if (!APP_SHELL) return;
|
|
102
|
+
// Navigations revalidate against the server, so a deploy is picked up on the
|
|
103
|
+
// next load rather than whenever the cache happens to turn over; the cached
|
|
104
|
+
// shell is strictly the offline answer. See shellFirst for why "network
|
|
105
|
+
// first" is not enough on its own here.
|
|
106
|
+
if (request.mode === 'navigate' && url.pathname.startsWith(SCOPE_PATH)) {
|
|
107
|
+
event.respondWith(shellFirst(request));
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
if (!inScope(url)) return;
|
|
111
|
+
// Hashed filenames are immutable by construction: a changed file is a
|
|
112
|
+
// changed URL, so a hit is never stale and revalidating one would be a
|
|
113
|
+
// round-trip spent to be told nothing.
|
|
114
|
+
if (HASHED_ASSET.test(url.pathname)) event.respondWith(cacheFirst(request));
|
|
115
|
+
// The fixed-name files can change under the same URL, so they are answered
|
|
116
|
+
// from the cache and refreshed behind it — offline-proof without ever
|
|
117
|
+
// pinning a stale icon or an old libpcre2.wasm to a dev server.
|
|
118
|
+
else if (STATIC_FILE.test(url.pathname)) event.respondWith(staleWhileRevalidate(request));
|
|
22
119
|
});
|
|
23
120
|
|
|
121
|
+
async function cacheShell() {
|
|
122
|
+
try {
|
|
123
|
+
const cache = await caches.open(APP_CACHE);
|
|
124
|
+
// `reload` so an install triggered by a reload of a stale page doesn't
|
|
125
|
+
// seed the cache from the HTTP cache's copy of the old document.
|
|
126
|
+
await cache.put(SHELL_URL, await fetch(new Request(SHELL_URL, { cache: 'reload' })));
|
|
127
|
+
} catch {
|
|
128
|
+
// Installed while offline, or the shell 404s under this scope. The first
|
|
129
|
+
// successful navigation fills it in.
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async function shellFirst(request) {
|
|
134
|
+
const cache = await caches.open(APP_CACHE);
|
|
135
|
+
try {
|
|
136
|
+
// Revalidate rather than `fetch(request)`. A navigation request carries
|
|
137
|
+
// cache mode `default`, so the plain form is answered from the browser
|
|
138
|
+
// HTTP cache — and GitHub Pages stamps every file it serves, index.html
|
|
139
|
+
// included, with `max-age=600`. That turned this "network first" branch
|
|
140
|
+
// into "ten-minute-old document first": the shell it returned could name
|
|
141
|
+
// content-hashed assets that the deploy had already deleted, so the entry
|
|
142
|
+
// module 404'd and the page came up blank. `no-cache` means revalidate,
|
|
143
|
+
// not refetch — the usual answer is a 304 on a 4KB document — and a
|
|
144
|
+
// server that cannot be reached still throws, so the offline path below
|
|
145
|
+
// is unchanged.
|
|
146
|
+
const response = await fetch(new Request(request, { cache: 'no-cache' }));
|
|
147
|
+
if (response.ok && response.type === 'basic') {
|
|
148
|
+
cache.put(SHELL_URL, response.clone()).catch(() => {});
|
|
149
|
+
}
|
|
150
|
+
return response;
|
|
151
|
+
} catch {
|
|
152
|
+
return (await cache.match(SHELL_URL, MATCH)) ?? Response.error();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async function cacheFirst(request) {
|
|
157
|
+
const cache = await caches.open(APP_CACHE);
|
|
158
|
+
const hit = await cache.match(request, MATCH);
|
|
159
|
+
if (hit) return hit;
|
|
160
|
+
try {
|
|
161
|
+
const response = await fetch(request);
|
|
162
|
+
if (response.ok && response.type === 'basic') {
|
|
163
|
+
cache.put(request, response.clone()).catch(() => {});
|
|
164
|
+
}
|
|
165
|
+
return response;
|
|
166
|
+
} catch {
|
|
167
|
+
return Response.error();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
async function staleWhileRevalidate(request) {
|
|
172
|
+
const cache = await caches.open(APP_CACHE);
|
|
173
|
+
const hit = await cache.match(request, MATCH);
|
|
174
|
+
const network = fetch(request).then((response) => {
|
|
175
|
+
if (response.ok && response.type === 'basic') {
|
|
176
|
+
cache.put(request, response.clone()).catch(() => {});
|
|
177
|
+
}
|
|
178
|
+
return response;
|
|
179
|
+
});
|
|
180
|
+
if (hit) {
|
|
181
|
+
// Let the refresh finish after the response has gone out.
|
|
182
|
+
network.catch(() => {});
|
|
183
|
+
return hit;
|
|
184
|
+
}
|
|
185
|
+
try {
|
|
186
|
+
return await network;
|
|
187
|
+
} catch {
|
|
188
|
+
return Response.error();
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Cache everything the page has already loaded, on the page's say-so.
|
|
194
|
+
*
|
|
195
|
+
* A first visit is not controlled by the worker until it claims, by which time
|
|
196
|
+
* the bundle has been fetched uncached — so without this, offline would only
|
|
197
|
+
* work from the *second* visit. The page sends the resource list it actually
|
|
198
|
+
* loaded (chunks and WASM included), which is more than this file could guess.
|
|
199
|
+
* Chunks loaded lazily later in an uncontrolled first session are the one gap,
|
|
200
|
+
* and they are picked up by `cacheFirst` on the next visit.
|
|
201
|
+
*/
|
|
202
|
+
async function precacheApp({ build, urls }) {
|
|
203
|
+
let cache = await caches.open(APP_CACHE);
|
|
204
|
+
const wanted = (Array.isArray(urls) ? urls : []).filter((raw) => {
|
|
205
|
+
try { return isAppAsset(new URL(raw, self.location.href)); } catch { return false; }
|
|
206
|
+
});
|
|
207
|
+
// A deploy renames every hashed asset, so the previous generation's entries
|
|
208
|
+
// are unreachable dead weight — drop the lot rather than grow forever.
|
|
209
|
+
// Keyed off the *app's* build id, not a constant in this file: this file
|
|
210
|
+
// changes about once a year, so a version bumped here would never fire.
|
|
211
|
+
//
|
|
212
|
+
// Only ever on a list with something in it. An empty one means the page
|
|
213
|
+
// could not enumerate what it loaded, and emptying a working cache on the
|
|
214
|
+
// strength of that would leave the app less able to open offline than
|
|
215
|
+
// before, which is the opposite of the point.
|
|
216
|
+
const stamped = await cache.match(BUILD_KEY, MATCH);
|
|
217
|
+
if (wanted.length > 0 && (stamped ? await stamped.text() : null) !== build) {
|
|
218
|
+
await caches.delete(APP_CACHE);
|
|
219
|
+
cache = await caches.open(APP_CACHE);
|
|
220
|
+
await cache.put(BUILD_KEY, new Response(build));
|
|
221
|
+
await cacheShell();
|
|
222
|
+
}
|
|
223
|
+
await Promise.all(wanted.map(async (url) => {
|
|
224
|
+
if (await cache.match(url, MATCH)) return;
|
|
225
|
+
// One asset that has since 404'd must not take the rest with it, which
|
|
226
|
+
// is what cache.addAll() would do.
|
|
227
|
+
try { await cache.add(url); } catch { /* keep going */ }
|
|
228
|
+
}));
|
|
229
|
+
}
|
|
230
|
+
|
|
24
231
|
async function handle(event, url) {
|
|
25
232
|
const rest = url.pathname.slice(PREFIX.length).split('/').filter(Boolean);
|
|
26
233
|
if (rest.length < 2) return new Response('Bad request', { status: 400 });
|
|
@@ -35,7 +242,7 @@ async function handle(event, url) {
|
|
|
35
242
|
if (!client) {
|
|
36
243
|
// Either there's no app tab loaded (direct URL hit in fresh tab) or
|
|
37
244
|
// the only candidate is the tab currently navigating to this URL.
|
|
38
|
-
return new Response('No app tab loaded; open
|
|
245
|
+
return new Response('No app tab loaded; open Mudlet Web first', { status: 503 });
|
|
39
246
|
}
|
|
40
247
|
|
|
41
248
|
const reply = await ask(client, { type: 'vfs:read', connectionId, path: filePath });
|
|
@@ -102,6 +309,8 @@ self.addEventListener('message', (event) => {
|
|
|
102
309
|
if (!data) return;
|
|
103
310
|
if (data.type === 'vfs:invalidate') {
|
|
104
311
|
event.waitUntil(invalidate(data));
|
|
312
|
+
} else if (data.type === 'app:precache' && APP_SHELL) {
|
|
313
|
+
event.waitUntil(precacheApp(data));
|
|
105
314
|
}
|
|
106
315
|
});
|
|
107
316
|
|
package/dist-lib/vite.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { PluginOption } from 'vite';
|
|
2
|
-
export default function
|
|
2
|
+
export default function mudlet(): PluginOption[];
|
package/dist-lib/vite.js
CHANGED
|
@@ -3,6 +3,7 @@ import { createRequire } from 'node:module';
|
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
4
|
import { dirname, join } from 'node:path';
|
|
5
5
|
import { nodePolyfills } from 'vite-plugin-node-polyfills';
|
|
6
|
+
import { patchLibpcre2Wasm } from './pcre2Wasm.js';
|
|
6
7
|
/**
|
|
7
8
|
* The `@mudlet/mudlet-web/vite` companion plugin. The library leaves all of its
|
|
8
9
|
* heavyweight dependencies external, so the consumer's Vite processes them —
|
|
@@ -19,10 +20,11 @@ import { nodePolyfills } from 'vite-plugin-node-polyfills';
|
|
|
19
20
|
*/
|
|
20
21
|
const require = createRequire(import.meta.url);
|
|
21
22
|
const POLYFILLS = ['buffer', 'stream', 'events', 'util'];
|
|
22
|
-
/**
|
|
23
|
-
*
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
/** The static files the app needs at its root (vfs-sw.js, oauth-callback.html)
|
|
24
|
+
* ship next to the compiled plugin in dist-lib (consumers) and in public/ when
|
|
25
|
+
* running from the Mudlet Web repo itself (source import). */
|
|
26
|
+
function resolveStaticPath(name) {
|
|
27
|
+
for (const rel of [`./${name}`, `../public/${name}`]) {
|
|
26
28
|
const p = fileURLToPath(new URL(rel, import.meta.url));
|
|
27
29
|
if (existsSync(p))
|
|
28
30
|
return p;
|
|
@@ -31,18 +33,28 @@ function resolveVfsSwPath() {
|
|
|
31
33
|
}
|
|
32
34
|
/** Serves libpcre2.wasm at the root URL in dev (where emscripten looks for it
|
|
33
35
|
* when document.currentScript is null) and emits it to the build output.
|
|
34
|
-
* Resolved from wherever pcre2-wasm-universal lives relative to
|
|
36
|
+
* Resolved from wherever pcre2-wasm-universal lives relative to mudlet, and
|
|
37
|
+
* patched on the way out so `_match` takes an options argument — without it a
|
|
38
|
+
* trigger's match-all is quadratic in the line's length (see pcre2Wasm.ts).
|
|
39
|
+
* A binary the patch doesn't recognise goes out as shipped: slower, not wrong.
|
|
40
|
+
* That fallback is silent here on purpose (a consumer's build shouldn't break
|
|
41
|
+
* over speed); tests/triggers/pcreMatchAllLinear.test.ts is what turns a
|
|
42
|
+
* pcre2-wasm-universal bump the patch no longer fits into a red CI run. */
|
|
35
43
|
function pcre2WasmPlugin() {
|
|
36
44
|
// The wasm file isn't in the package's exports map — resolve the exported
|
|
37
45
|
// ./libpcre2 entry (dist/libpcre2.js) and take its sibling.
|
|
38
46
|
const wasmPath = join(dirname(require.resolve('pcre2-wasm-universal/libpcre2')), 'libpcre2.wasm');
|
|
47
|
+
const wasm = () => {
|
|
48
|
+
const shipped = readFileSync(wasmPath);
|
|
49
|
+
return patchLibpcre2Wasm(shipped) ?? shipped;
|
|
50
|
+
};
|
|
39
51
|
return {
|
|
40
|
-
name: '
|
|
52
|
+
name: 'mudlet:pcre2-wasm',
|
|
41
53
|
configureServer(server) {
|
|
42
54
|
server.middlewares.use((req, res, next) => {
|
|
43
55
|
if (req.url === '/libpcre2.wasm') {
|
|
44
56
|
res.setHeader('Content-Type', 'application/wasm');
|
|
45
|
-
res.end(
|
|
57
|
+
res.end(wasm());
|
|
46
58
|
return;
|
|
47
59
|
}
|
|
48
60
|
next();
|
|
@@ -52,80 +64,90 @@ function pcre2WasmPlugin() {
|
|
|
52
64
|
this.emitFile({
|
|
53
65
|
type: 'asset',
|
|
54
66
|
fileName: 'libpcre2.wasm',
|
|
55
|
-
source:
|
|
67
|
+
source: wasm(),
|
|
56
68
|
});
|
|
57
69
|
},
|
|
58
70
|
};
|
|
59
71
|
}
|
|
60
|
-
/** Serves/emits
|
|
61
|
-
* `registerVfsServiceWorker()` (called by MudletWebApp) finds it
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
|
|
65
|
-
|
|
72
|
+
/** Serves/emits a static file at the site root. Used for the VFS service
|
|
73
|
+
* worker, so `registerVfsServiceWorker()` (called by MudletWebApp) finds it,
|
|
74
|
+
* and for `oauth-callback.html`, the redirect target of the client-driven GMCP
|
|
75
|
+
* `Char.Login` browser sign-in (see oauthClientFlow.ts). Skipped when the
|
|
76
|
+
* consumer already ships its own copy in public/ — as the standalone Mudlet
|
|
77
|
+
* Web app does. */
|
|
78
|
+
function rootStaticFilePlugin(name, contentType) {
|
|
79
|
+
const filePath = resolveStaticPath(name);
|
|
66
80
|
let skip = false;
|
|
67
81
|
return {
|
|
68
|
-
name:
|
|
82
|
+
name: `mudlet:static:${name}`,
|
|
69
83
|
configResolved(config) {
|
|
70
|
-
skip = !
|
|
84
|
+
skip = !filePath || (!!config.publicDir && existsSync(join(config.publicDir, name)));
|
|
71
85
|
},
|
|
72
86
|
configureServer(server) {
|
|
73
87
|
server.middlewares.use((req, res, next) => {
|
|
74
|
-
if (!skip &&
|
|
75
|
-
res.setHeader('Content-Type',
|
|
76
|
-
res.end(readFileSync(
|
|
88
|
+
if (!skip && filePath && req.url?.split('?')[0] === `/${name}`) {
|
|
89
|
+
res.setHeader('Content-Type', contentType);
|
|
90
|
+
res.end(readFileSync(filePath));
|
|
77
91
|
return;
|
|
78
92
|
}
|
|
79
93
|
next();
|
|
80
94
|
});
|
|
81
95
|
},
|
|
82
96
|
generateBundle() {
|
|
83
|
-
if (skip || !
|
|
97
|
+
if (skip || !filePath)
|
|
84
98
|
return;
|
|
85
99
|
this.emitFile({
|
|
86
100
|
type: 'asset',
|
|
87
|
-
fileName:
|
|
88
|
-
source: readFileSync(
|
|
101
|
+
fileName: name,
|
|
102
|
+
source: readFileSync(filePath, 'utf8'),
|
|
89
103
|
});
|
|
90
104
|
},
|
|
91
105
|
};
|
|
92
106
|
}
|
|
93
|
-
export default function
|
|
107
|
+
export default function mudlet() {
|
|
94
108
|
return [
|
|
95
109
|
{
|
|
96
|
-
name: '
|
|
110
|
+
name: 'mudlet:config',
|
|
97
111
|
config: () => ({
|
|
98
112
|
resolve: {
|
|
99
|
-
// Exactly one
|
|
100
|
-
//
|
|
101
|
-
//
|
|
102
|
-
//
|
|
103
|
-
//
|
|
104
|
-
//
|
|
105
|
-
//
|
|
106
|
-
//
|
|
113
|
+
// Exactly one instance of each, always. `mudlet-map-editor`
|
|
114
|
+
// used to declare these as plain *dependencies*, so the
|
|
115
|
+
// moment its range outran the range the app resolved, the
|
|
116
|
+
// package manager nested a second copy under the editor.
|
|
117
|
+
// The editor's `App` was then rendered by Mudlet Web's React
|
|
118
|
+
// while its hooks came from the nested one, whose
|
|
119
|
+
// dispatcher is null — "Invalid hook call", and with no
|
|
120
|
+
// error boundary above the lazy boundary the throw
|
|
107
121
|
// unmounts the whole root, so opening the map editor
|
|
108
122
|
// blanked the entire UI in dev and in production alike.
|
|
109
|
-
//
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
|
|
123
|
+
// Editor 2.0.0 makes all of them peer dependencies, which
|
|
124
|
+
// is the fix at the source; this stays as the backstop that
|
|
125
|
+
// does not depend on the package manager hoisting correctly
|
|
126
|
+
// — and consumers of the library (which externalizes react)
|
|
127
|
+
// get it through this plugin too. Konva and the renderer
|
|
128
|
+
// are here for the same reason and not only for symmetry:
|
|
129
|
+
// two Konvas split the stage registry, and two renderers
|
|
130
|
+
// disagree on scene structure, both silently.
|
|
131
|
+
dedupe: ['react', 'react-dom', 'konva', 'mudlet-map-renderer'],
|
|
113
132
|
},
|
|
114
133
|
// A Mudlet package archive is a zip, not source. `?url` imports
|
|
115
134
|
// get away without this (the explicit query short-circuits
|
|
116
135
|
// import analysis), but `?inline` — which the busted fixtures
|
|
117
136
|
// use to carry an archive into the VFS — reaches the asset
|
|
118
137
|
// pipeline and needs the extension declared.
|
|
119
|
-
|
|
138
|
+
// The map fixtures are plain `.zip` and binary `.dat`, and scoping
|
|
139
|
+
// those to the fixture tree keeps a bare import of either anywhere
|
|
140
|
+
// else meaning what it means today.
|
|
141
|
+
assetsInclude: ['**/*.mpackage', '**/specs/fixtures/**/*.zip', '**/specs/fixtures/**/*.dat'],
|
|
120
142
|
optimizeDeps: {
|
|
121
|
-
// '
|
|
143
|
+
// 'Mudlet Web': the library entry carries relative `?url` asset
|
|
122
144
|
// imports (external in the lib build); the dep optimizer's
|
|
123
145
|
// scanner treats the query as part of a filesystem path and
|
|
124
|
-
// dies on Windows (os error 123). Excluded,
|
|
146
|
+
// dies on Windows (os error 123). Excluded, Mudlet Web is served
|
|
125
147
|
// through Vite's transform pipeline in dev, where `?url`
|
|
126
|
-
// works. Harmless in
|
|
148
|
+
// works. Harmless in Mudlet Web's own repo (not a dep there).
|
|
127
149
|
exclude: ['pcre2-wasm-universal', '@mudlet/mudlet-web'],
|
|
128
|
-
// CJS deps reached from the excluded
|
|
150
|
+
// CJS deps reached from the excluded Mudlet Web entry must be
|
|
129
151
|
// pre-bundled explicitly (Vite doesn't interop CJS served
|
|
130
152
|
// raw). Extend this list if dev mode reports "does not
|
|
131
153
|
// provide an export named ..." for another dependency.
|
|
@@ -136,7 +158,7 @@ export default function mudix() {
|
|
|
136
158
|
// html-parse-stringify > void-elements) are CJS, and which
|
|
137
159
|
// of them trips first depends on evaluation order. Listing
|
|
138
160
|
// the editor pre-bundles the lot in one go — and mirrors
|
|
139
|
-
//
|
|
161
|
+
// Mudlet Web's own dev server, where the scanner finds the
|
|
140
162
|
// `import('mudlet-map-editor')` in MapEditorModal and
|
|
141
163
|
// pre-bundles it anyway. Bare package names only, no
|
|
142
164
|
// subpaths: `mudlet-map-renderer/bigmap` and friends only
|
|
@@ -171,6 +193,7 @@ export default function mudix() {
|
|
|
171
193
|
},
|
|
172
194
|
nodePolyfills({ include: POLYFILLS }),
|
|
173
195
|
pcre2WasmPlugin(),
|
|
174
|
-
|
|
196
|
+
rootStaticFilePlugin('vfs-sw.js', 'text/javascript'),
|
|
197
|
+
rootStaticFilePlugin('oauth-callback.html', 'text/html; charset=utf-8'),
|
|
175
198
|
];
|
|
176
199
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mudlet/mudlet-web",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Mudlet Web — Mudlet in the browser, usable standalone or as a library for branded builds",
|
|
6
6
|
"license": "GPL-2.0-or-later",
|
|
@@ -49,7 +49,9 @@
|
|
|
49
49
|
"busted:failures": "playwright test -c playwright.failures.config.ts",
|
|
50
50
|
"sync:mudlet-specs": "node scripts/sync-mudlet-specs.mjs",
|
|
51
51
|
"sync:mudlet-lua": "node scripts/sync-mudlet-lua.mjs",
|
|
52
|
-
"sync:mudlet-games": "node scripts/sync-mudlet-games.mjs"
|
|
52
|
+
"sync:mudlet-games": "node scripts/sync-mudlet-games.mjs",
|
|
53
|
+
"check:vendored": "node scripts/check-vendored-paths.mjs",
|
|
54
|
+
"test:e2e:upgrade": "playwright test -c playwright.upgrade.config.ts"
|
|
53
55
|
},
|
|
54
56
|
"dependencies": {
|
|
55
57
|
"@codemirror/autocomplete": "^6.20.1",
|
|
@@ -57,25 +59,29 @@
|
|
|
57
59
|
"@codemirror/lang-json": "^6.0.2",
|
|
58
60
|
"@codemirror/language": "^6.12.3",
|
|
59
61
|
"@codemirror/legacy-modes": "^6.5.2",
|
|
60
|
-
"@codemirror/
|
|
62
|
+
"@codemirror/search": "^6.7.2",
|
|
63
|
+
"@codemirror/state": "^6.7.4",
|
|
61
64
|
"@codemirror/theme-one-dark": "^6.1.3",
|
|
62
|
-
"@codemirror/view": "^6.
|
|
65
|
+
"@codemirror/view": "^6.43.11",
|
|
63
66
|
"@lezer/highlight": "^1.2.3",
|
|
64
67
|
"@sqlite.org/sqlite-wasm": "^3.53.0-build1",
|
|
65
68
|
"@zenfs/core": "^2.5.6",
|
|
66
69
|
"@zenfs/dom": "^1.2.9",
|
|
67
70
|
"dompurify": "^3.4.14",
|
|
68
71
|
"fflate": "^0.8.2",
|
|
72
|
+
"i18next": "^26.3.6",
|
|
73
|
+
"konva": "^10.3.0",
|
|
69
74
|
"lucide-react": "^1.14.0",
|
|
70
75
|
"marked": "^18.0.4",
|
|
71
|
-
"mudlet-map-binary-reader": "^1.
|
|
72
|
-
"mudlet-map-editor": "^
|
|
73
|
-
"mudlet-map-renderer": "^
|
|
76
|
+
"mudlet-map-binary-reader": "^1.3.0",
|
|
77
|
+
"mudlet-map-editor": "^2.0.0",
|
|
78
|
+
"mudlet-map-renderer": "^3.0.0",
|
|
74
79
|
"pako": "^2.1.0",
|
|
75
80
|
"pcre2-wasm-universal": "^1.0.0",
|
|
76
|
-
"react": "^19.2.
|
|
77
|
-
"react-dom": "^19.2.
|
|
78
|
-
"
|
|
81
|
+
"react": "^19.2.8",
|
|
82
|
+
"react-dom": "^19.2.8",
|
|
83
|
+
"react-i18next": "^17.0.11",
|
|
84
|
+
"vite-plugin-node-polyfills": "^0.28.0",
|
|
79
85
|
"wasmoon-lua5.1": "^1.18.10",
|
|
80
86
|
"zustand": "^5.0.12"
|
|
81
87
|
},
|
|
@@ -86,12 +92,14 @@
|
|
|
86
92
|
"@types/react": "^19.2.0",
|
|
87
93
|
"@types/react-dom": "^19.2.0",
|
|
88
94
|
"@vitejs/plugin-react": "^6.0.1",
|
|
89
|
-
"happy-dom": "^
|
|
95
|
+
"happy-dom": "^21.0.4",
|
|
90
96
|
"typescript": "^5.0.0",
|
|
91
|
-
"vite": "8.
|
|
92
|
-
"vitest": "^4.1.
|
|
97
|
+
"vite": "8.1.6",
|
|
98
|
+
"vitest": "^4.1.12"
|
|
93
99
|
},
|
|
94
100
|
"resolutions": {
|
|
95
|
-
"dompurify": "^3.4.14"
|
|
101
|
+
"dompurify": "^3.4.14",
|
|
102
|
+
"@codemirror/state": "^6.7.4",
|
|
103
|
+
"@codemirror/view": "^6.43.11"
|
|
96
104
|
}
|
|
97
105
|
}
|